aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ehci-sched.c13
-rw-r--r--drivers/usb/host/isp1362-hcd.c18
-rw-r--r--drivers/usb/host/isp1362.h12
-rw-r--r--drivers/usb/host/ohci-pxa27x.c30
-rw-r--r--drivers/usb/host/pci-quirks.c2
-rw-r--r--drivers/usb/host/whci/asl.c23
-rw-r--r--drivers/usb/host/whci/debug.c6
-rw-r--r--drivers/usb/host/whci/pzl.c24
-rw-r--r--drivers/usb/host/xhci-hcd.c29
9 files changed, 106 insertions, 51 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 3ea05936851..b25cdea93a1 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1400,6 +1400,10 @@ iso_stream_schedule (
1400 goto fail; 1400 goto fail;
1401 } 1401 }
1402 1402
1403 period = urb->interval;
1404 if (!stream->highspeed)
1405 period <<= 3;
1406
1403 now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; 1407 now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;
1404 1408
1405 /* when's the last uframe this urb could start? */ 1409 /* when's the last uframe this urb could start? */
@@ -1417,14 +1421,15 @@ iso_stream_schedule (
1417 1421
1418 /* Fell behind (by up to twice the slop amount)? */ 1422 /* Fell behind (by up to twice the slop amount)? */
1419 if (start >= max - 2 * 8 * SCHEDULE_SLOP) 1423 if (start >= max - 2 * 8 * SCHEDULE_SLOP)
1420 start += stream->interval * DIV_ROUND_UP( 1424 start += period * DIV_ROUND_UP(
1421 max - start, stream->interval) - mod; 1425 max - start, period) - mod;
1422 1426
1423 /* Tried to schedule too far into the future? */ 1427 /* Tried to schedule too far into the future? */
1424 if (unlikely((start + sched->span) >= max)) { 1428 if (unlikely((start + sched->span) >= max)) {
1425 status = -EFBIG; 1429 status = -EFBIG;
1426 goto fail; 1430 goto fail;
1427 } 1431 }
1432 stream->next_uframe = start;
1428 goto ready; 1433 goto ready;
1429 } 1434 }
1430 1435
@@ -1440,10 +1445,6 @@ iso_stream_schedule (
1440 1445
1441 /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ 1446 /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
1442 1447
1443 period = urb->interval;
1444 if (!stream->highspeed)
1445 period <<= 3;
1446
1447 /* find a uframe slot with enough bandwidth */ 1448 /* find a uframe slot with enough bandwidth */
1448 for (; start < (stream->next_uframe + period); start++) { 1449 for (; start < (stream->next_uframe + period); start++) {
1449 int enough_space; 1450 int enough_space;
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index e35d82808ba..5c774ab9825 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -2284,10 +2284,10 @@ static int isp1362_mem_config(struct usb_hcd *hcd)
2284 dev_info(hcd->self.controller, "ISP1362 Memory usage:\n"); 2284 dev_info(hcd->self.controller, "ISP1362 Memory usage:\n");
2285 dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n", 2285 dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n",
2286 istl_size / 2, istl_size, 0, istl_size / 2); 2286 istl_size / 2, istl_size, 0, istl_size / 2);
2287 dev_info(hcd->self.controller, " INTL: %4d * (%3u+8): %4d @ $%04x\n", 2287 dev_info(hcd->self.controller, " INTL: %4d * (%3lu+8): %4d @ $%04x\n",
2288 ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE, 2288 ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE,
2289 intl_size, istl_size); 2289 intl_size, istl_size);
2290 dev_info(hcd->self.controller, " ATL : %4d * (%3u+8): %4d @ $%04x\n", 2290 dev_info(hcd->self.controller, " ATL : %4d * (%3lu+8): %4d @ $%04x\n",
2291 atl_buffers, atl_blksize - PTD_HEADER_SIZE, 2291 atl_buffers, atl_blksize - PTD_HEADER_SIZE,
2292 atl_size, istl_size + intl_size); 2292 atl_size, istl_size + intl_size);
2293 dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total, 2293 dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total,
@@ -2677,12 +2677,12 @@ static int __devexit isp1362_remove(struct platform_device *pdev)
2677 DBG(0, "%s: Removing HCD\n", __func__); 2677 DBG(0, "%s: Removing HCD\n", __func__);
2678 usb_remove_hcd(hcd); 2678 usb_remove_hcd(hcd);
2679 2679
2680 DBG(0, "%s: Unmapping data_reg @ %08x\n", __func__, 2680 DBG(0, "%s: Unmapping data_reg @ %p\n", __func__,
2681 (u32)isp1362_hcd->data_reg); 2681 isp1362_hcd->data_reg);
2682 iounmap(isp1362_hcd->data_reg); 2682 iounmap(isp1362_hcd->data_reg);
2683 2683
2684 DBG(0, "%s: Unmapping addr_reg @ %08x\n", __func__, 2684 DBG(0, "%s: Unmapping addr_reg @ %p\n", __func__,
2685 (u32)isp1362_hcd->addr_reg); 2685 isp1362_hcd->addr_reg);
2686 iounmap(isp1362_hcd->addr_reg); 2686 iounmap(isp1362_hcd->addr_reg);
2687 2687
2688 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 2688 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -2810,16 +2810,16 @@ static int __init isp1362_probe(struct platform_device *pdev)
2810 return 0; 2810 return 0;
2811 2811
2812 err6: 2812 err6:
2813 DBG(0, "%s: Freeing dev %08x\n", __func__, (u32)isp1362_hcd); 2813 DBG(0, "%s: Freeing dev %p\n", __func__, isp1362_hcd);
2814 usb_put_hcd(hcd); 2814 usb_put_hcd(hcd);
2815 err5: 2815 err5:
2816 DBG(0, "%s: Unmapping data_reg @ %08x\n", __func__, (u32)data_reg); 2816 DBG(0, "%s: Unmapping data_reg @ %p\n", __func__, data_reg);
2817 iounmap(data_reg); 2817 iounmap(data_reg);
2818 err4: 2818 err4:
2819 DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)data->start); 2819 DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)data->start);
2820 release_mem_region(data->start, resource_len(data)); 2820 release_mem_region(data->start, resource_len(data));
2821 err3: 2821 err3:
2822 DBG(0, "%s: Unmapping addr_reg @ %08x\n", __func__, (u32)addr_reg); 2822 DBG(0, "%s: Unmapping addr_reg @ %p\n", __func__, addr_reg);
2823 iounmap(addr_reg); 2823 iounmap(addr_reg);
2824 err2: 2824 err2:
2825 DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)addr->start); 2825 DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)addr->start);
diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h
index fe60f62a32f..1a253ebf7e5 100644
--- a/drivers/usb/host/isp1362.h
+++ b/drivers/usb/host/isp1362.h
@@ -580,7 +580,7 @@ static inline const char *ISP1362_INT_NAME(int n)
580 580
581static inline void ALIGNSTAT(struct isp1362_hcd *isp1362_hcd, void *ptr) 581static inline void ALIGNSTAT(struct isp1362_hcd *isp1362_hcd, void *ptr)
582{ 582{
583 unsigned p = (unsigned)ptr; 583 unsigned long p = (unsigned long)ptr;
584 if (!(p & 0xf)) 584 if (!(p & 0xf))
585 isp1362_hcd->stat16++; 585 isp1362_hcd->stat16++;
586 else if (!(p & 0x7)) 586 else if (!(p & 0x7))
@@ -770,7 +770,7 @@ static void isp1362_write_fifo(struct isp1362_hcd *isp1362_hcd, void *buf, u16 l
770 if (!len) 770 if (!len)
771 return; 771 return;
772 772
773 if ((unsigned)dp & 0x1) { 773 if ((unsigned long)dp & 0x1) {
774 /* not aligned */ 774 /* not aligned */
775 for (; len > 1; len -= 2) { 775 for (; len > 1; len -= 2) {
776 data = *dp++; 776 data = *dp++;
@@ -962,8 +962,8 @@ static void isp1362_read_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16
962 962
963 isp1362_write_diraddr(isp1362_hcd, offset, len); 963 isp1362_write_diraddr(isp1362_hcd, offset, len);
964 964
965 DBG(3, "%s: Reading %d byte from buffer @%04x to memory @ %08x\n", __func__, 965 DBG(3, "%s: Reading %d byte from buffer @%04x to memory @ %p\n",
966 len, offset, (u32)buf); 966 __func__, len, offset, buf);
967 967
968 isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); 968 isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT);
969 _WARN_ON((isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_EOT)); 969 _WARN_ON((isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_EOT));
@@ -982,8 +982,8 @@ static void isp1362_write_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16
982 982
983 isp1362_write_diraddr(isp1362_hcd, offset, len); 983 isp1362_write_diraddr(isp1362_hcd, offset, len);
984 984
985 DBG(3, "%s: Writing %d byte to buffer @%04x from memory @ %08x\n", __func__, 985 DBG(3, "%s: Writing %d byte to buffer @%04x from memory @ %p\n",
986 len, offset, (u32)buf); 986 __func__, len, offset, buf);
987 987
988 isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); 988 isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT);
989 _WARN_ON((isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_EOT)); 989 _WARN_ON((isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_EOT));
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index b5294a9344d..f1c06202fdf 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -481,38 +481,47 @@ static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)
481 return 0; 481 return 0;
482} 482}
483 483
484#ifdef CONFIG_PM 484#ifdef CONFIG_PM
485static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_t state) 485static int ohci_hcd_pxa27x_drv_suspend(struct device *dev)
486{ 486{
487 struct usb_hcd *hcd = platform_get_drvdata(pdev); 487 struct usb_hcd *hcd = dev_get_drvdata(dev);
488 struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd); 488 struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
489 489
490 if (time_before(jiffies, ohci->ohci.next_statechange)) 490 if (time_before(jiffies, ohci->ohci.next_statechange))
491 msleep(5); 491 msleep(5);
492 ohci->ohci.next_statechange = jiffies; 492 ohci->ohci.next_statechange = jiffies;
493 493
494 pxa27x_stop_hc(ohci, &pdev->dev); 494 pxa27x_stop_hc(ohci, dev);
495 hcd->state = HC_STATE_SUSPENDED; 495 hcd->state = HC_STATE_SUSPENDED;
496 496
497 return 0; 497 return 0;
498} 498}
499 499
500static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev) 500static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
501{ 501{
502 struct usb_hcd *hcd = platform_get_drvdata(pdev); 502 struct usb_hcd *hcd = dev_get_drvdata(dev);
503 struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd); 503 struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
504 struct pxaohci_platform_data *inf = dev->platform_data;
504 int status; 505 int status;
505 506
506 if (time_before(jiffies, ohci->ohci.next_statechange)) 507 if (time_before(jiffies, ohci->ohci.next_statechange))
507 msleep(5); 508 msleep(5);
508 ohci->ohci.next_statechange = jiffies; 509 ohci->ohci.next_statechange = jiffies;
509 510
510 if ((status = pxa27x_start_hc(ohci, &pdev->dev)) < 0) 511 if ((status = pxa27x_start_hc(ohci, dev)) < 0)
511 return status; 512 return status;
512 513
514 /* Select Power Management Mode */
515 pxa27x_ohci_select_pmm(ohci, inf->port_mode);
516
513 ohci_finish_controller_resume(hcd); 517 ohci_finish_controller_resume(hcd);
514 return 0; 518 return 0;
515} 519}
520
521static struct dev_pm_ops ohci_hcd_pxa27x_pm_ops = {
522 .suspend = ohci_hcd_pxa27x_drv_suspend,
523 .resume = ohci_hcd_pxa27x_drv_resume,
524};
516#endif 525#endif
517 526
518/* work with hotplug and coldplug */ 527/* work with hotplug and coldplug */
@@ -522,13 +531,12 @@ static struct platform_driver ohci_hcd_pxa27x_driver = {
522 .probe = ohci_hcd_pxa27x_drv_probe, 531 .probe = ohci_hcd_pxa27x_drv_probe,
523 .remove = ohci_hcd_pxa27x_drv_remove, 532 .remove = ohci_hcd_pxa27x_drv_remove,
524 .shutdown = usb_hcd_platform_shutdown, 533 .shutdown = usb_hcd_platform_shutdown,
525#ifdef CONFIG_PM
526 .suspend = ohci_hcd_pxa27x_drv_suspend,
527 .resume = ohci_hcd_pxa27x_drv_resume,
528#endif
529 .driver = { 534 .driver = {
530 .name = "pxa27x-ohci", 535 .name = "pxa27x-ohci",
531 .owner = THIS_MODULE, 536 .owner = THIS_MODULE,
537#ifdef CONFIG_PM
538 .pm = &ohci_hcd_pxa27x_pm_ops,
539#endif
532 }, 540 },
533}; 541};
534 542
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 23cf3bde476..83b5f9cea85 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -475,4 +475,4 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
475 else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI) 475 else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI)
476 quirk_usb_handoff_xhci(pdev); 476 quirk_usb_handoff_xhci(pdev);
477} 477}
478DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); 478DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index c632437c764..562eba10881 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -115,6 +115,10 @@ static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
115 if (status & QTD_STS_HALTED) { 115 if (status & QTD_STS_HALTED) {
116 /* Ug, an error. */ 116 /* Ug, an error. */
117 process_halted_qtd(whc, qset, td); 117 process_halted_qtd(whc, qset, td);
118 /* A halted qTD always triggers an update
119 because the qset was either removed or
120 reactivated. */
121 update |= WHC_UPDATE_UPDATED;
118 goto done; 122 goto done;
119 } 123 }
120 124
@@ -305,6 +309,7 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
305 struct whc_urb *wurb = urb->hcpriv; 309 struct whc_urb *wurb = urb->hcpriv;
306 struct whc_qset *qset = wurb->qset; 310 struct whc_qset *qset = wurb->qset;
307 struct whc_std *std, *t; 311 struct whc_std *std, *t;
312 bool has_qtd = false;
308 int ret; 313 int ret;
309 unsigned long flags; 314 unsigned long flags;
310 315
@@ -315,17 +320,21 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
315 goto out; 320 goto out;
316 321
317 list_for_each_entry_safe(std, t, &qset->stds, list_node) { 322 list_for_each_entry_safe(std, t, &qset->stds, list_node) {
318 if (std->urb == urb) 323 if (std->urb == urb) {
324 if (std->qtd)
325 has_qtd = true;
319 qset_free_std(whc, std); 326 qset_free_std(whc, std);
320 else 327 } else
321 std->qtd = NULL; /* so this std is re-added when the qset is */ 328 std->qtd = NULL; /* so this std is re-added when the qset is */
322 } 329 }
323 330
324 asl_qset_remove(whc, qset); 331 if (has_qtd) {
325 wurb->status = status; 332 asl_qset_remove(whc, qset);
326 wurb->is_async = true; 333 wurb->status = status;
327 queue_work(whc->workqueue, &wurb->dequeue_work); 334 wurb->is_async = true;
328 335 queue_work(whc->workqueue, &wurb->dequeue_work);
336 } else
337 qset_remove_urb(whc, qset, urb, status);
329out: 338out:
330 spin_unlock_irqrestore(&whc->lock, flags); 339 spin_unlock_irqrestore(&whc->lock, flags);
331 340
diff --git a/drivers/usb/host/whci/debug.c b/drivers/usb/host/whci/debug.c
index cf2d45946c5..2273c815941 100644
--- a/drivers/usb/host/whci/debug.c
+++ b/drivers/usb/host/whci/debug.c
@@ -134,7 +134,7 @@ static int pzl_open(struct inode *inode, struct file *file)
134 return single_open(file, pzl_print, inode->i_private); 134 return single_open(file, pzl_print, inode->i_private);
135} 135}
136 136
137static struct file_operations di_fops = { 137static const struct file_operations di_fops = {
138 .open = di_open, 138 .open = di_open,
139 .read = seq_read, 139 .read = seq_read,
140 .llseek = seq_lseek, 140 .llseek = seq_lseek,
@@ -142,7 +142,7 @@ static struct file_operations di_fops = {
142 .owner = THIS_MODULE, 142 .owner = THIS_MODULE,
143}; 143};
144 144
145static struct file_operations asl_fops = { 145static const struct file_operations asl_fops = {
146 .open = asl_open, 146 .open = asl_open,
147 .read = seq_read, 147 .read = seq_read,
148 .llseek = seq_lseek, 148 .llseek = seq_lseek,
@@ -150,7 +150,7 @@ static struct file_operations asl_fops = {
150 .owner = THIS_MODULE, 150 .owner = THIS_MODULE,
151}; 151};
152 152
153static struct file_operations pzl_fops = { 153static const struct file_operations pzl_fops = {
154 .open = pzl_open, 154 .open = pzl_open,
155 .read = seq_read, 155 .read = seq_read,
156 .llseek = seq_lseek, 156 .llseek = seq_lseek,
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index a9e05bac664..0db3fb2dc03 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -121,6 +121,10 @@ static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset)
121 if (status & QTD_STS_HALTED) { 121 if (status & QTD_STS_HALTED) {
122 /* Ug, an error. */ 122 /* Ug, an error. */
123 process_halted_qtd(whc, qset, td); 123 process_halted_qtd(whc, qset, td);
124 /* A halted qTD always triggers an update
125 because the qset was either removed or
126 reactivated. */
127 update |= WHC_UPDATE_UPDATED;
124 goto done; 128 goto done;
125 } 129 }
126 130
@@ -333,6 +337,7 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
333 struct whc_urb *wurb = urb->hcpriv; 337 struct whc_urb *wurb = urb->hcpriv;
334 struct whc_qset *qset = wurb->qset; 338 struct whc_qset *qset = wurb->qset;
335 struct whc_std *std, *t; 339 struct whc_std *std, *t;
340 bool has_qtd = false;
336 int ret; 341 int ret;
337 unsigned long flags; 342 unsigned long flags;
338 343
@@ -343,17 +348,22 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
343 goto out; 348 goto out;
344 349
345 list_for_each_entry_safe(std, t, &qset->stds, list_node) { 350 list_for_each_entry_safe(std, t, &qset->stds, list_node) {
346 if (std->urb == urb) 351 if (std->urb == urb) {
352 if (std->qtd)
353 has_qtd = true;
347 qset_free_std(whc, std); 354 qset_free_std(whc, std);
348 else 355 } else
349 std->qtd = NULL; /* so this std is re-added when the qset is */ 356 std->qtd = NULL; /* so this std is re-added when the qset is */
350 } 357 }
351 358
352 pzl_qset_remove(whc, qset); 359 if (has_qtd) {
353 wurb->status = status; 360 pzl_qset_remove(whc, qset);
354 wurb->is_async = false; 361 update_pzl_hw_view(whc);
355 queue_work(whc->workqueue, &wurb->dequeue_work); 362 wurb->status = status;
356 363 wurb->is_async = false;
364 queue_work(whc->workqueue, &wurb->dequeue_work);
365 } else
366 qset_remove_urb(whc, qset, urb, status);
357out: 367out:
358 spin_unlock_irqrestore(&whc->lock, flags); 368 spin_unlock_irqrestore(&whc->lock, flags);
359 369
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index 99911e727e0..932f9993848 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -335,6 +335,12 @@ void xhci_event_ring_work(unsigned long arg)
335 spin_lock_irqsave(&xhci->lock, flags); 335 spin_lock_irqsave(&xhci->lock, flags);
336 temp = xhci_readl(xhci, &xhci->op_regs->status); 336 temp = xhci_readl(xhci, &xhci->op_regs->status);
337 xhci_dbg(xhci, "op reg status = 0x%x\n", temp); 337 xhci_dbg(xhci, "op reg status = 0x%x\n", temp);
338 if (temp == 0xffffffff) {
339 xhci_dbg(xhci, "HW died, polling stopped.\n");
340 spin_unlock_irqrestore(&xhci->lock, flags);
341 return;
342 }
343
338 temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); 344 temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
339 xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp); 345 xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp);
340 xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled); 346 xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled);
@@ -776,6 +782,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
776{ 782{
777 unsigned long flags; 783 unsigned long flags;
778 int ret; 784 int ret;
785 u32 temp;
779 struct xhci_hcd *xhci; 786 struct xhci_hcd *xhci;
780 struct xhci_td *td; 787 struct xhci_td *td;
781 unsigned int ep_index; 788 unsigned int ep_index;
@@ -788,6 +795,17 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
788 ret = usb_hcd_check_unlink_urb(hcd, urb, status); 795 ret = usb_hcd_check_unlink_urb(hcd, urb, status);
789 if (ret || !urb->hcpriv) 796 if (ret || !urb->hcpriv)
790 goto done; 797 goto done;
798 temp = xhci_readl(xhci, &xhci->op_regs->status);
799 if (temp == 0xffffffff) {
800 xhci_dbg(xhci, "HW died, freeing TD.\n");
801 td = (struct xhci_td *) urb->hcpriv;
802
803 usb_hcd_unlink_urb_from_ep(hcd, urb);
804 spin_unlock_irqrestore(&xhci->lock, flags);
805 usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN);
806 kfree(td);
807 return ret;
808 }
791 809
792 xhci_dbg(xhci, "Cancel URB %p\n", urb); 810 xhci_dbg(xhci, "Cancel URB %p\n", urb);
793 xhci_dbg(xhci, "Event ring:\n"); 811 xhci_dbg(xhci, "Event ring:\n");
@@ -877,7 +895,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
877 ctrl_ctx->drop_flags |= drop_flag; 895 ctrl_ctx->drop_flags |= drop_flag;
878 new_drop_flags = ctrl_ctx->drop_flags; 896 new_drop_flags = ctrl_ctx->drop_flags;
879 897
880 ctrl_ctx->add_flags = ~drop_flag; 898 ctrl_ctx->add_flags &= ~drop_flag;
881 new_add_flags = ctrl_ctx->add_flags; 899 new_add_flags = ctrl_ctx->add_flags;
882 900
883 last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags); 901 last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags);
@@ -1410,11 +1428,20 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
1410{ 1428{
1411 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 1429 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
1412 unsigned long flags; 1430 unsigned long flags;
1431 u32 state;
1413 1432
1414 if (udev->slot_id == 0) 1433 if (udev->slot_id == 0)
1415 return; 1434 return;
1416 1435
1417 spin_lock_irqsave(&xhci->lock, flags); 1436 spin_lock_irqsave(&xhci->lock, flags);
1437 /* Don't disable the slot if the host controller is dead. */
1438 state = xhci_readl(xhci, &xhci->op_regs->status);
1439 if (state == 0xffffffff) {
1440 xhci_free_virt_device(xhci, udev->slot_id);
1441 spin_unlock_irqrestore(&xhci->lock, flags);
1442 return;
1443 }
1444
1418 if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) { 1445 if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) {
1419 spin_unlock_irqrestore(&xhci->lock, flags); 1446 spin_unlock_irqrestore(&xhci->lock, flags);
1420 xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); 1447 xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");