Diff for /src/sys/dev/usbmisc/ukbd/ukbd.c between versions 1.3 and 1.4

version 1.3, 2003/08/07 21:17:14 version 1.4, 2003/12/30 01:01:47
Line 1 Line 1
/*        $FreeBSD: src/sys/dev/usb/ukbd.c,v 1.24.2.6 2002/11/06 20:23:50 joe Exp $      *//*
/*        $DragonFly$     */ * $FreeBSD: src/sys/dev/usb/ukbd.c,v 1.45 2003/10/04 21:41:01 joe Exp $
  * $DragonFly$
  */
   
 /*  /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.   * Copyright (c) 1998 The NetBSD Foundation, Inc.
Line 39 Line 41
  */   */
   
 /*  /*
 * HID spec: http://www.usb.org/developers/data/usbhid10.pdf * HID spec: http://www.usb.org/developers/data/devclass/hid1_1.pdf
  */   */
   
 #include "opt_kbd.h"  #include "opt_kbd.h"
Line 51 Line 53
 #include <sys/ioccom.h>  #include <sys/ioccom.h>
 #include <sys/module.h>  #include <sys/module.h>
 #include <sys/bus.h>  #include <sys/bus.h>
 #include <machine/clock.h>  
 #include <sys/file.h>  #include <sys/file.h>
   #if __FreeBSD_version >= 500000
   #include <sys/limits.h>
   #else
   #include <machine/limits.h>
   #endif
   #if __FreeBSD_version >= 500014
   #include <sys/selinfo.h>
   #else
 #include <sys/select.h>  #include <sys/select.h>
#include <sys/proc.h>#endif
 #include <sys/vnode.h>  #include <sys/vnode.h>
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
   
Line 234  ukbd_intr(usbd_xfer_handle xfer, usbd_pr Line 243  ukbd_intr(usbd_xfer_handle xfer, usbd_pr
   
 DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0);  DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0);
   
 #include <machine/limits.h>  
 #include <machine/clock.h>  
   
 #define UKBD_DEFAULT    0  #define UKBD_DEFAULT    0
   
Line 270  Static struct { Line 277  Static struct {
 };  };
   
 #define NN 0                    /* no translation */  #define NN 0                    /* no translation */
/* /*
  * Translate USB keycodes to AT keyboard scancodes.   * Translate USB keycodes to AT keyboard scancodes.
  */   */
 /*  /*
Line 427  Static keymap_t  default_keymap; Line 434  Static keymap_t  default_keymap;
 Static accentmap_t      default_accentmap;  Static accentmap_t      default_accentmap;
 Static fkeytab_t        default_fkeytab[NUM_FKEYS];  Static fkeytab_t        default_fkeytab[NUM_FKEYS];
   
/* /*
  * The back door to the keyboard driver!   * The back door to the keyboard driver!
  * This function is called by the console driver, via the kbdio module,   * This function is called by the console driver, via the kbdio module,
  * to tickle keyboard drivers when the low-level console is being initialized.   * to tickle keyboard drivers when the low-level console is being initialized.
Line 568  ukbd_init(int unit, keyboard_t **kbdp, v Line 575  ukbd_init(int unit, keyboard_t **kbdp, v
                 state->ks_uaa = uaa;                  state->ks_uaa = uaa;
                 state->ks_ifstate = 0;                  state->ks_ifstate = 0;
                 callout_handle_init(&state->ks_timeout_handle);                  callout_handle_init(&state->ks_timeout_handle);
                /*                 /*
                  * FIXME: set the initial value for lock keys in ks_state                   * FIXME: set the initial value for lock keys in ks_state
                  * according to the BIOS data?                   * according to the BIOS data?
                  */                   */
Line 603  ukbd_enable_intr(keyboard_t *kbd, int on Line 610  ukbd_enable_intr(keyboard_t *kbd, int on
                 /* Set up interrupt pipe. */                  /* Set up interrupt pipe. */
                 if (state->ks_ifstate & INTRENABLED)                  if (state->ks_ifstate & INTRENABLED)
                         return EBUSY;                          return EBUSY;
                
                 state->ks_ifstate |= INTRENABLED;                  state->ks_ifstate |= INTRENABLED;
                err = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr,                 err = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr,
                                         USBD_SHORT_XFER_OK,                                          USBD_SHORT_XFER_OK,
                                         &state->ks_intrpipe, kbd,                                          &state->ks_intrpipe, kbd,
                                        &state->ks_ndata,                                         &state->ks_ndata,
                                         sizeof(state->ks_ndata), func,                                          sizeof(state->ks_ndata), func,
                                         USBD_DEFAULT_INTERVAL);                                          USBD_DEFAULT_INTERVAL);
                 if (err)                  if (err)
Line 687  Static int Line 694  Static int
 ukbd_interrupt(keyboard_t *kbd, void *arg)  ukbd_interrupt(keyboard_t *kbd, void *arg)
 {  {
         usbd_status status = (usbd_status)arg;          usbd_status status = (usbd_status)arg;
        ukbd_state_t *state = (ukbd_state_t *)kbd->kb_data;        ukbd_state_t *state;
        struct ukbd_data *ud = &state->ks_ndata;        struct ukbd_data *ud;
         struct timeval tv;          struct timeval tv;
         u_long now;          u_long now;
         int mod, omod;          int mod, omod;
         int key, c;          int key, c;
         int i, j;          int i, j;
   
 #define ADDKEY1(c)              \  
         if (state->ks_inputs < INPUTBUFSIZE) {                          \  
                 state->ks_input[state->ks_inputtail] = (c);             \  
                 ++state->ks_inputs;                                     \  
                 state->ks_inputtail = (state->ks_inputtail + 1)%INPUTBUFSIZE; \  
         }  
   
         DPRINTFN(5, ("ukbd_intr: status=%d\n", status));          DPRINTFN(5, ("ukbd_intr: status=%d\n", status));
         if (status == USBD_CANCELLED)          if (status == USBD_CANCELLED)
                 return 0;                  return 0;
   
           state = (ukbd_state_t *)kbd->kb_data;
           ud = &state->ks_ndata;
   
         if (status != USBD_NORMAL_COMPLETION) {          if (status != USBD_NORMAL_COMPLETION) {
                 DPRINTF(("ukbd_intr: status=%d\n", status));                  DPRINTF(("ukbd_intr: status=%d\n", status));
                usbd_clear_endpoint_stall_async(state->ks_intrpipe);                if (status == USBD_STALLED)
                     usbd_clear_endpoint_stall_async(state->ks_intrpipe);
                 return 0;                  return 0;
         }          }
   
Line 718  ukbd_interrupt(keyboard_t *kbd, void *ar Line 722  ukbd_interrupt(keyboard_t *kbd, void *ar
         getmicrouptime(&tv);          getmicrouptime(&tv);
         now = (u_long)tv.tv_sec*1000 + (u_long)tv.tv_usec/1000;          now = (u_long)tv.tv_sec*1000 + (u_long)tv.tv_usec/1000;
   
   #define ADDKEY1(c)              \
           if (state->ks_inputs < INPUTBUFSIZE) {                          \
                   state->ks_input[state->ks_inputtail] = (c);             \
                   ++state->ks_inputs;                                     \
                   state->ks_inputtail = (state->ks_inputtail + 1)%INPUTBUFSIZE; \
           }
   
         mod = ud->modifiers;          mod = ud->modifiers;
         omod = state->ks_odata.modifiers;          omod = state->ks_odata.modifiers;
         if (mod != omod) {          if (mod != omod) {
                 for (i = 0; i < NMOD; i++)                  for (i = 0; i < NMOD; i++)
                        if (( mod & ukbd_mods[i].mask) !=                         if (( mod & ukbd_mods[i].mask) !=
                             (omod & ukbd_mods[i].mask))                              (omod & ukbd_mods[i].mask))
                                ADDKEY1(ukbd_mods[i].key |                                 ADDKEY1(ukbd_mods[i].key |
                                       (mod & ukbd_mods[i].mask                                        (mod & ukbd_mods[i].mask
                                           ? KEY_PRESS : KEY_RELEASE));                                            ? KEY_PRESS : KEY_RELEASE));
         }          }
   
Line 744  ukbd_interrupt(keyboard_t *kbd, void *ar Line 755  ukbd_interrupt(keyboard_t *kbd, void *ar
         rfound:          rfound:
                 ;                  ;
         }          }
                
         /* Check for pressed keys. */          /* Check for pressed keys. */
         for (i = 0; i < NKEYCODE; i++) {          for (i = 0; i < NKEYCODE; i++) {
                 key = ud->keycode[i];                  key = ud->keycode[i];
Line 837  ukbd_test_if(keyboard_t *kbd) Line 848  ukbd_test_if(keyboard_t *kbd)
         return 0;          return 0;
 }  }
   
/* /*
  * Enable the access to the device; until this function is called,   * Enable the access to the device; until this function is called,
  * the client cannot read from the keyboard.   * the client cannot read from the keyboard.
  */   */
Line 904  ukbd_read(keyboard_t *kbd, int wait) Line 915  ukbd_read(keyboard_t *kbd, int wait)
                                     usbcode & KEY_RELEASE);                                      usbcode & KEY_RELEASE);
         if (scancode & SCAN_PREFIX) {          if (scancode & SCAN_PREFIX) {
                 if (scancode & SCAN_PREFIX_CTL) {                  if (scancode & SCAN_PREFIX_CTL) {
                        state->ks_buffered_char[0] =                         state->ks_buffered_char[0] =
                                 0x1d | (scancode & SCAN_RELEASE); /* Ctrl */                                  0x1d | (scancode & SCAN_RELEASE); /* Ctrl */
                         state->ks_buffered_char[1] = scancode & ~SCAN_PREFIX;                          state->ks_buffered_char[1] = scancode & ~SCAN_PREFIX;
                 } else if (scancode & SCAN_PREFIX_SHIFT) {                  } else if (scancode & SCAN_PREFIX_SHIFT) {
                        state->ks_buffered_char[0] =                         state->ks_buffered_char[0] =
                                 0x2a | (scancode & SCAN_RELEASE); /* Shift */                                  0x2a | (scancode & SCAN_RELEASE); /* Shift */
                        state->ks_buffered_char[1] =                         state->ks_buffered_char[1] =
                                 scancode & ~SCAN_PREFIX_SHIFT;                                  scancode & ~SCAN_PREFIX_SHIFT;
                 } else {                  } else {
                         state->ks_buffered_char[0] = scancode & ~SCAN_PREFIX;                          state->ks_buffered_char[0] = scancode & ~SCAN_PREFIX;
Line 1000  next_code: Line 1011  next_code:
                                             usbcode & KEY_RELEASE);                                              usbcode & KEY_RELEASE);
                 if (scancode & SCAN_PREFIX) {                  if (scancode & SCAN_PREFIX) {
                         if (scancode & SCAN_PREFIX_CTL) {                          if (scancode & SCAN_PREFIX_CTL) {
                                state->ks_buffered_char[0] =                                 state->ks_buffered_char[0] =
                                         0x1d | (scancode & SCAN_RELEASE);                                          0x1d | (scancode & SCAN_RELEASE);
                                 state->ks_buffered_char[1] =                                  state->ks_buffered_char[1] =
                                         scancode & ~SCAN_PREFIX;                                          scancode & ~SCAN_PREFIX;
                         } else if (scancode & SCAN_PREFIX_SHIFT) {                          } else if (scancode & SCAN_PREFIX_SHIFT) {
                                state->ks_buffered_char[0] =                                 state->ks_buffered_char[0] =
                                         0x2a | (scancode & SCAN_RELEASE);                                          0x2a | (scancode & SCAN_RELEASE);
                                 state->ks_buffered_char[1] =                                  state->ks_buffered_char[1] =
                                         scancode & ~SCAN_PREFIX_SHIFT;                                          scancode & ~SCAN_PREFIX_SHIFT;
Line 1167  ukbd_ioctl(keyboard_t *kbd, u_long cmd, Line 1178  ukbd_ioctl(keyboard_t *kbd, u_long cmd,
                                 state->ks_state &= ~LOCK_MASK;                                  state->ks_state &= ~LOCK_MASK;
                                 state->ks_state |= KBD_LED_VAL(kbd);                                  state->ks_state |= KBD_LED_VAL(kbd);
                         }                          }
                        /* FALL THROUGH */                        /* FALLTHROUGH */
                 case K_RAW:                  case K_RAW:
                 case K_CODE:                  case K_CODE:
                         if (state->ks_mode != *(int *)arg) {                          if (state->ks_mode != *(int *)arg) {
Line 1242  ukbd_ioctl(keyboard_t *kbd, u_long cmd, Line 1253  ukbd_ioctl(keyboard_t *kbd, u_long cmd,
         case PIO_KEYMAPENT:     /* set keyboard translation table entry */          case PIO_KEYMAPENT:     /* set keyboard translation table entry */
         case PIO_DEADKEYMAP:    /* set accent key translation table */          case PIO_DEADKEYMAP:    /* set accent key translation table */
                 state->ks_accents = 0;                  state->ks_accents = 0;
                /* FALL THROUGH */                /* FALLTHROUGH */
         default:          default:
                 splx(s);                  splx(s);
                 return genkbd_commonioctl(kbd, cmd, arg);                  return genkbd_commonioctl(kbd, cmd, arg);
Line 1314  Static int Line 1325  Static int
 ukbd_poll(keyboard_t *kbd, int on)  ukbd_poll(keyboard_t *kbd, int on)
 {  {
         ukbd_state_t *state;          ukbd_state_t *state;
           usbd_device_handle dev;
         int s;          int s;
   
         state = (ukbd_state_t *)kbd->kb_data;          state = (ukbd_state_t *)kbd->kb_data;
           usbd_interface2device_handle(state->ks_iface, &dev);
   
         s = splusb();          s = splusb();
         if (on) {          if (on) {
                 if (state->ks_polling == 0)                  if (state->ks_polling == 0)
                        usbd_set_polling(state->ks_iface, on);                        usbd_set_polling(dev, on);
                 ++state->ks_polling;                  ++state->ks_polling;
         } else {          } else {
                 --state->ks_polling;                  --state->ks_polling;
                 if (state->ks_polling == 0)                  if (state->ks_polling == 0)
                        usbd_set_polling(state->ks_iface, on);                        usbd_set_polling(dev, on);
         }          }
         splx(s);          splx(s);
         return 0;          return 0;
Line 1338  Static int Line 1351  Static int
 probe_keyboard(struct usb_attach_arg *uaa, int flags)  probe_keyboard(struct usb_attach_arg *uaa, int flags)
 {  {
         usb_interface_descriptor_t *id;          usb_interface_descriptor_t *id;
        
         if (!uaa->iface)        /* we attach to ifaces only */          if (!uaa->iface)        /* we attach to ifaces only */
                 return EINVAL;                  return EINVAL;
   
Line 1358  init_keyboard(ukbd_state_t *state, int * Line 1371  init_keyboard(ukbd_state_t *state, int *
 {  {
         usb_endpoint_descriptor_t *ed;          usb_endpoint_descriptor_t *ed;
         usbd_status err;          usbd_status err;
        
         *type = KB_OTHER;          *type = KB_OTHER;
   
         state->ks_ifstate |= DISCONNECTED;          state->ks_ifstate |= DISCONNECTED;
Line 1431  Static int Line 1444  Static int
 keycode2scancode(int keycode, int shift, int up)  keycode2scancode(int keycode, int shift, int up)
 {  {
         static int scan[] = {          static int scan[] = {
                0x1c, 0x1d, 0x35,                 0x1c, 0x1d, 0x35,
                 0x37 | SCAN_PREFIX_SHIFT, /* PrintScreen */                  0x37 | SCAN_PREFIX_SHIFT, /* PrintScreen */
                0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,                 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
                0x50, 0x51, 0x52, 0x53,                 0x50, 0x51, 0x52, 0x53,
                 0x46,   /* XXX Pause/Break */                  0x46,   /* XXX Pause/Break */
                 0x5b, 0x5c, 0x5d,                  0x5b, 0x5c, 0x5d,
         };          };

Removed from v.1.3  
changed lines
  Added in v.1.4