Index: usbdi.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/usbdi.c,v retrieving revision 1.134.2.15 diff -p -r1.134.2.15 usbdi.c *** usbdi.c 6 Mar 2012 18:26:48 -0000 1.134.2.15 --- usbdi.c 31 May 2012 08:05:57 -0000 *************** usbd_transfer(usbd_xfer_handle xfer) *** 322,331 **** if (pipe->device->bus->use_polling) panic("usbd_transfer: not done"); ! if (pipe->device->bus->lock) ! cv_wait(&xfer->cv, pipe->device->bus->lock); ! else ! tsleep(xfer, PRIBIO, "usbsyn", 0); } usbd_unlock_pipe(pipe); return (xfer->status); --- 322,338 ---- if (pipe->device->bus->use_polling) panic("usbd_transfer: not done"); ! if ((flags & USBD_SYNCHRONOUS_SIG) != 0) { ! if (pipe->device->bus->lock) ! cv_wait_sig(&xfer->cv, pipe->device->bus->lock); ! else ! tsleep(xfer, PZERO|PCATCH, "usbsyn", 0); ! } else { ! if (pipe->device->bus->lock) ! cv_wait(&xfer->cv, pipe->device->bus->lock); ! else ! tsleep(xfer, PRIBIO, "usbsyn", 0); ! } } usbd_unlock_pipe(pipe); return (xfer->status); *************** usbd_sync_transfer(usbd_xfer_handle xfer *** 339,344 **** --- 346,359 ---- return (usbd_transfer(xfer)); } + /* Like usbd_transfer(), but waits for completion and listens for signals. */ + usbd_status + usbd_sync_transfer_sig(usbd_xfer_handle xfer) + { + xfer->flags |= USBD_SYNCHRONOUS | USBD_SYNCHRONOUS_SIG; + return (usbd_transfer(xfer)); + } + void * usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size) { Index: usbdi.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/usbdi.h,v retrieving revision 1.80.2.1 diff -p -r1.80.2.1 usbdi.h *** usbdi.h 24 Feb 2012 09:11:44 -0000 1.80.2.1 --- usbdi.h 31 May 2012 08:05:57 -0000 *************** typedef void (*usbd_callback)(usbd_xfer_ *** 80,85 **** --- 80,87 ---- #define USBD_SYNCHRONOUS 0x02 /* wait for completion */ /* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */ #define USBD_FORCE_SHORT_XFER 0x08 /* force last short packet on write */ + #define USBD_SYNCHRONOUS_SIG 0x10 /* if waiting for completion, + * also take signals */ #define USBD_NO_TIMEOUT 0 #define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */ *************** void *usbd_alloc_buffer(usbd_xfer_handle *** 125,130 **** --- 127,133 ---- void usbd_free_buffer(usbd_xfer_handle); void *usbd_get_buffer(usbd_xfer_handle); usbd_status usbd_sync_transfer(usbd_xfer_handle); + usbd_status usbd_sync_transfer_sig(usbd_xfer_handle); usbd_status usbd_open_pipe_intr(usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, usbd_private_handle, void *, Index: usbdi_util.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/usbdi_util.c,v retrieving revision 1.55.12.7 diff -p -r1.55.12.7 usbdi_util.c *** usbdi_util.c 6 Mar 2012 18:26:48 -0000 1.55.12.7 --- usbdi_util.c 31 May 2012 08:05:57 -0000 *************** usbd_bulk_transfer(usbd_xfer_handle xfer *** 434,461 **** u_int32_t *size, const char *lbl) { usbd_status err; - int s, error; usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout, usbd_bulk_transfer_cb); DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size)); ! usbd_lock_pipe(pipe); /* don't want callback until block */ ! err = usbd_transfer(xfer); ! if (err != USBD_IN_PROGRESS) { ! usbd_unlock_pipe(pipe); ! return (err); ! } ! if (pipe->device->bus->lock) ! error = cv_wait_sig(&xfer->cv, pipe->device->bus->lock); ! else ! error = tsleep(xfer, PZERO | PCATCH, lbl, 0); /* XXXSMP ok */ ! usbd_unlock_pipe(pipe); ! if (error) { ! DPRINTF(("usbd_bulk_transfer: wait=%d\n", error)); ! usbd_abort_pipe(pipe); ! return (USBD_INTERRUPTED); ! } ! usbd_get_xfer_status(xfer, NULL, NULL, size, &err); DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size)); if (err) { DPRINTF(("usbd_bulk_transfer: error=%d\n", err)); --- 434,446 ---- u_int32_t *size, const char *lbl) { usbd_status err; usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout, usbd_bulk_transfer_cb); DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size)); ! ! err = usbd_sync_transfer_sig(xfer); ! usbd_get_xfer_status(xfer, NULL, NULL, size, NULL); DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size)); if (err) { DPRINTF(("usbd_bulk_transfer: error=%d\n", err)); *************** usbd_intr_transfer(usbd_xfer_handle xfer *** 483,510 **** u_int32_t *size, const char *lbl) { usbd_status err; - int s, error; usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout, usbd_intr_transfer_cb); DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size)); ! usbd_lock_pipe(pipe); /* don't want callback until block */ ! err = usbd_transfer(xfer); ! if (err != USBD_IN_PROGRESS) { ! usbd_unlock_pipe(pipe); ! return (err); ! } ! if (pipe->device->bus->lock) ! error = cv_wait_sig(&xfer->cv, pipe->device->bus->lock); ! else ! error = tsleep(xfer, PZERO | PCATCH, lbl, 0); /* XXXSMP ok */ ! usbd_unlock_pipe(pipe); ! if (error) { ! DPRINTF(("usbd_intr_transfer: wait=%d\n", error)); ! usbd_abort_pipe(pipe); ! return (USBD_INTERRUPTED); ! } ! usbd_get_xfer_status(xfer, NULL, NULL, size, &err); DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size)); if (err) { DPRINTF(("usbd_intr_transfer: error=%d\n", err)); --- 468,479 ---- u_int32_t *size, const char *lbl) { usbd_status err; usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout, usbd_intr_transfer_cb); DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size)); ! err = usbd_sync_transfer_sig(xfer); ! usbd_get_xfer_status(xfer, NULL, NULL, size, NULL); DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size)); if (err) { DPRINTF(("usbd_intr_transfer: error=%d\n", err));