Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 54684 | Differences between
and this patch

Collapse All | Expand All

(-)drivers/usb/host/uhci-hcd.c.orig (-20 / +96 lines)
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
}
(-)drivers/usb/host/uhci-hcd.h.orig (-2 / +15 lines)
Lines 7-12 Link Here
7
#define usb_packetid(pipe)	(usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT)
7
#define usb_packetid(pipe)	(usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT)
8
#define PIPE_DEVEP_MASK		0x0007ff00
8
#define PIPE_DEVEP_MASK		0x0007ff00
9
9
10
//PATCH
11
#if L1_CACHE_LINE_SIZE > 16 
12
#define UHCI_ALIGN L1_CACHE_LINE_SIZE
13
#else
14
#define UHCI_ALIGN 16
15
#endif
16
17
10
/*
18
/*
11
 * Universal Host Controller Interface data structures and defines
19
 * Universal Host Controller Interface data structures and defines
12
 */
20
 */
Lines 109-122 Link Here
109
	u32 element;			/* Queue element pointer */
117
	u32 element;			/* Queue element pointer */
110
118
111
	/* Software fields */
119
	/* Software fields */
112
	dma_addr_t dma_handle;
120
	// PATCH
121
	dma_addr_t dma_handle __attribute__((aligned( UHCI_ALIGN ))); // Ensure that the software fields are out of any cache line or burst write so they can't be overwrite by DMA operation
113
122
114
	struct usb_device *dev;
123
	struct usb_device *dev;
115
	struct urb_priv *urbp;
124
	struct urb_priv *urbp;
116
125
117
	struct list_head list;		/* P: uhci->frame_list_lock */
126
	struct list_head list;		/* P: uhci->frame_list_lock */
118
	struct list_head remove_list;	/* P: uhci->remove_list_lock */
127
	struct list_head remove_list;	/* P: uhci->remove_list_lock */
119
} __attribute__((aligned(16)));
128
} __attribute__((aligned( UHCI_ALIGN )));
120
129
121
/*
130
/*
122
 * for TD <status>:
131
 * for TD <status>:
Lines 374-379 Link Here
374
383
375
	struct timer_list stall_timer;
384
	struct timer_list stall_timer;
376
385
386
	// PATCH
387
	// Software state of the interrupt register
388
	u16 IntEnableReg_SW;
389
377
	wait_queue_head_t waitqh;		/* endpoint_disable waiters */
390
	wait_queue_head_t waitqh;		/* endpoint_disable waiters */
378
};
391
};
379
392

Return to bug 54684