Commit | Line | Data |
---|---|---|
db11e47d SS |
1 | /* |
2 | * Driver for the NXP ISP1760 chip | |
3 | * | |
4 | * However, the code might contain some bugs. What doesn't work for sure is: | |
5 | * - ISO | |
6 | * - OTG | |
7 | e The interrupt line is configured as active low, level. | |
8 | * | |
9 | * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de> | |
10 | * | |
71a9f9d2 AB |
11 | * (c) 2011 Arvid Brodin <arvid.brodin@enea.com> |
12 | * | |
db11e47d | 13 | */ |
7eb42c6e | 14 | #include <linux/gpio/consumer.h> |
db11e47d SS |
15 | #include <linux/module.h> |
16 | #include <linux/kernel.h> | |
17 | #include <linux/slab.h> | |
18 | #include <linux/list.h> | |
19 | #include <linux/usb.h> | |
27729aad | 20 | #include <linux/usb/hcd.h> |
db11e47d SS |
21 | #include <linux/debugfs.h> |
22 | #include <linux/uaccess.h> | |
23 | #include <linux/io.h> | |
db8516f6 | 24 | #include <linux/mm.h> |
6d50c60e | 25 | #include <linux/timer.h> |
db11e47d | 26 | #include <asm/unaligned.h> |
db8516f6 | 27 | #include <asm/cacheflush.h> |
db11e47d | 28 | |
5171446a | 29 | #include "isp1760-core.h" |
db11e47d | 30 | #include "isp1760-hcd.h" |
e19c99e7 | 31 | #include "isp1760-regs.h" |
db11e47d SS |
32 | |
33 | static struct kmem_cache *qtd_cachep; | |
34 | static struct kmem_cache *qh_cachep; | |
71a9f9d2 | 35 | static struct kmem_cache *urb_listitem_cachep; |
db11e47d | 36 | |
f0bdbb0e LP |
37 | typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, |
38 | struct isp1760_qtd *qtd); | |
db11e47d SS |
39 | |
40 | static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) | |
41 | { | |
cdd36e87 | 42 | return *(struct isp1760_hcd **)hcd->hcd_priv; |
db11e47d | 43 | } |
db11e47d | 44 | |
e19c99e7 LP |
45 | /* urb state*/ |
46 | #define DELETE_URB (0x0008) | |
47 | #define NO_TRANSFER_ACTIVE (0xffffffff) | |
48 | ||
49 | /* Philips Proprietary Transfer Descriptor (PTD) */ | |
50 | typedef __u32 __bitwise __dw; | |
51 | struct ptd { | |
52 | __dw dw0; | |
53 | __dw dw1; | |
54 | __dw dw2; | |
55 | __dw dw3; | |
56 | __dw dw4; | |
57 | __dw dw5; | |
58 | __dw dw6; | |
59 | __dw dw7; | |
60 | }; | |
61 | #define PTD_OFFSET 0x0400 | |
62 | #define ISO_PTD_OFFSET 0x0400 | |
63 | #define INT_PTD_OFFSET 0x0800 | |
64 | #define ATL_PTD_OFFSET 0x0c00 | |
65 | #define PAYLOAD_OFFSET 0x1000 | |
66 | ||
67 | ||
68 | /* ATL */ | |
69 | /* DW0 */ | |
70 | #define DW0_VALID_BIT 1 | |
71 | #define FROM_DW0_VALID(x) ((x) & 0x01) | |
72 | #define TO_DW0_LENGTH(x) (((u32) x) << 3) | |
73 | #define TO_DW0_MAXPACKET(x) (((u32) x) << 18) | |
74 | #define TO_DW0_MULTI(x) (((u32) x) << 29) | |
75 | #define TO_DW0_ENDPOINT(x) (((u32) x) << 31) | |
76 | /* DW1 */ | |
77 | #define TO_DW1_DEVICE_ADDR(x) (((u32) x) << 3) | |
78 | #define TO_DW1_PID_TOKEN(x) (((u32) x) << 10) | |
79 | #define DW1_TRANS_BULK ((u32) 2 << 12) | |
80 | #define DW1_TRANS_INT ((u32) 3 << 12) | |
81 | #define DW1_TRANS_SPLIT ((u32) 1 << 14) | |
82 | #define DW1_SE_USB_LOSPEED ((u32) 2 << 16) | |
83 | #define TO_DW1_PORT_NUM(x) (((u32) x) << 18) | |
84 | #define TO_DW1_HUB_NUM(x) (((u32) x) << 25) | |
85 | /* DW2 */ | |
86 | #define TO_DW2_DATA_START_ADDR(x) (((u32) x) << 8) | |
87 | #define TO_DW2_RL(x) ((x) << 25) | |
88 | #define FROM_DW2_RL(x) (((x) >> 25) & 0xf) | |
89 | /* DW3 */ | |
90 | #define FROM_DW3_NRBYTESTRANSFERRED(x) ((x) & 0x7fff) | |
91 | #define FROM_DW3_SCS_NRBYTESTRANSFERRED(x) ((x) & 0x07ff) | |
92 | #define TO_DW3_NAKCOUNT(x) ((x) << 19) | |
93 | #define FROM_DW3_NAKCOUNT(x) (((x) >> 19) & 0xf) | |
94 | #define TO_DW3_CERR(x) ((x) << 23) | |
95 | #define FROM_DW3_CERR(x) (((x) >> 23) & 0x3) | |
96 | #define TO_DW3_DATA_TOGGLE(x) ((x) << 25) | |
97 | #define FROM_DW3_DATA_TOGGLE(x) (((x) >> 25) & 0x1) | |
98 | #define TO_DW3_PING(x) ((x) << 26) | |
99 | #define FROM_DW3_PING(x) (((x) >> 26) & 0x1) | |
100 | #define DW3_ERROR_BIT (1 << 28) | |
101 | #define DW3_BABBLE_BIT (1 << 29) | |
102 | #define DW3_HALT_BIT (1 << 30) | |
103 | #define DW3_ACTIVE_BIT (1 << 31) | |
104 | #define FROM_DW3_ACTIVE(x) (((x) >> 31) & 0x01) | |
105 | ||
106 | #define INT_UNDERRUN (1 << 2) | |
107 | #define INT_BABBLE (1 << 1) | |
108 | #define INT_EXACT (1 << 0) | |
109 | ||
110 | #define SETUP_PID (2) | |
111 | #define IN_PID (1) | |
112 | #define OUT_PID (0) | |
113 | ||
114 | /* Errata 1 */ | |
115 | #define RL_COUNTER (0) | |
116 | #define NAK_COUNTER (0) | |
117 | #define ERR_COUNTER (2) | |
db11e47d SS |
118 | |
119 | struct isp1760_qtd { | |
db11e47d | 120 | u8 packet_type; |
db11e47d | 121 | void *data_buffer; |
a041d8e4 AB |
122 | u32 payload_addr; |
123 | ||
db11e47d SS |
124 | /* the rest is HCD-private */ |
125 | struct list_head qtd_list; | |
126 | struct urb *urb; | |
127 | size_t length; | |
71a9f9d2 AB |
128 | size_t actual_length; |
129 | ||
130 | /* QTD_ENQUEUED: waiting for transfer (inactive) */ | |
131 | /* QTD_PAYLOAD_ALLOC: chip mem has been allocated for payload */ | |
132 | /* QTD_XFER_STARTED: valid ptd has been written to isp176x - only | |
133 | interrupt handler may touch this qtd! */ | |
134 | /* QTD_XFER_COMPLETE: payload has been transferred successfully */ | |
135 | /* QTD_RETIRE: transfer error/abort qtd */ | |
136 | #define QTD_ENQUEUED 0 | |
137 | #define QTD_PAYLOAD_ALLOC 1 | |
138 | #define QTD_XFER_STARTED 2 | |
139 | #define QTD_XFER_COMPLETE 3 | |
140 | #define QTD_RETIRE 4 | |
db11e47d | 141 | u32 status; |
db11e47d SS |
142 | }; |
143 | ||
71a9f9d2 | 144 | /* Queue head, one for each active endpoint */ |
db11e47d | 145 | struct isp1760_qh { |
71a9f9d2 | 146 | struct list_head qh_list; |
db11e47d | 147 | struct list_head qtd_list; |
db11e47d SS |
148 | u32 toggle; |
149 | u32 ping; | |
71a9f9d2 | 150 | int slot; |
74ad6029 | 151 | int tt_buffer_dirty; /* See USB2.0 spec section 11.17.5 */ |
71a9f9d2 AB |
152 | }; |
153 | ||
154 | struct urb_listitem { | |
155 | struct list_head urb_list; | |
156 | struct urb *urb; | |
db11e47d SS |
157 | }; |
158 | ||
bedc0c31 AB |
159 | /* |
160 | * Access functions for isp176x registers (addresses 0..0x03FF). | |
161 | */ | |
162 | static u32 reg_read32(void __iomem *base, u32 reg) | |
db11e47d | 163 | { |
5171446a | 164 | return isp1760_read32(base, reg); |
db11e47d SS |
165 | } |
166 | ||
bedc0c31 | 167 | static void reg_write32(void __iomem *base, u32 reg, u32 val) |
db11e47d | 168 | { |
5171446a | 169 | isp1760_write32(base, reg, val); |
db11e47d SS |
170 | } |
171 | ||
172 | /* | |
bedc0c31 AB |
173 | * Access functions for isp176x memory (offset >= 0x0400). |
174 | * | |
175 | * bank_reads8() reads memory locations prefetched by an earlier write to | |
176 | * HC_MEMORY_REG (see isp176x datasheet). Unless you want to do fancy multi- | |
177 | * bank optimizations, you should use the more generic mem_reads8() below. | |
178 | * | |
179 | * For access to ptd memory, use the specialized ptd_read() and ptd_write() | |
180 | * below. | |
181 | * | |
182 | * These functions copy via MMIO data to/from the device. memcpy_{to|from}io() | |
db11e47d SS |
183 | * doesn't quite work because some people have to enforce 32-bit access |
184 | */ | |
bedc0c31 AB |
185 | static void bank_reads8(void __iomem *src_base, u32 src_offset, u32 bank_addr, |
186 | __u32 *dst, u32 bytes) | |
db11e47d | 187 | { |
bedc0c31 | 188 | __u32 __iomem *src; |
db11e47d | 189 | u32 val; |
bedc0c31 AB |
190 | __u8 *src_byteptr; |
191 | __u8 *dst_byteptr; | |
db11e47d | 192 | |
bedc0c31 | 193 | src = src_base + (bank_addr | src_offset); |
db11e47d | 194 | |
bedc0c31 AB |
195 | if (src_offset < PAYLOAD_OFFSET) { |
196 | while (bytes >= 4) { | |
197 | *dst = le32_to_cpu(__raw_readl(src)); | |
198 | bytes -= 4; | |
199 | src++; | |
200 | dst++; | |
201 | } | |
202 | } else { | |
203 | while (bytes >= 4) { | |
204 | *dst = __raw_readl(src); | |
205 | bytes -= 4; | |
206 | src++; | |
207 | dst++; | |
208 | } | |
db11e47d SS |
209 | } |
210 | ||
bedc0c31 | 211 | if (!bytes) |
db11e47d SS |
212 | return; |
213 | ||
214 | /* in case we have 3, 2 or 1 by left. The dst buffer may not be fully | |
215 | * allocated. | |
216 | */ | |
bedc0c31 AB |
217 | if (src_offset < PAYLOAD_OFFSET) |
218 | val = le32_to_cpu(__raw_readl(src)); | |
219 | else | |
220 | val = __raw_readl(src); | |
221 | ||
222 | dst_byteptr = (void *) dst; | |
223 | src_byteptr = (void *) &val; | |
224 | while (bytes > 0) { | |
225 | *dst_byteptr = *src_byteptr; | |
226 | dst_byteptr++; | |
227 | src_byteptr++; | |
228 | bytes--; | |
db11e47d SS |
229 | } |
230 | } | |
231 | ||
bedc0c31 AB |
232 | static void mem_reads8(void __iomem *src_base, u32 src_offset, void *dst, |
233 | u32 bytes) | |
db11e47d | 234 | { |
bedc0c31 AB |
235 | reg_write32(src_base, HC_MEMORY_REG, src_offset + ISP_BANK(0)); |
236 | ndelay(90); | |
237 | bank_reads8(src_base, src_offset, ISP_BANK(0), dst, bytes); | |
238 | } | |
239 | ||
240 | static void mem_writes8(void __iomem *dst_base, u32 dst_offset, | |
241 | __u32 const *src, u32 bytes) | |
242 | { | |
243 | __u32 __iomem *dst; | |
244 | ||
245 | dst = dst_base + dst_offset; | |
246 | ||
247 | if (dst_offset < PAYLOAD_OFFSET) { | |
248 | while (bytes >= 4) { | |
249 | __raw_writel(cpu_to_le32(*src), dst); | |
250 | bytes -= 4; | |
251 | src++; | |
252 | dst++; | |
253 | } | |
254 | } else { | |
255 | while (bytes >= 4) { | |
256 | __raw_writel(*src, dst); | |
257 | bytes -= 4; | |
258 | src++; | |
259 | dst++; | |
260 | } | |
db11e47d SS |
261 | } |
262 | ||
bedc0c31 | 263 | if (!bytes) |
db11e47d | 264 | return; |
bedc0c31 AB |
265 | /* in case we have 3, 2 or 1 bytes left. The buffer is allocated and the |
266 | * extra bytes should not be read by the HW. | |
db11e47d SS |
267 | */ |
268 | ||
bedc0c31 AB |
269 | if (dst_offset < PAYLOAD_OFFSET) |
270 | __raw_writel(cpu_to_le32(*src), dst); | |
271 | else | |
272 | __raw_writel(*src, dst); | |
db11e47d SS |
273 | } |
274 | ||
bedc0c31 AB |
275 | /* |
276 | * Read and write ptds. 'ptd_offset' should be one of ISO_PTD_OFFSET, | |
277 | * INT_PTD_OFFSET, and ATL_PTD_OFFSET. 'slot' should be less than 32. | |
278 | */ | |
279 | static void ptd_read(void __iomem *base, u32 ptd_offset, u32 slot, | |
280 | struct ptd *ptd) | |
281 | { | |
282 | reg_write32(base, HC_MEMORY_REG, | |
283 | ISP_BANK(0) + ptd_offset + slot*sizeof(*ptd)); | |
284 | ndelay(90); | |
285 | bank_reads8(base, ptd_offset + slot*sizeof(*ptd), ISP_BANK(0), | |
286 | (void *) ptd, sizeof(*ptd)); | |
287 | } | |
288 | ||
289 | static void ptd_write(void __iomem *base, u32 ptd_offset, u32 slot, | |
290 | struct ptd *ptd) | |
291 | { | |
292 | mem_writes8(base, ptd_offset + slot*sizeof(*ptd) + sizeof(ptd->dw0), | |
293 | &ptd->dw1, 7*sizeof(ptd->dw1)); | |
294 | /* Make sure dw0 gets written last (after other dw's and after payload) | |
295 | since it contains the enable bit */ | |
296 | wmb(); | |
297 | mem_writes8(base, ptd_offset + slot*sizeof(*ptd), &ptd->dw0, | |
298 | sizeof(ptd->dw0)); | |
299 | } | |
300 | ||
301 | ||
db11e47d SS |
302 | /* memory management of the 60kb on the chip from 0x1000 to 0xffff */ |
303 | static void init_memory(struct isp1760_hcd *priv) | |
304 | { | |
a041d8e4 AB |
305 | int i, curr; |
306 | u32 payload_addr; | |
db11e47d | 307 | |
a041d8e4 | 308 | payload_addr = PAYLOAD_OFFSET; |
db11e47d | 309 | for (i = 0; i < BLOCK_1_NUM; i++) { |
a041d8e4 | 310 | priv->memory_pool[i].start = payload_addr; |
db11e47d SS |
311 | priv->memory_pool[i].size = BLOCK_1_SIZE; |
312 | priv->memory_pool[i].free = 1; | |
a041d8e4 | 313 | payload_addr += priv->memory_pool[i].size; |
db11e47d SS |
314 | } |
315 | ||
a041d8e4 AB |
316 | curr = i; |
317 | for (i = 0; i < BLOCK_2_NUM; i++) { | |
318 | priv->memory_pool[curr + i].start = payload_addr; | |
319 | priv->memory_pool[curr + i].size = BLOCK_2_SIZE; | |
320 | priv->memory_pool[curr + i].free = 1; | |
321 | payload_addr += priv->memory_pool[curr + i].size; | |
db11e47d SS |
322 | } |
323 | ||
a041d8e4 AB |
324 | curr = i; |
325 | for (i = 0; i < BLOCK_3_NUM; i++) { | |
326 | priv->memory_pool[curr + i].start = payload_addr; | |
327 | priv->memory_pool[curr + i].size = BLOCK_3_SIZE; | |
328 | priv->memory_pool[curr + i].free = 1; | |
329 | payload_addr += priv->memory_pool[curr + i].size; | |
db11e47d SS |
330 | } |
331 | ||
34537731 | 332 | WARN_ON(payload_addr - priv->memory_pool[0].start > PAYLOAD_AREA_SIZE); |
db11e47d SS |
333 | } |
334 | ||
6bda21bc | 335 | static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd) |
db11e47d | 336 | { |
6bda21bc | 337 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
db11e47d SS |
338 | int i; |
339 | ||
34537731 | 340 | WARN_ON(qtd->payload_addr); |
a041d8e4 AB |
341 | |
342 | if (!qtd->length) | |
343 | return; | |
db11e47d SS |
344 | |
345 | for (i = 0; i < BLOCKS; i++) { | |
a041d8e4 | 346 | if (priv->memory_pool[i].size >= qtd->length && |
db11e47d | 347 | priv->memory_pool[i].free) { |
db11e47d | 348 | priv->memory_pool[i].free = 0; |
a041d8e4 AB |
349 | qtd->payload_addr = priv->memory_pool[i].start; |
350 | return; | |
db11e47d SS |
351 | } |
352 | } | |
db11e47d SS |
353 | } |
354 | ||
6bda21bc | 355 | static void free_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd) |
db11e47d | 356 | { |
6bda21bc | 357 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
db11e47d SS |
358 | int i; |
359 | ||
a041d8e4 | 360 | if (!qtd->payload_addr) |
db11e47d SS |
361 | return; |
362 | ||
363 | for (i = 0; i < BLOCKS; i++) { | |
a041d8e4 | 364 | if (priv->memory_pool[i].start == qtd->payload_addr) { |
34537731 | 365 | WARN_ON(priv->memory_pool[i].free); |
db11e47d | 366 | priv->memory_pool[i].free = 1; |
a041d8e4 AB |
367 | qtd->payload_addr = 0; |
368 | return; | |
db11e47d SS |
369 | } |
370 | } | |
371 | ||
6bda21bc AB |
372 | dev_err(hcd->self.controller, "%s: Invalid pointer: %08x\n", |
373 | __func__, qtd->payload_addr); | |
71a9f9d2 AB |
374 | WARN_ON(1); |
375 | qtd->payload_addr = 0; | |
db11e47d SS |
376 | } |
377 | ||
bedc0c31 | 378 | static int handshake(struct usb_hcd *hcd, u32 reg, |
db11e47d SS |
379 | u32 mask, u32 done, int usec) |
380 | { | |
381 | u32 result; | |
382 | ||
383 | do { | |
bedc0c31 | 384 | result = reg_read32(hcd->regs, reg); |
db11e47d SS |
385 | if (result == ~0) |
386 | return -ENODEV; | |
387 | result &= mask; | |
388 | if (result == done) | |
389 | return 0; | |
390 | udelay(1); | |
391 | usec--; | |
392 | } while (usec > 0); | |
393 | return -ETIMEDOUT; | |
394 | } | |
395 | ||
396 | /* reset a non-running (STS_HALT == 1) controller */ | |
6bda21bc | 397 | static int ehci_reset(struct usb_hcd *hcd) |
db11e47d SS |
398 | { |
399 | int retval; | |
6bda21bc AB |
400 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
401 | ||
bedc0c31 | 402 | u32 command = reg_read32(hcd->regs, HC_USBCMD); |
db11e47d SS |
403 | |
404 | command |= CMD_RESET; | |
bedc0c31 | 405 | reg_write32(hcd->regs, HC_USBCMD, command); |
db11e47d SS |
406 | hcd->state = HC_STATE_HALT; |
407 | priv->next_statechange = jiffies; | |
bedc0c31 | 408 | retval = handshake(hcd, HC_USBCMD, |
db11e47d SS |
409 | CMD_RESET, 0, 250 * 1000); |
410 | return retval; | |
411 | } | |
412 | ||
71a9f9d2 | 413 | static struct isp1760_qh *qh_alloc(gfp_t flags) |
db11e47d SS |
414 | { |
415 | struct isp1760_qh *qh; | |
416 | ||
417 | qh = kmem_cache_zalloc(qh_cachep, flags); | |
418 | if (!qh) | |
71a9f9d2 | 419 | return NULL; |
db11e47d | 420 | |
71a9f9d2 | 421 | INIT_LIST_HEAD(&qh->qh_list); |
db11e47d | 422 | INIT_LIST_HEAD(&qh->qtd_list); |
71a9f9d2 AB |
423 | qh->slot = -1; |
424 | ||
db11e47d SS |
425 | return qh; |
426 | } | |
427 | ||
71a9f9d2 AB |
428 | static void qh_free(struct isp1760_qh *qh) |
429 | { | |
430 | WARN_ON(!list_empty(&qh->qtd_list)); | |
431 | WARN_ON(qh->slot > -1); | |
432 | kmem_cache_free(qh_cachep, qh); | |
433 | } | |
db11e47d SS |
434 | |
435 | /* one-time init, only for memory state */ | |
436 | static int priv_init(struct usb_hcd *hcd) | |
437 | { | |
438 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
439 | u32 hcc_params; | |
e08f6a27 | 440 | int i; |
db11e47d SS |
441 | |
442 | spin_lock_init(&priv->lock); | |
443 | ||
e08f6a27 AB |
444 | for (i = 0; i < QH_END; i++) |
445 | INIT_LIST_HEAD(&priv->qh_list[i]); | |
71a9f9d2 | 446 | |
db11e47d SS |
447 | /* |
448 | * hw default: 1K periodic list heads, one per frame. | |
449 | * periodic_size can shrink by USBCMD update if hcc_params allows. | |
450 | */ | |
451 | priv->periodic_size = DEFAULT_I_TDPS; | |
452 | ||
453 | /* controllers may cache some of the periodic schedule ... */ | |
bedc0c31 | 454 | hcc_params = reg_read32(hcd->regs, HC_HCCPARAMS); |
db11e47d SS |
455 | /* full frame cache */ |
456 | if (HCC_ISOC_CACHE(hcc_params)) | |
457 | priv->i_thresh = 8; | |
458 | else /* N microframes cached */ | |
459 | priv->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); | |
460 | ||
461 | return 0; | |
462 | } | |
463 | ||
464 | static int isp1760_hc_setup(struct usb_hcd *hcd) | |
465 | { | |
466 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
467 | int result; | |
3faefc88 NC |
468 | u32 scratch, hwmode; |
469 | ||
bedc0c31 | 470 | reg_write32(hcd->regs, HC_SCRATCH_REG, 0xdeadbabe); |
3faefc88 | 471 | /* Change bus pattern */ |
bedc0c31 AB |
472 | scratch = reg_read32(hcd->regs, HC_CHIP_ID_REG); |
473 | scratch = reg_read32(hcd->regs, HC_SCRATCH_REG); | |
db11e47d | 474 | if (scratch != 0xdeadbabe) { |
6bda21bc | 475 | dev_err(hcd->self.controller, "Scratch test failed.\n"); |
db11e47d SS |
476 | return -ENODEV; |
477 | } | |
478 | ||
5171446a LP |
479 | /* |
480 | * The RESET_HC bit in the SW_RESET register is supposed to reset the | |
481 | * host controller without touching the CPU interface registers, but at | |
482 | * least on the ISP1761 it seems to behave as the RESET_ALL bit and | |
483 | * reset the whole device. We thus can't use it here, so let's reset | |
484 | * the host controller through the EHCI USB Command register. The device | |
485 | * has been reset in core code anyway, so this shouldn't matter. | |
486 | */ | |
71a9f9d2 AB |
487 | reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, 0); |
488 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); | |
489 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); | |
490 | reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); | |
db11e47d | 491 | |
6bda21bc | 492 | result = ehci_reset(hcd); |
db11e47d SS |
493 | if (result) |
494 | return result; | |
495 | ||
496 | /* Step 11 passed */ | |
497 | ||
db11e47d | 498 | /* ATL reset */ |
5171446a | 499 | hwmode = reg_read32(hcd->regs, HC_HW_MODE_CTRL) & ~ALL_ATX_RESET; |
bedc0c31 | 500 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET); |
db11e47d | 501 | mdelay(10); |
bedc0c31 | 502 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode); |
db11e47d | 503 | |
bedc0c31 | 504 | reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, INTERRUPT_ENABLE_MASK); |
3faefc88 | 505 | |
bedc0c31 | 506 | priv->hcs_params = reg_read32(hcd->regs, HC_HCSPARAMS); |
db11e47d SS |
507 | |
508 | return priv_init(hcd); | |
509 | } | |
510 | ||
db11e47d SS |
511 | static u32 base_to_chip(u32 base) |
512 | { | |
513 | return ((base - 0x400) >> 3); | |
514 | } | |
515 | ||
7adc14b1 AB |
516 | static int last_qtd_of_urb(struct isp1760_qtd *qtd, struct isp1760_qh *qh) |
517 | { | |
518 | struct urb *urb; | |
519 | ||
520 | if (list_is_last(&qtd->qtd_list, &qh->qtd_list)) | |
521 | return 1; | |
522 | ||
523 | urb = qtd->urb; | |
524 | qtd = list_entry(qtd->qtd_list.next, typeof(*qtd), qtd_list); | |
525 | return (qtd->urb != urb); | |
526 | } | |
527 | ||
71a9f9d2 AB |
528 | /* magic numbers that can affect system performance */ |
529 | #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ | |
530 | #define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ | |
531 | #define EHCI_TUNE_RL_TT 0 | |
532 | #define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ | |
533 | #define EHCI_TUNE_MULT_TT 1 | |
534 | #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ | |
535 | ||
536 | static void create_ptd_atl(struct isp1760_qh *qh, | |
a041d8e4 | 537 | struct isp1760_qtd *qtd, struct ptd *ptd) |
db11e47d | 538 | { |
db11e47d SS |
539 | u32 maxpacket; |
540 | u32 multi; | |
db11e47d SS |
541 | u32 rl = RL_COUNTER; |
542 | u32 nak = NAK_COUNTER; | |
543 | ||
bedc0c31 AB |
544 | memset(ptd, 0, sizeof(*ptd)); |
545 | ||
db11e47d | 546 | /* according to 3.6.2, max packet len can not be > 0x400 */ |
a041d8e4 AB |
547 | maxpacket = usb_maxpacket(qtd->urb->dev, qtd->urb->pipe, |
548 | usb_pipeout(qtd->urb->pipe)); | |
db11e47d SS |
549 | multi = 1 + ((maxpacket >> 11) & 0x3); |
550 | maxpacket &= 0x7ff; | |
551 | ||
552 | /* DW0 */ | |
71a9f9d2 AB |
553 | ptd->dw0 = DW0_VALID_BIT; |
554 | ptd->dw0 |= TO_DW0_LENGTH(qtd->length); | |
555 | ptd->dw0 |= TO_DW0_MAXPACKET(maxpacket); | |
556 | ptd->dw0 |= TO_DW0_ENDPOINT(usb_pipeendpoint(qtd->urb->pipe)); | |
db11e47d SS |
557 | |
558 | /* DW1 */ | |
a041d8e4 | 559 | ptd->dw1 = usb_pipeendpoint(qtd->urb->pipe) >> 1; |
71a9f9d2 AB |
560 | ptd->dw1 |= TO_DW1_DEVICE_ADDR(usb_pipedevice(qtd->urb->pipe)); |
561 | ptd->dw1 |= TO_DW1_PID_TOKEN(qtd->packet_type); | |
db11e47d | 562 | |
a041d8e4 | 563 | if (usb_pipebulk(qtd->urb->pipe)) |
71a9f9d2 | 564 | ptd->dw1 |= DW1_TRANS_BULK; |
a041d8e4 | 565 | else if (usb_pipeint(qtd->urb->pipe)) |
71a9f9d2 | 566 | ptd->dw1 |= DW1_TRANS_INT; |
db11e47d | 567 | |
a041d8e4 | 568 | if (qtd->urb->dev->speed != USB_SPEED_HIGH) { |
db11e47d SS |
569 | /* split transaction */ |
570 | ||
71a9f9d2 | 571 | ptd->dw1 |= DW1_TRANS_SPLIT; |
a041d8e4 | 572 | if (qtd->urb->dev->speed == USB_SPEED_LOW) |
71a9f9d2 | 573 | ptd->dw1 |= DW1_SE_USB_LOSPEED; |
db11e47d | 574 | |
71a9f9d2 AB |
575 | ptd->dw1 |= TO_DW1_PORT_NUM(qtd->urb->dev->ttport); |
576 | ptd->dw1 |= TO_DW1_HUB_NUM(qtd->urb->dev->tt->hub->devnum); | |
db11e47d SS |
577 | |
578 | /* SE bit for Split INT transfers */ | |
a041d8e4 AB |
579 | if (usb_pipeint(qtd->urb->pipe) && |
580 | (qtd->urb->dev->speed == USB_SPEED_LOW)) | |
bedc0c31 | 581 | ptd->dw1 |= 2 << 16; |
db11e47d | 582 | |
db11e47d SS |
583 | rl = 0; |
584 | nak = 0; | |
585 | } else { | |
71a9f9d2 | 586 | ptd->dw0 |= TO_DW0_MULTI(multi); |
a041d8e4 AB |
587 | if (usb_pipecontrol(qtd->urb->pipe) || |
588 | usb_pipebulk(qtd->urb->pipe)) | |
71a9f9d2 | 589 | ptd->dw3 |= TO_DW3_PING(qh->ping); |
db11e47d SS |
590 | } |
591 | /* DW2 */ | |
bedc0c31 | 592 | ptd->dw2 = 0; |
71a9f9d2 AB |
593 | ptd->dw2 |= TO_DW2_DATA_START_ADDR(base_to_chip(qtd->payload_addr)); |
594 | ptd->dw2 |= TO_DW2_RL(rl); | |
db11e47d SS |
595 | |
596 | /* DW3 */ | |
71a9f9d2 AB |
597 | ptd->dw3 |= TO_DW3_NAKCOUNT(nak); |
598 | ptd->dw3 |= TO_DW3_DATA_TOGGLE(qh->toggle); | |
7adc14b1 AB |
599 | if (usb_pipecontrol(qtd->urb->pipe)) { |
600 | if (qtd->data_buffer == qtd->urb->setup_packet) | |
71a9f9d2 | 601 | ptd->dw3 &= ~TO_DW3_DATA_TOGGLE(1); |
7adc14b1 | 602 | else if (last_qtd_of_urb(qtd, qh)) |
71a9f9d2 | 603 | ptd->dw3 |= TO_DW3_DATA_TOGGLE(1); |
7adc14b1 | 604 | } |
db11e47d | 605 | |
71a9f9d2 | 606 | ptd->dw3 |= DW3_ACTIVE_BIT; |
db11e47d | 607 | /* Cerr */ |
71a9f9d2 | 608 | ptd->dw3 |= TO_DW3_CERR(ERR_COUNTER); |
db11e47d SS |
609 | } |
610 | ||
6bda21bc | 611 | static void transform_add_int(struct isp1760_qh *qh, |
a041d8e4 | 612 | struct isp1760_qtd *qtd, struct ptd *ptd) |
db11e47d | 613 | { |
65f1b525 | 614 | u32 usof; |
db11e47d SS |
615 | u32 period; |
616 | ||
65f1b525 AB |
617 | /* |
618 | * Most of this is guessing. ISP1761 datasheet is quite unclear, and | |
619 | * the algorithm from the original Philips driver code, which was | |
620 | * pretty much used in this driver before as well, is quite horrendous | |
621 | * and, i believe, incorrect. The code below follows the datasheet and | |
622 | * USB2.0 spec as far as I can tell, and plug/unplug seems to be much | |
623 | * more reliable this way (fingers crossed...). | |
624 | */ | |
db11e47d | 625 | |
65f1b525 AB |
626 | if (qtd->urb->dev->speed == USB_SPEED_HIGH) { |
627 | /* urb->interval is in units of microframes (1/8 ms) */ | |
628 | period = qtd->urb->interval >> 3; | |
629 | ||
630 | if (qtd->urb->interval > 4) | |
631 | usof = 0x01; /* One bit set => | |
632 | interval 1 ms * uFrame-match */ | |
633 | else if (qtd->urb->interval > 2) | |
634 | usof = 0x22; /* Two bits set => interval 1/2 ms */ | |
635 | else if (qtd->urb->interval > 1) | |
636 | usof = 0x55; /* Four bits set => interval 1/4 ms */ | |
db11e47d | 637 | else |
65f1b525 | 638 | usof = 0xff; /* All bits set => interval 1/8 ms */ |
db11e47d | 639 | } else { |
65f1b525 AB |
640 | /* urb->interval is in units of frames (1 ms) */ |
641 | period = qtd->urb->interval; | |
642 | usof = 0x0f; /* Execute Start Split on any of the | |
643 | four first uFrames */ | |
644 | ||
645 | /* | |
646 | * First 8 bits in dw5 is uSCS and "specifies which uSOF the | |
647 | * complete split needs to be sent. Valid only for IN." Also, | |
648 | * "All bits can be set to one for every transfer." (p 82, | |
649 | * ISP1761 data sheet.) 0x1c is from Philips driver. Where did | |
650 | * that number come from? 0xff seems to work fine... | |
651 | */ | |
652 | /* ptd->dw5 = 0x1c; */ | |
653 | ptd->dw5 = 0xff; /* Execute Complete Split on any uFrame */ | |
db11e47d SS |
654 | } |
655 | ||
65f1b525 AB |
656 | period = period >> 1;/* Ensure equal or shorter period than requested */ |
657 | period &= 0xf8; /* Mask off too large values and lowest unused 3 bits */ | |
658 | ||
bedc0c31 AB |
659 | ptd->dw2 |= period; |
660 | ptd->dw4 = usof; | |
db11e47d SS |
661 | } |
662 | ||
71a9f9d2 | 663 | static void create_ptd_int(struct isp1760_qh *qh, |
a041d8e4 | 664 | struct isp1760_qtd *qtd, struct ptd *ptd) |
db11e47d | 665 | { |
71a9f9d2 | 666 | create_ptd_atl(qh, qtd, ptd); |
6bda21bc | 667 | transform_add_int(qh, qtd, ptd); |
db11e47d SS |
668 | } |
669 | ||
6bda21bc | 670 | static void isp1760_urb_done(struct usb_hcd *hcd, struct urb *urb) |
db11e47d SS |
671 | __releases(priv->lock) |
672 | __acquires(priv->lock) | |
673 | { | |
6bda21bc AB |
674 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
675 | ||
db11e47d | 676 | if (!urb->unlinked) { |
6bda21bc AB |
677 | if (urb->status == -EINPROGRESS) |
678 | urb->status = 0; | |
db11e47d SS |
679 | } |
680 | ||
db8516f6 CM |
681 | if (usb_pipein(urb->pipe) && usb_pipetype(urb->pipe) != PIPE_CONTROL) { |
682 | void *ptr; | |
683 | for (ptr = urb->transfer_buffer; | |
684 | ptr < urb->transfer_buffer + urb->transfer_buffer_length; | |
685 | ptr += PAGE_SIZE) | |
686 | flush_dcache_page(virt_to_page(ptr)); | |
687 | } | |
688 | ||
db11e47d | 689 | /* complete() can reenter this HCD */ |
6bda21bc | 690 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
db11e47d | 691 | spin_unlock(&priv->lock); |
6bda21bc | 692 | usb_hcd_giveback_urb(hcd, urb, urb->status); |
db11e47d SS |
693 | spin_lock(&priv->lock); |
694 | } | |
695 | ||
34537731 AB |
696 | static struct isp1760_qtd *qtd_alloc(gfp_t flags, struct urb *urb, |
697 | u8 packet_type) | |
db11e47d | 698 | { |
34537731 AB |
699 | struct isp1760_qtd *qtd; |
700 | ||
701 | qtd = kmem_cache_zalloc(qtd_cachep, flags); | |
702 | if (!qtd) | |
703 | return NULL; | |
704 | ||
705 | INIT_LIST_HEAD(&qtd->qtd_list); | |
706 | qtd->urb = urb; | |
707 | qtd->packet_type = packet_type; | |
71a9f9d2 AB |
708 | qtd->status = QTD_ENQUEUED; |
709 | qtd->actual_length = 0; | |
34537731 AB |
710 | |
711 | return qtd; | |
712 | } | |
713 | ||
714 | static void qtd_free(struct isp1760_qtd *qtd) | |
715 | { | |
716 | WARN_ON(qtd->payload_addr); | |
db11e47d SS |
717 | kmem_cache_free(qtd_cachep, qtd); |
718 | } | |
719 | ||
71a9f9d2 | 720 | static void start_bus_transfer(struct usb_hcd *hcd, u32 ptd_offset, int slot, |
ea0b1fab LP |
721 | struct isp1760_slotinfo *slots, |
722 | struct isp1760_qtd *qtd, struct isp1760_qh *qh, | |
723 | struct ptd *ptd) | |
db11e47d | 724 | { |
71a9f9d2 | 725 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
d05b6ec0 AB |
726 | int skip_map; |
727 | ||
71a9f9d2 AB |
728 | WARN_ON((slot < 0) || (slot > 31)); |
729 | WARN_ON(qtd->length && !qtd->payload_addr); | |
730 | WARN_ON(slots[slot].qtd); | |
731 | WARN_ON(slots[slot].qh); | |
732 | WARN_ON(qtd->status != QTD_PAYLOAD_ALLOC); | |
733 | ||
d05b6ec0 AB |
734 | /* Make sure done map has not triggered from some unlinked transfer */ |
735 | if (ptd_offset == ATL_PTD_OFFSET) { | |
736 | priv->atl_done_map |= reg_read32(hcd->regs, | |
737 | HC_ATL_PTD_DONEMAP_REG); | |
6477acc0 AB |
738 | priv->atl_done_map &= ~(1 << slot); |
739 | } else { | |
740 | priv->int_done_map |= reg_read32(hcd->regs, | |
741 | HC_INT_PTD_DONEMAP_REG); | |
742 | priv->int_done_map &= ~(1 << slot); | |
743 | } | |
d05b6ec0 | 744 | |
6477acc0 AB |
745 | qh->slot = slot; |
746 | qtd->status = QTD_XFER_STARTED; | |
747 | slots[slot].timestamp = jiffies; | |
748 | slots[slot].qtd = qtd; | |
749 | slots[slot].qh = qh; | |
750 | ptd_write(hcd->regs, ptd_offset, slot, ptd); | |
751 | ||
752 | if (ptd_offset == ATL_PTD_OFFSET) { | |
d05b6ec0 AB |
753 | skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); |
754 | skip_map &= ~(1 << qh->slot); | |
755 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); | |
756 | } else { | |
d05b6ec0 AB |
757 | skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); |
758 | skip_map &= ~(1 << qh->slot); | |
759 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map); | |
760 | } | |
db11e47d SS |
761 | } |
762 | ||
71a9f9d2 | 763 | static int is_short_bulk(struct isp1760_qtd *qtd) |
db11e47d | 764 | { |
71a9f9d2 AB |
765 | return (usb_pipebulk(qtd->urb->pipe) && |
766 | (qtd->actual_length < qtd->length)); | |
db11e47d SS |
767 | } |
768 | ||
71a9f9d2 AB |
769 | static void collect_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh, |
770 | struct list_head *urb_list) | |
db11e47d | 771 | { |
71a9f9d2 AB |
772 | int last_qtd; |
773 | struct isp1760_qtd *qtd, *qtd_next; | |
774 | struct urb_listitem *urb_listitem; | |
db11e47d | 775 | |
71a9f9d2 AB |
776 | list_for_each_entry_safe(qtd, qtd_next, &qh->qtd_list, qtd_list) { |
777 | if (qtd->status < QTD_XFER_COMPLETE) | |
778 | break; | |
db11e47d | 779 | |
38679b72 | 780 | last_qtd = last_qtd_of_urb(qtd, qh); |
71a9f9d2 AB |
781 | |
782 | if ((!last_qtd) && (qtd->status == QTD_RETIRE)) | |
783 | qtd_next->status = QTD_RETIRE; | |
784 | ||
785 | if (qtd->status == QTD_XFER_COMPLETE) { | |
786 | if (qtd->actual_length) { | |
787 | switch (qtd->packet_type) { | |
788 | case IN_PID: | |
789 | mem_reads8(hcd->regs, qtd->payload_addr, | |
790 | qtd->data_buffer, | |
791 | qtd->actual_length); | |
792 | /* Fall through (?) */ | |
793 | case OUT_PID: | |
794 | qtd->urb->actual_length += | |
795 | qtd->actual_length; | |
796 | /* Fall through ... */ | |
797 | case SETUP_PID: | |
798 | break; | |
799 | } | |
800 | } | |
db11e47d | 801 | |
71a9f9d2 AB |
802 | if (is_short_bulk(qtd)) { |
803 | if (qtd->urb->transfer_flags & URB_SHORT_NOT_OK) | |
804 | qtd->urb->status = -EREMOTEIO; | |
805 | if (!last_qtd) | |
806 | qtd_next->status = QTD_RETIRE; | |
807 | } | |
808 | } | |
db11e47d | 809 | |
71a9f9d2 AB |
810 | if (qtd->payload_addr) |
811 | free_mem(hcd, qtd); | |
db11e47d | 812 | |
71a9f9d2 AB |
813 | if (last_qtd) { |
814 | if ((qtd->status == QTD_RETIRE) && | |
815 | (qtd->urb->status == -EINPROGRESS)) | |
816 | qtd->urb->status = -EPIPE; | |
817 | /* Defer calling of urb_done() since it releases lock */ | |
818 | urb_listitem = kmem_cache_zalloc(urb_listitem_cachep, | |
819 | GFP_ATOMIC); | |
820 | if (unlikely(!urb_listitem)) | |
38679b72 | 821 | break; /* Try again on next call */ |
71a9f9d2 AB |
822 | urb_listitem->urb = qtd->urb; |
823 | list_add_tail(&urb_listitem->urb_list, urb_list); | |
824 | } | |
847ed3e8 | 825 | |
71a9f9d2 AB |
826 | list_del(&qtd->qtd_list); |
827 | qtd_free(qtd); | |
828 | } | |
829 | } | |
3f02a957 | 830 | |
71a9f9d2 AB |
831 | #define ENQUEUE_DEPTH 2 |
832 | static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh) | |
833 | { | |
834 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
835 | int ptd_offset; | |
ea0b1fab | 836 | struct isp1760_slotinfo *slots; |
71a9f9d2 AB |
837 | int curr_slot, free_slot; |
838 | int n; | |
839 | struct ptd ptd; | |
840 | struct isp1760_qtd *qtd; | |
db11e47d | 841 | |
71a9f9d2 AB |
842 | if (unlikely(list_empty(&qh->qtd_list))) { |
843 | WARN_ON(1); | |
844 | return; | |
845 | } | |
db11e47d | 846 | |
74ad6029 AB |
847 | /* Make sure this endpoint's TT buffer is clean before queueing ptds */ |
848 | if (qh->tt_buffer_dirty) | |
849 | return; | |
850 | ||
71a9f9d2 AB |
851 | if (usb_pipeint(list_entry(qh->qtd_list.next, struct isp1760_qtd, |
852 | qtd_list)->urb->pipe)) { | |
853 | ptd_offset = INT_PTD_OFFSET; | |
854 | slots = priv->int_slots; | |
855 | } else { | |
856 | ptd_offset = ATL_PTD_OFFSET; | |
857 | slots = priv->atl_slots; | |
858 | } | |
db11e47d | 859 | |
71a9f9d2 AB |
860 | free_slot = -1; |
861 | for (curr_slot = 0; curr_slot < 32; curr_slot++) { | |
862 | if ((free_slot == -1) && (slots[curr_slot].qtd == NULL)) | |
863 | free_slot = curr_slot; | |
864 | if (slots[curr_slot].qh == qh) | |
865 | break; | |
866 | } | |
db11e47d | 867 | |
71a9f9d2 AB |
868 | n = 0; |
869 | list_for_each_entry(qtd, &qh->qtd_list, qtd_list) { | |
870 | if (qtd->status == QTD_ENQUEUED) { | |
871 | WARN_ON(qtd->payload_addr); | |
872 | alloc_mem(hcd, qtd); | |
873 | if ((qtd->length) && (!qtd->payload_addr)) | |
874 | break; | |
db11e47d | 875 | |
71a9f9d2 AB |
876 | if ((qtd->length) && |
877 | ((qtd->packet_type == SETUP_PID) || | |
878 | (qtd->packet_type == OUT_PID))) { | |
879 | mem_writes8(hcd->regs, qtd->payload_addr, | |
880 | qtd->data_buffer, qtd->length); | |
881 | } | |
db11e47d | 882 | |
71a9f9d2 | 883 | qtd->status = QTD_PAYLOAD_ALLOC; |
db11e47d SS |
884 | } |
885 | ||
71a9f9d2 AB |
886 | if (qtd->status == QTD_PAYLOAD_ALLOC) { |
887 | /* | |
888 | if ((curr_slot > 31) && (free_slot == -1)) | |
889 | dev_dbg(hcd->self.controller, "%s: No slot " | |
890 | "available for transfer\n", __func__); | |
891 | */ | |
892 | /* Start xfer for this endpoint if not already done */ | |
893 | if ((curr_slot > 31) && (free_slot > -1)) { | |
894 | if (usb_pipeint(qtd->urb->pipe)) | |
895 | create_ptd_int(qh, qtd, &ptd); | |
896 | else | |
897 | create_ptd_atl(qh, qtd, &ptd); | |
898 | ||
899 | start_bus_transfer(hcd, ptd_offset, free_slot, | |
900 | slots, qtd, qh, &ptd); | |
901 | curr_slot = free_slot; | |
902 | } | |
db11e47d | 903 | |
71a9f9d2 AB |
904 | n++; |
905 | if (n >= ENQUEUE_DEPTH) | |
906 | break; | |
907 | } | |
908 | } | |
909 | } | |
db11e47d | 910 | |
de9c6307 | 911 | static void schedule_ptds(struct usb_hcd *hcd) |
71a9f9d2 AB |
912 | { |
913 | struct isp1760_hcd *priv; | |
914 | struct isp1760_qh *qh, *qh_next; | |
915 | struct list_head *ep_queue; | |
71a9f9d2 AB |
916 | LIST_HEAD(urb_list); |
917 | struct urb_listitem *urb_listitem, *urb_listitem_next; | |
e08f6a27 | 918 | int i; |
71a9f9d2 AB |
919 | |
920 | if (!hcd) { | |
921 | WARN_ON(1); | |
922 | return; | |
923 | } | |
db11e47d | 924 | |
71a9f9d2 | 925 | priv = hcd_to_priv(hcd); |
db11e47d | 926 | |
71a9f9d2 AB |
927 | /* |
928 | * check finished/retired xfers, transfer payloads, call urb_done() | |
929 | */ | |
e08f6a27 AB |
930 | for (i = 0; i < QH_END; i++) { |
931 | ep_queue = &priv->qh_list[i]; | |
71a9f9d2 | 932 | list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) { |
71a9f9d2 | 933 | collect_qtds(hcd, qh, &urb_list); |
c64391f2 | 934 | if (list_empty(&qh->qtd_list)) |
71a9f9d2 | 935 | list_del(&qh->qh_list); |
db11e47d | 936 | } |
71a9f9d2 | 937 | } |
db11e47d | 938 | |
71a9f9d2 AB |
939 | list_for_each_entry_safe(urb_listitem, urb_listitem_next, &urb_list, |
940 | urb_list) { | |
941 | isp1760_urb_done(hcd, urb_listitem->urb); | |
942 | kmem_cache_free(urb_listitem_cachep, urb_listitem); | |
943 | } | |
db11e47d | 944 | |
71a9f9d2 AB |
945 | /* |
946 | * Schedule packets for transfer. | |
947 | * | |
948 | * According to USB2.0 specification: | |
949 | * | |
950 | * 1st prio: interrupt xfers, up to 80 % of bandwidth | |
951 | * 2nd prio: control xfers | |
952 | * 3rd prio: bulk xfers | |
953 | * | |
954 | * ... but let's use a simpler scheme here (mostly because ISP1761 doc | |
955 | * is very unclear on how to prioritize traffic): | |
956 | * | |
957 | * 1) Enqueue any queued control transfers, as long as payload chip mem | |
958 | * and PTD ATL slots are available. | |
959 | * 2) Enqueue any queued INT transfers, as long as payload chip mem | |
960 | * and PTD INT slots are available. | |
961 | * 3) Enqueue any queued bulk transfers, as long as payload chip mem | |
962 | * and PTD ATL slots are available. | |
963 | * | |
964 | * Use double buffering (ENQUEUE_DEPTH==2) as a compromise between | |
965 | * conservation of chip mem and performance. | |
966 | * | |
967 | * I'm sure this scheme could be improved upon! | |
968 | */ | |
e08f6a27 AB |
969 | for (i = 0; i < QH_END; i++) { |
970 | ep_queue = &priv->qh_list[i]; | |
71a9f9d2 AB |
971 | list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) |
972 | enqueue_qtds(hcd, qh); | |
71a9f9d2 AB |
973 | } |
974 | } | |
db11e47d | 975 | |
71a9f9d2 AB |
976 | #define PTD_STATE_QTD_DONE 1 |
977 | #define PTD_STATE_QTD_RELOAD 2 | |
978 | #define PTD_STATE_URB_RETIRE 3 | |
db11e47d | 979 | |
71a9f9d2 AB |
980 | static int check_int_transfer(struct usb_hcd *hcd, struct ptd *ptd, |
981 | struct urb *urb) | |
982 | { | |
983 | __dw dw4; | |
984 | int i; | |
db11e47d | 985 | |
71a9f9d2 AB |
986 | dw4 = ptd->dw4; |
987 | dw4 >>= 8; | |
db11e47d | 988 | |
71a9f9d2 AB |
989 | /* FIXME: ISP1761 datasheet does not say what to do with these. Do we |
990 | need to handle these errors? Is it done in hardware? */ | |
db11e47d | 991 | |
71a9f9d2 | 992 | if (ptd->dw3 & DW3_HALT_BIT) { |
db11e47d | 993 | |
71a9f9d2 | 994 | urb->status = -EPROTO; /* Default unknown error */ |
db11e47d | 995 | |
71a9f9d2 AB |
996 | for (i = 0; i < 8; i++) { |
997 | switch (dw4 & 0x7) { | |
998 | case INT_UNDERRUN: | |
999 | dev_dbg(hcd->self.controller, "%s: underrun " | |
1000 | "during uFrame %d\n", | |
1001 | __func__, i); | |
1002 | urb->status = -ECOMM; /* Could not write data */ | |
1003 | break; | |
1004 | case INT_EXACT: | |
1005 | dev_dbg(hcd->self.controller, "%s: transaction " | |
1006 | "error during uFrame %d\n", | |
1007 | __func__, i); | |
1008 | urb->status = -EPROTO; /* timeout, bad CRC, PID | |
1009 | error etc. */ | |
1010 | break; | |
1011 | case INT_BABBLE: | |
1012 | dev_dbg(hcd->self.controller, "%s: babble " | |
1013 | "error during uFrame %d\n", | |
1014 | __func__, i); | |
1015 | urb->status = -EOVERFLOW; | |
1016 | break; | |
1017 | } | |
1018 | dw4 >>= 3; | |
1019 | } | |
db11e47d | 1020 | |
71a9f9d2 AB |
1021 | return PTD_STATE_URB_RETIRE; |
1022 | } | |
db11e47d | 1023 | |
71a9f9d2 AB |
1024 | return PTD_STATE_QTD_DONE; |
1025 | } | |
db11e47d | 1026 | |
71a9f9d2 AB |
1027 | static int check_atl_transfer(struct usb_hcd *hcd, struct ptd *ptd, |
1028 | struct urb *urb) | |
1029 | { | |
1030 | WARN_ON(!ptd); | |
1031 | if (ptd->dw3 & DW3_HALT_BIT) { | |
1032 | if (ptd->dw3 & DW3_BABBLE_BIT) | |
1033 | urb->status = -EOVERFLOW; | |
1034 | else if (FROM_DW3_CERR(ptd->dw3)) | |
1035 | urb->status = -EPIPE; /* Stall */ | |
1036 | else if (ptd->dw3 & DW3_ERROR_BIT) | |
1037 | urb->status = -EPROTO; /* XactErr */ | |
1038 | else | |
1039 | urb->status = -EPROTO; /* Unknown */ | |
1040 | /* | |
1041 | dev_dbg(hcd->self.controller, "%s: ptd error:\n" | |
1042 | " dw0: %08x dw1: %08x dw2: %08x dw3: %08x\n" | |
1043 | " dw4: %08x dw5: %08x dw6: %08x dw7: %08x\n", | |
1044 | __func__, | |
1045 | ptd->dw0, ptd->dw1, ptd->dw2, ptd->dw3, | |
1046 | ptd->dw4, ptd->dw5, ptd->dw6, ptd->dw7); | |
1047 | */ | |
1048 | return PTD_STATE_URB_RETIRE; | |
1049 | } | |
db11e47d | 1050 | |
71a9f9d2 AB |
1051 | if ((ptd->dw3 & DW3_ERROR_BIT) && (ptd->dw3 & DW3_ACTIVE_BIT)) { |
1052 | /* Transfer Error, *but* active and no HALT -> reload */ | |
1053 | dev_dbg(hcd->self.controller, "PID error; reloading ptd\n"); | |
1054 | return PTD_STATE_QTD_RELOAD; | |
1055 | } | |
db11e47d | 1056 | |
71a9f9d2 AB |
1057 | if (!FROM_DW3_NAKCOUNT(ptd->dw3) && (ptd->dw3 & DW3_ACTIVE_BIT)) { |
1058 | /* | |
1059 | * NAKs are handled in HW by the chip. Usually if the | |
1060 | * device is not able to send data fast enough. | |
1061 | * This happens mostly on slower hardware. | |
1062 | */ | |
1063 | return PTD_STATE_QTD_RELOAD; | |
db11e47d | 1064 | } |
71a9f9d2 AB |
1065 | |
1066 | return PTD_STATE_QTD_DONE; | |
db11e47d SS |
1067 | } |
1068 | ||
6d50c60e | 1069 | static void handle_done_ptds(struct usb_hcd *hcd) |
db11e47d | 1070 | { |
bedc0c31 | 1071 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
db11e47d | 1072 | struct ptd ptd; |
db11e47d | 1073 | struct isp1760_qh *qh; |
71a9f9d2 AB |
1074 | int slot; |
1075 | int state; | |
ea0b1fab | 1076 | struct isp1760_slotinfo *slots; |
71a9f9d2 AB |
1077 | u32 ptd_offset; |
1078 | struct isp1760_qtd *qtd; | |
1079 | int modified; | |
6d50c60e | 1080 | int skip_map; |
71a9f9d2 | 1081 | |
6d50c60e AB |
1082 | skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); |
1083 | priv->int_done_map &= ~skip_map; | |
1084 | skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); | |
1085 | priv->atl_done_map &= ~skip_map; | |
71a9f9d2 | 1086 | |
6d50c60e | 1087 | modified = priv->int_done_map || priv->atl_done_map; |
d05b6ec0 AB |
1088 | |
1089 | while (priv->int_done_map || priv->atl_done_map) { | |
1090 | if (priv->int_done_map) { | |
71a9f9d2 | 1091 | /* INT ptd */ |
d05b6ec0 AB |
1092 | slot = __ffs(priv->int_done_map); |
1093 | priv->int_done_map &= ~(1 << slot); | |
71a9f9d2 | 1094 | slots = priv->int_slots; |
d05b6ec0 AB |
1095 | /* This should not trigger, and could be removed if |
1096 | noone have any problems with it triggering: */ | |
1097 | if (!slots[slot].qh) { | |
1098 | WARN_ON(1); | |
71a9f9d2 | 1099 | continue; |
d05b6ec0 | 1100 | } |
71a9f9d2 AB |
1101 | ptd_offset = INT_PTD_OFFSET; |
1102 | ptd_read(hcd->regs, INT_PTD_OFFSET, slot, &ptd); | |
1103 | state = check_int_transfer(hcd, &ptd, | |
1104 | slots[slot].qtd->urb); | |
db11e47d | 1105 | } else { |
71a9f9d2 | 1106 | /* ATL ptd */ |
d05b6ec0 AB |
1107 | slot = __ffs(priv->atl_done_map); |
1108 | priv->atl_done_map &= ~(1 << slot); | |
71a9f9d2 | 1109 | slots = priv->atl_slots; |
d05b6ec0 AB |
1110 | /* This should not trigger, and could be removed if |
1111 | noone have any problems with it triggering: */ | |
1112 | if (!slots[slot].qh) { | |
1113 | WARN_ON(1); | |
71a9f9d2 | 1114 | continue; |
d05b6ec0 | 1115 | } |
71a9f9d2 AB |
1116 | ptd_offset = ATL_PTD_OFFSET; |
1117 | ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd); | |
1118 | state = check_atl_transfer(hcd, &ptd, | |
1119 | slots[slot].qtd->urb); | |
db11e47d SS |
1120 | } |
1121 | ||
71a9f9d2 AB |
1122 | qtd = slots[slot].qtd; |
1123 | slots[slot].qtd = NULL; | |
1124 | qh = slots[slot].qh; | |
1125 | slots[slot].qh = NULL; | |
71a9f9d2 AB |
1126 | qh->slot = -1; |
1127 | ||
1128 | WARN_ON(qtd->status != QTD_XFER_STARTED); | |
1129 | ||
1130 | switch (state) { | |
1131 | case PTD_STATE_QTD_DONE: | |
1132 | if ((usb_pipeint(qtd->urb->pipe)) && | |
1133 | (qtd->urb->dev->speed != USB_SPEED_HIGH)) | |
1134 | qtd->actual_length = | |
1135 | FROM_DW3_SCS_NRBYTESTRANSFERRED(ptd.dw3); | |
1136 | else | |
1137 | qtd->actual_length = | |
1138 | FROM_DW3_NRBYTESTRANSFERRED(ptd.dw3); | |
db11e47d | 1139 | |
71a9f9d2 AB |
1140 | qtd->status = QTD_XFER_COMPLETE; |
1141 | if (list_is_last(&qtd->qtd_list, &qh->qtd_list) || | |
1142 | is_short_bulk(qtd)) | |
1143 | qtd = NULL; | |
1144 | else | |
1145 | qtd = list_entry(qtd->qtd_list.next, | |
1146 | typeof(*qtd), qtd_list); | |
db11e47d | 1147 | |
71a9f9d2 AB |
1148 | qh->toggle = FROM_DW3_DATA_TOGGLE(ptd.dw3); |
1149 | qh->ping = FROM_DW3_PING(ptd.dw3); | |
1150 | break; | |
db11e47d | 1151 | |
71a9f9d2 AB |
1152 | case PTD_STATE_QTD_RELOAD: /* QTD_RETRY, for atls only */ |
1153 | qtd->status = QTD_PAYLOAD_ALLOC; | |
1154 | ptd.dw0 |= DW0_VALID_BIT; | |
1155 | /* RL counter = ERR counter */ | |
1156 | ptd.dw3 &= ~TO_DW3_NAKCOUNT(0xf); | |
1157 | ptd.dw3 |= TO_DW3_NAKCOUNT(FROM_DW2_RL(ptd.dw2)); | |
1158 | ptd.dw3 &= ~TO_DW3_CERR(3); | |
1159 | ptd.dw3 |= TO_DW3_CERR(ERR_COUNTER); | |
1160 | qh->toggle = FROM_DW3_DATA_TOGGLE(ptd.dw3); | |
1161 | qh->ping = FROM_DW3_PING(ptd.dw3); | |
1162 | break; | |
db11e47d | 1163 | |
71a9f9d2 AB |
1164 | case PTD_STATE_URB_RETIRE: |
1165 | qtd->status = QTD_RETIRE; | |
74ad6029 AB |
1166 | if ((qtd->urb->dev->speed != USB_SPEED_HIGH) && |
1167 | (qtd->urb->status != -EPIPE) && | |
1168 | (qtd->urb->status != -EREMOTEIO)) { | |
1169 | qh->tt_buffer_dirty = 1; | |
1170 | if (usb_hub_clear_tt_buffer(qtd->urb)) | |
1171 | /* Clear failed; let's hope things work | |
1172 | anyway */ | |
1173 | qh->tt_buffer_dirty = 0; | |
1174 | } | |
71a9f9d2 AB |
1175 | qtd = NULL; |
1176 | qh->toggle = 0; | |
1177 | qh->ping = 0; | |
1178 | break; | |
db11e47d | 1179 | |
71a9f9d2 AB |
1180 | default: |
1181 | WARN_ON(1); | |
1182 | continue; | |
1183 | } | |
db11e47d | 1184 | |
71a9f9d2 AB |
1185 | if (qtd && (qtd->status == QTD_PAYLOAD_ALLOC)) { |
1186 | if (slots == priv->int_slots) { | |
1187 | if (state == PTD_STATE_QTD_RELOAD) | |
1188 | dev_err(hcd->self.controller, | |
1189 | "%s: PTD_STATE_QTD_RELOAD on " | |
1190 | "interrupt packet\n", __func__); | |
1191 | if (state != PTD_STATE_QTD_RELOAD) | |
1192 | create_ptd_int(qh, qtd, &ptd); | |
1193 | } else { | |
1194 | if (state != PTD_STATE_QTD_RELOAD) | |
1195 | create_ptd_atl(qh, qtd, &ptd); | |
1196 | } | |
db11e47d | 1197 | |
71a9f9d2 AB |
1198 | start_bus_transfer(hcd, ptd_offset, slot, slots, qtd, |
1199 | qh, &ptd); | |
1200 | } | |
1201 | } | |
db11e47d | 1202 | |
71a9f9d2 AB |
1203 | if (modified) |
1204 | schedule_ptds(hcd); | |
6d50c60e | 1205 | } |
db11e47d | 1206 | |
6d50c60e AB |
1207 | static irqreturn_t isp1760_irq(struct usb_hcd *hcd) |
1208 | { | |
1209 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
1210 | u32 imask; | |
1211 | irqreturn_t irqret = IRQ_NONE; | |
db11e47d | 1212 | |
6d50c60e AB |
1213 | spin_lock(&priv->lock); |
1214 | ||
1215 | if (!(hcd->state & HC_STATE_RUNNING)) | |
1216 | goto leave; | |
1217 | ||
1218 | imask = reg_read32(hcd->regs, HC_INTERRUPT_REG); | |
1219 | if (unlikely(!imask)) | |
1220 | goto leave; | |
1221 | reg_write32(hcd->regs, HC_INTERRUPT_REG, imask); /* Clear */ | |
1222 | ||
1223 | priv->int_done_map |= reg_read32(hcd->regs, HC_INT_PTD_DONEMAP_REG); | |
1224 | priv->atl_done_map |= reg_read32(hcd->regs, HC_ATL_PTD_DONEMAP_REG); | |
1225 | ||
1226 | handle_done_ptds(hcd); | |
db11e47d | 1227 | |
71a9f9d2 AB |
1228 | irqret = IRQ_HANDLED; |
1229 | leave: | |
1230 | spin_unlock(&priv->lock); | |
db11e47d | 1231 | |
71a9f9d2 | 1232 | return irqret; |
db11e47d SS |
1233 | } |
1234 | ||
6d50c60e AB |
1235 | /* |
1236 | * Workaround for problem described in chip errata 2: | |
1237 | * | |
1238 | * Sometimes interrupts are not generated when ATL (not INT?) completion occurs. | |
1239 | * One solution suggested in the errata is to use SOF interrupts _instead_of_ | |
1240 | * ATL done interrupts (the "instead of" might be important since it seems | |
1241 | * enabling ATL interrupts also causes the chip to sometimes - rarely - "forget" | |
1242 | * to set the PTD's done bit in addition to not generating an interrupt!). | |
1243 | * | |
1244 | * So if we use SOF + ATL interrupts, we sometimes get stale PTDs since their | |
1245 | * done bit is not being set. This is bad - it blocks the endpoint until reboot. | |
1246 | * | |
1247 | * If we use SOF interrupts only, we get latency between ptd completion and the | |
1248 | * actual handling. This is very noticeable in testusb runs which takes several | |
1249 | * minutes longer without ATL interrupts. | |
1250 | * | |
1251 | * A better solution is to run the code below every SLOT_CHECK_PERIOD ms. If it | |
1252 | * finds active ATL slots which are older than SLOT_TIMEOUT ms, it checks the | |
1253 | * slot's ACTIVE and VALID bits. If these are not set, the ptd is considered | |
1254 | * completed and its done map bit is set. | |
1255 | * | |
1256 | * The values of SLOT_TIMEOUT and SLOT_CHECK_PERIOD have been arbitrarily chosen | |
1257 | * not to cause too much lag when this HW bug occurs, while still hopefully | |
1258 | * ensuring that the check does not falsely trigger. | |
1259 | */ | |
6477acc0 | 1260 | #define SLOT_TIMEOUT 300 |
6d50c60e AB |
1261 | #define SLOT_CHECK_PERIOD 200 |
1262 | static struct timer_list errata2_timer; | |
1263 | ||
de9c6307 | 1264 | static void errata2_function(unsigned long data) |
6d50c60e AB |
1265 | { |
1266 | struct usb_hcd *hcd = (struct usb_hcd *) data; | |
1267 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
1268 | int slot; | |
1269 | struct ptd ptd; | |
1270 | unsigned long spinflags; | |
1271 | ||
1272 | spin_lock_irqsave(&priv->lock, spinflags); | |
1273 | ||
1274 | for (slot = 0; slot < 32; slot++) | |
6477acc0 AB |
1275 | if (priv->atl_slots[slot].qh && time_after(jiffies, |
1276 | priv->atl_slots[slot].timestamp + | |
4d3db7d7 | 1277 | msecs_to_jiffies(SLOT_TIMEOUT))) { |
6d50c60e AB |
1278 | ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd); |
1279 | if (!FROM_DW0_VALID(ptd.dw0) && | |
1280 | !FROM_DW3_ACTIVE(ptd.dw3)) | |
1281 | priv->atl_done_map |= 1 << slot; | |
1282 | } | |
1283 | ||
6477acc0 AB |
1284 | if (priv->atl_done_map) |
1285 | handle_done_ptds(hcd); | |
6d50c60e AB |
1286 | |
1287 | spin_unlock_irqrestore(&priv->lock, spinflags); | |
1288 | ||
4d3db7d7 | 1289 | errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD); |
6d50c60e AB |
1290 | add_timer(&errata2_timer); |
1291 | } | |
1292 | ||
0ba7905e AB |
1293 | static int isp1760_run(struct usb_hcd *hcd) |
1294 | { | |
1295 | int retval; | |
1296 | u32 temp; | |
1297 | u32 command; | |
1298 | u32 chipid; | |
1299 | ||
1300 | hcd->uses_new_polling = 1; | |
1301 | ||
1302 | hcd->state = HC_STATE_RUNNING; | |
1303 | ||
1304 | /* Set PTD interrupt AND & OR maps */ | |
1305 | reg_write32(hcd->regs, HC_ATL_IRQ_MASK_AND_REG, 0); | |
1306 | reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, 0xffffffff); | |
1307 | reg_write32(hcd->regs, HC_INT_IRQ_MASK_AND_REG, 0); | |
1308 | reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, 0xffffffff); | |
1309 | reg_write32(hcd->regs, HC_ISO_IRQ_MASK_AND_REG, 0); | |
1310 | reg_write32(hcd->regs, HC_ISO_IRQ_MASK_OR_REG, 0xffffffff); | |
1311 | /* step 23 passed */ | |
1312 | ||
1313 | temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL); | |
1314 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp | HW_GLOBAL_INTR_EN); | |
1315 | ||
1316 | command = reg_read32(hcd->regs, HC_USBCMD); | |
1317 | command &= ~(CMD_LRESET|CMD_RESET); | |
1318 | command |= CMD_RUN; | |
1319 | reg_write32(hcd->regs, HC_USBCMD, command); | |
1320 | ||
1321 | retval = handshake(hcd, HC_USBCMD, CMD_RUN, CMD_RUN, 250 * 1000); | |
1322 | if (retval) | |
1323 | return retval; | |
1324 | ||
1325 | /* | |
1326 | * XXX | |
1327 | * Spec says to write FLAG_CF as last config action, priv code grabs | |
1328 | * the semaphore while doing so. | |
1329 | */ | |
1330 | down_write(&ehci_cf_port_reset_rwsem); | |
1331 | reg_write32(hcd->regs, HC_CONFIGFLAG, FLAG_CF); | |
1332 | ||
1333 | retval = handshake(hcd, HC_CONFIGFLAG, FLAG_CF, FLAG_CF, 250 * 1000); | |
1334 | up_write(&ehci_cf_port_reset_rwsem); | |
1335 | if (retval) | |
1336 | return retval; | |
1337 | ||
b7aa4cc3 | 1338 | setup_timer(&errata2_timer, errata2_function, (unsigned long)hcd); |
4d3db7d7 | 1339 | errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD); |
6d50c60e AB |
1340 | add_timer(&errata2_timer); |
1341 | ||
0ba7905e AB |
1342 | chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG); |
1343 | dev_info(hcd->self.controller, "USB ISP %04x HW rev. %d started\n", | |
1344 | chipid & 0xffff, chipid >> 16); | |
1345 | ||
1346 | /* PTD Register Init Part 2, Step 28 */ | |
1347 | ||
1348 | /* Setup registers controlling PTD checking */ | |
1349 | reg_write32(hcd->regs, HC_ATL_PTD_LASTPTD_REG, 0x80000000); | |
1350 | reg_write32(hcd->regs, HC_INT_PTD_LASTPTD_REG, 0x80000000); | |
1351 | reg_write32(hcd->regs, HC_ISO_PTD_LASTPTD_REG, 0x00000001); | |
1352 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, 0xffffffff); | |
1353 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, 0xffffffff); | |
1354 | reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, 0xffffffff); | |
1355 | reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, | |
1356 | ATL_BUF_FILL | INT_BUF_FILL); | |
1357 | ||
1358 | /* GRR this is run-once init(), being done every time the HC starts. | |
1359 | * So long as they're part of class devices, we can't do it init() | |
1360 | * since the class device isn't created that early. | |
1361 | */ | |
1362 | return 0; | |
1363 | } | |
1364 | ||
34537731 | 1365 | static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len) |
db11e47d | 1366 | { |
34537731 | 1367 | qtd->data_buffer = databuffer; |
db11e47d | 1368 | |
34537731 AB |
1369 | if (len > MAX_PAYLOAD_SIZE) |
1370 | len = MAX_PAYLOAD_SIZE; | |
1371 | qtd->length = len; | |
db11e47d | 1372 | |
34537731 | 1373 | return qtd->length; |
db11e47d SS |
1374 | } |
1375 | ||
34537731 | 1376 | static void qtd_list_free(struct list_head *qtd_list) |
db11e47d | 1377 | { |
34537731 | 1378 | struct isp1760_qtd *qtd, *qtd_next; |
db11e47d | 1379 | |
34537731 | 1380 | list_for_each_entry_safe(qtd, qtd_next, qtd_list, qtd_list) { |
db11e47d | 1381 | list_del(&qtd->qtd_list); |
34537731 | 1382 | qtd_free(qtd); |
db11e47d SS |
1383 | } |
1384 | } | |
1385 | ||
db11e47d | 1386 | /* |
34537731 AB |
1387 | * Packetize urb->transfer_buffer into list of packets of size wMaxPacketSize. |
1388 | * Also calculate the PID type (SETUP/IN/OUT) for each packet. | |
db11e47d | 1389 | */ |
6bda21bc | 1390 | #define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) |
34537731 | 1391 | static void packetize_urb(struct usb_hcd *hcd, |
db11e47d SS |
1392 | struct urb *urb, struct list_head *head, gfp_t flags) |
1393 | { | |
fd436aee | 1394 | struct isp1760_qtd *qtd; |
db11e47d | 1395 | void *buf; |
34537731 AB |
1396 | int len, maxpacketsize; |
1397 | u8 packet_type; | |
db11e47d SS |
1398 | |
1399 | /* | |
1400 | * URBs map to sequences of QTDs: one logical transaction | |
1401 | */ | |
db11e47d | 1402 | |
34537731 AB |
1403 | if (!urb->transfer_buffer && urb->transfer_buffer_length) { |
1404 | /* XXX This looks like usb storage / SCSI bug */ | |
1405 | dev_err(hcd->self.controller, | |
1406 | "buf is null, dma is %08lx len is %d\n", | |
1407 | (long unsigned)urb->transfer_dma, | |
1408 | urb->transfer_buffer_length); | |
1409 | WARN_ON(1); | |
1410 | } | |
db11e47d | 1411 | |
34537731 AB |
1412 | if (usb_pipein(urb->pipe)) |
1413 | packet_type = IN_PID; | |
1414 | else | |
1415 | packet_type = OUT_PID; | |
db11e47d | 1416 | |
db11e47d | 1417 | if (usb_pipecontrol(urb->pipe)) { |
34537731 | 1418 | qtd = qtd_alloc(flags, urb, SETUP_PID); |
db11e47d SS |
1419 | if (!qtd) |
1420 | goto cleanup; | |
34537731 | 1421 | qtd_fill(qtd, urb->setup_packet, sizeof(struct usb_ctrlrequest)); |
db11e47d SS |
1422 | list_add_tail(&qtd->qtd_list, head); |
1423 | ||
1424 | /* for zero length DATA stages, STATUS is always IN */ | |
34537731 AB |
1425 | if (urb->transfer_buffer_length == 0) |
1426 | packet_type = IN_PID; | |
db11e47d SS |
1427 | } |
1428 | ||
34537731 AB |
1429 | maxpacketsize = max_packet(usb_maxpacket(urb->dev, urb->pipe, |
1430 | usb_pipeout(urb->pipe))); | |
db11e47d SS |
1431 | |
1432 | /* | |
1433 | * buffer gets wrapped in one or more qtds; | |
1434 | * last one may be "short" (including zero len) | |
1435 | * and may serve as a control status ack | |
1436 | */ | |
34537731 AB |
1437 | buf = urb->transfer_buffer; |
1438 | len = urb->transfer_buffer_length; | |
1439 | ||
db11e47d SS |
1440 | for (;;) { |
1441 | int this_qtd_len; | |
1442 | ||
34537731 AB |
1443 | qtd = qtd_alloc(flags, urb, packet_type); |
1444 | if (!qtd) | |
1445 | goto cleanup; | |
1446 | this_qtd_len = qtd_fill(qtd, buf, len); | |
1447 | list_add_tail(&qtd->qtd_list, head); | |
db11e47d | 1448 | |
db11e47d SS |
1449 | len -= this_qtd_len; |
1450 | buf += this_qtd_len; | |
1451 | ||
db11e47d SS |
1452 | if (len <= 0) |
1453 | break; | |
db11e47d SS |
1454 | } |
1455 | ||
1456 | /* | |
1457 | * control requests may need a terminating data "status" ack; | |
1458 | * bulk ones may need a terminating short packet (zero length). | |
1459 | */ | |
1460 | if (urb->transfer_buffer_length != 0) { | |
1461 | int one_more = 0; | |
1462 | ||
1463 | if (usb_pipecontrol(urb->pipe)) { | |
1464 | one_more = 1; | |
34537731 AB |
1465 | if (packet_type == IN_PID) |
1466 | packet_type = OUT_PID; | |
1467 | else | |
1468 | packet_type = IN_PID; | |
db11e47d SS |
1469 | } else if (usb_pipebulk(urb->pipe) |
1470 | && (urb->transfer_flags & URB_ZERO_PACKET) | |
34537731 AB |
1471 | && !(urb->transfer_buffer_length % |
1472 | maxpacketsize)) { | |
db11e47d SS |
1473 | one_more = 1; |
1474 | } | |
1475 | if (one_more) { | |
34537731 | 1476 | qtd = qtd_alloc(flags, urb, packet_type); |
db11e47d SS |
1477 | if (!qtd) |
1478 | goto cleanup; | |
db11e47d SS |
1479 | |
1480 | /* never any data in such packets */ | |
34537731 AB |
1481 | qtd_fill(qtd, NULL, 0); |
1482 | list_add_tail(&qtd->qtd_list, head); | |
db11e47d SS |
1483 | } |
1484 | } | |
1485 | ||
34537731 | 1486 | return; |
db11e47d SS |
1487 | |
1488 | cleanup: | |
34537731 AB |
1489 | qtd_list_free(head); |
1490 | } | |
1491 | ||
db11e47d SS |
1492 | static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, |
1493 | gfp_t mem_flags) | |
1494 | { | |
71a9f9d2 AB |
1495 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
1496 | struct list_head *ep_queue; | |
1497 | struct isp1760_qh *qh, *qhit; | |
1498 | unsigned long spinflags; | |
1499 | LIST_HEAD(new_qtds); | |
1500 | int retval; | |
1501 | int qh_in_queue; | |
db11e47d SS |
1502 | |
1503 | switch (usb_pipetype(urb->pipe)) { | |
1504 | case PIPE_CONTROL: | |
e08f6a27 | 1505 | ep_queue = &priv->qh_list[QH_CONTROL]; |
71a9f9d2 | 1506 | break; |
db11e47d | 1507 | case PIPE_BULK: |
e08f6a27 | 1508 | ep_queue = &priv->qh_list[QH_BULK]; |
db11e47d | 1509 | break; |
db11e47d | 1510 | case PIPE_INTERRUPT: |
71a9f9d2 AB |
1511 | if (urb->interval < 0) |
1512 | return -EINVAL; | |
1513 | /* FIXME: Check bandwidth */ | |
e08f6a27 | 1514 | ep_queue = &priv->qh_list[QH_INTERRUPT]; |
db11e47d | 1515 | break; |
db11e47d | 1516 | case PIPE_ISOCHRONOUS: |
71a9f9d2 AB |
1517 | dev_err(hcd->self.controller, "%s: isochronous USB packets " |
1518 | "not yet supported\n", | |
1519 | __func__); | |
1520 | return -EPIPE; | |
db11e47d | 1521 | default: |
71a9f9d2 AB |
1522 | dev_err(hcd->self.controller, "%s: unknown pipe type\n", |
1523 | __func__); | |
db11e47d SS |
1524 | return -EPIPE; |
1525 | } | |
1526 | ||
71a9f9d2 AB |
1527 | if (usb_pipein(urb->pipe)) |
1528 | urb->actual_length = 0; | |
db11e47d | 1529 | |
71a9f9d2 AB |
1530 | packetize_urb(hcd, urb, &new_qtds, mem_flags); |
1531 | if (list_empty(&new_qtds)) | |
1532 | return -ENOMEM; | |
db11e47d | 1533 | |
71a9f9d2 AB |
1534 | retval = 0; |
1535 | spin_lock_irqsave(&priv->lock, spinflags); | |
db11e47d | 1536 | |
71a9f9d2 AB |
1537 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { |
1538 | retval = -ESHUTDOWN; | |
8788fa03 | 1539 | qtd_list_free(&new_qtds); |
71a9f9d2 | 1540 | goto out; |
db11e47d | 1541 | } |
71a9f9d2 | 1542 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
8788fa03 MG |
1543 | if (retval) { |
1544 | qtd_list_free(&new_qtds); | |
71a9f9d2 | 1545 | goto out; |
8788fa03 | 1546 | } |
db11e47d | 1547 | |
71a9f9d2 AB |
1548 | qh = urb->ep->hcpriv; |
1549 | if (qh) { | |
1550 | qh_in_queue = 0; | |
1551 | list_for_each_entry(qhit, ep_queue, qh_list) { | |
1552 | if (qhit == qh) { | |
1553 | qh_in_queue = 1; | |
0afb20e0 | 1554 | break; |
71a9f9d2 AB |
1555 | } |
1556 | } | |
1557 | if (!qh_in_queue) | |
1558 | list_add_tail(&qh->qh_list, ep_queue); | |
1559 | } else { | |
1560 | qh = qh_alloc(GFP_ATOMIC); | |
1561 | if (!qh) { | |
1562 | retval = -ENOMEM; | |
38679b72 | 1563 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
8788fa03 | 1564 | qtd_list_free(&new_qtds); |
71a9f9d2 | 1565 | goto out; |
db11e47d | 1566 | } |
71a9f9d2 AB |
1567 | list_add_tail(&qh->qh_list, ep_queue); |
1568 | urb->ep->hcpriv = qh; | |
db11e47d SS |
1569 | } |
1570 | ||
71a9f9d2 AB |
1571 | list_splice_tail(&new_qtds, &qh->qtd_list); |
1572 | schedule_ptds(hcd); | |
1573 | ||
1574 | out: | |
1575 | spin_unlock_irqrestore(&priv->lock, spinflags); | |
1576 | return retval; | |
db11e47d SS |
1577 | } |
1578 | ||
d05b6ec0 AB |
1579 | static void kill_transfer(struct usb_hcd *hcd, struct urb *urb, |
1580 | struct isp1760_qh *qh) | |
1581 | { | |
1582 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
1583 | int skip_map; | |
1584 | ||
1585 | WARN_ON(qh->slot == -1); | |
1586 | ||
1587 | /* We need to forcefully reclaim the slot since some transfers never | |
1588 | return, e.g. interrupt transfers and NAKed bulk transfers. */ | |
8b1ab60c | 1589 | if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) { |
d05b6ec0 AB |
1590 | skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); |
1591 | skip_map |= (1 << qh->slot); | |
1592 | reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); | |
1593 | priv->atl_slots[qh->slot].qh = NULL; | |
1594 | priv->atl_slots[qh->slot].qtd = NULL; | |
1595 | } else { | |
1596 | skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); | |
1597 | skip_map |= (1 << qh->slot); | |
1598 | reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map); | |
1599 | priv->int_slots[qh->slot].qh = NULL; | |
1600 | priv->int_slots[qh->slot].qtd = NULL; | |
1601 | } | |
1602 | ||
1603 | qh->slot = -1; | |
d05b6ec0 AB |
1604 | } |
1605 | ||
74ad6029 AB |
1606 | /* |
1607 | * Retire the qtds beginning at 'qtd' and belonging all to the same urb, killing | |
1608 | * any active transfer belonging to the urb in the process. | |
1609 | */ | |
1610 | static void dequeue_urb_from_qtd(struct usb_hcd *hcd, struct isp1760_qh *qh, | |
1611 | struct isp1760_qtd *qtd) | |
1612 | { | |
1613 | struct urb *urb; | |
1614 | int urb_was_running; | |
1615 | ||
1616 | urb = qtd->urb; | |
1617 | urb_was_running = 0; | |
1618 | list_for_each_entry_from(qtd, &qh->qtd_list, qtd_list) { | |
1619 | if (qtd->urb != urb) | |
1620 | break; | |
1621 | ||
1622 | if (qtd->status >= QTD_XFER_STARTED) | |
1623 | urb_was_running = 1; | |
1624 | if (last_qtd_of_urb(qtd, qh) && | |
1625 | (qtd->status >= QTD_XFER_COMPLETE)) | |
1626 | urb_was_running = 0; | |
1627 | ||
1628 | if (qtd->status == QTD_XFER_STARTED) | |
1629 | kill_transfer(hcd, urb, qh); | |
1630 | qtd->status = QTD_RETIRE; | |
1631 | } | |
1632 | ||
1633 | if ((urb->dev->speed != USB_SPEED_HIGH) && urb_was_running) { | |
1634 | qh->tt_buffer_dirty = 1; | |
1635 | if (usb_hub_clear_tt_buffer(urb)) | |
1636 | /* Clear failed; let's hope things work anyway */ | |
1637 | qh->tt_buffer_dirty = 0; | |
1638 | } | |
1639 | } | |
1640 | ||
71a9f9d2 AB |
1641 | static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, |
1642 | int status) | |
db11e47d | 1643 | { |
6bda21bc | 1644 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
d05b6ec0 | 1645 | unsigned long spinflags; |
71a9f9d2 AB |
1646 | struct isp1760_qh *qh; |
1647 | struct isp1760_qtd *qtd; | |
71a9f9d2 | 1648 | int retval = 0; |
db11e47d | 1649 | |
71a9f9d2 | 1650 | spin_lock_irqsave(&priv->lock, spinflags); |
17d3e145 AB |
1651 | retval = usb_hcd_check_unlink_urb(hcd, urb, status); |
1652 | if (retval) | |
1653 | goto out; | |
db11e47d | 1654 | |
71a9f9d2 AB |
1655 | qh = urb->ep->hcpriv; |
1656 | if (!qh) { | |
1657 | retval = -EINVAL; | |
1658 | goto out; | |
1659 | } | |
db11e47d | 1660 | |
d05b6ec0 AB |
1661 | list_for_each_entry(qtd, &qh->qtd_list, qtd_list) |
1662 | if (qtd->urb == urb) { | |
74ad6029 | 1663 | dequeue_urb_from_qtd(hcd, qh, qtd); |
8cb22680 | 1664 | list_move(&qtd->qtd_list, &qh->qtd_list); |
74ad6029 | 1665 | break; |
d05b6ec0 | 1666 | } |
db11e47d | 1667 | |
71a9f9d2 AB |
1668 | urb->status = status; |
1669 | schedule_ptds(hcd); | |
db11e47d | 1670 | |
71a9f9d2 AB |
1671 | out: |
1672 | spin_unlock_irqrestore(&priv->lock, spinflags); | |
71a9f9d2 | 1673 | return retval; |
db11e47d SS |
1674 | } |
1675 | ||
079cdb09 AB |
1676 | static void isp1760_endpoint_disable(struct usb_hcd *hcd, |
1677 | struct usb_host_endpoint *ep) | |
1678 | { | |
1679 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
d05b6ec0 | 1680 | unsigned long spinflags; |
c64391f2 AB |
1681 | struct isp1760_qh *qh, *qh_iter; |
1682 | int i; | |
079cdb09 AB |
1683 | |
1684 | spin_lock_irqsave(&priv->lock, spinflags); | |
d05b6ec0 | 1685 | |
079cdb09 AB |
1686 | qh = ep->hcpriv; |
1687 | if (!qh) | |
1688 | goto out; | |
1689 | ||
c64391f2 | 1690 | WARN_ON(!list_empty(&qh->qtd_list)); |
d05b6ec0 | 1691 | |
c64391f2 AB |
1692 | for (i = 0; i < QH_END; i++) |
1693 | list_for_each_entry(qh_iter, &priv->qh_list[i], qh_list) | |
1694 | if (qh_iter == qh) { | |
1695 | list_del(&qh_iter->qh_list); | |
1696 | i = QH_END; | |
1697 | break; | |
1698 | } | |
1699 | qh_free(qh); | |
079cdb09 | 1700 | ep->hcpriv = NULL; |
079cdb09 | 1701 | |
d05b6ec0 AB |
1702 | schedule_ptds(hcd); |
1703 | ||
079cdb09 AB |
1704 | out: |
1705 | spin_unlock_irqrestore(&priv->lock, spinflags); | |
1706 | } | |
1707 | ||
db11e47d SS |
1708 | static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf) |
1709 | { | |
1710 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
1711 | u32 temp, status = 0; | |
1712 | u32 mask; | |
1713 | int retval = 1; | |
1714 | unsigned long flags; | |
1715 | ||
464ed18e | 1716 | /* if !PM, root hub timers won't get shut down ... */ |
db11e47d SS |
1717 | if (!HC_IS_RUNNING(hcd->state)) |
1718 | return 0; | |
1719 | ||
1720 | /* init status to no-changes */ | |
1721 | buf[0] = 0; | |
1722 | mask = PORT_CSC; | |
1723 | ||
1724 | spin_lock_irqsave(&priv->lock, flags); | |
bedc0c31 | 1725 | temp = reg_read32(hcd->regs, HC_PORTSC1); |
db11e47d SS |
1726 | |
1727 | if (temp & PORT_OWNER) { | |
1728 | if (temp & PORT_CSC) { | |
1729 | temp &= ~PORT_CSC; | |
bedc0c31 | 1730 | reg_write32(hcd->regs, HC_PORTSC1, temp); |
db11e47d SS |
1731 | goto done; |
1732 | } | |
1733 | } | |
1734 | ||
1735 | /* | |
1736 | * Return status information even for ports with OWNER set. | |
37ebb549 | 1737 | * Otherwise hub_wq wouldn't see the disconnect event when a |
db11e47d SS |
1738 | * high-speed device is switched over to the companion |
1739 | * controller by the user. | |
1740 | */ | |
1741 | ||
1742 | if ((temp & mask) != 0 | |
1743 | || ((temp & PORT_RESUME) != 0 | |
1744 | && time_after_eq(jiffies, | |
1745 | priv->reset_done))) { | |
1746 | buf [0] |= 1 << (0 + 1); | |
1747 | status = STS_PCD; | |
1748 | } | |
1749 | /* FIXME autosuspend idle root hubs */ | |
1750 | done: | |
1751 | spin_unlock_irqrestore(&priv->lock, flags); | |
1752 | return status ? retval : 0; | |
1753 | } | |
1754 | ||
1755 | static void isp1760_hub_descriptor(struct isp1760_hcd *priv, | |
1756 | struct usb_hub_descriptor *desc) | |
1757 | { | |
1758 | int ports = HCS_N_PORTS(priv->hcs_params); | |
1759 | u16 temp; | |
1760 | ||
1cf6563b | 1761 | desc->bDescriptorType = USB_DT_HUB; |
db11e47d SS |
1762 | /* priv 1.0, 2.3.9 says 20ms max */ |
1763 | desc->bPwrOn2PwrGood = 10; | |
1764 | desc->bHubContrCurrent = 0; | |
1765 | ||
1766 | desc->bNbrPorts = ports; | |
1767 | temp = 1 + (ports / 8); | |
1768 | desc->bDescLength = 7 + 2 * temp; | |
1769 | ||
da13051c | 1770 | /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */ |
dbe79bbe JY |
1771 | memset(&desc->u.hs.DeviceRemovable[0], 0, temp); |
1772 | memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); | |
db11e47d SS |
1773 | |
1774 | /* per-port overcurrent reporting */ | |
cc581c12 | 1775 | temp = HUB_CHAR_INDV_PORT_OCPM; |
db11e47d SS |
1776 | if (HCS_PPC(priv->hcs_params)) |
1777 | /* per-port power control */ | |
cc581c12 | 1778 | temp |= HUB_CHAR_INDV_PORT_LPSM; |
db11e47d SS |
1779 | else |
1780 | /* no power switching */ | |
cc581c12 | 1781 | temp |= HUB_CHAR_NO_LPSM; |
db11e47d SS |
1782 | desc->wHubCharacteristics = cpu_to_le16(temp); |
1783 | } | |
1784 | ||
1785 | #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) | |
1786 | ||
bedc0c31 AB |
1787 | static int check_reset_complete(struct usb_hcd *hcd, int index, |
1788 | int port_status) | |
db11e47d SS |
1789 | { |
1790 | if (!(port_status & PORT_CONNECT)) | |
1791 | return port_status; | |
1792 | ||
1793 | /* if reset finished and it's still not enabled -- handoff */ | |
1794 | if (!(port_status & PORT_PE)) { | |
1795 | ||
71a9f9d2 | 1796 | dev_info(hcd->self.controller, |
6bda21bc AB |
1797 | "port %d full speed --> companion\n", |
1798 | index + 1); | |
db11e47d SS |
1799 | |
1800 | port_status |= PORT_OWNER; | |
1801 | port_status &= ~PORT_RWC_BITS; | |
bedc0c31 | 1802 | reg_write32(hcd->regs, HC_PORTSC1, port_status); |
db11e47d SS |
1803 | |
1804 | } else | |
71a9f9d2 | 1805 | dev_info(hcd->self.controller, "port %d high speed\n", |
6bda21bc | 1806 | index + 1); |
db11e47d SS |
1807 | |
1808 | return port_status; | |
1809 | } | |
1810 | ||
1811 | static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, | |
1812 | u16 wValue, u16 wIndex, char *buf, u16 wLength) | |
1813 | { | |
1814 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
1815 | int ports = HCS_N_PORTS(priv->hcs_params); | |
db11e47d SS |
1816 | u32 temp, status; |
1817 | unsigned long flags; | |
1818 | int retval = 0; | |
1819 | unsigned selector; | |
1820 | ||
1821 | /* | |
1822 | * FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR. | |
1823 | * HCS_INDICATOR may say we can change LEDs to off/amber/green. | |
1824 | * (track current state ourselves) ... blink for diagnostics, | |
1825 | * power, "this is the one", etc. EHCI spec supports this. | |
1826 | */ | |
1827 | ||
1828 | spin_lock_irqsave(&priv->lock, flags); | |
1829 | switch (typeReq) { | |
1830 | case ClearHubFeature: | |
1831 | switch (wValue) { | |
1832 | case C_HUB_LOCAL_POWER: | |
1833 | case C_HUB_OVER_CURRENT: | |
1834 | /* no hub-wide feature/status flags */ | |
1835 | break; | |
1836 | default: | |
1837 | goto error; | |
1838 | } | |
1839 | break; | |
1840 | case ClearPortFeature: | |
1841 | if (!wIndex || wIndex > ports) | |
1842 | goto error; | |
1843 | wIndex--; | |
bedc0c31 | 1844 | temp = reg_read32(hcd->regs, HC_PORTSC1); |
db11e47d SS |
1845 | |
1846 | /* | |
1847 | * Even if OWNER is set, so the port is owned by the | |
37ebb549 | 1848 | * companion controller, hub_wq needs to be able to clear |
db11e47d | 1849 | * the port-change status bits (especially |
749da5f8 | 1850 | * USB_PORT_STAT_C_CONNECTION). |
db11e47d SS |
1851 | */ |
1852 | ||
1853 | switch (wValue) { | |
1854 | case USB_PORT_FEAT_ENABLE: | |
bedc0c31 | 1855 | reg_write32(hcd->regs, HC_PORTSC1, temp & ~PORT_PE); |
db11e47d SS |
1856 | break; |
1857 | case USB_PORT_FEAT_C_ENABLE: | |
1858 | /* XXX error? */ | |
1859 | break; | |
1860 | case USB_PORT_FEAT_SUSPEND: | |
1861 | if (temp & PORT_RESET) | |
1862 | goto error; | |
1863 | ||
1864 | if (temp & PORT_SUSPEND) { | |
1865 | if ((temp & PORT_PE) == 0) | |
1866 | goto error; | |
1867 | /* resume signaling for 20 msec */ | |
1868 | temp &= ~(PORT_RWC_BITS); | |
bedc0c31 AB |
1869 | reg_write32(hcd->regs, HC_PORTSC1, |
1870 | temp | PORT_RESUME); | |
db11e47d | 1871 | priv->reset_done = jiffies + |
59c9904c | 1872 | msecs_to_jiffies(USB_RESUME_TIMEOUT); |
db11e47d SS |
1873 | } |
1874 | break; | |
1875 | case USB_PORT_FEAT_C_SUSPEND: | |
1876 | /* we auto-clear this feature */ | |
1877 | break; | |
1878 | case USB_PORT_FEAT_POWER: | |
1879 | if (HCS_PPC(priv->hcs_params)) | |
bedc0c31 AB |
1880 | reg_write32(hcd->regs, HC_PORTSC1, |
1881 | temp & ~PORT_POWER); | |
db11e47d SS |
1882 | break; |
1883 | case USB_PORT_FEAT_C_CONNECTION: | |
bedc0c31 | 1884 | reg_write32(hcd->regs, HC_PORTSC1, temp | PORT_CSC); |
db11e47d SS |
1885 | break; |
1886 | case USB_PORT_FEAT_C_OVER_CURRENT: | |
1887 | /* XXX error ?*/ | |
1888 | break; | |
1889 | case USB_PORT_FEAT_C_RESET: | |
1890 | /* GetPortStatus clears reset */ | |
1891 | break; | |
1892 | default: | |
1893 | goto error; | |
1894 | } | |
bedc0c31 | 1895 | reg_read32(hcd->regs, HC_USBCMD); |
db11e47d SS |
1896 | break; |
1897 | case GetHubDescriptor: | |
1898 | isp1760_hub_descriptor(priv, (struct usb_hub_descriptor *) | |
1899 | buf); | |
1900 | break; | |
1901 | case GetHubStatus: | |
1902 | /* no hub-wide feature/status flags */ | |
1903 | memset(buf, 0, 4); | |
1904 | break; | |
1905 | case GetPortStatus: | |
1906 | if (!wIndex || wIndex > ports) | |
1907 | goto error; | |
1908 | wIndex--; | |
1909 | status = 0; | |
bedc0c31 | 1910 | temp = reg_read32(hcd->regs, HC_PORTSC1); |
db11e47d SS |
1911 | |
1912 | /* wPortChange bits */ | |
1913 | if (temp & PORT_CSC) | |
749da5f8 | 1914 | status |= USB_PORT_STAT_C_CONNECTION << 16; |
db11e47d SS |
1915 | |
1916 | ||
1917 | /* whoever resumes must GetPortStatus to complete it!! */ | |
1918 | if (temp & PORT_RESUME) { | |
6bda21bc | 1919 | dev_err(hcd->self.controller, "Port resume should be skipped.\n"); |
db11e47d SS |
1920 | |
1921 | /* Remote Wakeup received? */ | |
1922 | if (!priv->reset_done) { | |
1923 | /* resume signaling for 20 msec */ | |
1924 | priv->reset_done = jiffies | |
1925 | + msecs_to_jiffies(20); | |
1926 | /* check the port again */ | |
6bda21bc | 1927 | mod_timer(&hcd->rh_timer, priv->reset_done); |
db11e47d SS |
1928 | } |
1929 | ||
1930 | /* resume completed? */ | |
1931 | else if (time_after_eq(jiffies, | |
1932 | priv->reset_done)) { | |
749da5f8 | 1933 | status |= USB_PORT_STAT_C_SUSPEND << 16; |
db11e47d SS |
1934 | priv->reset_done = 0; |
1935 | ||
1936 | /* stop resume signaling */ | |
bedc0c31 AB |
1937 | temp = reg_read32(hcd->regs, HC_PORTSC1); |
1938 | reg_write32(hcd->regs, HC_PORTSC1, | |
1939 | temp & ~(PORT_RWC_BITS | PORT_RESUME)); | |
1940 | retval = handshake(hcd, HC_PORTSC1, | |
db11e47d SS |
1941 | PORT_RESUME, 0, 2000 /* 2msec */); |
1942 | if (retval != 0) { | |
6bda21bc | 1943 | dev_err(hcd->self.controller, |
db11e47d SS |
1944 | "port %d resume error %d\n", |
1945 | wIndex + 1, retval); | |
1946 | goto error; | |
1947 | } | |
1948 | temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); | |
1949 | } | |
1950 | } | |
1951 | ||
1952 | /* whoever resets must GetPortStatus to complete it!! */ | |
1953 | if ((temp & PORT_RESET) | |
1954 | && time_after_eq(jiffies, | |
1955 | priv->reset_done)) { | |
749da5f8 | 1956 | status |= USB_PORT_STAT_C_RESET << 16; |
db11e47d SS |
1957 | priv->reset_done = 0; |
1958 | ||
1959 | /* force reset to complete */ | |
bedc0c31 | 1960 | reg_write32(hcd->regs, HC_PORTSC1, temp & ~PORT_RESET); |
db11e47d SS |
1961 | /* REVISIT: some hardware needs 550+ usec to clear |
1962 | * this bit; seems too long to spin routinely... | |
1963 | */ | |
bedc0c31 | 1964 | retval = handshake(hcd, HC_PORTSC1, |
db11e47d SS |
1965 | PORT_RESET, 0, 750); |
1966 | if (retval != 0) { | |
6bda21bc | 1967 | dev_err(hcd->self.controller, "port %d reset error %d\n", |
db11e47d SS |
1968 | wIndex + 1, retval); |
1969 | goto error; | |
1970 | } | |
1971 | ||
1972 | /* see what we found out */ | |
bedc0c31 AB |
1973 | temp = check_reset_complete(hcd, wIndex, |
1974 | reg_read32(hcd->regs, HC_PORTSC1)); | |
db11e47d SS |
1975 | } |
1976 | /* | |
37ebb549 | 1977 | * Even if OWNER is set, there's no harm letting hub_wq |
db11e47d SS |
1978 | * see the wPortStatus values (they should all be 0 except |
1979 | * for PORT_POWER anyway). | |
1980 | */ | |
1981 | ||
1982 | if (temp & PORT_OWNER) | |
6bda21bc | 1983 | dev_err(hcd->self.controller, "PORT_OWNER is set\n"); |
db11e47d SS |
1984 | |
1985 | if (temp & PORT_CONNECT) { | |
749da5f8 | 1986 | status |= USB_PORT_STAT_CONNECTION; |
db11e47d | 1987 | /* status may be from integrated TT */ |
6bda21bc | 1988 | status |= USB_PORT_STAT_HIGH_SPEED; |
db11e47d SS |
1989 | } |
1990 | if (temp & PORT_PE) | |
749da5f8 | 1991 | status |= USB_PORT_STAT_ENABLE; |
db11e47d | 1992 | if (temp & (PORT_SUSPEND|PORT_RESUME)) |
749da5f8 | 1993 | status |= USB_PORT_STAT_SUSPEND; |
db11e47d | 1994 | if (temp & PORT_RESET) |
749da5f8 | 1995 | status |= USB_PORT_STAT_RESET; |
db11e47d | 1996 | if (temp & PORT_POWER) |
749da5f8 | 1997 | status |= USB_PORT_STAT_POWER; |
db11e47d SS |
1998 | |
1999 | put_unaligned(cpu_to_le32(status), (__le32 *) buf); | |
2000 | break; | |
2001 | case SetHubFeature: | |
2002 | switch (wValue) { | |
2003 | case C_HUB_LOCAL_POWER: | |
2004 | case C_HUB_OVER_CURRENT: | |
2005 | /* no hub-wide feature/status flags */ | |
2006 | break; | |
2007 | default: | |
2008 | goto error; | |
2009 | } | |
2010 | break; | |
2011 | case SetPortFeature: | |
2012 | selector = wIndex >> 8; | |
2013 | wIndex &= 0xff; | |
2014 | if (!wIndex || wIndex > ports) | |
2015 | goto error; | |
2016 | wIndex--; | |
bedc0c31 | 2017 | temp = reg_read32(hcd->regs, HC_PORTSC1); |
db11e47d SS |
2018 | if (temp & PORT_OWNER) |
2019 | break; | |
2020 | ||
2021 | /* temp &= ~PORT_RWC_BITS; */ | |
2022 | switch (wValue) { | |
2023 | case USB_PORT_FEAT_ENABLE: | |
bedc0c31 | 2024 | reg_write32(hcd->regs, HC_PORTSC1, temp | PORT_PE); |
db11e47d SS |
2025 | break; |
2026 | ||
2027 | case USB_PORT_FEAT_SUSPEND: | |
2028 | if ((temp & PORT_PE) == 0 | |
2029 | || (temp & PORT_RESET) != 0) | |
2030 | goto error; | |
2031 | ||
bedc0c31 | 2032 | reg_write32(hcd->regs, HC_PORTSC1, temp | PORT_SUSPEND); |
db11e47d SS |
2033 | break; |
2034 | case USB_PORT_FEAT_POWER: | |
2035 | if (HCS_PPC(priv->hcs_params)) | |
bedc0c31 AB |
2036 | reg_write32(hcd->regs, HC_PORTSC1, |
2037 | temp | PORT_POWER); | |
db11e47d SS |
2038 | break; |
2039 | case USB_PORT_FEAT_RESET: | |
2040 | if (temp & PORT_RESUME) | |
2041 | goto error; | |
2042 | /* line status bits may report this as low speed, | |
2043 | * which can be fine if this root hub has a | |
2044 | * transaction translator built in. | |
2045 | */ | |
2046 | if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT | |
2047 | && PORT_USB11(temp)) { | |
2048 | temp |= PORT_OWNER; | |
2049 | } else { | |
2050 | temp |= PORT_RESET; | |
2051 | temp &= ~PORT_PE; | |
2052 | ||
2053 | /* | |
2054 | * caller must wait, then call GetPortStatus | |
2055 | * usb 2.0 spec says 50 ms resets on root | |
2056 | */ | |
2057 | priv->reset_done = jiffies + | |
2058 | msecs_to_jiffies(50); | |
2059 | } | |
bedc0c31 | 2060 | reg_write32(hcd->regs, HC_PORTSC1, temp); |
db11e47d SS |
2061 | break; |
2062 | default: | |
2063 | goto error; | |
2064 | } | |
bedc0c31 | 2065 | reg_read32(hcd->regs, HC_USBCMD); |
db11e47d SS |
2066 | break; |
2067 | ||
2068 | default: | |
2069 | error: | |
2070 | /* "stall" on error */ | |
2071 | retval = -EPIPE; | |
2072 | } | |
2073 | spin_unlock_irqrestore(&priv->lock, flags); | |
2074 | return retval; | |
2075 | } | |
2076 | ||
db11e47d SS |
2077 | static int isp1760_get_frame(struct usb_hcd *hcd) |
2078 | { | |
2079 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
2080 | u32 fr; | |
2081 | ||
bedc0c31 | 2082 | fr = reg_read32(hcd->regs, HC_FRINDEX); |
db11e47d SS |
2083 | return (fr >> 3) % priv->periodic_size; |
2084 | } | |
2085 | ||
2086 | static void isp1760_stop(struct usb_hcd *hcd) | |
2087 | { | |
2088 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
3faefc88 | 2089 | u32 temp; |
db11e47d | 2090 | |
6d50c60e AB |
2091 | del_timer(&errata2_timer); |
2092 | ||
db11e47d SS |
2093 | isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, |
2094 | NULL, 0); | |
2095 | mdelay(20); | |
2096 | ||
2097 | spin_lock_irq(&priv->lock); | |
6bda21bc | 2098 | ehci_reset(hcd); |
db11e47d | 2099 | /* Disable IRQ */ |
bedc0c31 AB |
2100 | temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL); |
2101 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp &= ~HW_GLOBAL_INTR_EN); | |
db11e47d SS |
2102 | spin_unlock_irq(&priv->lock); |
2103 | ||
bedc0c31 | 2104 | reg_write32(hcd->regs, HC_CONFIGFLAG, 0); |
db11e47d SS |
2105 | } |
2106 | ||
2107 | static void isp1760_shutdown(struct usb_hcd *hcd) | |
2108 | { | |
3faefc88 | 2109 | u32 command, temp; |
db11e47d SS |
2110 | |
2111 | isp1760_stop(hcd); | |
bedc0c31 AB |
2112 | temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL); |
2113 | reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp &= ~HW_GLOBAL_INTR_EN); | |
db11e47d | 2114 | |
bedc0c31 | 2115 | command = reg_read32(hcd->regs, HC_USBCMD); |
db11e47d | 2116 | command &= ~CMD_RUN; |
bedc0c31 | 2117 | reg_write32(hcd->regs, HC_USBCMD, command); |
db11e47d SS |
2118 | } |
2119 | ||
74ad6029 AB |
2120 | static void isp1760_clear_tt_buffer_complete(struct usb_hcd *hcd, |
2121 | struct usb_host_endpoint *ep) | |
2122 | { | |
2123 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | |
2124 | struct isp1760_qh *qh = ep->hcpriv; | |
2125 | unsigned long spinflags; | |
2126 | ||
2127 | if (!qh) | |
2128 | return; | |
2129 | ||
2130 | spin_lock_irqsave(&priv->lock, spinflags); | |
2131 | qh->tt_buffer_dirty = 0; | |
2132 | schedule_ptds(hcd); | |
2133 | spin_unlock_irqrestore(&priv->lock, spinflags); | |
2134 | } | |
2135 | ||
2136 | ||
db11e47d SS |
2137 | static const struct hc_driver isp1760_hc_driver = { |
2138 | .description = "isp1760-hcd", | |
2139 | .product_desc = "NXP ISP1760 USB Host Controller", | |
cdd36e87 | 2140 | .hcd_priv_size = sizeof(struct isp1760_hcd *), |
db11e47d SS |
2141 | .irq = isp1760_irq, |
2142 | .flags = HCD_MEMORY | HCD_USB2, | |
2143 | .reset = isp1760_hc_setup, | |
2144 | .start = isp1760_run, | |
2145 | .stop = isp1760_stop, | |
2146 | .shutdown = isp1760_shutdown, | |
2147 | .urb_enqueue = isp1760_urb_enqueue, | |
2148 | .urb_dequeue = isp1760_urb_dequeue, | |
2149 | .endpoint_disable = isp1760_endpoint_disable, | |
2150 | .get_frame_number = isp1760_get_frame, | |
2151 | .hub_status_data = isp1760_hub_status_data, | |
2152 | .hub_control = isp1760_hub_control, | |
74ad6029 | 2153 | .clear_tt_buffer_complete = isp1760_clear_tt_buffer_complete, |
db11e47d SS |
2154 | }; |
2155 | ||
5a6356ac | 2156 | int __init isp1760_init_kmem_once(void) |
db11e47d | 2157 | { |
94011ec2 | 2158 | urb_listitem_cachep = kmem_cache_create("isp1760_urb_listitem", |
71a9f9d2 AB |
2159 | sizeof(struct urb_listitem), 0, SLAB_TEMPORARY | |
2160 | SLAB_MEM_SPREAD, NULL); | |
2161 | ||
2162 | if (!urb_listitem_cachep) | |
2163 | return -ENOMEM; | |
2164 | ||
db11e47d SS |
2165 | qtd_cachep = kmem_cache_create("isp1760_qtd", |
2166 | sizeof(struct isp1760_qtd), 0, SLAB_TEMPORARY | | |
2167 | SLAB_MEM_SPREAD, NULL); | |
2168 | ||
2169 | if (!qtd_cachep) | |
2170 | return -ENOMEM; | |
2171 | ||
2172 | qh_cachep = kmem_cache_create("isp1760_qh", sizeof(struct isp1760_qh), | |
2173 | 0, SLAB_TEMPORARY | SLAB_MEM_SPREAD, NULL); | |
2174 | ||
2175 | if (!qh_cachep) { | |
2176 | kmem_cache_destroy(qtd_cachep); | |
2177 | return -ENOMEM; | |
2178 | } | |
2179 | ||
2180 | return 0; | |
2181 | } | |
2182 | ||
5a6356ac | 2183 | void isp1760_deinit_kmem_cache(void) |
db11e47d SS |
2184 | { |
2185 | kmem_cache_destroy(qtd_cachep); | |
2186 | kmem_cache_destroy(qh_cachep); | |
71a9f9d2 | 2187 | kmem_cache_destroy(urb_listitem_cachep); |
db11e47d SS |
2188 | } |
2189 | ||
4b1a577d LP |
2190 | int isp1760_hcd_register(struct isp1760_hcd *priv, void __iomem *regs, |
2191 | struct resource *mem, int irq, unsigned long irqflags, | |
5171446a | 2192 | struct device *dev) |
db11e47d SS |
2193 | { |
2194 | struct usb_hcd *hcd; | |
db11e47d SS |
2195 | int ret; |
2196 | ||
0031a06e | 2197 | hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev_name(dev)); |
db11e47d | 2198 | if (!hcd) |
f0bdbb0e | 2199 | return -ENOMEM; |
db11e47d | 2200 | |
cdd36e87 LP |
2201 | *(struct isp1760_hcd **)hcd->hcd_priv = priv; |
2202 | ||
4b1a577d | 2203 | priv->hcd = hcd; |
db11e47d | 2204 | |
db11e47d | 2205 | init_memory(priv); |
db11e47d | 2206 | |
db11e47d | 2207 | hcd->irq = irq; |
4b1a577d | 2208 | hcd->regs = regs; |
4942e00e LP |
2209 | hcd->rsrc_start = mem->start; |
2210 | hcd->rsrc_len = resource_size(mem); | |
db11e47d | 2211 | |
074f9dd5 AS |
2212 | /* This driver doesn't support wakeup requests */ |
2213 | hcd->cant_recv_wakeups = 1; | |
2214 | ||
e6942d63 NC |
2215 | ret = usb_add_hcd(hcd, irq, irqflags); |
2216 | if (ret) | |
10feee14 | 2217 | goto error; |
e6942d63 | 2218 | |
3c9740a1 | 2219 | device_wakeup_enable(hcd->self.controller); |
e6942d63 | 2220 | |
f0bdbb0e | 2221 | return 0; |
db11e47d | 2222 | |
10feee14 | 2223 | error: |
30573751 | 2224 | usb_put_hcd(hcd); |
30573751 | 2225 | return ret; |
db11e47d | 2226 | } |
db11e47d | 2227 | |
4b1a577d | 2228 | void isp1760_hcd_unregister(struct isp1760_hcd *priv) |
10c73f09 | 2229 | { |
d21daf1e LP |
2230 | if (!priv->hcd) |
2231 | return; | |
db11e47d | 2232 | |
4b1a577d LP |
2233 | usb_remove_hcd(priv->hcd); |
2234 | usb_put_hcd(priv->hcd); | |
db11e47d | 2235 | } |