| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ukbd.c,v 1.112 2011/11/02 08:49:08 macallan Exp $ */ | | 1 | /* $NetBSD: ukbd.c,v 1.113 2011/11/03 02:41:29 macallan Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1998 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1998 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Lennart Augustsson (lennart@augustsson.net) at | | 8 | * by Lennart Augustsson (lennart@augustsson.net) at |
9 | * Carlstedt Research & Technology. | | 9 | * Carlstedt Research & Technology. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -25,27 +25,27 @@ | | | @@ -25,27 +25,27 @@ |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 | * POSSIBILITY OF SUCH DAMAGE. | | 30 | * POSSIBILITY OF SUCH DAMAGE. |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | /* | | 33 | /* |
34 | * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf | | 34 | * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf |
35 | */ | | 35 | */ |
36 | | | 36 | |
37 | #include <sys/cdefs.h> | | 37 | #include <sys/cdefs.h> |
38 | __KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.112 2011/11/02 08:49:08 macallan Exp $"); | | 38 | __KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.113 2011/11/03 02:41:29 macallan Exp $"); |
39 | | | 39 | |
40 | #include <sys/param.h> | | 40 | #include <sys/param.h> |
41 | #include <sys/systm.h> | | 41 | #include <sys/systm.h> |
42 | #include <sys/callout.h> | | 42 | #include <sys/callout.h> |
43 | #include <sys/kernel.h> | | 43 | #include <sys/kernel.h> |
44 | #include <sys/device.h> | | 44 | #include <sys/device.h> |
45 | #include <sys/ioctl.h> | | 45 | #include <sys/ioctl.h> |
46 | #include <sys/file.h> | | 46 | #include <sys/file.h> |
47 | #include <sys/select.h> | | 47 | #include <sys/select.h> |
48 | #include <sys/proc.h> | | 48 | #include <sys/proc.h> |
49 | #include <sys/vnode.h> | | 49 | #include <sys/vnode.h> |
50 | #include <sys/poll.h> | | 50 | #include <sys/poll.h> |
51 | | | 51 | |
| @@ -56,26 +56,27 @@ __KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.1 | | | @@ -56,26 +56,27 @@ __KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.1 |
56 | #include <dev/usb/usbdi_util.h> | | 56 | #include <dev/usb/usbdi_util.h> |
57 | #include <dev/usb/usbdevs.h> | | 57 | #include <dev/usb/usbdevs.h> |
58 | #include <dev/usb/usb_quirks.h> | | 58 | #include <dev/usb/usb_quirks.h> |
59 | #include <dev/usb/uhidev.h> | | 59 | #include <dev/usb/uhidev.h> |
60 | #include <dev/usb/hid.h> | | 60 | #include <dev/usb/hid.h> |
61 | #include <dev/usb/ukbdvar.h> | | 61 | #include <dev/usb/ukbdvar.h> |
62 | | | 62 | |
63 | #include <dev/wscons/wsconsio.h> | | 63 | #include <dev/wscons/wsconsio.h> |
64 | #include <dev/wscons/wskbdvar.h> | | 64 | #include <dev/wscons/wskbdvar.h> |
65 | #include <dev/wscons/wsksymdef.h> | | 65 | #include <dev/wscons/wsksymdef.h> |
66 | #include <dev/wscons/wsksymvar.h> | | 66 | #include <dev/wscons/wsksymvar.h> |
67 | | | 67 | |
68 | #ifdef _KERNEL_OPT | | 68 | #ifdef _KERNEL_OPT |
| | | 69 | #include "opt_ukbd.h" |
69 | #include "opt_ukbd_layout.h" | | 70 | #include "opt_ukbd_layout.h" |
70 | #include "opt_wsdisplay_compat.h" | | 71 | #include "opt_wsdisplay_compat.h" |
71 | #include "opt_ddb.h" | | 72 | #include "opt_ddb.h" |
72 | #endif /* _KERNEL_OPT */ | | 73 | #endif /* _KERNEL_OPT */ |
73 | | | 74 | |
74 | #ifdef UKBD_DEBUG | | 75 | #ifdef UKBD_DEBUG |
75 | #define DPRINTF(x) if (ukbddebug) printf x | | 76 | #define DPRINTF(x) if (ukbddebug) printf x |
76 | #define DPRINTFN(n,x) if (ukbddebug>(n)) printf x | | 77 | #define DPRINTFN(n,x) if (ukbddebug>(n)) printf x |
77 | int ukbddebug = 0; | | 78 | int ukbddebug = 0; |
78 | #else | | 79 | #else |
79 | #define DPRINTF(x) | | 80 | #define DPRINTF(x) |
80 | #define DPRINTFN(n,x) | | 81 | #define DPRINTFN(n,x) |
81 | #endif | | 82 | #endif |
| @@ -135,50 +136,52 @@ Static const struct ukbd_keycodetrans tr | | | @@ -135,50 +136,52 @@ Static const struct ukbd_keycodetrans tr |
135 | { 0x50, 0x4a }, /* Left -> Home */ | | 136 | { 0x50, 0x4a }, /* Left -> Home */ |
136 | { 0x51, 0x4e }, /* Down -> PageDown */ | | 137 | { 0x51, 0x4e }, /* Down -> PageDown */ |
137 | { 0x52, 0x4b }, /* Up -> PageUp */ | | 138 | { 0x52, 0x4b }, /* Up -> PageUp */ |
138 | { 0x00, 0x00 } | | 139 | { 0x00, 0x00 } |
139 | }; | | 140 | }; |
140 | | | 141 | |
141 | Static const struct ukbd_keycodetrans trtab_apple_iso[] = { | | 142 | Static const struct ukbd_keycodetrans trtab_apple_iso[] = { |
142 | { 0x35, 0x64 }, /* swap the key above tab with key right of shift */ | | 143 | { 0x35, 0x64 }, /* swap the key above tab with key right of shift */ |
143 | { 0x64, 0x35 }, | | 144 | { 0x64, 0x35 }, |
144 | { 0x31, 0x32 }, /* key left of return is Europe1, not "\|" */ | | 145 | { 0x31, 0x32 }, /* key left of return is Europe1, not "\|" */ |
145 | { 0x00, 0x00 } | | 146 | { 0x00, 0x00 } |
146 | }; | | 147 | }; |
147 | | | 148 | |
| | | 149 | #ifdef GDIUM_KEYBOARD_HACK |
148 | Static const struct ukbd_keycodetrans trtab_gdium_fn[] = { | | 150 | Static const struct ukbd_keycodetrans trtab_gdium_fn[] = { |
149 | #ifdef notyet | | 151 | #ifdef notyet |
150 | { 58, 0 }, /* F1 -> toggle camera */ | | 152 | { 58, 0 }, /* F1 -> toggle camera */ |
151 | { 59, 0 }, /* F2 -> toggle wireless */ | | 153 | { 59, 0 }, /* F2 -> toggle wireless */ |
152 | #endif | | 154 | #endif |
153 | { 60, IS_PMF | PMFE_AUDIO_VOLUME_TOGGLE }, | | 155 | { 60, IS_PMF | PMFE_AUDIO_VOLUME_TOGGLE }, |
154 | { 61, IS_PMF | PMFE_AUDIO_VOLUME_UP }, | | 156 | { 61, IS_PMF | PMFE_AUDIO_VOLUME_UP }, |
155 | { 62, IS_PMF | PMFE_AUDIO_VOLUME_DOWN }, | | 157 | { 62, IS_PMF | PMFE_AUDIO_VOLUME_DOWN }, |
156 | #ifdef notyet | | 158 | #ifdef notyet |
157 | { 63, 0 }, /* F6 -> toggle ext. video */ | | 159 | { 63, 0 }, /* F6 -> toggle ext. video */ |
158 | { 64, 0 }, /* F7 -> toggle mouse */ | | 160 | { 64, 0 }, /* F7 -> toggle mouse */ |
159 | #endif | | 161 | #endif |
160 | { 65, IS_PMF | PMFE_DISPLAY_BRIGHTNESS_UP }, | | 162 | { 65, IS_PMF | PMFE_DISPLAY_BRIGHTNESS_UP }, |
161 | { 66, IS_PMF | PMFE_DISPLAY_BRIGHTNESS_DOWN }, | | 163 | { 66, IS_PMF | PMFE_DISPLAY_BRIGHTNESS_DOWN }, |
162 | #ifdef notyet | | 164 | #ifdef notyet |
163 | { 67, 0 }, /* F10 -> suspend */ | | 165 | { 67, 0 }, /* F10 -> suspend */ |
164 | { 68, 0 }, /* F11 -> user1 */ | | 166 | { 68, 0 }, /* F11 -> user1 */ |
165 | { 69, 0 }, /* F12 -> user2 */ | | 167 | { 69, 0 }, /* F12 -> user2 */ |
166 | { 70, 0 }, /* print screen -> sysrq */ | | 168 | { 70, 0 }, /* print screen -> sysrq */ |
167 | #endif | | 169 | #endif |
168 | { 76, 71 }, /* delete -> scroll lock */ | | 170 | { 76, 71 }, /* delete -> scroll lock */ |
169 | { 81, 78 }, /* down -> page down */ | | 171 | { 81, 78 }, /* down -> page down */ |
170 | { 82, 75 } /* up -> page up */ | | 172 | { 82, 75 } /* up -> page up */ |
171 | }; | | 173 | }; |
| | | 174 | #endif |
172 | | | 175 | |
173 | #if defined(__NetBSD__) && defined(WSDISPLAY_COMPAT_RAWKBD) | | 176 | #if defined(__NetBSD__) && defined(WSDISPLAY_COMPAT_RAWKBD) |
174 | #define NN 0 /* no translation */ | | 177 | #define NN 0 /* no translation */ |
175 | /* | | 178 | /* |
176 | * Translate USB keycodes to US keyboard XT scancodes. | | 179 | * Translate USB keycodes to US keyboard XT scancodes. |
177 | * Scancodes >= 0x80 represent EXTENDED keycodes. | | 180 | * Scancodes >= 0x80 represent EXTENDED keycodes. |
178 | * | | 181 | * |
179 | * See http://www.microsoft.com/whdc/archive/scancode.mspx | | 182 | * See http://www.microsoft.com/whdc/archive/scancode.mspx |
180 | * | | 183 | * |
181 | * Note: a real pckbd(4) has more complexity in its | | 184 | * Note: a real pckbd(4) has more complexity in its |
182 | * protocol for some keys than this translation implements. | | 185 | * protocol for some keys than this translation implements. |
183 | * For example, some keys generate Fake ShiftL events (e0 2a) | | 186 | * For example, some keys generate Fake ShiftL events (e0 2a) |
184 | * before the actual key sequence. | | 187 | * before the actual key sequence. |
| @@ -413,29 +416,31 @@ ukbd_attach(device_t parent, device_t se | | | @@ -413,29 +416,31 @@ ukbd_attach(device_t parent, device_t se |
413 | if (parseerr != NULL) { | | 416 | if (parseerr != NULL) { |
414 | aprint_normal("\n"); | | 417 | aprint_normal("\n"); |
415 | aprint_error_dev(self, "attach failed, %s\n", parseerr); | | 418 | aprint_error_dev(self, "attach failed, %s\n", parseerr); |
416 | return; | | 419 | return; |
417 | } | | 420 | } |
418 | | | 421 | |
419 | /* Quirks */ | | 422 | /* Quirks */ |
420 | qflags = usbd_get_quirks(uha->parent->sc_udev)->uq_flags; | | 423 | qflags = usbd_get_quirks(uha->parent->sc_udev)->uq_flags; |
421 | if (qflags & UQ_SPUR_BUT_UP) | | 424 | if (qflags & UQ_SPUR_BUT_UP) |
422 | sc->sc_flags |= FLAG_DEBOUNCE; | | 425 | sc->sc_flags |= FLAG_DEBOUNCE; |
423 | if (qflags & UQ_APPLE_ISO) | | 426 | if (qflags & UQ_APPLE_ISO) |
424 | sc->sc_flags |= FLAG_APPLE_FIX_ISO; | | 427 | sc->sc_flags |= FLAG_APPLE_FIX_ISO; |
425 | | | 428 | |
| | | 429 | #ifdef GDIUM_KEYBOARD_HACK |
426 | if (uha->uaa->vendor == USB_VENDOR_CYPRESS && | | 430 | if (uha->uaa->vendor == USB_VENDOR_CYPRESS && |
427 | uha->uaa->product == USB_PRODUCT_CYPRESS_LPRDK) | | 431 | uha->uaa->product == USB_PRODUCT_CYPRESS_LPRDK) |
428 | sc->sc_flags = FLAG_GDIUM_FN; | | 432 | sc->sc_flags = FLAG_GDIUM_FN; |
| | | 433 | #endif |
429 | | | 434 | |
430 | #ifdef DIAGNOSTIC | | 435 | #ifdef DIAGNOSTIC |
431 | aprint_normal(": %d modifier keys, %d key codes", sc->sc_nmod, | | 436 | aprint_normal(": %d modifier keys, %d key codes", sc->sc_nmod, |
432 | sc->sc_nkeycode); | | 437 | sc->sc_nkeycode); |
433 | if (sc->sc_flags & FLAG_APPLE_FN) | | 438 | if (sc->sc_flags & FLAG_APPLE_FN) |
434 | aprint_normal(", apple fn key"); | | 439 | aprint_normal(", apple fn key"); |
435 | if (sc->sc_flags & FLAG_APPLE_FIX_ISO) | | 440 | if (sc->sc_flags & FLAG_APPLE_FIX_ISO) |
436 | aprint_normal(", fix apple iso"); | | 441 | aprint_normal(", fix apple iso"); |
437 | if (sc->sc_flags & FLAG_GDIUM_FN) | | 442 | if (sc->sc_flags & FLAG_GDIUM_FN) |
438 | aprint_normal(", Gdium fn key"); | | 443 | aprint_normal(", Gdium fn key"); |
439 | #endif | | 444 | #endif |
440 | aprint_normal("\n"); | | 445 | aprint_normal("\n"); |
441 | | | 446 | |
| @@ -644,32 +649,34 @@ ukbd_intr(struct uhidev *addr, void *ibu | | | @@ -644,32 +649,34 @@ ukbd_intr(struct uhidev *addr, void *ibu |
644 | if (hid_get_data(ibuf, &sc->sc_modloc[i])) | | 649 | if (hid_get_data(ibuf, &sc->sc_modloc[i])) |
645 | ud->modifiers |= sc->sc_mods[i].mask; | | 650 | ud->modifiers |= sc->sc_mods[i].mask; |
646 | memcpy(ud->keycode, (char *)ibuf + sc->sc_keycodeloc.pos / 8, | | 651 | memcpy(ud->keycode, (char *)ibuf + sc->sc_keycodeloc.pos / 8, |
647 | sc->sc_nkeycode); | | 652 | sc->sc_nkeycode); |
648 | | | 653 | |
649 | if (sc->sc_flags & FLAG_APPLE_FN) { | | 654 | if (sc->sc_flags & FLAG_APPLE_FN) { |
650 | if (hid_get_data(ibuf, &sc->sc_apple_fn)) { | | 655 | if (hid_get_data(ibuf, &sc->sc_apple_fn)) { |
651 | sc->sc_flags |= FLAG_FN_PRESSED; | | 656 | sc->sc_flags |= FLAG_FN_PRESSED; |
652 | ukbd_translate_keycodes(sc, ud, trtab_apple_fn); | | 657 | ukbd_translate_keycodes(sc, ud, trtab_apple_fn); |
653 | } | | 658 | } |
654 | else | | 659 | else |
655 | sc->sc_flags &= ~FLAG_FN_PRESSED; | | 660 | sc->sc_flags &= ~FLAG_FN_PRESSED; |
656 | } | | 661 | } |
657 | | | 662 | |
| | | 663 | #ifdef GDIUM_KEYBOARD_HACK |
658 | if (sc->sc_flags & FLAG_GDIUM_FN) { | | 664 | if (sc->sc_flags & FLAG_GDIUM_FN) { |
659 | if (sc->sc_flags & FLAG_FN_PRESSED) { | | 665 | if (sc->sc_flags & FLAG_FN_PRESSED) { |
660 | ukbd_translate_keycodes(sc, ud, trtab_gdium_fn); | | 666 | ukbd_translate_keycodes(sc, ud, trtab_gdium_fn); |
661 | } | | 667 | } |
662 | } | | 668 | } |
| | | 669 | #endif |
663 | | | 670 | |
664 | if ((sc->sc_flags & FLAG_DEBOUNCE) && !(sc->sc_flags & FLAG_POLLING)) { | | 671 | if ((sc->sc_flags & FLAG_DEBOUNCE) && !(sc->sc_flags & FLAG_POLLING)) { |
665 | /* | | 672 | /* |
666 | * Some keyboards have a peculiar quirk. They sometimes | | 673 | * Some keyboards have a peculiar quirk. They sometimes |
667 | * generate a key up followed by a key down for the same | | 674 | * generate a key up followed by a key down for the same |
668 | * key after about 10 ms. | | 675 | * key after about 10 ms. |
669 | * We avoid this bug by holding off decoding for 20 ms. | | 676 | * We avoid this bug by holding off decoding for 20 ms. |
670 | */ | | 677 | */ |
671 | sc->sc_data = *ud; | | 678 | sc->sc_data = *ud; |
672 | callout_reset(&sc->sc_delay, hz / 50, ukbd_delayed_decode, sc); | | 679 | callout_reset(&sc->sc_delay, hz / 50, ukbd_delayed_decode, sc); |
673 | #ifdef DDB | | 680 | #ifdef DDB |
674 | } else if (sc->sc_console_keyboard && !(sc->sc_flags & FLAG_POLLING)) { | | 681 | } else if (sc->sc_console_keyboard && !(sc->sc_flags & FLAG_POLLING)) { |
675 | /* | | 682 | /* |
| @@ -748,52 +755,56 @@ ukbd_decode(struct ukbd_softc *sc, struc | | | @@ -748,52 +755,56 @@ ukbd_decode(struct ukbd_softc *sc, struc |
748 | PRESS : RELEASE); | | 755 | PRESS : RELEASE); |
749 | ADDKEY(ukbd_translate_modifier(sc, key)); | | 756 | ADDKEY(ukbd_translate_modifier(sc, key)); |
750 | } | | 757 | } |
751 | if (memcmp(ud->keycode, sc->sc_odata.keycode, sc->sc_nkeycode) != 0) { | | 758 | if (memcmp(ud->keycode, sc->sc_odata.keycode, sc->sc_nkeycode) != 0) { |
752 | /* Check for released keys. */ | | 759 | /* Check for released keys. */ |
753 | for (i = 0; i < sc->sc_nkeycode; i++) { | | 760 | for (i = 0; i < sc->sc_nkeycode; i++) { |
754 | key = sc->sc_odata.keycode[i]; | | 761 | key = sc->sc_odata.keycode[i]; |
755 | if (key == 0) | | 762 | if (key == 0) |
756 | continue; | | 763 | continue; |
757 | for (j = 0; j < sc->sc_nkeycode; j++) | | 764 | for (j = 0; j < sc->sc_nkeycode; j++) |
758 | if (key == ud->keycode[j]) | | 765 | if (key == ud->keycode[j]) |
759 | goto rfound; | | 766 | goto rfound; |
760 | DPRINTFN(3,("ukbd_intr: relse key=0x%02x\n", key)); | | 767 | DPRINTFN(3,("ukbd_intr: relse key=0x%02x\n", key)); |
| | | 768 | #ifdef GDIUM_KEYBOARD_HACK |
761 | if (sc->sc_flags & FLAG_GDIUM_FN) { | | 769 | if (sc->sc_flags & FLAG_GDIUM_FN) { |
762 | if (key == 0x82) { | | 770 | if (key == 0x82) { |
763 | sc->sc_flags &= ~FLAG_FN_PRESSED; | | 771 | sc->sc_flags &= ~FLAG_FN_PRESSED; |
764 | goto rfound; | | 772 | goto rfound; |
765 | } | | 773 | } |
766 | } | | 774 | } |
| | | 775 | #endif |
767 | ADDKEY(key | RELEASE); | | 776 | ADDKEY(key | RELEASE); |
768 | rfound: | | 777 | rfound: |
769 | ; | | 778 | ; |
770 | } | | 779 | } |
771 | | | 780 | |
772 | /* Check for pressed keys. */ | | 781 | /* Check for pressed keys. */ |
773 | for (i = 0; i < sc->sc_nkeycode; i++) { | | 782 | for (i = 0; i < sc->sc_nkeycode; i++) { |
774 | key = ud->keycode[i]; | | 783 | key = ud->keycode[i]; |
775 | if (key == 0) | | 784 | if (key == 0) |
776 | continue; | | 785 | continue; |
777 | for (j = 0; j < sc->sc_nkeycode; j++) | | 786 | for (j = 0; j < sc->sc_nkeycode; j++) |
778 | if (key == sc->sc_odata.keycode[j]) | | 787 | if (key == sc->sc_odata.keycode[j]) |
779 | goto pfound; | | 788 | goto pfound; |
780 | DPRINTFN(2,("ukbd_intr: press key=0x%02x\n", key)); | | 789 | DPRINTFN(2,("ukbd_intr: press key=0x%02x\n", key)); |
| | | 790 | #ifdef GDIUM_KEYBOARD_HACK |
781 | if (sc->sc_flags & FLAG_GDIUM_FN) { | | 791 | if (sc->sc_flags & FLAG_GDIUM_FN) { |
782 | if (key == 0x82) { | | 792 | if (key == 0x82) { |
783 | sc->sc_flags |= FLAG_FN_PRESSED; | | 793 | sc->sc_flags |= FLAG_FN_PRESSED; |
784 | goto pfound; | | 794 | goto pfound; |
785 | } | | 795 | } |
786 | } | | 796 | } |
| | | 797 | #endif |
787 | ADDKEY(key | PRESS); | | 798 | ADDKEY(key | PRESS); |
788 | pfound: | | 799 | pfound: |
789 | ; | | 800 | ; |
790 | } | | 801 | } |
791 | } | | 802 | } |
792 | sc->sc_odata = *ud; | | 803 | sc->sc_odata = *ud; |
793 | | | 804 | |
794 | if (nkeys == 0) | | 805 | if (nkeys == 0) |
795 | return; | | 806 | return; |
796 | | | 807 | |
797 | if (sc->sc_flags & FLAG_POLLING) { | | 808 | if (sc->sc_flags & FLAG_POLLING) { |
798 | DPRINTFN(1,("ukbd_intr: pollchar = 0x%03x\n", ibuf[0])); | | 809 | DPRINTFN(1,("ukbd_intr: pollchar = 0x%03x\n", ibuf[0])); |
799 | memcpy(sc->sc_pollchars, ibuf, nkeys * sizeof(u_int16_t)); | | 810 | memcpy(sc->sc_pollchars, ibuf, nkeys * sizeof(u_int16_t)); |