aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-mem.c')
-rw-r--r--drivers/usb/host/ehci-mem.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index a8ba2e1497a4..8816d09903d0 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -27,7 +27,7 @@
27 * need to use dma_pool or dma_alloc_coherent 27 * need to use dma_pool or dma_alloc_coherent
28 * - driver buffers, read/written by HC ... single shot DMA mapped 28 * - driver buffers, read/written by HC ... single shot DMA mapped
29 * 29 *
30 * There's also PCI "register" data, which is memory mapped. 30 * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
31 * No memory seen by this driver is pageable. 31 * No memory seen by this driver is pageable.
32 */ 32 */
33 33
@@ -35,13 +35,14 @@
35 35
36/* Allocate the key transfer structures from the previously allocated pool */ 36/* Allocate the key transfer structures from the previously allocated pool */
37 37
38static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma) 38static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd,
39 dma_addr_t dma)
39{ 40{
40 memset (qtd, 0, sizeof *qtd); 41 memset (qtd, 0, sizeof *qtd);
41 qtd->qtd_dma = dma; 42 qtd->qtd_dma = dma;
42 qtd->hw_token = cpu_to_le32 (QTD_STS_HALT); 43 qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
43 qtd->hw_next = EHCI_LIST_END; 44 qtd->hw_next = EHCI_LIST_END(ehci);
44 qtd->hw_alt_next = EHCI_LIST_END; 45 qtd->hw_alt_next = EHCI_LIST_END(ehci);
45 INIT_LIST_HEAD (&qtd->qtd_list); 46 INIT_LIST_HEAD (&qtd->qtd_list);
46} 47}
47 48
@@ -52,7 +53,7 @@ static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, gfp_t flags)
52 53
53 qtd = dma_pool_alloc (ehci->qtd_pool, flags, &dma); 54 qtd = dma_pool_alloc (ehci->qtd_pool, flags, &dma);
54 if (qtd != NULL) { 55 if (qtd != NULL) {
55 ehci_qtd_init (qtd, dma); 56 ehci_qtd_init(ehci, qtd, dma);
56 } 57 }
57 return qtd; 58 return qtd;
58} 59}
@@ -63,9 +64,8 @@ static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
63} 64}
64 65
65 66
66static void qh_destroy (struct kref *kref) 67static void qh_destroy(struct ehci_qh *qh)
67{ 68{
68 struct ehci_qh *qh = container_of(kref, struct ehci_qh, kref);
69 struct ehci_hcd *ehci = qh->ehci; 69 struct ehci_hcd *ehci = qh->ehci;
70 70
71 /* clean qtds first, and know this is not linked */ 71 /* clean qtds first, and know this is not linked */
@@ -89,11 +89,14 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
89 return qh; 89 return qh;
90 90
91 memset (qh, 0, sizeof *qh); 91 memset (qh, 0, sizeof *qh);
92 kref_init(&qh->kref); 92 qh->refcount = 1;
93 qh->ehci = ehci; 93 qh->ehci = ehci;
94 qh->qh_dma = dma; 94 qh->qh_dma = dma;
95 // INIT_LIST_HEAD (&qh->qh_list); 95 // INIT_LIST_HEAD (&qh->qh_list);
96 INIT_LIST_HEAD (&qh->qtd_list); 96 INIT_LIST_HEAD (&qh->qtd_list);
97#ifdef CONFIG_CPU_FREQ
98 INIT_LIST_HEAD (&qh->split_intr_qhs);
99#endif
97 100
98 /* dummy td enables safe urb queuing */ 101 /* dummy td enables safe urb queuing */
99 qh->dummy = ehci_qtd_alloc (ehci, flags); 102 qh->dummy = ehci_qtd_alloc (ehci, flags);
@@ -108,13 +111,15 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
108/* to share a qh (cpu threads, or hc) */ 111/* to share a qh (cpu threads, or hc) */
109static inline struct ehci_qh *qh_get (struct ehci_qh *qh) 112static inline struct ehci_qh *qh_get (struct ehci_qh *qh)
110{ 113{
111 kref_get(&qh->kref); 114 WARN_ON(!qh->refcount);
115 qh->refcount++;
112 return qh; 116 return qh;
113} 117}
114 118
115static inline void qh_put (struct ehci_qh *qh) 119static inline void qh_put (struct ehci_qh *qh)
116{ 120{
117 kref_put(&qh->kref, qh_destroy); 121 if (!--qh->refcount)
122 qh_destroy(qh);
118} 123}
119 124
120/*-------------------------------------------------------------------------*/ 125/*-------------------------------------------------------------------------*/
@@ -217,7 +222,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
217 goto fail; 222 goto fail;
218 } 223 }
219 for (i = 0; i < ehci->periodic_size; i++) 224 for (i = 0; i < ehci->periodic_size; i++)
220 ehci->periodic [i] = EHCI_LIST_END; 225 ehci->periodic [i] = EHCI_LIST_END(ehci);
221 226
222 /* software shadow of hardware table */ 227 /* software shadow of hardware table */
223 ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags); 228 ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags);