summaryrefslogtreecommitdiff
path: root/sys/dev/usb/usb_transfer.c
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2012-08-12 17:53:06 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2012-08-12 17:53:06 +0000
commita5cf1aaaffd3716d6246b5214216c89e278bfce6 (patch)
tree4ef3a2c09abbce548ca79a0652beee2be50d1199 /sys/dev/usb/usb_transfer.c
parent5e6609a21ac77e27438f513843f24922981c9fe1 (diff)
Notes
Diffstat (limited to 'sys/dev/usb/usb_transfer.c')
-rw-r--r--sys/dev/usb/usb_transfer.c43
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 */