diff options
author | Alek Du <alek.du@intel.com> | 2009-07-13 19:23:29 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-23 09:46:29 -0400 |
commit | 3807e26d69b9ad3864fe03224ebebc9610d5802e (patch) | |
tree | 3c85a5cb0686a7e72255c523b963942bbfc60b7f /drivers/usb/host/ehci-mem.c | |
parent | 403dbd36739e344d2d25f56ebbe342248487bd48 (diff) |
USB: EHCI: split ehci_qh into hw and sw parts
The ehci_qh structure merged hw and sw together which is not good:
1. More and more items are being added into ehci_qh, the ehci_qh software
part are unnecessary to be allocated in DMA qh_pool.
2. If HCD has local SRAM, the sw part will consume it too, and it won't
bring any benefit.
3. For non-cache-coherence system, the entire ehci_qh is uncachable, actually
we only need the hw part to be uncacheable. Spliting them will let the sw
part to be cacheable.
Signed-off-by: Alek Du <alek.du@intel.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
CC: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci-mem.c')
-rw-r--r-- | drivers/usb/host/ehci-mem.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 10d52919abbb..aeda96e0af67 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c | |||
@@ -75,7 +75,8 @@ static void qh_destroy(struct ehci_qh *qh) | |||
75 | } | 75 | } |
76 | if (qh->dummy) | 76 | if (qh->dummy) |
77 | ehci_qtd_free (ehci, qh->dummy); | 77 | ehci_qtd_free (ehci, qh->dummy); |
78 | dma_pool_free (ehci->qh_pool, qh, qh->qh_dma); | 78 | dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma); |
79 | kfree(qh); | ||
79 | } | 80 | } |
80 | 81 | ||
81 | static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) | 82 | static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) |
@@ -83,12 +84,14 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) | |||
83 | struct ehci_qh *qh; | 84 | struct ehci_qh *qh; |
84 | dma_addr_t dma; | 85 | dma_addr_t dma; |
85 | 86 | ||
86 | qh = (struct ehci_qh *) | 87 | qh = kzalloc(sizeof *qh, GFP_ATOMIC); |
87 | dma_pool_alloc (ehci->qh_pool, flags, &dma); | ||
88 | if (!qh) | 88 | if (!qh) |
89 | return qh; | 89 | goto done; |
90 | 90 | qh->hw = (struct ehci_qh_hw *) | |
91 | memset (qh, 0, sizeof *qh); | 91 | dma_pool_alloc(ehci->qh_pool, flags, &dma); |
92 | if (!qh->hw) | ||
93 | goto fail; | ||
94 | memset(qh->hw, 0, sizeof *qh->hw); | ||
92 | qh->refcount = 1; | 95 | qh->refcount = 1; |
93 | qh->ehci = ehci; | 96 | qh->ehci = ehci; |
94 | qh->qh_dma = dma; | 97 | qh->qh_dma = dma; |
@@ -99,10 +102,15 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) | |||
99 | qh->dummy = ehci_qtd_alloc (ehci, flags); | 102 | qh->dummy = ehci_qtd_alloc (ehci, flags); |
100 | if (qh->dummy == NULL) { | 103 | if (qh->dummy == NULL) { |
101 | ehci_dbg (ehci, "no dummy td\n"); | 104 | ehci_dbg (ehci, "no dummy td\n"); |
102 | dma_pool_free (ehci->qh_pool, qh, qh->qh_dma); | 105 | goto fail1; |
103 | qh = NULL; | ||
104 | } | 106 | } |
107 | done: | ||
105 | return qh; | 108 | return qh; |
109 | fail1: | ||
110 | dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma); | ||
111 | fail: | ||
112 | kfree(qh); | ||
113 | return NULL; | ||
106 | } | 114 | } |
107 | 115 | ||
108 | /* to share a qh (cpu threads, or hc) */ | 116 | /* to share a qh (cpu threads, or hc) */ |
@@ -180,7 +188,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags) | |||
180 | /* QHs for control/bulk/intr transfers */ | 188 | /* QHs for control/bulk/intr transfers */ |
181 | ehci->qh_pool = dma_pool_create ("ehci_qh", | 189 | ehci->qh_pool = dma_pool_create ("ehci_qh", |
182 | ehci_to_hcd(ehci)->self.controller, | 190 | ehci_to_hcd(ehci)->self.controller, |
183 | sizeof (struct ehci_qh), | 191 | sizeof(struct ehci_qh_hw), |
184 | 32 /* byte alignment (for hw parts) */, | 192 | 32 /* byte alignment (for hw parts) */, |
185 | 4096 /* can't cross 4K */); | 193 | 4096 /* can't cross 4K */); |
186 | if (!ehci->qh_pool) { | 194 | if (!ehci->qh_pool) { |