|
Lines 135-140
Link Here
|
| 135 |
list_move_tail(&urbp->urb_list, &uhci->complete_list); |
135 |
list_move_tail(&urbp->urb_list, &uhci->complete_list); |
| 136 |
} |
136 |
} |
| 137 |
|
137 |
|
|
|
138 |
/********************************/ |
| 139 |
/********************************/ |
| 140 |
/********************************/ |
| 141 |
/********************************/ |
| 142 |
// PATCH |
| 143 |
// |
| 144 |
// Stop the interrupt inside the chip |
| 145 |
// You have to pass the uhci structure |
| 146 |
// you will get back the old interrupt state that you have |
| 147 |
// to pass back to start_interrupt |
| 148 |
static u16 stop_interrupt(struct usb_hcd *hcd) |
| 149 |
{ |
| 150 |
struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
| 151 |
unsigned int io_addr = uhci->io_addr; |
| 152 |
|
| 153 |
u16 old_value = uhci->IntEnableReg_SW; |
| 154 |
uhci->IntEnableReg_SW = 0; |
| 155 |
outw(0, io_addr + USBINTR); |
| 156 |
|
| 157 |
return old_value; |
| 158 |
} |
| 159 |
|
| 160 |
static void start_interrupt(struct usb_hcd *hcd, u16 restore_value) |
| 161 |
{ |
| 162 |
struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
| 163 |
unsigned int io_addr = uhci->io_addr; |
| 164 |
|
| 165 |
uhci->IntEnableReg_SW = restore_value; |
| 166 |
outw(restore_value, io_addr + USBINTR); |
| 167 |
} |
| 168 |
/********************************/ |
| 169 |
/********************************/ |
| 170 |
/********************************/ |
| 171 |
/********************************/ |
| 172 |
|
| 138 |
static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci, struct usb_device *dev) |
173 |
static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci, struct usb_device *dev) |
| 139 |
{ |
174 |
{ |
| 140 |
dma_addr_t dma_handle; |
175 |
dma_addr_t dma_handle; |
|
Lines 1346-1356
Link Here
|
| 1346 |
{ |
1381 |
{ |
| 1347 |
int ret = -EINVAL; |
1382 |
int ret = -EINVAL; |
| 1348 |
struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
1383 |
struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
| 1349 |
unsigned long flags; |
1384 |
//unsigned long flags; |
|
|
1385 |
u16 irq_state; |
| 1350 |
struct urb *eurb; |
1386 |
struct urb *eurb; |
| 1351 |
int bustime; |
1387 |
int bustime; |
| 1352 |
|
1388 |
|
| 1353 |
spin_lock_irqsave(&uhci->schedule_lock, flags); |
1389 |
//PATCH |
|
|
1390 |
spin_lock_irq(&uhci->schedule_lock); |
| 1391 |
irq_state = stop_interrupt(hcd); |
| 1354 |
|
1392 |
|
| 1355 |
if (urb->status != -EINPROGRESS) /* URB already unlinked! */ |
1393 |
if (urb->status != -EINPROGRESS) /* URB already unlinked! */ |
| 1356 |
goto out; |
1394 |
goto out; |
|
Lines 1407-1413
Link Here
|
| 1407 |
ret = 0; |
1445 |
ret = 0; |
| 1408 |
|
1446 |
|
| 1409 |
out: |
1447 |
out: |
| 1410 |
spin_unlock_irqrestore(&uhci->schedule_lock, flags); |
1448 |
//PATCH |
|
|
1449 |
spin_unlock(&uhci->schedule_lock); |
| 1450 |
start_interrupt(hcd, irq_state); |
| 1451 |
|
| 1411 |
return ret; |
1452 |
return ret; |
| 1412 |
} |
1453 |
} |
| 1413 |
|
1454 |
|
|
Lines 1528-1538
Link Here
|
| 1528 |
static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) |
1569 |
static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) |
| 1529 |
{ |
1570 |
{ |
| 1530 |
struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
1571 |
struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
| 1531 |
unsigned long flags; |
1572 |
//unsigned long flags; |
|
|
1573 |
u16 irq_state; |
| 1532 |
struct urb_priv *urbp; |
1574 |
struct urb_priv *urbp; |
| 1533 |
unsigned int age; |
1575 |
unsigned int age; |
| 1534 |
|
1576 |
|
| 1535 |
spin_lock_irqsave(&uhci->schedule_lock, flags); |
1577 |
// PATCH |
|
|
1578 |
spin_lock_irq(&uhci->schedule_lock); |
| 1579 |
irq_state = stop_interrupt(hcd); |
| 1580 |
|
| 1536 |
urbp = urb->hcpriv; |
1581 |
urbp = urb->hcpriv; |
| 1537 |
if (!urbp) /* URB was never linked! */ |
1582 |
if (!urbp) /* URB was never linked! */ |
| 1538 |
goto done; |
1583 |
goto done; |
|
Lines 1552-1558
Link Here
|
| 1552 |
list_add_tail(&urbp->urb_list, &uhci->urb_remove_list); |
1597 |
list_add_tail(&urbp->urb_list, &uhci->urb_remove_list); |
| 1553 |
|
1598 |
|
| 1554 |
done: |
1599 |
done: |
| 1555 |
spin_unlock_irqrestore(&uhci->schedule_lock, flags); |
1600 |
// PATCH |
|
|
1601 |
spin_unlock(&uhci->schedule_lock); |
| 1602 |
start_interrupt(hcd, irq_state); |
| 1556 |
return 0; |
1603 |
return 0; |
| 1557 |
} |
1604 |
} |
| 1558 |
|
1605 |
|
|
Lines 1610-1620
Link Here
|
| 1610 |
struct usb_hcd *hcd = (struct usb_hcd *)ptr; |
1657 |
struct usb_hcd *hcd = (struct usb_hcd *)ptr; |
| 1611 |
struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
1658 |
struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
| 1612 |
struct list_head list, *tmp, *head; |
1659 |
struct list_head list, *tmp, *head; |
| 1613 |
unsigned long flags; |
1660 |
//unsigned long flags; |
|
|
1661 |
|
| 1662 |
// PATCH |
| 1663 |
u16 irq_state; |
| 1614 |
|
1664 |
|
| 1615 |
INIT_LIST_HEAD(&list); |
1665 |
INIT_LIST_HEAD(&list); |
| 1616 |
|
1666 |
|
| 1617 |
spin_lock_irqsave(&uhci->schedule_lock, flags); |
1667 |
spin_lock(&uhci->schedule_lock); |
|
|
1668 |
irq_state = stop_interrupt(hcd); |
| 1669 |
|
| 1618 |
if (!list_empty(&uhci->urb_remove_list) && |
1670 |
if (!list_empty(&uhci->urb_remove_list) && |
| 1619 |
uhci_get_current_frame_number(uhci) != uhci->urb_remove_age) { |
1671 |
uhci_get_current_frame_number(uhci) != uhci->urb_remove_age) { |
| 1620 |
uhci_remove_pending_urbps(uhci); |
1672 |
uhci_remove_pending_urbps(uhci); |
|
Lines 1644-1650
Link Here
|
| 1644 |
|
1696 |
|
| 1645 |
spin_unlock(&u->lock); |
1697 |
spin_unlock(&u->lock); |
| 1646 |
} |
1698 |
} |
| 1647 |
spin_unlock_irqrestore(&uhci->schedule_lock, flags); |
1699 |
// PATCH |
|
|
1700 |
spin_unlock(&uhci->schedule_lock); |
| 1701 |
start_interrupt(hcd, irq_state); |
| 1648 |
|
1702 |
|
| 1649 |
head = &list; |
1703 |
head = &list; |
| 1650 |
tmp = head->next; |
1704 |
tmp = head->next; |
|
Lines 1761-1774
Link Here
|
| 1761 |
struct list_head *tmp, *head; |
1815 |
struct list_head *tmp, *head; |
| 1762 |
unsigned int age; |
1816 |
unsigned int age; |
| 1763 |
|
1817 |
|
|
|
1818 |
// PATCH |
| 1819 |
irqreturn_t retval = IRQ_HANDLED; |
| 1820 |
|
| 1821 |
// disable interrupt |
| 1822 |
outw(0, io_addr + USBINTR); |
| 1823 |
|
| 1764 |
/* |
1824 |
/* |
| 1765 |
* Read the interrupt status, and write it back to clear the |
1825 |
* Read the interrupt status, and write it back to clear the |
| 1766 |
* interrupt cause. Contrary to the UHCI specification, the |
1826 |
* interrupt cause. Contrary to the UHCI specification, the |
| 1767 |
* "HC Halted" status bit is persistent: it is RO, not R/WC. |
1827 |
* "HC Halted" status bit is persistent: it is RO, not R/WC. |
| 1768 |
*/ |
1828 |
*/ |
| 1769 |
status = inw(io_addr + USBSTS); |
1829 |
status = inw(io_addr + USBSTS); |
| 1770 |
if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */ |
1830 |
if ( (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */ |
| 1771 |
return IRQ_NONE; |
1831 |
|| (!uhci->IntEnableReg_SW) ) |
|
|
1832 |
{ |
| 1833 |
retval = IRQ_NONE; |
| 1834 |
goto end; |
| 1835 |
} |
| 1772 |
outw(status, io_addr + USBSTS); /* Clear it */ |
1836 |
outw(status, io_addr + USBSTS); /* Clear it */ |
| 1773 |
|
1837 |
|
| 1774 |
if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { |
1838 |
if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { |
|
Lines 1788-1794
Link Here
|
| 1788 |
if (status & USBSTS_RD) |
1852 |
if (status & USBSTS_RD) |
| 1789 |
uhci->resume_detect = 1; |
1853 |
uhci->resume_detect = 1; |
| 1790 |
|
1854 |
|
| 1791 |
spin_lock(&uhci->schedule_lock); |
1855 |
//spin_lock(&uhci->schedule_lock); |
| 1792 |
|
1856 |
|
| 1793 |
age = uhci_get_current_frame_number(uhci); |
1857 |
age = uhci_get_current_frame_number(uhci); |
| 1794 |
if (age != uhci->qh_remove_age) |
1858 |
if (age != uhci->qh_remove_age) |
|
Lines 1819-1830
Link Here
|
| 1819 |
} |
1883 |
} |
| 1820 |
uhci_finish_completion(hcd, regs); |
1884 |
uhci_finish_completion(hcd, regs); |
| 1821 |
|
1885 |
|
| 1822 |
spin_unlock(&uhci->schedule_lock); |
|
|
| 1823 |
|
| 1824 |
/* Wake up anyone waiting for an URB to complete */ |
1886 |
/* Wake up anyone waiting for an URB to complete */ |
| 1825 |
wake_up_all(&uhci->waitqh); |
1887 |
wake_up_all(&uhci->waitqh); |
| 1826 |
|
1888 |
|
| 1827 |
return IRQ_HANDLED; |
1889 |
// PATCH |
|
|
1890 |
end: |
| 1891 |
//spin_unlock(&uhci->schedule_lock); |
| 1892 |
outw(uhci->IntEnableReg_SW, io_addr + USBINTR); |
| 1893 |
return retval; |
| 1828 |
} |
1894 |
} |
| 1829 |
|
1895 |
|
| 1830 |
static void reset_hc(struct uhci_hcd *uhci) |
1896 |
static void reset_hc(struct uhci_hcd *uhci) |
|
Lines 1991-1996
Link Here
|
| 1991 |
} |
2057 |
} |
| 1992 |
|
2058 |
|
| 1993 |
/* Turn on all interrupts */ |
2059 |
/* Turn on all interrupts */ |
|
|
2060 |
// PATCH |
| 2061 |
uhci->IntEnableReg_SW = USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP; |
| 1994 |
outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, |
2062 |
outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, |
| 1995 |
io_addr + USBINTR); |
2063 |
io_addr + USBINTR); |
| 1996 |
|
2064 |
|
|
Lines 2113-2119
Link Here
|
| 2113 |
uhci->fsbr = 0; |
2181 |
uhci->fsbr = 0; |
| 2114 |
uhci->fsbrtimeout = 0; |
2182 |
uhci->fsbrtimeout = 0; |
| 2115 |
|
2183 |
|
| 2116 |
spin_lock_init(&uhci->schedule_lock); |
2184 |
// PATCH |
|
|
2185 |
//spin_lock_init(&uhci->schedule_lock); |
| 2117 |
INIT_LIST_HEAD(&uhci->qh_remove_list); |
2186 |
INIT_LIST_HEAD(&uhci->qh_remove_list); |
| 2118 |
|
2187 |
|
| 2119 |
INIT_LIST_HEAD(&uhci->td_remove_list); |
2188 |
INIT_LIST_HEAD(&uhci->td_remove_list); |
|
Lines 2139-2152
Link Here
|
| 2139 |
uhci->fl->dma_handle = dma_handle; |
2208 |
uhci->fl->dma_handle = dma_handle; |
| 2140 |
|
2209 |
|
| 2141 |
uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), |
2210 |
uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), |
| 2142 |
sizeof(struct uhci_td), 16, 0); |
2211 |
sizeof(struct uhci_td), UHCI_ALIGN, 0); |
| 2143 |
if (!uhci->td_pool) { |
2212 |
if (!uhci->td_pool) { |
| 2144 |
dev_err(uhci_dev(uhci), "unable to create td dma_pool\n"); |
2213 |
dev_err(uhci_dev(uhci), "unable to create td dma_pool\n"); |
| 2145 |
goto err_create_td_pool; |
2214 |
goto err_create_td_pool; |
| 2146 |
} |
2215 |
} |
| 2147 |
|
2216 |
|
| 2148 |
uhci->qh_pool = dma_pool_create("uhci_qh", uhci_dev(uhci), |
2217 |
uhci->qh_pool = dma_pool_create("uhci_qh", uhci_dev(uhci), |
| 2149 |
sizeof(struct uhci_qh), 16, 0); |
2218 |
sizeof(struct uhci_qh), UHCI_ALIGN, 0); |
| 2150 |
if (!uhci->qh_pool) { |
2219 |
if (!uhci->qh_pool) { |
| 2151 |
dev_err(uhci_dev(uhci), "unable to create qh dma_pool\n"); |
2220 |
dev_err(uhci_dev(uhci), "unable to create qh dma_pool\n"); |
| 2152 |
goto err_create_qh_pool; |
2221 |
goto err_create_qh_pool; |
|
Lines 2317-2322
Link Here
|
| 2317 |
static void uhci_stop(struct usb_hcd *hcd) |
2386 |
static void uhci_stop(struct usb_hcd *hcd) |
| 2318 |
{ |
2387 |
{ |
| 2319 |
struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
2388 |
struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
|
|
2389 |
u16 irq_state; |
| 2320 |
|
2390 |
|
| 2321 |
del_timer_sync(&uhci->stall_timer); |
2391 |
del_timer_sync(&uhci->stall_timer); |
| 2322 |
|
2392 |
|
|
Lines 2327-2333
Link Here
|
| 2327 |
|
2397 |
|
| 2328 |
reset_hc(uhci); |
2398 |
reset_hc(uhci); |
| 2329 |
|
2399 |
|
| 2330 |
spin_lock_irq(&uhci->schedule_lock); |
2400 |
//PATCH |
|
|
2401 |
spin_lock(&uhci->schedule_lock); |
| 2402 |
irq_state = stop_interrupt(hcd); |
| 2403 |
|
| 2331 |
uhci_free_pending_qhs(uhci); |
2404 |
uhci_free_pending_qhs(uhci); |
| 2332 |
uhci_free_pending_tds(uhci); |
2405 |
uhci_free_pending_tds(uhci); |
| 2333 |
uhci_remove_pending_urbps(uhci); |
2406 |
uhci_remove_pending_urbps(uhci); |
|
Lines 2335-2344
Link Here
|
| 2335 |
|
2408 |
|
| 2336 |
uhci_free_pending_qhs(uhci); |
2409 |
uhci_free_pending_qhs(uhci); |
| 2337 |
uhci_free_pending_tds(uhci); |
2410 |
uhci_free_pending_tds(uhci); |
| 2338 |
spin_unlock_irq(&uhci->schedule_lock); |
|
|
| 2339 |
|
2411 |
|
| 2340 |
/* Wake up anyone waiting for an URB to complete */ |
2412 |
/* Wake up anyone waiting for an URB to complete */ |
| 2341 |
wake_up_all(&uhci->waitqh); |
2413 |
wake_up_all(&uhci->waitqh); |
|
|
2414 |
|
| 2415 |
// PATCH |
| 2416 |
spin_unlock(&uhci->schedule_lock); |
| 2417 |
start_interrupt(hcd, irq_state); |
| 2342 |
|
2418 |
|
| 2343 |
release_uhci(uhci); |
2419 |
release_uhci(uhci); |
| 2344 |
} |
2420 |
} |