Diff for /src/sys/dev/usbmisc/ums/ums.c between versions 1.5 and 1.6

version 1.5, 2003/08/07 21:17:15 version 1.6, 2003/12/30 01:01:47
Line 1 Line 1
/*        $FreeBSD: src/sys/dev/usb/ums.c,v 1.36.2.6 2002/11/06 20:23:50 joe Exp $  *//*
/*        $DragonFly$     */ * $FreeBSD: src/sys/dev/usb/ums.c,v 1.64 2003/11/09 09:17:22 tanimura 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 <sys/param.h>  #include <sys/param.h>
Line 52 Line 54
 #include <sys/conf.h>  #include <sys/conf.h>
 #include <sys/tty.h>  #include <sys/tty.h>
 #include <sys/file.h>  #include <sys/file.h>
   #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/poll.h>  #include <sys/poll.h>
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
Line 67 Line 72
 #include <bus/usb/usb_quirks.h>  #include <bus/usb/usb_quirks.h>
 #include <bus/usb/hid.h>  #include <bus/usb/hid.h>
   
   #if __FreeBSD_version >= 500000
   #include <sys/mouse.h>
   #else
 #include <machine/mouse.h>  #include <machine/mouse.h>
   #endif
   
 #ifdef USB_DEBUG  #ifdef USB_DEBUG
 #define DPRINTF(x)      if (umsdebug) logprintf x  #define DPRINTF(x)      if (umsdebug) logprintf x
Line 83  SYSCTL_INT(_hw_usb_ums, OID_AUTO, debug, Line 92  SYSCTL_INT(_hw_usb_ums, OID_AUTO, debug,
   
 #define UMSUNIT(s)      (minor(s)&0x1f)  #define UMSUNIT(s)      (minor(s)&0x1f)
   
#define MS_TO_TICKS(ms) ((ms) * hz / 1000)                            #define MS_TO_TICKS(ms) ((ms) * hz / 1000)
   
 #define QUEUE_BUFSIZE   400     /* MUST be divisible by 5 _and_ 8 */  #define QUEUE_BUFSIZE   400     /* MUST be divisible by 5 _and_ 8 */
   
Line 99  struct ums_softc { Line 108  struct ums_softc {
         struct hid_location sc_loc_x, sc_loc_y, sc_loc_z;          struct hid_location sc_loc_x, sc_loc_y, sc_loc_z;
         struct hid_location *sc_loc_btn;          struct hid_location *sc_loc_btn;
   
        struct callout_handle  timeout_handle;     /* for spurious button ups */        usb_callout_t callout_handle;     /* for spurious button ups */
   
         int sc_enabled;          int sc_enabled;
         int sc_disconnected;    /* device is gone */          int sc_disconnected;    /* device is gone */
Line 174  USB_MATCH(ums) Line 183  USB_MATCH(ums)
         int size, ret;          int size, ret;
         void *desc;          void *desc;
         usbd_status err;          usbd_status err;
        
         if (!uaa->iface)          if (!uaa->iface)
                 return (UMATCH_NONE);                  return (UMATCH_NONE);
         id = usbd_get_interface_descriptor(uaa->iface);          id = usbd_get_interface_descriptor(uaa->iface);
         if (!id || id->bInterfaceClass != UICLASS_HID)          if (!id || id->bInterfaceClass != UICLASS_HID)
                 return (UMATCH_NONE);                  return (UMATCH_NONE);
   
        err = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP);        err = usbd_read_report_desc(uaa->iface, &desc, &size, M_TEMP);
         if (err)          if (err)
                 return (UMATCH_NONE);                  return (UMATCH_NONE);
   
        if (hid_is_collection(desc, size,         if (hid_is_collection(desc, size,
                               HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))                                HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
                 ret = UMATCH_IFACECLASS;                  ret = UMATCH_IFACECLASS;
         else          else
Line 208  USB_ATTACH(ums) Line 217  USB_ATTACH(ums)
         u_int32_t flags;          u_int32_t flags;
         int i;          int i;
         struct hid_location loc_btn;          struct hid_location loc_btn;
        
         sc->sc_disconnected = 1;          sc->sc_disconnected = 1;
         sc->sc_iface = iface;          sc->sc_iface = iface;
         id = usbd_get_interface_descriptor(iface);          id = usbd_get_interface_descriptor(iface);
Line 226  USB_ATTACH(ums) Line 235  USB_ATTACH(ums)
         DPRINTFN(10,("ums_attach: bLength=%d bDescriptorType=%d "          DPRINTFN(10,("ums_attach: bLength=%d bDescriptorType=%d "
                      "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"                       "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
                      " bInterval=%d\n",                       " bInterval=%d\n",
                     ed->bLength, ed->bDescriptorType,                      ed->bLength, ed->bDescriptorType,
                      UE_GET_ADDR(ed->bEndpointAddress),                       UE_GET_ADDR(ed->bEndpointAddress),
                      UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? "in":"out",                       UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? "in":"out",
                      UE_GET_XFERTYPE(ed->bmAttributes),                       UE_GET_XFERTYPE(ed->bmAttributes),
Line 239  USB_ATTACH(ums) Line 248  USB_ATTACH(ums)
                 USB_ATTACH_ERROR_RETURN;                  USB_ATTACH_ERROR_RETURN;
         }          }
   
        err = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP);        err = usbd_read_report_desc(uaa->iface, &desc, &size, M_TEMP);
         if (err)          if (err)
                 USB_ATTACH_ERROR_RETURN;                  USB_ATTACH_ERROR_RETURN;
   
Line 283  USB_ATTACH(ums) Line 292  USB_ATTACH(ums)
                                 hid_input, &loc_btn, 0))                                  hid_input, &loc_btn, 0))
                         break;                          break;
         sc->nbuttons = i - 1;          sc->nbuttons = i - 1;
        sc->sc_loc_btn = malloc(sizeof(struct hid_location)*sc->nbuttons,         sc->sc_loc_btn = malloc(sizeof(struct hid_location)*sc->nbuttons,
                                 M_USBDEV, M_NOWAIT);                                  M_USBDEV, M_NOWAIT);
         if (!sc->sc_loc_btn) {          if (!sc->sc_loc_btn) {
                 printf("%s: no memory\n", USBDEVNAME(sc->sc_dev));                  printf("%s: no memory\n", USBDEVNAME(sc->sc_dev));
Line 311  USB_ATTACH(ums) Line 320  USB_ATTACH(ums)
   
 #ifdef USB_DEBUG  #ifdef USB_DEBUG
         DPRINTF(("ums_attach: sc=%p\n", sc));          DPRINTF(("ums_attach: sc=%p\n", sc));
        DPRINTF(("ums_attach: X\t%d/%d\n",         DPRINTF(("ums_attach: X\t%d/%d\n",
                  sc->sc_loc_x.pos, sc->sc_loc_x.size));                   sc->sc_loc_x.pos, sc->sc_loc_x.size));
        DPRINTF(("ums_attach: Y\t%d/%d\n",         DPRINTF(("ums_attach: Y\t%d/%d\n",
                  sc->sc_loc_y.pos, sc->sc_loc_y.size));                   sc->sc_loc_y.pos, sc->sc_loc_y.size));
         if (sc->flags & UMS_Z)          if (sc->flags & UMS_Z)
                DPRINTF(("ums_attach: Z\t%d/%d\n",                 DPRINTF(("ums_attach: Z\t%d/%d\n",
                          sc->sc_loc_z.pos, sc->sc_loc_z.size));                           sc->sc_loc_z.pos, sc->sc_loc_z.size));
         for (i = 1; i <= sc->nbuttons; i++) {          for (i = 1; i <= sc->nbuttons; i++) {
                 DPRINTF(("ums_attach: B%d\t%d/%d\n",                  DPRINTF(("ums_attach: B%d\t%d/%d\n",
Line 346  USB_ATTACH(ums) Line 355  USB_ATTACH(ums)
         sc->status.button = sc->status.obutton = 0;          sc->status.button = sc->status.obutton = 0;
         sc->status.dx = sc->status.dy = sc->status.dz = 0;          sc->status.dx = sc->status.dy = sc->status.dz = 0;
   
   #ifndef __FreeBSD__
         sc->rsel.si_flags = 0;          sc->rsel.si_flags = 0;
         sc->rsel.si_pid = 0;          sc->rsel.si_pid = 0;
   #endif
   
         sc->dev = make_dev(&ums_cdevsw, device_get_unit(self),          sc->dev = make_dev(&ums_cdevsw, device_get_unit(self),
                         UID_ROOT, GID_OPERATOR,                          UID_ROOT, GID_OPERATOR,
Line 367  Static int Line 378  Static int
 ums_detach(device_t self)  ums_detach(device_t self)
 {  {
         struct ums_softc *sc = device_get_softc(self);          struct ums_softc *sc = device_get_softc(self);
         struct vnode *vp;  
   
         if (sc->sc_enabled)          if (sc->sc_enabled)
                 ums_disable(sc);                  ums_disable(sc);
Line 377  ums_detach(device_t self) Line 387  ums_detach(device_t self)
         free(sc->sc_loc_btn, M_USB);          free(sc->sc_loc_btn, M_USB);
         free(sc->sc_ibuf, M_USB);          free(sc->sc_ibuf, M_USB);
   
         vp = SLIST_FIRST(&sc->dev->si_hlist);  
         if (vp)  
                 VOP_REVOKE(vp, REVOKEALL);  
   
         /* someone waiting for data */          /* someone waiting for data */
         /*          /*
          * XXX If we wakeup the process here, the device will be gone by           * XXX If we wakeup the process here, the device will be gone by
Line 395  ums_detach(device_t self) Line 401  ums_detach(device_t self)
         }          }
         if (sc->state & UMS_SELECT) {          if (sc->state & UMS_SELECT) {
                 sc->state &= ~UMS_SELECT;                  sc->state &= ~UMS_SELECT;
                selwakeup(&sc->rsel);                selwakeuppri(&sc->rsel, PZERO);
         }          }
   
         destroy_dev(sc->dev);          destroy_dev(sc->dev);
Line 426  ums_intr(xfer, addr, status) Line 432  ums_intr(xfer, addr, status)
   
         if (status != USBD_NORMAL_COMPLETION) {          if (status != USBD_NORMAL_COMPLETION) {
                 DPRINTF(("ums_intr: status=%d\n", status));                  DPRINTF(("ums_intr: status=%d\n", status));
                usbd_clear_endpoint_stall_async(sc->sc_intrpipe);                if (status == USBD_STALLED)
                     usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
                 return;                  return;
         }          }
   
Line 469  ums_intr(xfer, addr, status) Line 476  ums_intr(xfer, addr, status)
                  */                   */
                 if (sc->flags & UMS_SPUR_BUT_UP &&                  if (sc->flags & UMS_SPUR_BUT_UP &&
                     dx == 0 && dy == 0 && dz == 0 && buttons == 0) {                      dx == 0 && dy == 0 && dz == 0 && buttons == 0) {
                        usb_timeout(ums_add_to_queue_timeout, (void *) sc,                        usb_callout(sc->callout_handle, MS_TO_TICKS(50 /*msecs*/),
                                MS_TO_TICKS(50 /*msecs*/), sc->timeout_handle);                                    ums_add_to_queue_timeout, (void *) sc);
                 } else {                  } else {
                        usb_untimeout(ums_add_to_queue_timeout, (void *) sc,                        usb_uncallout(sc->callout_handle,
                                sc->timeout_handle);                                      ums_add_to_queue_timeout, (void *) sc);
 
                         ums_add_to_queue(sc, dx, dy, dz, buttons);                          ums_add_to_queue(sc, dx, dy, dz, buttons);
                 }                  }
         }          }
Line 534  ums_add_to_queue(struct ums_softc *sc, i Line 540  ums_add_to_queue(struct ums_softc *sc, i
         }          }
         if (sc->state & UMS_SELECT) {          if (sc->state & UMS_SELECT) {
                 sc->state &= ~UMS_SELECT;                  sc->state &= ~UMS_SELECT;
                selwakeup(&sc->rsel);                selwakeuppri(&sc->rsel, PZERO);
         }          }
 }  }
 Static int  Static int
Line 555  ums_enable(v) Line 561  ums_enable(v)
         sc->status.button = sc->status.obutton = 0;          sc->status.button = sc->status.obutton = 0;
         sc->status.dx = sc->status.dy = sc->status.dz = 0;          sc->status.dx = sc->status.dy = sc->status.dz = 0;
   
        callout_handle_init(&sc->timeout_handle);        callout_handle_init((struct callout_handle *)&sc->callout_handle);
   
         /* Set up interrupt pipe. */          /* Set up interrupt pipe. */
        err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,         err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
                                USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc,                                 USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc,
                                 sc->sc_ibuf, sc->sc_isize, ums_intr,                                  sc->sc_ibuf, sc->sc_isize, ums_intr,
                                 USBD_DEFAULT_INTERVAL);                                  USBD_DEFAULT_INTERVAL);
         if (err) {          if (err) {
Line 577  ums_disable(priv) Line 583  ums_disable(priv)
 {  {
         struct ums_softc *sc = priv;          struct ums_softc *sc = priv;
   
        usb_untimeout(ums_add_to_queue_timeout, sc, sc->timeout_handle);        usb_uncallout(sc->callout_handle, ums_add_to_queue_timeout, sc);
   
         /* Disable interrupts. */          /* Disable interrupts. */
         usbd_abort_pipe(sc->sc_intrpipe);          usbd_abort_pipe(sc->sc_intrpipe);
Line 637  ums_read(dev_t dev, struct uio *uio, int Line 643  ums_read(dev_t dev, struct uio *uio, int
                         splx(s);                          splx(s);
                         return EWOULDBLOCK;                          return EWOULDBLOCK;
                 }                  }
                
                 sc->state |= UMS_ASLEEP;        /* blocking I/O */                  sc->state |= UMS_ASLEEP;        /* blocking I/O */
                 error = tsleep(sc, PCATCH, "umsrea", 0);                  error = tsleep(sc, PCATCH, "umsrea", 0);
                 if (error) {                  if (error) {
Line 710  ums_poll(dev_t dev, int events, usb_proc Line 716  ums_poll(dev_t dev, int events, usb_proc
   
         return revents;          return revents;
 }  }
        
 int  int
 ums_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)  ums_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
 {  {

Removed from v.1.5  
changed lines
  Added in v.1.6