diff options
| -rw-r--r-- | drivers/usb/class/cdc-acm.c | 18 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-hcd.c | 5 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-pci.c | 20 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-q.c | 18 | ||||
| -rw-r--r-- | drivers/usb/host/ohci.h | 9 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-mem.c | 10 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-ring.c | 7 | ||||
| -rw-r--r-- | drivers/usb/mon/mon_bin.c | 11 | ||||
| -rw-r--r-- | drivers/usb/serial/option.c | 2 |
9 files changed, 78 insertions, 22 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e3861b21e776..e4eca7810bcf 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -609,9 +609,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 609 | 609 | ||
| 610 | acm->throttle = 0; | 610 | acm->throttle = 0; |
| 611 | 611 | ||
| 612 | tasklet_schedule(&acm->urb_task); | ||
| 613 | set_bit(ASYNCB_INITIALIZED, &acm->port.flags); | 612 | set_bit(ASYNCB_INITIALIZED, &acm->port.flags); |
| 614 | rv = tty_port_block_til_ready(&acm->port, tty, filp); | 613 | rv = tty_port_block_til_ready(&acm->port, tty, filp); |
| 614 | tasklet_schedule(&acm->urb_task); | ||
| 615 | done: | 615 | done: |
| 616 | mutex_unlock(&acm->mutex); | 616 | mutex_unlock(&acm->mutex); |
| 617 | err_out: | 617 | err_out: |
| @@ -686,15 +686,21 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
| 686 | 686 | ||
| 687 | /* Perform the closing process and see if we need to do the hardware | 687 | /* Perform the closing process and see if we need to do the hardware |
| 688 | shutdown */ | 688 | shutdown */ |
| 689 | if (!acm || tty_port_close_start(&acm->port, tty, filp) == 0) | 689 | if (!acm) |
| 690 | return; | ||
| 691 | if (tty_port_close_start(&acm->port, tty, filp) == 0) { | ||
| 692 | mutex_lock(&open_mutex); | ||
| 693 | if (!acm->dev) { | ||
| 694 | tty_port_tty_set(&acm->port, NULL); | ||
| 695 | acm_tty_unregister(acm); | ||
| 696 | tty->driver_data = NULL; | ||
| 697 | } | ||
| 698 | mutex_unlock(&open_mutex); | ||
| 690 | return; | 699 | return; |
| 700 | } | ||
| 691 | acm_port_down(acm, 0); | 701 | acm_port_down(acm, 0); |
| 692 | tty_port_close_end(&acm->port, tty); | 702 | tty_port_close_end(&acm->port, tty); |
| 693 | mutex_lock(&open_mutex); | ||
| 694 | tty_port_tty_set(&acm->port, NULL); | 703 | tty_port_tty_set(&acm->port, NULL); |
| 695 | if (!acm->dev) | ||
| 696 | acm_tty_unregister(acm); | ||
| 697 | mutex_unlock(&open_mutex); | ||
| 698 | } | 704 | } |
| 699 | 705 | ||
| 700 | static int acm_tty_write(struct tty_struct *tty, | 706 | static int acm_tty_write(struct tty_struct *tty, |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 78bb7710f36d..24eb74781919 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
| @@ -87,6 +87,7 @@ static int ohci_restart (struct ohci_hcd *ohci); | |||
| 87 | #ifdef CONFIG_PCI | 87 | #ifdef CONFIG_PCI |
| 88 | static void quirk_amd_pll(int state); | 88 | static void quirk_amd_pll(int state); |
| 89 | static void amd_iso_dev_put(void); | 89 | static void amd_iso_dev_put(void); |
| 90 | static void sb800_prefetch(struct ohci_hcd *ohci, int on); | ||
| 90 | #else | 91 | #else |
| 91 | static inline void quirk_amd_pll(int state) | 92 | static inline void quirk_amd_pll(int state) |
| 92 | { | 93 | { |
| @@ -96,6 +97,10 @@ static inline void amd_iso_dev_put(void) | |||
| 96 | { | 97 | { |
| 97 | return; | 98 | return; |
| 98 | } | 99 | } |
| 100 | static inline void sb800_prefetch(struct ohci_hcd *ohci, int on) | ||
| 101 | { | ||
| 102 | return; | ||
| 103 | } | ||
| 99 | #endif | 104 | #endif |
| 100 | 105 | ||
| 101 | 106 | ||
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index d2ba04dd785e..b8a1148f248e 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
| @@ -177,6 +177,13 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) | |||
| 177 | return 0; | 177 | return 0; |
| 178 | 178 | ||
| 179 | pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); | 179 | pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); |
| 180 | |||
| 181 | /* SB800 needs pre-fetch fix */ | ||
| 182 | if ((rev >= 0x40) && (rev <= 0x4f)) { | ||
| 183 | ohci->flags |= OHCI_QUIRK_AMD_PREFETCH; | ||
| 184 | ohci_dbg(ohci, "enabled AMD prefetch quirk\n"); | ||
| 185 | } | ||
| 186 | |||
| 180 | if ((rev > 0x3b) || (rev < 0x30)) { | 187 | if ((rev > 0x3b) || (rev < 0x30)) { |
| 181 | pci_dev_put(amd_smbus_dev); | 188 | pci_dev_put(amd_smbus_dev); |
| 182 | amd_smbus_dev = NULL; | 189 | amd_smbus_dev = NULL; |
| @@ -262,6 +269,19 @@ static void amd_iso_dev_put(void) | |||
| 262 | 269 | ||
| 263 | } | 270 | } |
| 264 | 271 | ||
| 272 | static void sb800_prefetch(struct ohci_hcd *ohci, int on) | ||
| 273 | { | ||
| 274 | struct pci_dev *pdev; | ||
| 275 | u16 misc; | ||
| 276 | |||
| 277 | pdev = to_pci_dev(ohci_to_hcd(ohci)->self.controller); | ||
| 278 | pci_read_config_word(pdev, 0x50, &misc); | ||
| 279 | if (on == 0) | ||
| 280 | pci_write_config_word(pdev, 0x50, misc & 0xfcff); | ||
| 281 | else | ||
| 282 | pci_write_config_word(pdev, 0x50, misc | 0x0300); | ||
| 283 | } | ||
| 284 | |||
| 265 | /* List of quirks for OHCI */ | 285 | /* List of quirks for OHCI */ |
| 266 | static const struct pci_device_id ohci_pci_quirks[] = { | 286 | static const struct pci_device_id ohci_pci_quirks[] = { |
| 267 | { | 287 | { |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 16fecb8ecc39..35288bcae0db 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
| @@ -49,9 +49,12 @@ __acquires(ohci->lock) | |||
| 49 | switch (usb_pipetype (urb->pipe)) { | 49 | switch (usb_pipetype (urb->pipe)) { |
| 50 | case PIPE_ISOCHRONOUS: | 50 | case PIPE_ISOCHRONOUS: |
| 51 | ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; | 51 | ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; |
| 52 | if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 | 52 | if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { |
| 53 | && quirk_amdiso(ohci)) | 53 | if (quirk_amdiso(ohci)) |
| 54 | quirk_amd_pll(1); | 54 | quirk_amd_pll(1); |
| 55 | if (quirk_amdprefetch(ohci)) | ||
| 56 | sb800_prefetch(ohci, 0); | ||
| 57 | } | ||
| 55 | break; | 58 | break; |
| 56 | case PIPE_INTERRUPT: | 59 | case PIPE_INTERRUPT: |
| 57 | ohci_to_hcd(ohci)->self.bandwidth_int_reqs--; | 60 | ohci_to_hcd(ohci)->self.bandwidth_int_reqs--; |
| @@ -680,9 +683,12 @@ static void td_submit_urb ( | |||
| 680 | data + urb->iso_frame_desc [cnt].offset, | 683 | data + urb->iso_frame_desc [cnt].offset, |
| 681 | urb->iso_frame_desc [cnt].length, urb, cnt); | 684 | urb->iso_frame_desc [cnt].length, urb, cnt); |
| 682 | } | 685 | } |
| 683 | if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 | 686 | if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { |
| 684 | && quirk_amdiso(ohci)) | 687 | if (quirk_amdiso(ohci)) |
| 685 | quirk_amd_pll(0); | 688 | quirk_amd_pll(0); |
| 689 | if (quirk_amdprefetch(ohci)) | ||
| 690 | sb800_prefetch(ohci, 1); | ||
| 691 | } | ||
| 686 | periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0 | 692 | periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0 |
| 687 | && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0; | 693 | && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0; |
| 688 | break; | 694 | break; |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 222011f6172c..5bf15fed0d9f 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
| @@ -402,6 +402,7 @@ struct ohci_hcd { | |||
| 402 | #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ | 402 | #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ |
| 403 | #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ | 403 | #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ |
| 404 | #define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ | 404 | #define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ |
| 405 | #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ | ||
| 405 | // there are also chip quirks/bugs in init logic | 406 | // there are also chip quirks/bugs in init logic |
| 406 | 407 | ||
| 407 | struct work_struct nec_work; /* Worker for NEC quirk */ | 408 | struct work_struct nec_work; /* Worker for NEC quirk */ |
| @@ -433,6 +434,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci) | |||
| 433 | { | 434 | { |
| 434 | return ohci->flags & OHCI_QUIRK_AMD_ISO; | 435 | return ohci->flags & OHCI_QUIRK_AMD_ISO; |
| 435 | } | 436 | } |
| 437 | static inline int quirk_amdprefetch(struct ohci_hcd *ohci) | ||
| 438 | { | ||
| 439 | return ohci->flags & OHCI_QUIRK_AMD_PREFETCH; | ||
| 440 | } | ||
| 436 | #else | 441 | #else |
| 437 | static inline int quirk_nec(struct ohci_hcd *ohci) | 442 | static inline int quirk_nec(struct ohci_hcd *ohci) |
| 438 | { | 443 | { |
| @@ -446,6 +451,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci) | |||
| 446 | { | 451 | { |
| 447 | return 0; | 452 | return 0; |
| 448 | } | 453 | } |
| 454 | static inline int quirk_amdprefetch(struct ohci_hcd *ohci) | ||
| 455 | { | ||
| 456 | return 0; | ||
| 457 | } | ||
| 449 | #endif | 458 | #endif |
| 450 | 459 | ||
| 451 | /* convert between an hcd pointer and the corresponding ohci_hcd */ | 460 | /* convert between an hcd pointer and the corresponding ohci_hcd */ |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 1db4fea8c170..b8fd270a8b0d 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
| @@ -802,9 +802,11 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
| 802 | int i; | 802 | int i; |
| 803 | 803 | ||
| 804 | /* Free the Event Ring Segment Table and the actual Event Ring */ | 804 | /* Free the Event Ring Segment Table and the actual Event Ring */ |
| 805 | xhci_writel(xhci, 0, &xhci->ir_set->erst_size); | 805 | if (xhci->ir_set) { |
| 806 | xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); | 806 | xhci_writel(xhci, 0, &xhci->ir_set->erst_size); |
| 807 | xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); | 807 | xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); |
| 808 | xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); | ||
| 809 | } | ||
| 808 | size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); | 810 | size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); |
| 809 | if (xhci->erst.entries) | 811 | if (xhci->erst.entries) |
| 810 | pci_free_consistent(pdev, size, | 812 | pci_free_consistent(pdev, size, |
| @@ -841,9 +843,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
| 841 | xhci->dcbaa, xhci->dcbaa->dma); | 843 | xhci->dcbaa, xhci->dcbaa->dma); |
| 842 | xhci->dcbaa = NULL; | 844 | xhci->dcbaa = NULL; |
| 843 | 845 | ||
| 846 | scratchpad_free(xhci); | ||
| 844 | xhci->page_size = 0; | 847 | xhci->page_size = 0; |
| 845 | xhci->page_shift = 0; | 848 | xhci->page_shift = 0; |
| 846 | scratchpad_free(xhci); | ||
| 847 | } | 849 | } |
| 848 | 850 | ||
| 849 | int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | 851 | int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 173c39c76489..821b7b4709de 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
| @@ -864,9 +864,11 @@ static struct xhci_segment *trb_in_td( | |||
| 864 | cur_seg = start_seg; | 864 | cur_seg = start_seg; |
| 865 | 865 | ||
| 866 | do { | 866 | do { |
| 867 | if (start_dma == 0) | ||
| 868 | return 0; | ||
| 867 | /* We may get an event for a Link TRB in the middle of a TD */ | 869 | /* We may get an event for a Link TRB in the middle of a TD */ |
| 868 | end_seg_dma = xhci_trb_virt_to_dma(cur_seg, | 870 | end_seg_dma = xhci_trb_virt_to_dma(cur_seg, |
| 869 | &start_seg->trbs[TRBS_PER_SEGMENT - 1]); | 871 | &cur_seg->trbs[TRBS_PER_SEGMENT - 1]); |
| 870 | /* If the end TRB isn't in this segment, this is set to 0 */ | 872 | /* If the end TRB isn't in this segment, this is set to 0 */ |
| 871 | end_trb_dma = xhci_trb_virt_to_dma(cur_seg, end_trb); | 873 | end_trb_dma = xhci_trb_virt_to_dma(cur_seg, end_trb); |
| 872 | 874 | ||
| @@ -893,8 +895,9 @@ static struct xhci_segment *trb_in_td( | |||
| 893 | } | 895 | } |
| 894 | cur_seg = cur_seg->next; | 896 | cur_seg = cur_seg->next; |
| 895 | start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]); | 897 | start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]); |
| 896 | } while (1); | 898 | } while (cur_seg != start_seg); |
| 897 | 899 | ||
| 900 | return 0; | ||
| 898 | } | 901 | } |
| 899 | 902 | ||
| 900 | /* | 903 | /* |
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 9ed3e741bee1..10f3205798e8 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
| @@ -348,12 +348,12 @@ static unsigned int mon_buff_area_alloc_contiguous(struct mon_reader_bin *rp, | |||
| 348 | 348 | ||
| 349 | /* | 349 | /* |
| 350 | * Return a few (kilo-)bytes to the head of the buffer. | 350 | * Return a few (kilo-)bytes to the head of the buffer. |
| 351 | * This is used if a DMA fetch fails. | 351 | * This is used if a data fetch fails. |
| 352 | */ | 352 | */ |
| 353 | static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size) | 353 | static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size) |
| 354 | { | 354 | { |
| 355 | 355 | ||
| 356 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | 356 | /* size &= ~(PKT_ALIGN-1); -- we're called with aligned size */ |
| 357 | rp->b_cnt -= size; | 357 | rp->b_cnt -= size; |
| 358 | if (rp->b_in < size) | 358 | if (rp->b_in < size) |
| 359 | rp->b_in += rp->b_size; | 359 | rp->b_in += rp->b_size; |
| @@ -433,6 +433,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
| 433 | unsigned int urb_length; | 433 | unsigned int urb_length; |
| 434 | unsigned int offset; | 434 | unsigned int offset; |
| 435 | unsigned int length; | 435 | unsigned int length; |
| 436 | unsigned int delta; | ||
| 436 | unsigned int ndesc, lendesc; | 437 | unsigned int ndesc, lendesc; |
| 437 | unsigned char dir; | 438 | unsigned char dir; |
| 438 | struct mon_bin_hdr *ep; | 439 | struct mon_bin_hdr *ep; |
| @@ -537,8 +538,10 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
| 537 | if (length != 0) { | 538 | if (length != 0) { |
| 538 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); | 539 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); |
| 539 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ | 540 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ |
| 540 | ep->len_cap = 0; | 541 | delta = (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1); |
| 541 | mon_buff_area_shrink(rp, length); | 542 | ep->len_cap -= length; |
| 543 | delta -= (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
| 544 | mon_buff_area_shrink(rp, delta); | ||
| 542 | } | 545 | } |
| 543 | } else { | 546 | } else { |
| 544 | ep->flag_data = data_tag; | 547 | ep->flag_data = data_tag; |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index cd44c68954df..319aaf9725b3 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -308,6 +308,7 @@ static int option_resume(struct usb_serial *serial); | |||
| 308 | 308 | ||
| 309 | #define DLINK_VENDOR_ID 0x1186 | 309 | #define DLINK_VENDOR_ID 0x1186 |
| 310 | #define DLINK_PRODUCT_DWM_652 0x3e04 | 310 | #define DLINK_PRODUCT_DWM_652 0x3e04 |
| 311 | #define DLINK_PRODUCT_DWM_652_U5 0xce16 | ||
| 311 | 312 | ||
| 312 | #define QISDA_VENDOR_ID 0x1da5 | 313 | #define QISDA_VENDOR_ID 0x1da5 |
| 313 | #define QISDA_PRODUCT_H21_4512 0x4512 | 314 | #define QISDA_PRODUCT_H21_4512 0x4512 |
| @@ -586,6 +587,7 @@ static struct usb_device_id option_ids[] = { | |||
| 586 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | 587 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, |
| 587 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 588 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
| 588 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 589 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
| 590 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ | ||
| 589 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, | 591 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, |
| 590 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, | 592 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, |
| 591 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, | 593 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, |
