diff options
Diffstat (limited to 'drivers/usb/core')
| -rw-r--r-- | drivers/usb/core/devio.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 2a95e4e574bb..c88d8bfaca8d 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
| @@ -1208,6 +1208,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1208 | struct usb_ctrlrequest *dr = NULL; | 1208 | struct usb_ctrlrequest *dr = NULL; |
| 1209 | unsigned int u, totlen, isofrmlen; | 1209 | unsigned int u, totlen, isofrmlen; |
| 1210 | int i, ret, is_in, num_sgs = 0, ifnum = -1; | 1210 | int i, ret, is_in, num_sgs = 0, ifnum = -1; |
| 1211 | int number_of_packets = 0; | ||
| 1211 | void *buf; | 1212 | void *buf; |
| 1212 | 1213 | ||
| 1213 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP | | 1214 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP | |
| @@ -1261,7 +1262,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1261 | le16_to_cpup(&dr->wIndex)); | 1262 | le16_to_cpup(&dr->wIndex)); |
| 1262 | if (ret) | 1263 | if (ret) |
| 1263 | goto error; | 1264 | goto error; |
| 1264 | uurb->number_of_packets = 0; | ||
| 1265 | uurb->buffer_length = le16_to_cpup(&dr->wLength); | 1265 | uurb->buffer_length = le16_to_cpup(&dr->wLength); |
| 1266 | uurb->buffer += 8; | 1266 | uurb->buffer += 8; |
| 1267 | if ((dr->bRequestType & USB_DIR_IN) && uurb->buffer_length) { | 1267 | if ((dr->bRequestType & USB_DIR_IN) && uurb->buffer_length) { |
| @@ -1291,7 +1291,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1291 | uurb->type = USBDEVFS_URB_TYPE_INTERRUPT; | 1291 | uurb->type = USBDEVFS_URB_TYPE_INTERRUPT; |
| 1292 | goto interrupt_urb; | 1292 | goto interrupt_urb; |
| 1293 | } | 1293 | } |
| 1294 | uurb->number_of_packets = 0; | ||
| 1295 | num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE); | 1294 | num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE); |
| 1296 | if (num_sgs == 1 || num_sgs > ps->dev->bus->sg_tablesize) | 1295 | if (num_sgs == 1 || num_sgs > ps->dev->bus->sg_tablesize) |
| 1297 | num_sgs = 0; | 1296 | num_sgs = 0; |
| @@ -1301,7 +1300,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1301 | if (!usb_endpoint_xfer_int(&ep->desc)) | 1300 | if (!usb_endpoint_xfer_int(&ep->desc)) |
| 1302 | return -EINVAL; | 1301 | return -EINVAL; |
| 1303 | interrupt_urb: | 1302 | interrupt_urb: |
| 1304 | uurb->number_of_packets = 0; | ||
| 1305 | break; | 1303 | break; |
| 1306 | 1304 | ||
| 1307 | case USBDEVFS_URB_TYPE_ISO: | 1305 | case USBDEVFS_URB_TYPE_ISO: |
| @@ -1311,15 +1309,16 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1311 | return -EINVAL; | 1309 | return -EINVAL; |
| 1312 | if (!usb_endpoint_xfer_isoc(&ep->desc)) | 1310 | if (!usb_endpoint_xfer_isoc(&ep->desc)) |
| 1313 | return -EINVAL; | 1311 | return -EINVAL; |
| 1312 | number_of_packets = uurb->number_of_packets; | ||
| 1314 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * | 1313 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * |
| 1315 | uurb->number_of_packets; | 1314 | number_of_packets; |
| 1316 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) | 1315 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) |
| 1317 | return -ENOMEM; | 1316 | return -ENOMEM; |
| 1318 | if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { | 1317 | if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { |
| 1319 | ret = -EFAULT; | 1318 | ret = -EFAULT; |
| 1320 | goto error; | 1319 | goto error; |
| 1321 | } | 1320 | } |
| 1322 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { | 1321 | for (totlen = u = 0; u < number_of_packets; u++) { |
| 1323 | /* | 1322 | /* |
| 1324 | * arbitrary limit need for USB 3.0 | 1323 | * arbitrary limit need for USB 3.0 |
| 1325 | * bMaxBurst (0~15 allowed, 1~16 packets) | 1324 | * bMaxBurst (0~15 allowed, 1~16 packets) |
| @@ -1350,7 +1349,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1350 | ret = -EFAULT; | 1349 | ret = -EFAULT; |
| 1351 | goto error; | 1350 | goto error; |
| 1352 | } | 1351 | } |
| 1353 | as = alloc_async(uurb->number_of_packets); | 1352 | as = alloc_async(number_of_packets); |
| 1354 | if (!as) { | 1353 | if (!as) { |
| 1355 | ret = -ENOMEM; | 1354 | ret = -ENOMEM; |
| 1356 | goto error; | 1355 | goto error; |
| @@ -1444,7 +1443,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1444 | as->urb->setup_packet = (unsigned char *)dr; | 1443 | as->urb->setup_packet = (unsigned char *)dr; |
| 1445 | dr = NULL; | 1444 | dr = NULL; |
| 1446 | as->urb->start_frame = uurb->start_frame; | 1445 | as->urb->start_frame = uurb->start_frame; |
| 1447 | as->urb->number_of_packets = uurb->number_of_packets; | 1446 | as->urb->number_of_packets = number_of_packets; |
| 1448 | if (uurb->type == USBDEVFS_URB_TYPE_ISO || | 1447 | if (uurb->type == USBDEVFS_URB_TYPE_ISO || |
| 1449 | ps->dev->speed == USB_SPEED_HIGH) | 1448 | ps->dev->speed == USB_SPEED_HIGH) |
| 1450 | as->urb->interval = 1 << min(15, ep->desc.bInterval - 1); | 1449 | as->urb->interval = 1 << min(15, ep->desc.bInterval - 1); |
| @@ -1452,7 +1451,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1452 | as->urb->interval = ep->desc.bInterval; | 1451 | as->urb->interval = ep->desc.bInterval; |
| 1453 | as->urb->context = as; | 1452 | as->urb->context = as; |
| 1454 | as->urb->complete = async_completed; | 1453 | as->urb->complete = async_completed; |
| 1455 | for (totlen = u = 0; u < uurb->number_of_packets; u++) { | 1454 | for (totlen = u = 0; u < number_of_packets; u++) { |
| 1456 | as->urb->iso_frame_desc[u].offset = totlen; | 1455 | as->urb->iso_frame_desc[u].offset = totlen; |
| 1457 | as->urb->iso_frame_desc[u].length = isopkt[u].length; | 1456 | as->urb->iso_frame_desc[u].length = isopkt[u].length; |
| 1458 | totlen += isopkt[u].length; | 1457 | totlen += isopkt[u].length; |
