diff options
Diffstat (limited to 'drivers/usb/host')
43 files changed, 721 insertions, 296 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 060e0e2b1ae6..a52769b5c904 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -194,6 +194,15 @@ config USB_EHCI_S5P | |||
194 | help | 194 | help |
195 | Enable support for the S5P SOC's on-chip EHCI controller. | 195 | Enable support for the S5P SOC's on-chip EHCI controller. |
196 | 196 | ||
197 | config USB_EHCI_MV | ||
198 | bool "EHCI support for Marvell on-chip controller" | ||
199 | depends on USB_EHCI_HCD | ||
200 | select USB_EHCI_ROOT_HUB_TT | ||
201 | ---help--- | ||
202 | Enables support for Marvell (including PXA and MMP series) on-chip | ||
203 | USB SPH and OTG controller. SPH is a single port host, and it can | ||
204 | only be EHCI host. OTG is controller that can switch to host mode. | ||
205 | |||
197 | config USB_W90X900_EHCI | 206 | config USB_W90X900_EHCI |
198 | bool "W90X900(W90P910) EHCI support" | 207 | bool "W90X900(W90P910) EHCI support" |
199 | depends on USB_EHCI_HCD && ARCH_W90X900 | 208 | depends on USB_EHCI_HCD && ARCH_W90X900 |
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 18bafa99fe57..bf7441afed16 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -23,6 +23,7 @@ static int au1xxx_ehci_setup(struct usb_hcd *hcd) | |||
23 | int ret = ehci_init(hcd); | 23 | int ret = ehci_init(hcd); |
24 | 24 | ||
25 | ehci->need_io_watchdog = 0; | 25 | ehci->need_io_watchdog = 0; |
26 | ehci_reset(ehci); | ||
26 | return ret; | 27 | return ret; |
27 | } | 28 | } |
28 | 29 | ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 3ff9f82f7263..e311a511529b 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -48,6 +48,10 @@ | |||
48 | #include <asm/system.h> | 48 | #include <asm/system.h> |
49 | #include <asm/unaligned.h> | 49 | #include <asm/unaligned.h> |
50 | 50 | ||
51 | #if defined(CONFIG_PPC_PS3) | ||
52 | #include <asm/firmware.h> | ||
53 | #endif | ||
54 | |||
51 | /*-------------------------------------------------------------------------*/ | 55 | /*-------------------------------------------------------------------------*/ |
52 | 56 | ||
53 | /* | 57 | /* |
@@ -230,12 +234,58 @@ static int ehci_halt (struct ehci_hcd *ehci) | |||
230 | STS_HALT, STS_HALT, 16 * 125); | 234 | STS_HALT, STS_HALT, 16 * 125); |
231 | } | 235 | } |
232 | 236 | ||
237 | #if defined(CONFIG_USB_SUSPEND) && defined(CONFIG_PPC_PS3) | ||
238 | |||
239 | /* | ||
240 | * The EHCI controller of the Cell Super Companion Chip used in the | ||
241 | * PS3 will stop the root hub after all root hub ports are suspended. | ||
242 | * When in this condition handshake will return -ETIMEDOUT. The | ||
243 | * STS_HLT bit will not be set, so inspection of the frame index is | ||
244 | * used here to test for the condition. If the condition is found | ||
245 | * return success to allow the USB suspend to complete. | ||
246 | */ | ||
247 | |||
248 | static int handshake_for_broken_root_hub(struct ehci_hcd *ehci, | ||
249 | void __iomem *ptr, u32 mask, u32 done, | ||
250 | int usec) | ||
251 | { | ||
252 | unsigned int old_index; | ||
253 | int error; | ||
254 | |||
255 | if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) | ||
256 | return -ETIMEDOUT; | ||
257 | |||
258 | old_index = ehci_read_frame_index(ehci); | ||
259 | |||
260 | error = handshake(ehci, ptr, mask, done, usec); | ||
261 | |||
262 | if (error == -ETIMEDOUT && ehci_read_frame_index(ehci) == old_index) | ||
263 | return 0; | ||
264 | |||
265 | return error; | ||
266 | } | ||
267 | |||
268 | #else | ||
269 | |||
270 | static int handshake_for_broken_root_hub(struct ehci_hcd *ehci, | ||
271 | void __iomem *ptr, u32 mask, u32 done, | ||
272 | int usec) | ||
273 | { | ||
274 | return -ETIMEDOUT; | ||
275 | } | ||
276 | |||
277 | #endif | ||
278 | |||
233 | static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, | 279 | static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, |
234 | u32 mask, u32 done, int usec) | 280 | u32 mask, u32 done, int usec) |
235 | { | 281 | { |
236 | int error; | 282 | int error; |
237 | 283 | ||
238 | error = handshake(ehci, ptr, mask, done, usec); | 284 | error = handshake(ehci, ptr, mask, done, usec); |
285 | if (error == -ETIMEDOUT) | ||
286 | error = handshake_for_broken_root_hub(ehci, ptr, mask, done, | ||
287 | usec); | ||
288 | |||
239 | if (error) { | 289 | if (error) { |
240 | ehci_halt(ehci); | 290 | ehci_halt(ehci); |
241 | ehci->rh_state = EHCI_RH_HALTED; | 291 | ehci->rh_state = EHCI_RH_HALTED; |
@@ -620,6 +670,7 @@ static int ehci_init(struct usb_hcd *hcd) | |||
620 | hw = ehci->async->hw; | 670 | hw = ehci->async->hw; |
621 | hw->hw_next = QH_NEXT(ehci, ehci->async->qh_dma); | 671 | hw->hw_next = QH_NEXT(ehci, ehci->async->qh_dma); |
622 | hw->hw_info1 = cpu_to_hc32(ehci, QH_HEAD); | 672 | hw->hw_info1 = cpu_to_hc32(ehci, QH_HEAD); |
673 | hw->hw_info1 |= cpu_to_hc32(ehci, (1 << 7)); /* I = 1 */ | ||
623 | hw->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT); | 674 | hw->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT); |
624 | hw->hw_qtd_next = EHCI_LIST_END(ehci); | 675 | hw->hw_qtd_next = EHCI_LIST_END(ehci); |
625 | ehci->async->qh_state = QH_STATE_LINKED; | 676 | ehci->async->qh_state = QH_STATE_LINKED; |
@@ -677,22 +728,13 @@ static int ehci_init(struct usb_hcd *hcd) | |||
677 | static int ehci_run (struct usb_hcd *hcd) | 728 | static int ehci_run (struct usb_hcd *hcd) |
678 | { | 729 | { |
679 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 730 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
680 | int retval; | ||
681 | u32 temp; | 731 | u32 temp; |
682 | u32 hcc_params; | 732 | u32 hcc_params; |
683 | 733 | ||
684 | hcd->uses_new_polling = 1; | 734 | hcd->uses_new_polling = 1; |
685 | 735 | ||
686 | /* EHCI spec section 4.1 */ | 736 | /* EHCI spec section 4.1 */ |
687 | /* | 737 | |
688 | * TDI driver does the ehci_reset in their reset callback. | ||
689 | * Don't reset here, because configuration settings will | ||
690 | * vanish. | ||
691 | */ | ||
692 | if (!ehci_is_TDI(ehci) && (retval = ehci_reset(ehci)) != 0) { | ||
693 | ehci_mem_cleanup(ehci); | ||
694 | return retval; | ||
695 | } | ||
696 | ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); | 738 | ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); |
697 | ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); | 739 | ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); |
698 | 740 | ||
@@ -1324,11 +1366,16 @@ MODULE_LICENSE ("GPL"); | |||
1324 | #define PLATFORM_DRIVER ehci_pxa168_driver | 1366 | #define PLATFORM_DRIVER ehci_pxa168_driver |
1325 | #endif | 1367 | #endif |
1326 | 1368 | ||
1327 | #ifdef CONFIG_NLM_XLR | 1369 | #ifdef CONFIG_CPU_XLR |
1328 | #include "ehci-xls.c" | 1370 | #include "ehci-xls.c" |
1329 | #define PLATFORM_DRIVER ehci_xls_driver | 1371 | #define PLATFORM_DRIVER ehci_xls_driver |
1330 | #endif | 1372 | #endif |
1331 | 1373 | ||
1374 | #ifdef CONFIG_USB_EHCI_MV | ||
1375 | #include "ehci-mv.c" | ||
1376 | #define PLATFORM_DRIVER ehci_mv_driver | ||
1377 | #endif | ||
1378 | |||
1332 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ | 1379 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ |
1333 | !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ | 1380 | !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ |
1334 | !defined(XILINX_OF_PLATFORM_DRIVER) | 1381 | !defined(XILINX_OF_PLATFORM_DRIVER) |
diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c new file mode 100644 index 000000000000..52a604fb9321 --- /dev/null +++ b/drivers/usb/host/ehci-mv.c | |||
@@ -0,0 +1,391 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Marvell International Ltd. All rights reserved. | ||
3 | * Author: Chao Xie <chao.xie@marvell.com> | ||
4 | * Neil Zhang <zhangwm@marvell.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/usb/otg.h> | ||
17 | #include <linux/platform_data/mv_usb.h> | ||
18 | |||
19 | #define CAPLENGTH_MASK (0xff) | ||
20 | |||
21 | struct ehci_hcd_mv { | ||
22 | struct usb_hcd *hcd; | ||
23 | |||
24 | /* Which mode does this ehci running OTG/Host ? */ | ||
25 | int mode; | ||
26 | |||
27 | void __iomem *phy_regs; | ||
28 | void __iomem *cap_regs; | ||
29 | void __iomem *op_regs; | ||
30 | |||
31 | struct otg_transceiver *otg; | ||
32 | |||
33 | struct mv_usb_platform_data *pdata; | ||
34 | |||
35 | /* clock source and total clock number */ | ||
36 | unsigned int clknum; | ||
37 | struct clk *clk[0]; | ||
38 | }; | ||
39 | |||
40 | static void ehci_clock_enable(struct ehci_hcd_mv *ehci_mv) | ||
41 | { | ||
42 | unsigned int i; | ||
43 | |||
44 | for (i = 0; i < ehci_mv->clknum; i++) | ||
45 | clk_enable(ehci_mv->clk[i]); | ||
46 | } | ||
47 | |||
48 | static void ehci_clock_disable(struct ehci_hcd_mv *ehci_mv) | ||
49 | { | ||
50 | unsigned int i; | ||
51 | |||
52 | for (i = 0; i < ehci_mv->clknum; i++) | ||
53 | clk_disable(ehci_mv->clk[i]); | ||
54 | } | ||
55 | |||
56 | static int mv_ehci_enable(struct ehci_hcd_mv *ehci_mv) | ||
57 | { | ||
58 | int retval; | ||
59 | |||
60 | ehci_clock_enable(ehci_mv); | ||
61 | if (ehci_mv->pdata->phy_init) { | ||
62 | retval = ehci_mv->pdata->phy_init(ehci_mv->phy_regs); | ||
63 | if (retval) | ||
64 | return retval; | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static void mv_ehci_disable(struct ehci_hcd_mv *ehci_mv) | ||
71 | { | ||
72 | if (ehci_mv->pdata->phy_deinit) | ||
73 | ehci_mv->pdata->phy_deinit(ehci_mv->phy_regs); | ||
74 | ehci_clock_disable(ehci_mv); | ||
75 | } | ||
76 | |||
77 | static int mv_ehci_reset(struct usb_hcd *hcd) | ||
78 | { | ||
79 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
80 | struct device *dev = hcd->self.controller; | ||
81 | struct ehci_hcd_mv *ehci_mv = dev_get_drvdata(dev); | ||
82 | int retval; | ||
83 | |||
84 | if (ehci_mv == NULL) { | ||
85 | dev_err(dev, "Can not find private ehci data\n"); | ||
86 | return -ENODEV; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * data structure init | ||
91 | */ | ||
92 | retval = ehci_init(hcd); | ||
93 | if (retval) { | ||
94 | dev_err(dev, "ehci_init failed %d\n", retval); | ||
95 | return retval; | ||
96 | } | ||
97 | |||
98 | hcd->has_tt = 1; | ||
99 | ehci->sbrn = 0x20; | ||
100 | |||
101 | retval = ehci_reset(ehci); | ||
102 | if (retval) { | ||
103 | dev_err(dev, "ehci_reset failed %d\n", retval); | ||
104 | return retval; | ||
105 | } | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static const struct hc_driver mv_ehci_hc_driver = { | ||
111 | .description = hcd_name, | ||
112 | .product_desc = "Marvell EHCI", | ||
113 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
114 | |||
115 | /* | ||
116 | * generic hardware linkage | ||
117 | */ | ||
118 | .irq = ehci_irq, | ||
119 | .flags = HCD_MEMORY | HCD_USB2, | ||
120 | |||
121 | /* | ||
122 | * basic lifecycle operations | ||
123 | */ | ||
124 | .reset = mv_ehci_reset, | ||
125 | .start = ehci_run, | ||
126 | .stop = ehci_stop, | ||
127 | .shutdown = ehci_shutdown, | ||
128 | |||
129 | /* | ||
130 | * managing i/o requests and associated device resources | ||
131 | */ | ||
132 | .urb_enqueue = ehci_urb_enqueue, | ||
133 | .urb_dequeue = ehci_urb_dequeue, | ||
134 | .endpoint_disable = ehci_endpoint_disable, | ||
135 | .endpoint_reset = ehci_endpoint_reset, | ||
136 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
137 | |||
138 | /* | ||
139 | * scheduling support | ||
140 | */ | ||
141 | .get_frame_number = ehci_get_frame, | ||
142 | |||
143 | /* | ||
144 | * root hub support | ||
145 | */ | ||
146 | .hub_status_data = ehci_hub_status_data, | ||
147 | .hub_control = ehci_hub_control, | ||
148 | .bus_suspend = ehci_bus_suspend, | ||
149 | .bus_resume = ehci_bus_resume, | ||
150 | }; | ||
151 | |||
152 | static int mv_ehci_probe(struct platform_device *pdev) | ||
153 | { | ||
154 | struct mv_usb_platform_data *pdata = pdev->dev.platform_data; | ||
155 | struct usb_hcd *hcd; | ||
156 | struct ehci_hcd *ehci; | ||
157 | struct ehci_hcd_mv *ehci_mv; | ||
158 | struct resource *r; | ||
159 | int clk_i, retval = -ENODEV; | ||
160 | u32 offset; | ||
161 | size_t size; | ||
162 | |||
163 | if (!pdata) { | ||
164 | dev_err(&pdev->dev, "missing platform_data\n"); | ||
165 | return -ENODEV; | ||
166 | } | ||
167 | |||
168 | if (usb_disabled()) | ||
169 | return -ENODEV; | ||
170 | |||
171 | hcd = usb_create_hcd(&mv_ehci_hc_driver, &pdev->dev, "mv ehci"); | ||
172 | if (!hcd) | ||
173 | return -ENOMEM; | ||
174 | |||
175 | size = sizeof(*ehci_mv) + sizeof(struct clk *) * pdata->clknum; | ||
176 | ehci_mv = kzalloc(size, GFP_KERNEL); | ||
177 | if (ehci_mv == NULL) { | ||
178 | dev_err(&pdev->dev, "cannot allocate ehci_hcd_mv\n"); | ||
179 | retval = -ENOMEM; | ||
180 | goto err_put_hcd; | ||
181 | } | ||
182 | |||
183 | platform_set_drvdata(pdev, ehci_mv); | ||
184 | ehci_mv->pdata = pdata; | ||
185 | ehci_mv->hcd = hcd; | ||
186 | |||
187 | ehci_mv->clknum = pdata->clknum; | ||
188 | for (clk_i = 0; clk_i < ehci_mv->clknum; clk_i++) { | ||
189 | ehci_mv->clk[clk_i] = | ||
190 | clk_get(&pdev->dev, pdata->clkname[clk_i]); | ||
191 | if (IS_ERR(ehci_mv->clk[clk_i])) { | ||
192 | dev_err(&pdev->dev, "error get clck \"%s\"\n", | ||
193 | pdata->clkname[clk_i]); | ||
194 | retval = PTR_ERR(ehci_mv->clk[clk_i]); | ||
195 | goto err_put_clk; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phyregs"); | ||
200 | if (r == NULL) { | ||
201 | dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); | ||
202 | retval = -ENODEV; | ||
203 | goto err_put_clk; | ||
204 | } | ||
205 | |||
206 | ehci_mv->phy_regs = ioremap(r->start, resource_size(r)); | ||
207 | if (ehci_mv->phy_regs == 0) { | ||
208 | dev_err(&pdev->dev, "failed to map phy I/O memory\n"); | ||
209 | retval = -EFAULT; | ||
210 | goto err_put_clk; | ||
211 | } | ||
212 | |||
213 | r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "capregs"); | ||
214 | if (!r) { | ||
215 | dev_err(&pdev->dev, "no I/O memory resource defined\n"); | ||
216 | retval = -ENODEV; | ||
217 | goto err_iounmap_phyreg; | ||
218 | } | ||
219 | |||
220 | ehci_mv->cap_regs = ioremap(r->start, resource_size(r)); | ||
221 | if (ehci_mv->cap_regs == NULL) { | ||
222 | dev_err(&pdev->dev, "failed to map I/O memory\n"); | ||
223 | retval = -EFAULT; | ||
224 | goto err_iounmap_phyreg; | ||
225 | } | ||
226 | |||
227 | retval = mv_ehci_enable(ehci_mv); | ||
228 | if (retval) { | ||
229 | dev_err(&pdev->dev, "init phy error %d\n", retval); | ||
230 | goto err_iounmap_capreg; | ||
231 | } | ||
232 | |||
233 | offset = readl(ehci_mv->cap_regs) & CAPLENGTH_MASK; | ||
234 | ehci_mv->op_regs = | ||
235 | (void __iomem *) ((unsigned long) ehci_mv->cap_regs + offset); | ||
236 | |||
237 | hcd->rsrc_start = r->start; | ||
238 | hcd->rsrc_len = r->end - r->start + 1; | ||
239 | hcd->regs = ehci_mv->op_regs; | ||
240 | |||
241 | hcd->irq = platform_get_irq(pdev, 0); | ||
242 | if (!hcd->irq) { | ||
243 | dev_err(&pdev->dev, "Cannot get irq."); | ||
244 | retval = -ENODEV; | ||
245 | goto err_disable_clk; | ||
246 | } | ||
247 | |||
248 | ehci = hcd_to_ehci(hcd); | ||
249 | ehci->caps = (struct ehci_caps *) ehci_mv->cap_regs; | ||
250 | ehci->regs = (struct ehci_regs *) ehci_mv->op_regs; | ||
251 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
252 | |||
253 | ehci_mv->mode = pdata->mode; | ||
254 | if (ehci_mv->mode == MV_USB_MODE_OTG) { | ||
255 | #ifdef CONFIG_USB_OTG_UTILS | ||
256 | ehci_mv->otg = otg_get_transceiver(); | ||
257 | if (!ehci_mv->otg) { | ||
258 | dev_err(&pdev->dev, | ||
259 | "unable to find transceiver\n"); | ||
260 | retval = -ENODEV; | ||
261 | goto err_disable_clk; | ||
262 | } | ||
263 | |||
264 | retval = otg_set_host(ehci_mv->otg, &hcd->self); | ||
265 | if (retval < 0) { | ||
266 | dev_err(&pdev->dev, | ||
267 | "unable to register with transceiver\n"); | ||
268 | retval = -ENODEV; | ||
269 | goto err_put_transceiver; | ||
270 | } | ||
271 | /* otg will enable clock before use as host */ | ||
272 | mv_ehci_disable(ehci_mv); | ||
273 | #else | ||
274 | dev_info(&pdev->dev, "MV_USB_MODE_OTG " | ||
275 | "must have CONFIG_USB_OTG_UTILS enabled\n"); | ||
276 | goto err_disable_clk; | ||
277 | #endif | ||
278 | } else { | ||
279 | if (pdata->set_vbus) | ||
280 | pdata->set_vbus(1); | ||
281 | |||
282 | retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); | ||
283 | if (retval) { | ||
284 | dev_err(&pdev->dev, | ||
285 | "failed to add hcd with err %d\n", retval); | ||
286 | goto err_set_vbus; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | if (pdata->private_init) | ||
291 | pdata->private_init(ehci_mv->op_regs, ehci_mv->phy_regs); | ||
292 | |||
293 | dev_info(&pdev->dev, | ||
294 | "successful find EHCI device with regs 0x%p irq %d" | ||
295 | " working in %s mode\n", hcd->regs, hcd->irq, | ||
296 | ehci_mv->mode == MV_USB_MODE_OTG ? "OTG" : "Host"); | ||
297 | |||
298 | return 0; | ||
299 | |||
300 | err_set_vbus: | ||
301 | if (pdata->set_vbus) | ||
302 | pdata->set_vbus(0); | ||
303 | #ifdef CONFIG_USB_OTG_UTILS | ||
304 | err_put_transceiver: | ||
305 | if (ehci_mv->otg) | ||
306 | otg_put_transceiver(ehci_mv->otg); | ||
307 | #endif | ||
308 | err_disable_clk: | ||
309 | mv_ehci_disable(ehci_mv); | ||
310 | err_iounmap_capreg: | ||
311 | iounmap(ehci_mv->cap_regs); | ||
312 | err_iounmap_phyreg: | ||
313 | iounmap(ehci_mv->phy_regs); | ||
314 | err_put_clk: | ||
315 | for (clk_i--; clk_i >= 0; clk_i--) | ||
316 | clk_put(ehci_mv->clk[clk_i]); | ||
317 | platform_set_drvdata(pdev, NULL); | ||
318 | kfree(ehci_mv); | ||
319 | err_put_hcd: | ||
320 | usb_put_hcd(hcd); | ||
321 | |||
322 | return retval; | ||
323 | } | ||
324 | |||
325 | static int mv_ehci_remove(struct platform_device *pdev) | ||
326 | { | ||
327 | struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev); | ||
328 | struct usb_hcd *hcd = ehci_mv->hcd; | ||
329 | int clk_i; | ||
330 | |||
331 | if (hcd->rh_registered) | ||
332 | usb_remove_hcd(hcd); | ||
333 | |||
334 | if (ehci_mv->otg) { | ||
335 | otg_set_host(ehci_mv->otg, NULL); | ||
336 | otg_put_transceiver(ehci_mv->otg); | ||
337 | } | ||
338 | |||
339 | if (ehci_mv->mode == MV_USB_MODE_HOST) { | ||
340 | if (ehci_mv->pdata->set_vbus) | ||
341 | ehci_mv->pdata->set_vbus(0); | ||
342 | |||
343 | mv_ehci_disable(ehci_mv); | ||
344 | } | ||
345 | |||
346 | iounmap(ehci_mv->cap_regs); | ||
347 | iounmap(ehci_mv->phy_regs); | ||
348 | |||
349 | for (clk_i = 0; clk_i < ehci_mv->clknum; clk_i++) | ||
350 | clk_put(ehci_mv->clk[clk_i]); | ||
351 | |||
352 | platform_set_drvdata(pdev, NULL); | ||
353 | |||
354 | kfree(ehci_mv); | ||
355 | usb_put_hcd(hcd); | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | MODULE_ALIAS("mv-ehci"); | ||
361 | |||
362 | static const struct platform_device_id ehci_id_table[] = { | ||
363 | {"pxa-u2oehci", PXA_U2OEHCI}, | ||
364 | {"pxa-sph", PXA_SPH}, | ||
365 | {"mmp3-hsic", MMP3_HSIC}, | ||
366 | {"mmp3-fsic", MMP3_FSIC}, | ||
367 | {}, | ||
368 | }; | ||
369 | |||
370 | static void mv_ehci_shutdown(struct platform_device *pdev) | ||
371 | { | ||
372 | struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev); | ||
373 | struct usb_hcd *hcd = ehci_mv->hcd; | ||
374 | |||
375 | if (!hcd->rh_registered) | ||
376 | return; | ||
377 | |||
378 | if (hcd->driver->shutdown) | ||
379 | hcd->driver->shutdown(hcd); | ||
380 | } | ||
381 | |||
382 | static struct platform_driver ehci_mv_driver = { | ||
383 | .probe = mv_ehci_probe, | ||
384 | .remove = mv_ehci_remove, | ||
385 | .shutdown = mv_ehci_shutdown, | ||
386 | .driver = { | ||
387 | .name = "mv-ehci", | ||
388 | .bus = &platform_bus_type, | ||
389 | }, | ||
390 | .id_table = ehci_id_table, | ||
391 | }; | ||
diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c index ba1f51361134..c0104882c72d 100644 --- a/drivers/usb/host/ehci-octeon.c +++ b/drivers/usb/host/ehci-octeon.c | |||
@@ -155,6 +155,8 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev) | |||
155 | /* cache this readonly data; minimize chip reads */ | 155 | /* cache this readonly data; minimize chip reads */ |
156 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | 156 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
157 | 157 | ||
158 | ehci_reset(ehci); | ||
159 | |||
158 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); | 160 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
159 | if (ret) { | 161 | if (ret) { |
160 | dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); | 162 | dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index e39b0297bad1..e33baf9052cb 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -228,6 +228,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
228 | /* cache this readonly data; minimize chip reads */ | 228 | /* cache this readonly data; minimize chip reads */ |
229 | omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params); | 229 | omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params); |
230 | 230 | ||
231 | ehci_reset(omap_ehci); | ||
232 | |||
231 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); | 233 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); |
232 | if (ret) { | 234 | if (ret) { |
233 | dev_err(dev, "failed to add hcd with err %d\n", ret); | 235 | dev_err(dev, "failed to add hcd with err %d\n", ret); |
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 2dc32da75cfc..a20e496eb479 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -21,6 +21,34 @@ | |||
21 | #include <asm/firmware.h> | 21 | #include <asm/firmware.h> |
22 | #include <asm/ps3.h> | 22 | #include <asm/ps3.h> |
23 | 23 | ||
24 | static void ps3_ehci_setup_insnreg(struct ehci_hcd *ehci) | ||
25 | { | ||
26 | /* PS3 HC internal setup register offsets. */ | ||
27 | |||
28 | enum ps3_ehci_hc_insnreg { | ||
29 | ps3_ehci_hc_insnreg01 = 0x084, | ||
30 | ps3_ehci_hc_insnreg02 = 0x088, | ||
31 | ps3_ehci_hc_insnreg03 = 0x08c, | ||
32 | }; | ||
33 | |||
34 | /* PS3 EHCI HC errata fix 316 - The PS3 EHCI HC will reset its | ||
35 | * internal INSNREGXX setup regs back to the chip default values | ||
36 | * on Host Controller Reset (CMD_RESET) or Light Host Controller | ||
37 | * Reset (CMD_LRESET). The work-around for this is for the HC | ||
38 | * driver to re-initialise these regs when ever the HC is reset. | ||
39 | */ | ||
40 | |||
41 | /* Set burst transfer counts to 256 out, 32 in. */ | ||
42 | |||
43 | writel_be(0x01000020, (void __iomem *)ehci->regs + | ||
44 | ps3_ehci_hc_insnreg01); | ||
45 | |||
46 | /* Enable burst transfer counts. */ | ||
47 | |||
48 | writel_be(0x00000001, (void __iomem *)ehci->regs + | ||
49 | ps3_ehci_hc_insnreg03); | ||
50 | } | ||
51 | |||
24 | static int ps3_ehci_hc_reset(struct usb_hcd *hcd) | 52 | static int ps3_ehci_hc_reset(struct usb_hcd *hcd) |
25 | { | 53 | { |
26 | int result; | 54 | int result; |
@@ -49,6 +77,8 @@ static int ps3_ehci_hc_reset(struct usb_hcd *hcd) | |||
49 | 77 | ||
50 | ehci_reset(ehci); | 78 | ehci_reset(ehci); |
51 | 79 | ||
80 | ps3_ehci_setup_insnreg(ehci); | ||
81 | |||
52 | return result; | 82 | return result; |
53 | } | 83 | } |
54 | 84 | ||
diff --git a/drivers/usb/host/ehci-pxa168.c b/drivers/usb/host/ehci-pxa168.c index ac0c16e8f539..8d0e7a22e711 100644 --- a/drivers/usb/host/ehci-pxa168.c +++ b/drivers/usb/host/ehci-pxa168.c | |||
@@ -299,7 +299,7 @@ static int __devinit ehci_pxa168_drv_probe(struct platform_device *pdev) | |||
299 | ehci = hcd_to_ehci(hcd); | 299 | ehci = hcd_to_ehci(hcd); |
300 | ehci->caps = hcd->regs + 0x100; | 300 | ehci->caps = hcd->regs + 0x100; |
301 | ehci->regs = hcd->regs + 0x100 + | 301 | ehci->regs = hcd->regs + 0x100 + |
302 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | 302 | HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); |
303 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | 303 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
304 | hcd->has_tt = 1; | 304 | hcd->has_tt = 1; |
305 | ehci->sbrn = 0x20; | 305 | ehci->sbrn = 0x20; |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 4e4066c35a09..36ca5077cdf7 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -373,6 +373,17 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
373 | retry_xacterr: | 373 | retry_xacterr: |
374 | if ((token & QTD_STS_ACTIVE) == 0) { | 374 | if ((token & QTD_STS_ACTIVE) == 0) { |
375 | 375 | ||
376 | /* Report Data Buffer Error: non-fatal but useful */ | ||
377 | if (token & QTD_STS_DBE) | ||
378 | ehci_dbg(ehci, | ||
379 | "detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n", | ||
380 | urb, | ||
381 | usb_endpoint_num(&urb->ep->desc), | ||
382 | usb_endpoint_dir_in(&urb->ep->desc) ? "in" : "out", | ||
383 | urb->transfer_buffer_length, | ||
384 | qtd, | ||
385 | qh); | ||
386 | |||
376 | /* on STALL, error, and short reads this urb must | 387 | /* on STALL, error, and short reads this urb must |
377 | * complete and all its qtds must be recycled. | 388 | * complete and all its qtds must be recycled. |
378 | */ | 389 | */ |
@@ -647,7 +658,7 @@ qh_urb_transaction ( | |||
647 | /* | 658 | /* |
648 | * data transfer stage: buffer setup | 659 | * data transfer stage: buffer setup |
649 | */ | 660 | */ |
650 | i = urb->num_sgs; | 661 | i = urb->num_mapped_sgs; |
651 | if (len > 0 && i > 0) { | 662 | if (len > 0 && i > 0) { |
652 | sg = urb->sg; | 663 | sg = urb->sg; |
653 | buf = sg_dma_address(sg); | 664 | buf = sg_dma_address(sg); |
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 024b65c4990d..293f7412992e 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c | |||
@@ -14,8 +14,6 @@ | |||
14 | 14 | ||
15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <mach/regs-pmu.h> | ||
18 | #include <plat/cpu.h> | ||
19 | #include <plat/ehci.h> | 17 | #include <plat/ehci.h> |
20 | #include <plat/usb-phy.h> | 18 | #include <plat/usb-phy.h> |
21 | 19 | ||
@@ -136,6 +134,8 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev) | |||
136 | /* cache this readonly data; minimize chip reads */ | 134 | /* cache this readonly data; minimize chip reads */ |
137 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | 135 | ehci->hcs_params = readl(&ehci->caps->hcs_params); |
138 | 136 | ||
137 | ehci_reset(ehci); | ||
138 | |||
139 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); | 139 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); |
140 | if (err) { | 140 | if (err) { |
141 | dev_err(&pdev->dev, "Failed to add USB HCD\n"); | 141 | dev_err(&pdev->dev, "Failed to add USB HCD\n"); |
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c index 54d1ab8aec49..c1eda73916cd 100644 --- a/drivers/usb/host/ehci-vt8500.c +++ b/drivers/usb/host/ehci-vt8500.c | |||
@@ -132,6 +132,8 @@ static int vt8500_ehci_drv_probe(struct platform_device *pdev) | |||
132 | 132 | ||
133 | ehci_port_power(ehci, 1); | 133 | ehci_port_power(ehci, 1); |
134 | 134 | ||
135 | ehci_reset(ehci); | ||
136 | |||
135 | ret = usb_add_hcd(hcd, pdev->resource[1].start, | 137 | ret = usb_add_hcd(hcd, pdev->resource[1].start, |
136 | IRQF_SHARED); | 138 | IRQF_SHARED); |
137 | if (ret == 0) { | 139 | if (ret == 0) { |
diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index d661cf7de140..3d2e26cbb34c 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c | |||
@@ -78,6 +78,8 @@ static int __devinit usb_w90x900_probe(const struct hc_driver *driver, | |||
78 | if (irq < 0) | 78 | if (irq < 0) |
79 | goto err4; | 79 | goto err4; |
80 | 80 | ||
81 | ehci_reset(ehci); | ||
82 | |||
81 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | 83 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); |
82 | if (retval != 0) | 84 | if (retval != 0) |
83 | goto err4; | 85 | goto err4; |
diff --git a/drivers/usb/host/ehci-xls.c b/drivers/usb/host/ehci-xls.c index b4fb511d24bc..72f08196f8cd 100644 --- a/drivers/usb/host/ehci-xls.c +++ b/drivers/usb/host/ehci-xls.c | |||
@@ -69,7 +69,7 @@ int ehci_xls_probe_internal(const struct hc_driver *driver, | |||
69 | } | 69 | } |
70 | 70 | ||
71 | hcd->rsrc_start = res->start; | 71 | hcd->rsrc_start = res->start; |
72 | hcd->rsrc_len = res->end - res->start + 1; | 72 | hcd->rsrc_len = resource_size(res); |
73 | 73 | ||
74 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | 74 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, |
75 | driver->description)) { | 75 | driver->description)) { |
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 4ed6d19f2a54..d2623747b489 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c | |||
@@ -824,17 +824,7 @@ static struct platform_driver of_fhci_driver = { | |||
824 | .remove = __devexit_p(of_fhci_remove), | 824 | .remove = __devexit_p(of_fhci_remove), |
825 | }; | 825 | }; |
826 | 826 | ||
827 | static int __init fhci_module_init(void) | 827 | module_platform_driver(of_fhci_driver); |
828 | { | ||
829 | return platform_driver_register(&of_fhci_driver); | ||
830 | } | ||
831 | module_init(fhci_module_init); | ||
832 | |||
833 | static void __exit fhci_module_exit(void) | ||
834 | { | ||
835 | platform_driver_unregister(&of_fhci_driver); | ||
836 | } | ||
837 | module_exit(fhci_module_exit); | ||
838 | 828 | ||
839 | MODULE_DESCRIPTION("USB Freescale Host Controller Interface Driver"); | 829 | MODULE_DESCRIPTION("USB Freescale Host Controller Interface Driver"); |
840 | MODULE_AUTHOR("Shlomi Gridish <gridish@freescale.com>, " | 830 | MODULE_AUTHOR("Shlomi Gridish <gridish@freescale.com>, " |
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 9037035ad1e4..7916e56a725e 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c | |||
@@ -297,17 +297,7 @@ static struct platform_driver fsl_usb2_mph_dr_driver = { | |||
297 | .remove = __devexit_p(fsl_usb2_mph_dr_of_remove), | 297 | .remove = __devexit_p(fsl_usb2_mph_dr_of_remove), |
298 | }; | 298 | }; |
299 | 299 | ||
300 | static int __init fsl_usb2_mph_dr_init(void) | 300 | module_platform_driver(fsl_usb2_mph_dr_driver); |
301 | { | ||
302 | return platform_driver_register(&fsl_usb2_mph_dr_driver); | ||
303 | } | ||
304 | module_init(fsl_usb2_mph_dr_init); | ||
305 | |||
306 | static void __exit fsl_usb2_mph_dr_exit(void) | ||
307 | { | ||
308 | platform_driver_unregister(&fsl_usb2_mph_dr_driver); | ||
309 | } | ||
310 | module_exit(fsl_usb2_mph_dr_exit); | ||
311 | 301 | ||
312 | MODULE_DESCRIPTION("FSL MPH DR OF devices driver"); | 302 | MODULE_DESCRIPTION("FSL MPH DR OF devices driver"); |
313 | MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); | 303 | MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); |
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 43b3ca48d753..104730dabd2d 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c | |||
@@ -776,7 +776,6 @@ static int hwahc_probe(struct usb_interface *usb_iface, | |||
776 | goto error_alloc; | 776 | goto error_alloc; |
777 | } | 777 | } |
778 | usb_hcd->wireless = 1; | 778 | usb_hcd->wireless = 1; |
779 | set_bit(HCD_FLAG_SAW_IRQ, &usb_hcd->flags); | ||
780 | wusbhc = usb_hcd_to_wusbhc(usb_hcd); | 779 | wusbhc = usb_hcd_to_wusbhc(usb_hcd); |
781 | hwahc = container_of(wusbhc, struct hwahc, wusbhc); | 780 | hwahc = container_of(wusbhc, struct hwahc, wusbhc); |
782 | hwahc_init(hwahc); | 781 | hwahc_init(hwahc); |
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index dbf0f156ed9e..ff471c1c165e 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c | |||
@@ -1924,18 +1924,7 @@ static struct platform_driver imx21_hcd_driver = { | |||
1924 | .resume = NULL, | 1924 | .resume = NULL, |
1925 | }; | 1925 | }; |
1926 | 1926 | ||
1927 | static int __init imx21_hcd_init(void) | 1927 | module_platform_driver(imx21_hcd_driver); |
1928 | { | ||
1929 | return platform_driver_register(&imx21_hcd_driver); | ||
1930 | } | ||
1931 | |||
1932 | static void __exit imx21_hcd_cleanup(void) | ||
1933 | { | ||
1934 | platform_driver_unregister(&imx21_hcd_driver); | ||
1935 | } | ||
1936 | |||
1937 | module_init(imx21_hcd_init); | ||
1938 | module_exit(imx21_hcd_cleanup); | ||
1939 | 1928 | ||
1940 | MODULE_DESCRIPTION("i.MX21 USB Host controller"); | 1929 | MODULE_DESCRIPTION("i.MX21 USB Host controller"); |
1941 | MODULE_AUTHOR("Martin Fuzzey"); | 1930 | MODULE_AUTHOR("Martin Fuzzey"); |
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 27dfab80ed8f..fc72d44bf787 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -32,6 +32,13 @@ static struct kmem_cache *qtd_cachep; | |||
32 | static struct kmem_cache *qh_cachep; | 32 | static struct kmem_cache *qh_cachep; |
33 | static struct kmem_cache *urb_listitem_cachep; | 33 | static struct kmem_cache *urb_listitem_cachep; |
34 | 34 | ||
35 | enum queue_head_types { | ||
36 | QH_CONTROL, | ||
37 | QH_BULK, | ||
38 | QH_INTERRUPT, | ||
39 | QH_END | ||
40 | }; | ||
41 | |||
35 | struct isp1760_hcd { | 42 | struct isp1760_hcd { |
36 | u32 hcs_params; | 43 | u32 hcs_params; |
37 | spinlock_t lock; | 44 | spinlock_t lock; |
@@ -40,7 +47,7 @@ struct isp1760_hcd { | |||
40 | struct slotinfo int_slots[32]; | 47 | struct slotinfo int_slots[32]; |
41 | int int_done_map; | 48 | int int_done_map; |
42 | struct memory_chunk memory_pool[BLOCKS]; | 49 | struct memory_chunk memory_pool[BLOCKS]; |
43 | struct list_head controlqhs, bulkqhs, interruptqhs; | 50 | struct list_head qh_list[QH_END]; |
44 | 51 | ||
45 | /* periodic schedule support */ | 52 | /* periodic schedule support */ |
46 | #define DEFAULT_I_TDPS 1024 | 53 | #define DEFAULT_I_TDPS 1024 |
@@ -406,12 +413,12 @@ static int priv_init(struct usb_hcd *hcd) | |||
406 | { | 413 | { |
407 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 414 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
408 | u32 hcc_params; | 415 | u32 hcc_params; |
416 | int i; | ||
409 | 417 | ||
410 | spin_lock_init(&priv->lock); | 418 | spin_lock_init(&priv->lock); |
411 | 419 | ||
412 | INIT_LIST_HEAD(&priv->interruptqhs); | 420 | for (i = 0; i < QH_END; i++) |
413 | INIT_LIST_HEAD(&priv->controlqhs); | 421 | INIT_LIST_HEAD(&priv->qh_list[i]); |
414 | INIT_LIST_HEAD(&priv->bulkqhs); | ||
415 | 422 | ||
416 | /* | 423 | /* |
417 | * hw default: 1K periodic list heads, one per frame. | 424 | * hw default: 1K periodic list heads, one per frame. |
@@ -930,9 +937,9 @@ void schedule_ptds(struct usb_hcd *hcd) | |||
930 | struct isp1760_hcd *priv; | 937 | struct isp1760_hcd *priv; |
931 | struct isp1760_qh *qh, *qh_next; | 938 | struct isp1760_qh *qh, *qh_next; |
932 | struct list_head *ep_queue; | 939 | struct list_head *ep_queue; |
933 | struct usb_host_endpoint *ep; | ||
934 | LIST_HEAD(urb_list); | 940 | LIST_HEAD(urb_list); |
935 | struct urb_listitem *urb_listitem, *urb_listitem_next; | 941 | struct urb_listitem *urb_listitem, *urb_listitem_next; |
942 | int i; | ||
936 | 943 | ||
937 | if (!hcd) { | 944 | if (!hcd) { |
938 | WARN_ON(1); | 945 | WARN_ON(1); |
@@ -944,28 +951,13 @@ void schedule_ptds(struct usb_hcd *hcd) | |||
944 | /* | 951 | /* |
945 | * check finished/retired xfers, transfer payloads, call urb_done() | 952 | * check finished/retired xfers, transfer payloads, call urb_done() |
946 | */ | 953 | */ |
947 | ep_queue = &priv->interruptqhs; | 954 | for (i = 0; i < QH_END; i++) { |
948 | while (ep_queue) { | 955 | ep_queue = &priv->qh_list[i]; |
949 | list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) { | 956 | list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) { |
950 | ep = list_entry(qh->qtd_list.next, struct isp1760_qtd, | ||
951 | qtd_list)->urb->ep; | ||
952 | collect_qtds(hcd, qh, &urb_list); | 957 | collect_qtds(hcd, qh, &urb_list); |
953 | if (list_empty(&qh->qtd_list)) { | 958 | if (list_empty(&qh->qtd_list)) |
954 | list_del(&qh->qh_list); | 959 | list_del(&qh->qh_list); |
955 | if (ep->hcpriv == NULL) { | ||
956 | /* Endpoint has been disabled, so we | ||
957 | can free the associated queue head. */ | ||
958 | qh_free(qh); | ||
959 | } | ||
960 | } | ||
961 | } | 960 | } |
962 | |||
963 | if (ep_queue == &priv->interruptqhs) | ||
964 | ep_queue = &priv->controlqhs; | ||
965 | else if (ep_queue == &priv->controlqhs) | ||
966 | ep_queue = &priv->bulkqhs; | ||
967 | else | ||
968 | ep_queue = NULL; | ||
969 | } | 961 | } |
970 | 962 | ||
971 | list_for_each_entry_safe(urb_listitem, urb_listitem_next, &urb_list, | 963 | list_for_each_entry_safe(urb_listitem, urb_listitem_next, &urb_list, |
@@ -998,17 +990,10 @@ void schedule_ptds(struct usb_hcd *hcd) | |||
998 | * | 990 | * |
999 | * I'm sure this scheme could be improved upon! | 991 | * I'm sure this scheme could be improved upon! |
1000 | */ | 992 | */ |
1001 | ep_queue = &priv->controlqhs; | 993 | for (i = 0; i < QH_END; i++) { |
1002 | while (ep_queue) { | 994 | ep_queue = &priv->qh_list[i]; |
1003 | list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) | 995 | list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) |
1004 | enqueue_qtds(hcd, qh); | 996 | enqueue_qtds(hcd, qh); |
1005 | |||
1006 | if (ep_queue == &priv->controlqhs) | ||
1007 | ep_queue = &priv->interruptqhs; | ||
1008 | else if (ep_queue == &priv->interruptqhs) | ||
1009 | ep_queue = &priv->bulkqhs; | ||
1010 | else | ||
1011 | ep_queue = NULL; | ||
1012 | } | 997 | } |
1013 | } | 998 | } |
1014 | 999 | ||
@@ -1543,16 +1528,16 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | |||
1543 | 1528 | ||
1544 | switch (usb_pipetype(urb->pipe)) { | 1529 | switch (usb_pipetype(urb->pipe)) { |
1545 | case PIPE_CONTROL: | 1530 | case PIPE_CONTROL: |
1546 | ep_queue = &priv->controlqhs; | 1531 | ep_queue = &priv->qh_list[QH_CONTROL]; |
1547 | break; | 1532 | break; |
1548 | case PIPE_BULK: | 1533 | case PIPE_BULK: |
1549 | ep_queue = &priv->bulkqhs; | 1534 | ep_queue = &priv->qh_list[QH_BULK]; |
1550 | break; | 1535 | break; |
1551 | case PIPE_INTERRUPT: | 1536 | case PIPE_INTERRUPT: |
1552 | if (urb->interval < 0) | 1537 | if (urb->interval < 0) |
1553 | return -EINVAL; | 1538 | return -EINVAL; |
1554 | /* FIXME: Check bandwidth */ | 1539 | /* FIXME: Check bandwidth */ |
1555 | ep_queue = &priv->interruptqhs; | 1540 | ep_queue = &priv->qh_list[QH_INTERRUPT]; |
1556 | break; | 1541 | break; |
1557 | case PIPE_ISOCHRONOUS: | 1542 | case PIPE_ISOCHRONOUS: |
1558 | dev_err(hcd->self.controller, "%s: isochronous USB packets " | 1543 | dev_err(hcd->self.controller, "%s: isochronous USB packets " |
@@ -1714,8 +1699,8 @@ static void isp1760_endpoint_disable(struct usb_hcd *hcd, | |||
1714 | { | 1699 | { |
1715 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 1700 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
1716 | unsigned long spinflags; | 1701 | unsigned long spinflags; |
1717 | struct isp1760_qh *qh; | 1702 | struct isp1760_qh *qh, *qh_iter; |
1718 | struct isp1760_qtd *qtd; | 1703 | int i; |
1719 | 1704 | ||
1720 | spin_lock_irqsave(&priv->lock, spinflags); | 1705 | spin_lock_irqsave(&priv->lock, spinflags); |
1721 | 1706 | ||
@@ -1723,14 +1708,17 @@ static void isp1760_endpoint_disable(struct usb_hcd *hcd, | |||
1723 | if (!qh) | 1708 | if (!qh) |
1724 | goto out; | 1709 | goto out; |
1725 | 1710 | ||
1726 | list_for_each_entry(qtd, &qh->qtd_list, qtd_list) | 1711 | WARN_ON(!list_empty(&qh->qtd_list)); |
1727 | if (qtd->status != QTD_RETIRE) { | ||
1728 | dequeue_urb_from_qtd(hcd, qh, qtd); | ||
1729 | qtd->urb->status = -ECONNRESET; | ||
1730 | } | ||
1731 | 1712 | ||
1713 | for (i = 0; i < QH_END; i++) | ||
1714 | list_for_each_entry(qh_iter, &priv->qh_list[i], qh_list) | ||
1715 | if (qh_iter == qh) { | ||
1716 | list_del(&qh_iter->qh_list); | ||
1717 | i = QH_END; | ||
1718 | break; | ||
1719 | } | ||
1720 | qh_free(qh); | ||
1732 | ep->hcpriv = NULL; | 1721 | ep->hcpriv = NULL; |
1733 | /* Cannot free qh here since it will be parsed by schedule_ptds() */ | ||
1734 | 1722 | ||
1735 | schedule_ptds(hcd); | 1723 | schedule_ptds(hcd); |
1736 | 1724 | ||
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 2ac4ac2e4ef9..4592dc17a9f9 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c | |||
@@ -47,23 +47,27 @@ static int of_isp1760_probe(struct platform_device *dev) | |||
47 | int virq; | 47 | int virq; |
48 | resource_size_t res_len; | 48 | resource_size_t res_len; |
49 | int ret; | 49 | int ret; |
50 | const unsigned int *prop; | ||
51 | unsigned int devflags = 0; | 50 | unsigned int devflags = 0; |
52 | enum of_gpio_flags gpio_flags; | 51 | enum of_gpio_flags gpio_flags; |
52 | u32 bus_width = 0; | ||
53 | 53 | ||
54 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); | 54 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); |
55 | if (!drvdata) | 55 | if (!drvdata) |
56 | return -ENOMEM; | 56 | return -ENOMEM; |
57 | 57 | ||
58 | ret = of_address_to_resource(dp, 0, &memory); | 58 | ret = of_address_to_resource(dp, 0, &memory); |
59 | if (ret) | 59 | if (ret) { |
60 | return -ENXIO; | 60 | ret = -ENXIO; |
61 | goto free_data; | ||
62 | } | ||
61 | 63 | ||
62 | res_len = resource_size(&memory); | 64 | res_len = resource_size(&memory); |
63 | 65 | ||
64 | res = request_mem_region(memory.start, res_len, dev_name(&dev->dev)); | 66 | res = request_mem_region(memory.start, res_len, dev_name(&dev->dev)); |
65 | if (!res) | 67 | if (!res) { |
66 | return -EBUSY; | 68 | ret = -EBUSY; |
69 | goto free_data; | ||
70 | } | ||
67 | 71 | ||
68 | if (of_irq_map_one(dp, 0, &oirq)) { | 72 | if (of_irq_map_one(dp, 0, &oirq)) { |
69 | ret = -ENODEV; | 73 | ret = -ENODEV; |
@@ -77,8 +81,8 @@ static int of_isp1760_probe(struct platform_device *dev) | |||
77 | devflags |= ISP1760_FLAG_ISP1761; | 81 | devflags |= ISP1760_FLAG_ISP1761; |
78 | 82 | ||
79 | /* Some systems wire up only 16 of the 32 data lines */ | 83 | /* Some systems wire up only 16 of the 32 data lines */ |
80 | prop = of_get_property(dp, "bus-width", NULL); | 84 | of_property_read_u32(dp, "bus-width", &bus_width); |
81 | if (prop && *prop == 16) | 85 | if (bus_width == 16) |
82 | devflags |= ISP1760_FLAG_BUS_WIDTH_16; | 86 | devflags |= ISP1760_FLAG_BUS_WIDTH_16; |
83 | 87 | ||
84 | if (of_get_property(dp, "port1-otg", NULL) != NULL) | 88 | if (of_get_property(dp, "port1-otg", NULL) != NULL) |
@@ -125,6 +129,7 @@ free_gpio: | |||
125 | gpio_free(drvdata->rst_gpio); | 129 | gpio_free(drvdata->rst_gpio); |
126 | release_reg: | 130 | release_reg: |
127 | release_mem_region(memory.start, res_len); | 131 | release_mem_region(memory.start, res_len); |
132 | free_data: | ||
128 | kfree(drvdata); | 133 | kfree(drvdata); |
129 | return ret; | 134 | return ret; |
130 | } | 135 | } |
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 9b66df8278f3..40d886adff53 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -173,12 +173,9 @@ static int ohci_hcd_au1xxx_drv_suspend(struct device *dev) | |||
173 | * mark HW unaccessible, bail out if RH has been resumed. Use | 173 | * mark HW unaccessible, bail out if RH has been resumed. Use |
174 | * the spinlock to properly synchronize with possible pending | 174 | * the spinlock to properly synchronize with possible pending |
175 | * RH suspend or resume activity. | 175 | * RH suspend or resume activity. |
176 | * | ||
177 | * This is still racy as hcd->state is manipulated outside of | ||
178 | * any locks =P But that will be a different fix. | ||
179 | */ | 176 | */ |
180 | spin_lock_irqsave(&ohci->lock, flags); | 177 | spin_lock_irqsave(&ohci->lock, flags); |
181 | if (hcd->state != HC_STATE_SUSPENDED) { | 178 | if (ohci->rh_state != OHCI_RH_SUSPENDED) { |
182 | rc = -EINVAL; | 179 | rc = -EINVAL; |
183 | goto bail; | 180 | goto bail; |
184 | } | 181 | } |
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index d7d34492934a..5179fcd73d8a 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -127,6 +127,19 @@ static char *hcfs2string (int state) | |||
127 | return "?"; | 127 | return "?"; |
128 | } | 128 | } |
129 | 129 | ||
130 | static const char *rh_state_string(struct ohci_hcd *ohci) | ||
131 | { | ||
132 | switch (ohci->rh_state) { | ||
133 | case OHCI_RH_HALTED: | ||
134 | return "halted"; | ||
135 | case OHCI_RH_SUSPENDED: | ||
136 | return "suspended"; | ||
137 | case OHCI_RH_RUNNING: | ||
138 | return "running"; | ||
139 | } | ||
140 | return "?"; | ||
141 | } | ||
142 | |||
130 | // dump control and status registers | 143 | // dump control and status registers |
131 | static void | 144 | static void |
132 | ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) | 145 | ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) |
@@ -136,9 +149,10 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) | |||
136 | 149 | ||
137 | temp = ohci_readl (controller, ®s->revision) & 0xff; | 150 | temp = ohci_readl (controller, ®s->revision) & 0xff; |
138 | ohci_dbg_sw (controller, next, size, | 151 | ohci_dbg_sw (controller, next, size, |
139 | "OHCI %d.%d, %s legacy support registers\n", | 152 | "OHCI %d.%d, %s legacy support registers, rh state %s\n", |
140 | 0x03 & (temp >> 4), (temp & 0x0f), | 153 | 0x03 & (temp >> 4), (temp & 0x0f), |
141 | (temp & 0x0100) ? "with" : "NO"); | 154 | (temp & 0x0100) ? "with" : "NO", |
155 | rh_state_string(controller)); | ||
142 | 156 | ||
143 | temp = ohci_readl (controller, ®s->control); | 157 | temp = ohci_readl (controller, ®s->control); |
144 | ohci_dbg_sw (controller, next, size, | 158 | ohci_dbg_sw (controller, next, size, |
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index dc45d489d00e..3d63574d2c7e 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c | |||
@@ -179,8 +179,6 @@ static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_ | |||
179 | ohci->next_statechange = jiffies; | 179 | ohci->next_statechange = jiffies; |
180 | 180 | ||
181 | ep93xx_stop_hc(&pdev->dev); | 181 | ep93xx_stop_hc(&pdev->dev); |
182 | hcd->state = HC_STATE_SUSPENDED; | ||
183 | |||
184 | return 0; | 182 | return 0; |
185 | } | 183 | } |
186 | 184 | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index b2639191549e..4fa5d8c4d239 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -209,7 +209,7 @@ static int ohci_urb_enqueue ( | |||
209 | retval = -ENODEV; | 209 | retval = -ENODEV; |
210 | goto fail; | 210 | goto fail; |
211 | } | 211 | } |
212 | if (!HC_IS_RUNNING(hcd->state)) { | 212 | if (ohci->rh_state != OHCI_RH_RUNNING) { |
213 | retval = -ENODEV; | 213 | retval = -ENODEV; |
214 | goto fail; | 214 | goto fail; |
215 | } | 215 | } |
@@ -274,7 +274,7 @@ static int ohci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
274 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | 274 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); |
275 | if (rc) { | 275 | if (rc) { |
276 | ; /* Do nothing */ | 276 | ; /* Do nothing */ |
277 | } else if (HC_IS_RUNNING(hcd->state)) { | 277 | } else if (ohci->rh_state == OHCI_RH_RUNNING) { |
278 | urb_priv_t *urb_priv; | 278 | urb_priv_t *urb_priv; |
279 | 279 | ||
280 | /* Unless an IRQ completed the unlink while it was being | 280 | /* Unless an IRQ completed the unlink while it was being |
@@ -321,7 +321,7 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) | |||
321 | rescan: | 321 | rescan: |
322 | spin_lock_irqsave (&ohci->lock, flags); | 322 | spin_lock_irqsave (&ohci->lock, flags); |
323 | 323 | ||
324 | if (!HC_IS_RUNNING (hcd->state)) { | 324 | if (ohci->rh_state != OHCI_RH_RUNNING) { |
325 | sanitize: | 325 | sanitize: |
326 | ed->state = ED_IDLE; | 326 | ed->state = ED_IDLE; |
327 | if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) | 327 | if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) |
@@ -377,6 +377,7 @@ static void ohci_usb_reset (struct ohci_hcd *ohci) | |||
377 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); | 377 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); |
378 | ohci->hc_control &= OHCI_CTRL_RWC; | 378 | ohci->hc_control &= OHCI_CTRL_RWC; |
379 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); | 379 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); |
380 | ohci->rh_state = OHCI_RH_HALTED; | ||
380 | } | 381 | } |
381 | 382 | ||
382 | /* ohci_shutdown forcibly disables IRQs and DMA, helping kexec and | 383 | /* ohci_shutdown forcibly disables IRQs and DMA, helping kexec and |
@@ -500,7 +501,7 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
500 | if (distrust_firmware) | 501 | if (distrust_firmware) |
501 | ohci->flags |= OHCI_QUIRK_HUB_POWER; | 502 | ohci->flags |= OHCI_QUIRK_HUB_POWER; |
502 | 503 | ||
503 | disable (ohci); | 504 | ohci->rh_state = OHCI_RH_HALTED; |
504 | ohci->regs = hcd->regs; | 505 | ohci->regs = hcd->regs; |
505 | 506 | ||
506 | /* REVISIT this BIOS handshake is now moved into PCI "quirks", and | 507 | /* REVISIT this BIOS handshake is now moved into PCI "quirks", and |
@@ -575,7 +576,7 @@ static int ohci_run (struct ohci_hcd *ohci) | |||
575 | int first = ohci->fminterval == 0; | 576 | int first = ohci->fminterval == 0; |
576 | struct usb_hcd *hcd = ohci_to_hcd(ohci); | 577 | struct usb_hcd *hcd = ohci_to_hcd(ohci); |
577 | 578 | ||
578 | disable (ohci); | 579 | ohci->rh_state = OHCI_RH_HALTED; |
579 | 580 | ||
580 | /* boot firmware should have set this up (5.1.1.3.1) */ | 581 | /* boot firmware should have set this up (5.1.1.3.1) */ |
581 | if (first) { | 582 | if (first) { |
@@ -688,7 +689,7 @@ retry: | |||
688 | ohci->hc_control &= OHCI_CTRL_RWC; | 689 | ohci->hc_control &= OHCI_CTRL_RWC; |
689 | ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; | 690 | ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; |
690 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); | 691 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); |
691 | hcd->state = HC_STATE_RUNNING; | 692 | ohci->rh_state = OHCI_RH_RUNNING; |
692 | 693 | ||
693 | /* wake on ConnectStatusChange, matching external hubs */ | 694 | /* wake on ConnectStatusChange, matching external hubs */ |
694 | ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status); | 695 | ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status); |
@@ -725,7 +726,6 @@ retry: | |||
725 | 726 | ||
726 | // POTPGT delay is bits 24-31, in 2 ms units. | 727 | // POTPGT delay is bits 24-31, in 2 ms units. |
727 | mdelay ((val >> 23) & 0x1fe); | 728 | mdelay ((val >> 23) & 0x1fe); |
728 | hcd->state = HC_STATE_RUNNING; | ||
729 | 729 | ||
730 | if (quirk_zfmicro(ohci)) { | 730 | if (quirk_zfmicro(ohci)) { |
731 | /* Create timer to watch for bad queue state on ZF Micro */ | 731 | /* Create timer to watch for bad queue state on ZF Micro */ |
@@ -761,7 +761,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
761 | * of dead, unclocked, or unplugged (CardBus...) devices | 761 | * of dead, unclocked, or unplugged (CardBus...) devices |
762 | */ | 762 | */ |
763 | if (ints == ~(u32)0) { | 763 | if (ints == ~(u32)0) { |
764 | disable (ohci); | 764 | ohci->rh_state = OHCI_RH_HALTED; |
765 | ohci_dbg (ohci, "device removed!\n"); | 765 | ohci_dbg (ohci, "device removed!\n"); |
766 | usb_hc_died(hcd); | 766 | usb_hc_died(hcd); |
767 | return IRQ_HANDLED; | 767 | return IRQ_HANDLED; |
@@ -771,7 +771,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
771 | ints &= ohci_readl(ohci, ®s->intrenable); | 771 | ints &= ohci_readl(ohci, ®s->intrenable); |
772 | 772 | ||
773 | /* interrupt for some other device? */ | 773 | /* interrupt for some other device? */ |
774 | if (ints == 0 || unlikely(hcd->state == HC_STATE_HALT)) | 774 | if (ints == 0 || unlikely(ohci->rh_state == OHCI_RH_HALTED)) |
775 | return IRQ_NOTMINE; | 775 | return IRQ_NOTMINE; |
776 | 776 | ||
777 | if (ints & OHCI_INTR_UE) { | 777 | if (ints & OHCI_INTR_UE) { |
@@ -786,8 +786,8 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
786 | 786 | ||
787 | schedule_work (&ohci->nec_work); | 787 | schedule_work (&ohci->nec_work); |
788 | } else { | 788 | } else { |
789 | disable (ohci); | ||
790 | ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n"); | 789 | ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n"); |
790 | ohci->rh_state = OHCI_RH_HALTED; | ||
791 | usb_hc_died(hcd); | 791 | usb_hc_died(hcd); |
792 | } | 792 | } |
793 | 793 | ||
@@ -871,11 +871,11 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
871 | if ((ints & OHCI_INTR_SF) != 0 | 871 | if ((ints & OHCI_INTR_SF) != 0 |
872 | && !ohci->ed_rm_list | 872 | && !ohci->ed_rm_list |
873 | && !ohci->ed_to_check | 873 | && !ohci->ed_to_check |
874 | && HC_IS_RUNNING(hcd->state)) | 874 | && ohci->rh_state == OHCI_RH_RUNNING) |
875 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); | 875 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); |
876 | spin_unlock (&ohci->lock); | 876 | spin_unlock (&ohci->lock); |
877 | 877 | ||
878 | if (HC_IS_RUNNING(hcd->state)) { | 878 | if (ohci->rh_state == OHCI_RH_RUNNING) { |
879 | ohci_writel (ohci, ints, ®s->intrstatus); | 879 | ohci_writel (ohci, ints, ®s->intrstatus); |
880 | ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable); | 880 | ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable); |
881 | // flush those writes | 881 | // flush those writes |
@@ -929,7 +929,7 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
929 | struct urb_priv *priv; | 929 | struct urb_priv *priv; |
930 | 930 | ||
931 | spin_lock_irq(&ohci->lock); | 931 | spin_lock_irq(&ohci->lock); |
932 | disable (ohci); | 932 | ohci->rh_state = OHCI_RH_HALTED; |
933 | 933 | ||
934 | /* Recycle any "live" eds/tds (and urbs). */ | 934 | /* Recycle any "live" eds/tds (and urbs). */ |
935 | if (!list_empty (&ohci->pending)) | 935 | if (!list_empty (&ohci->pending)) |
@@ -1111,7 +1111,7 @@ MODULE_LICENSE ("GPL"); | |||
1111 | #define PLATFORM_DRIVER ohci_hcd_ath79_driver | 1111 | #define PLATFORM_DRIVER ohci_hcd_ath79_driver |
1112 | #endif | 1112 | #endif |
1113 | 1113 | ||
1114 | #ifdef CONFIG_NLM_XLR | 1114 | #ifdef CONFIG_CPU_XLR |
1115 | #include "ohci-xls.c" | 1115 | #include "ohci-xls.c" |
1116 | #define PLATFORM_DRIVER ohci_xls_driver | 1116 | #define PLATFORM_DRIVER ohci_xls_driver |
1117 | #endif | 1117 | #endif |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 2f00040fc408..836772dfabd3 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -111,6 +111,7 @@ __acquires(ohci->lock) | |||
111 | if (!autostop) { | 111 | if (!autostop) { |
112 | ohci->next_statechange = jiffies + msecs_to_jiffies (5); | 112 | ohci->next_statechange = jiffies + msecs_to_jiffies (5); |
113 | ohci->autostop = 0; | 113 | ohci->autostop = 0; |
114 | ohci->rh_state = OHCI_RH_SUSPENDED; | ||
114 | } | 115 | } |
115 | 116 | ||
116 | done: | 117 | done: |
@@ -140,7 +141,7 @@ __acquires(ohci->lock) | |||
140 | 141 | ||
141 | if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { | 142 | if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { |
142 | /* this can happen after resuming a swsusp snapshot */ | 143 | /* this can happen after resuming a swsusp snapshot */ |
143 | if (hcd->state == HC_STATE_RESUMING) { | 144 | if (ohci->rh_state != OHCI_RH_RUNNING) { |
144 | ohci_dbg (ohci, "BIOS/SMM active, control %03x\n", | 145 | ohci_dbg (ohci, "BIOS/SMM active, control %03x\n", |
145 | ohci->hc_control); | 146 | ohci->hc_control); |
146 | status = -EBUSY; | 147 | status = -EBUSY; |
@@ -274,6 +275,7 @@ skip_resume: | |||
274 | (void) ohci_readl (ohci, &ohci->regs->control); | 275 | (void) ohci_readl (ohci, &ohci->regs->control); |
275 | } | 276 | } |
276 | 277 | ||
278 | ohci->rh_state = OHCI_RH_RUNNING; | ||
277 | return 0; | 279 | return 0; |
278 | } | 280 | } |
279 | 281 | ||
@@ -336,11 +338,8 @@ static void ohci_finish_controller_resume(struct usb_hcd *hcd) | |||
336 | /* If needed, reinitialize and suspend the root hub */ | 338 | /* If needed, reinitialize and suspend the root hub */ |
337 | if (need_reinit) { | 339 | if (need_reinit) { |
338 | spin_lock_irq(&ohci->lock); | 340 | spin_lock_irq(&ohci->lock); |
339 | hcd->state = HC_STATE_RESUMING; | ||
340 | ohci_rh_resume(ohci); | 341 | ohci_rh_resume(ohci); |
341 | hcd->state = HC_STATE_QUIESCING; | ||
342 | ohci_rh_suspend(ohci, 0); | 342 | ohci_rh_suspend(ohci, 0); |
343 | hcd->state = HC_STATE_SUSPENDED; | ||
344 | spin_unlock_irq(&ohci->lock); | 343 | spin_unlock_irq(&ohci->lock); |
345 | } | 344 | } |
346 | 345 | ||
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index e4b8782cc6e2..db3968656d21 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -516,7 +516,6 @@ static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message) | |||
516 | ohci->next_statechange = jiffies; | 516 | ohci->next_statechange = jiffies; |
517 | 517 | ||
518 | omap_ohci_clock_power(0); | 518 | omap_ohci_clock_power(0); |
519 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; | ||
520 | return 0; | 519 | return 0; |
521 | } | 520 | } |
522 | 521 | ||
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index bc01b064585a..6109810cc2d3 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -308,12 +308,9 @@ static int ohci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
308 | * mark HW unaccessible, bail out if RH has been resumed. Use | 308 | * mark HW unaccessible, bail out if RH has been resumed. Use |
309 | * the spinlock to properly synchronize with possible pending | 309 | * the spinlock to properly synchronize with possible pending |
310 | * RH suspend or resume activity. | 310 | * RH suspend or resume activity. |
311 | * | ||
312 | * This is still racy as hcd->state is manipulated outside of | ||
313 | * any locks =P But that will be a different fix. | ||
314 | */ | 311 | */ |
315 | spin_lock_irqsave (&ohci->lock, flags); | 312 | spin_lock_irqsave (&ohci->lock, flags); |
316 | if (hcd->state != HC_STATE_SUSPENDED) { | 313 | if (ohci->rh_state != OHCI_RH_SUSPENDED) { |
317 | rc = -EINVAL; | 314 | rc = -EINVAL; |
318 | goto bail; | 315 | goto bail; |
319 | } | 316 | } |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 29dfefe1c726..6313e4439f37 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -502,8 +502,6 @@ static int ohci_hcd_pxa27x_drv_suspend(struct device *dev) | |||
502 | ohci->ohci.next_statechange = jiffies; | 502 | ohci->ohci.next_statechange = jiffies; |
503 | 503 | ||
504 | pxa27x_stop_hc(ohci, dev); | 504 | pxa27x_stop_hc(ohci, dev); |
505 | hcd->state = HC_STATE_SUSPENDED; | ||
506 | |||
507 | return 0; | 505 | return 0; |
508 | } | 506 | } |
509 | 507 | ||
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 15dc51ded61a..c5a1ea9145fa 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -912,7 +912,7 @@ rescan_all: | |||
912 | /* only take off EDs that the HC isn't using, accounting for | 912 | /* only take off EDs that the HC isn't using, accounting for |
913 | * frame counter wraps and EDs with partially retired TDs | 913 | * frame counter wraps and EDs with partially retired TDs |
914 | */ | 914 | */ |
915 | if (likely (HC_IS_RUNNING(ohci_to_hcd(ohci)->state))) { | 915 | if (likely(ohci->rh_state == OHCI_RH_RUNNING)) { |
916 | if (tick_before (tick, ed->tick)) { | 916 | if (tick_before (tick, ed->tick)) { |
917 | skip_ed: | 917 | skip_ed: |
918 | last = &ed->ed_next; | 918 | last = &ed->ed_next; |
@@ -1012,7 +1012,7 @@ rescan_this: | |||
1012 | 1012 | ||
1013 | /* but if there's work queued, reschedule */ | 1013 | /* but if there's work queued, reschedule */ |
1014 | if (!list_empty (&ed->td_list)) { | 1014 | if (!list_empty (&ed->td_list)) { |
1015 | if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state)) | 1015 | if (ohci->rh_state == OHCI_RH_RUNNING) |
1016 | ed_schedule (ohci, ed); | 1016 | ed_schedule (ohci, ed); |
1017 | } | 1017 | } |
1018 | 1018 | ||
@@ -1021,9 +1021,7 @@ rescan_this: | |||
1021 | } | 1021 | } |
1022 | 1022 | ||
1023 | /* maybe reenable control and bulk lists */ | 1023 | /* maybe reenable control and bulk lists */ |
1024 | if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state) | 1024 | if (ohci->rh_state == OHCI_RH_RUNNING && !ohci->ed_rm_list) { |
1025 | && ohci_to_hcd(ohci)->state != HC_STATE_QUIESCING | ||
1026 | && !ohci->ed_rm_list) { | ||
1027 | u32 command = 0, control = 0; | 1025 | u32 command = 0, control = 0; |
1028 | 1026 | ||
1029 | if (ohci->ed_controltail) { | 1027 | if (ohci->ed_controltail) { |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index a1877c47601e..56dcf069246d 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -486,15 +486,66 @@ static int __devexit ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev) | |||
486 | return 0; | 486 | return 0; |
487 | } | 487 | } |
488 | 488 | ||
489 | #ifdef CONFIG_PM | ||
490 | static int ohci_hcd_s3c2410_drv_suspend(struct device *dev) | ||
491 | { | ||
492 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
493 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
494 | struct platform_device *pdev = to_platform_device(dev); | ||
495 | unsigned long flags; | ||
496 | int rc = 0; | ||
497 | |||
498 | /* | ||
499 | * Root hub was already suspended. Disable irq emission and | ||
500 | * mark HW unaccessible, bail out if RH has been resumed. Use | ||
501 | * the spinlock to properly synchronize with possible pending | ||
502 | * RH suspend or resume activity. | ||
503 | */ | ||
504 | spin_lock_irqsave(&ohci->lock, flags); | ||
505 | if (ohci->rh_state != OHCI_RH_SUSPENDED) { | ||
506 | rc = -EINVAL; | ||
507 | goto bail; | ||
508 | } | ||
509 | |||
510 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
511 | |||
512 | s3c2410_stop_hc(pdev); | ||
513 | bail: | ||
514 | spin_unlock_irqrestore(&ohci->lock, flags); | ||
515 | |||
516 | return rc; | ||
517 | } | ||
518 | |||
519 | static int ohci_hcd_s3c2410_drv_resume(struct device *dev) | ||
520 | { | ||
521 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
522 | struct platform_device *pdev = to_platform_device(dev); | ||
523 | |||
524 | s3c2410_start_hc(pdev, hcd); | ||
525 | |||
526 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
527 | ohci_finish_controller_resume(hcd); | ||
528 | |||
529 | return 0; | ||
530 | } | ||
531 | #else | ||
532 | #define ohci_hcd_s3c2410_drv_suspend NULL | ||
533 | #define ohci_hcd_s3c2410_drv_resume NULL | ||
534 | #endif | ||
535 | |||
536 | static const struct dev_pm_ops ohci_hcd_s3c2410_pm_ops = { | ||
537 | .suspend = ohci_hcd_s3c2410_drv_suspend, | ||
538 | .resume = ohci_hcd_s3c2410_drv_resume, | ||
539 | }; | ||
540 | |||
489 | static struct platform_driver ohci_hcd_s3c2410_driver = { | 541 | static struct platform_driver ohci_hcd_s3c2410_driver = { |
490 | .probe = ohci_hcd_s3c2410_drv_probe, | 542 | .probe = ohci_hcd_s3c2410_drv_probe, |
491 | .remove = __devexit_p(ohci_hcd_s3c2410_drv_remove), | 543 | .remove = __devexit_p(ohci_hcd_s3c2410_drv_remove), |
492 | .shutdown = usb_hcd_platform_shutdown, | 544 | .shutdown = usb_hcd_platform_shutdown, |
493 | /*.suspend = ohci_hcd_s3c2410_drv_suspend, */ | ||
494 | /*.resume = ohci_hcd_s3c2410_drv_resume, */ | ||
495 | .driver = { | 545 | .driver = { |
496 | .owner = THIS_MODULE, | 546 | .owner = THIS_MODULE, |
497 | .name = "s3c2410-ohci", | 547 | .name = "s3c2410-ohci", |
548 | .pm = &ohci_hcd_s3c2410_pm_ops, | ||
498 | }, | 549 | }, |
499 | }; | 550 | }; |
500 | 551 | ||
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c index afc4eb6bb9d0..84686d90805b 100644 --- a/drivers/usb/host/ohci-sh.c +++ b/drivers/usb/host/ohci-sh.c | |||
@@ -29,7 +29,6 @@ static int ohci_sh_start(struct usb_hcd *hcd) | |||
29 | ohci_hcd_init(ohci); | 29 | ohci_hcd_init(ohci); |
30 | ohci_init(ohci); | 30 | ohci_init(ohci); |
31 | ohci_run(ohci); | 31 | ohci_run(ohci); |
32 | hcd->state = HC_STATE_RUNNING; | ||
33 | return 0; | 32 | return 0; |
34 | } | 33 | } |
35 | 34 | ||
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 968cea2b6d4e..5596ac2ba1ca 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c | |||
@@ -224,7 +224,6 @@ static int ohci_sm501_suspend(struct platform_device *pdev, pm_message_t msg) | |||
224 | ohci->next_statechange = jiffies; | 224 | ohci->next_statechange = jiffies; |
225 | 225 | ||
226 | sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 0); | 226 | sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 0); |
227 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; | ||
228 | return 0; | 227 | return 0; |
229 | } | 228 | } |
230 | 229 | ||
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index 69874654f3b5..95c16489e883 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c | |||
@@ -203,7 +203,6 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev, | |||
203 | ohci->next_statechange = jiffies; | 203 | ohci->next_statechange = jiffies; |
204 | 204 | ||
205 | spear_stop_ohci(ohci_p); | 205 | spear_stop_ohci(ohci_p); |
206 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; | ||
207 | return 0; | 206 | return 0; |
208 | } | 207 | } |
209 | 208 | ||
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index 06331d931171..120bfe6ede38 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c | |||
@@ -318,9 +318,6 @@ static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t s | |||
318 | if (ret) | 318 | if (ret) |
319 | return ret; | 319 | return ret; |
320 | } | 320 | } |
321 | |||
322 | hcd->state = HC_STATE_SUSPENDED; | ||
323 | |||
324 | return 0; | 321 | return 0; |
325 | } | 322 | } |
326 | 323 | ||
diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c index a3a9c6f45b91..a2247867af86 100644 --- a/drivers/usb/host/ohci-xls.c +++ b/drivers/usb/host/ohci-xls.c | |||
@@ -40,7 +40,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver, | |||
40 | goto err1; | 40 | goto err1; |
41 | } | 41 | } |
42 | hcd->rsrc_start = res->start; | 42 | hcd->rsrc_start = res->start; |
43 | hcd->rsrc_len = res->end - res->start + 1; | 43 | hcd->rsrc_len = resource_size(res); |
44 | 44 | ||
45 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | 45 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, |
46 | driver->description)) { | 46 | driver->description)) { |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 0795b934d00c..8ff6f7ea96fd 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -344,6 +344,12 @@ typedef struct urb_priv { | |||
344 | * a subset of what the full implementation needs. (Linus) | 344 | * a subset of what the full implementation needs. (Linus) |
345 | */ | 345 | */ |
346 | 346 | ||
347 | enum ohci_rh_state { | ||
348 | OHCI_RH_HALTED, | ||
349 | OHCI_RH_SUSPENDED, | ||
350 | OHCI_RH_RUNNING | ||
351 | }; | ||
352 | |||
347 | struct ohci_hcd { | 353 | struct ohci_hcd { |
348 | spinlock_t lock; | 354 | spinlock_t lock; |
349 | 355 | ||
@@ -384,6 +390,7 @@ struct ohci_hcd { | |||
384 | /* | 390 | /* |
385 | * driver state | 391 | * driver state |
386 | */ | 392 | */ |
393 | enum ohci_rh_state rh_state; | ||
387 | int num_ports; | 394 | int num_ports; |
388 | int load [NUM_INTS]; | 395 | int load [NUM_INTS]; |
389 | u32 hc_control; /* copy of hc control reg */ | 396 | u32 hc_control; /* copy of hc control reg */ |
@@ -679,11 +686,6 @@ static inline u16 ohci_hwPSW(const struct ohci_hcd *ohci, | |||
679 | 686 | ||
680 | /*-------------------------------------------------------------------------*/ | 687 | /*-------------------------------------------------------------------------*/ |
681 | 688 | ||
682 | static inline void disable (struct ohci_hcd *ohci) | ||
683 | { | ||
684 | ohci_to_hcd(ohci)->state = HC_STATE_HALT; | ||
685 | } | ||
686 | |||
687 | #define FI 0x2edf /* 12000 bits per frame (-1) */ | 689 | #define FI 0x2edf /* 12000 bits per frame (-1) */ |
688 | #define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7)) | 690 | #define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7)) |
689 | #define FIT (1 << 31) | 691 | #define FIT (1 << 31) |
@@ -707,7 +709,7 @@ static inline void periodic_reinit (struct ohci_hcd *ohci) | |||
707 | #define read_roothub(hc, register, mask) ({ \ | 709 | #define read_roothub(hc, register, mask) ({ \ |
708 | u32 temp = ohci_readl (hc, &hc->regs->roothub.register); \ | 710 | u32 temp = ohci_readl (hc, &hc->regs->roothub.register); \ |
709 | if (temp == -1) \ | 711 | if (temp == -1) \ |
710 | disable (hc); \ | 712 | hc->rh_state = OHCI_RH_HALTED; \ |
711 | else if (hc->flags & OHCI_QUIRK_AMD756) \ | 713 | else if (hc->flags & OHCI_QUIRK_AMD756) \ |
712 | while (temp & mask) \ | 714 | while (temp & mask) \ |
713 | temp = ohci_readl (hc, &hc->regs->roothub.register); \ | 715 | temp = ohci_readl (hc, &hc->regs->roothub.register); \ |
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index dcd889803f0f..6f62de5c6e35 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c | |||
@@ -3951,24 +3951,7 @@ static struct platform_driver oxu_driver = { | |||
3951 | } | 3951 | } |
3952 | }; | 3952 | }; |
3953 | 3953 | ||
3954 | static int __init oxu_module_init(void) | 3954 | module_platform_driver(oxu_driver); |
3955 | { | ||
3956 | int retval = 0; | ||
3957 | |||
3958 | retval = platform_driver_register(&oxu_driver); | ||
3959 | if (retval < 0) | ||
3960 | return retval; | ||
3961 | |||
3962 | return retval; | ||
3963 | } | ||
3964 | |||
3965 | static void __exit oxu_module_cleanup(void) | ||
3966 | { | ||
3967 | platform_driver_unregister(&oxu_driver); | ||
3968 | } | ||
3969 | |||
3970 | module_init(oxu_module_init); | ||
3971 | module_exit(oxu_module_cleanup); | ||
3972 | 3955 | ||
3973 | MODULE_DESCRIPTION("Oxford OXU210HP HCD driver - ver. " DRIVER_VERSION); | 3956 | MODULE_DESCRIPTION("Oxford OXU210HP HCD driver - ver. " DRIVER_VERSION); |
3974 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); | 3957 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index f6ca80ee4cec..d2c6f5ac4626 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -943,7 +943,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
943 | if (usb_pipein(urb->pipe)) | 943 | if (usb_pipein(urb->pipe)) |
944 | status |= TD_CTRL_SPD; | 944 | status |= TD_CTRL_SPD; |
945 | 945 | ||
946 | i = urb->num_sgs; | 946 | i = urb->num_mapped_sgs; |
947 | if (len > 0 && i > 0) { | 947 | if (len > 0 && i > 0) { |
948 | sg = urb->sg; | 948 | sg = urb->sg; |
949 | data = sg_dma_address(sg); | 949 | data = sg_dma_address(sg); |
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index a403b53e86b9..76083ae92138 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c | |||
@@ -443,7 +443,7 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u | |||
443 | 443 | ||
444 | remaining = urb->transfer_buffer_length; | 444 | remaining = urb->transfer_buffer_length; |
445 | 445 | ||
446 | for_each_sg(urb->sg, sg, urb->num_sgs, i) { | 446 | for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) { |
447 | dma_addr_t dma_addr; | 447 | dma_addr_t dma_addr; |
448 | size_t dma_remaining; | 448 | size_t dma_remaining; |
449 | dma_addr_t sp, ep; | 449 | dma_addr_t sp, ep; |
@@ -561,7 +561,7 @@ static int qset_add_urb_sg_linearize(struct whc *whc, struct whc_qset *qset, | |||
561 | 561 | ||
562 | remaining = urb->transfer_buffer_length; | 562 | remaining = urb->transfer_buffer_length; |
563 | 563 | ||
564 | for_each_sg(urb->sg, sg, urb->num_sgs, i) { | 564 | for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) { |
565 | size_t len; | 565 | size_t len; |
566 | size_t sg_remaining; | 566 | size_t sg_remaining; |
567 | void *orig; | 567 | void *orig; |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 430e88fd3f6c..35e257f79c7b 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -57,17 +57,15 @@ static void xhci_common_hub_descriptor(struct xhci_hcd *xhci, | |||
57 | desc->bHubContrCurrent = 0; | 57 | desc->bHubContrCurrent = 0; |
58 | 58 | ||
59 | desc->bNbrPorts = ports; | 59 | desc->bNbrPorts = ports; |
60 | /* Ugh, these should be #defines, FIXME */ | ||
61 | /* Using table 11-13 in USB 2.0 spec. */ | ||
62 | temp = 0; | 60 | temp = 0; |
63 | /* Bits 1:0 - support port power switching, or power always on */ | 61 | /* Bits 1:0 - support per-port power switching, or power always on */ |
64 | if (HCC_PPC(xhci->hcc_params)) | 62 | if (HCC_PPC(xhci->hcc_params)) |
65 | temp |= 0x0001; | 63 | temp |= HUB_CHAR_INDV_PORT_LPSM; |
66 | else | 64 | else |
67 | temp |= 0x0002; | 65 | temp |= HUB_CHAR_NO_LPSM; |
68 | /* Bit 2 - root hubs are not part of a compound device */ | 66 | /* Bit 2 - root hubs are not part of a compound device */ |
69 | /* Bits 4:3 - individual port over current protection */ | 67 | /* Bits 4:3 - individual port over current protection */ |
70 | temp |= 0x0008; | 68 | temp |= HUB_CHAR_INDV_PORT_OCPM; |
71 | /* Bits 6:5 - no TTs in root ports */ | 69 | /* Bits 6:5 - no TTs in root ports */ |
72 | /* Bit 7 - no port indicators */ | 70 | /* Bit 7 - no port indicators */ |
73 | desc->wHubCharacteristics = cpu_to_le16(temp); | 71 | desc->wHubCharacteristics = cpu_to_le16(temp); |
@@ -86,9 +84,9 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, | |||
86 | ports = xhci->num_usb2_ports; | 84 | ports = xhci->num_usb2_ports; |
87 | 85 | ||
88 | xhci_common_hub_descriptor(xhci, desc, ports); | 86 | xhci_common_hub_descriptor(xhci, desc, ports); |
89 | desc->bDescriptorType = 0x29; | 87 | desc->bDescriptorType = USB_DT_HUB; |
90 | temp = 1 + (ports / 8); | 88 | temp = 1 + (ports / 8); |
91 | desc->bDescLength = 7 + 2 * temp; | 89 | desc->bDescLength = USB_DT_HUB_NONVAR_SIZE + 2 * temp; |
92 | 90 | ||
93 | /* The Device Removable bits are reported on a byte granularity. | 91 | /* The Device Removable bits are reported on a byte granularity. |
94 | * If the port doesn't exist within that byte, the bit is set to 0. | 92 | * If the port doesn't exist within that byte, the bit is set to 0. |
@@ -137,8 +135,8 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, | |||
137 | 135 | ||
138 | ports = xhci->num_usb3_ports; | 136 | ports = xhci->num_usb3_ports; |
139 | xhci_common_hub_descriptor(xhci, desc, ports); | 137 | xhci_common_hub_descriptor(xhci, desc, ports); |
140 | desc->bDescriptorType = 0x2a; | 138 | desc->bDescriptorType = USB_DT_SS_HUB; |
141 | desc->bDescLength = 12; | 139 | desc->bDescLength = USB_DT_SS_HUB_SIZE; |
142 | 140 | ||
143 | /* header decode latency should be zero for roothubs, | 141 | /* header decode latency should be zero for roothubs, |
144 | * see section 4.23.5.2. | 142 | * see section 4.23.5.2. |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 0e4b25fa3bcd..36cbe2226a44 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -42,15 +42,12 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, gfp_t flag | |||
42 | seg = kzalloc(sizeof *seg, flags); | 42 | seg = kzalloc(sizeof *seg, flags); |
43 | if (!seg) | 43 | if (!seg) |
44 | return NULL; | 44 | return NULL; |
45 | xhci_dbg(xhci, "Allocating priv segment structure at %p\n", seg); | ||
46 | 45 | ||
47 | seg->trbs = dma_pool_alloc(xhci->segment_pool, flags, &dma); | 46 | seg->trbs = dma_pool_alloc(xhci->segment_pool, flags, &dma); |
48 | if (!seg->trbs) { | 47 | if (!seg->trbs) { |
49 | kfree(seg); | 48 | kfree(seg); |
50 | return NULL; | 49 | return NULL; |
51 | } | 50 | } |
52 | xhci_dbg(xhci, "// Allocating segment at %p (virtual) 0x%llx (DMA)\n", | ||
53 | seg->trbs, (unsigned long long)dma); | ||
54 | 51 | ||
55 | memset(seg->trbs, 0, SEGMENT_SIZE); | 52 | memset(seg->trbs, 0, SEGMENT_SIZE); |
56 | seg->dma = dma; | 53 | seg->dma = dma; |
@@ -62,12 +59,9 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, gfp_t flag | |||
62 | static void xhci_segment_free(struct xhci_hcd *xhci, struct xhci_segment *seg) | 59 | static void xhci_segment_free(struct xhci_hcd *xhci, struct xhci_segment *seg) |
63 | { | 60 | { |
64 | if (seg->trbs) { | 61 | if (seg->trbs) { |
65 | xhci_dbg(xhci, "Freeing DMA segment at %p (virtual) 0x%llx (DMA)\n", | ||
66 | seg->trbs, (unsigned long long)seg->dma); | ||
67 | dma_pool_free(xhci->segment_pool, seg->trbs, seg->dma); | 62 | dma_pool_free(xhci->segment_pool, seg->trbs, seg->dma); |
68 | seg->trbs = NULL; | 63 | seg->trbs = NULL; |
69 | } | 64 | } |
70 | xhci_dbg(xhci, "Freeing priv segment structure at %p\n", seg); | ||
71 | kfree(seg); | 65 | kfree(seg); |
72 | } | 66 | } |
73 | 67 | ||
@@ -101,9 +95,6 @@ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev, | |||
101 | val |= TRB_CHAIN; | 95 | val |= TRB_CHAIN; |
102 | prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val); | 96 | prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val); |
103 | } | 97 | } |
104 | xhci_dbg(xhci, "Linking segment 0x%llx to segment 0x%llx (DMA)\n", | ||
105 | (unsigned long long)prev->dma, | ||
106 | (unsigned long long)next->dma); | ||
107 | } | 98 | } |
108 | 99 | ||
109 | /* XXX: Do we need the hcd structure in all these functions? */ | 100 | /* XXX: Do we need the hcd structure in all these functions? */ |
@@ -117,7 +108,6 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring) | |||
117 | if (ring->first_seg) { | 108 | if (ring->first_seg) { |
118 | first_seg = ring->first_seg; | 109 | first_seg = ring->first_seg; |
119 | seg = first_seg->next; | 110 | seg = first_seg->next; |
120 | xhci_dbg(xhci, "Freeing ring at %p\n", ring); | ||
121 | while (seg != first_seg) { | 111 | while (seg != first_seg) { |
122 | struct xhci_segment *next = seg->next; | 112 | struct xhci_segment *next = seg->next; |
123 | xhci_segment_free(xhci, seg); | 113 | xhci_segment_free(xhci, seg); |
@@ -160,7 +150,6 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, | |||
160 | struct xhci_segment *prev; | 150 | struct xhci_segment *prev; |
161 | 151 | ||
162 | ring = kzalloc(sizeof *(ring), flags); | 152 | ring = kzalloc(sizeof *(ring), flags); |
163 | xhci_dbg(xhci, "Allocating ring at %p\n", ring); | ||
164 | if (!ring) | 153 | if (!ring) |
165 | return NULL; | 154 | return NULL; |
166 | 155 | ||
@@ -191,9 +180,6 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, | |||
191 | /* See section 4.9.2.1 and 6.4.4.1 */ | 180 | /* See section 4.9.2.1 and 6.4.4.1 */ |
192 | prev->trbs[TRBS_PER_SEGMENT-1].link.control |= | 181 | prev->trbs[TRBS_PER_SEGMENT-1].link.control |= |
193 | cpu_to_le32(LINK_TOGGLE); | 182 | cpu_to_le32(LINK_TOGGLE); |
194 | xhci_dbg(xhci, "Wrote link toggle flag to" | ||
195 | " segment %p (virtual), 0x%llx (DMA)\n", | ||
196 | prev, (unsigned long long)prev->dma); | ||
197 | } | 183 | } |
198 | xhci_initialize_ring_info(ring); | 184 | xhci_initialize_ring_info(ring); |
199 | return ring; | 185 | return ring; |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 9f1d4b15d818..b90e1386418b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -155,10 +155,6 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer | |||
155 | while (last_trb(xhci, ring, ring->deq_seg, next)) { | 155 | while (last_trb(xhci, ring, ring->deq_seg, next)) { |
156 | if (consumer && last_trb_on_last_seg(xhci, ring, ring->deq_seg, next)) { | 156 | if (consumer && last_trb_on_last_seg(xhci, ring, ring->deq_seg, next)) { |
157 | ring->cycle_state = (ring->cycle_state ? 0 : 1); | 157 | ring->cycle_state = (ring->cycle_state ? 0 : 1); |
158 | if (!in_interrupt()) | ||
159 | xhci_dbg(xhci, "Toggle cycle state for ring %p = %i\n", | ||
160 | ring, | ||
161 | (unsigned int) ring->cycle_state); | ||
162 | } | 158 | } |
163 | ring->deq_seg = ring->deq_seg->next; | 159 | ring->deq_seg = ring->deq_seg->next; |
164 | ring->dequeue = ring->deq_seg->trbs; | 160 | ring->dequeue = ring->deq_seg->trbs; |
@@ -231,10 +227,6 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, | |||
231 | /* Toggle the cycle bit after the last ring segment. */ | 227 | /* Toggle the cycle bit after the last ring segment. */ |
232 | if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) { | 228 | if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) { |
233 | ring->cycle_state = (ring->cycle_state ? 0 : 1); | 229 | ring->cycle_state = (ring->cycle_state ? 0 : 1); |
234 | if (!in_interrupt()) | ||
235 | xhci_dbg(xhci, "Toggle cycle state for ring %p = %i\n", | ||
236 | ring, | ||
237 | (unsigned int) ring->cycle_state); | ||
238 | } | 230 | } |
239 | } | 231 | } |
240 | ring->enq_seg = ring->enq_seg->next; | 232 | ring->enq_seg = ring->enq_seg->next; |
@@ -560,12 +552,9 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, | |||
560 | cpu_to_le32(TRB_CYCLE); | 552 | cpu_to_le32(TRB_CYCLE); |
561 | cur_trb->generic.field[3] |= cpu_to_le32( | 553 | cur_trb->generic.field[3] |= cpu_to_le32( |
562 | TRB_TYPE(TRB_TR_NOOP)); | 554 | TRB_TYPE(TRB_TR_NOOP)); |
563 | xhci_dbg(xhci, "Cancel TRB %p (0x%llx dma) " | 555 | xhci_dbg(xhci, "TRB to noop at offset 0x%llx\n", |
564 | "in seg %p (0x%llx dma)\n", | 556 | (unsigned long long) |
565 | cur_trb, | 557 | xhci_trb_virt_to_dma(cur_seg, cur_trb)); |
566 | (unsigned long long)xhci_trb_virt_to_dma(cur_seg, cur_trb), | ||
567 | cur_seg, | ||
568 | (unsigned long long)cur_seg->dma); | ||
569 | } | 558 | } |
570 | if (cur_trb == cur_td->last_trb) | 559 | if (cur_trb == cur_td->last_trb) |
571 | break; | 560 | break; |
@@ -705,9 +694,9 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, | |||
705 | */ | 694 | */ |
706 | list_for_each(entry, &ep->cancelled_td_list) { | 695 | list_for_each(entry, &ep->cancelled_td_list) { |
707 | cur_td = list_entry(entry, struct xhci_td, cancelled_td_list); | 696 | cur_td = list_entry(entry, struct xhci_td, cancelled_td_list); |
708 | xhci_dbg(xhci, "Cancelling TD starting at %p, 0x%llx (dma).\n", | 697 | xhci_dbg(xhci, "Removing canceled TD starting at 0x%llx (dma).\n", |
709 | cur_td->first_trb, | 698 | (unsigned long long)xhci_trb_virt_to_dma( |
710 | (unsigned long long)xhci_trb_virt_to_dma(cur_td->start_seg, cur_td->first_trb)); | 699 | cur_td->start_seg, cur_td->first_trb)); |
711 | ep_ring = xhci_urb_to_transfer_ring(xhci, cur_td->urb); | 700 | ep_ring = xhci_urb_to_transfer_ring(xhci, cur_td->urb); |
712 | if (!ep_ring) { | 701 | if (!ep_ring) { |
713 | /* This shouldn't happen unless a driver is mucking | 702 | /* This shouldn't happen unless a driver is mucking |
@@ -1627,7 +1616,6 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1627 | ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); | 1616 | ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); |
1628 | trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); | 1617 | trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); |
1629 | 1618 | ||
1630 | xhci_debug_trb(xhci, xhci->event_ring->dequeue); | ||
1631 | switch (trb_comp_code) { | 1619 | switch (trb_comp_code) { |
1632 | case COMP_SUCCESS: | 1620 | case COMP_SUCCESS: |
1633 | if (event_trb == ep_ring->dequeue) { | 1621 | if (event_trb == ep_ring->dequeue) { |
@@ -1643,7 +1631,6 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1643 | } | 1631 | } |
1644 | break; | 1632 | break; |
1645 | case COMP_SHORT_TX: | 1633 | case COMP_SHORT_TX: |
1646 | xhci_warn(xhci, "WARN: short transfer on control ep\n"); | ||
1647 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) | 1634 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) |
1648 | *status = -EREMOTEIO; | 1635 | *status = -EREMOTEIO; |
1649 | else | 1636 | else |
@@ -1946,6 +1933,16 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
1946 | xdev = xhci->devs[slot_id]; | 1933 | xdev = xhci->devs[slot_id]; |
1947 | if (!xdev) { | 1934 | if (!xdev) { |
1948 | xhci_err(xhci, "ERROR Transfer event pointed to bad slot\n"); | 1935 | xhci_err(xhci, "ERROR Transfer event pointed to bad slot\n"); |
1936 | xhci_err(xhci, "@%016llx %08x %08x %08x %08x\n", | ||
1937 | (unsigned long long) xhci_trb_virt_to_dma( | ||
1938 | xhci->event_ring->deq_seg, | ||
1939 | xhci->event_ring->dequeue), | ||
1940 | lower_32_bits(le64_to_cpu(event->buffer)), | ||
1941 | upper_32_bits(le64_to_cpu(event->buffer)), | ||
1942 | le32_to_cpu(event->transfer_len), | ||
1943 | le32_to_cpu(event->flags)); | ||
1944 | xhci_dbg(xhci, "Event ring:\n"); | ||
1945 | xhci_debug_segment(xhci, xhci->event_ring->deq_seg); | ||
1949 | return -ENODEV; | 1946 | return -ENODEV; |
1950 | } | 1947 | } |
1951 | 1948 | ||
@@ -1959,6 +1956,16 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
1959 | EP_STATE_DISABLED) { | 1956 | EP_STATE_DISABLED) { |
1960 | xhci_err(xhci, "ERROR Transfer event for disabled endpoint " | 1957 | xhci_err(xhci, "ERROR Transfer event for disabled endpoint " |
1961 | "or incorrect stream ring\n"); | 1958 | "or incorrect stream ring\n"); |
1959 | xhci_err(xhci, "@%016llx %08x %08x %08x %08x\n", | ||
1960 | (unsigned long long) xhci_trb_virt_to_dma( | ||
1961 | xhci->event_ring->deq_seg, | ||
1962 | xhci->event_ring->dequeue), | ||
1963 | lower_32_bits(le64_to_cpu(event->buffer)), | ||
1964 | upper_32_bits(le64_to_cpu(event->buffer)), | ||
1965 | le32_to_cpu(event->transfer_len), | ||
1966 | le32_to_cpu(event->flags)); | ||
1967 | xhci_dbg(xhci, "Event ring:\n"); | ||
1968 | xhci_debug_segment(xhci, xhci->event_ring->deq_seg); | ||
1962 | return -ENODEV; | 1969 | return -ENODEV; |
1963 | } | 1970 | } |
1964 | 1971 | ||
@@ -1985,7 +1992,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
1985 | xhci_dbg(xhci, "Stopped on No-op or Link TRB\n"); | 1992 | xhci_dbg(xhci, "Stopped on No-op or Link TRB\n"); |
1986 | break; | 1993 | break; |
1987 | case COMP_STALL: | 1994 | case COMP_STALL: |
1988 | xhci_warn(xhci, "WARN: Stalled endpoint\n"); | 1995 | xhci_dbg(xhci, "Stalled endpoint\n"); |
1989 | ep->ep_state |= EP_HALTED; | 1996 | ep->ep_state |= EP_HALTED; |
1990 | status = -EPIPE; | 1997 | status = -EPIPE; |
1991 | break; | 1998 | break; |
@@ -1995,11 +2002,11 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
1995 | break; | 2002 | break; |
1996 | case COMP_SPLIT_ERR: | 2003 | case COMP_SPLIT_ERR: |
1997 | case COMP_TX_ERR: | 2004 | case COMP_TX_ERR: |
1998 | xhci_warn(xhci, "WARN: transfer error on endpoint\n"); | 2005 | xhci_dbg(xhci, "Transfer error on endpoint\n"); |
1999 | status = -EPROTO; | 2006 | status = -EPROTO; |
2000 | break; | 2007 | break; |
2001 | case COMP_BABBLE: | 2008 | case COMP_BABBLE: |
2002 | xhci_warn(xhci, "WARN: babble error on endpoint\n"); | 2009 | xhci_dbg(xhci, "Babble error on endpoint\n"); |
2003 | status = -EOVERFLOW; | 2010 | status = -EOVERFLOW; |
2004 | break; | 2011 | break; |
2005 | case COMP_DB_ERR: | 2012 | case COMP_DB_ERR: |
@@ -2390,17 +2397,7 @@ hw_died: | |||
2390 | 2397 | ||
2391 | irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd) | 2398 | irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd) |
2392 | { | 2399 | { |
2393 | irqreturn_t ret; | 2400 | return xhci_irq(hcd); |
2394 | struct xhci_hcd *xhci; | ||
2395 | |||
2396 | xhci = hcd_to_xhci(hcd); | ||
2397 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | ||
2398 | if (xhci->shared_hcd) | ||
2399 | set_bit(HCD_FLAG_SAW_IRQ, &xhci->shared_hcd->flags); | ||
2400 | |||
2401 | ret = xhci_irq(hcd); | ||
2402 | |||
2403 | return ret; | ||
2404 | } | 2401 | } |
2405 | 2402 | ||
2406 | /**** Endpoint Ring Operations ****/ | 2403 | /**** Endpoint Ring Operations ****/ |
@@ -2488,11 +2485,6 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, | |||
2488 | /* Toggle the cycle bit after the last ring segment. */ | 2485 | /* Toggle the cycle bit after the last ring segment. */ |
2489 | if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) { | 2486 | if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) { |
2490 | ring->cycle_state = (ring->cycle_state ? 0 : 1); | 2487 | ring->cycle_state = (ring->cycle_state ? 0 : 1); |
2491 | if (!in_interrupt()) { | ||
2492 | xhci_dbg(xhci, "queue_trb: Toggle cycle " | ||
2493 | "state for ring %p = %i\n", | ||
2494 | ring, (unsigned int)ring->cycle_state); | ||
2495 | } | ||
2496 | } | 2488 | } |
2497 | ring->enq_seg = ring->enq_seg->next; | 2489 | ring->enq_seg = ring->enq_seg->next; |
2498 | ring->enqueue = ring->enq_seg->trbs; | 2490 | ring->enqueue = ring->enq_seg->trbs; |
@@ -2561,13 +2553,11 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) | |||
2561 | struct scatterlist *sg; | 2553 | struct scatterlist *sg; |
2562 | 2554 | ||
2563 | sg = NULL; | 2555 | sg = NULL; |
2564 | num_sgs = urb->num_sgs; | 2556 | num_sgs = urb->num_mapped_sgs; |
2565 | temp = urb->transfer_buffer_length; | 2557 | temp = urb->transfer_buffer_length; |
2566 | 2558 | ||
2567 | xhci_dbg(xhci, "count sg list trbs: \n"); | ||
2568 | num_trbs = 0; | 2559 | num_trbs = 0; |
2569 | for_each_sg(urb->sg, sg, num_sgs, i) { | 2560 | for_each_sg(urb->sg, sg, num_sgs, i) { |
2570 | unsigned int previous_total_trbs = num_trbs; | ||
2571 | unsigned int len = sg_dma_len(sg); | 2561 | unsigned int len = sg_dma_len(sg); |
2572 | 2562 | ||
2573 | /* Scatter gather list entries may cross 64KB boundaries */ | 2563 | /* Scatter gather list entries may cross 64KB boundaries */ |
@@ -2582,22 +2572,11 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) | |||
2582 | num_trbs++; | 2572 | num_trbs++; |
2583 | running_total += TRB_MAX_BUFF_SIZE; | 2573 | running_total += TRB_MAX_BUFF_SIZE; |
2584 | } | 2574 | } |
2585 | xhci_dbg(xhci, " sg #%d: dma = %#llx, len = %#x (%d), num_trbs = %d\n", | ||
2586 | i, (unsigned long long)sg_dma_address(sg), | ||
2587 | len, len, num_trbs - previous_total_trbs); | ||
2588 | |||
2589 | len = min_t(int, len, temp); | 2575 | len = min_t(int, len, temp); |
2590 | temp -= len; | 2576 | temp -= len; |
2591 | if (temp == 0) | 2577 | if (temp == 0) |
2592 | break; | 2578 | break; |
2593 | } | 2579 | } |
2594 | xhci_dbg(xhci, "\n"); | ||
2595 | if (!in_interrupt()) | ||
2596 | xhci_dbg(xhci, "ep %#x - urb len = %d, sglist used, " | ||
2597 | "num_trbs = %d\n", | ||
2598 | urb->ep->desc.bEndpointAddress, | ||
2599 | urb->transfer_buffer_length, | ||
2600 | num_trbs); | ||
2601 | return num_trbs; | 2580 | return num_trbs; |
2602 | } | 2581 | } |
2603 | 2582 | ||
@@ -2745,7 +2724,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
2745 | return -EINVAL; | 2724 | return -EINVAL; |
2746 | 2725 | ||
2747 | num_trbs = count_sg_trbs_needed(xhci, urb); | 2726 | num_trbs = count_sg_trbs_needed(xhci, urb); |
2748 | num_sgs = urb->num_sgs; | 2727 | num_sgs = urb->num_mapped_sgs; |
2749 | total_packet_count = roundup(urb->transfer_buffer_length, | 2728 | total_packet_count = roundup(urb->transfer_buffer_length, |
2750 | usb_endpoint_maxp(&urb->ep->desc)); | 2729 | usb_endpoint_maxp(&urb->ep->desc)); |
2751 | 2730 | ||
@@ -2783,8 +2762,6 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
2783 | trb_buff_len = min_t(int, trb_buff_len, this_sg_len); | 2762 | trb_buff_len = min_t(int, trb_buff_len, this_sg_len); |
2784 | if (trb_buff_len > urb->transfer_buffer_length) | 2763 | if (trb_buff_len > urb->transfer_buffer_length) |
2785 | trb_buff_len = urb->transfer_buffer_length; | 2764 | trb_buff_len = urb->transfer_buffer_length; |
2786 | xhci_dbg(xhci, "First length to xfer from 1st sglist entry = %u\n", | ||
2787 | trb_buff_len); | ||
2788 | 2765 | ||
2789 | first_trb = true; | 2766 | first_trb = true; |
2790 | /* Queue the first TRB, even if it's zero-length */ | 2767 | /* Queue the first TRB, even if it's zero-length */ |
@@ -2816,11 +2793,6 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
2816 | if (usb_urb_dir_in(urb)) | 2793 | if (usb_urb_dir_in(urb)) |
2817 | field |= TRB_ISP; | 2794 | field |= TRB_ISP; |
2818 | 2795 | ||
2819 | xhci_dbg(xhci, " sg entry: dma = %#x, len = %#x (%d), " | ||
2820 | "64KB boundary at %#x, end dma = %#x\n", | ||
2821 | (unsigned int) addr, trb_buff_len, trb_buff_len, | ||
2822 | (unsigned int) (addr + TRB_MAX_BUFF_SIZE) & ~(TRB_MAX_BUFF_SIZE - 1), | ||
2823 | (unsigned int) addr + trb_buff_len); | ||
2824 | if (TRB_MAX_BUFF_SIZE - | 2796 | if (TRB_MAX_BUFF_SIZE - |
2825 | (addr & (TRB_MAX_BUFF_SIZE - 1)) < trb_buff_len) { | 2797 | (addr & (TRB_MAX_BUFF_SIZE - 1)) < trb_buff_len) { |
2826 | xhci_warn(xhci, "WARN: sg dma xfer crosses 64KB boundaries!\n"); | 2798 | xhci_warn(xhci, "WARN: sg dma xfer crosses 64KB boundaries!\n"); |
@@ -2926,15 +2898,6 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
2926 | } | 2898 | } |
2927 | /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */ | 2899 | /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */ |
2928 | 2900 | ||
2929 | if (!in_interrupt()) | ||
2930 | xhci_dbg(xhci, "ep %#x - urb len = %#x (%d), " | ||
2931 | "addr = %#llx, num_trbs = %d\n", | ||
2932 | urb->ep->desc.bEndpointAddress, | ||
2933 | urb->transfer_buffer_length, | ||
2934 | urb->transfer_buffer_length, | ||
2935 | (unsigned long long)urb->transfer_dma, | ||
2936 | num_trbs); | ||
2937 | |||
2938 | ret = prepare_transfer(xhci, xhci->devs[slot_id], | 2901 | ret = prepare_transfer(xhci, xhci->devs[slot_id], |
2939 | ep_index, urb->stream_id, | 2902 | ep_index, urb->stream_id, |
2940 | num_trbs, urb, 0, false, mem_flags); | 2903 | num_trbs, urb, 0, false, mem_flags); |
@@ -3055,9 +3018,6 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3055 | if (!urb->setup_packet) | 3018 | if (!urb->setup_packet) |
3056 | return -EINVAL; | 3019 | return -EINVAL; |
3057 | 3020 | ||
3058 | if (!in_interrupt()) | ||
3059 | xhci_dbg(xhci, "Queueing ctrl tx for slot id %d, ep %d\n", | ||
3060 | slot_id, ep_index); | ||
3061 | /* 1 TRB for setup, 1 for status */ | 3021 | /* 1 TRB for setup, 1 for status */ |
3062 | num_trbs = 2; | 3022 | num_trbs = 2; |
3063 | /* | 3023 | /* |
@@ -3249,15 +3209,6 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3249 | return -EINVAL; | 3209 | return -EINVAL; |
3250 | } | 3210 | } |
3251 | 3211 | ||
3252 | if (!in_interrupt()) | ||
3253 | xhci_dbg(xhci, "ep %#x - urb len = %#x (%d)," | ||
3254 | " addr = %#llx, num_tds = %d\n", | ||
3255 | urb->ep->desc.bEndpointAddress, | ||
3256 | urb->transfer_buffer_length, | ||
3257 | urb->transfer_buffer_length, | ||
3258 | (unsigned long long)urb->transfer_dma, | ||
3259 | num_tds); | ||
3260 | |||
3261 | start_addr = (u64) urb->transfer_dma; | 3212 | start_addr = (u64) urb->transfer_dma; |
3262 | start_trb = &ep_ring->enqueue->generic; | 3213 | start_trb = &ep_ring->enqueue->generic; |
3263 | start_cycle = ep_ring->cycle_state; | 3214 | start_cycle = ep_ring->cycle_state; |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index a1afb7c39f7e..6bbe3c3a7111 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -200,14 +200,14 @@ static int xhci_setup_msi(struct xhci_hcd *xhci) | |||
200 | 200 | ||
201 | ret = pci_enable_msi(pdev); | 201 | ret = pci_enable_msi(pdev); |
202 | if (ret) { | 202 | if (ret) { |
203 | xhci_err(xhci, "failed to allocate MSI entry\n"); | 203 | xhci_dbg(xhci, "failed to allocate MSI entry\n"); |
204 | return ret; | 204 | return ret; |
205 | } | 205 | } |
206 | 206 | ||
207 | ret = request_irq(pdev->irq, (irq_handler_t)xhci_msi_irq, | 207 | ret = request_irq(pdev->irq, (irq_handler_t)xhci_msi_irq, |
208 | 0, "xhci_hcd", xhci_to_hcd(xhci)); | 208 | 0, "xhci_hcd", xhci_to_hcd(xhci)); |
209 | if (ret) { | 209 | if (ret) { |
210 | xhci_err(xhci, "disable MSI interrupt\n"); | 210 | xhci_dbg(xhci, "disable MSI interrupt\n"); |
211 | pci_disable_msi(pdev); | 211 | pci_disable_msi(pdev); |
212 | } | 212 | } |
213 | 213 | ||
@@ -270,7 +270,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci) | |||
270 | 270 | ||
271 | ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count); | 271 | ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count); |
272 | if (ret) { | 272 | if (ret) { |
273 | xhci_err(xhci, "Failed to enable MSI-X\n"); | 273 | xhci_dbg(xhci, "Failed to enable MSI-X\n"); |
274 | goto free_entries; | 274 | goto free_entries; |
275 | } | 275 | } |
276 | 276 | ||
@@ -286,7 +286,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci) | |||
286 | return ret; | 286 | return ret; |
287 | 287 | ||
288 | disable_msix: | 288 | disable_msix: |
289 | xhci_err(xhci, "disable MSI-X interrupt\n"); | 289 | xhci_dbg(xhci, "disable MSI-X interrupt\n"); |
290 | xhci_free_irq(xhci); | 290 | xhci_free_irq(xhci); |
291 | pci_disable_msix(pdev); | 291 | pci_disable_msix(pdev); |
292 | free_entries: | 292 | free_entries: |
@@ -1333,9 +1333,6 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1333 | goto done; | 1333 | goto done; |
1334 | } | 1334 | } |
1335 | 1335 | ||
1336 | xhci_dbg(xhci, "Cancel URB %p\n", urb); | ||
1337 | xhci_dbg(xhci, "Event ring:\n"); | ||
1338 | xhci_debug_ring(xhci, xhci->event_ring); | ||
1339 | ep_index = xhci_get_endpoint_index(&urb->ep->desc); | 1336 | ep_index = xhci_get_endpoint_index(&urb->ep->desc); |
1340 | ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; | 1337 | ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; |
1341 | ep_ring = xhci_urb_to_transfer_ring(xhci, urb); | 1338 | ep_ring = xhci_urb_to_transfer_ring(xhci, urb); |
@@ -1344,12 +1341,18 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1344 | goto done; | 1341 | goto done; |
1345 | } | 1342 | } |
1346 | 1343 | ||
1347 | xhci_dbg(xhci, "Endpoint ring:\n"); | ||
1348 | xhci_debug_ring(xhci, ep_ring); | ||
1349 | |||
1350 | urb_priv = urb->hcpriv; | 1344 | urb_priv = urb->hcpriv; |
1351 | 1345 | i = urb_priv->td_cnt; | |
1352 | for (i = urb_priv->td_cnt; i < urb_priv->length; i++) { | 1346 | if (i < urb_priv->length) |
1347 | xhci_dbg(xhci, "Cancel URB %p, dev %s, ep 0x%x, " | ||
1348 | "starting at offset 0x%llx\n", | ||
1349 | urb, urb->dev->devpath, | ||
1350 | urb->ep->desc.bEndpointAddress, | ||
1351 | (unsigned long long) xhci_trb_virt_to_dma( | ||
1352 | urb_priv->td[i]->start_seg, | ||
1353 | urb_priv->td[i]->first_trb)); | ||
1354 | |||
1355 | for (; i < urb_priv->length; i++) { | ||
1353 | td = urb_priv->td[i]; | 1356 | td = urb_priv->td[i]; |
1354 | list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); | 1357 | list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); |
1355 | } | 1358 | } |
@@ -1620,6 +1623,7 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, | |||
1620 | /* FIXME: can we allocate more resources for the HC? */ | 1623 | /* FIXME: can we allocate more resources for the HC? */ |
1621 | break; | 1624 | break; |
1622 | case COMP_BW_ERR: | 1625 | case COMP_BW_ERR: |
1626 | case COMP_2ND_BW_ERR: | ||
1623 | dev_warn(&udev->dev, "Not enough bandwidth " | 1627 | dev_warn(&udev->dev, "Not enough bandwidth " |
1624 | "for new device state.\n"); | 1628 | "for new device state.\n"); |
1625 | ret = -ENOSPC; | 1629 | ret = -ENOSPC; |
@@ -2796,8 +2800,7 @@ static int xhci_calculate_streams_and_bitmask(struct xhci_hcd *xhci, | |||
2796 | if (ret < 0) | 2800 | if (ret < 0) |
2797 | return ret; | 2801 | return ret; |
2798 | 2802 | ||
2799 | max_streams = USB_SS_MAX_STREAMS( | 2803 | max_streams = usb_ss_max_streams(&eps[i]->ss_ep_comp); |
2800 | eps[i]->ss_ep_comp.bmAttributes); | ||
2801 | if (max_streams < (*num_streams - 1)) { | 2804 | if (max_streams < (*num_streams - 1)) { |
2802 | xhci_dbg(xhci, "Ep 0x%x only supports %u stream IDs.\n", | 2805 | xhci_dbg(xhci, "Ep 0x%x only supports %u stream IDs.\n", |
2803 | eps[i]->desc.bEndpointAddress, | 2806 | eps[i]->desc.bEndpointAddress, |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 3c8fbd2772ea..fb99c8379142 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1033,7 +1033,6 @@ struct xhci_transfer_event { | |||
1033 | /* Invalid Stream ID Error */ | 1033 | /* Invalid Stream ID Error */ |
1034 | #define COMP_STRID_ERR 34 | 1034 | #define COMP_STRID_ERR 34 |
1035 | /* Secondary Bandwidth Error - may be returned by a Configure Endpoint cmd */ | 1035 | /* Secondary Bandwidth Error - may be returned by a Configure Endpoint cmd */ |
1036 | /* FIXME - check for this */ | ||
1037 | #define COMP_2ND_BW_ERR 35 | 1036 | #define COMP_2ND_BW_ERR 35 |
1038 | /* Split Transaction Error */ | 1037 | /* Split Transaction Error */ |
1039 | #define COMP_SPLIT_ERR 36 | 1038 | #define COMP_SPLIT_ERR 36 |
@@ -1356,7 +1355,7 @@ static inline unsigned int hcd_index(struct usb_hcd *hcd) | |||
1356 | return 1; | 1355 | return 1; |
1357 | } | 1356 | } |
1358 | 1357 | ||
1359 | /* There is one ehci_hci structure per controller */ | 1358 | /* There is one xhci_hcd structure per controller */ |
1360 | struct xhci_hcd { | 1359 | struct xhci_hcd { |
1361 | struct usb_hcd *main_hcd; | 1360 | struct usb_hcd *main_hcd; |
1362 | struct usb_hcd *shared_hcd; | 1361 | struct usb_hcd *shared_hcd; |