diff options
32 files changed, 335 insertions, 148 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index a986e9bbba3d..bcebb9eaedce 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb | |||
@@ -160,7 +160,7 @@ Description: | |||
160 | match the driver to the device. For example: | 160 | match the driver to the device. For example: |
161 | # echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id | 161 | # echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id |
162 | 162 | ||
163 | What: /sys/bus/usb/device/.../avoid_reset | 163 | What: /sys/bus/usb/device/.../avoid_reset_quirk |
164 | Date: December 2009 | 164 | Date: December 2009 |
165 | Contact: Oliver Neukum <oliver@neukum.org> | 165 | Contact: Oliver Neukum <oliver@neukum.org> |
166 | Description: | 166 | Description: |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 975d556b4787..be6331e2c276 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1441,7 +1441,7 @@ static int acm_resume(struct usb_interface *intf) | |||
1441 | wb = acm->delayed_wb; | 1441 | wb = acm->delayed_wb; |
1442 | acm->delayed_wb = NULL; | 1442 | acm->delayed_wb = NULL; |
1443 | spin_unlock_irq(&acm->write_lock); | 1443 | spin_unlock_irq(&acm->write_lock); |
1444 | acm_start_wb(acm, acm->delayed_wb); | 1444 | acm_start_wb(acm, wb); |
1445 | } else { | 1445 | } else { |
1446 | spin_unlock_irq(&acm->write_lock); | 1446 | spin_unlock_irq(&acm->write_lock); |
1447 | } | 1447 | } |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 18aafcb08fc8..189141ca4e05 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -52,7 +52,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); | |||
52 | #define WDM_READ 4 | 52 | #define WDM_READ 4 |
53 | #define WDM_INT_STALL 5 | 53 | #define WDM_INT_STALL 5 |
54 | #define WDM_POLL_RUNNING 6 | 54 | #define WDM_POLL_RUNNING 6 |
55 | 55 | #define WDM_RESPONDING 7 | |
56 | #define WDM_SUSPENDING 8 | ||
56 | 57 | ||
57 | #define WDM_MAX 16 | 58 | #define WDM_MAX 16 |
58 | 59 | ||
@@ -87,9 +88,7 @@ struct wdm_device { | |||
87 | int count; | 88 | int count; |
88 | dma_addr_t shandle; | 89 | dma_addr_t shandle; |
89 | dma_addr_t ihandle; | 90 | dma_addr_t ihandle; |
90 | struct mutex wlock; | 91 | struct mutex lock; |
91 | struct mutex rlock; | ||
92 | struct mutex plock; | ||
93 | wait_queue_head_t wait; | 92 | wait_queue_head_t wait; |
94 | struct work_struct rxwork; | 93 | struct work_struct rxwork; |
95 | int werr; | 94 | int werr; |
@@ -117,21 +116,22 @@ static void wdm_in_callback(struct urb *urb) | |||
117 | int status = urb->status; | 116 | int status = urb->status; |
118 | 117 | ||
119 | spin_lock(&desc->iuspin); | 118 | spin_lock(&desc->iuspin); |
119 | clear_bit(WDM_RESPONDING, &desc->flags); | ||
120 | 120 | ||
121 | if (status) { | 121 | if (status) { |
122 | switch (status) { | 122 | switch (status) { |
123 | case -ENOENT: | 123 | case -ENOENT: |
124 | dev_dbg(&desc->intf->dev, | 124 | dev_dbg(&desc->intf->dev, |
125 | "nonzero urb status received: -ENOENT"); | 125 | "nonzero urb status received: -ENOENT"); |
126 | break; | 126 | goto skip_error; |
127 | case -ECONNRESET: | 127 | case -ECONNRESET: |
128 | dev_dbg(&desc->intf->dev, | 128 | dev_dbg(&desc->intf->dev, |
129 | "nonzero urb status received: -ECONNRESET"); | 129 | "nonzero urb status received: -ECONNRESET"); |
130 | break; | 130 | goto skip_error; |
131 | case -ESHUTDOWN: | 131 | case -ESHUTDOWN: |
132 | dev_dbg(&desc->intf->dev, | 132 | dev_dbg(&desc->intf->dev, |
133 | "nonzero urb status received: -ESHUTDOWN"); | 133 | "nonzero urb status received: -ESHUTDOWN"); |
134 | break; | 134 | goto skip_error; |
135 | case -EPIPE: | 135 | case -EPIPE: |
136 | dev_err(&desc->intf->dev, | 136 | dev_err(&desc->intf->dev, |
137 | "nonzero urb status received: -EPIPE\n"); | 137 | "nonzero urb status received: -EPIPE\n"); |
@@ -147,6 +147,7 @@ static void wdm_in_callback(struct urb *urb) | |||
147 | desc->reslength = urb->actual_length; | 147 | desc->reslength = urb->actual_length; |
148 | memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); | 148 | memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); |
149 | desc->length += desc->reslength; | 149 | desc->length += desc->reslength; |
150 | skip_error: | ||
150 | wake_up(&desc->wait); | 151 | wake_up(&desc->wait); |
151 | 152 | ||
152 | set_bit(WDM_READ, &desc->flags); | 153 | set_bit(WDM_READ, &desc->flags); |
@@ -229,13 +230,16 @@ static void wdm_int_callback(struct urb *urb) | |||
229 | desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 230 | desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
230 | spin_lock(&desc->iuspin); | 231 | spin_lock(&desc->iuspin); |
231 | clear_bit(WDM_READ, &desc->flags); | 232 | clear_bit(WDM_READ, &desc->flags); |
232 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { | 233 | set_bit(WDM_RESPONDING, &desc->flags); |
234 | if (!test_bit(WDM_DISCONNECTING, &desc->flags) | ||
235 | && !test_bit(WDM_SUSPENDING, &desc->flags)) { | ||
233 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); | 236 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); |
234 | dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", | 237 | dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", |
235 | __func__, rv); | 238 | __func__, rv); |
236 | } | 239 | } |
237 | spin_unlock(&desc->iuspin); | 240 | spin_unlock(&desc->iuspin); |
238 | if (rv < 0) { | 241 | if (rv < 0) { |
242 | clear_bit(WDM_RESPONDING, &desc->flags); | ||
239 | if (rv == -EPERM) | 243 | if (rv == -EPERM) |
240 | return; | 244 | return; |
241 | if (rv == -ENOMEM) { | 245 | if (rv == -ENOMEM) { |
@@ -305,14 +309,38 @@ static ssize_t wdm_write | |||
305 | if (we < 0) | 309 | if (we < 0) |
306 | return -EIO; | 310 | return -EIO; |
307 | 311 | ||
308 | r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */ | 312 | desc->outbuf = buf = kmalloc(count, GFP_KERNEL); |
313 | if (!buf) { | ||
314 | rv = -ENOMEM; | ||
315 | goto outnl; | ||
316 | } | ||
317 | |||
318 | r = copy_from_user(buf, buffer, count); | ||
319 | if (r > 0) { | ||
320 | kfree(buf); | ||
321 | rv = -EFAULT; | ||
322 | goto outnl; | ||
323 | } | ||
324 | |||
325 | /* concurrent writes and disconnect */ | ||
326 | r = mutex_lock_interruptible(&desc->lock); | ||
309 | rv = -ERESTARTSYS; | 327 | rv = -ERESTARTSYS; |
310 | if (r) | 328 | if (r) { |
329 | kfree(buf); | ||
311 | goto outnl; | 330 | goto outnl; |
331 | } | ||
332 | |||
333 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
334 | kfree(buf); | ||
335 | rv = -ENODEV; | ||
336 | goto outnp; | ||
337 | } | ||
312 | 338 | ||
313 | r = usb_autopm_get_interface(desc->intf); | 339 | r = usb_autopm_get_interface(desc->intf); |
314 | if (r < 0) | 340 | if (r < 0) { |
341 | kfree(buf); | ||
315 | goto outnp; | 342 | goto outnp; |
343 | } | ||
316 | 344 | ||
317 | if (!file->f_flags && O_NONBLOCK) | 345 | if (!file->f_flags && O_NONBLOCK) |
318 | r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, | 346 | r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, |
@@ -320,24 +348,8 @@ static ssize_t wdm_write | |||
320 | else | 348 | else |
321 | if (test_bit(WDM_IN_USE, &desc->flags)) | 349 | if (test_bit(WDM_IN_USE, &desc->flags)) |
322 | r = -EAGAIN; | 350 | r = -EAGAIN; |
323 | if (r < 0) | 351 | if (r < 0) { |
324 | goto out; | ||
325 | |||
326 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
327 | rv = -ENODEV; | ||
328 | goto out; | ||
329 | } | ||
330 | |||
331 | desc->outbuf = buf = kmalloc(count, GFP_KERNEL); | ||
332 | if (!buf) { | ||
333 | rv = -ENOMEM; | ||
334 | goto out; | ||
335 | } | ||
336 | |||
337 | r = copy_from_user(buf, buffer, count); | ||
338 | if (r > 0) { | ||
339 | kfree(buf); | 352 | kfree(buf); |
340 | rv = -EFAULT; | ||
341 | goto out; | 353 | goto out; |
342 | } | 354 | } |
343 | 355 | ||
@@ -374,7 +386,7 @@ static ssize_t wdm_write | |||
374 | out: | 386 | out: |
375 | usb_autopm_put_interface(desc->intf); | 387 | usb_autopm_put_interface(desc->intf); |
376 | outnp: | 388 | outnp: |
377 | mutex_unlock(&desc->wlock); | 389 | mutex_unlock(&desc->lock); |
378 | outnl: | 390 | outnl: |
379 | return rv < 0 ? rv : count; | 391 | return rv < 0 ? rv : count; |
380 | } | 392 | } |
@@ -387,7 +399,7 @@ static ssize_t wdm_read | |||
387 | struct wdm_device *desc = file->private_data; | 399 | struct wdm_device *desc = file->private_data; |
388 | 400 | ||
389 | 401 | ||
390 | rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */ | 402 | rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */ |
391 | if (rv < 0) | 403 | if (rv < 0) |
392 | return -ERESTARTSYS; | 404 | return -ERESTARTSYS; |
393 | 405 | ||
@@ -424,11 +436,8 @@ retry: | |||
424 | spin_lock_irq(&desc->iuspin); | 436 | spin_lock_irq(&desc->iuspin); |
425 | 437 | ||
426 | if (desc->rerr) { /* read completed, error happened */ | 438 | if (desc->rerr) { /* read completed, error happened */ |
427 | int t = desc->rerr; | ||
428 | desc->rerr = 0; | 439 | desc->rerr = 0; |
429 | spin_unlock_irq(&desc->iuspin); | 440 | spin_unlock_irq(&desc->iuspin); |
430 | dev_err(&desc->intf->dev, | ||
431 | "reading had resulted in %d\n", t); | ||
432 | rv = -EIO; | 441 | rv = -EIO; |
433 | goto err; | 442 | goto err; |
434 | } | 443 | } |
@@ -465,9 +474,7 @@ retry: | |||
465 | rv = cntr; | 474 | rv = cntr; |
466 | 475 | ||
467 | err: | 476 | err: |
468 | mutex_unlock(&desc->rlock); | 477 | mutex_unlock(&desc->lock); |
469 | if (rv < 0 && rv != -EAGAIN) | ||
470 | dev_err(&desc->intf->dev, "wdm_read: exit error\n"); | ||
471 | return rv; | 478 | return rv; |
472 | } | 479 | } |
473 | 480 | ||
@@ -533,7 +540,7 @@ static int wdm_open(struct inode *inode, struct file *file) | |||
533 | } | 540 | } |
534 | intf->needs_remote_wakeup = 1; | 541 | intf->needs_remote_wakeup = 1; |
535 | 542 | ||
536 | mutex_lock(&desc->plock); | 543 | mutex_lock(&desc->lock); |
537 | if (!desc->count++) { | 544 | if (!desc->count++) { |
538 | rv = usb_submit_urb(desc->validity, GFP_KERNEL); | 545 | rv = usb_submit_urb(desc->validity, GFP_KERNEL); |
539 | if (rv < 0) { | 546 | if (rv < 0) { |
@@ -544,7 +551,7 @@ static int wdm_open(struct inode *inode, struct file *file) | |||
544 | } else { | 551 | } else { |
545 | rv = 0; | 552 | rv = 0; |
546 | } | 553 | } |
547 | mutex_unlock(&desc->plock); | 554 | mutex_unlock(&desc->lock); |
548 | usb_autopm_put_interface(desc->intf); | 555 | usb_autopm_put_interface(desc->intf); |
549 | out: | 556 | out: |
550 | mutex_unlock(&wdm_mutex); | 557 | mutex_unlock(&wdm_mutex); |
@@ -556,9 +563,9 @@ static int wdm_release(struct inode *inode, struct file *file) | |||
556 | struct wdm_device *desc = file->private_data; | 563 | struct wdm_device *desc = file->private_data; |
557 | 564 | ||
558 | mutex_lock(&wdm_mutex); | 565 | mutex_lock(&wdm_mutex); |
559 | mutex_lock(&desc->plock); | 566 | mutex_lock(&desc->lock); |
560 | desc->count--; | 567 | desc->count--; |
561 | mutex_unlock(&desc->plock); | 568 | mutex_unlock(&desc->lock); |
562 | 569 | ||
563 | if (!desc->count) { | 570 | if (!desc->count) { |
564 | dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); | 571 | dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); |
@@ -655,9 +662,7 @@ next_desc: | |||
655 | desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); | 662 | desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); |
656 | if (!desc) | 663 | if (!desc) |
657 | goto out; | 664 | goto out; |
658 | mutex_init(&desc->wlock); | 665 | mutex_init(&desc->lock); |
659 | mutex_init(&desc->rlock); | ||
660 | mutex_init(&desc->plock); | ||
661 | spin_lock_init(&desc->iuspin); | 666 | spin_lock_init(&desc->iuspin); |
662 | init_waitqueue_head(&desc->wait); | 667 | init_waitqueue_head(&desc->wait); |
663 | desc->wMaxCommand = maxcom; | 668 | desc->wMaxCommand = maxcom; |
@@ -771,14 +776,17 @@ static void wdm_disconnect(struct usb_interface *intf) | |||
771 | /* to terminate pending flushes */ | 776 | /* to terminate pending flushes */ |
772 | clear_bit(WDM_IN_USE, &desc->flags); | 777 | clear_bit(WDM_IN_USE, &desc->flags); |
773 | spin_unlock_irqrestore(&desc->iuspin, flags); | 778 | spin_unlock_irqrestore(&desc->iuspin, flags); |
774 | cancel_work_sync(&desc->rxwork); | 779 | mutex_lock(&desc->lock); |
775 | kill_urbs(desc); | 780 | kill_urbs(desc); |
781 | cancel_work_sync(&desc->rxwork); | ||
782 | mutex_unlock(&desc->lock); | ||
776 | wake_up_all(&desc->wait); | 783 | wake_up_all(&desc->wait); |
777 | if (!desc->count) | 784 | if (!desc->count) |
778 | cleanup(desc); | 785 | cleanup(desc); |
779 | mutex_unlock(&wdm_mutex); | 786 | mutex_unlock(&wdm_mutex); |
780 | } | 787 | } |
781 | 788 | ||
789 | #ifdef CONFIG_PM | ||
782 | static int wdm_suspend(struct usb_interface *intf, pm_message_t message) | 790 | static int wdm_suspend(struct usb_interface *intf, pm_message_t message) |
783 | { | 791 | { |
784 | struct wdm_device *desc = usb_get_intfdata(intf); | 792 | struct wdm_device *desc = usb_get_intfdata(intf); |
@@ -786,22 +794,30 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) | |||
786 | 794 | ||
787 | dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); | 795 | dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); |
788 | 796 | ||
789 | mutex_lock(&desc->plock); | 797 | /* if this is an autosuspend the caller does the locking */ |
790 | #ifdef CONFIG_PM | 798 | if (!(message.event & PM_EVENT_AUTO)) |
799 | mutex_lock(&desc->lock); | ||
800 | spin_lock_irq(&desc->iuspin); | ||
801 | |||
791 | if ((message.event & PM_EVENT_AUTO) && | 802 | if ((message.event & PM_EVENT_AUTO) && |
792 | test_bit(WDM_IN_USE, &desc->flags)) { | 803 | (test_bit(WDM_IN_USE, &desc->flags) |
804 | || test_bit(WDM_RESPONDING, &desc->flags))) { | ||
805 | spin_unlock_irq(&desc->iuspin); | ||
793 | rv = -EBUSY; | 806 | rv = -EBUSY; |
794 | } else { | 807 | } else { |
795 | #endif | 808 | |
796 | cancel_work_sync(&desc->rxwork); | 809 | set_bit(WDM_SUSPENDING, &desc->flags); |
810 | spin_unlock_irq(&desc->iuspin); | ||
811 | /* callback submits work - order is essential */ | ||
797 | kill_urbs(desc); | 812 | kill_urbs(desc); |
798 | #ifdef CONFIG_PM | 813 | cancel_work_sync(&desc->rxwork); |
799 | } | 814 | } |
800 | #endif | 815 | if (!(message.event & PM_EVENT_AUTO)) |
801 | mutex_unlock(&desc->plock); | 816 | mutex_unlock(&desc->lock); |
802 | 817 | ||
803 | return rv; | 818 | return rv; |
804 | } | 819 | } |
820 | #endif | ||
805 | 821 | ||
806 | static int recover_from_urb_loss(struct wdm_device *desc) | 822 | static int recover_from_urb_loss(struct wdm_device *desc) |
807 | { | 823 | { |
@@ -815,23 +831,27 @@ static int recover_from_urb_loss(struct wdm_device *desc) | |||
815 | } | 831 | } |
816 | return rv; | 832 | return rv; |
817 | } | 833 | } |
834 | |||
835 | #ifdef CONFIG_PM | ||
818 | static int wdm_resume(struct usb_interface *intf) | 836 | static int wdm_resume(struct usb_interface *intf) |
819 | { | 837 | { |
820 | struct wdm_device *desc = usb_get_intfdata(intf); | 838 | struct wdm_device *desc = usb_get_intfdata(intf); |
821 | int rv; | 839 | int rv; |
822 | 840 | ||
823 | dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); | 841 | dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); |
824 | mutex_lock(&desc->plock); | 842 | |
843 | clear_bit(WDM_SUSPENDING, &desc->flags); | ||
825 | rv = recover_from_urb_loss(desc); | 844 | rv = recover_from_urb_loss(desc); |
826 | mutex_unlock(&desc->plock); | 845 | |
827 | return rv; | 846 | return rv; |
828 | } | 847 | } |
848 | #endif | ||
829 | 849 | ||
830 | static int wdm_pre_reset(struct usb_interface *intf) | 850 | static int wdm_pre_reset(struct usb_interface *intf) |
831 | { | 851 | { |
832 | struct wdm_device *desc = usb_get_intfdata(intf); | 852 | struct wdm_device *desc = usb_get_intfdata(intf); |
833 | 853 | ||
834 | mutex_lock(&desc->plock); | 854 | mutex_lock(&desc->lock); |
835 | return 0; | 855 | return 0; |
836 | } | 856 | } |
837 | 857 | ||
@@ -841,7 +861,7 @@ static int wdm_post_reset(struct usb_interface *intf) | |||
841 | int rv; | 861 | int rv; |
842 | 862 | ||
843 | rv = recover_from_urb_loss(desc); | 863 | rv = recover_from_urb_loss(desc); |
844 | mutex_unlock(&desc->plock); | 864 | mutex_unlock(&desc->lock); |
845 | return 0; | 865 | return 0; |
846 | } | 866 | } |
847 | 867 | ||
@@ -849,9 +869,11 @@ static struct usb_driver wdm_driver = { | |||
849 | .name = "cdc_wdm", | 869 | .name = "cdc_wdm", |
850 | .probe = wdm_probe, | 870 | .probe = wdm_probe, |
851 | .disconnect = wdm_disconnect, | 871 | .disconnect = wdm_disconnect, |
872 | #ifdef CONFIG_PM | ||
852 | .suspend = wdm_suspend, | 873 | .suspend = wdm_suspend, |
853 | .resume = wdm_resume, | 874 | .resume = wdm_resume, |
854 | .reset_resume = wdm_resume, | 875 | .reset_resume = wdm_resume, |
876 | #endif | ||
855 | .pre_reset = wdm_pre_reset, | 877 | .pre_reset = wdm_pre_reset, |
856 | .post_reset = wdm_post_reset, | 878 | .post_reset = wdm_post_reset, |
857 | .id_table = wdm_ids, | 879 | .id_table = wdm_ids, |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e909ff7b9094..3466fdc5bb11 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -1207,6 +1207,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1207 | free_async(as); | 1207 | free_async(as); |
1208 | return -ENOMEM; | 1208 | return -ENOMEM; |
1209 | } | 1209 | } |
1210 | /* Isochronous input data may end up being discontiguous | ||
1211 | * if some of the packets are short. Clear the buffer so | ||
1212 | * that the gaps don't leak kernel data to userspace. | ||
1213 | */ | ||
1214 | if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO) | ||
1215 | memset(as->urb->transfer_buffer, 0, | ||
1216 | uurb->buffer_length); | ||
1210 | } | 1217 | } |
1211 | as->urb->dev = ps->dev; | 1218 | as->urb->dev = ps->dev; |
1212 | as->urb->pipe = (uurb->type << 30) | | 1219 | as->urb->pipe = (uurb->type << 30) | |
@@ -1345,10 +1352,14 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1345 | void __user *addr = as->userurb; | 1352 | void __user *addr = as->userurb; |
1346 | unsigned int i; | 1353 | unsigned int i; |
1347 | 1354 | ||
1348 | if (as->userbuffer && urb->actual_length) | 1355 | if (as->userbuffer && urb->actual_length) { |
1349 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, | 1356 | if (urb->number_of_packets > 0) /* Isochronous */ |
1350 | urb->actual_length)) | 1357 | i = urb->transfer_buffer_length; |
1358 | else /* Non-Isoc */ | ||
1359 | i = urb->actual_length; | ||
1360 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) | ||
1351 | goto err_out; | 1361 | goto err_out; |
1362 | } | ||
1352 | if (put_user(as->status, &userurb->status)) | 1363 | if (put_user(as->status, &userurb->status)) |
1353 | goto err_out; | 1364 | goto err_out; |
1354 | if (put_user(urb->actual_length, &userurb->actual_length)) | 1365 | if (put_user(urb->actual_length, &userurb->actual_length)) |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 27080561a1c2..45a32dadb406 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -453,6 +453,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
453 | if (urb->interval > (1 << 15)) | 453 | if (urb->interval > (1 << 15)) |
454 | return -EINVAL; | 454 | return -EINVAL; |
455 | max = 1 << 15; | 455 | max = 1 << 15; |
456 | break; | ||
456 | case USB_SPEED_WIRELESS: | 457 | case USB_SPEED_WIRELESS: |
457 | if (urb->interval > 16) | 458 | if (urb->interval > 16) |
458 | return -EINVAL; | 459 | return -EINVAL; |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 7460cd797f45..11a3e0fa4331 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -747,7 +747,7 @@ config USB_MASS_STORAGE | |||
747 | which may be used with composite framework. | 747 | which may be used with composite framework. |
748 | 748 | ||
749 | Say "y" to link the driver statically, or "m" to build | 749 | Say "y" to link the driver statically, or "m" to build |
750 | a dynamically linked module called "g_file_storage". If unsure, | 750 | a dynamically linked module called "g_mass_storage". If unsure, |
751 | consider File-backed Storage Gadget. | 751 | consider File-backed Storage Gadget. |
752 | 752 | ||
753 | config USB_G_SERIAL | 753 | config USB_G_SERIAL |
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 65a5f94cbc04..3568de210f79 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -266,7 +266,7 @@ struct usb_ep * __init usb_ep_autoconfig ( | |||
266 | } | 266 | } |
267 | 267 | ||
268 | #ifdef CONFIG_BLACKFIN | 268 | #ifdef CONFIG_BLACKFIN |
269 | } else if (gadget_is_musbhsfc(gadget) || gadget_is_musbhdrc(gadget)) { | 269 | } else if (gadget_is_musbhdrc(gadget)) { |
270 | if ((USB_ENDPOINT_XFER_BULK == type) || | 270 | if ((USB_ENDPOINT_XFER_BULK == type) || |
271 | (USB_ENDPOINT_XFER_ISOC == type)) { | 271 | (USB_ENDPOINT_XFER_ISOC == type)) { |
272 | if (USB_DIR_IN & desc->bEndpointAddress) | 272 | if (USB_DIR_IN & desc->bEndpointAddress) |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 5a3cdd08f1d0..f4911c09022e 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -2910,7 +2910,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) | |||
2910 | } | 2910 | } |
2911 | 2911 | ||
2912 | 2912 | ||
2913 | static int fsg_bind(struct usb_configuration *c, struct usb_function *f) | 2913 | static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f) |
2914 | { | 2914 | { |
2915 | struct fsg_dev *fsg = fsg_from_func(f); | 2915 | struct fsg_dev *fsg = fsg_from_func(f); |
2916 | struct usb_gadget *gadget = c->cdev->gadget; | 2916 | struct usb_gadget *gadget = c->cdev->gadget; |
@@ -2954,7 +2954,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) | |||
2954 | autoconf_fail: | 2954 | autoconf_fail: |
2955 | ERROR(fsg, "unable to autoconfigure all endpoints\n"); | 2955 | ERROR(fsg, "unable to autoconfigure all endpoints\n"); |
2956 | rc = -ENOTSUPP; | 2956 | rc = -ENOTSUPP; |
2957 | fsg_unbind(c, f); | ||
2958 | return rc; | 2957 | return rc; |
2959 | } | 2958 | } |
2960 | 2959 | ||
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index 1edbc12fff18..e511fec9f26d 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -136,6 +136,12 @@ | |||
136 | #define gadget_is_r8a66597(g) 0 | 136 | #define gadget_is_r8a66597(g) 0 |
137 | #endif | 137 | #endif |
138 | 138 | ||
139 | #ifdef CONFIG_USB_S3C_HSOTG | ||
140 | #define gadget_is_s3c_hsotg(g) (!strcmp("s3c-hsotg", (g)->name)) | ||
141 | #else | ||
142 | #define gadget_is_s3c_hsotg(g) 0 | ||
143 | #endif | ||
144 | |||
139 | 145 | ||
140 | /** | 146 | /** |
141 | * usb_gadget_controller_number - support bcdDevice id convention | 147 | * usb_gadget_controller_number - support bcdDevice id convention |
@@ -192,6 +198,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
192 | return 0x24; | 198 | return 0x24; |
193 | else if (gadget_is_r8a66597(gadget)) | 199 | else if (gadget_is_r8a66597(gadget)) |
194 | return 0x25; | 200 | return 0x25; |
201 | else if (gadget_is_s3c_hsotg(gadget)) | ||
202 | return 0x26; | ||
195 | return -ENOENT; | 203 | return -ENOENT; |
196 | } | 204 | } |
197 | 205 | ||
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index e8edc640381e..1088d08c7ed8 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1768,7 +1768,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1768 | * usb_gadget_driver_{register,unregister}() must change. | 1768 | * usb_gadget_driver_{register,unregister}() must change. |
1769 | */ | 1769 | */ |
1770 | if (the_controller) { | 1770 | if (the_controller) { |
1771 | WARNING(dev, "ignoring %s\n", pci_name(pdev)); | 1771 | pr_warning("ignoring %s\n", pci_name(pdev)); |
1772 | return -EBUSY; | 1772 | return -EBUSY; |
1773 | } | 1773 | } |
1774 | if (!pdev->irq) { | 1774 | if (!pdev->irq) { |
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 76496f5d272c..a930d7fd7e7a 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c | |||
@@ -211,8 +211,6 @@ static int __init cdc_do_config(struct usb_configuration *c) | |||
211 | ret = fsg_add(c->cdev, c, fsg_common); | 211 | ret = fsg_add(c->cdev, c, fsg_common); |
212 | if (ret < 0) | 212 | if (ret < 0) |
213 | return ret; | 213 | return ret; |
214 | if (ret < 0) | ||
215 | return ret; | ||
216 | 214 | ||
217 | return 0; | 215 | return 0; |
218 | } | 216 | } |
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 8b45145b9136..5e13d23b5f0c 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/err.h> | ||
26 | #include <linux/io.h> | 27 | #include <linux/io.h> |
27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
28 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 4e0c67f1f51b..b6315aa47f7a 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -12,7 +12,7 @@ fhci-objs := fhci-hcd.o fhci-hub.o fhci-q.o fhci-mem.o \ | |||
12 | ifeq ($(CONFIG_FHCI_DEBUG),y) | 12 | ifeq ($(CONFIG_FHCI_DEBUG),y) |
13 | fhci-objs += fhci-dbg.o | 13 | fhci-objs += fhci-dbg.o |
14 | endif | 14 | endif |
15 | xhci-objs := xhci-hcd.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o | 15 | xhci-hcd-objs := xhci.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o |
16 | 16 | ||
17 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ | 17 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ |
18 | 18 | ||
@@ -25,7 +25,7 @@ obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o | |||
25 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o | 25 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o |
26 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o | 26 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o |
27 | obj-$(CONFIG_USB_FHCI_HCD) += fhci.o | 27 | obj-$(CONFIG_USB_FHCI_HCD) += fhci.o |
28 | obj-$(CONFIG_USB_XHCI_HCD) += xhci.o | 28 | obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o |
29 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o | 29 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o |
30 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o | 30 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o |
31 | obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o | 31 | obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index d8d6d3461d32..dc55a62859c6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -995,7 +995,7 @@ rescan: | |||
995 | /* endpoints can be iso streams. for now, we don't | 995 | /* endpoints can be iso streams. for now, we don't |
996 | * accelerate iso completions ... so spin a while. | 996 | * accelerate iso completions ... so spin a while. |
997 | */ | 997 | */ |
998 | if (qh->hw->hw_info1 == 0) { | 998 | if (qh->hw == NULL) { |
999 | ehci_vdbg (ehci, "iso delay\n"); | 999 | ehci_vdbg (ehci, "iso delay\n"); |
1000 | goto idle_timeout; | 1000 | goto idle_timeout; |
1001 | } | 1001 | } |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 39340ae00ac4..a0aaaaff2560 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1123,8 +1123,8 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) | |||
1123 | urb->interval); | 1123 | urb->interval); |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */ | 1126 | /* if dev->ep [epnum] is a QH, hw is set */ |
1127 | } else if (unlikely (stream->hw_info1 != 0)) { | 1127 | } else if (unlikely (stream->hw != NULL)) { |
1128 | ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", | 1128 | ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", |
1129 | urb->dev->devpath, epnum, | 1129 | urb->dev->devpath, epnum, |
1130 | usb_pipein(urb->pipe) ? "in" : "out"); | 1130 | usb_pipein(urb->pipe) ? "in" : "out"); |
@@ -1565,13 +1565,27 @@ itd_patch( | |||
1565 | static inline void | 1565 | static inline void |
1566 | itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) | 1566 | itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) |
1567 | { | 1567 | { |
1568 | /* always prepend ITD/SITD ... only QH tree is order-sensitive */ | 1568 | union ehci_shadow *prev = &ehci->pshadow[frame]; |
1569 | itd->itd_next = ehci->pshadow [frame]; | 1569 | __hc32 *hw_p = &ehci->periodic[frame]; |
1570 | itd->hw_next = ehci->periodic [frame]; | 1570 | union ehci_shadow here = *prev; |
1571 | ehci->pshadow [frame].itd = itd; | 1571 | __hc32 type = 0; |
1572 | |||
1573 | /* skip any iso nodes which might belong to previous microframes */ | ||
1574 | while (here.ptr) { | ||
1575 | type = Q_NEXT_TYPE(ehci, *hw_p); | ||
1576 | if (type == cpu_to_hc32(ehci, Q_TYPE_QH)) | ||
1577 | break; | ||
1578 | prev = periodic_next_shadow(ehci, prev, type); | ||
1579 | hw_p = shadow_next_periodic(ehci, &here, type); | ||
1580 | here = *prev; | ||
1581 | } | ||
1582 | |||
1583 | itd->itd_next = here; | ||
1584 | itd->hw_next = *hw_p; | ||
1585 | prev->itd = itd; | ||
1572 | itd->frame = frame; | 1586 | itd->frame = frame; |
1573 | wmb (); | 1587 | wmb (); |
1574 | ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); | 1588 | *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); |
1575 | } | 1589 | } |
1576 | 1590 | ||
1577 | /* fit urb's itds into the selected schedule slot; activate as needed */ | 1591 | /* fit urb's itds into the selected schedule slot; activate as needed */ |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2d85e21ff282..b1dce96dd621 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -394,9 +394,8 @@ struct ehci_iso_sched { | |||
394 | * acts like a qh would, if EHCI had them for ISO. | 394 | * acts like a qh would, if EHCI had them for ISO. |
395 | */ | 395 | */ |
396 | struct ehci_iso_stream { | 396 | struct ehci_iso_stream { |
397 | /* first two fields match QH, but info1 == 0 */ | 397 | /* first field matches ehci_hq, but is NULL */ |
398 | __hc32 hw_next; | 398 | struct ehci_qh_hw *hw; |
399 | __hc32 hw_info1; | ||
400 | 399 | ||
401 | u32 refcount; | 400 | u32 refcount; |
402 | u8 bEndpointAddress; | 401 | u8 bEndpointAddress; |
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index bee558aed427..f71a73a93d0c 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -418,7 +418,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb) | |||
418 | 418 | ||
419 | /* this function must be called with interrupt disabled */ | 419 | /* this function must be called with interrupt disabled */ |
420 | static void free_usb_address(struct r8a66597 *r8a66597, | 420 | static void free_usb_address(struct r8a66597 *r8a66597, |
421 | struct r8a66597_device *dev) | 421 | struct r8a66597_device *dev, int reset) |
422 | { | 422 | { |
423 | int port; | 423 | int port; |
424 | 424 | ||
@@ -430,7 +430,13 @@ static void free_usb_address(struct r8a66597 *r8a66597, | |||
430 | dev->state = USB_STATE_DEFAULT; | 430 | dev->state = USB_STATE_DEFAULT; |
431 | r8a66597->address_map &= ~(1 << dev->address); | 431 | r8a66597->address_map &= ~(1 << dev->address); |
432 | dev->address = 0; | 432 | dev->address = 0; |
433 | dev_set_drvdata(&dev->udev->dev, NULL); | 433 | /* |
434 | * Only when resetting USB, it is necessary to erase drvdata. When | ||
435 | * a usb device with usb hub is disconnect, "dev->udev" is already | ||
436 | * freed on usb_desconnect(). So we cannot access the data. | ||
437 | */ | ||
438 | if (reset) | ||
439 | dev_set_drvdata(&dev->udev->dev, NULL); | ||
434 | list_del(&dev->device_list); | 440 | list_del(&dev->device_list); |
435 | kfree(dev); | 441 | kfree(dev); |
436 | 442 | ||
@@ -1069,7 +1075,7 @@ static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port) | |||
1069 | struct r8a66597_device *dev = r8a66597->root_hub[port].dev; | 1075 | struct r8a66597_device *dev = r8a66597->root_hub[port].dev; |
1070 | 1076 | ||
1071 | disable_r8a66597_pipe_all(r8a66597, dev); | 1077 | disable_r8a66597_pipe_all(r8a66597, dev); |
1072 | free_usb_address(r8a66597, dev); | 1078 | free_usb_address(r8a66597, dev, 0); |
1073 | 1079 | ||
1074 | start_root_hub_sampling(r8a66597, port, 0); | 1080 | start_root_hub_sampling(r8a66597, port, 0); |
1075 | } | 1081 | } |
@@ -2085,7 +2091,7 @@ static void update_usb_address_map(struct r8a66597 *r8a66597, | |||
2085 | spin_lock_irqsave(&r8a66597->lock, flags); | 2091 | spin_lock_irqsave(&r8a66597->lock, flags); |
2086 | dev = get_r8a66597_device(r8a66597, addr); | 2092 | dev = get_r8a66597_device(r8a66597, addr); |
2087 | disable_r8a66597_pipe_all(r8a66597, dev); | 2093 | disable_r8a66597_pipe_all(r8a66597, dev); |
2088 | free_usb_address(r8a66597, dev); | 2094 | free_usb_address(r8a66597, dev, 0); |
2089 | put_child_connect_map(r8a66597, addr); | 2095 | put_child_connect_map(r8a66597, addr); |
2090 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 2096 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
2091 | } | 2097 | } |
@@ -2228,7 +2234,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
2228 | rh->port |= (1 << USB_PORT_FEAT_RESET); | 2234 | rh->port |= (1 << USB_PORT_FEAT_RESET); |
2229 | 2235 | ||
2230 | disable_r8a66597_pipe_all(r8a66597, dev); | 2236 | disable_r8a66597_pipe_all(r8a66597, dev); |
2231 | free_usb_address(r8a66597, dev); | 2237 | free_usb_address(r8a66597, dev, 1); |
2232 | 2238 | ||
2233 | r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, | 2239 | r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, |
2234 | get_dvstctr_reg(port)); | 2240 | get_dvstctr_reg(port)); |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 49f7d72f8b1b..bba9b19ed1b9 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -566,8 +566,13 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, | |||
566 | if (interval < 3) | 566 | if (interval < 3) |
567 | interval = 3; | 567 | interval = 3; |
568 | if ((1 << interval) != 8*ep->desc.bInterval) | 568 | if ((1 << interval) != 8*ep->desc.bInterval) |
569 | dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n", | 569 | dev_warn(&udev->dev, |
570 | ep->desc.bEndpointAddress, 1 << interval); | 570 | "ep %#x - rounding interval" |
571 | " to %d microframes, " | ||
572 | "ep desc says %d microframes\n", | ||
573 | ep->desc.bEndpointAddress, | ||
574 | 1 << interval, | ||
575 | 8*ep->desc.bInterval); | ||
571 | } | 576 | } |
572 | break; | 577 | break; |
573 | default: | 578 | default: |
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci.c index 4cb69e0af834..492a61c2c79d 100644 --- a/drivers/usb/host/xhci-hcd.c +++ b/drivers/usb/host/xhci.c | |||
@@ -1173,6 +1173,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
1173 | cmd_completion = &virt_dev->cmd_completion; | 1173 | cmd_completion = &virt_dev->cmd_completion; |
1174 | cmd_status = &virt_dev->cmd_status; | 1174 | cmd_status = &virt_dev->cmd_status; |
1175 | } | 1175 | } |
1176 | init_completion(cmd_completion); | ||
1176 | 1177 | ||
1177 | if (!ctx_change) | 1178 | if (!ctx_change) |
1178 | ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, | 1179 | ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b4bbf8f2c238..0e8b8ab1d168 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -379,7 +379,6 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
379 | u8 devctl, u8 power) | 379 | u8 devctl, u8 power) |
380 | { | 380 | { |
381 | irqreturn_t handled = IRQ_NONE; | 381 | irqreturn_t handled = IRQ_NONE; |
382 | void __iomem *mbase = musb->mregs; | ||
383 | 382 | ||
384 | DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, | 383 | DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, |
385 | int_usb); | 384 | int_usb); |
@@ -394,6 +393,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
394 | 393 | ||
395 | if (devctl & MUSB_DEVCTL_HM) { | 394 | if (devctl & MUSB_DEVCTL_HM) { |
396 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 395 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
396 | void __iomem *mbase = musb->mregs; | ||
397 | |||
397 | switch (musb->xceiv->state) { | 398 | switch (musb->xceiv->state) { |
398 | case OTG_STATE_A_SUSPEND: | 399 | case OTG_STATE_A_SUSPEND: |
399 | /* remote wakeup? later, GetPortStatus | 400 | /* remote wakeup? later, GetPortStatus |
@@ -471,6 +472,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
471 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 472 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
472 | /* see manual for the order of the tests */ | 473 | /* see manual for the order of the tests */ |
473 | if (int_usb & MUSB_INTR_SESSREQ) { | 474 | if (int_usb & MUSB_INTR_SESSREQ) { |
475 | void __iomem *mbase = musb->mregs; | ||
476 | |||
474 | DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); | 477 | DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); |
475 | 478 | ||
476 | /* IRQ arrives from ID pin sense or (later, if VBUS power | 479 | /* IRQ arrives from ID pin sense or (later, if VBUS power |
@@ -519,6 +522,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
519 | case OTG_STATE_A_WAIT_BCON: | 522 | case OTG_STATE_A_WAIT_BCON: |
520 | case OTG_STATE_A_WAIT_VRISE: | 523 | case OTG_STATE_A_WAIT_VRISE: |
521 | if (musb->vbuserr_retry) { | 524 | if (musb->vbuserr_retry) { |
525 | void __iomem *mbase = musb->mregs; | ||
526 | |||
522 | musb->vbuserr_retry--; | 527 | musb->vbuserr_retry--; |
523 | ignore = 1; | 528 | ignore = 1; |
524 | devctl |= MUSB_DEVCTL_SESSION; | 529 | devctl |= MUSB_DEVCTL_SESSION; |
@@ -622,6 +627,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
622 | 627 | ||
623 | if (int_usb & MUSB_INTR_CONNECT) { | 628 | if (int_usb & MUSB_INTR_CONNECT) { |
624 | struct usb_hcd *hcd = musb_to_hcd(musb); | 629 | struct usb_hcd *hcd = musb_to_hcd(musb); |
630 | void __iomem *mbase = musb->mregs; | ||
625 | 631 | ||
626 | handled = IRQ_HANDLED; | 632 | handled = IRQ_HANDLED; |
627 | musb->is_active = 1; | 633 | musb->is_active = 1; |
@@ -2007,7 +2013,6 @@ bad_config: | |||
2007 | /* host side needs more setup */ | 2013 | /* host side needs more setup */ |
2008 | if (is_host_enabled(musb)) { | 2014 | if (is_host_enabled(musb)) { |
2009 | struct usb_hcd *hcd = musb_to_hcd(musb); | 2015 | struct usb_hcd *hcd = musb_to_hcd(musb); |
2010 | u8 busctl; | ||
2011 | 2016 | ||
2012 | otg_set_host(musb->xceiv, &hcd->self); | 2017 | otg_set_host(musb->xceiv, &hcd->self); |
2013 | 2018 | ||
@@ -2018,9 +2023,9 @@ bad_config: | |||
2018 | 2023 | ||
2019 | /* program PHY to use external vBus if required */ | 2024 | /* program PHY to use external vBus if required */ |
2020 | if (plat->extvbus) { | 2025 | if (plat->extvbus) { |
2021 | busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL); | 2026 | u8 busctl = musb_read_ulpi_buscontrol(musb->mregs); |
2022 | busctl |= MUSB_ULPI_USE_EXTVBUS; | 2027 | busctl |= MUSB_ULPI_USE_EXTVBUS; |
2023 | musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl); | 2028 | musb_write_ulpi_buscontrol(musb->mregs, busctl); |
2024 | } | 2029 | } |
2025 | } | 2030 | } |
2026 | 2031 | ||
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index d849fb81c131..cd9f4a9a06c6 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -469,7 +469,7 @@ struct musb_csr_regs { | |||
469 | 469 | ||
470 | struct musb_context_registers { | 470 | struct musb_context_registers { |
471 | 471 | ||
472 | #if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) | 472 | #ifdef CONFIG_PM |
473 | u32 otg_sysconfig, otg_forcestandby; | 473 | u32 otg_sysconfig, otg_forcestandby; |
474 | #endif | 474 | #endif |
475 | u8 power; | 475 | u8 power; |
@@ -483,7 +483,7 @@ struct musb_context_registers { | |||
483 | struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; | 483 | struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; |
484 | }; | 484 | }; |
485 | 485 | ||
486 | #if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) | 486 | #ifdef CONFIG_PM |
487 | extern void musb_platform_save_context(struct musb *musb, | 487 | extern void musb_platform_save_context(struct musb *musb, |
488 | struct musb_context_registers *musb_context); | 488 | struct musb_context_registers *musb_context); |
489 | extern void musb_platform_restore_context(struct musb *musb, | 489 | extern void musb_platform_restore_context(struct musb *musb, |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 3421cf9858b5..dec896e888db 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -1689,7 +1689,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1689 | dma->desired_mode = 1; | 1689 | dma->desired_mode = 1; |
1690 | if (rx_count < hw_ep->max_packet_sz_rx) { | 1690 | if (rx_count < hw_ep->max_packet_sz_rx) { |
1691 | length = rx_count; | 1691 | length = rx_count; |
1692 | dma->bDesiredMode = 0; | 1692 | dma->desired_mode = 0; |
1693 | } else { | 1693 | } else { |
1694 | length = urb->transfer_buffer_length; | 1694 | length = urb->transfer_buffer_length; |
1695 | } | 1695 | } |
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 8d8062b10e2f..fa55aacc385d 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h | |||
@@ -326,6 +326,11 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) | |||
326 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); | 326 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); |
327 | } | 327 | } |
328 | 328 | ||
329 | static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) | ||
330 | { | ||
331 | musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val); | ||
332 | } | ||
333 | |||
329 | static inline u8 musb_read_txfifosz(void __iomem *mbase) | 334 | static inline u8 musb_read_txfifosz(void __iomem *mbase) |
330 | { | 335 | { |
331 | return musb_readb(mbase, MUSB_TXFIFOSZ); | 336 | return musb_readb(mbase, MUSB_TXFIFOSZ); |
@@ -346,6 +351,11 @@ static inline u16 musb_read_rxfifoadd(void __iomem *mbase) | |||
346 | return musb_readw(mbase, MUSB_RXFIFOADD); | 351 | return musb_readw(mbase, MUSB_RXFIFOADD); |
347 | } | 352 | } |
348 | 353 | ||
354 | static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) | ||
355 | { | ||
356 | return musb_readb(mbase, MUSB_ULPI_BUSCONTROL); | ||
357 | } | ||
358 | |||
349 | static inline u8 musb_read_configdata(void __iomem *mbase) | 359 | static inline u8 musb_read_configdata(void __iomem *mbase) |
350 | { | 360 | { |
351 | musb_writeb(mbase, MUSB_INDEX, 0); | 361 | musb_writeb(mbase, MUSB_INDEX, 0); |
@@ -510,20 +520,33 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) | |||
510 | { | 520 | { |
511 | } | 521 | } |
512 | 522 | ||
523 | static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) | ||
524 | { | ||
525 | } | ||
526 | |||
513 | static inline u8 musb_read_txfifosz(void __iomem *mbase) | 527 | static inline u8 musb_read_txfifosz(void __iomem *mbase) |
514 | { | 528 | { |
529 | return 0; | ||
515 | } | 530 | } |
516 | 531 | ||
517 | static inline u16 musb_read_txfifoadd(void __iomem *mbase) | 532 | static inline u16 musb_read_txfifoadd(void __iomem *mbase) |
518 | { | 533 | { |
534 | return 0; | ||
519 | } | 535 | } |
520 | 536 | ||
521 | static inline u8 musb_read_rxfifosz(void __iomem *mbase) | 537 | static inline u8 musb_read_rxfifosz(void __iomem *mbase) |
522 | { | 538 | { |
539 | return 0; | ||
523 | } | 540 | } |
524 | 541 | ||
525 | static inline u16 musb_read_rxfifoadd(void __iomem *mbase) | 542 | static inline u16 musb_read_rxfifoadd(void __iomem *mbase) |
526 | { | 543 | { |
544 | return 0; | ||
545 | } | ||
546 | |||
547 | static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) | ||
548 | { | ||
549 | return 0; | ||
527 | } | 550 | } |
528 | 551 | ||
529 | static inline u8 musb_read_configdata(void __iomem *mbase) | 552 | static inline u8 musb_read_configdata(void __iomem *mbase) |
@@ -577,22 +600,27 @@ static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, | |||
577 | 600 | ||
578 | static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) | 601 | static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) |
579 | { | 602 | { |
603 | return 0; | ||
580 | } | 604 | } |
581 | 605 | ||
582 | static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) | 606 | static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) |
583 | { | 607 | { |
608 | return 0; | ||
584 | } | 609 | } |
585 | 610 | ||
586 | static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) | 611 | static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) |
587 | { | 612 | { |
613 | return 0; | ||
588 | } | 614 | } |
589 | 615 | ||
590 | static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) | 616 | static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) |
591 | { | 617 | { |
618 | return 0; | ||
592 | } | 619 | } |
593 | 620 | ||
594 | static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) | 621 | static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) |
595 | { | 622 | { |
623 | return 0; | ||
596 | } | 624 | } |
597 | 625 | ||
598 | static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) | 626 | static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index c78b255e3f83..a0ecb42cb33a 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -474,14 +474,14 @@ config USB_SERIAL_OTI6858 | |||
474 | 474 | ||
475 | config USB_SERIAL_QCAUX | 475 | config USB_SERIAL_QCAUX |
476 | tristate "USB Qualcomm Auxiliary Serial Port Driver" | 476 | tristate "USB Qualcomm Auxiliary Serial Port Driver" |
477 | ---help--- | 477 | help |
478 | Say Y here if you want to use the auxiliary serial ports provided | 478 | Say Y here if you want to use the auxiliary serial ports provided |
479 | by many modems based on Qualcomm chipsets. These ports often use | 479 | by many modems based on Qualcomm chipsets. These ports often use |
480 | a proprietary protocol called DM and cannot be used for AT- or | 480 | a proprietary protocol called DM and cannot be used for AT- or |
481 | PPP-based communication. | 481 | PPP-based communication. |
482 | 482 | ||
483 | To compile this driver as a module, choose M here: the | 483 | To compile this driver as a module, choose M here: the |
484 | module will be called moto_modem. If unsure, choose N. | 484 | module will be called qcaux. If unsure, choose N. |
485 | 485 | ||
486 | config USB_SERIAL_QUALCOMM | 486 | config USB_SERIAL_QUALCOMM |
487 | tristate "USB Qualcomm Serial modem" | 487 | tristate "USB Qualcomm Serial modem" |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 507382b0a9ed..ec9b0449ccf6 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -313,11 +313,6 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, | |||
313 | return -EPROTO; | 313 | return -EPROTO; |
314 | } | 314 | } |
315 | 315 | ||
316 | /* Single data value */ | ||
317 | result = usb_control_msg(serial->dev, | ||
318 | usb_sndctrlpipe(serial->dev, 0), | ||
319 | request, REQTYPE_HOST_TO_DEVICE, data[0], | ||
320 | 0, NULL, 0, 300); | ||
321 | return 0; | 316 | return 0; |
322 | } | 317 | } |
323 | 318 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 6af0dfa5f5ac..1d7c4fac02e8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -91,7 +91,7 @@ struct ftdi_private { | |||
91 | unsigned long tx_outstanding_bytes; | 91 | unsigned long tx_outstanding_bytes; |
92 | unsigned long tx_outstanding_urbs; | 92 | unsigned long tx_outstanding_urbs; |
93 | unsigned short max_packet_size; | 93 | unsigned short max_packet_size; |
94 | struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() */ | 94 | struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */ |
95 | }; | 95 | }; |
96 | 96 | ||
97 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ | 97 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ |
@@ -658,6 +658,7 @@ static struct usb_device_id id_table_combined [] = { | |||
658 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, | 658 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, |
659 | { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, | 659 | { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, |
660 | { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, | 660 | { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, |
661 | { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, | ||
661 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, | 662 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, |
662 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, | 663 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, |
663 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, | 664 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, |
@@ -1272,8 +1273,8 @@ check_and_exit: | |||
1272 | (priv->flags & ASYNC_SPD_MASK)) || | 1273 | (priv->flags & ASYNC_SPD_MASK)) || |
1273 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && | 1274 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && |
1274 | (old_priv.custom_divisor != priv->custom_divisor))) { | 1275 | (old_priv.custom_divisor != priv->custom_divisor))) { |
1275 | mutex_unlock(&priv->cfg_lock); | ||
1276 | change_speed(tty, port); | 1276 | change_speed(tty, port); |
1277 | mutex_unlock(&priv->cfg_lock); | ||
1277 | } | 1278 | } |
1278 | else | 1279 | else |
1279 | mutex_unlock(&priv->cfg_lock); | 1280 | mutex_unlock(&priv->cfg_lock); |
@@ -2264,9 +2265,11 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2264 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | 2265 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
2265 | } else { | 2266 | } else { |
2266 | /* set the baudrate determined before */ | 2267 | /* set the baudrate determined before */ |
2268 | mutex_lock(&priv->cfg_lock); | ||
2267 | if (change_speed(tty, port)) | 2269 | if (change_speed(tty, port)) |
2268 | dev_err(&port->dev, "%s urb failed to set baudrate\n", | 2270 | dev_err(&port->dev, "%s urb failed to set baudrate\n", |
2269 | __func__); | 2271 | __func__); |
2272 | mutex_unlock(&priv->cfg_lock); | ||
2270 | /* Ensure RTS and DTR are raised when baudrate changed from 0 */ | 2273 | /* Ensure RTS and DTR are raised when baudrate changed from 0 */ |
2271 | if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) | 2274 | if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) |
2272 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | 2275 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 0727e198503e..75482cbc3998 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -501,6 +501,13 @@ | |||
501 | #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ | 501 | #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ |
502 | 502 | ||
503 | /* | 503 | /* |
504 | * Contec products (http://www.contec.com) | ||
505 | * Submitted by Daniel Sangorrin | ||
506 | */ | ||
507 | #define CONTEC_VID 0x06CE /* Vendor ID */ | ||
508 | #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ | ||
509 | |||
510 | /* | ||
504 | * Definitions for B&B Electronics products. | 511 | * Definitions for B&B Electronics products. |
505 | */ | 512 | */ |
506 | #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ | 513 | #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 89fac36684c5..f804acb138ec 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -130,7 +130,7 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port | |||
130 | spin_unlock_irqrestore(&port->lock, flags); | 130 | spin_unlock_irqrestore(&port->lock, flags); |
131 | 131 | ||
132 | /* if we have a bulk endpoint, start reading from it */ | 132 | /* if we have a bulk endpoint, start reading from it */ |
133 | if (serial->num_bulk_in) { | 133 | if (port->bulk_in_size) { |
134 | /* Start reading from the device */ | 134 | /* Start reading from the device */ |
135 | usb_fill_bulk_urb(port->read_urb, serial->dev, | 135 | usb_fill_bulk_urb(port->read_urb, serial->dev, |
136 | usb_rcvbulkpipe(serial->dev, | 136 | usb_rcvbulkpipe(serial->dev, |
@@ -159,10 +159,10 @@ static void generic_cleanup(struct usb_serial_port *port) | |||
159 | dbg("%s - port %d", __func__, port->number); | 159 | dbg("%s - port %d", __func__, port->number); |
160 | 160 | ||
161 | if (serial->dev) { | 161 | if (serial->dev) { |
162 | /* shutdown any bulk reads that might be going on */ | 162 | /* shutdown any bulk transfers that might be going on */ |
163 | if (serial->num_bulk_out) | 163 | if (port->bulk_out_size) |
164 | usb_kill_urb(port->write_urb); | 164 | usb_kill_urb(port->write_urb); |
165 | if (serial->num_bulk_in) | 165 | if (port->bulk_in_size) |
166 | usb_kill_urb(port->read_urb); | 166 | usb_kill_urb(port->read_urb); |
167 | } | 167 | } |
168 | } | 168 | } |
@@ -333,15 +333,15 @@ int usb_serial_generic_write(struct tty_struct *tty, | |||
333 | 333 | ||
334 | dbg("%s - port %d", __func__, port->number); | 334 | dbg("%s - port %d", __func__, port->number); |
335 | 335 | ||
336 | /* only do something if we have a bulk out endpoint */ | ||
337 | if (!port->bulk_out_size) | ||
338 | return -ENODEV; | ||
339 | |||
336 | if (count == 0) { | 340 | if (count == 0) { |
337 | dbg("%s - write request of 0 bytes", __func__); | 341 | dbg("%s - write request of 0 bytes", __func__); |
338 | return 0; | 342 | return 0; |
339 | } | 343 | } |
340 | 344 | ||
341 | /* only do something if we have a bulk out endpoint */ | ||
342 | if (!serial->num_bulk_out) | ||
343 | return 0; | ||
344 | |||
345 | if (serial->type->max_in_flight_urbs) | 345 | if (serial->type->max_in_flight_urbs) |
346 | return usb_serial_multi_urb_write(tty, port, | 346 | return usb_serial_multi_urb_write(tty, port, |
347 | buf, count); | 347 | buf, count); |
@@ -364,14 +364,19 @@ int usb_serial_generic_write_room(struct tty_struct *tty) | |||
364 | int room = 0; | 364 | int room = 0; |
365 | 365 | ||
366 | dbg("%s - port %d", __func__, port->number); | 366 | dbg("%s - port %d", __func__, port->number); |
367 | |||
368 | if (!port->bulk_out_size) | ||
369 | return 0; | ||
370 | |||
367 | spin_lock_irqsave(&port->lock, flags); | 371 | spin_lock_irqsave(&port->lock, flags); |
368 | if (serial->type->max_in_flight_urbs) { | 372 | if (serial->type->max_in_flight_urbs) { |
369 | if (port->urbs_in_flight < serial->type->max_in_flight_urbs) | 373 | if (port->urbs_in_flight < serial->type->max_in_flight_urbs) |
370 | room = port->bulk_out_size * | 374 | room = port->bulk_out_size * |
371 | (serial->type->max_in_flight_urbs - | 375 | (serial->type->max_in_flight_urbs - |
372 | port->urbs_in_flight); | 376 | port->urbs_in_flight); |
373 | } else if (serial->num_bulk_out) | 377 | } else { |
374 | room = kfifo_avail(&port->write_fifo); | 378 | room = kfifo_avail(&port->write_fifo); |
379 | } | ||
375 | spin_unlock_irqrestore(&port->lock, flags); | 380 | spin_unlock_irqrestore(&port->lock, flags); |
376 | 381 | ||
377 | dbg("%s - returns %d", __func__, room); | 382 | dbg("%s - returns %d", __func__, room); |
@@ -382,15 +387,18 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) | |||
382 | { | 387 | { |
383 | struct usb_serial_port *port = tty->driver_data; | 388 | struct usb_serial_port *port = tty->driver_data; |
384 | struct usb_serial *serial = port->serial; | 389 | struct usb_serial *serial = port->serial; |
385 | int chars = 0; | ||
386 | unsigned long flags; | 390 | unsigned long flags; |
391 | int chars; | ||
387 | 392 | ||
388 | dbg("%s - port %d", __func__, port->number); | 393 | dbg("%s - port %d", __func__, port->number); |
389 | 394 | ||
395 | if (!port->bulk_out_size) | ||
396 | return 0; | ||
397 | |||
390 | spin_lock_irqsave(&port->lock, flags); | 398 | spin_lock_irqsave(&port->lock, flags); |
391 | if (serial->type->max_in_flight_urbs) | 399 | if (serial->type->max_in_flight_urbs) |
392 | chars = port->tx_bytes_flight; | 400 | chars = port->tx_bytes_flight; |
393 | else if (serial->num_bulk_out) | 401 | else |
394 | chars = kfifo_len(&port->write_fifo); | 402 | chars = kfifo_len(&port->write_fifo); |
395 | spin_unlock_irqrestore(&port->lock, flags); | 403 | spin_unlock_irqrestore(&port->lock, flags); |
396 | 404 | ||
@@ -415,11 +423,13 @@ void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port, | |||
415 | ((serial->type->read_bulk_callback) ? | 423 | ((serial->type->read_bulk_callback) ? |
416 | serial->type->read_bulk_callback : | 424 | serial->type->read_bulk_callback : |
417 | usb_serial_generic_read_bulk_callback), port); | 425 | usb_serial_generic_read_bulk_callback), port); |
426 | |||
418 | result = usb_submit_urb(urb, mem_flags); | 427 | result = usb_submit_urb(urb, mem_flags); |
419 | if (result) | 428 | if (result && result != -EPERM) { |
420 | dev_err(&port->dev, | 429 | dev_err(&port->dev, |
421 | "%s - failed resubmitting read urb, error %d\n", | 430 | "%s - failed resubmitting read urb, error %d\n", |
422 | __func__, result); | 431 | __func__, result); |
432 | } | ||
423 | } | 433 | } |
424 | EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb); | 434 | EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb); |
425 | 435 | ||
@@ -498,23 +508,18 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) | |||
498 | if (port->urbs_in_flight < 0) | 508 | if (port->urbs_in_flight < 0) |
499 | port->urbs_in_flight = 0; | 509 | port->urbs_in_flight = 0; |
500 | spin_unlock_irqrestore(&port->lock, flags); | 510 | spin_unlock_irqrestore(&port->lock, flags); |
501 | |||
502 | if (status) { | ||
503 | dbg("%s - nonzero multi-urb write bulk status " | ||
504 | "received: %d", __func__, status); | ||
505 | return; | ||
506 | } | ||
507 | } else { | 511 | } else { |
508 | port->write_urb_busy = 0; | 512 | port->write_urb_busy = 0; |
509 | 513 | ||
510 | if (status) { | 514 | if (status) |
511 | dbg("%s - nonzero multi-urb write bulk status " | ||
512 | "received: %d", __func__, status); | ||
513 | kfifo_reset_out(&port->write_fifo); | 515 | kfifo_reset_out(&port->write_fifo); |
514 | } else | 516 | else |
515 | usb_serial_generic_write_start(port); | 517 | usb_serial_generic_write_start(port); |
516 | } | 518 | } |
517 | 519 | ||
520 | if (status) | ||
521 | dbg("%s - non-zero urb status: %d", __func__, status); | ||
522 | |||
518 | usb_serial_port_softint(port); | 523 | usb_serial_port_softint(port); |
519 | } | 524 | } |
520 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); | 525 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 847b805d63a3..950cb311ca94 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -288,7 +288,9 @@ static int option_resume(struct usb_serial *serial); | |||
288 | 288 | ||
289 | #define QUALCOMM_VENDOR_ID 0x05C6 | 289 | #define QUALCOMM_VENDOR_ID 0x05C6 |
290 | 290 | ||
291 | #define MAXON_VENDOR_ID 0x16d8 | 291 | #define CMOTECH_VENDOR_ID 0x16d8 |
292 | #define CMOTECH_PRODUCT_6008 0x6008 | ||
293 | #define CMOTECH_PRODUCT_6280 0x6280 | ||
292 | 294 | ||
293 | #define TELIT_VENDOR_ID 0x1bc7 | 295 | #define TELIT_VENDOR_ID 0x1bc7 |
294 | #define TELIT_PRODUCT_UC864E 0x1003 | 296 | #define TELIT_PRODUCT_UC864E 0x1003 |
@@ -309,6 +311,7 @@ static int option_resume(struct usb_serial *serial); | |||
309 | #define DLINK_VENDOR_ID 0x1186 | 311 | #define DLINK_VENDOR_ID 0x1186 |
310 | #define DLINK_PRODUCT_DWM_652 0x3e04 | 312 | #define DLINK_PRODUCT_DWM_652 0x3e04 |
311 | #define DLINK_PRODUCT_DWM_652_U5 0xce16 | 313 | #define DLINK_PRODUCT_DWM_652_U5 0xce16 |
314 | #define DLINK_PRODUCT_DWM_652_U5A 0xce1e | ||
312 | 315 | ||
313 | #define QISDA_VENDOR_ID 0x1da5 | 316 | #define QISDA_VENDOR_ID 0x1da5 |
314 | #define QISDA_PRODUCT_H21_4512 0x4512 | 317 | #define QISDA_PRODUCT_H21_4512 0x4512 |
@@ -332,6 +335,24 @@ static int option_resume(struct usb_serial *serial); | |||
332 | #define ALCATEL_VENDOR_ID 0x1bbb | 335 | #define ALCATEL_VENDOR_ID 0x1bbb |
333 | #define ALCATEL_PRODUCT_X060S 0x0000 | 336 | #define ALCATEL_PRODUCT_X060S 0x0000 |
334 | 337 | ||
338 | #define PIRELLI_VENDOR_ID 0x1266 | ||
339 | #define PIRELLI_PRODUCT_C100_1 0x1002 | ||
340 | #define PIRELLI_PRODUCT_C100_2 0x1003 | ||
341 | #define PIRELLI_PRODUCT_1004 0x1004 | ||
342 | #define PIRELLI_PRODUCT_1005 0x1005 | ||
343 | #define PIRELLI_PRODUCT_1006 0x1006 | ||
344 | #define PIRELLI_PRODUCT_1007 0x1007 | ||
345 | #define PIRELLI_PRODUCT_1008 0x1008 | ||
346 | #define PIRELLI_PRODUCT_1009 0x1009 | ||
347 | #define PIRELLI_PRODUCT_100A 0x100a | ||
348 | #define PIRELLI_PRODUCT_100B 0x100b | ||
349 | #define PIRELLI_PRODUCT_100C 0x100c | ||
350 | #define PIRELLI_PRODUCT_100D 0x100d | ||
351 | #define PIRELLI_PRODUCT_100E 0x100e | ||
352 | #define PIRELLI_PRODUCT_100F 0x100f | ||
353 | #define PIRELLI_PRODUCT_1011 0x1011 | ||
354 | #define PIRELLI_PRODUCT_1012 0x1012 | ||
355 | |||
335 | /* Airplus products */ | 356 | /* Airplus products */ |
336 | #define AIRPLUS_VENDOR_ID 0x1011 | 357 | #define AIRPLUS_VENDOR_ID 0x1011 |
337 | #define AIRPLUS_PRODUCT_MCD650 0x3198 | 358 | #define AIRPLUS_PRODUCT_MCD650 0x3198 |
@@ -547,7 +568,8 @@ static const struct usb_device_id option_ids[] = { | |||
547 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, | 568 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, |
548 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ | 569 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ |
549 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 570 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
550 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ | 571 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ |
572 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, | ||
551 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, | 573 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, |
552 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, | 574 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, |
553 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ | 575 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ |
@@ -659,6 +681,7 @@ static const struct usb_device_id option_ids[] = { | |||
659 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 681 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
660 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 682 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
661 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ | 683 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ |
684 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5A) }, | ||
662 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, | 685 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, |
663 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, | 686 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, |
664 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, | 687 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, |
@@ -666,7 +689,6 @@ static const struct usb_device_id option_ids[] = { | |||
666 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, | 689 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, |
667 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ | 690 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ |
668 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, | 691 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, |
669 | { USB_DEVICE(ALINK_VENDOR_ID, 0xce16) }, | ||
670 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, | 692 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, |
671 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, | 693 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, |
672 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, | 694 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, |
@@ -675,6 +697,24 @@ static const struct usb_device_id option_ids[] = { | |||
675 | .driver_info = (kernel_ulong_t)&four_g_w14_blacklist | 697 | .driver_info = (kernel_ulong_t)&four_g_w14_blacklist |
676 | }, | 698 | }, |
677 | { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, | 699 | { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, |
700 | /* Pirelli */ | ||
701 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)}, | ||
702 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)}, | ||
703 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)}, | ||
704 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)}, | ||
705 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)}, | ||
706 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)}, | ||
707 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)}, | ||
708 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)}, | ||
709 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)}, | ||
710 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) }, | ||
711 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) }, | ||
712 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) }, | ||
713 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) }, | ||
714 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, | ||
715 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, | ||
716 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, | ||
717 | |||
678 | { } /* Terminating entry */ | 718 | { } /* Terminating entry */ |
679 | }; | 719 | }; |
680 | MODULE_DEVICE_TABLE(usb, option_ids); | 720 | MODULE_DEVICE_TABLE(usb, option_ids); |
@@ -798,12 +838,19 @@ static int option_probe(struct usb_serial *serial, | |||
798 | const struct usb_device_id *id) | 838 | const struct usb_device_id *id) |
799 | { | 839 | { |
800 | struct option_intf_private *data; | 840 | struct option_intf_private *data; |
841 | |||
801 | /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ | 842 | /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ |
802 | if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && | 843 | if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && |
803 | serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && | 844 | serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && |
804 | serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) | 845 | serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) |
805 | return -ENODEV; | 846 | return -ENODEV; |
806 | 847 | ||
848 | /* Bandrich modem and AT command interface is 0xff */ | ||
849 | if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID || | ||
850 | serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) && | ||
851 | serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) | ||
852 | return -ENODEV; | ||
853 | |||
807 | data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); | 854 | data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); |
808 | if (!data) | 855 | if (!data) |
809 | return -ENOMEM; | 856 | return -ENOMEM; |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 310ff6ec6567..53a2d5a935a2 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -47,6 +47,35 @@ static const struct usb_device_id id_table[] = { | |||
47 | {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ | 47 | {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ |
48 | {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ | 48 | {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ |
49 | {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ | 49 | {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ |
50 | {USB_DEVICE(0x413c, 0x8185)}, /* Dell Gobi 2000 QDL device (N0218, VU936) */ | ||
51 | {USB_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ | ||
52 | {USB_DEVICE(0x05c6, 0x9224)}, /* Sony Gobi 2000 QDL device (N0279, VU730) */ | ||
53 | {USB_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ | ||
54 | {USB_DEVICE(0x05c6, 0x9244)}, /* Samsung Gobi 2000 QDL device (VL176) */ | ||
55 | {USB_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ | ||
56 | {USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */ | ||
57 | {USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ | ||
58 | {USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */ | ||
59 | {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ | ||
60 | {USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */ | ||
61 | {USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ | ||
62 | {USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */ | ||
63 | {USB_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ | ||
64 | {USB_DEVICE(0x05c6, 0x9274)}, /* iRex Technologies Gobi 2000 QDL device (VR307) */ | ||
65 | {USB_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ | ||
66 | {USB_DEVICE(0x1199, 0x9000)}, /* Sierra Wireless Gobi 2000 QDL device (VT773) */ | ||
67 | {USB_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
68 | {USB_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
69 | {USB_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
70 | {USB_DEVICE(0x1199, 0x9004)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
71 | {USB_DEVICE(0x1199, 0x9005)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
72 | {USB_DEVICE(0x1199, 0x9006)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
73 | {USB_DEVICE(0x1199, 0x9007)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
74 | {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
75 | {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
76 | {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
77 | {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ | ||
78 | {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ | ||
50 | { } /* Terminating entry */ | 79 | { } /* Terminating entry */ |
51 | }; | 80 | }; |
52 | MODULE_DEVICE_TABLE(usb, id_table); | 81 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 98b549b1cab2..ccf1dbbb87ef 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -374,6 +374,15 @@ UNUSUAL_DEV( 0x04ce, 0x0002, 0x0074, 0x0074, | |||
374 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 374 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
375 | US_FL_FIX_INQUIRY), | 375 | US_FL_FIX_INQUIRY), |
376 | 376 | ||
377 | /* Reported by Ondrej Zary <linux@rainbow-software.org> | ||
378 | * The device reports one sector more and breaks when that sector is accessed | ||
379 | */ | ||
380 | UNUSUAL_DEV( 0x04ce, 0x0002, 0x026c, 0x026c, | ||
381 | "ScanLogic", | ||
382 | "SL11R-IDE", | ||
383 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
384 | US_FL_FIX_CAPACITY), | ||
385 | |||
377 | /* Reported by Kriston Fincher <kriston@airmail.net> | 386 | /* Reported by Kriston Fincher <kriston@airmail.net> |
378 | * Patch submitted by Sean Millichamp <sean@bruenor.org> | 387 | * Patch submitted by Sean Millichamp <sean@bruenor.org> |
379 | * This is to support the Panasonic PalmCam PV-SD4090 | 388 | * This is to support the Panasonic PalmCam PV-SD4090 |
@@ -1380,20 +1389,6 @@ UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100, | |||
1380 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1389 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1381 | US_FL_IGNORE_RESIDUE ), | 1390 | US_FL_IGNORE_RESIDUE ), |
1382 | 1391 | ||
1383 | /* Jeremy Katz <katzj@redhat.com>: | ||
1384 | * The Blackberry Pearl can run in two modes; a usb-storage only mode | ||
1385 | * and a mode that allows access via mass storage and to its database. | ||
1386 | * The berry_charge module will set the device to dual mode and thus we | ||
1387 | * should ignore its native mode if that module is built | ||
1388 | */ | ||
1389 | #ifdef CONFIG_USB_BERRY_CHARGE | ||
1390 | UNUSUAL_DEV( 0x0fca, 0x0006, 0x0001, 0x0001, | ||
1391 | "RIM", | ||
1392 | "Blackberry Pearl", | ||
1393 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1394 | US_FL_IGNORE_DEVICE ), | ||
1395 | #endif | ||
1396 | |||
1397 | /* Reported by Michael Stattmann <michael@stattmann.com> */ | 1392 | /* Reported by Michael Stattmann <michael@stattmann.com> */ |
1398 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, | 1393 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, |
1399 | "Sony Ericsson", | 1394 | "Sony Ericsson", |
diff --git a/include/linux/usb.h b/include/linux/usb.h index 8c9f053111bb..ce1323c4e47c 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -1055,7 +1055,8 @@ typedef void (*usb_complete_t)(struct urb *); | |||
1055 | * @number_of_packets: Lists the number of ISO transfer buffers. | 1055 | * @number_of_packets: Lists the number of ISO transfer buffers. |
1056 | * @interval: Specifies the polling interval for interrupt or isochronous | 1056 | * @interval: Specifies the polling interval for interrupt or isochronous |
1057 | * transfers. The units are frames (milliseconds) for full and low | 1057 | * transfers. The units are frames (milliseconds) for full and low |
1058 | * speed devices, and microframes (1/8 millisecond) for highspeed ones. | 1058 | * speed devices, and microframes (1/8 millisecond) for highspeed |
1059 | * and SuperSpeed devices. | ||
1059 | * @error_count: Returns the number of ISO transfers that reported errors. | 1060 | * @error_count: Returns the number of ISO transfers that reported errors. |
1060 | * @context: For use in completion functions. This normally points to | 1061 | * @context: For use in completion functions. This normally points to |
1061 | * request-specific driver context. | 1062 | * request-specific driver context. |
@@ -1286,9 +1287,16 @@ static inline void usb_fill_bulk_urb(struct urb *urb, | |||
1286 | * | 1287 | * |
1287 | * Initializes a interrupt urb with the proper information needed to submit | 1288 | * Initializes a interrupt urb with the proper information needed to submit |
1288 | * it to a device. | 1289 | * it to a device. |
1289 | * Note that high speed interrupt endpoints use a logarithmic encoding of | 1290 | * |
1290 | * the endpoint interval, and express polling intervals in microframes | 1291 | * Note that High Speed and SuperSpeed interrupt endpoints use a logarithmic |
1291 | * (eight per millisecond) rather than in frames (one per millisecond). | 1292 | * encoding of the endpoint interval, and express polling intervals in |
1293 | * microframes (eight per millisecond) rather than in frames (one per | ||
1294 | * millisecond). | ||
1295 | * | ||
1296 | * Wireless USB also uses the logarithmic encoding, but specifies it in units of | ||
1297 | * 128us instead of 125us. For Wireless USB devices, the interval is passed | ||
1298 | * through to the host controller, rather than being translated into microframe | ||
1299 | * units. | ||
1292 | */ | 1300 | */ |
1293 | static inline void usb_fill_int_urb(struct urb *urb, | 1301 | static inline void usb_fill_int_urb(struct urb *urb, |
1294 | struct usb_device *dev, | 1302 | struct usb_device *dev, |
@@ -1305,7 +1313,7 @@ static inline void usb_fill_int_urb(struct urb *urb, | |||
1305 | urb->transfer_buffer_length = buffer_length; | 1313 | urb->transfer_buffer_length = buffer_length; |
1306 | urb->complete = complete_fn; | 1314 | urb->complete = complete_fn; |
1307 | urb->context = context; | 1315 | urb->context = context; |
1308 | if (dev->speed == USB_SPEED_HIGH) | 1316 | if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER) |
1309 | urb->interval = 1 << (interval - 1); | 1317 | urb->interval = 1 << (interval - 1); |
1310 | else | 1318 | else |
1311 | urb->interval = interval; | 1319 | urb->interval = interval; |