diff options
Diffstat (limited to 'drivers/usb/gadget/net2280.c')
-rw-r--r-- | drivers/usb/gadget/net2280.c | 1119 |
1 files changed, 1033 insertions, 86 deletions
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 300b3a71383b..8112d9140a90 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -18,6 +18,9 @@ | |||
18 | * hint to completely eliminate some IRQs, if a later IRQ is guaranteed | 18 | * hint to completely eliminate some IRQs, if a later IRQ is guaranteed |
19 | * and DMA chaining is enabled. | 19 | * and DMA chaining is enabled. |
20 | * | 20 | * |
21 | * MSI is enabled by default. The legacy IRQ is used if MSI couldn't | ||
22 | * be enabled. | ||
23 | * | ||
21 | * Note that almost all the errata workarounds here are only needed for | 24 | * Note that almost all the errata workarounds here are only needed for |
22 | * rev1 chips. Rev1a silicon (0110) fixes almost all of them. | 25 | * rev1 chips. Rev1a silicon (0110) fixes almost all of them. |
23 | */ | 26 | */ |
@@ -25,10 +28,14 @@ | |||
25 | /* | 28 | /* |
26 | * Copyright (C) 2003 David Brownell | 29 | * Copyright (C) 2003 David Brownell |
27 | * Copyright (C) 2003-2005 PLX Technology, Inc. | 30 | * Copyright (C) 2003-2005 PLX Technology, Inc. |
31 | * Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS | ||
28 | * | 32 | * |
29 | * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility | 33 | * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility |
30 | * with 2282 chip | 34 | * with 2282 chip |
31 | * | 35 | * |
36 | * Modified Ricardo Ribalda Qtechnology AS to provide compatibility | ||
37 | * with usb 338x chip. Based on PLX driver | ||
38 | * | ||
32 | * This program is free software; you can redistribute it and/or modify | 39 | * This program is free software; you can redistribute it and/or modify |
33 | * it under the terms of the GNU General Public License as published by | 40 | * it under the terms of the GNU General Public License as published by |
34 | * the Free Software Foundation; either version 2 of the License, or | 41 | * the Free Software Foundation; either version 2 of the License, or |
@@ -61,9 +68,8 @@ | |||
61 | #include <asm/irq.h> | 68 | #include <asm/irq.h> |
62 | #include <asm/unaligned.h> | 69 | #include <asm/unaligned.h> |
63 | 70 | ||
64 | 71 | #define DRIVER_DESC "PLX NET228x/USB338x USB Peripheral Controller" | |
65 | #define DRIVER_DESC "PLX NET228x USB Peripheral Controller" | 72 | #define DRIVER_VERSION "2005 Sept 27/v3.0" |
66 | #define DRIVER_VERSION "2005 Sept 27" | ||
67 | 73 | ||
68 | #define EP_DONTUSE 13 /* nonzero */ | 74 | #define EP_DONTUSE 13 /* nonzero */ |
69 | 75 | ||
@@ -73,11 +79,12 @@ | |||
73 | static const char driver_name [] = "net2280"; | 79 | static const char driver_name [] = "net2280"; |
74 | static const char driver_desc [] = DRIVER_DESC; | 80 | static const char driver_desc [] = DRIVER_DESC; |
75 | 81 | ||
82 | static const u32 ep_bit[9] = { 0, 17, 2, 19, 4, 1, 18, 3, 20 }; | ||
76 | static const char ep0name [] = "ep0"; | 83 | static const char ep0name [] = "ep0"; |
77 | static const char *const ep_name [] = { | 84 | static const char *const ep_name [] = { |
78 | ep0name, | 85 | ep0name, |
79 | "ep-a", "ep-b", "ep-c", "ep-d", | 86 | "ep-a", "ep-b", "ep-c", "ep-d", |
80 | "ep-e", "ep-f", | 87 | "ep-e", "ep-f", "ep-g", "ep-h", |
81 | }; | 88 | }; |
82 | 89 | ||
83 | /* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO) | 90 | /* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO) |
@@ -90,11 +97,12 @@ static const char *const ep_name [] = { | |||
90 | */ | 97 | */ |
91 | static bool use_dma = 1; | 98 | static bool use_dma = 1; |
92 | static bool use_dma_chaining = 0; | 99 | static bool use_dma_chaining = 0; |
100 | static bool use_msi = 1; | ||
93 | 101 | ||
94 | /* "modprobe net2280 use_dma=n" etc */ | 102 | /* "modprobe net2280 use_dma=n" etc */ |
95 | module_param (use_dma, bool, S_IRUGO); | 103 | module_param (use_dma, bool, S_IRUGO); |
96 | module_param (use_dma_chaining, bool, S_IRUGO); | 104 | module_param (use_dma_chaining, bool, S_IRUGO); |
97 | 105 | module_param(use_msi, bool, S_IRUGO); | |
98 | 106 | ||
99 | /* mode 0 == ep-{a,b,c,d} 1K fifo each | 107 | /* mode 0 == ep-{a,b,c,d} 1K fifo each |
100 | * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable | 108 | * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable |
@@ -140,6 +148,18 @@ static char *type_string (u8 bmAttributes) | |||
140 | #define dma_done_ie cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE) | 148 | #define dma_done_ie cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE) |
141 | 149 | ||
142 | /*-------------------------------------------------------------------------*/ | 150 | /*-------------------------------------------------------------------------*/ |
151 | static inline void enable_pciirqenb(struct net2280_ep *ep) | ||
152 | { | ||
153 | u32 tmp = readl(&ep->dev->regs->pciirqenb0); | ||
154 | |||
155 | if (ep->dev->pdev->vendor == 0x17cc) | ||
156 | tmp |= 1 << ep->num; | ||
157 | else | ||
158 | tmp |= 1 << ep_bit[ep->num]; | ||
159 | writel(tmp, &ep->dev->regs->pciirqenb0); | ||
160 | |||
161 | return; | ||
162 | } | ||
143 | 163 | ||
144 | static int | 164 | static int |
145 | net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | 165 | net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) |
@@ -148,6 +168,7 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
148 | struct net2280_ep *ep; | 168 | struct net2280_ep *ep; |
149 | u32 max, tmp; | 169 | u32 max, tmp; |
150 | unsigned long flags; | 170 | unsigned long flags; |
171 | static const u32 ep_key[9] = { 1, 0, 1, 0, 1, 1, 0, 1, 0 }; | ||
151 | 172 | ||
152 | ep = container_of (_ep, struct net2280_ep, ep); | 173 | ep = container_of (_ep, struct net2280_ep, ep); |
153 | if (!_ep || !desc || ep->desc || _ep->name == ep0name | 174 | if (!_ep || !desc || ep->desc || _ep->name == ep0name |
@@ -161,9 +182,17 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
161 | if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE) | 182 | if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE) |
162 | return -EDOM; | 183 | return -EDOM; |
163 | 184 | ||
185 | if (dev->pdev->vendor == 0x10b5) { | ||
186 | if ((desc->bEndpointAddress & 0x0f) >= 0x0c) | ||
187 | return -EDOM; | ||
188 | ep->is_in = !!usb_endpoint_dir_in(desc); | ||
189 | if (dev->enhanced_mode && ep->is_in && ep_key[ep->num]) | ||
190 | return -EINVAL; | ||
191 | } | ||
192 | |||
164 | /* sanity check ep-e/ep-f since their fifos are small */ | 193 | /* sanity check ep-e/ep-f since their fifos are small */ |
165 | max = usb_endpoint_maxp (desc) & 0x1fff; | 194 | max = usb_endpoint_maxp (desc) & 0x1fff; |
166 | if (ep->num > 4 && max > 64) | 195 | if (ep->num > 4 && max > 64 && (dev->pdev->vendor == 0x17cc)) |
167 | return -ERANGE; | 196 | return -ERANGE; |
168 | 197 | ||
169 | spin_lock_irqsave (&dev->lock, flags); | 198 | spin_lock_irqsave (&dev->lock, flags); |
@@ -176,7 +205,7 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
176 | ep->out_overflow = 0; | 205 | ep->out_overflow = 0; |
177 | 206 | ||
178 | /* set speed-dependent max packet; may kick in high bandwidth */ | 207 | /* set speed-dependent max packet; may kick in high bandwidth */ |
179 | set_idx_reg (dev->regs, REG_EP_MAXPKT (dev, ep->num), max); | 208 | set_max_speed(ep, max); |
180 | 209 | ||
181 | /* FIFO lines can't go to different packets. PIO is ok, so | 210 | /* FIFO lines can't go to different packets. PIO is ok, so |
182 | * use it instead of troublesome (non-bulk) multi-packet DMA. | 211 | * use it instead of troublesome (non-bulk) multi-packet DMA. |
@@ -199,23 +228,43 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
199 | &ep->regs->ep_rsp); | 228 | &ep->regs->ep_rsp); |
200 | } else if (tmp == USB_ENDPOINT_XFER_BULK) { | 229 | } else if (tmp == USB_ENDPOINT_XFER_BULK) { |
201 | /* catch some particularly blatant driver bugs */ | 230 | /* catch some particularly blatant driver bugs */ |
202 | if ((dev->gadget.speed == USB_SPEED_HIGH | 231 | if ((dev->gadget.speed == USB_SPEED_SUPER && max != 1024) || |
203 | && max != 512) | 232 | (dev->gadget.speed == USB_SPEED_HIGH && max != 512) || |
204 | || (dev->gadget.speed == USB_SPEED_FULL | 233 | (dev->gadget.speed == USB_SPEED_FULL && max > 64)) { |
205 | && max > 64)) { | 234 | spin_unlock_irqrestore(&dev->lock, flags); |
206 | spin_unlock_irqrestore (&dev->lock, flags); | ||
207 | return -ERANGE; | 235 | return -ERANGE; |
208 | } | 236 | } |
209 | } | 237 | } |
210 | ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0; | 238 | ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0; |
211 | tmp <<= ENDPOINT_TYPE; | 239 | /* Enable this endpoint */ |
212 | tmp |= desc->bEndpointAddress; | 240 | if (dev->pdev->vendor == 0x17cc) { |
213 | tmp |= (4 << ENDPOINT_BYTE_COUNT); /* default full fifo lines */ | 241 | tmp <<= ENDPOINT_TYPE; |
214 | tmp |= 1 << ENDPOINT_ENABLE; | 242 | tmp |= desc->bEndpointAddress; |
215 | wmb (); | 243 | /* default full fifo lines */ |
244 | tmp |= (4 << ENDPOINT_BYTE_COUNT); | ||
245 | tmp |= 1 << ENDPOINT_ENABLE; | ||
246 | ep->is_in = (tmp & USB_DIR_IN) != 0; | ||
247 | } else { | ||
248 | /* In Legacy mode, only OUT endpoints are used */ | ||
249 | if (dev->enhanced_mode && ep->is_in) { | ||
250 | tmp <<= IN_ENDPOINT_TYPE; | ||
251 | tmp |= (1 << IN_ENDPOINT_ENABLE); | ||
252 | /* Not applicable to Legacy */ | ||
253 | tmp |= (1 << ENDPOINT_DIRECTION); | ||
254 | } else { | ||
255 | tmp <<= OUT_ENDPOINT_TYPE; | ||
256 | tmp |= (1 << OUT_ENDPOINT_ENABLE); | ||
257 | tmp |= (ep->is_in << ENDPOINT_DIRECTION); | ||
258 | } | ||
259 | |||
260 | tmp |= usb_endpoint_num(desc); | ||
261 | tmp |= (ep->ep.maxburst << MAX_BURST_SIZE); | ||
262 | } | ||
263 | |||
264 | /* Make sure all the registers are written before ep_rsp*/ | ||
265 | wmb(); | ||
216 | 266 | ||
217 | /* for OUT transfers, block the rx fifo until a read is posted */ | 267 | /* for OUT transfers, block the rx fifo until a read is posted */ |
218 | ep->is_in = (tmp & USB_DIR_IN) != 0; | ||
219 | if (!ep->is_in) | 268 | if (!ep->is_in) |
220 | writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); | 269 | writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); |
221 | else if (dev->pdev->device != 0x2280) { | 270 | else if (dev->pdev->device != 0x2280) { |
@@ -226,12 +275,11 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
226 | | (1 << CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); | 275 | | (1 << CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); |
227 | } | 276 | } |
228 | 277 | ||
229 | writel (tmp, &ep->regs->ep_cfg); | 278 | writel(tmp, &ep->cfg->ep_cfg); |
230 | 279 | ||
231 | /* enable irqs */ | 280 | /* enable irqs */ |
232 | if (!ep->dma) { /* pio, per-packet */ | 281 | if (!ep->dma) { /* pio, per-packet */ |
233 | tmp = (1 << ep->num) | readl (&dev->regs->pciirqenb0); | 282 | enable_pciirqenb(ep); |
234 | writel (tmp, &dev->regs->pciirqenb0); | ||
235 | 283 | ||
236 | tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) | 284 | tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) |
237 | | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE); | 285 | | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE); |
@@ -251,8 +299,7 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
251 | tmp = (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE); | 299 | tmp = (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE); |
252 | writel (tmp, &ep->regs->ep_irqenb); | 300 | writel (tmp, &ep->regs->ep_irqenb); |
253 | 301 | ||
254 | tmp = (1 << ep->num) | readl (&dev->regs->pciirqenb0); | 302 | enable_pciirqenb(ep); |
255 | writel (tmp, &dev->regs->pciirqenb0); | ||
256 | } | 303 | } |
257 | } | 304 | } |
258 | 305 | ||
@@ -286,7 +333,8 @@ static int handshake (u32 __iomem *ptr, u32 mask, u32 done, int usec) | |||
286 | 333 | ||
287 | static const struct usb_ep_ops net2280_ep_ops; | 334 | static const struct usb_ep_ops net2280_ep_ops; |
288 | 335 | ||
289 | static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep) | 336 | static void ep_reset_228x(struct net2280_regs __iomem *regs, |
337 | struct net2280_ep *ep) | ||
290 | { | 338 | { |
291 | u32 tmp; | 339 | u32 tmp; |
292 | 340 | ||
@@ -361,6 +409,55 @@ static void ep_reset (struct net2280_regs __iomem *regs, struct net2280_ep *ep) | |||
361 | /* fifo size is handled separately */ | 409 | /* fifo size is handled separately */ |
362 | } | 410 | } |
363 | 411 | ||
412 | static void ep_reset_338x(struct net2280_regs __iomem *regs, | ||
413 | struct net2280_ep *ep) | ||
414 | { | ||
415 | u32 tmp, dmastat; | ||
416 | |||
417 | ep->desc = NULL; | ||
418 | INIT_LIST_HEAD(&ep->queue); | ||
419 | |||
420 | usb_ep_set_maxpacket_limit(&ep->ep, ~0); | ||
421 | ep->ep.ops = &net2280_ep_ops; | ||
422 | |||
423 | /* disable the dma, irqs, endpoint... */ | ||
424 | if (ep->dma) { | ||
425 | writel(0, &ep->dma->dmactl); | ||
426 | writel((1 << DMA_ABORT_DONE_INTERRUPT) | | ||
427 | (1 << DMA_PAUSE_DONE_INTERRUPT) | | ||
428 | (1 << DMA_SCATTER_GATHER_DONE_INTERRUPT) | | ||
429 | (1 << DMA_TRANSACTION_DONE_INTERRUPT) | ||
430 | /* | (1 << DMA_ABORT) */ | ||
431 | , &ep->dma->dmastat); | ||
432 | |||
433 | dmastat = readl(&ep->dma->dmastat); | ||
434 | if (dmastat == 0x5002) { | ||
435 | WARNING(ep->dev, "The dmastat return = %x!!\n", | ||
436 | dmastat); | ||
437 | writel(0x5a, &ep->dma->dmastat); | ||
438 | } | ||
439 | |||
440 | tmp = readl(®s->pciirqenb0); | ||
441 | tmp &= ~(1 << ep_bit[ep->num]); | ||
442 | writel(tmp, ®s->pciirqenb0); | ||
443 | } else { | ||
444 | if (ep->num < 5) { | ||
445 | tmp = readl(®s->pciirqenb1); | ||
446 | tmp &= ~(1 << (8 + ep->num)); /* completion */ | ||
447 | writel(tmp, ®s->pciirqenb1); | ||
448 | } | ||
449 | } | ||
450 | writel(0, &ep->regs->ep_irqenb); | ||
451 | |||
452 | writel((1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | | ||
453 | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) | | ||
454 | (1 << FIFO_OVERFLOW) | | ||
455 | (1 << DATA_PACKET_RECEIVED_INTERRUPT) | | ||
456 | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT) | | ||
457 | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | | ||
458 | (1 << DATA_IN_TOKEN_INTERRUPT), &ep->regs->ep_stat); | ||
459 | } | ||
460 | |||
364 | static void nuke (struct net2280_ep *); | 461 | static void nuke (struct net2280_ep *); |
365 | 462 | ||
366 | static int net2280_disable (struct usb_ep *_ep) | 463 | static int net2280_disable (struct usb_ep *_ep) |
@@ -374,13 +471,17 @@ static int net2280_disable (struct usb_ep *_ep) | |||
374 | 471 | ||
375 | spin_lock_irqsave (&ep->dev->lock, flags); | 472 | spin_lock_irqsave (&ep->dev->lock, flags); |
376 | nuke (ep); | 473 | nuke (ep); |
377 | ep_reset (ep->dev->regs, ep); | 474 | |
475 | if (ep->dev->pdev->vendor == 0x10b5) | ||
476 | ep_reset_338x(ep->dev->regs, ep); | ||
477 | else | ||
478 | ep_reset_228x(ep->dev->regs, ep); | ||
378 | 479 | ||
379 | VDEBUG (ep->dev, "disabled %s %s\n", | 480 | VDEBUG (ep->dev, "disabled %s %s\n", |
380 | ep->dma ? "dma" : "pio", _ep->name); | 481 | ep->dma ? "dma" : "pio", _ep->name); |
381 | 482 | ||
382 | /* synch memory views with the device */ | 483 | /* synch memory views with the device */ |
383 | (void) readl (&ep->regs->ep_cfg); | 484 | (void)readl(&ep->cfg->ep_cfg); |
384 | 485 | ||
385 | if (use_dma && !ep->dma && ep->num >= 1 && ep->num <= 4) | 486 | if (use_dma && !ep->dma && ep->num >= 1 && ep->num <= 4) |
386 | ep->dma = &ep->dev->dma [ep->num - 1]; | 487 | ep->dma = &ep->dev->dma [ep->num - 1]; |
@@ -698,6 +799,8 @@ static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma) | |||
698 | writel (readl (&dma->dmastat), &dma->dmastat); | 799 | writel (readl (&dma->dmastat), &dma->dmastat); |
699 | 800 | ||
700 | writel (td_dma, &dma->dmadesc); | 801 | writel (td_dma, &dma->dmadesc); |
802 | if (ep->dev->pdev->vendor == 0x10b5) | ||
803 | dmactl |= (0x01 << DMA_REQUEST_OUTSTANDING); | ||
701 | writel (dmactl, &dma->dmactl); | 804 | writel (dmactl, &dma->dmactl); |
702 | 805 | ||
703 | /* erratum 0116 workaround part 3: pci arbiter away from net2280 */ | 806 | /* erratum 0116 workaround part 3: pci arbiter away from net2280 */ |
@@ -772,6 +875,21 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req) | |||
772 | start_queue (ep, tmp, req->td_dma); | 875 | start_queue (ep, tmp, req->td_dma); |
773 | } | 876 | } |
774 | 877 | ||
878 | static inline void resume_dma(struct net2280_ep *ep) | ||
879 | { | ||
880 | writel(readl(&ep->dma->dmactl) | (1 << DMA_ENABLE), &ep->dma->dmactl); | ||
881 | |||
882 | ep->dma_started = true; | ||
883 | } | ||
884 | |||
885 | static inline void ep_stop_dma(struct net2280_ep *ep) | ||
886 | { | ||
887 | writel(readl(&ep->dma->dmactl) & ~(1 << DMA_ENABLE), &ep->dma->dmactl); | ||
888 | spin_stop_dma(ep->dma); | ||
889 | |||
890 | ep->dma_started = false; | ||
891 | } | ||
892 | |||
775 | static inline void | 893 | static inline void |
776 | queue_dma (struct net2280_ep *ep, struct net2280_request *req, int valid) | 894 | queue_dma (struct net2280_ep *ep, struct net2280_request *req, int valid) |
777 | { | 895 | { |
@@ -874,8 +992,23 @@ net2280_queue (struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
874 | 992 | ||
875 | /* kickstart this i/o queue? */ | 993 | /* kickstart this i/o queue? */ |
876 | if (list_empty (&ep->queue) && !ep->stopped) { | 994 | if (list_empty (&ep->queue) && !ep->stopped) { |
995 | /* DMA request while EP halted */ | ||
996 | if (ep->dma && | ||
997 | (readl(&ep->regs->ep_rsp) & (1 << CLEAR_ENDPOINT_HALT)) && | ||
998 | (dev->pdev->vendor == 0x10b5)) { | ||
999 | int valid = 1; | ||
1000 | if (ep->is_in) { | ||
1001 | int expect; | ||
1002 | expect = likely(req->req.zero || | ||
1003 | ((req->req.length % | ||
1004 | ep->ep.maxpacket) != 0)); | ||
1005 | if (expect != ep->in_fifo_validate) | ||
1006 | valid = 0; | ||
1007 | } | ||
1008 | queue_dma(ep, req, valid); | ||
1009 | } | ||
877 | /* use DMA if the endpoint supports it, else pio */ | 1010 | /* use DMA if the endpoint supports it, else pio */ |
878 | if (ep->dma) | 1011 | else if (ep->dma) |
879 | start_dma (ep, req); | 1012 | start_dma (ep, req); |
880 | else { | 1013 | else { |
881 | /* maybe there's no control data, just status ack */ | 1014 | /* maybe there's no control data, just status ack */ |
@@ -993,6 +1126,8 @@ static void scan_dma_completions (struct net2280_ep *ep) | |||
993 | } else if (!ep->is_in | 1126 | } else if (!ep->is_in |
994 | && (req->req.length % ep->ep.maxpacket) != 0) { | 1127 | && (req->req.length % ep->ep.maxpacket) != 0) { |
995 | tmp = readl (&ep->regs->ep_stat); | 1128 | tmp = readl (&ep->regs->ep_stat); |
1129 | if (ep->dev->pdev->vendor == 0x10b5) | ||
1130 | return dma_done(ep, req, tmp, 0); | ||
996 | 1131 | ||
997 | /* AVOID TROUBLE HERE by not issuing short reads from | 1132 | /* AVOID TROUBLE HERE by not issuing short reads from |
998 | * your gadget driver. That helps avoids errata 0121, | 1133 | * your gadget driver. That helps avoids errata 0121, |
@@ -1079,7 +1214,7 @@ static void restart_dma (struct net2280_ep *ep) | |||
1079 | start_queue (ep, dmactl, req->td_dma); | 1214 | start_queue (ep, dmactl, req->td_dma); |
1080 | } | 1215 | } |
1081 | 1216 | ||
1082 | static void abort_dma (struct net2280_ep *ep) | 1217 | static void abort_dma_228x(struct net2280_ep *ep) |
1083 | { | 1218 | { |
1084 | /* abort the current transfer */ | 1219 | /* abort the current transfer */ |
1085 | if (likely (!list_empty (&ep->queue))) { | 1220 | if (likely (!list_empty (&ep->queue))) { |
@@ -1091,6 +1226,19 @@ static void abort_dma (struct net2280_ep *ep) | |||
1091 | scan_dma_completions (ep); | 1226 | scan_dma_completions (ep); |
1092 | } | 1227 | } |
1093 | 1228 | ||
1229 | static void abort_dma_338x(struct net2280_ep *ep) | ||
1230 | { | ||
1231 | writel((1 << DMA_ABORT), &ep->dma->dmastat); | ||
1232 | spin_stop_dma(ep->dma); | ||
1233 | } | ||
1234 | |||
1235 | static void abort_dma(struct net2280_ep *ep) | ||
1236 | { | ||
1237 | if (ep->dev->pdev->vendor == 0x17cc) | ||
1238 | return abort_dma_228x(ep); | ||
1239 | return abort_dma_338x(ep); | ||
1240 | } | ||
1241 | |||
1094 | /* dequeue ALL requests */ | 1242 | /* dequeue ALL requests */ |
1095 | static void nuke (struct net2280_ep *ep) | 1243 | static void nuke (struct net2280_ep *ep) |
1096 | { | 1244 | { |
@@ -1244,6 +1392,9 @@ net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) | |||
1244 | ep->wedged = 1; | 1392 | ep->wedged = 1; |
1245 | } else { | 1393 | } else { |
1246 | clear_halt (ep); | 1394 | clear_halt (ep); |
1395 | if (ep->dev->pdev->vendor == 0x10b5 && | ||
1396 | !list_empty(&ep->queue) && ep->td_dma) | ||
1397 | restart_dma(ep); | ||
1247 | ep->wedged = 0; | 1398 | ep->wedged = 0; |
1248 | } | 1399 | } |
1249 | (void) readl (&ep->regs->ep_rsp); | 1400 | (void) readl (&ep->regs->ep_rsp); |
@@ -1367,10 +1518,13 @@ static int net2280_set_selfpowered (struct usb_gadget *_gadget, int value) | |||
1367 | 1518 | ||
1368 | spin_lock_irqsave (&dev->lock, flags); | 1519 | spin_lock_irqsave (&dev->lock, flags); |
1369 | tmp = readl (&dev->usb->usbctl); | 1520 | tmp = readl (&dev->usb->usbctl); |
1370 | if (value) | 1521 | if (value) { |
1371 | tmp |= (1 << SELF_POWERED_STATUS); | 1522 | tmp |= (1 << SELF_POWERED_STATUS); |
1372 | else | 1523 | dev->selfpowered = 1; |
1524 | } else { | ||
1373 | tmp &= ~(1 << SELF_POWERED_STATUS); | 1525 | tmp &= ~(1 << SELF_POWERED_STATUS); |
1526 | dev->selfpowered = 0; | ||
1527 | } | ||
1374 | writel (tmp, &dev->usb->usbctl); | 1528 | writel (tmp, &dev->usb->usbctl); |
1375 | spin_unlock_irqrestore (&dev->lock, flags); | 1529 | spin_unlock_irqrestore (&dev->lock, flags); |
1376 | 1530 | ||
@@ -1504,14 +1658,14 @@ static ssize_t registers_show(struct device *_dev, | |||
1504 | /* DMA Control Registers */ | 1658 | /* DMA Control Registers */ |
1505 | 1659 | ||
1506 | /* Configurable EP Control Registers */ | 1660 | /* Configurable EP Control Registers */ |
1507 | for (i = 0; i < 7; i++) { | 1661 | for (i = 0; i < dev->n_ep; i++) { |
1508 | struct net2280_ep *ep; | 1662 | struct net2280_ep *ep; |
1509 | 1663 | ||
1510 | ep = &dev->ep [i]; | 1664 | ep = &dev->ep [i]; |
1511 | if (i && !ep->desc) | 1665 | if (i && !ep->desc) |
1512 | continue; | 1666 | continue; |
1513 | 1667 | ||
1514 | t1 = readl (&ep->regs->ep_cfg); | 1668 | t1 = readl(&ep->cfg->ep_cfg); |
1515 | t2 = readl (&ep->regs->ep_rsp) & 0xff; | 1669 | t2 = readl (&ep->regs->ep_rsp) & 0xff; |
1516 | t = scnprintf (next, size, | 1670 | t = scnprintf (next, size, |
1517 | "\n%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s" | 1671 | "\n%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s" |
@@ -1571,7 +1725,7 @@ static ssize_t registers_show(struct device *_dev, | |||
1571 | t = scnprintf (next, size, "\nirqs: "); | 1725 | t = scnprintf (next, size, "\nirqs: "); |
1572 | size -= t; | 1726 | size -= t; |
1573 | next += t; | 1727 | next += t; |
1574 | for (i = 0; i < 7; i++) { | 1728 | for (i = 0; i < dev->n_ep; i++) { |
1575 | struct net2280_ep *ep; | 1729 | struct net2280_ep *ep; |
1576 | 1730 | ||
1577 | ep = &dev->ep [i]; | 1731 | ep = &dev->ep [i]; |
@@ -1606,7 +1760,7 @@ static ssize_t queues_show(struct device *_dev, struct device_attribute *attr, | |||
1606 | size = PAGE_SIZE; | 1760 | size = PAGE_SIZE; |
1607 | spin_lock_irqsave (&dev->lock, flags); | 1761 | spin_lock_irqsave (&dev->lock, flags); |
1608 | 1762 | ||
1609 | for (i = 0; i < 7; i++) { | 1763 | for (i = 0; i < dev->n_ep; i++) { |
1610 | struct net2280_ep *ep = &dev->ep [i]; | 1764 | struct net2280_ep *ep = &dev->ep [i]; |
1611 | struct net2280_request *req; | 1765 | struct net2280_request *req; |
1612 | int t; | 1766 | int t; |
@@ -1735,6 +1889,121 @@ static void set_fifo_mode (struct net2280 *dev, int mode) | |||
1735 | list_add_tail (&dev->ep [6].ep.ep_list, &dev->gadget.ep_list); | 1889 | list_add_tail (&dev->ep [6].ep.ep_list, &dev->gadget.ep_list); |
1736 | } | 1890 | } |
1737 | 1891 | ||
1892 | static void defect7374_disable_data_eps(struct net2280 *dev) | ||
1893 | { | ||
1894 | /* | ||
1895 | * For Defect 7374, disable data EPs (and more): | ||
1896 | * - This phase undoes the earlier phase of the Defect 7374 workaround, | ||
1897 | * returing ep regs back to normal. | ||
1898 | */ | ||
1899 | struct net2280_ep *ep; | ||
1900 | int i; | ||
1901 | unsigned char ep_sel; | ||
1902 | u32 tmp_reg; | ||
1903 | |||
1904 | for (i = 1; i < 5; i++) { | ||
1905 | ep = &dev->ep[i]; | ||
1906 | writel(0, &ep->cfg->ep_cfg); | ||
1907 | } | ||
1908 | |||
1909 | /* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */ | ||
1910 | for (i = 0; i < 6; i++) | ||
1911 | writel(0, &dev->dep[i].dep_cfg); | ||
1912 | |||
1913 | for (ep_sel = 0; ep_sel <= 21; ep_sel++) { | ||
1914 | /* Select an endpoint for subsequent operations: */ | ||
1915 | tmp_reg = readl(&dev->plregs->pl_ep_ctrl); | ||
1916 | writel(((tmp_reg & ~0x1f) | ep_sel), &dev->plregs->pl_ep_ctrl); | ||
1917 | |||
1918 | if (ep_sel < 2 || (ep_sel > 9 && ep_sel < 14) || | ||
1919 | ep_sel == 18 || ep_sel == 20) | ||
1920 | continue; | ||
1921 | |||
1922 | /* Change settings on some selected endpoints */ | ||
1923 | tmp_reg = readl(&dev->plregs->pl_ep_cfg_4); | ||
1924 | tmp_reg &= ~(1 << NON_CTRL_IN_TOLERATE_BAD_DIR); | ||
1925 | writel(tmp_reg, &dev->plregs->pl_ep_cfg_4); | ||
1926 | tmp_reg = readl(&dev->plregs->pl_ep_ctrl); | ||
1927 | tmp_reg |= (1 << EP_INITIALIZED); | ||
1928 | writel(tmp_reg, &dev->plregs->pl_ep_ctrl); | ||
1929 | } | ||
1930 | } | ||
1931 | |||
1932 | static void defect7374_enable_data_eps_zero(struct net2280 *dev) | ||
1933 | { | ||
1934 | u32 tmp = 0, tmp_reg; | ||
1935 | u32 fsmvalue, scratch; | ||
1936 | int i; | ||
1937 | unsigned char ep_sel; | ||
1938 | |||
1939 | scratch = get_idx_reg(dev->regs, SCRATCH); | ||
1940 | fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD); | ||
1941 | scratch &= ~(0xf << DEFECT7374_FSM_FIELD); | ||
1942 | |||
1943 | /*See if firmware needs to set up for workaround*/ | ||
1944 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) { | ||
1945 | WARNING(dev, "Operate Defect 7374 workaround soft this time"); | ||
1946 | WARNING(dev, "It will operate on cold-reboot and SS connect"); | ||
1947 | |||
1948 | /*GPEPs:*/ | ||
1949 | tmp = ((0 << ENDPOINT_NUMBER) | (1 << ENDPOINT_DIRECTION) | | ||
1950 | (2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) | | ||
1951 | ((dev->enhanced_mode) ? | ||
1952 | 1 << OUT_ENDPOINT_ENABLE : 1 << ENDPOINT_ENABLE) | | ||
1953 | (1 << IN_ENDPOINT_ENABLE)); | ||
1954 | |||
1955 | for (i = 1; i < 5; i++) | ||
1956 | writel(tmp, &dev->ep[i].cfg->ep_cfg); | ||
1957 | |||
1958 | /* CSRIN, PCIIN, STATIN, RCIN*/ | ||
1959 | tmp = ((0 << ENDPOINT_NUMBER) | (1 << ENDPOINT_ENABLE)); | ||
1960 | writel(tmp, &dev->dep[1].dep_cfg); | ||
1961 | writel(tmp, &dev->dep[3].dep_cfg); | ||
1962 | writel(tmp, &dev->dep[4].dep_cfg); | ||
1963 | writel(tmp, &dev->dep[5].dep_cfg); | ||
1964 | |||
1965 | /*Implemented for development and debug. | ||
1966 | * Can be refined/tuned later.*/ | ||
1967 | for (ep_sel = 0; ep_sel <= 21; ep_sel++) { | ||
1968 | /* Select an endpoint for subsequent operations: */ | ||
1969 | tmp_reg = readl(&dev->plregs->pl_ep_ctrl); | ||
1970 | writel(((tmp_reg & ~0x1f) | ep_sel), | ||
1971 | &dev->plregs->pl_ep_ctrl); | ||
1972 | |||
1973 | if (ep_sel == 1) { | ||
1974 | tmp = | ||
1975 | (readl(&dev->plregs->pl_ep_ctrl) | | ||
1976 | (1 << CLEAR_ACK_ERROR_CODE) | 0); | ||
1977 | writel(tmp, &dev->plregs->pl_ep_ctrl); | ||
1978 | continue; | ||
1979 | } | ||
1980 | |||
1981 | if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) || | ||
1982 | ep_sel == 18 || ep_sel == 20) | ||
1983 | continue; | ||
1984 | |||
1985 | tmp = (readl(&dev->plregs->pl_ep_cfg_4) | | ||
1986 | (1 << NON_CTRL_IN_TOLERATE_BAD_DIR) | 0); | ||
1987 | writel(tmp, &dev->plregs->pl_ep_cfg_4); | ||
1988 | |||
1989 | tmp = readl(&dev->plregs->pl_ep_ctrl) & | ||
1990 | ~(1 << EP_INITIALIZED); | ||
1991 | writel(tmp, &dev->plregs->pl_ep_ctrl); | ||
1992 | |||
1993 | } | ||
1994 | |||
1995 | /* Set FSM to focus on the first Control Read: | ||
1996 | * - Tip: Connection speed is known upon the first | ||
1997 | * setup request.*/ | ||
1998 | scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ; | ||
1999 | set_idx_reg(dev->regs, SCRATCH, scratch); | ||
2000 | |||
2001 | } else{ | ||
2002 | WARNING(dev, "Defect 7374 workaround soft will NOT operate"); | ||
2003 | WARNING(dev, "It will operate on cold-reboot and SS connect"); | ||
2004 | } | ||
2005 | } | ||
2006 | |||
1738 | /* keeping it simple: | 2007 | /* keeping it simple: |
1739 | * - one bus driver, initted first; | 2008 | * - one bus driver, initted first; |
1740 | * - one function driver, initted second | 2009 | * - one function driver, initted second |
@@ -1744,7 +2013,7 @@ static void set_fifo_mode (struct net2280 *dev, int mode) | |||
1744 | * perhaps to bind specific drivers to specific devices. | 2013 | * perhaps to bind specific drivers to specific devices. |
1745 | */ | 2014 | */ |
1746 | 2015 | ||
1747 | static void usb_reset (struct net2280 *dev) | 2016 | static void usb_reset_228x(struct net2280 *dev) |
1748 | { | 2017 | { |
1749 | u32 tmp; | 2018 | u32 tmp; |
1750 | 2019 | ||
@@ -1760,11 +2029,11 @@ static void usb_reset (struct net2280 *dev) | |||
1760 | 2029 | ||
1761 | /* clear old dma and irq state */ | 2030 | /* clear old dma and irq state */ |
1762 | for (tmp = 0; tmp < 4; tmp++) { | 2031 | for (tmp = 0; tmp < 4; tmp++) { |
1763 | struct net2280_ep *ep = &dev->ep [tmp + 1]; | 2032 | struct net2280_ep *ep = &dev->ep[tmp + 1]; |
1764 | |||
1765 | if (ep->dma) | 2033 | if (ep->dma) |
1766 | abort_dma (ep); | 2034 | abort_dma(ep); |
1767 | } | 2035 | } |
2036 | |||
1768 | writel (~0, &dev->regs->irqstat0), | 2037 | writel (~0, &dev->regs->irqstat0), |
1769 | writel (~(1 << SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1), | 2038 | writel (~(1 << SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1), |
1770 | 2039 | ||
@@ -1780,7 +2049,67 @@ static void usb_reset (struct net2280 *dev) | |||
1780 | set_fifo_mode (dev, (fifo_mode <= 2) ? fifo_mode : 0); | 2049 | set_fifo_mode (dev, (fifo_mode <= 2) ? fifo_mode : 0); |
1781 | } | 2050 | } |
1782 | 2051 | ||
1783 | static void usb_reinit (struct net2280 *dev) | 2052 | static void usb_reset_338x(struct net2280 *dev) |
2053 | { | ||
2054 | u32 tmp; | ||
2055 | u32 fsmvalue; | ||
2056 | |||
2057 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
2058 | (void)readl(&dev->usb->usbctl); | ||
2059 | |||
2060 | net2280_led_init(dev); | ||
2061 | |||
2062 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
2063 | (0xf << DEFECT7374_FSM_FIELD); | ||
2064 | |||
2065 | /* See if firmware needs to set up for workaround: */ | ||
2066 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) { | ||
2067 | INFO(dev, "%s: Defect 7374 FsmValue 0x%08x\n", __func__, | ||
2068 | fsmvalue); | ||
2069 | } else { | ||
2070 | /* disable automatic responses, and irqs */ | ||
2071 | writel(0, &dev->usb->stdrsp); | ||
2072 | writel(0, &dev->regs->pciirqenb0); | ||
2073 | writel(0, &dev->regs->pciirqenb1); | ||
2074 | } | ||
2075 | |||
2076 | /* clear old dma and irq state */ | ||
2077 | for (tmp = 0; tmp < 4; tmp++) { | ||
2078 | struct net2280_ep *ep = &dev->ep[tmp + 1]; | ||
2079 | |||
2080 | if (ep->dma) | ||
2081 | abort_dma(ep); | ||
2082 | } | ||
2083 | |||
2084 | writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1); | ||
2085 | |||
2086 | if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) { | ||
2087 | /* reset, and enable pci */ | ||
2088 | tmp = readl(&dev->regs->devinit) | | ||
2089 | (1 << PCI_ENABLE) | | ||
2090 | (1 << FIFO_SOFT_RESET) | | ||
2091 | (1 << USB_SOFT_RESET) | | ||
2092 | (1 << M8051_RESET); | ||
2093 | |||
2094 | writel(tmp, &dev->regs->devinit); | ||
2095 | } | ||
2096 | |||
2097 | /* always ep-{1,2,3,4} ... maybe not ep-3 or ep-4 */ | ||
2098 | INIT_LIST_HEAD(&dev->gadget.ep_list); | ||
2099 | |||
2100 | for (tmp = 1; tmp < dev->n_ep; tmp++) | ||
2101 | list_add_tail(&dev->ep[tmp].ep.ep_list, &dev->gadget.ep_list); | ||
2102 | |||
2103 | } | ||
2104 | |||
2105 | static void usb_reset(struct net2280 *dev) | ||
2106 | { | ||
2107 | if (dev->pdev->vendor == 0x17cc) | ||
2108 | return usb_reset_228x(dev); | ||
2109 | return usb_reset_338x(dev); | ||
2110 | } | ||
2111 | |||
2112 | static void usb_reinit_228x(struct net2280 *dev) | ||
1784 | { | 2113 | { |
1785 | u32 tmp; | 2114 | u32 tmp; |
1786 | int init_dma; | 2115 | int init_dma; |
@@ -1803,7 +2132,8 @@ static void usb_reinit (struct net2280 *dev) | |||
1803 | } else | 2132 | } else |
1804 | ep->fifo_size = 64; | 2133 | ep->fifo_size = 64; |
1805 | ep->regs = &dev->epregs [tmp]; | 2134 | ep->regs = &dev->epregs [tmp]; |
1806 | ep_reset (dev->regs, ep); | 2135 | ep->cfg = &dev->epregs[tmp]; |
2136 | ep_reset_228x(dev->regs, ep); | ||
1807 | } | 2137 | } |
1808 | usb_ep_set_maxpacket_limit(&dev->ep [0].ep, 64); | 2138 | usb_ep_set_maxpacket_limit(&dev->ep [0].ep, 64); |
1809 | usb_ep_set_maxpacket_limit(&dev->ep [5].ep, 64); | 2139 | usb_ep_set_maxpacket_limit(&dev->ep [5].ep, 64); |
@@ -1820,7 +2150,122 @@ static void usb_reinit (struct net2280 *dev) | |||
1820 | writel (EP_DONTUSE, &dev->dep [tmp].dep_cfg); | 2150 | writel (EP_DONTUSE, &dev->dep [tmp].dep_cfg); |
1821 | } | 2151 | } |
1822 | 2152 | ||
1823 | static void ep0_start (struct net2280 *dev) | 2153 | static void usb_reinit_338x(struct net2280 *dev) |
2154 | { | ||
2155 | int init_dma; | ||
2156 | int i; | ||
2157 | u32 tmp, val; | ||
2158 | u32 fsmvalue; | ||
2159 | static const u32 ne[9] = { 0, 1, 2, 3, 4, 1, 2, 3, 4 }; | ||
2160 | static const u32 ep_reg_addr[9] = { 0x00, 0xC0, 0x00, 0xC0, 0x00, | ||
2161 | 0x00, 0xC0, 0x00, 0xC0 }; | ||
2162 | |||
2163 | /* use_dma changes are ignored till next device re-init */ | ||
2164 | init_dma = use_dma; | ||
2165 | |||
2166 | /* basic endpoint init */ | ||
2167 | for (i = 0; i < dev->n_ep; i++) { | ||
2168 | struct net2280_ep *ep = &dev->ep[i]; | ||
2169 | |||
2170 | ep->ep.name = ep_name[i]; | ||
2171 | ep->dev = dev; | ||
2172 | ep->num = i; | ||
2173 | |||
2174 | if (i > 0 && i <= 4 && init_dma) | ||
2175 | ep->dma = &dev->dma[i - 1]; | ||
2176 | |||
2177 | if (dev->enhanced_mode) { | ||
2178 | ep->cfg = &dev->epregs[ne[i]]; | ||
2179 | ep->regs = (struct net2280_ep_regs __iomem *) | ||
2180 | (((void *)&dev->epregs[ne[i]]) + | ||
2181 | ep_reg_addr[i]); | ||
2182 | ep->fiforegs = &dev->fiforegs[i]; | ||
2183 | } else { | ||
2184 | ep->cfg = &dev->epregs[i]; | ||
2185 | ep->regs = &dev->epregs[i]; | ||
2186 | ep->fiforegs = &dev->fiforegs[i]; | ||
2187 | } | ||
2188 | |||
2189 | ep->fifo_size = (i != 0) ? 2048 : 512; | ||
2190 | |||
2191 | ep_reset_338x(dev->regs, ep); | ||
2192 | } | ||
2193 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, 512); | ||
2194 | |||
2195 | dev->gadget.ep0 = &dev->ep[0].ep; | ||
2196 | dev->ep[0].stopped = 0; | ||
2197 | |||
2198 | /* Link layer set up */ | ||
2199 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
2200 | (0xf << DEFECT7374_FSM_FIELD); | ||
2201 | |||
2202 | /* See if driver needs to set up for workaround: */ | ||
2203 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) | ||
2204 | INFO(dev, "%s: Defect 7374 FsmValue %08x\n", | ||
2205 | __func__, fsmvalue); | ||
2206 | else { | ||
2207 | tmp = readl(&dev->usb_ext->usbctl2) & | ||
2208 | ~((1 << U1_ENABLE) | (1 << U2_ENABLE) | (1 << LTM_ENABLE)); | ||
2209 | writel(tmp, &dev->usb_ext->usbctl2); | ||
2210 | } | ||
2211 | |||
2212 | /* Hardware Defect and Workaround */ | ||
2213 | val = readl(&dev->ll_lfps_regs->ll_lfps_5); | ||
2214 | val &= ~(0xf << TIMER_LFPS_6US); | ||
2215 | val |= 0x5 << TIMER_LFPS_6US; | ||
2216 | writel(val, &dev->ll_lfps_regs->ll_lfps_5); | ||
2217 | |||
2218 | val = readl(&dev->ll_lfps_regs->ll_lfps_6); | ||
2219 | val &= ~(0xffff << TIMER_LFPS_80US); | ||
2220 | val |= 0x0100 << TIMER_LFPS_80US; | ||
2221 | writel(val, &dev->ll_lfps_regs->ll_lfps_6); | ||
2222 | |||
2223 | /* | ||
2224 | * AA_AB Errata. Issue 4. Workaround for SuperSpeed USB | ||
2225 | * Hot Reset Exit Handshake may Fail in Specific Case using | ||
2226 | * Default Register Settings. Workaround for Enumeration test. | ||
2227 | */ | ||
2228 | val = readl(&dev->ll_tsn_regs->ll_tsn_counters_2); | ||
2229 | val &= ~(0x1f << HOT_TX_NORESET_TS2); | ||
2230 | val |= 0x10 << HOT_TX_NORESET_TS2; | ||
2231 | writel(val, &dev->ll_tsn_regs->ll_tsn_counters_2); | ||
2232 | |||
2233 | val = readl(&dev->ll_tsn_regs->ll_tsn_counters_3); | ||
2234 | val &= ~(0x1f << HOT_RX_RESET_TS2); | ||
2235 | val |= 0x3 << HOT_RX_RESET_TS2; | ||
2236 | writel(val, &dev->ll_tsn_regs->ll_tsn_counters_3); | ||
2237 | |||
2238 | /* | ||
2239 | * Set Recovery Idle to Recover bit: | ||
2240 | * - On SS connections, setting Recovery Idle to Recover Fmw improves | ||
2241 | * link robustness with various hosts and hubs. | ||
2242 | * - It is safe to set for all connection speeds; all chip revisions. | ||
2243 | * - R-M-W to leave other bits undisturbed. | ||
2244 | * - Reference PLX TT-7372 | ||
2245 | */ | ||
2246 | val = readl(&dev->ll_chicken_reg->ll_tsn_chicken_bit); | ||
2247 | val |= (1 << RECOVERY_IDLE_TO_RECOVER_FMW); | ||
2248 | writel(val, &dev->ll_chicken_reg->ll_tsn_chicken_bit); | ||
2249 | |||
2250 | INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); | ||
2251 | |||
2252 | /* disable dedicated endpoints */ | ||
2253 | writel(0x0D, &dev->dep[0].dep_cfg); | ||
2254 | writel(0x0D, &dev->dep[1].dep_cfg); | ||
2255 | writel(0x0E, &dev->dep[2].dep_cfg); | ||
2256 | writel(0x0E, &dev->dep[3].dep_cfg); | ||
2257 | writel(0x0F, &dev->dep[4].dep_cfg); | ||
2258 | writel(0x0C, &dev->dep[5].dep_cfg); | ||
2259 | } | ||
2260 | |||
2261 | static void usb_reinit(struct net2280 *dev) | ||
2262 | { | ||
2263 | if (dev->pdev->vendor == 0x17cc) | ||
2264 | return usb_reinit_228x(dev); | ||
2265 | return usb_reinit_338x(dev); | ||
2266 | } | ||
2267 | |||
2268 | static void ep0_start_228x(struct net2280 *dev) | ||
1824 | { | 2269 | { |
1825 | writel ( (1 << CLEAR_EP_HIDE_STATUS_PHASE) | 2270 | writel ( (1 << CLEAR_EP_HIDE_STATUS_PHASE) |
1826 | | (1 << CLEAR_NAK_OUT_PACKETS) | 2271 | | (1 << CLEAR_NAK_OUT_PACKETS) |
@@ -1863,6 +2308,61 @@ static void ep0_start (struct net2280 *dev) | |||
1863 | (void) readl (&dev->usb->usbctl); | 2308 | (void) readl (&dev->usb->usbctl); |
1864 | } | 2309 | } |
1865 | 2310 | ||
2311 | static void ep0_start_338x(struct net2280 *dev) | ||
2312 | { | ||
2313 | u32 fsmvalue; | ||
2314 | |||
2315 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
2316 | (0xf << DEFECT7374_FSM_FIELD); | ||
2317 | |||
2318 | if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) | ||
2319 | INFO(dev, "%s: Defect 7374 FsmValue %08x\n", __func__, | ||
2320 | fsmvalue); | ||
2321 | else | ||
2322 | writel((1 << CLEAR_NAK_OUT_PACKETS_MODE) | | ||
2323 | (1 << SET_EP_HIDE_STATUS_PHASE), | ||
2324 | &dev->epregs[0].ep_rsp); | ||
2325 | |||
2326 | /* | ||
2327 | * hardware optionally handles a bunch of standard requests | ||
2328 | * that the API hides from drivers anyway. have it do so. | ||
2329 | * endpoint status/features are handled in software, to | ||
2330 | * help pass tests for some dubious behavior. | ||
2331 | */ | ||
2332 | writel((1 << SET_ISOCHRONOUS_DELAY) | | ||
2333 | (1 << SET_SEL) | | ||
2334 | (1 << SET_TEST_MODE) | | ||
2335 | (1 << SET_ADDRESS) | | ||
2336 | (1 << GET_INTERFACE_STATUS) | | ||
2337 | (1 << GET_DEVICE_STATUS), | ||
2338 | &dev->usb->stdrsp); | ||
2339 | dev->wakeup_enable = 1; | ||
2340 | writel((1 << USB_ROOT_PORT_WAKEUP_ENABLE) | | ||
2341 | (dev->softconnect << USB_DETECT_ENABLE) | | ||
2342 | (1 << DEVICE_REMOTE_WAKEUP_ENABLE), | ||
2343 | &dev->usb->usbctl); | ||
2344 | |||
2345 | /* enable irqs so we can see ep0 and general operation */ | ||
2346 | writel((1 << SETUP_PACKET_INTERRUPT_ENABLE) | | ||
2347 | (1 << ENDPOINT_0_INTERRUPT_ENABLE) | ||
2348 | , &dev->regs->pciirqenb0); | ||
2349 | writel((1 << PCI_INTERRUPT_ENABLE) | | ||
2350 | (1 << ROOT_PORT_RESET_INTERRUPT_ENABLE) | | ||
2351 | (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE) | | ||
2352 | (1 << VBUS_INTERRUPT_ENABLE), | ||
2353 | &dev->regs->pciirqenb1); | ||
2354 | |||
2355 | /* don't leave any writes posted */ | ||
2356 | (void)readl(&dev->usb->usbctl); | ||
2357 | } | ||
2358 | |||
2359 | static void ep0_start(struct net2280 *dev) | ||
2360 | { | ||
2361 | if (dev->pdev->vendor == 0x17cc) | ||
2362 | return ep0_start_228x(dev); | ||
2363 | return ep0_start_338x(dev); | ||
2364 | } | ||
2365 | |||
1866 | /* when a driver is successfully registered, it will receive | 2366 | /* when a driver is successfully registered, it will receive |
1867 | * control requests including set_configuration(), which enables | 2367 | * control requests including set_configuration(), which enables |
1868 | * non-control requests. then usb traffic follows until a | 2368 | * non-control requests. then usb traffic follows until a |
@@ -1886,7 +2386,7 @@ static int net2280_start(struct usb_gadget *_gadget, | |||
1886 | 2386 | ||
1887 | dev = container_of (_gadget, struct net2280, gadget); | 2387 | dev = container_of (_gadget, struct net2280, gadget); |
1888 | 2388 | ||
1889 | for (i = 0; i < 7; i++) | 2389 | for (i = 0; i < dev->n_ep; i++) |
1890 | dev->ep [i].irqs = 0; | 2390 | dev->ep [i].irqs = 0; |
1891 | 2391 | ||
1892 | /* hook up the driver ... */ | 2392 | /* hook up the driver ... */ |
@@ -1900,13 +2400,17 @@ static int net2280_start(struct usb_gadget *_gadget, | |||
1900 | if (retval) goto err_func; | 2400 | if (retval) goto err_func; |
1901 | 2401 | ||
1902 | /* Enable force-full-speed testing mode, if desired */ | 2402 | /* Enable force-full-speed testing mode, if desired */ |
1903 | if (full_speed) | 2403 | if (full_speed && dev->pdev->vendor == 0x17cc) |
1904 | writel(1 << FORCE_FULL_SPEED_MODE, &dev->usb->xcvrdiag); | 2404 | writel(1 << FORCE_FULL_SPEED_MODE, &dev->usb->xcvrdiag); |
1905 | 2405 | ||
1906 | /* ... then enable host detection and ep0; and we're ready | 2406 | /* ... then enable host detection and ep0; and we're ready |
1907 | * for set_configuration as well as eventual disconnect. | 2407 | * for set_configuration as well as eventual disconnect. |
1908 | */ | 2408 | */ |
1909 | net2280_led_active (dev, 1); | 2409 | net2280_led_active (dev, 1); |
2410 | |||
2411 | if (dev->pdev->vendor == 0x10b5) | ||
2412 | defect7374_enable_data_eps_zero(dev); | ||
2413 | |||
1910 | ep0_start (dev); | 2414 | ep0_start (dev); |
1911 | 2415 | ||
1912 | DEBUG (dev, "%s ready, usbctl %08x stdrsp %08x\n", | 2416 | DEBUG (dev, "%s ready, usbctl %08x stdrsp %08x\n", |
@@ -1937,7 +2441,7 @@ stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver) | |||
1937 | * and kill any outstanding requests. | 2441 | * and kill any outstanding requests. |
1938 | */ | 2442 | */ |
1939 | usb_reset (dev); | 2443 | usb_reset (dev); |
1940 | for (i = 0; i < 7; i++) | 2444 | for (i = 0; i < dev->n_ep; i++) |
1941 | nuke (&dev->ep [i]); | 2445 | nuke (&dev->ep [i]); |
1942 | 2446 | ||
1943 | /* report disconnect; the driver is already quiesced */ | 2447 | /* report disconnect; the driver is already quiesced */ |
@@ -1967,7 +2471,8 @@ static int net2280_stop(struct usb_gadget *_gadget, | |||
1967 | net2280_led_active (dev, 0); | 2471 | net2280_led_active (dev, 0); |
1968 | 2472 | ||
1969 | /* Disable full-speed test mode */ | 2473 | /* Disable full-speed test mode */ |
1970 | writel(0, &dev->usb->xcvrdiag); | 2474 | if (dev->pdev->vendor == 0x17cc) |
2475 | writel(0, &dev->usb->xcvrdiag); | ||
1971 | 2476 | ||
1972 | device_remove_file (&dev->pdev->dev, &dev_attr_function); | 2477 | device_remove_file (&dev->pdev->dev, &dev_attr_function); |
1973 | device_remove_file (&dev->pdev->dev, &dev_attr_queues); | 2478 | device_remove_file (&dev->pdev->dev, &dev_attr_queues); |
@@ -2219,6 +2724,350 @@ get_ep_by_addr (struct net2280 *dev, u16 wIndex) | |||
2219 | return NULL; | 2724 | return NULL; |
2220 | } | 2725 | } |
2221 | 2726 | ||
2727 | static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r) | ||
2728 | { | ||
2729 | u32 scratch, fsmvalue; | ||
2730 | u32 ack_wait_timeout, state; | ||
2731 | |||
2732 | /* Workaround for Defect 7374 (U1/U2 erroneously rejected): */ | ||
2733 | scratch = get_idx_reg(dev->regs, SCRATCH); | ||
2734 | fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD); | ||
2735 | scratch &= ~(0xf << DEFECT7374_FSM_FIELD); | ||
2736 | |||
2737 | if (!((fsmvalue == DEFECT7374_FSM_WAITING_FOR_CONTROL_READ) && | ||
2738 | (r.bRequestType & USB_DIR_IN))) | ||
2739 | return; | ||
2740 | |||
2741 | /* This is the first Control Read for this connection: */ | ||
2742 | if (!(readl(&dev->usb->usbstat) & (1 << SUPER_SPEED_MODE))) { | ||
2743 | /* | ||
2744 | * Connection is NOT SS: | ||
2745 | * - Connection must be FS or HS. | ||
2746 | * - This FSM state should allow workaround software to | ||
2747 | * run after the next USB connection. | ||
2748 | */ | ||
2749 | scratch |= DEFECT7374_FSM_NON_SS_CONTROL_READ; | ||
2750 | goto restore_data_eps; | ||
2751 | } | ||
2752 | |||
2753 | /* Connection is SS: */ | ||
2754 | for (ack_wait_timeout = 0; | ||
2755 | ack_wait_timeout < DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS; | ||
2756 | ack_wait_timeout++) { | ||
2757 | |||
2758 | state = readl(&dev->plregs->pl_ep_status_1) | ||
2759 | & (0xff << STATE); | ||
2760 | if ((state >= (ACK_GOOD_NORMAL << STATE)) && | ||
2761 | (state <= (ACK_GOOD_MORE_ACKS_TO_COME << STATE))) { | ||
2762 | scratch |= DEFECT7374_FSM_SS_CONTROL_READ; | ||
2763 | break; | ||
2764 | } | ||
2765 | |||
2766 | /* | ||
2767 | * We have not yet received host's Data Phase ACK | ||
2768 | * - Wait and try again. | ||
2769 | */ | ||
2770 | udelay(DEFECT_7374_PROCESSOR_WAIT_TIME); | ||
2771 | |||
2772 | continue; | ||
2773 | } | ||
2774 | |||
2775 | |||
2776 | if (ack_wait_timeout >= DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS) { | ||
2777 | ERROR(dev, "FAIL: Defect 7374 workaround waited but failed " | ||
2778 | "to detect SS host's data phase ACK."); | ||
2779 | ERROR(dev, "PL_EP_STATUS_1(23:16):.Expected from 0x11 to 0x16" | ||
2780 | "got 0x%2.2x.\n", state >> STATE); | ||
2781 | } else { | ||
2782 | WARNING(dev, "INFO: Defect 7374 workaround waited about\n" | ||
2783 | "%duSec for Control Read Data Phase ACK\n", | ||
2784 | DEFECT_7374_PROCESSOR_WAIT_TIME * ack_wait_timeout); | ||
2785 | } | ||
2786 | |||
2787 | restore_data_eps: | ||
2788 | /* | ||
2789 | * Restore data EPs to their pre-workaround settings (disabled, | ||
2790 | * initialized, and other details). | ||
2791 | */ | ||
2792 | defect7374_disable_data_eps(dev); | ||
2793 | |||
2794 | set_idx_reg(dev->regs, SCRATCH, scratch); | ||
2795 | |||
2796 | return; | ||
2797 | } | ||
2798 | |||
2799 | static void ep_stall(struct net2280_ep *ep, int stall) | ||
2800 | { | ||
2801 | struct net2280 *dev = ep->dev; | ||
2802 | u32 val; | ||
2803 | static const u32 ep_pl[9] = { 0, 3, 4, 7, 8, 2, 5, 6, 9 }; | ||
2804 | |||
2805 | if (stall) { | ||
2806 | writel((1 << SET_ENDPOINT_HALT) | | ||
2807 | /* (1 << SET_NAK_PACKETS) | */ | ||
2808 | (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE), | ||
2809 | &ep->regs->ep_rsp); | ||
2810 | ep->is_halt = 1; | ||
2811 | } else { | ||
2812 | if (dev->gadget.speed == USB_SPEED_SUPER) { | ||
2813 | /* | ||
2814 | * Workaround for SS SeqNum not cleared via | ||
2815 | * Endpoint Halt (Clear) bit. select endpoint | ||
2816 | */ | ||
2817 | val = readl(&dev->plregs->pl_ep_ctrl); | ||
2818 | val = (val & ~0x1f) | ep_pl[ep->num]; | ||
2819 | writel(val, &dev->plregs->pl_ep_ctrl); | ||
2820 | |||
2821 | val |= (1 << SEQUENCE_NUMBER_RESET); | ||
2822 | writel(val, &dev->plregs->pl_ep_ctrl); | ||
2823 | } | ||
2824 | val = readl(&ep->regs->ep_rsp); | ||
2825 | val |= (1 << CLEAR_ENDPOINT_HALT) | | ||
2826 | (1 << CLEAR_ENDPOINT_TOGGLE); | ||
2827 | writel(val | ||
2828 | /* | (1 << CLEAR_NAK_PACKETS)*/ | ||
2829 | , &ep->regs->ep_rsp); | ||
2830 | ep->is_halt = 0; | ||
2831 | val = readl(&ep->regs->ep_rsp); | ||
2832 | } | ||
2833 | } | ||
2834 | |||
2835 | static void ep_stdrsp(struct net2280_ep *ep, int value, int wedged) | ||
2836 | { | ||
2837 | /* set/clear, then synch memory views with the device */ | ||
2838 | if (value) { | ||
2839 | ep->stopped = 1; | ||
2840 | if (ep->num == 0) | ||
2841 | ep->dev->protocol_stall = 1; | ||
2842 | else { | ||
2843 | if (ep->dma) | ||
2844 | ep_stop_dma(ep); | ||
2845 | ep_stall(ep, true); | ||
2846 | } | ||
2847 | |||
2848 | if (wedged) | ||
2849 | ep->wedged = 1; | ||
2850 | } else { | ||
2851 | ep->stopped = 0; | ||
2852 | ep->wedged = 0; | ||
2853 | |||
2854 | ep_stall(ep, false); | ||
2855 | |||
2856 | /* Flush the queue */ | ||
2857 | if (!list_empty(&ep->queue)) { | ||
2858 | struct net2280_request *req = | ||
2859 | list_entry(ep->queue.next, struct net2280_request, | ||
2860 | queue); | ||
2861 | if (ep->dma) | ||
2862 | resume_dma(ep); | ||
2863 | else { | ||
2864 | if (ep->is_in) | ||
2865 | write_fifo(ep, &req->req); | ||
2866 | else { | ||
2867 | if (read_fifo(ep, req)) | ||
2868 | done(ep, req, 0); | ||
2869 | } | ||
2870 | } | ||
2871 | } | ||
2872 | } | ||
2873 | } | ||
2874 | |||
2875 | static void handle_stat0_irqs_superspeed(struct net2280 *dev, | ||
2876 | struct net2280_ep *ep, struct usb_ctrlrequest r) | ||
2877 | { | ||
2878 | int tmp = 0; | ||
2879 | |||
2880 | #define w_value le16_to_cpu(r.wValue) | ||
2881 | #define w_index le16_to_cpu(r.wIndex) | ||
2882 | #define w_length le16_to_cpu(r.wLength) | ||
2883 | |||
2884 | switch (r.bRequest) { | ||
2885 | struct net2280_ep *e; | ||
2886 | u16 status; | ||
2887 | |||
2888 | case USB_REQ_SET_CONFIGURATION: | ||
2889 | dev->addressed_state = !w_value; | ||
2890 | goto usb3_delegate; | ||
2891 | |||
2892 | case USB_REQ_GET_STATUS: | ||
2893 | switch (r.bRequestType) { | ||
2894 | case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE): | ||
2895 | status = dev->wakeup_enable ? 0x02 : 0x00; | ||
2896 | if (dev->selfpowered) | ||
2897 | status |= 1 << 0; | ||
2898 | status |= (dev->u1_enable << 2 | dev->u2_enable << 3 | | ||
2899 | dev->ltm_enable << 4); | ||
2900 | writel(0, &dev->epregs[0].ep_irqenb); | ||
2901 | set_fifo_bytecount(ep, sizeof(status)); | ||
2902 | writel((__force u32) status, &dev->epregs[0].ep_data); | ||
2903 | allow_status_338x(ep); | ||
2904 | break; | ||
2905 | |||
2906 | case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT): | ||
2907 | e = get_ep_by_addr(dev, w_index); | ||
2908 | if (!e) | ||
2909 | goto do_stall3; | ||
2910 | status = readl(&e->regs->ep_rsp) & | ||
2911 | (1 << CLEAR_ENDPOINT_HALT); | ||
2912 | writel(0, &dev->epregs[0].ep_irqenb); | ||
2913 | set_fifo_bytecount(ep, sizeof(status)); | ||
2914 | writel((__force u32) status, &dev->epregs[0].ep_data); | ||
2915 | allow_status_338x(ep); | ||
2916 | break; | ||
2917 | |||
2918 | default: | ||
2919 | goto usb3_delegate; | ||
2920 | } | ||
2921 | break; | ||
2922 | |||
2923 | case USB_REQ_CLEAR_FEATURE: | ||
2924 | switch (r.bRequestType) { | ||
2925 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE): | ||
2926 | if (!dev->addressed_state) { | ||
2927 | switch (w_value) { | ||
2928 | case USB_DEVICE_U1_ENABLE: | ||
2929 | dev->u1_enable = 0; | ||
2930 | writel(readl(&dev->usb_ext->usbctl2) & | ||
2931 | ~(1 << U1_ENABLE), | ||
2932 | &dev->usb_ext->usbctl2); | ||
2933 | allow_status_338x(ep); | ||
2934 | goto next_endpoints3; | ||
2935 | |||
2936 | case USB_DEVICE_U2_ENABLE: | ||
2937 | dev->u2_enable = 0; | ||
2938 | writel(readl(&dev->usb_ext->usbctl2) & | ||
2939 | ~(1 << U2_ENABLE), | ||
2940 | &dev->usb_ext->usbctl2); | ||
2941 | allow_status_338x(ep); | ||
2942 | goto next_endpoints3; | ||
2943 | |||
2944 | case USB_DEVICE_LTM_ENABLE: | ||
2945 | dev->ltm_enable = 0; | ||
2946 | writel(readl(&dev->usb_ext->usbctl2) & | ||
2947 | ~(1 << LTM_ENABLE), | ||
2948 | &dev->usb_ext->usbctl2); | ||
2949 | allow_status_338x(ep); | ||
2950 | goto next_endpoints3; | ||
2951 | |||
2952 | default: | ||
2953 | break; | ||
2954 | } | ||
2955 | } | ||
2956 | if (w_value == USB_DEVICE_REMOTE_WAKEUP) { | ||
2957 | dev->wakeup_enable = 0; | ||
2958 | writel(readl(&dev->usb->usbctl) & | ||
2959 | ~(1 << DEVICE_REMOTE_WAKEUP_ENABLE), | ||
2960 | &dev->usb->usbctl); | ||
2961 | allow_status_338x(ep); | ||
2962 | break; | ||
2963 | } | ||
2964 | goto usb3_delegate; | ||
2965 | |||
2966 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT): | ||
2967 | e = get_ep_by_addr(dev, w_index); | ||
2968 | if (!e) | ||
2969 | goto do_stall3; | ||
2970 | if (w_value != USB_ENDPOINT_HALT) | ||
2971 | goto do_stall3; | ||
2972 | VDEBUG(dev, "%s clear halt\n", e->ep.name); | ||
2973 | ep_stall(e, false); | ||
2974 | if (!list_empty(&e->queue) && e->td_dma) | ||
2975 | restart_dma(e); | ||
2976 | allow_status(ep); | ||
2977 | ep->stopped = 1; | ||
2978 | break; | ||
2979 | |||
2980 | default: | ||
2981 | goto usb3_delegate; | ||
2982 | } | ||
2983 | break; | ||
2984 | case USB_REQ_SET_FEATURE: | ||
2985 | switch (r.bRequestType) { | ||
2986 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE): | ||
2987 | if (!dev->addressed_state) { | ||
2988 | switch (w_value) { | ||
2989 | case USB_DEVICE_U1_ENABLE: | ||
2990 | dev->u1_enable = 1; | ||
2991 | writel(readl(&dev->usb_ext->usbctl2) | | ||
2992 | (1 << U1_ENABLE), | ||
2993 | &dev->usb_ext->usbctl2); | ||
2994 | allow_status_338x(ep); | ||
2995 | goto next_endpoints3; | ||
2996 | |||
2997 | case USB_DEVICE_U2_ENABLE: | ||
2998 | dev->u2_enable = 1; | ||
2999 | writel(readl(&dev->usb_ext->usbctl2) | | ||
3000 | (1 << U2_ENABLE), | ||
3001 | &dev->usb_ext->usbctl2); | ||
3002 | allow_status_338x(ep); | ||
3003 | goto next_endpoints3; | ||
3004 | |||
3005 | case USB_DEVICE_LTM_ENABLE: | ||
3006 | dev->ltm_enable = 1; | ||
3007 | writel(readl(&dev->usb_ext->usbctl2) | | ||
3008 | (1 << LTM_ENABLE), | ||
3009 | &dev->usb_ext->usbctl2); | ||
3010 | allow_status_338x(ep); | ||
3011 | goto next_endpoints3; | ||
3012 | default: | ||
3013 | break; | ||
3014 | } | ||
3015 | } | ||
3016 | |||
3017 | if (w_value == USB_DEVICE_REMOTE_WAKEUP) { | ||
3018 | dev->wakeup_enable = 1; | ||
3019 | writel(readl(&dev->usb->usbctl) | | ||
3020 | (1 << DEVICE_REMOTE_WAKEUP_ENABLE), | ||
3021 | &dev->usb->usbctl); | ||
3022 | allow_status_338x(ep); | ||
3023 | break; | ||
3024 | } | ||
3025 | goto usb3_delegate; | ||
3026 | |||
3027 | case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT): | ||
3028 | e = get_ep_by_addr(dev, w_index); | ||
3029 | if (!e || (w_value != USB_ENDPOINT_HALT)) | ||
3030 | goto do_stall3; | ||
3031 | ep_stdrsp(e, true, false); | ||
3032 | allow_status_338x(ep); | ||
3033 | break; | ||
3034 | |||
3035 | default: | ||
3036 | goto usb3_delegate; | ||
3037 | } | ||
3038 | |||
3039 | break; | ||
3040 | default: | ||
3041 | |||
3042 | usb3_delegate: | ||
3043 | VDEBUG(dev, "setup %02x.%02x v%04x i%04x l%04x ep_cfg %08x\n", | ||
3044 | r.bRequestType, r.bRequest, | ||
3045 | w_value, w_index, w_length, | ||
3046 | readl(&ep->cfg->ep_cfg)); | ||
3047 | |||
3048 | ep->responded = 0; | ||
3049 | spin_unlock(&dev->lock); | ||
3050 | tmp = dev->driver->setup(&dev->gadget, &r); | ||
3051 | spin_lock(&dev->lock); | ||
3052 | } | ||
3053 | do_stall3: | ||
3054 | if (tmp < 0) { | ||
3055 | VDEBUG(dev, "req %02x.%02x protocol STALL; stat %d\n", | ||
3056 | r.bRequestType, r.bRequest, tmp); | ||
3057 | dev->protocol_stall = 1; | ||
3058 | /* TD 9.9 Halt Endpoint test. TD 9.22 Set feature test */ | ||
3059 | ep_stall(ep, true); | ||
3060 | } | ||
3061 | |||
3062 | next_endpoints3: | ||
3063 | |||
3064 | #undef w_value | ||
3065 | #undef w_index | ||
3066 | #undef w_length | ||
3067 | |||
3068 | return; | ||
3069 | } | ||
3070 | |||
2222 | static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | 3071 | static void handle_stat0_irqs (struct net2280 *dev, u32 stat) |
2223 | { | 3072 | { |
2224 | struct net2280_ep *ep; | 3073 | struct net2280_ep *ep; |
@@ -2240,10 +3089,20 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2240 | struct net2280_request *req; | 3089 | struct net2280_request *req; |
2241 | 3090 | ||
2242 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) { | 3091 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) { |
2243 | if (readl (&dev->usb->usbstat) & (1 << HIGH_SPEED)) | 3092 | u32 val = readl(&dev->usb->usbstat); |
3093 | if (val & (1 << SUPER_SPEED)) { | ||
3094 | dev->gadget.speed = USB_SPEED_SUPER; | ||
3095 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, | ||
3096 | EP0_SS_MAX_PACKET_SIZE); | ||
3097 | } else if (val & (1 << HIGH_SPEED)) { | ||
2244 | dev->gadget.speed = USB_SPEED_HIGH; | 3098 | dev->gadget.speed = USB_SPEED_HIGH; |
2245 | else | 3099 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, |
3100 | EP0_HS_MAX_PACKET_SIZE); | ||
3101 | } else { | ||
2246 | dev->gadget.speed = USB_SPEED_FULL; | 3102 | dev->gadget.speed = USB_SPEED_FULL; |
3103 | usb_ep_set_maxpacket_limit(&dev->ep[0].ep, | ||
3104 | EP0_HS_MAX_PACKET_SIZE); | ||
3105 | } | ||
2247 | net2280_led_speed (dev, dev->gadget.speed); | 3106 | net2280_led_speed (dev, dev->gadget.speed); |
2248 | DEBUG(dev, "%s\n", usb_speed_string(dev->gadget.speed)); | 3107 | DEBUG(dev, "%s\n", usb_speed_string(dev->gadget.speed)); |
2249 | } | 3108 | } |
@@ -2261,32 +3120,38 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2261 | } | 3120 | } |
2262 | ep->stopped = 0; | 3121 | ep->stopped = 0; |
2263 | dev->protocol_stall = 0; | 3122 | dev->protocol_stall = 0; |
2264 | 3123 | if (dev->pdev->vendor == 0x10b5) | |
2265 | if (ep->dev->pdev->device == 0x2280) | 3124 | ep->is_halt = 0; |
2266 | tmp = (1 << FIFO_OVERFLOW) | 3125 | else{ |
2267 | | (1 << FIFO_UNDERFLOW); | 3126 | if (ep->dev->pdev->device == 0x2280) |
2268 | else | 3127 | tmp = (1 << FIFO_OVERFLOW) | |
2269 | tmp = 0; | 3128 | (1 << FIFO_UNDERFLOW); |
2270 | 3129 | else | |
2271 | writel (tmp | (1 << TIMEOUT) | 3130 | tmp = 0; |
2272 | | (1 << USB_STALL_SENT) | 3131 | |
2273 | | (1 << USB_IN_NAK_SENT) | 3132 | writel(tmp | (1 << TIMEOUT) | |
2274 | | (1 << USB_IN_ACK_RCVD) | 3133 | (1 << USB_STALL_SENT) | |
2275 | | (1 << USB_OUT_PING_NAK_SENT) | 3134 | (1 << USB_IN_NAK_SENT) | |
2276 | | (1 << USB_OUT_ACK_SENT) | 3135 | (1 << USB_IN_ACK_RCVD) | |
2277 | | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | 3136 | (1 << USB_OUT_PING_NAK_SENT) | |
2278 | | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) | 3137 | (1 << USB_OUT_ACK_SENT) | |
2279 | | (1 << DATA_PACKET_RECEIVED_INTERRUPT) | 3138 | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) | |
2280 | | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT) | 3139 | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) | |
2281 | | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | 3140 | (1 << DATA_PACKET_RECEIVED_INTERRUPT) | |
2282 | | (1 << DATA_IN_TOKEN_INTERRUPT) | 3141 | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT) | |
2283 | , &ep->regs->ep_stat); | 3142 | (1 << DATA_OUT_PING_TOKEN_INTERRUPT) | |
2284 | u.raw [0] = readl (&dev->usb->setup0123); | 3143 | (1 << DATA_IN_TOKEN_INTERRUPT) |
2285 | u.raw [1] = readl (&dev->usb->setup4567); | 3144 | , &ep->regs->ep_stat); |
3145 | } | ||
3146 | u.raw[0] = readl(&dev->usb->setup0123); | ||
3147 | u.raw[1] = readl(&dev->usb->setup4567); | ||
2286 | 3148 | ||
2287 | cpu_to_le32s (&u.raw [0]); | 3149 | cpu_to_le32s (&u.raw [0]); |
2288 | cpu_to_le32s (&u.raw [1]); | 3150 | cpu_to_le32s (&u.raw [1]); |
2289 | 3151 | ||
3152 | if (dev->pdev->vendor == 0x10b5) | ||
3153 | defect7374_workaround(dev, u.r); | ||
3154 | |||
2290 | tmp = 0; | 3155 | tmp = 0; |
2291 | 3156 | ||
2292 | #define w_value le16_to_cpu(u.r.wValue) | 3157 | #define w_value le16_to_cpu(u.r.wValue) |
@@ -2318,6 +3183,12 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2318 | * everything else goes uplevel to the gadget code. | 3183 | * everything else goes uplevel to the gadget code. |
2319 | */ | 3184 | */ |
2320 | ep->responded = 1; | 3185 | ep->responded = 1; |
3186 | |||
3187 | if (dev->gadget.speed == USB_SPEED_SUPER) { | ||
3188 | handle_stat0_irqs_superspeed(dev, ep, u.r); | ||
3189 | goto next_endpoints; | ||
3190 | } | ||
3191 | |||
2321 | switch (u.r.bRequest) { | 3192 | switch (u.r.bRequest) { |
2322 | case USB_REQ_GET_STATUS: { | 3193 | case USB_REQ_GET_STATUS: { |
2323 | struct net2280_ep *e; | 3194 | struct net2280_ep *e; |
@@ -2360,8 +3231,11 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2360 | VDEBUG(dev, "%s wedged, halt not cleared\n", | 3231 | VDEBUG(dev, "%s wedged, halt not cleared\n", |
2361 | ep->ep.name); | 3232 | ep->ep.name); |
2362 | } else { | 3233 | } else { |
2363 | VDEBUG(dev, "%s clear halt\n", ep->ep.name); | 3234 | VDEBUG(dev, "%s clear halt\n", e->ep.name); |
2364 | clear_halt(e); | 3235 | clear_halt(e); |
3236 | if (ep->dev->pdev->vendor == 0x10b5 && | ||
3237 | !list_empty(&e->queue) && e->td_dma) | ||
3238 | restart_dma(e); | ||
2365 | } | 3239 | } |
2366 | allow_status (ep); | 3240 | allow_status (ep); |
2367 | goto next_endpoints; | 3241 | goto next_endpoints; |
@@ -2381,6 +3255,8 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2381 | if (e->ep.name == ep0name) | 3255 | if (e->ep.name == ep0name) |
2382 | goto do_stall; | 3256 | goto do_stall; |
2383 | set_halt (e); | 3257 | set_halt (e); |
3258 | if (dev->pdev->vendor == 0x10b5 && e->dma) | ||
3259 | abort_dma(e); | ||
2384 | allow_status (ep); | 3260 | allow_status (ep); |
2385 | VDEBUG (dev, "%s set halt\n", ep->ep.name); | 3261 | VDEBUG (dev, "%s set halt\n", ep->ep.name); |
2386 | goto next_endpoints; | 3262 | goto next_endpoints; |
@@ -2392,7 +3268,7 @@ delegate: | |||
2392 | "ep_cfg %08x\n", | 3268 | "ep_cfg %08x\n", |
2393 | u.r.bRequestType, u.r.bRequest, | 3269 | u.r.bRequestType, u.r.bRequest, |
2394 | w_value, w_index, w_length, | 3270 | w_value, w_index, w_length, |
2395 | readl (&ep->regs->ep_cfg)); | 3271 | readl(&ep->cfg->ep_cfg)); |
2396 | ep->responded = 0; | 3272 | ep->responded = 0; |
2397 | spin_unlock (&dev->lock); | 3273 | spin_unlock (&dev->lock); |
2398 | tmp = dev->driver->setup (&dev->gadget, &u.r); | 3274 | tmp = dev->driver->setup (&dev->gadget, &u.r); |
@@ -2455,7 +3331,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat) | |||
2455 | 3331 | ||
2456 | /* after disconnect there's nothing else to do! */ | 3332 | /* after disconnect there's nothing else to do! */ |
2457 | tmp = (1 << VBUS_INTERRUPT) | (1 << ROOT_PORT_RESET_INTERRUPT); | 3333 | tmp = (1 << VBUS_INTERRUPT) | (1 << ROOT_PORT_RESET_INTERRUPT); |
2458 | mask = (1 << HIGH_SPEED) | (1 << FULL_SPEED); | 3334 | mask = (1 << SUPER_SPEED) | (1 << HIGH_SPEED) | (1 << FULL_SPEED); |
2459 | 3335 | ||
2460 | /* VBUS disconnect is indicated by VBUS_PIN and VBUS_INTERRUPT set. | 3336 | /* VBUS disconnect is indicated by VBUS_PIN and VBUS_INTERRUPT set. |
2461 | * Root Port Reset is indicated by ROOT_PORT_RESET_INTERRUPT set and | 3337 | * Root Port Reset is indicated by ROOT_PORT_RESET_INTERRUPT set and |
@@ -2546,12 +3422,19 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat) | |||
2546 | tmp = readl (&dma->dmastat); | 3422 | tmp = readl (&dma->dmastat); |
2547 | writel (tmp, &dma->dmastat); | 3423 | writel (tmp, &dma->dmastat); |
2548 | 3424 | ||
3425 | /* dma sync*/ | ||
3426 | if (dev->pdev->vendor == 0x10b5) { | ||
3427 | u32 r_dmacount = readl(&dma->dmacount); | ||
3428 | if (!ep->is_in && (r_dmacount & 0x00FFFFFF) && | ||
3429 | (tmp & (1 << DMA_TRANSACTION_DONE_INTERRUPT))) | ||
3430 | continue; | ||
3431 | } | ||
3432 | |||
2549 | /* chaining should stop on abort, short OUT from fifo, | 3433 | /* chaining should stop on abort, short OUT from fifo, |
2550 | * or (stat0 codepath) short OUT transfer. | 3434 | * or (stat0 codepath) short OUT transfer. |
2551 | */ | 3435 | */ |
2552 | if (!use_dma_chaining) { | 3436 | if (!use_dma_chaining) { |
2553 | if ((tmp & (1 << DMA_TRANSACTION_DONE_INTERRUPT)) | 3437 | if (!(tmp & (1 << DMA_TRANSACTION_DONE_INTERRUPT))) { |
2554 | == 0) { | ||
2555 | DEBUG (ep->dev, "%s no xact done? %08x\n", | 3438 | DEBUG (ep->dev, "%s no xact done? %08x\n", |
2556 | ep->ep.name, tmp); | 3439 | ep->ep.name, tmp); |
2557 | continue; | 3440 | continue; |
@@ -2625,7 +3508,8 @@ static irqreturn_t net2280_irq (int irq, void *_dev) | |||
2625 | struct net2280 *dev = _dev; | 3508 | struct net2280 *dev = _dev; |
2626 | 3509 | ||
2627 | /* shared interrupt, not ours */ | 3510 | /* shared interrupt, not ours */ |
2628 | if (!(readl(&dev->regs->irqstat0) & (1 << INTA_ASSERTED))) | 3511 | if (dev->pdev->vendor == 0x17cc && |
3512 | (!(readl(&dev->regs->irqstat0) & (1 << INTA_ASSERTED)))) | ||
2629 | return IRQ_NONE; | 3513 | return IRQ_NONE; |
2630 | 3514 | ||
2631 | spin_lock (&dev->lock); | 3515 | spin_lock (&dev->lock); |
@@ -2636,6 +3520,13 @@ static irqreturn_t net2280_irq (int irq, void *_dev) | |||
2636 | /* control requests and PIO */ | 3520 | /* control requests and PIO */ |
2637 | handle_stat0_irqs (dev, readl (&dev->regs->irqstat0)); | 3521 | handle_stat0_irqs (dev, readl (&dev->regs->irqstat0)); |
2638 | 3522 | ||
3523 | if (dev->pdev->vendor == 0x10b5) { | ||
3524 | /* re-enable interrupt to trigger any possible new interrupt */ | ||
3525 | u32 pciirqenb1 = readl(&dev->regs->pciirqenb1); | ||
3526 | writel(pciirqenb1 & 0x7FFFFFFF, &dev->regs->pciirqenb1); | ||
3527 | writel(pciirqenb1, &dev->regs->pciirqenb1); | ||
3528 | } | ||
3529 | |||
2639 | spin_unlock (&dev->lock); | 3530 | spin_unlock (&dev->lock); |
2640 | 3531 | ||
2641 | return IRQ_HANDLED; | 3532 | return IRQ_HANDLED; |
@@ -2674,6 +3565,8 @@ static void net2280_remove (struct pci_dev *pdev) | |||
2674 | } | 3565 | } |
2675 | if (dev->got_irq) | 3566 | if (dev->got_irq) |
2676 | free_irq (pdev->irq, dev); | 3567 | free_irq (pdev->irq, dev); |
3568 | if (use_msi && dev->pdev->vendor == 0x10b5) | ||
3569 | pci_disable_msi(pdev); | ||
2677 | if (dev->regs) | 3570 | if (dev->regs) |
2678 | iounmap (dev->regs); | 3571 | iounmap (dev->regs); |
2679 | if (dev->region) | 3572 | if (dev->region) |
@@ -2708,7 +3601,8 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
2708 | spin_lock_init (&dev->lock); | 3601 | spin_lock_init (&dev->lock); |
2709 | dev->pdev = pdev; | 3602 | dev->pdev = pdev; |
2710 | dev->gadget.ops = &net2280_ops; | 3603 | dev->gadget.ops = &net2280_ops; |
2711 | dev->gadget.max_speed = USB_SPEED_HIGH; | 3604 | dev->gadget.max_speed = (dev->pdev->vendor == 0x10b5) ? |
3605 | USB_SPEED_SUPER : USB_SPEED_HIGH; | ||
2712 | 3606 | ||
2713 | /* the "gadget" abstracts/virtualizes the controller */ | 3607 | /* the "gadget" abstracts/virtualizes the controller */ |
2714 | dev->gadget.name = driver_name; | 3608 | dev->gadget.name = driver_name; |
@@ -2750,8 +3644,39 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
2750 | dev->dep = (struct net2280_dep_regs __iomem *) (base + 0x0200); | 3644 | dev->dep = (struct net2280_dep_regs __iomem *) (base + 0x0200); |
2751 | dev->epregs = (struct net2280_ep_regs __iomem *) (base + 0x0300); | 3645 | dev->epregs = (struct net2280_ep_regs __iomem *) (base + 0x0300); |
2752 | 3646 | ||
2753 | /* put into initial config, link up all endpoints */ | 3647 | if (dev->pdev->vendor == 0x10b5) { |
2754 | writel (0, &dev->usb->usbctl); | 3648 | u32 fsmvalue; |
3649 | u32 usbstat; | ||
3650 | dev->usb_ext = (struct usb338x_usb_ext_regs __iomem *) | ||
3651 | (base + 0x00b4); | ||
3652 | dev->fiforegs = (struct usb338x_fifo_regs __iomem *) | ||
3653 | (base + 0x0500); | ||
3654 | dev->llregs = (struct usb338x_ll_regs __iomem *) | ||
3655 | (base + 0x0700); | ||
3656 | dev->ll_lfps_regs = (struct usb338x_ll_lfps_regs __iomem *) | ||
3657 | (base + 0x0748); | ||
3658 | dev->ll_tsn_regs = (struct usb338x_ll_tsn_regs __iomem *) | ||
3659 | (base + 0x077c); | ||
3660 | dev->ll_chicken_reg = (struct usb338x_ll_chi_regs __iomem *) | ||
3661 | (base + 0x079c); | ||
3662 | dev->plregs = (struct usb338x_pl_regs __iomem *) | ||
3663 | (base + 0x0800); | ||
3664 | usbstat = readl(&dev->usb->usbstat); | ||
3665 | dev->enhanced_mode = (usbstat & (1 << 11)) ? 1 : 0; | ||
3666 | dev->n_ep = (dev->enhanced_mode) ? 9 : 5; | ||
3667 | /* put into initial config, link up all endpoints */ | ||
3668 | fsmvalue = get_idx_reg(dev->regs, SCRATCH) & | ||
3669 | (0xf << DEFECT7374_FSM_FIELD); | ||
3670 | /* See if firmware needs to set up for workaround: */ | ||
3671 | if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) | ||
3672 | writel(0, &dev->usb->usbctl); | ||
3673 | } else{ | ||
3674 | dev->enhanced_mode = 0; | ||
3675 | dev->n_ep = 7; | ||
3676 | /* put into initial config, link up all endpoints */ | ||
3677 | writel(0, &dev->usb->usbctl); | ||
3678 | } | ||
3679 | |||
2755 | usb_reset (dev); | 3680 | usb_reset (dev); |
2756 | usb_reinit (dev); | 3681 | usb_reinit (dev); |
2757 | 3682 | ||
@@ -2762,6 +3687,10 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
2762 | goto done; | 3687 | goto done; |
2763 | } | 3688 | } |
2764 | 3689 | ||
3690 | if (use_msi && dev->pdev->vendor == 0x10b5) | ||
3691 | if (pci_enable_msi(pdev)) | ||
3692 | ERROR(dev, "Failed to enable MSI mode\n"); | ||
3693 | |||
2765 | if (request_irq (pdev->irq, net2280_irq, IRQF_SHARED, driver_name, dev) | 3694 | if (request_irq (pdev->irq, net2280_irq, IRQF_SHARED, driver_name, dev) |
2766 | != 0) { | 3695 | != 0) { |
2767 | ERROR (dev, "request interrupt %d failed\n", pdev->irq); | 3696 | ERROR (dev, "request interrupt %d failed\n", pdev->irq); |
@@ -2797,7 +3726,8 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
2797 | } | 3726 | } |
2798 | 3727 | ||
2799 | /* enable lower-overhead pci memory bursts during DMA */ | 3728 | /* enable lower-overhead pci memory bursts during DMA */ |
2800 | writel ( (1 << DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE) | 3729 | if (dev->pdev->vendor == 0x17cc) |
3730 | writel((1 << DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE) | ||
2801 | // 256 write retries may not be enough... | 3731 | // 256 write retries may not be enough... |
2802 | // | (1 << PCI_RETRY_ABORT_ENABLE) | 3732 | // | (1 << PCI_RETRY_ABORT_ENABLE) |
2803 | | (1 << DMA_READ_MULTIPLE_ENABLE) | 3733 | | (1 << DMA_READ_MULTIPLE_ENABLE) |
@@ -2814,10 +3744,10 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
2814 | INFO (dev, "%s\n", driver_desc); | 3744 | INFO (dev, "%s\n", driver_desc); |
2815 | INFO (dev, "irq %d, pci mem %p, chip rev %04x\n", | 3745 | INFO (dev, "irq %d, pci mem %p, chip rev %04x\n", |
2816 | pdev->irq, base, dev->chiprev); | 3746 | pdev->irq, base, dev->chiprev); |
2817 | INFO (dev, "version: " DRIVER_VERSION "; dma %s\n", | 3747 | INFO(dev, "version: " DRIVER_VERSION "; dma %s %s\n", |
2818 | use_dma | 3748 | use_dma ? (use_dma_chaining ? "chaining" : "enabled") |
2819 | ? (use_dma_chaining ? "chaining" : "enabled") | 3749 | : "disabled", |
2820 | : "disabled"); | 3750 | dev->enhanced_mode ? "enhanced mode" : "legacy mode"); |
2821 | retval = device_create_file (&pdev->dev, &dev_attr_registers); | 3751 | retval = device_create_file (&pdev->dev, &dev_attr_registers); |
2822 | if (retval) goto done; | 3752 | if (retval) goto done; |
2823 | 3753 | ||
@@ -2849,7 +3779,8 @@ static void net2280_shutdown (struct pci_dev *pdev) | |||
2849 | writel (0, &dev->usb->usbctl); | 3779 | writel (0, &dev->usb->usbctl); |
2850 | 3780 | ||
2851 | /* Disable full-speed test mode */ | 3781 | /* Disable full-speed test mode */ |
2852 | writel(0, &dev->usb->xcvrdiag); | 3782 | if (dev->pdev->vendor == 0x17cc) |
3783 | writel(0, &dev->usb->xcvrdiag); | ||
2853 | } | 3784 | } |
2854 | 3785 | ||
2855 | 3786 | ||
@@ -2869,8 +3800,24 @@ static const struct pci_device_id pci_ids [] = { { | |||
2869 | .device = 0x2282, | 3800 | .device = 0x2282, |
2870 | .subvendor = PCI_ANY_ID, | 3801 | .subvendor = PCI_ANY_ID, |
2871 | .subdevice = PCI_ANY_ID, | 3802 | .subdevice = PCI_ANY_ID, |
2872 | 3803 | }, | |
2873 | }, { /* end: all zeroes */ } | 3804 | { |
3805 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
3806 | .class_mask = ~0, | ||
3807 | .vendor = 0x10b5, | ||
3808 | .device = 0x3380, | ||
3809 | .subvendor = PCI_ANY_ID, | ||
3810 | .subdevice = PCI_ANY_ID, | ||
3811 | }, | ||
3812 | { | ||
3813 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
3814 | .class_mask = ~0, | ||
3815 | .vendor = 0x10b5, | ||
3816 | .device = 0x3382, | ||
3817 | .subvendor = PCI_ANY_ID, | ||
3818 | .subdevice = PCI_ANY_ID, | ||
3819 | }, | ||
3820 | { /* end: all zeroes */ } | ||
2874 | }; | 3821 | }; |
2875 | MODULE_DEVICE_TABLE (pci, pci_ids); | 3822 | MODULE_DEVICE_TABLE (pci, pci_ids); |
2876 | 3823 | ||