[BACK]Return to usbdi.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / usb

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/dev/usb/usbdi.c between version 1.43 and 1.43.2.1

version 1.43, 1999/09/15 21:08:59 version 1.43.2.1, 1999/12/27 18:35:46
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   /*      $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $      */
   
 /*  /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.   * Copyright (c) 1998 The NetBSD Foundation, Inc.
Line 39 
Line 40 
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/systm.h>  #include <sys/systm.h>
 #include <sys/kernel.h>  
 #if defined(__NetBSD__) || defined(__OpenBSD__)  #if defined(__NetBSD__) || defined(__OpenBSD__)
   #include <sys/kernel.h>
 #include <sys/device.h>  #include <sys/device.h>
 #else  #elif defined(__FreeBSD__)
 #include <sys/module.h>  #include <sys/module.h>
 #include <sys/bus.h>  #include <sys/bus.h>
 #include <sys/conf.h>  #include <sys/conf.h>
   #include "usb_if.h"
   #if defined(DIAGNOSTIC) && defined(__i386__)
   #include <machine/cpu.h>
   #endif
 #endif  #endif
 #include <sys/malloc.h>  #include <sys/malloc.h>
 #include <sys/proc.h>  #include <sys/proc.h>
Line 61 
Line 66 
 #if defined(__FreeBSD__)  #if defined(__FreeBSD__)
 #include "usb_if.h"  #include "usb_if.h"
 #endif  #endif
   
 #ifdef USB_DEBUG  #ifdef USB_DEBUG
 #define DPRINTF(x)      if (usbdebug) logprintf x  #define DPRINTF(x)      if (usbdebug) logprintf x
 #define DPRINTFN(n,x)   if (usbdebug>(n)) logprintf x  #define DPRINTFN(n,x)   if (usbdebug>(n)) logprintf x
Line 72  extern int usbdebug;
Line 77  extern int usbdebug;
 #endif  #endif
   
 static usbd_status usbd_ar_pipe  __P((usbd_pipe_handle pipe));  static usbd_status usbd_ar_pipe  __P((usbd_pipe_handle pipe));
 void usbd_do_request_async_cb  static void usbd_do_request_async_cb
         __P((usbd_request_handle, usbd_private_handle, usbd_status));          __P((usbd_xfer_handle, usbd_private_handle, usbd_status));
 void usbd_start_next __P((usbd_pipe_handle pipe));  static void usbd_start_next __P((usbd_pipe_handle pipe));
   
 static SIMPLEQ_HEAD(, usbd_request) usbd_free_requests;  static SIMPLEQ_HEAD(, usbd_xfer) usbd_free_xfers =
           SIMPLEQ_HEAD_INITIALIZER(usbd_free_xfers);
   
 #if defined(__FreeBSD__)  static int usbd_nbuses = 0;
 #define USB_CDEV_MAJOR  108  
   
 extern struct cdevsw usb_cdevsw;  void
 #endif  usbd_init()
   {
           usbd_nbuses++;
   }
   
   void
   usbd_finish()
   {
           usbd_xfer_handle xfer;
   
           if (--usbd_nbuses == 0) {
                   /* Last controller is gone, free all xfers. */
                   for (;;) {
                           xfer = SIMPLEQ_FIRST(&usbd_free_xfers);
                           if (xfer == NULL)
                                   break;
                           SIMPLEQ_REMOVE_HEAD(&usbd_free_xfers, xfer, next);
                           free(xfer, M_USB);
                   }
           }
   }
   
 static __inline int usbd_reqh_isread __P((usbd_request_handle reqh));  static __inline int usbd_xfer_isread __P((usbd_xfer_handle xfer));
 static __inline int  static __inline int
 usbd_reqh_isread(reqh)  usbd_xfer_isread(xfer)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
 {  {
         if (reqh->rqflags & URQ_REQUEST)          if (xfer->rqflags & URQ_REQUEST)
                 return (reqh->request.bmRequestType & UT_READ);                  return (xfer->request.bmRequestType & UT_READ);
         else          else
                 return (reqh->pipe->endpoint->edesc->bEndpointAddress &                  return (xfer->pipe->endpoint->edesc->bEndpointAddress &
                         UE_DIR_IN);                          UE_DIR_IN);
 }  }
   
Line 103  void
Line 128  void
 usbd_dump_queue(pipe)  usbd_dump_queue(pipe)
         usbd_pipe_handle pipe;          usbd_pipe_handle pipe;
 {  {
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
   
         printf("usbd_dump_queue: pipe=%p\n", pipe);          printf("usbd_dump_queue: pipe=%p\n", pipe);
         for (reqh = SIMPLEQ_FIRST(&pipe->queue);          for (xfer = SIMPLEQ_FIRST(&pipe->queue);
              reqh;               xfer;
              reqh = SIMPLEQ_NEXT(reqh, next)) {               xfer = SIMPLEQ_NEXT(xfer, next)) {
                 printf("  reqh=%p\n", reqh);                  printf("  xfer=%p\n", xfer);
         }          }
 }  }
 #endif  #endif
Line 123  usbd_open_pipe(iface, address, flags, pi
Line 148  usbd_open_pipe(iface, address, flags, pi
 {  {
         usbd_pipe_handle p;          usbd_pipe_handle p;
         struct usbd_endpoint *ep;          struct usbd_endpoint *ep;
         usbd_status r;          usbd_status err;
         int i;          int i;
   
           DPRINTFN(3,("usbd_open_pipe: address=0x%x flags=0x%x\n", address,
                       flags));
   
         for (i = 0; i < iface->idesc->bNumEndpoints; i++) {          for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
                 ep = &iface->endpoints[i];                  ep = &iface->endpoints[i];
                   if (ep->edesc == NULL)
                           return (USBD_IOERROR);
                 if (ep->edesc->bEndpointAddress == address)                  if (ep->edesc->bEndpointAddress == address)
                         goto found;                          goto found;
         }          }
Line 136  usbd_open_pipe(iface, address, flags, pi
Line 166  usbd_open_pipe(iface, address, flags, pi
         if ((flags & USBD_EXCLUSIVE_USE) &&          if ((flags & USBD_EXCLUSIVE_USE) &&
             ep->refcnt != 0)              ep->refcnt != 0)
                 return (USBD_IN_USE);                  return (USBD_IN_USE);
         r = usbd_setup_pipe(iface->device, iface, ep, &p);          err = usbd_setup_pipe(iface->device, iface, ep, &p);
         if (r != USBD_NORMAL_COMPLETION)          if (err)
                 return (r);                  return (err);
         LIST_INSERT_HEAD(&iface->pipes, p, next);          LIST_INSERT_HEAD(&iface->pipes, p, next);
         *pipe = p;          *pipe = p;
         return (USBD_NORMAL_COMPLETION);          return (USBD_NORMAL_COMPLETION);
Line 155  usbd_open_pipe_intr(iface, address, flag
Line 185  usbd_open_pipe_intr(iface, address, flag
         u_int32_t length;          u_int32_t length;
         usbd_callback cb;          usbd_callback cb;
 {  {
         usbd_status r;          usbd_status err;
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
         usbd_pipe_handle ipipe;          usbd_pipe_handle ipipe;
   
         r = usbd_open_pipe(iface, address, USBD_EXCLUSIVE_USE, &ipipe);          DPRINTFN(3,("usbd_open_pipe_intr: address=0x%x flags=0x%x length=%d\n",
         if (r != USBD_NORMAL_COMPLETION)                      address, flags, length));
                 return (r);  
         reqh = usbd_alloc_request(iface->device);          err = usbd_open_pipe(iface, address, USBD_EXCLUSIVE_USE, &ipipe);
         if (reqh == 0) {          if (err)
                 r = USBD_NOMEM;                  return (err);
           xfer = usbd_alloc_xfer(iface->device);
           if (xfer == NULL) {
                   err = USBD_NOMEM;
                 goto bad1;                  goto bad1;
         }          }
         usbd_setup_request(reqh, ipipe, priv, buffer, length, flags,          usbd_setup_xfer(xfer, ipipe, priv, buffer, length, flags,
                            USBD_NO_TIMEOUT, cb);                             USBD_NO_TIMEOUT, cb);
         ipipe->intrreqh = reqh;          ipipe->intrxfer = xfer;
         ipipe->repeat = 1;          ipipe->repeat = 1;
         r = usbd_transfer(reqh);          err = usbd_transfer(xfer);
         *pipe = ipipe;          *pipe = ipipe;
         if (r != USBD_IN_PROGRESS)          if (err != USBD_IN_PROGRESS)
                 goto bad2;                  goto bad2;
         return (USBD_NORMAL_COMPLETION);          return (USBD_NORMAL_COMPLETION);
   
  bad2:   bad2:
         ipipe->intrreqh = 0;          ipipe->intrxfer = NULL;
         ipipe->repeat = 0;          ipipe->repeat = 0;
         usbd_free_request(reqh);          usbd_free_xfer(xfer);
  bad1:   bad1:
         usbd_close_pipe(ipipe);          usbd_close_pipe(ipipe);
         return r;          return (err);
 }  }
   
 usbd_status  usbd_status
Line 191  usbd_close_pipe(pipe)
Line 224  usbd_close_pipe(pipe)
         usbd_pipe_handle pipe;          usbd_pipe_handle pipe;
 {  {
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if (pipe == 0) {          if (pipe == NULL) {
                 printf("usbd_close_pipe: pipe==NULL\n");                  printf("usbd_close_pipe: pipe==NULL\n");
                 return (USBD_NORMAL_COMPLETION);                  return (USBD_NORMAL_COMPLETION);
         }          }
Line 204  usbd_close_pipe(pipe)
Line 237  usbd_close_pipe(pipe)
         LIST_REMOVE(pipe, next);          LIST_REMOVE(pipe, next);
         pipe->endpoint->refcnt--;          pipe->endpoint->refcnt--;
         pipe->methods->close(pipe);          pipe->methods->close(pipe);
         if (pipe->intrreqh)          if (pipe->intrxfer != NULL)
                 usbd_free_request(pipe->intrreqh);                  usbd_free_xfer(pipe->intrxfer);
         free(pipe, M_USB);          free(pipe, M_USB);
         return (USBD_NORMAL_COMPLETION);          return (USBD_NORMAL_COMPLETION);
 }  }
   
 usbd_status  usbd_status
 usbd_transfer(reqh)  usbd_transfer(xfer)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
 {  {
         usbd_pipe_handle pipe = reqh->pipe;          usbd_pipe_handle pipe = xfer->pipe;
         usb_dma_t *dmap = &reqh->dmabuf;          usb_dma_t *dmap = &xfer->dmabuf;
         usbd_status r;          usbd_status err;
         u_int size;          u_int size;
         int s;          int s;
   
         DPRINTFN(5,("usbd_transfer: reqh=%p, flags=%d, pipe=%p, running=%d\n",          DPRINTFN(5,("usbd_transfer: xfer=%p, flags=%d, pipe=%p, running=%d\n",
                     reqh, reqh->flags, pipe, pipe->running));                      xfer, xfer->flags, pipe, pipe->running));
 #ifdef USB_DEBUG  #ifdef USB_DEBUG
         if (usbdebug > 5)          if (usbdebug > 5)
                 usbd_dump_queue(pipe);                  usbd_dump_queue(pipe);
 #endif  #endif
         reqh->done = 0;          xfer->done = 0;
   
         size = reqh->length;          size = xfer->length;
         /* If there is no buffer, allocate one. */          /* If there is no buffer, allocate one. */
         if (!(reqh->rqflags & URQ_DEV_DMABUF) && size != 0) {          if (!(xfer->rqflags & URQ_DEV_DMABUF) && size != 0) {
                 struct usbd_bus *bus = pipe->device->bus;                  struct usbd_bus *bus = pipe->device->bus;
   
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
                 if (reqh->rqflags & URQ_AUTO_DMABUF)                  if (xfer->rqflags & URQ_AUTO_DMABUF)
                         printf("usbd_transfer: has old buffer!\n");                          printf("usbd_transfer: has old buffer!\n");
 #endif  #endif
                 r = bus->methods->allocm(bus, dmap, size);                  err = bus->methods->allocm(bus, dmap, size);
                 if (r != USBD_NORMAL_COMPLETION)                  if (err)
                         return (r);                          return (err);
                 reqh->rqflags |= URQ_AUTO_DMABUF;                  xfer->rqflags |= URQ_AUTO_DMABUF;
         }          }
   
         /* Copy data if going out. */          /* Copy data if going out. */
         if (!(reqh->flags & USBD_NO_COPY) && size != 0 &&          if (!(xfer->flags & USBD_NO_COPY) && size != 0 &&
             !usbd_reqh_isread(reqh))              !usbd_xfer_isread(xfer))
                 memcpy(KERNADDR(dmap), reqh->buffer, size);                  memcpy(KERNADDR(dmap), xfer->buffer, size);
   
         r = pipe->methods->transfer(reqh);          err = pipe->methods->transfer(xfer);
   
         if (r != USBD_IN_PROGRESS && r != USBD_NORMAL_COMPLETION) {          if (err != USBD_IN_PROGRESS && err) {
                 /* The transfer has not been queued, so free buffer. */                  /* The transfer has not been queued, so free buffer. */
                 if (reqh->rqflags & URQ_AUTO_DMABUF) {                  if (xfer->rqflags & URQ_AUTO_DMABUF) {
                         struct usbd_bus *bus = pipe->device->bus;                          struct usbd_bus *bus = pipe->device->bus;
   
                         bus->methods->freem(bus, &reqh->dmabuf);                          bus->methods->freem(bus, &xfer->dmabuf);
                         reqh->rqflags &= ~URQ_AUTO_DMABUF;                          xfer->rqflags &= ~URQ_AUTO_DMABUF;
                 }                  }
         }          }
   
         if (!(reqh->flags & USBD_SYNCHRONOUS))          if (!(xfer->flags & USBD_SYNCHRONOUS))
                 return (r);                  return (err);
   
         /* Sync transfer, wait for completion. */          /* Sync transfer, wait for completion. */
         if (r != USBD_IN_PROGRESS)          if (err != USBD_IN_PROGRESS)
                 return (r);                  return (err);
         s = splusb();          s = splusb();
         if (!reqh->done) {          if (!xfer->done) {
                 if (pipe->device->bus->use_polling)                  if (pipe->device->bus->use_polling)
                         panic("usbd_transfer: not done\n");                          panic("usbd_transfer: not done\n");
                 tsleep(reqh, PRIBIO, "usbsyn", 0);                  tsleep(xfer, PRIBIO, "usbsyn", 0);
         }          }
         splx(s);          splx(s);
         return (reqh->status);          return (xfer->status);
 }  }
   
 /* Like usbd_transfer(), but waits for completion. */  /* Like usbd_transfer(), but waits for completion. */
 usbd_status  usbd_status
 usbd_sync_transfer(reqh)  usbd_sync_transfer(xfer)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
 {  {
         reqh->flags |= USBD_SYNCHRONOUS;          xfer->flags |= USBD_SYNCHRONOUS;
         return (usbd_transfer(reqh));          return (usbd_transfer(xfer));
 }  }
   
 void *  void *
 usbd_alloc_buffer(reqh, size)  usbd_alloc_buffer(xfer, size)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
         u_int32_t size;          u_int32_t size;
 {  {
         struct usbd_bus *bus = reqh->device->bus;          struct usbd_bus *bus = xfer->device->bus;
         usbd_status r;          usbd_status err;
   
         r = bus->methods->allocm(bus, &reqh->dmabuf, size);          err = bus->methods->allocm(bus, &xfer->dmabuf, size);
         if (r != USBD_NORMAL_COMPLETION)          if (err)
                 return (0);                  return (0);
         reqh->rqflags |= URQ_DEV_DMABUF;          xfer->rqflags |= URQ_DEV_DMABUF;
         return (KERNADDR(&reqh->dmabuf));          return (KERNADDR(&xfer->dmabuf));
 }  }
   
 void  void
 usbd_free_buffer(reqh)  usbd_free_buffer(xfer)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
 {  {
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if (!(reqh->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) {          if (!(xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) {
                 printf("usbd_free_buffer: no buffer\n");                  printf("usbd_free_buffer: no buffer\n");
                 return;                  return;
         }          }
 #endif  #endif
         reqh->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF);          xfer->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF);
         reqh->device->bus->methods->freem(reqh->device->bus, &reqh->dmabuf);          xfer->device->bus->methods->freem(xfer->device->bus, &xfer->dmabuf);
 }  }
   
 void *  void *
 usbd_get_buffer(reqh)  usbd_get_buffer(xfer)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
 {  {
         if (!(reqh->rqflags & URQ_DEV_DMABUF))          if (!(xfer->rqflags & URQ_DEV_DMABUF))
                 return (0);                  return (0);
         return (KERNADDR(&reqh->dmabuf));          return (KERNADDR(&xfer->dmabuf));
 }  }
   
 usbd_request_handle  usbd_xfer_handle
 usbd_alloc_request(dev)  usbd_alloc_xfer(dev)
         usbd_device_handle dev;          usbd_device_handle dev;
 {  {
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
   
         reqh = SIMPLEQ_FIRST(&usbd_free_requests);          xfer = SIMPLEQ_FIRST(&usbd_free_xfers);
         if (reqh)          if (xfer != NULL)
                 SIMPLEQ_REMOVE_HEAD(&usbd_free_requests, reqh, next);                  SIMPLEQ_REMOVE_HEAD(&usbd_free_xfers, xfer, next);
         else          else
                 reqh = malloc(sizeof(*reqh), M_USB, M_NOWAIT);                  xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT);
         if (!reqh)          if (xfer == NULL)
                 return (0);                  return (0);
         memset(reqh, 0, sizeof *reqh);          memset(xfer, 0, sizeof *xfer);
         reqh->device = dev;          xfer->device = dev;
         DPRINTFN(5,("usbd_alloc_request() = %p\n", reqh));          DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer));
         return (reqh);          return (xfer);
 }  }
   
 usbd_status  usbd_status
 usbd_free_request(reqh)  usbd_free_xfer(xfer)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
 {  {
         DPRINTFN(5,("usbd_free_request: %p\n", reqh));          DPRINTFN(5,("usbd_free_xfer: %p\n", xfer));
         if (reqh->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))          if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
                 usbd_free_buffer(reqh);                  usbd_free_buffer(xfer);
         SIMPLEQ_INSERT_HEAD(&usbd_free_requests, reqh, next);          SIMPLEQ_INSERT_HEAD(&usbd_free_xfers, xfer, next);
         return (USBD_NORMAL_COMPLETION);          return (USBD_NORMAL_COMPLETION);
 }  }
   
 void  void
 usbd_setup_request(reqh, pipe, priv, buffer, length, flags, timeout, callback)  usbd_setup_xfer(xfer, pipe, priv, buffer, length, flags, timeout, callback)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
         usbd_pipe_handle pipe;          usbd_pipe_handle pipe;
         usbd_private_handle priv;          usbd_private_handle priv;
         void *buffer;          void *buffer;
         u_int32_t length;          u_int32_t length;
         u_int16_t flags;          u_int16_t flags;
         u_int32_t timeout;          u_int32_t timeout;
         void (*callback) __P((usbd_request_handle,          void (*callback) __P((usbd_xfer_handle,
                               usbd_private_handle,                                usbd_private_handle,
                               usbd_status));                                usbd_status));
 {  {
         reqh->pipe = pipe;          xfer->pipe = pipe;
         reqh->priv = priv;          xfer->priv = priv;
         reqh->buffer = buffer;          xfer->buffer = buffer;
         reqh->length = length;          xfer->length = length;
         reqh->actlen = 0;          xfer->actlen = 0;
         reqh->flags = flags;          xfer->flags = flags;
         reqh->timeout = timeout;          xfer->timeout = timeout;
         reqh->status = USBD_NOT_STARTED;          xfer->status = USBD_NOT_STARTED;
         reqh->callback = callback;          xfer->callback = callback;
         reqh->rqflags &= ~URQ_REQUEST;          xfer->rqflags &= ~URQ_REQUEST;
         reqh->nframes = 0;          xfer->nframes = 0;
 }  }
   
 void  void
 usbd_setup_default_request(reqh, dev, priv, timeout, req, buffer,  usbd_setup_default_xfer(xfer, dev, priv, timeout, req, buffer,
                            length, flags, callback)                             length, flags, callback)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
         usbd_device_handle dev;          usbd_device_handle dev;
         usbd_private_handle priv;          usbd_private_handle priv;
         u_int32_t timeout;          u_int32_t timeout;
Line 390  usbd_setup_default_request(reqh, dev, pr
Line 423  usbd_setup_default_request(reqh, dev, pr
         void *buffer;          void *buffer;
         u_int32_t length;          u_int32_t length;
         u_int16_t flags;          u_int16_t flags;
         void (*callback) __P((usbd_request_handle,          void (*callback) __P((usbd_xfer_handle,
                               usbd_private_handle,                                usbd_private_handle,
                               usbd_status));                                usbd_status));
 {  {
         reqh->pipe = dev->default_pipe;          xfer->pipe = dev->default_pipe;
         reqh->priv = priv;          xfer->priv = priv;
         reqh->buffer = buffer;          xfer->buffer = buffer;
         reqh->length = length;          xfer->length = length;
         reqh->actlen = 0;          xfer->actlen = 0;
         reqh->flags = flags;          xfer->flags = flags;
         reqh->timeout = timeout;          xfer->timeout = timeout;
         reqh->status = USBD_NOT_STARTED;          xfer->status = USBD_NOT_STARTED;
         reqh->callback = callback;          xfer->callback = callback;
         reqh->request = *req;          xfer->request = *req;
         reqh->rqflags |= URQ_REQUEST;          xfer->rqflags |= URQ_REQUEST;
         reqh->nframes = 0;          xfer->nframes = 0;
 }  }
   
 void  void
 usbd_setup_isoc_request(reqh, pipe, priv, frlengths, nframes, flags, callback)  usbd_setup_isoc_xfer(xfer, pipe, priv, frlengths, nframes, flags, callback)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
         usbd_pipe_handle pipe;          usbd_pipe_handle pipe;
         usbd_private_handle priv;          usbd_private_handle priv;
         u_int16_t *frlengths;          u_int16_t *frlengths;
Line 418  usbd_setup_isoc_request(reqh, pipe, priv
Line 451  usbd_setup_isoc_request(reqh, pipe, priv
         u_int16_t flags;          u_int16_t flags;
         usbd_callback callback;          usbd_callback callback;
 {  {
         reqh->pipe = pipe;          xfer->pipe = pipe;
         reqh->priv = priv;          xfer->priv = priv;
         reqh->buffer = 0;          xfer->buffer = 0;
         reqh->length = 0;          xfer->length = 0;
         reqh->actlen = 0;          xfer->actlen = 0;
         reqh->flags = flags;          xfer->flags = flags;
         reqh->timeout = USBD_NO_TIMEOUT;          xfer->timeout = USBD_NO_TIMEOUT;
         reqh->status = USBD_NOT_STARTED;          xfer->status = USBD_NOT_STARTED;
         reqh->callback = callback;          xfer->callback = callback;
         reqh->rqflags &= ~URQ_REQUEST;          xfer->rqflags &= ~URQ_REQUEST;
         reqh->frlengths = frlengths;          xfer->frlengths = frlengths;
         reqh->nframes = nframes;          xfer->nframes = nframes;
 }  }
   
 void  void
 usbd_get_request_status(reqh, priv, buffer, count, status)  usbd_get_xfer_status(xfer, priv, buffer, count, status)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
         usbd_private_handle *priv;          usbd_private_handle *priv;
         void **buffer;          void **buffer;
         u_int32_t *count;          u_int32_t *count;
         usbd_status *status;          usbd_status *status;
 {  {
         if (priv)          if (priv != NULL)
                 *priv = reqh->priv;                  *priv = xfer->priv;
         if (buffer)          if (buffer != NULL)
                 *buffer = reqh->buffer;                  *buffer = xfer->buffer;
         if (count)          if (count != NULL)
                 *count = reqh->actlen;                  *count = xfer->actlen;
         if (status)          if (status != NULL)
                 *status = reqh->status;                  *status = xfer->status;
 }  }
   
 usb_config_descriptor_t *  usb_config_descriptor_t *
 usbd_get_config_descriptor(dev)  usbd_get_config_descriptor(dev)
         usbd_device_handle dev;          usbd_device_handle dev;
 {  {
   #ifdef DIAGNOSTIC
           if (dev == NULL) {
                   printf("usbd_get_config_descriptor: dev == NULL\n");
                   return (NULL);
           }
   #endif
         return (dev->cdesc);          return (dev->cdesc);
 }  }
   
Line 461  usb_interface_descriptor_t *
Line 500  usb_interface_descriptor_t *
 usbd_get_interface_descriptor(iface)  usbd_get_interface_descriptor(iface)
         usbd_interface_handle iface;          usbd_interface_handle iface;
 {  {
   #ifdef DIAGNOSTIC
           if (iface == NULL) {
                   printf("usbd_get_interface_descriptor: dev == NULL\n");
                   return (NULL);
           }
   #endif
         return (iface->idesc);          return (iface->idesc);
 }  }
   
Line 485  usbd_status 
Line 530  usbd_status 
 usbd_abort_pipe(pipe)  usbd_abort_pipe(pipe)
         usbd_pipe_handle pipe;          usbd_pipe_handle pipe;
 {  {
         usbd_status r;          usbd_status err;
         int s;          int s;
   
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if (pipe == 0) {          if (pipe == NULL) {
                 printf("usbd_close_pipe: pipe==NULL\n");                  printf("usbd_close_pipe: pipe==NULL\n");
                 return (USBD_NORMAL_COMPLETION);                  return (USBD_NORMAL_COMPLETION);
         }          }
 #endif  #endif
         s = splusb();          s = splusb();
         r = usbd_ar_pipe(pipe);          err = usbd_ar_pipe(pipe);
         splx(s);          splx(s);
         return (r);          return (err);
 }  }
   
 usbd_status  usbd_status
Line 506  usbd_clear_endpoint_stall(pipe)
Line 551  usbd_clear_endpoint_stall(pipe)
 {  {
         usbd_device_handle dev = pipe->device;          usbd_device_handle dev = pipe->device;
         usb_device_request_t req;          usb_device_request_t req;
         usbd_status r;          usbd_status err;
   
         DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));          DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));
   
Line 521  usbd_clear_endpoint_stall(pipe)
Line 566  usbd_clear_endpoint_stall(pipe)
         USETW(req.wValue, UF_ENDPOINT_HALT);          USETW(req.wValue, UF_ENDPOINT_HALT);
         USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);          USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
         USETW(req.wLength, 0);          USETW(req.wLength, 0);
         r = usbd_do_request(dev, &req, 0);          err = usbd_do_request(dev, &req, 0);
 #if 0  #if 0
 XXX should we do this?  XXX should we do this?
         if (r == USBD_NORMAL_COMPLETION) {          if (!err) {
                 pipe->state = USBD_PIPE_ACTIVE;                  pipe->state = USBD_PIPE_ACTIVE;
                 /* XXX activate pipe */                  /* XXX activate pipe */
         }          }
 #endif  #endif
         return (r);          return (err);
 }  }
   
 usbd_status  usbd_status
Line 538  usbd_clear_endpoint_stall_async(pipe)
Line 583  usbd_clear_endpoint_stall_async(pipe)
 {  {
         usbd_device_handle dev = pipe->device;          usbd_device_handle dev = pipe->device;
         usb_device_request_t req;          usb_device_request_t req;
         usbd_status r;          usbd_status err;
   
         pipe->methods->cleartoggle(pipe);          pipe->methods->cleartoggle(pipe);
   
Line 547  usbd_clear_endpoint_stall_async(pipe)
Line 592  usbd_clear_endpoint_stall_async(pipe)
         USETW(req.wValue, UF_ENDPOINT_HALT);          USETW(req.wValue, UF_ENDPOINT_HALT);
         USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);          USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
         USETW(req.wLength, 0);          USETW(req.wLength, 0);
         r = usbd_do_request_async(dev, &req, 0);          err = usbd_do_request_async(dev, &req, 0);
         return (r);          return (err);
 }  }
   
 usbd_status  usbd_status
Line 565  usbd_interface_count(dev, count)
Line 610  usbd_interface_count(dev, count)
         usbd_device_handle dev;          usbd_device_handle dev;
         u_int8_t *count;          u_int8_t *count;
 {  {
         if (!dev->cdesc)          if (dev->cdesc == NULL)
                 return (USBD_NOT_CONFIGURED);                  return (USBD_NOT_CONFIGURED);
         *count = dev->cdesc->bNumInterface;          *count = dev->cdesc->bNumInterface;
         return (USBD_NORMAL_COMPLETION);          return (USBD_NORMAL_COMPLETION);
Line 586  usbd_device2interface_handle(dev, ifacen
Line 631  usbd_device2interface_handle(dev, ifacen
         u_int8_t ifaceno;          u_int8_t ifaceno;
         usbd_interface_handle *iface;          usbd_interface_handle *iface;
 {  {
         if (!dev->cdesc)          if (dev->cdesc == NULL)
                 return (USBD_NOT_CONFIGURED);                  return (USBD_NOT_CONFIGURED);
         if (ifaceno >= dev->cdesc->bNumInterface)          if (ifaceno >= dev->cdesc->bNumInterface)
                 return (USBD_INVAL);                  return (USBD_INVAL);
Line 608  usbd_set_interface(iface, altidx)
Line 653  usbd_set_interface(iface, altidx)
         int altidx;          int altidx;
 {  {
         usb_device_request_t req;          usb_device_request_t req;
         usbd_status r;          usbd_status err;
   
         if (LIST_FIRST(&iface->pipes) != 0)          if (LIST_FIRST(&iface->pipes) != 0)
                 return (USBD_IN_USE);                  return (USBD_IN_USE);
Line 618  usbd_set_interface(iface, altidx)
Line 663  usbd_set_interface(iface, altidx)
         iface->endpoints = 0;          iface->endpoints = 0;
         iface->idesc = 0;          iface->idesc = 0;
   
         r = usbd_fill_iface_data(iface->device, iface->index, altidx);          err = usbd_fill_iface_data(iface->device, iface->index, altidx);
         if (r != USBD_NORMAL_COMPLETION)          if (err)
                 return (r);                  return (err);
   
         req.bmRequestType = UT_WRITE_INTERFACE;          req.bmRequestType = UT_WRITE_INTERFACE;
         req.bRequest = UR_SET_INTERFACE;          req.bRequest = UR_SET_INTERFACE;
         USETW(req.wValue, iface->idesc->bAlternateSetting);          USETW(req.wValue, iface->idesc->bAlternateSetting);
         USETW(req.wIndex, iface->idesc->bInterfaceNumber);          USETW(req.wIndex, iface->idesc->bInterfaceNumber);
         USETW(req.wLength, 0);          USETW(req.wLength, 0);
         return usbd_do_request(iface->device, &req, 0);          return (usbd_do_request(iface->device, &req, 0));
 }  }
   
 int  int
Line 669  usbd_get_interface(iface, aiface)
Line 714  usbd_get_interface(iface, aiface)
         USETW(req.wValue, 0);          USETW(req.wValue, 0);
         USETW(req.wIndex, iface->idesc->bInterfaceNumber);          USETW(req.wIndex, iface->idesc->bInterfaceNumber);
         USETW(req.wLength, 1);          USETW(req.wLength, 1);
         return usbd_do_request(iface->device, &req, aiface);          return (usbd_do_request(iface->device, &req, aiface));
 }  }
   
 /*** Internal routines ***/  /*** Internal routines ***/
Line 679  static usbd_status
Line 724  static usbd_status
 usbd_ar_pipe(pipe)  usbd_ar_pipe(pipe)
         usbd_pipe_handle pipe;          usbd_pipe_handle pipe;
 {  {
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
   
         SPLUSBCHECK;          SPLUSBCHECK;
   
Line 688  usbd_ar_pipe(pipe)
Line 733  usbd_ar_pipe(pipe)
         if (usbdebug > 5)          if (usbdebug > 5)
                 usbd_dump_queue(pipe);                  usbd_dump_queue(pipe);
 #endif  #endif
         while ((reqh = SIMPLEQ_FIRST(&pipe->queue))) {          pipe->repeat = 0;
                 DPRINTFN(2,("usbd_ar_pipe: pipe=%p reqh=%p (methods=%p)\n",          while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) {
                             pipe, reqh, pipe->methods));                  DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n",
                               pipe, xfer, pipe->methods));
                 /* Make the HC abort it (and invoke the callback). */                  /* Make the HC abort it (and invoke the callback). */
                 pipe->methods->abort(reqh);                  pipe->methods->abort(xfer);
                 /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */                  /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
         }          }
         return (USBD_NORMAL_COMPLETION);          return (USBD_NORMAL_COMPLETION);
 }  }
   
 void  
 usbd_init()  
 {  
         static int usbd_global_init_done = 0;  
 #if defined(__FreeBSD__)  
         dev_t dev;  
 #endif  
   
         if (!usbd_global_init_done) {  
                 usbd_global_init_done = 1;  
                 SIMPLEQ_INIT(&usbd_free_requests);  
   
 #if defined(__FreeBSD__)  
                 dev = makedev(USB_CDEV_MAJOR, 0);  
                 cdevsw_add(&dev, &usb_cdevsw, NULL);  
 #endif  
         }  
 }  
   
 /* Called at splusb() */  /* Called at splusb() */
 void  void
 usb_transfer_complete(reqh)  usb_transfer_complete(xfer)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
 {  {
         usbd_pipe_handle pipe = reqh->pipe;          usbd_pipe_handle pipe = xfer->pipe;
         usb_dma_t *dmap = &reqh->dmabuf;          usb_dma_t *dmap = &xfer->dmabuf;
           int repeat = pipe->repeat;
         int polling;          int polling;
   
         SPLUSBCHECK;          SPLUSBCHECK;
   
         DPRINTFN(5, ("usb_transfer_complete: pipe=%p reqh=%p status=%d actlen=%d\n",          DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d "
                      pipe, reqh, reqh->status, reqh->actlen));                       "actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen));
   
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if (!pipe) {          if (pipe == NULL) {
                 printf("usbd_transfer_cb: pipe==0, reqh=%p\n", reqh);                  printf("usbd_transfer_cb: pipe==0, xfer=%p\n", xfer);
                 return;                  return;
         }          }
 #endif  #endif
Line 742  usb_transfer_complete(reqh)
Line 770  usb_transfer_complete(reqh)
         if (polling)          if (polling)
                 pipe->running = 0;                  pipe->running = 0;
   
         if (!(reqh->flags & USBD_NO_COPY) && reqh->actlen != 0 &&          if (!(xfer->flags & USBD_NO_COPY) && xfer->actlen != 0 &&
             usbd_reqh_isread(reqh)) {              usbd_xfer_isread(xfer)) {
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
                 if (reqh->actlen > reqh->length) {                  if (xfer->actlen > xfer->length) {
                         printf("usb_transfer_complete: actlen > len %d > %d\n",                          printf("usb_transfer_complete: actlen > len %d > %d\n",
                                reqh->actlen, reqh->length);                                 xfer->actlen, xfer->length);
                         reqh->actlen = reqh->length;                          xfer->actlen = xfer->length;
                 }                  }
 #endif  #endif
                 memcpy(reqh->buffer, KERNADDR(dmap), reqh->actlen);                  memcpy(xfer->buffer, KERNADDR(dmap), xfer->actlen);
         }          }
   
         /* if we allocated the buffer in usbd_transfer() we free it here. */          /* if we allocated the buffer in usbd_transfer() we free it here. */
         if (reqh->rqflags & URQ_AUTO_DMABUF) {          if (xfer->rqflags & URQ_AUTO_DMABUF) {
                 if (!pipe->repeat) {                  if (!repeat) {
                         struct usbd_bus *bus = pipe->device->bus;                          struct usbd_bus *bus = pipe->device->bus;
                         bus->methods->freem(bus, dmap);                          bus->methods->freem(bus, dmap);
                         reqh->rqflags &= ~URQ_AUTO_DMABUF;                          xfer->rqflags &= ~URQ_AUTO_DMABUF;
                 }                  }
         }          }
   
         if (pipe->methods->done)          if (pipe->methods->done != NULL)
                 pipe->methods->done(reqh);                  pipe->methods->done(xfer);
   
         /* Remove request from queue. */          if (!repeat) {
         SIMPLEQ_REMOVE_HEAD(&pipe->queue, reqh, next);                  /* Remove request from queue. */
   #ifdef DIAGNOSTIC
                   if (xfer != SIMPLEQ_FIRST(&pipe->queue))
                           printf("usb_transfer_complete: bad dequeue %p != %p\n",
                                  xfer, SIMPLEQ_FIRST(&pipe->queue));
   #endif
                   SIMPLEQ_REMOVE_HEAD(&pipe->queue, xfer, next);
           }
   
         /* Count completed transfers. */          /* Count completed transfers. */
         ++pipe->device->bus->stats.requests          ++pipe->device->bus->stats.requests
                 [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE];                  [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE];
   
         reqh->done = 1;          xfer->done = 1;
         if (reqh->status == USBD_NORMAL_COMPLETION &&          if (!xfer->status && xfer->actlen < xfer->length &&
             reqh->actlen < reqh->length &&              !(xfer->flags & USBD_SHORT_XFER_OK)) {
             !(reqh->flags & USBD_SHORT_XFER_OK)) {                  DPRINTFN(-1,("usbd_transfer_cb: short transfer %d<%d\n",
                 DPRINTFN(-1, ("usbd_transfer_cb: short xfer %d<%d (bytes)\n",                               xfer->actlen, xfer->length));
                               reqh->actlen, reqh->length));                  xfer->status = USBD_SHORT_XFER;
                 reqh->status = USBD_SHORT_XFER;  
         }          }
   
         if (reqh->callback)          if (xfer->callback)
                 reqh->callback(reqh, reqh->priv, reqh->status);                  xfer->callback(xfer, xfer->priv, xfer->status);
   
         if ((reqh->flags & USBD_SYNCHRONOUS) && !polling)          if ((xfer->flags & USBD_SYNCHRONOUS) && !polling)
                 wakeup(reqh);                  wakeup(xfer);
   
         if (!pipe->repeat) {          if (!repeat) {
                 /* XXX should we stop the queue on all errors? */                  /* XXX should we stop the queue on all errors? */
                 if (reqh->status == USBD_CANCELLED ||                  if (xfer->status == USBD_CANCELLED ||
                     reqh->status == USBD_TIMEOUT)                      xfer->status == USBD_TIMEOUT)
                         pipe->running = 0;                          pipe->running = 0;
                 else                  else
                         usbd_start_next(pipe);                          usbd_start_next(pipe);
Line 799  usb_transfer_complete(reqh)
Line 833  usb_transfer_complete(reqh)
 }  }
   
 usbd_status  usbd_status
 usb_insert_transfer(reqh)  usb_insert_transfer(xfer)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
 {  {
         usbd_pipe_handle pipe = reqh->pipe;          usbd_pipe_handle pipe = xfer->pipe;
         usbd_status r;          usbd_status err;
         int s;          int s;
   
         DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",          DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
                     pipe, pipe->running, reqh->timeout));                      pipe, pipe->running, xfer->timeout));
         s = splusb();          s = splusb();
         SIMPLEQ_INSERT_TAIL(&pipe->queue, reqh, next);          SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next);
         if (pipe->running)          if (pipe->running)
                 r = USBD_IN_PROGRESS;                  err = USBD_IN_PROGRESS;
         else {          else {
                 pipe->running = 1;                  pipe->running = 1;
                 r = USBD_NORMAL_COMPLETION;                  err = USBD_NORMAL_COMPLETION;
         }          }
         splx(s);          splx(s);
         return (r);          return (err);
 }  }
   
 /* Called at splusb() */  /* Called at splusb() */
Line 825  void
Line 859  void
 usbd_start_next(pipe)  usbd_start_next(pipe)
         usbd_pipe_handle pipe;          usbd_pipe_handle pipe;
 {  {
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
         usbd_status r;          usbd_status err;
   
         SPLUSBCHECK;          SPLUSBCHECK;
   
         DPRINTFN(10, ("usbd_start_next: pipe=%p\n", pipe));  
   
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if (!pipe) {          if (pipe == NULL) {
                 printf("usbd_start_next: pipe == 0\n");                  printf("usbd_start_next: pipe == NULL\n");
                 return;                  return;
         }          }
         if (!pipe->methods || !pipe->methods->start) {          if (pipe->methods == NULL || pipe->methods->start == NULL) {
                 printf("usbd_start_next:  no start method\n");                  printf("usbd_start_next: pipe=%p no start method\n", pipe);
                 return;                  return;
         }          }
 #endif  #endif
   
         /* Get next request in queue. */          /* Get next request in queue. */
         reqh = SIMPLEQ_FIRST(&pipe->queue);          xfer = SIMPLEQ_FIRST(&pipe->queue);
         DPRINTFN(5, ("usbd_start_next: pipe=%p start reqh=%p\n", pipe, reqh));          DPRINTFN(5, ("usbd_start_next: pipe=%p, xfer=%p\n", pipe, xfer));
         if (!reqh)          if (xfer == NULL) {
                 pipe->running = 0;                  pipe->running = 0;
         else {          } else {
                 r = pipe->methods->start(reqh);                  err = pipe->methods->start(xfer);
                 if (r != USBD_IN_PROGRESS) {                  if (err != USBD_IN_PROGRESS) {
                         printf("usbd_start_next: error=%d\n", r);                          printf("usbd_start_next: error=%d\n", err);
                         pipe->running = 0;                          pipe->running = 0;
                         /* XXX do what? */                          /* XXX do what? */
                 }                  }
Line 875  usbd_do_request_flags(dev, req, data, fl
Line 907  usbd_do_request_flags(dev, req, data, fl
         u_int16_t flags;          u_int16_t flags;
         int *actlen;          int *actlen;
 {  {
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
         usbd_status r;          usbd_status err;
   
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
   #if defined(__i386__) && defined(__FreeBSD__)
           KASSERT(intr_nesting_level == 0,
                   ("ohci_abort_req in interrupt context"));
   #endif
         if (dev->bus->intr_context) {          if (dev->bus->intr_context) {
                 printf("usbd_do_request: not in process context\n");                  printf("usbd_do_request: not in process context\n");
                 return (USBD_INVAL);                  return (USBD_INVAL);
         }          }
 #endif  #endif
   
         reqh = usbd_alloc_request(dev);          xfer = usbd_alloc_xfer(dev);
         if (reqh == 0)          if (xfer == NULL)
                 return (USBD_NOMEM);                  return (USBD_NOMEM);
         usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT, req,          usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
                                    data, UGETW(req->wLength), flags, 0);                                     data, UGETW(req->wLength), flags, 0);
         r = usbd_sync_transfer(reqh);          err = usbd_sync_transfer(xfer);
 #if defined(USB_DEBUG) || defined(DIAGNOSTIC)  #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
         if (reqh->actlen > reqh->length)          if (xfer->actlen > xfer->length)
                 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"                  DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
                          "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",                           "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
                          dev->address, reqh->request.bmRequestType,                           dev->address, xfer->request.bmRequestType,
                          reqh->request.bRequest, UGETW(reqh->request.wValue),                           xfer->request.bRequest, UGETW(xfer->request.wValue),
                          UGETW(reqh->request.wIndex),                           UGETW(xfer->request.wIndex),
                          UGETW(reqh->request.wLength),                           UGETW(xfer->request.wLength),
                          reqh->length, reqh->actlen));                           xfer->length, xfer->actlen));
 #endif  #endif
         if (actlen)          if (actlen != NULL)
                 *actlen = reqh->actlen;                  *actlen = xfer->actlen;
         if (r == USBD_STALLED) {          if (err == USBD_STALLED) {
                 /*                  /*
                  * The control endpoint has stalled.  Control endpoints                   * The control endpoint has stalled.  Control endpoints
                  * should not halt, but some may do so anyway so clear                   * should not halt, but some may do so anyway so clear
Line 912  usbd_do_request_flags(dev, req, data, fl
Line 948  usbd_do_request_flags(dev, req, data, fl
                 usb_device_request_t treq;                  usb_device_request_t treq;
                 usb_status_t status;                  usb_status_t status;
                 u_int16_t s;                  u_int16_t s;
                 usbd_status nr;                  usbd_status nerr;
   
                 treq.bmRequestType = UT_READ_ENDPOINT;                  treq.bmRequestType = UT_READ_ENDPOINT;
                 treq.bRequest = UR_GET_STATUS;                  treq.bRequest = UR_GET_STATUS;
                 USETW(treq.wValue, 0);                  USETW(treq.wValue, 0);
                 USETW(treq.wIndex, 0);                  USETW(treq.wIndex, 0);
                 USETW(treq.wLength, sizeof(usb_status_t));                  USETW(treq.wLength, sizeof(usb_status_t));
                 usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT,                  usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
                                            &treq, &status,sizeof(usb_status_t),                                             &treq, &status,sizeof(usb_status_t),
                                            0, 0);                                             0, 0);
                 nr = usbd_sync_transfer(reqh);                  nerr = usbd_sync_transfer(xfer);
                 if (nr != USBD_NORMAL_COMPLETION)                  if (nerr)
                         goto bad;                          goto bad;
                 s = UGETW(status.wStatus);                  s = UGETW(status.wStatus);
                 DPRINTF(("usbd_do_request: status = 0x%04x\n", s));                  DPRINTF(("usbd_do_request: status = 0x%04x\n", s));
Line 934  usbd_do_request_flags(dev, req, data, fl
Line 970  usbd_do_request_flags(dev, req, data, fl
                 USETW(treq.wValue, UF_ENDPOINT_HALT);                  USETW(treq.wValue, UF_ENDPOINT_HALT);
                 USETW(treq.wIndex, 0);                  USETW(treq.wIndex, 0);
                 USETW(treq.wLength, 0);                  USETW(treq.wLength, 0);
                 usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT,                  usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
                                            &treq, &status, 0, 0, 0);                                             &treq, &status, 0, 0, 0);
                 nr = usbd_sync_transfer(reqh);                  nerr = usbd_sync_transfer(xfer);
                 if (nr != USBD_NORMAL_COMPLETION)                  if (nerr)
                         goto bad;                          goto bad;
         }          }
   
  bad:   bad:
         usbd_free_request(reqh);          usbd_free_xfer(xfer);
         return (r);          return (err);
 }  }
   
 void  void
 usbd_do_request_async_cb(reqh, priv, status)  usbd_do_request_async_cb(xfer, priv, status)
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
         usbd_private_handle priv;          usbd_private_handle priv;
         usbd_status status;          usbd_status status;
 {  {
 #if defined(USB_DEBUG) || defined(DIAGNOSTIC)  #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
         if (reqh->actlen > reqh->length)          if (xfer->actlen > xfer->length)
                 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"                  DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
                          "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",                           "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
                          reqh->pipe->device->address,                           xfer->pipe->device->address,
                          reqh->request.bmRequestType,                           xfer->request.bmRequestType,
                          reqh->request.bRequest, UGETW(reqh->request.wValue),                           xfer->request.bRequest, UGETW(xfer->request.wValue),
                          UGETW(reqh->request.wIndex),                           UGETW(xfer->request.wIndex),
                          UGETW(reqh->request.wLength),                           UGETW(xfer->request.wLength),
                          reqh->length, reqh->actlen));                           xfer->length, xfer->actlen));
 #endif  #endif
         usbd_free_request(reqh);          usbd_free_xfer(xfer);
 }  }
   
 /*  /*
Line 976  usbd_do_request_async(dev, req, data)
Line 1012  usbd_do_request_async(dev, req, data)
         usb_device_request_t *req;          usb_device_request_t *req;
         void *data;          void *data;
 {  {
         usbd_request_handle reqh;          usbd_xfer_handle xfer;
         usbd_status r;          usbd_status err;
   
         reqh = usbd_alloc_request(dev);          xfer = usbd_alloc_xfer(dev);
         if (reqh == 0)          if (xfer == NULL)
                 return (USBD_NOMEM);                  return (USBD_NOMEM);
         usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT, req, data,          usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
                                    UGETW(req->wLength), 0,              data, UGETW(req->wLength), 0, usbd_do_request_async_cb);
                                    usbd_do_request_async_cb);          err = usbd_transfer(xfer);
         r = usbd_transfer(reqh);          if (err != USBD_IN_PROGRESS) {
         if (r != USBD_IN_PROGRESS) {                  usbd_free_xfer(xfer);
                 usbd_free_request(reqh);                  return (err);
                 return (r);  
         }          }
         return (USBD_NORMAL_COMPLETION);          return (USBD_NORMAL_COMPLETION);
 }  }
Line 1041  usbd_get_endpoint_descriptor(iface, addr
Line 1076  usbd_get_endpoint_descriptor(iface, addr
 }  }
   
 #if defined(__FreeBSD__)  #if defined(__FreeBSD__)
 void  
 usbd_print_child(device_t parent, device_t child)  
 {  
         /*  
         struct usb_softc *sc = device_get_softc(child);  
         */  
   
         printf(" at %s%d", device_get_name(parent), device_get_unit(parent));  
   
         /* XXX How do we get to the usbd_device_handle???  
         usbd_device_handle dev = invalidadosch;  
   
         printf(" addr %d", dev->addr);  
   
         if (bootverbose) {  
                 if (dev->lowspeed)  
                         printf(", lowspeed");  
                 if (dev->self_powered)  
                         printf(", self powered");  
                 else  
                         printf(", %dmA", dev->power);  
                 printf(", config %d", dev->config);  
         }  
          */  
 }  
   
 /* Reconfigure all the USB busses in the system. */  
 int  int
 usbd_driver_load(module_t mod, int what, void *arg)  usbd_driver_load(module_t mod, int what, void *arg)
 {  {
         devclass_t usb_devclass = devclass_find("usb");          /* XXX should implement something like a function that removes all generic devices */
         devclass_t ugen_devclass = devclass_find("ugen");  
         device_t *devlist;          return (0);
         int devcount;  
         int error;  
   
         switch (what) {  
         case MOD_LOAD:  
         case MOD_UNLOAD:  
                 if (!usb_devclass)  
                         return 0;       /* just ignore call */  
   
                 if (ugen_devclass) {  
                         /* detach devices from generic driver if possible */  
                         error = devclass_get_devices(ugen_devclass, &devlist,  
                                                      &devcount);  
                         if (!error)  
                                 for (devcount--; devcount >= 0; devcount--)  
                                         (void)DEVICE_DETACH(devlist[devcount]);  
                 }  
   
                 error = devclass_get_devices(usb_devclass, &devlist, &devcount);  
                 if (error)  
                         return 0;       /* XXX maybe transient, or error? */  
   
                 for (devcount--; devcount >= 0; devcount--)  
                         USB_RECONFIGURE(devlist[devcount]);  
   
                 free(devlist, M_TEMP);  
                 return 0;  
         }  
   
         return 0;                       /* nothing to do by us */  
 }  
   
 /* Set the description of the device including a malloc and copy. */  
 void  
 usbd_device_set_desc(device_t device, char *devinfo)  
 {  
         size_t l;  
         char *desc;  
   
         if ( devinfo ) {  
                 l = strlen(devinfo);  
                 desc = malloc(l+1, M_USB, M_NOWAIT);  
                 if (desc)  
                         memcpy(desc, devinfo, l+1);  
         } else  
                 desc = NULL;  
   
         device_set_desc(device, desc);  
 }  
   
 char *  
 usbd_devname(device_t bdev)  
 {  
         static char buf[20];  
         /*  
          * A static buffer is a loss if this routine is used from an interrupt,  
          * but it's not fatal.  
          */  
   
         sprintf(buf, "%s%d", device_get_name(bdev), device_get_unit(bdev));  
         return (buf);  
 }  }
   
 #endif  #endif

Legend:
Removed from v.1.43  
changed lines
  Added in v.1.43.2.1

CVSweb <webmaster@jp.NetBSD.org>