diff options
| author | Hans Petter Selasky <hselasky@FreeBSD.org> | 2012-08-12 17:53:06 +0000 |
|---|---|---|
| committer | Hans Petter Selasky <hselasky@FreeBSD.org> | 2012-08-12 17:53:06 +0000 |
| commit | a5cf1aaaffd3716d6246b5214216c89e278bfce6 (patch) | |
| tree | 4ef3a2c09abbce548ca79a0652beee2be50d1199 /sys/dev/usb/usb_transfer.c | |
| parent | 5e6609a21ac77e27438f513843f24922981c9fe1 (diff) | |
Notes
Diffstat (limited to 'sys/dev/usb/usb_transfer.c')
| -rw-r--r-- | sys/dev/usb/usb_transfer.c | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index b799897c7f8e..e4cb5fb10502 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -358,7 +358,8 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm) switch (type) { case UE_ISOCHRONOUS: case UE_INTERRUPT: - xfer->max_packet_count += (xfer->max_packet_size >> 11) & 3; + xfer->max_packet_count += + (xfer->max_packet_size >> 11) & 3; /* check for invalid max packet count */ if (xfer->max_packet_count > 3) @@ -387,7 +388,8 @@ usbd_transfer_setup_sub(struct usb_setup_params *parm) if (ecomp != NULL) { uint8_t mult; - mult = (ecomp->bmAttributes & 3) + 1; + mult = UE_GET_SS_ISO_MULT( + ecomp->bmAttributes) + 1; if (mult > 3) mult = 3; @@ -946,7 +948,20 @@ usbd_transfer_setup(struct usb_device *udev, ep = usbd_get_endpoint(udev, ifaces[setup->if_index], setup); - if ((ep == NULL) || (ep->methods == NULL)) { + /* + * Check that the USB PIPE is valid and that + * the endpoint mode is proper. + * + * Make sure we don't allocate a streams + * transfer when such a combination is not + * valid. + */ + if ((ep == NULL) || (ep->methods == NULL) || + ((ep->ep_mode != USB_EP_MODE_STREAMS) && + (ep->ep_mode != USB_EP_MODE_DEFAULT)) || + (setup->stream_id != 0 && + (setup->stream_id >= USB_MAX_EP_STREAMS || + (ep->ep_mode != USB_EP_MODE_STREAMS)))) { if (setup->flags.no_pipe_ok) continue; if ((setup->usb_mode != USB_MODE_DUAL) && @@ -990,6 +1005,9 @@ usbd_transfer_setup(struct usb_device *udev, /* set transfer endpoint pointer */ xfer->endpoint = ep; + /* set transfer stream ID */ + xfer->stream_id = setup->stream_id; + parm.size[0] += sizeof(xfer[0]); parm.methods = xfer->endpoint->methods; parm.curr_xfer = xfer; @@ -1575,7 +1593,8 @@ usbd_transfer_submit(struct usb_xfer *xfer) USB_BUS_LOCK(bus); xfer->flags_int.can_cancel_immed = 1; /* start the transfer */ - usb_command_wrapper(&xfer->endpoint->endpoint_q, xfer); + usb_command_wrapper(&xfer->endpoint-> + endpoint_q[xfer->stream_id], xfer); USB_BUS_UNLOCK(bus); return; } @@ -1696,7 +1715,7 @@ usbd_pipe_enter(struct usb_xfer *xfer) } /* start the transfer */ - usb_command_wrapper(&ep->endpoint_q, xfer); + usb_command_wrapper(&ep->endpoint_q[xfer->stream_id], xfer); USB_BUS_UNLOCK(xfer->xroot->bus); } @@ -1817,8 +1836,9 @@ usbd_transfer_stop(struct usb_xfer *xfer) * If the current USB transfer is completing we need * to start the next one: */ - if (ep->endpoint_q.curr == xfer) { - usb_command_wrapper(&ep->endpoint_q, NULL); + if (ep->endpoint_q[xfer->stream_id].curr == xfer) { + usb_command_wrapper( + &ep->endpoint_q[xfer->stream_id], NULL); } } @@ -2533,7 +2553,7 @@ usbd_pipe_start(struct usb_xfer_queue *pq) if (udev->flags.usb_mode == USB_MODE_DEVICE) { (udev->bus->methods->set_stall) ( - udev, NULL, ep, &did_stall); + udev, ep, &did_stall); } else if (udev->ctrl_xfer[1]) { info = udev->ctrl_xfer[1]->xroot; usb_proc_msignal( @@ -2800,10 +2820,11 @@ usbd_callback_wrapper_sub(struct usb_xfer *xfer) * next one: */ USB_BUS_LOCK(bus); - if (ep->endpoint_q.curr == xfer) { - usb_command_wrapper(&ep->endpoint_q, NULL); + if (ep->endpoint_q[xfer->stream_id].curr == xfer) { + usb_command_wrapper(&ep->endpoint_q[xfer->stream_id], NULL); - if (ep->endpoint_q.curr || TAILQ_FIRST(&ep->endpoint_q.head)) { + if (ep->endpoint_q[xfer->stream_id].curr != NULL || + TAILQ_FIRST(&ep->endpoint_q[xfer->stream_id].head) != NULL) { /* there is another USB transfer waiting */ } else { /* this is the last USB transfer */ |
