diff options
| -rw-r--r-- | drivers/usb/core/devio.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6ce77b33da61..263dd2f309fb 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
| @@ -1434,10 +1434,13 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
| 1434 | struct async *as = NULL; | 1434 | struct async *as = NULL; |
| 1435 | struct usb_ctrlrequest *dr = NULL; | 1435 | struct usb_ctrlrequest *dr = NULL; |
| 1436 | unsigned int u, totlen, isofrmlen; | 1436 | unsigned int u, totlen, isofrmlen; |
| 1437 | int i, ret, is_in, num_sgs = 0, ifnum = -1; | 1437 | int i, ret, num_sgs = 0, ifnum = -1; |
| 1438 | int number_of_packets = 0; | 1438 | int number_of_packets = 0; |
| 1439 | unsigned int stream_id = 0; | 1439 | unsigned int stream_id = 0; |
| 1440 | void *buf; | 1440 | void *buf; |
| 1441 | bool is_in; | ||
| 1442 | bool allow_short = false; | ||
| 1443 | bool allow_zero = false; | ||
| 1441 | unsigned long mask = USBDEVFS_URB_SHORT_NOT_OK | | 1444 | unsigned long mask = USBDEVFS_URB_SHORT_NOT_OK | |
| 1442 | USBDEVFS_URB_BULK_CONTINUATION | | 1445 | USBDEVFS_URB_BULK_CONTINUATION | |
| 1443 | USBDEVFS_URB_NO_FSBR | | 1446 | USBDEVFS_URB_NO_FSBR | |
| @@ -1471,6 +1474,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
| 1471 | u = 0; | 1474 | u = 0; |
| 1472 | switch (uurb->type) { | 1475 | switch (uurb->type) { |
| 1473 | case USBDEVFS_URB_TYPE_CONTROL: | 1476 | case USBDEVFS_URB_TYPE_CONTROL: |
| 1477 | if (is_in) | ||
| 1478 | allow_short = true; | ||
| 1474 | if (!usb_endpoint_xfer_control(&ep->desc)) | 1479 | if (!usb_endpoint_xfer_control(&ep->desc)) |
| 1475 | return -EINVAL; | 1480 | return -EINVAL; |
| 1476 | /* min 8 byte setup packet */ | 1481 | /* min 8 byte setup packet */ |
| @@ -1511,6 +1516,10 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
| 1511 | break; | 1516 | break; |
| 1512 | 1517 | ||
| 1513 | case USBDEVFS_URB_TYPE_BULK: | 1518 | case USBDEVFS_URB_TYPE_BULK: |
| 1519 | if (!is_in) | ||
| 1520 | allow_zero = true; | ||
| 1521 | else | ||
| 1522 | allow_short = true; | ||
| 1514 | switch (usb_endpoint_type(&ep->desc)) { | 1523 | switch (usb_endpoint_type(&ep->desc)) { |
| 1515 | case USB_ENDPOINT_XFER_CONTROL: | 1524 | case USB_ENDPOINT_XFER_CONTROL: |
| 1516 | case USB_ENDPOINT_XFER_ISOC: | 1525 | case USB_ENDPOINT_XFER_ISOC: |
| @@ -1531,6 +1540,10 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
| 1531 | if (!usb_endpoint_xfer_int(&ep->desc)) | 1540 | if (!usb_endpoint_xfer_int(&ep->desc)) |
| 1532 | return -EINVAL; | 1541 | return -EINVAL; |
| 1533 | interrupt_urb: | 1542 | interrupt_urb: |
| 1543 | if (!is_in) | ||
| 1544 | allow_zero = true; | ||
| 1545 | else | ||
| 1546 | allow_short = true; | ||
| 1534 | break; | 1547 | break; |
| 1535 | 1548 | ||
| 1536 | case USBDEVFS_URB_TYPE_ISO: | 1549 | case USBDEVFS_URB_TYPE_ISO: |
| @@ -1676,9 +1689,9 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb | |||
| 1676 | u = (is_in ? URB_DIR_IN : URB_DIR_OUT); | 1689 | u = (is_in ? URB_DIR_IN : URB_DIR_OUT); |
| 1677 | if (uurb->flags & USBDEVFS_URB_ISO_ASAP) | 1690 | if (uurb->flags & USBDEVFS_URB_ISO_ASAP) |
| 1678 | u |= URB_ISO_ASAP; | 1691 | u |= URB_ISO_ASAP; |
| 1679 | if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK && is_in) | 1692 | if (allow_short && uurb->flags & USBDEVFS_URB_SHORT_NOT_OK) |
| 1680 | u |= URB_SHORT_NOT_OK; | 1693 | u |= URB_SHORT_NOT_OK; |
| 1681 | if (uurb->flags & USBDEVFS_URB_ZERO_PACKET) | 1694 | if (allow_zero && uurb->flags & USBDEVFS_URB_ZERO_PACKET) |
| 1682 | u |= URB_ZERO_PACKET; | 1695 | u |= URB_ZERO_PACKET; |
| 1683 | if (uurb->flags & USBDEVFS_URB_NO_INTERRUPT) | 1696 | if (uurb->flags & USBDEVFS_URB_NO_INTERRUPT) |
| 1684 | u |= URB_NO_INTERRUPT; | 1697 | u |= URB_NO_INTERRUPT; |
