This source file includes following definitions.
- ehci_reverse_bits
- ehci_init
- ehci_intr
- ehci_intr1
- ehci_pcd_able
- ehci_pcd_enable
- ehci_pcd
- ehci_softintr
- ehci_check_intr
- ehci_idone
- ehci_waitintr
- ehci_poll
- ehci_detach
- ehci_activate
- ehci_power
- ehci_shutdown
- ehci_allocm
- ehci_freem
- ehci_allocx
- ehci_freex
- ehci_device_clear_toggle
- ehci_noop
- ehci_dump_regs
- ehci_dump
- ehci_dump_link
- ehci_dump_sqtds
- ehci_dump_sqtd
- ehci_dump_qtd
- ehci_dump_sqh
- ehci_dump_exfer
- ehci_open
- ehci_add_qh
- ehci_rem_qh
- ehci_set_qh_qtd
- ehci_sync_hc
- ehci_str
- ehci_root_ctrl_transfer
- ehci_root_ctrl_start
- ehci_disown
- ehci_root_ctrl_abort
- ehci_root_ctrl_close
- ehci_root_intr_done
- ehci_root_intr_transfer
- ehci_root_intr_start
- ehci_root_intr_abort
- ehci_root_intr_close
- ehci_root_ctrl_done
- ehci_alloc_sqh
- ehci_free_sqh
- ehci_alloc_sqtd
- ehci_free_sqtd
- ehci_alloc_sqtd_chain
- ehci_free_sqtd_chain
- ehci_close_pipe
- ehci_abort_xfer
- ehci_timeout
- ehci_timeout_task
- ehci_intrlist_timeout
- ehci_device_ctrl_transfer
- ehci_device_ctrl_start
- ehci_device_ctrl_done
- ehci_device_ctrl_abort
- ehci_device_ctrl_close
- ehci_device_request
- ehci_device_bulk_transfer
- ehci_device_bulk_start
- ehci_device_bulk_abort
- ehci_device_bulk_close
- ehci_device_bulk_done
- ehci_device_setintr
- ehci_device_intr_transfer
- ehci_device_intr_start
- ehci_device_intr_abort
- ehci_device_intr_close
- ehci_device_intr_done
- ehci_device_isoc_transfer
- ehci_device_isoc_start
- ehci_device_isoc_abort
- ehci_device_isoc_close
- ehci_device_isoc_done
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 #include <sys/param.h>
63 #include <sys/systm.h>
64 #include <sys/kernel.h>
65 #include <sys/rwlock.h>
66 #include <sys/malloc.h>
67 #include <sys/device.h>
68 #include <sys/selinfo.h>
69 #include <sys/proc.h>
70 #include <sys/queue.h>
71 #include <sys/timeout.h>
72
73 #include <machine/bus.h>
74 #include <machine/endian.h>
75
76 #include <dev/usb/usb.h>
77 #include <dev/usb/usbdi.h>
78 #include <dev/usb/usbdivar.h>
79 #include <dev/usb/usb_mem.h>
80 #include <dev/usb/usb_quirks.h>
81
82 #include <dev/usb/ehcireg.h>
83 #include <dev/usb/ehcivar.h>
84
85 #include <dev/rndvar.h>
86
87 struct cfdriver ehci_cd = {
88 NULL, "ehci", DV_DULL
89 };
90
91 #ifdef USB_DEBUG
92 #define EHCI_DEBUG
93 #endif
94
95 #ifdef EHCI_DEBUG
96 #define DPRINTF(x) do { if (ehcidebug) printf x; } while(0)
97 #define DPRINTFN(n,x) do { if (ehcidebug>(n)) printf x; } while (0)
98 int ehcidebug = 0;
99 #define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
100 #else
101 #define DPRINTF(x)
102 #define DPRINTFN(n,x)
103 #endif
104
105 #define mstohz(ms) ((ms) * hz / 1000)
106
107 struct ehci_pipe {
108 struct usbd_pipe pipe;
109
110 ehci_soft_qh_t *sqh;
111 union {
112 ehci_soft_qtd_t *qtd;
113
114 } tail;
115 union {
116
117 struct {
118 usb_dma_t reqdma;
119 u_int length;
120
121 } ctl;
122
123 struct {
124 u_int length;
125 } intr;
126
127 struct {
128 u_int length;
129 } bulk;
130
131
132 } u;
133 };
134
135 u_int8_t ehci_reverse_bits(u_int8_t, int);
136
137 void ehci_power(int, void *);
138
139 usbd_status ehci_open(usbd_pipe_handle);
140 void ehci_poll(struct usbd_bus *);
141 void ehci_softintr(void *);
142 int ehci_intr1(ehci_softc_t *);
143 void ehci_waitintr(ehci_softc_t *, usbd_xfer_handle);
144 void ehci_check_intr(ehci_softc_t *, struct ehci_xfer *);
145 void ehci_idone(struct ehci_xfer *);
146 void ehci_timeout(void *);
147 void ehci_timeout_task(void *);
148 void ehci_intrlist_timeout(void *);
149
150 usbd_status ehci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
151 void ehci_freem(struct usbd_bus *, usb_dma_t *);
152
153 usbd_xfer_handle ehci_allocx(struct usbd_bus *);
154 void ehci_freex(struct usbd_bus *, usbd_xfer_handle);
155
156 usbd_status ehci_root_ctrl_transfer(usbd_xfer_handle);
157 usbd_status ehci_root_ctrl_start(usbd_xfer_handle);
158 void ehci_root_ctrl_abort(usbd_xfer_handle);
159 void ehci_root_ctrl_close(usbd_pipe_handle);
160 void ehci_root_ctrl_done(usbd_xfer_handle);
161
162 usbd_status ehci_root_intr_transfer(usbd_xfer_handle);
163 usbd_status ehci_root_intr_start(usbd_xfer_handle);
164 void ehci_root_intr_abort(usbd_xfer_handle);
165 void ehci_root_intr_close(usbd_pipe_handle);
166 void ehci_root_intr_done(usbd_xfer_handle);
167
168 usbd_status ehci_device_ctrl_transfer(usbd_xfer_handle);
169 usbd_status ehci_device_ctrl_start(usbd_xfer_handle);
170 void ehci_device_ctrl_abort(usbd_xfer_handle);
171 void ehci_device_ctrl_close(usbd_pipe_handle);
172 void ehci_device_ctrl_done(usbd_xfer_handle);
173
174 usbd_status ehci_device_bulk_transfer(usbd_xfer_handle);
175 usbd_status ehci_device_bulk_start(usbd_xfer_handle);
176 void ehci_device_bulk_abort(usbd_xfer_handle);
177 void ehci_device_bulk_close(usbd_pipe_handle);
178 void ehci_device_bulk_done(usbd_xfer_handle);
179
180 usbd_status ehci_device_intr_transfer(usbd_xfer_handle);
181 usbd_status ehci_device_intr_start(usbd_xfer_handle);
182 void ehci_device_intr_abort(usbd_xfer_handle);
183 void ehci_device_intr_close(usbd_pipe_handle);
184 void ehci_device_intr_done(usbd_xfer_handle);
185
186 usbd_status ehci_device_isoc_transfer(usbd_xfer_handle);
187 usbd_status ehci_device_isoc_start(usbd_xfer_handle);
188 void ehci_device_isoc_abort(usbd_xfer_handle);
189 void ehci_device_isoc_close(usbd_pipe_handle);
190 void ehci_device_isoc_done(usbd_xfer_handle);
191
192 void ehci_device_clear_toggle(usbd_pipe_handle pipe);
193 void ehci_noop(usbd_pipe_handle pipe);
194
195 int ehci_str(usb_string_descriptor_t *, int, const char *);
196 void ehci_pcd(ehci_softc_t *, usbd_xfer_handle);
197 void ehci_pcd_able(ehci_softc_t *, int);
198 void ehci_pcd_enable(void *);
199 void ehci_disown(ehci_softc_t *, int, int);
200
201 ehci_soft_qh_t *ehci_alloc_sqh(ehci_softc_t *);
202 void ehci_free_sqh(ehci_softc_t *, ehci_soft_qh_t *);
203
204 ehci_soft_qtd_t *ehci_alloc_sqtd(ehci_softc_t *);
205 void ehci_free_sqtd(ehci_softc_t *, ehci_soft_qtd_t *);
206 usbd_status ehci_alloc_sqtd_chain(struct ehci_pipe *,
207 ehci_softc_t *, int, int, usbd_xfer_handle,
208 ehci_soft_qtd_t **, ehci_soft_qtd_t **);
209 void ehci_free_sqtd_chain(ehci_softc_t *, ehci_soft_qtd_t *,
210 ehci_soft_qtd_t *);
211
212 usbd_status ehci_device_request(usbd_xfer_handle xfer);
213
214 usbd_status ehci_device_setintr(ehci_softc_t *, ehci_soft_qh_t *,
215 int ival);
216
217 void ehci_add_qh(ehci_soft_qh_t *, ehci_soft_qh_t *);
218 void ehci_rem_qh(ehci_softc_t *, ehci_soft_qh_t *,
219 ehci_soft_qh_t *);
220 void ehci_set_qh_qtd(ehci_soft_qh_t *, ehci_soft_qtd_t *);
221 void ehci_sync_hc(ehci_softc_t *);
222
223 void ehci_close_pipe(usbd_pipe_handle, ehci_soft_qh_t *);
224 void ehci_abort_xfer(usbd_xfer_handle, usbd_status);
225
226 #ifdef EHCI_DEBUG
227 void ehci_dump_regs(ehci_softc_t *);
228 void ehci_dump(void);
229 ehci_softc_t *theehci;
230 void ehci_dump_link(ehci_link_t, int);
231 void ehci_dump_sqtds(ehci_soft_qtd_t *);
232 void ehci_dump_sqtd(ehci_soft_qtd_t *);
233 void ehci_dump_qtd(ehci_qtd_t *);
234 void ehci_dump_sqh(ehci_soft_qh_t *);
235 #ifdef DIAGNOSTIC
236 void ehci_dump_exfer(struct ehci_xfer *);
237 #endif
238 #endif
239
240 #define EHCI_NULL htole32(EHCI_LINK_TERMINATE)
241
242 #define EHCI_INTR_ENDPT 1
243
244 #define ehci_add_intr_list(sc, ex) \
245 LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ex), inext);
246 #define ehci_del_intr_list(ex) \
247 do { \
248 LIST_REMOVE((ex), inext); \
249 (ex)->inext.le_prev = NULL; \
250 } while (0)
251 #define ehci_active_intr_list(ex) ((ex)->inext.le_prev != NULL)
252
253 struct usbd_bus_methods ehci_bus_methods = {
254 ehci_open,
255 ehci_softintr,
256 ehci_poll,
257 ehci_allocm,
258 ehci_freem,
259 ehci_allocx,
260 ehci_freex,
261 };
262
263 struct usbd_pipe_methods ehci_root_ctrl_methods = {
264 ehci_root_ctrl_transfer,
265 ehci_root_ctrl_start,
266 ehci_root_ctrl_abort,
267 ehci_root_ctrl_close,
268 ehci_noop,
269 ehci_root_ctrl_done,
270 };
271
272 struct usbd_pipe_methods ehci_root_intr_methods = {
273 ehci_root_intr_transfer,
274 ehci_root_intr_start,
275 ehci_root_intr_abort,
276 ehci_root_intr_close,
277 ehci_noop,
278 ehci_root_intr_done,
279 };
280
281 struct usbd_pipe_methods ehci_device_ctrl_methods = {
282 ehci_device_ctrl_transfer,
283 ehci_device_ctrl_start,
284 ehci_device_ctrl_abort,
285 ehci_device_ctrl_close,
286 ehci_noop,
287 ehci_device_ctrl_done,
288 };
289
290 struct usbd_pipe_methods ehci_device_intr_methods = {
291 ehci_device_intr_transfer,
292 ehci_device_intr_start,
293 ehci_device_intr_abort,
294 ehci_device_intr_close,
295 ehci_device_clear_toggle,
296 ehci_device_intr_done,
297 };
298
299 struct usbd_pipe_methods ehci_device_bulk_methods = {
300 ehci_device_bulk_transfer,
301 ehci_device_bulk_start,
302 ehci_device_bulk_abort,
303 ehci_device_bulk_close,
304 ehci_device_clear_toggle,
305 ehci_device_bulk_done,
306 };
307
308 struct usbd_pipe_methods ehci_device_isoc_methods = {
309 ehci_device_isoc_transfer,
310 ehci_device_isoc_start,
311 ehci_device_isoc_abort,
312 ehci_device_isoc_close,
313 ehci_noop,
314 ehci_device_isoc_done,
315 };
316
317
318
319
320
321
322 u_int8_t
323 ehci_reverse_bits(u_int8_t c, int nbits)
324 {
325 c = ((c >> 1) & 0x55) | ((c << 1) & 0xaa);
326 c = ((c >> 2) & 0x33) | ((c << 2) & 0xcc);
327 c = ((c >> 4) & 0x0f) | ((c << 4) & 0xf0);
328
329 return c >> (8 - nbits);
330 }
331
332 usbd_status
333 ehci_init(ehci_softc_t *sc)
334 {
335 u_int32_t sparams, cparams, hcr;
336 u_int i, j;
337 usbd_status err;
338 ehci_soft_qh_t *sqh;
339
340 #ifdef EHCI_DEBUG
341 u_int32_t vers;
342 theehci = sc;
343
344 DPRINTF(("ehci_init: start\n"));
345
346 vers = EREAD2(sc, EHCI_HCIVERSION);
347 DPRINTF(("%s: EHCI version %x.%x\n", sc->sc_bus.bdev.dv_xname,
348 vers >> 8, vers & 0xff));
349 #endif
350
351 sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
352
353 sparams = EREAD4(sc, EHCI_HCSPARAMS);
354 DPRINTF(("ehci_init: sparams=0x%x\n", sparams));
355 sc->sc_noport = EHCI_HCS_N_PORTS(sparams);
356 cparams = EREAD4(sc, EHCI_HCCPARAMS);
357 DPRINTF(("ehci_init: cparams=0x%x\n", cparams));
358
359
360 if (EHCI_HCC_64BIT(cparams))
361 EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
362
363 sc->sc_bus.usbrev = USBREV_2_0;
364
365
366 DPRINTF(("%s: resetting\n", sc->sc_bus.bdev.dv_xname));
367 EOWRITE4(sc, EHCI_USBCMD, 0);
368 usb_delay_ms(&sc->sc_bus, 1);
369 EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
370 for (i = 0; i < 100; i++) {
371 usb_delay_ms(&sc->sc_bus, 1);
372 hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET;
373 if (!hcr)
374 break;
375 }
376 if (hcr) {
377 printf("%s: reset timeout\n",
378 sc->sc_bus.bdev.dv_xname);
379 return (USBD_IOERROR);
380 }
381
382
383 sc->sc_rand = 96;
384
385
386 switch (EHCI_CMD_FLS(EOREAD4(sc, EHCI_USBCMD))) {
387 case 0: sc->sc_flsize = 1024; break;
388 case 1: sc->sc_flsize = 512; break;
389 case 2: sc->sc_flsize = 256; break;
390 case 3: return (USBD_IOERROR);
391 }
392 err = usb_allocmem(&sc->sc_bus, sc->sc_flsize * sizeof(ehci_link_t),
393 EHCI_FLALIGN_ALIGN, &sc->sc_fldma);
394 if (err)
395 return (err);
396 DPRINTF(("%s: flsize=%d\n", sc->sc_bus.bdev.dv_xname,sc->sc_flsize));
397 sc->sc_flist = KERNADDR(&sc->sc_fldma, 0);
398 EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
399
400
401 sc->sc_bus.methods = &ehci_bus_methods;
402 sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
403
404 sc->sc_powerhook = powerhook_establish(ehci_power, sc);
405
406 sc->sc_eintrs = EHCI_NORMAL_INTRS;
407
408
409
410
411
412 for (i = 0; i < EHCI_INTRQHS; i++) {
413 sqh = ehci_alloc_sqh(sc);
414 if (sqh == NULL) {
415 err = USBD_NOMEM;
416 goto bad1;
417 }
418 sc->sc_islots[i].sqh = sqh;
419 }
420 for (i = 0; i < EHCI_INTRQHS; i++) {
421 sqh = sc->sc_islots[i].sqh;
422 if (i == 0) {
423
424 sqh->qh.qh_link = EHCI_NULL;
425 sqh->next = NULL;
426 } else {
427
428 sqh->next = sc->sc_islots[(i + 1) / 2 - 1].sqh;
429 sqh->qh.qh_link = htole32(sqh->next->physaddr |
430 EHCI_LINK_QH);
431 }
432 sqh->qh.qh_endp = htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH));
433 sqh->qh.qh_endphub = htole32(EHCI_QH_SET_MULT(1));
434 sqh->qh.qh_curqtd = EHCI_NULL;
435 sqh->qh.qh_qtd.qtd_next = EHCI_NULL;
436 sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
437 sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED);
438 sqh->sqtd = NULL;
439 }
440
441 for (i = 0; i < (1 << (EHCI_IPOLLRATES - 1)); i++)
442 for (j = i; j < sc->sc_flsize; j += 1 << (EHCI_IPOLLRATES - 1))
443 sc->sc_flist[j] = htole32(EHCI_LINK_QH | sc->sc_islots[
444 EHCI_IQHIDX(EHCI_IPOLLRATES - 1, ehci_reverse_bits(
445 i, EHCI_IPOLLRATES - 1))].sqh->physaddr);
446
447
448 sqh = ehci_alloc_sqh(sc);
449 if (sqh == NULL) {
450 err = USBD_NOMEM;
451 goto bad1;
452 }
453
454 sqh->qh.qh_endp =
455 htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL);
456 sqh->qh.qh_link =
457 htole32(sqh->physaddr | EHCI_LINK_QH);
458 sqh->qh.qh_curqtd = EHCI_NULL;
459 sqh->prev = sqh;
460 sqh->next = sqh;
461
462 sqh->qh.qh_qtd.qtd_next = EHCI_NULL;
463 sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
464 sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED);
465 sqh->sqtd = NULL;
466 #ifdef EHCI_DEBUG
467 if (ehcidebug)
468 ehci_dump_sqh(sqh);
469 #endif
470
471
472 sc->sc_async_head = sqh;
473 EOWRITE4(sc, EHCI_ASYNCLISTADDR, sqh->physaddr | EHCI_LINK_QH);
474
475 timeout_set(&sc->sc_tmo_pcd, NULL, NULL);
476 timeout_set(&sc->sc_tmo_intrlist, NULL, NULL);
477
478 rw_init(&sc->sc_doorbell_lock, "ehcidb");
479
480
481 EOWRITE4(sc, EHCI_USBCMD,
482 EHCI_CMD_ITC_2 |
483 (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |
484 EHCI_CMD_ASE |
485 EHCI_CMD_PSE |
486 EHCI_CMD_RS);
487
488
489 EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
490
491 for (i = 0; i < 100; i++) {
492 usb_delay_ms(&sc->sc_bus, 1);
493 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
494 if (!hcr)
495 break;
496 }
497 if (hcr) {
498 printf("%s: run timeout\n", sc->sc_bus.bdev.dv_xname);
499 return (USBD_IOERROR);
500 }
501
502
503 DPRINTFN(1,("ehci_init: enabling\n"));
504 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
505
506 return (USBD_NORMAL_COMPLETION);
507
508 #if 0
509 bad2:
510 ehci_free_sqh(sc, sc->sc_async_head);
511 #endif
512 bad1:
513 usb_freemem(&sc->sc_bus, &sc->sc_fldma);
514 return (err);
515 }
516
517 int
518 ehci_intr(void *v)
519 {
520 ehci_softc_t *sc = v;
521
522 if (sc == NULL || sc->sc_dying)
523 return (0);
524
525
526 if (sc->sc_bus.use_polling) {
527 u_int32_t intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
528
529 if (intrs)
530 EOWRITE4(sc, EHCI_USBSTS, intrs);
531 return (0);
532 }
533
534 return (ehci_intr1(sc));
535 }
536
537 int
538 ehci_intr1(ehci_softc_t *sc)
539 {
540 u_int32_t intrs, eintrs;
541
542 DPRINTFN(20,("ehci_intr1: enter\n"));
543
544
545 if (sc == NULL) {
546 #ifdef DIAGNOSTIC
547 printf("ehci_intr1: sc == NULL\n");
548 #endif
549 return (0);
550 }
551
552 intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
553 if (!intrs)
554 return (0);
555
556 eintrs = intrs & sc->sc_eintrs;
557 DPRINTFN(7, ("ehci_intr1: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n",
558 sc, (u_int)intrs, EOREAD4(sc, EHCI_USBSTS), (u_int)eintrs));
559 if (!eintrs)
560 return (0);
561
562 EOWRITE4(sc, EHCI_USBSTS, intrs);
563 sc->sc_bus.intr_context++;
564 sc->sc_bus.no_intrs++;
565 if (eintrs & EHCI_STS_IAA) {
566 DPRINTF(("ehci_intr1: door bell\n"));
567 wakeup(&sc->sc_async_head);
568 eintrs &= ~EHCI_STS_IAA;
569 }
570 if (eintrs & (EHCI_STS_INT | EHCI_STS_ERRINT)) {
571 DPRINTFN(5,("ehci_intr1: %s %s\n",
572 eintrs & EHCI_STS_INT ? "INT" : "",
573 eintrs & EHCI_STS_ERRINT ? "ERRINT" : ""));
574 usb_schedsoftintr(&sc->sc_bus);
575 eintrs &= ~(EHCI_STS_INT | EHCI_STS_ERRINT);
576 }
577 if (eintrs & EHCI_STS_HSE) {
578 printf("%s: unrecoverable error, controller halted\n",
579 sc->sc_bus.bdev.dv_xname);
580
581 }
582 if (eintrs & EHCI_STS_PCD) {
583 ehci_pcd(sc, sc->sc_intrxfer);
584
585
586
587
588 ehci_pcd_able(sc, 0);
589
590 timeout_del(&sc->sc_tmo_pcd);
591 timeout_set(&sc->sc_tmo_pcd, ehci_pcd_enable, sc);
592 timeout_add(&sc->sc_tmo_pcd, hz);
593 eintrs &= ~EHCI_STS_PCD;
594 }
595
596 sc->sc_bus.intr_context--;
597
598 if (eintrs != 0) {
599
600 sc->sc_eintrs &= ~eintrs;
601 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
602 printf("%s: blocking intrs 0x%x\n",
603 sc->sc_bus.bdev.dv_xname, eintrs);
604 }
605
606 return (1);
607 }
608
609 void
610 ehci_pcd_able(ehci_softc_t *sc, int on)
611 {
612 DPRINTFN(4, ("ehci_pcd_able: on=%d\n", on));
613 if (on)
614 sc->sc_eintrs |= EHCI_STS_PCD;
615 else
616 sc->sc_eintrs &= ~EHCI_STS_PCD;
617 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
618 }
619
620 void
621 ehci_pcd_enable(void *v_sc)
622 {
623 ehci_softc_t *sc = v_sc;
624
625 ehci_pcd_able(sc, 1);
626 }
627
628 void
629 ehci_pcd(ehci_softc_t *sc, usbd_xfer_handle xfer)
630 {
631 usbd_pipe_handle pipe;
632 u_char *p;
633 int i, m;
634
635 if (xfer == NULL) {
636
637 return;
638 }
639
640 pipe = xfer->pipe;
641
642 p = KERNADDR(&xfer->dmabuf, 0);
643 m = min(sc->sc_noport, xfer->length * 8 - 1);
644 memset(p, 0, xfer->length);
645 for (i = 1; i <= m; i++) {
646
647 if (EOREAD4(sc, EHCI_PORTSC(i)) & EHCI_PS_CLEAR)
648 p[i/8] |= 1 << (i%8);
649 }
650 DPRINTF(("ehci_pcd: change=0x%02x\n", *p));
651 xfer->actlen = xfer->length;
652 xfer->status = USBD_NORMAL_COMPLETION;
653
654 usb_transfer_complete(xfer);
655 }
656
657 void
658 ehci_softintr(void *v)
659 {
660 ehci_softc_t *sc = v;
661 struct ehci_xfer *ex, *nextex;
662
663 DPRINTFN(10,("%s: ehci_softintr (%d)\n", sc->sc_bus.bdev.dv_xname,
664 sc->sc_bus.intr_context));
665
666 sc->sc_bus.intr_context++;
667
668
669
670
671
672
673
674 for (ex = LIST_FIRST(&sc->sc_intrhead); ex; ex = nextex) {
675 nextex = LIST_NEXT(ex, inext);
676 ehci_check_intr(sc, ex);
677 }
678
679
680 if ((sc->sc_flags & EHCIF_DROPPED_INTR_WORKAROUND) &&
681 !LIST_EMPTY(&sc->sc_intrhead)) {
682 timeout_del(&sc->sc_tmo_intrlist);
683 timeout_set(&sc->sc_tmo_intrlist, ehci_intrlist_timeout, sc);
684 timeout_add(&sc->sc_tmo_intrlist, hz);
685 }
686
687 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
688 if (sc->sc_softwake) {
689 sc->sc_softwake = 0;
690 wakeup(&sc->sc_softwake);
691 }
692 #endif
693
694 sc->sc_bus.intr_context--;
695 }
696
697
698 void
699 ehci_check_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
700 {
701 ehci_soft_qtd_t *sqtd, *lsqtd;
702 u_int32_t status;
703
704 DPRINTFN(2, ("ehci_check_intr: ex=%p\n", ex));
705
706 if (ex->sqtdstart == NULL) {
707 printf("ehci_check_intr: sqtdstart=NULL\n");
708 return;
709 }
710 lsqtd = ex->sqtdend;
711 #ifdef DIAGNOSTIC
712 if (lsqtd == NULL) {
713 printf("ehci_check_intr: lsqtd==0\n");
714 return;
715 }
716 #endif
717
718
719
720
721
722 if (letoh32(lsqtd->qtd.qtd_status) & EHCI_QTD_ACTIVE) {
723 DPRINTFN(12, ("ehci_check_intr: active ex=%p\n", ex));
724 for (sqtd = ex->sqtdstart; sqtd != lsqtd; sqtd=sqtd->nextqtd) {
725 status = letoh32(sqtd->qtd.qtd_status);
726
727 if (status & EHCI_QTD_ACTIVE)
728 break;
729
730 if (status & EHCI_QTD_HALTED)
731 goto done;
732
733 if (EHCI_QTD_GET_BYTES(status) != 0)
734 goto done;
735 }
736 DPRINTFN(12, ("ehci_check_intr: ex=%p std=%p still active\n",
737 ex, ex->sqtdstart));
738 return;
739 }
740 done:
741 DPRINTFN(12, ("ehci_check_intr: ex=%p done\n", ex));
742 timeout_del(&ex->xfer.timeout_handle);
743 usb_rem_task(ex->xfer.pipe->device, &ex->abort_task);
744 ehci_idone(ex);
745 }
746
747 void
748 ehci_idone(struct ehci_xfer *ex)
749 {
750 usbd_xfer_handle xfer = &ex->xfer;
751 #ifdef EHCI_DEBUG
752 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
753 #endif
754 ehci_soft_qtd_t *sqtd, *lsqtd;
755 u_int32_t status = 0, nstatus = 0;
756 int actlen, cerr;
757
758 DPRINTFN(2, ("ehci_idone: ex=%p\n", ex));
759 #ifdef DIAGNOSTIC
760 {
761 int s = splhigh();
762 if (ex->isdone) {
763 splx(s);
764 #ifdef EHCI_DEBUG
765 printf("ehci_idone: ex is done!\n ");
766 ehci_dump_exfer(ex);
767 #else
768 printf("ehci_idone: ex=%p is done!\n", ex);
769 #endif
770 return;
771 }
772 ex->isdone = 1;
773 splx(s);
774 }
775 #endif
776
777 if (xfer->status == USBD_CANCELLED ||
778 xfer->status == USBD_TIMEOUT) {
779 DPRINTF(("ehci_idone: aborted xfer=%p\n", xfer));
780 return;
781 }
782
783 #ifdef EHCI_DEBUG
784 DPRINTFN(2, ("ehci_idone: xfer=%p, pipe=%p ready\n", xfer, epipe));
785 if (ehcidebug > 10)
786 ehci_dump_sqtds(ex->sqtdstart);
787 #endif
788
789
790 lsqtd = ex->sqtdend;
791 actlen = 0;
792 for (sqtd = ex->sqtdstart; sqtd != lsqtd->nextqtd;
793 sqtd = sqtd->nextqtd) {
794 nstatus = letoh32(sqtd->qtd.qtd_status);
795 if (nstatus & EHCI_QTD_ACTIVE)
796 break;
797
798 status = nstatus;
799
800 if (sqtd->qtd.qtd_next == EHCI_NULL &&
801 EHCI_QTD_GET_BYTES(status) == 0)
802 status &= ~EHCI_QTD_HALTED;
803 if (EHCI_QTD_GET_PID(status) != EHCI_QTD_PID_SETUP)
804 actlen += sqtd->len - EHCI_QTD_GET_BYTES(status);
805 }
806
807 cerr = EHCI_QTD_GET_CERR(status);
808 DPRINTFN(2, ("ehci_idone: len=%d, actlen=%d, cerr=%d, "
809 "status=0x%x\n", xfer->length, actlen, cerr, status));
810 xfer->actlen = actlen;
811 if ((status & EHCI_QTD_HALTED) != 0) {
812 #ifdef EHCI_DEBUG
813 char sbuf[128];
814
815 bitmask_snprintf((u_int32_t)status,
816 "\20\7HALTED\6BUFERR\5BABBLE\4XACTERR"
817 "\3MISSED\2SPLIT\1PING", sbuf, sizeof(sbuf));
818
819 DPRINTFN(2,
820 ("ehci_idone: error, addr=%d, endpt=0x%02x, "
821 "status 0x%s\n",
822 xfer->pipe->device->address,
823 xfer->pipe->endpoint->edesc->bEndpointAddress,
824 sbuf));
825 if (ehcidebug > 2) {
826 ehci_dump_sqh(epipe->sqh);
827 ehci_dump_sqtds(ex->sqtdstart);
828 }
829 #endif
830 if ((status & EHCI_QTD_BABBLE) == 0 && cerr > 0)
831 xfer->status = USBD_STALLED;
832 else
833 xfer->status = USBD_IOERROR;
834 } else
835 xfer->status = USBD_NORMAL_COMPLETION;
836
837 usb_transfer_complete(xfer);
838 DPRINTFN(2, ("ehci_idone: ex=%p done\n", ex));
839 }
840
841
842
843
844
845
846 void
847 ehci_waitintr(ehci_softc_t *sc, usbd_xfer_handle xfer)
848 {
849 int timo;
850 u_int32_t intrs;
851
852 xfer->status = USBD_IN_PROGRESS;
853 for (timo = xfer->timeout; timo >= 0; timo--) {
854 usb_delay_ms(&sc->sc_bus, 1);
855 if (sc->sc_dying)
856 break;
857 intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS)) &
858 sc->sc_eintrs;
859 DPRINTFN(15,("ehci_waitintr: 0x%04x\n", intrs));
860 #ifdef EHCI_DEBUG
861 if (ehcidebug > 15)
862 ehci_dump_regs(sc);
863 #endif
864 if (intrs) {
865 ehci_intr1(sc);
866 if (xfer->status != USBD_IN_PROGRESS)
867 return;
868 }
869 }
870
871
872 DPRINTF(("ehci_waitintr: timeout\n"));
873 xfer->status = USBD_TIMEOUT;
874 usb_transfer_complete(xfer);
875
876 }
877
878 void
879 ehci_poll(struct usbd_bus *bus)
880 {
881 ehci_softc_t *sc = (ehci_softc_t *)bus;
882 #ifdef EHCI_DEBUG
883 static int last;
884 int new;
885 new = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
886 if (new != last) {
887 DPRINTFN(10,("ehci_poll: intrs=0x%04x\n", new));
888 last = new;
889 }
890 #endif
891
892 if (EOREAD4(sc, EHCI_USBSTS) & sc->sc_eintrs)
893 ehci_intr1(sc);
894 }
895
896 int
897 ehci_detach(struct ehci_softc *sc, int flags)
898 {
899 int rv = 0;
900
901 if (sc->sc_child != NULL)
902 rv = config_detach(sc->sc_child, flags);
903
904 if (rv != 0)
905 return (rv);
906
907 timeout_del(&sc->sc_tmo_intrlist);
908 timeout_del(&sc->sc_tmo_pcd);
909
910 if (sc->sc_powerhook != NULL)
911 powerhook_disestablish(sc->sc_powerhook);
912 if (sc->sc_shutdownhook != NULL)
913 shutdownhook_disestablish(sc->sc_shutdownhook);
914
915 usb_delay_ms(&sc->sc_bus, 300);
916
917
918
919 return (rv);
920 }
921
922
923 int
924 ehci_activate(struct device *self, enum devact act)
925 {
926 struct ehci_softc *sc = (struct ehci_softc *)self;
927 int rv = 0;
928
929 switch (act) {
930 case DVACT_ACTIVATE:
931 break;
932
933 case DVACT_DEACTIVATE:
934 if (sc->sc_child != NULL)
935 rv = config_deactivate(sc->sc_child);
936 sc->sc_dying = 1;
937 break;
938 }
939 return (rv);
940 }
941
942
943
944
945
946
947
948
949 void
950 ehci_power(int why, void *v)
951 {
952 ehci_softc_t *sc = v;
953 u_int32_t cmd, hcr;
954 int s, i;
955
956 #ifdef EHCI_DEBUG
957 DPRINTF(("ehci_power: sc=%p, why=%d\n", sc, why));
958 if (ehcidebug > 0)
959 ehci_dump_regs(sc);
960 #endif
961
962 s = splhardusb();
963 switch (why) {
964 case PWR_SUSPEND:
965 case PWR_STANDBY:
966 sc->sc_bus.use_polling++;
967
968 for (i = 1; i <= sc->sc_noport; i++) {
969 cmd = EOREAD4(sc, EHCI_PORTSC(i));
970 if ((cmd & (EHCI_PS_PO|EHCI_PS_PE)) == EHCI_PS_PE)
971 EOWRITE4(sc, EHCI_PORTSC(i),
972 cmd | EHCI_PS_SUSP);
973 }
974
975 sc->sc_cmd = EOREAD4(sc, EHCI_USBCMD);
976 cmd = sc->sc_cmd & ~(EHCI_CMD_ASE | EHCI_CMD_PSE);
977 EOWRITE4(sc, EHCI_USBCMD, cmd);
978
979 for (i = 0; i < 100; i++) {
980 hcr = EOREAD4(sc, EHCI_USBSTS) &
981 (EHCI_STS_ASS | EHCI_STS_PSS);
982 if (hcr == 0)
983 break;
984
985 usb_delay_ms(&sc->sc_bus, 1);
986 }
987 if (hcr != 0)
988 printf("%s: reset timeout\n",
989 sc->sc_bus.bdev.dv_xname);
990
991 cmd &= ~EHCI_CMD_RS;
992 EOWRITE4(sc, EHCI_USBCMD, cmd);
993
994 for (i = 0; i < 100; i++) {
995 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
996 if (hcr == EHCI_STS_HCH)
997 break;
998
999 usb_delay_ms(&sc->sc_bus, 1);
1000 }
1001 if (hcr != EHCI_STS_HCH)
1002 printf("%s: config timeout\n",
1003 sc->sc_bus.bdev.dv_xname);
1004
1005 sc->sc_bus.use_polling--;
1006 break;
1007
1008 case PWR_RESUME:
1009 sc->sc_bus.use_polling++;
1010
1011
1012 EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
1013 EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
1014 EOWRITE4(sc, EHCI_ASYNCLISTADDR,
1015 sc->sc_async_head->physaddr | EHCI_LINK_QH);
1016 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
1017
1018 hcr = 0;
1019 for (i = 1; i <= sc->sc_noport; i++) {
1020 cmd = EOREAD4(sc, EHCI_PORTSC(i));
1021 if ((cmd & (EHCI_PS_PO|EHCI_PS_SUSP)) == EHCI_PS_SUSP) {
1022 EOWRITE4(sc, EHCI_PORTSC(i),
1023 cmd | EHCI_PS_FPR);
1024 hcr = 1;
1025 }
1026 }
1027
1028 if (hcr) {
1029 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
1030 for (i = 1; i <= sc->sc_noport; i++) {
1031 cmd = EOREAD4(sc, EHCI_PORTSC(i));
1032 if ((cmd & (EHCI_PS_PO|EHCI_PS_SUSP)) ==
1033 EHCI_PS_SUSP)
1034 EOWRITE4(sc, EHCI_PORTSC(i),
1035 cmd & ~EHCI_PS_FPR);
1036 }
1037 }
1038
1039 EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);
1040
1041
1042 EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
1043
1044 for (i = 0; i < 100; i++) {
1045 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
1046 if (hcr != EHCI_STS_HCH)
1047 break;
1048
1049 usb_delay_ms(&sc->sc_bus, 1);
1050 }
1051 if (hcr == EHCI_STS_HCH)
1052 printf("%s: config timeout\n",
1053 sc->sc_bus.bdev.dv_xname);
1054
1055 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
1056
1057 sc->sc_bus.use_polling--;
1058 break;
1059 }
1060 splx(s);
1061
1062 #ifdef EHCI_DEBUG
1063 DPRINTF(("ehci_power: sc=%p\n", sc));
1064 if (ehcidebug > 0)
1065 ehci_dump_regs(sc);
1066 #endif
1067 }
1068
1069
1070
1071
1072 void
1073 ehci_shutdown(void *v)
1074 {
1075 ehci_softc_t *sc = v;
1076
1077 DPRINTF(("ehci_shutdown: stopping the HC\n"));
1078 EOWRITE4(sc, EHCI_USBCMD, 0);
1079 EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
1080 }
1081
1082 usbd_status
1083 ehci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
1084 {
1085 struct ehci_softc *sc = (struct ehci_softc *)bus;
1086 usbd_status err;
1087
1088 err = usb_allocmem(&sc->sc_bus, size, 0, dma);
1089 #ifdef EHCI_DEBUG
1090 if (err)
1091 printf("ehci_allocm: usb_allocmem()=%d\n", err);
1092 #endif
1093 return (err);
1094 }
1095
1096 void
1097 ehci_freem(struct usbd_bus *bus, usb_dma_t *dma)
1098 {
1099 struct ehci_softc *sc = (struct ehci_softc *)bus;
1100
1101 usb_freemem(&sc->sc_bus, dma);
1102 }
1103
1104 usbd_xfer_handle
1105 ehci_allocx(struct usbd_bus *bus)
1106 {
1107 struct ehci_softc *sc = (struct ehci_softc *)bus;
1108 usbd_xfer_handle xfer;
1109
1110 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
1111 if (xfer != NULL) {
1112 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
1113 #ifdef DIAGNOSTIC
1114 if (xfer->busy_free != XFER_FREE)
1115 printf("ehci_allocx: xfer=%p not free, 0x%08x\n",
1116 xfer, xfer->busy_free);
1117 #endif
1118 } else
1119 xfer = malloc(sizeof(struct ehci_xfer), M_USB, M_NOWAIT);
1120
1121 if (xfer != NULL) {
1122 memset(xfer, 0, sizeof(struct ehci_xfer));
1123 usb_init_task(&EXFER(xfer)->abort_task, ehci_timeout_task,
1124 xfer);
1125 EXFER(xfer)->ehci_xfer_flags = 0;
1126 #ifdef DIAGNOSTIC
1127 EXFER(xfer)->isdone = 1;
1128 xfer->busy_free = XFER_BUSY;
1129 #endif
1130 }
1131 return (xfer);
1132 }
1133
1134 void
1135 ehci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
1136 {
1137 struct ehci_softc *sc = (struct ehci_softc *)bus;
1138
1139 #ifdef DIAGNOSTIC
1140 if (xfer->busy_free != XFER_BUSY) {
1141 printf("ehci_freex: xfer=%p not busy, 0x%08x\n", xfer,
1142 xfer->busy_free);
1143 return;
1144 }
1145 xfer->busy_free = XFER_FREE;
1146 if (!EXFER(xfer)->isdone) {
1147 printf("ehci_freex: !isdone\n");
1148 return;
1149 }
1150 #endif
1151 SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
1152 }
1153
1154 void
1155 ehci_device_clear_toggle(usbd_pipe_handle pipe)
1156 {
1157 struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
1158
1159 DPRINTF(("ehci_device_clear_toggle: epipe=%p status=0x%x\n",
1160 epipe, epipe->sqh->qh.qh_qtd.qtd_status));
1161 #ifdef USB_DEBUG
1162 if (ehcidebug)
1163 usbd_dump_pipe(pipe);
1164 #endif
1165 #ifdef DIAGNOSTIC
1166 if ((epipe->sqh->qh.qh_qtd.qtd_status & htole32(EHCI_QTD_ACTIVE)) != 0)
1167 panic("ehci_device_clear_toggle: queue active");
1168 #endif
1169 epipe->sqh->qh.qh_qtd.qtd_status &= htole32(~EHCI_QTD_TOGGLE_MASK);
1170 }
1171
1172 void
1173 ehci_noop(usbd_pipe_handle pipe)
1174 {
1175 }
1176
1177 #ifdef EHCI_DEBUG
1178 void
1179 ehci_dump_regs(ehci_softc_t *sc)
1180 {
1181 int i;
1182
1183 printf("cmd=0x%08x, sts=0x%08x, ien=0x%08x\n",
1184 EOREAD4(sc, EHCI_USBCMD),
1185 EOREAD4(sc, EHCI_USBSTS),
1186 EOREAD4(sc, EHCI_USBINTR));
1187 printf("frindex=0x%08x ctrdsegm=0x%08x periodic=0x%08x async=0x%08x\n",
1188 EOREAD4(sc, EHCI_FRINDEX),
1189 EOREAD4(sc, EHCI_CTRLDSSEGMENT),
1190 EOREAD4(sc, EHCI_PERIODICLISTBASE),
1191 EOREAD4(sc, EHCI_ASYNCLISTADDR));
1192 for (i = 1; i <= sc->sc_noport; i++)
1193 printf("port %d status=0x%08x\n", i,
1194 EOREAD4(sc, EHCI_PORTSC(i)));
1195 }
1196
1197
1198
1199
1200
1201 void
1202 ehci_dump()
1203 {
1204 ehci_dump_regs(theehci);
1205 }
1206
1207 void
1208 ehci_dump_link(ehci_link_t link, int type)
1209 {
1210 link = letoh32(link);
1211 printf("0x%08x", link);
1212 if (link & EHCI_LINK_TERMINATE)
1213 printf("<T>");
1214 else {
1215 printf("<");
1216 if (type) {
1217 switch (EHCI_LINK_TYPE(link)) {
1218 case EHCI_LINK_ITD: printf("ITD"); break;
1219 case EHCI_LINK_QH: printf("QH"); break;
1220 case EHCI_LINK_SITD: printf("SITD"); break;
1221 case EHCI_LINK_FSTN: printf("FSTN"); break;
1222 }
1223 }
1224 printf(">");
1225 }
1226 }
1227
1228 void
1229 ehci_dump_sqtds(ehci_soft_qtd_t *sqtd)
1230 {
1231 int i;
1232 u_int32_t stop;
1233
1234 stop = 0;
1235 for (i = 0; sqtd && i < 20 && !stop; sqtd = sqtd->nextqtd, i++) {
1236 ehci_dump_sqtd(sqtd);
1237 stop = sqtd->qtd.qtd_next & htole32(EHCI_LINK_TERMINATE);
1238 }
1239 if (!stop)
1240 printf("dump aborted, too many TDs\n");
1241 }
1242
1243 void
1244 ehci_dump_sqtd(ehci_soft_qtd_t *sqtd)
1245 {
1246 printf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
1247 ehci_dump_qtd(&sqtd->qtd);
1248 }
1249
1250 void
1251 ehci_dump_qtd(ehci_qtd_t *qtd)
1252 {
1253 u_int32_t s;
1254 char sbuf[128];
1255
1256 printf(" next="); ehci_dump_link(qtd->qtd_next, 0);
1257 printf(" altnext="); ehci_dump_link(qtd->qtd_altnext, 0);
1258 printf("\n");
1259 s = letoh32(qtd->qtd_status);
1260 bitmask_snprintf(EHCI_QTD_GET_STATUS(s), "\20\10ACTIVE\7HALTED"
1261 "\6BUFERR\5BABBLE\4XACTERR\3MISSED\2SPLIT\1PING",
1262 sbuf, sizeof(sbuf));
1263 printf(" status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
1264 s, EHCI_QTD_GET_TOGGLE(s), EHCI_QTD_GET_BYTES(s),
1265 EHCI_QTD_GET_IOC(s), EHCI_QTD_GET_C_PAGE(s));
1266 printf(" cerr=%d pid=%d stat=0x%s\n", EHCI_QTD_GET_CERR(s),
1267 EHCI_QTD_GET_PID(s), sbuf);
1268 for (s = 0; s < 5; s++)
1269 printf(" buffer[%d]=0x%08x\n", s, letoh32(qtd->qtd_buffer[s]));
1270 }
1271
1272 void
1273 ehci_dump_sqh(ehci_soft_qh_t *sqh)
1274 {
1275 ehci_qh_t *qh = &sqh->qh;
1276 u_int32_t endp, endphub;
1277
1278 printf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
1279 printf(" link="); ehci_dump_link(qh->qh_link, 1); printf("\n");
1280 endp = letoh32(qh->qh_endp);
1281 printf(" endp=0x%08x\n", endp);
1282 printf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
1283 EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp),
1284 EHCI_QH_GET_ENDPT(endp), EHCI_QH_GET_EPS(endp),
1285 EHCI_QH_GET_DTC(endp), EHCI_QH_GET_HRECL(endp));
1286 printf(" mpl=0x%x ctl=%d nrl=%d\n",
1287 EHCI_QH_GET_MPL(endp), EHCI_QH_GET_CTL(endp),
1288 EHCI_QH_GET_NRL(endp));
1289 endphub = letoh32(qh->qh_endphub);
1290 printf(" endphub=0x%08x\n", endphub);
1291 printf(" smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
1292 EHCI_QH_GET_SMASK(endphub), EHCI_QH_GET_CMASK(endphub),
1293 EHCI_QH_GET_HUBA(endphub), EHCI_QH_GET_PORT(endphub),
1294 EHCI_QH_GET_MULT(endphub));
1295 printf(" curqtd="); ehci_dump_link(qh->qh_curqtd, 0); printf("\n");
1296 printf("Overlay qTD:\n");
1297 ehci_dump_qtd(&qh->qh_qtd);
1298 }
1299
1300 #ifdef DIAGNOSTIC
1301 void
1302 ehci_dump_exfer(struct ehci_xfer *ex)
1303 {
1304 printf("ehci_dump_exfer: ex=%p\n", ex);
1305 }
1306 #endif
1307 #endif
1308
1309 usbd_status
1310 ehci_open(usbd_pipe_handle pipe)
1311 {
1312 usbd_device_handle dev = pipe->device;
1313 ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
1314 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
1315 u_int8_t addr = dev->address;
1316 u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
1317 struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
1318 ehci_soft_qh_t *sqh;
1319 usbd_status err;
1320 int s;
1321 int ival, speed, naks;
1322 int hshubaddr, hshubport;
1323
1324 DPRINTFN(1, ("ehci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
1325 pipe, addr, ed->bEndpointAddress, sc->sc_addr));
1326
1327 if (sc->sc_dying)
1328 return (USBD_IOERROR);
1329
1330 if (dev->myhsport) {
1331 hshubaddr = dev->myhsport->parent->address;
1332 hshubport = dev->myhsport->portno;
1333 } else {
1334 hshubaddr = 0;
1335 hshubport = 0;
1336 }
1337
1338 if (addr == sc->sc_addr) {
1339 switch (ed->bEndpointAddress) {
1340 case USB_CONTROL_ENDPOINT:
1341 pipe->methods = &ehci_root_ctrl_methods;
1342 break;
1343 case UE_DIR_IN | EHCI_INTR_ENDPT:
1344 pipe->methods = &ehci_root_intr_methods;
1345 break;
1346 default:
1347 return (USBD_INVAL);
1348 }
1349 return (USBD_NORMAL_COMPLETION);
1350 }
1351
1352
1353 switch (dev->speed) {
1354 case USB_SPEED_LOW: speed = EHCI_QH_SPEED_LOW; break;
1355 case USB_SPEED_FULL: speed = EHCI_QH_SPEED_FULL; break;
1356 case USB_SPEED_HIGH: speed = EHCI_QH_SPEED_HIGH; break;
1357 default: panic("ehci_open: bad device speed %d", dev->speed);
1358 }
1359 if (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_ISOCHRONOUS) {
1360 printf("%s: *** WARNING: opening low/full speed isochronous "
1361 "device, this does not work yet.\n",
1362 sc->sc_bus.bdev.dv_xname);
1363 DPRINTFN(1,("ehci_open: hshubaddr=%d hshubport=%d\n",
1364 hshubaddr, hshubport));
1365 return (USBD_INVAL);
1366 }
1367
1368 naks = 8;
1369 sqh = ehci_alloc_sqh(sc);
1370 if (sqh == NULL)
1371 goto bad0;
1372
1373 sqh->qh.qh_endp = htole32(
1374 EHCI_QH_SET_ADDR(addr) |
1375 EHCI_QH_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress)) |
1376 EHCI_QH_SET_EPS(speed) |
1377 (xfertype == UE_CONTROL ? EHCI_QH_DTC : 0) |
1378 EHCI_QH_SET_MPL(UGETW(ed->wMaxPacketSize)) |
1379 (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_CONTROL ?
1380 EHCI_QH_CTL : 0) |
1381 EHCI_QH_SET_NRL(naks));
1382 sqh->qh.qh_endphub = htole32(
1383 EHCI_QH_SET_MULT(1) |
1384 EHCI_QH_SET_HUBA(hshubaddr) |
1385 EHCI_QH_SET_PORT(hshubport) |
1386 EHCI_QH_SET_CMASK(0x1c) |
1387 EHCI_QH_SET_SMASK(xfertype == UE_INTERRUPT ? 0x01 : 0));
1388 sqh->qh.qh_curqtd = EHCI_NULL;
1389
1390 sqh->qh.qh_qtd.qtd_next = EHCI_NULL;
1391 sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
1392 sqh->qh.qh_qtd.qtd_status =
1393 htole32(EHCI_QTD_SET_TOGGLE(pipe->endpoint->savedtoggle));
1394
1395 epipe->sqh = sqh;
1396
1397 switch (xfertype) {
1398 case UE_CONTROL:
1399 err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t),
1400 0, &epipe->u.ctl.reqdma);
1401 #ifdef EHCI_DEBUG
1402 if (err)
1403 printf("ehci_open: usb_allocmem()=%d\n", err);
1404 #endif
1405 if (err)
1406 goto bad1;
1407 pipe->methods = &ehci_device_ctrl_methods;
1408 s = splusb();
1409 ehci_add_qh(sqh, sc->sc_async_head);
1410 splx(s);
1411 break;
1412 case UE_BULK:
1413 pipe->methods = &ehci_device_bulk_methods;
1414 s = splusb();
1415 ehci_add_qh(sqh, sc->sc_async_head);
1416 splx(s);
1417 break;
1418 case UE_INTERRUPT:
1419 pipe->methods = &ehci_device_intr_methods;
1420 ival = pipe->interval;
1421 if (ival == USBD_DEFAULT_INTERVAL)
1422 ival = ed->bInterval;
1423 return (ehci_device_setintr(sc, sqh, ival));
1424 case UE_ISOCHRONOUS:
1425 pipe->methods = &ehci_device_isoc_methods;
1426 return (USBD_INVAL);
1427 default:
1428 return (USBD_INVAL);
1429 }
1430 return (USBD_NORMAL_COMPLETION);
1431
1432 bad1:
1433 ehci_free_sqh(sc, sqh);
1434 bad0:
1435 return (USBD_NOMEM);
1436 }
1437
1438
1439
1440
1441
1442
1443 void
1444 ehci_add_qh(ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
1445 {
1446 SPLUSBCHECK;
1447
1448 sqh->next = head->next;
1449 sqh->prev = head;
1450 sqh->qh.qh_link = head->qh.qh_link;
1451 head->next = sqh;
1452 if (sqh->next)
1453 sqh->next->prev = sqh;
1454 head->qh.qh_link = htole32(sqh->physaddr | EHCI_LINK_QH);
1455
1456 #ifdef EHCI_DEBUG
1457 if (ehcidebug > 5) {
1458 printf("ehci_add_qh:\n");
1459 ehci_dump_sqh(sqh);
1460 }
1461 #endif
1462 }
1463
1464
1465
1466
1467
1468 void
1469 ehci_rem_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
1470 {
1471 SPLUSBCHECK;
1472
1473 sqh->prev->qh.qh_link = sqh->qh.qh_link;
1474 sqh->prev->next = sqh->next;
1475 if (sqh->next)
1476 sqh->next->prev = sqh->prev;
1477 ehci_sync_hc(sc);
1478 }
1479
1480 void
1481 ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd)
1482 {
1483 int i;
1484 u_int32_t status;
1485
1486
1487 status = sqh->qh.qh_qtd.qtd_status &
1488 htole32(EHCI_QTD_TOGGLE_MASK |
1489 EHCI_QTD_SET_STATUS(EHCI_QTD_PINGSTATE));
1490
1491 sqh->qh.qh_qtd.qtd_status =
1492 htole32(EHCI_QTD_SET_STATUS(EHCI_QTD_HALTED));
1493 sqh->qh.qh_curqtd = 0;
1494 sqh->qh.qh_qtd.qtd_next = htole32(sqtd->physaddr);
1495 sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
1496 for (i = 0; i < EHCI_QTD_NBUFFERS; i++)
1497 sqh->qh.qh_qtd.qtd_buffer[i] = 0;
1498 sqh->sqtd = sqtd;
1499
1500 sqh->qh.qh_qtd.qtd_status = status;
1501 }
1502
1503
1504
1505
1506
1507
1508
1509 void
1510 ehci_sync_hc(ehci_softc_t *sc)
1511 {
1512 int s, error;
1513 int tries = 0;
1514
1515 if (sc->sc_dying) {
1516 DPRINTFN(2,("ehci_sync_hc: dying\n"));
1517 return;
1518 }
1519 DPRINTFN(2,("ehci_sync_hc: enter\n"));
1520
1521 rw_enter_write(&sc->sc_doorbell_lock);
1522 s = splhardusb();
1523 do {
1524
1525 EOWRITE4(sc, EHCI_USBCMD, EOREAD4(sc, EHCI_USBCMD) |
1526 EHCI_CMD_IAAD);
1527 DPRINTFN(1,("ehci_sync_hc: cmd=0x%08x sts=0x%08x\n",
1528 EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS)));
1529
1530 error = tsleep(&sc->sc_async_head, PZERO, "ehcidi", hz / 2);
1531 DPRINTFN(1,("ehci_sync_hc: cmd=0x%08x sts=0x%08x\n",
1532 EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS)));
1533 } while (error && ++tries < 10);
1534 splx(s);
1535
1536 rw_exit_write(&sc->sc_doorbell_lock);
1537 #ifdef DIAGNOSTIC
1538 if (error)
1539 printf("ehci_sync_hc: tsleep() = %d\n", error);
1540 #endif
1541 DPRINTFN(2,("ehci_sync_hc: exit\n"));
1542 }
1543
1544
1545
1546
1547
1548
1549 usb_device_descriptor_t ehci_devd = {
1550 USB_DEVICE_DESCRIPTOR_SIZE,
1551 UDESC_DEVICE,
1552 {0x00, 0x02},
1553 UDCLASS_HUB,
1554 UDSUBCLASS_HUB,
1555 UDPROTO_HSHUBSTT,
1556 64,
1557 {0},{0},{0x00,0x01},
1558 1,2,0,
1559 1
1560 };
1561
1562 usb_device_qualifier_t ehci_odevd = {
1563 USB_DEVICE_DESCRIPTOR_SIZE,
1564 UDESC_DEVICE_QUALIFIER,
1565 {0x00, 0x02},
1566 UDCLASS_HUB,
1567 UDSUBCLASS_HUB,
1568 UDPROTO_FSHUB,
1569 64,
1570 1,
1571 0
1572 };
1573
1574 usb_config_descriptor_t ehci_confd = {
1575 USB_CONFIG_DESCRIPTOR_SIZE,
1576 UDESC_CONFIG,
1577 {USB_CONFIG_DESCRIPTOR_SIZE +
1578 USB_INTERFACE_DESCRIPTOR_SIZE +
1579 USB_ENDPOINT_DESCRIPTOR_SIZE},
1580 1,
1581 1,
1582 0,
1583 UC_SELF_POWERED,
1584 0
1585 };
1586
1587 usb_interface_descriptor_t ehci_ifcd = {
1588 USB_INTERFACE_DESCRIPTOR_SIZE,
1589 UDESC_INTERFACE,
1590 0,
1591 0,
1592 1,
1593 UICLASS_HUB,
1594 UISUBCLASS_HUB,
1595 UIPROTO_HSHUBSTT,
1596 0
1597 };
1598
1599 usb_endpoint_descriptor_t ehci_endpd = {
1600 USB_ENDPOINT_DESCRIPTOR_SIZE,
1601 UDESC_ENDPOINT,
1602 UE_DIR_IN | EHCI_INTR_ENDPT,
1603 UE_INTERRUPT,
1604 {8, 0},
1605 255
1606 };
1607
1608 usb_hub_descriptor_t ehci_hubd = {
1609 USB_HUB_DESCRIPTOR_SIZE,
1610 UDESC_HUB,
1611 0,
1612 {0,0},
1613 0,
1614 0,
1615 {0},
1616 };
1617
1618 int
1619 ehci_str(usb_string_descriptor_t *p, int l, const char *s)
1620 {
1621 int i;
1622
1623 if (l == 0)
1624 return (0);
1625 p->bLength = 2 * strlen(s) + 2;
1626 if (l == 1)
1627 return (1);
1628 p->bDescriptorType = UDESC_STRING;
1629 l -= 2;
1630 for (i = 0; s[i] && l > 1; i++, l -= 2)
1631 USETW2(p->bString[i], 0, s[i]);
1632 return (2*i+2);
1633 }
1634
1635
1636
1637
1638 usbd_status
1639 ehci_root_ctrl_transfer(usbd_xfer_handle xfer)
1640 {
1641 usbd_status err;
1642
1643
1644 err = usb_insert_transfer(xfer);
1645 if (err)
1646 return (err);
1647
1648
1649 return (ehci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
1650 }
1651
1652 usbd_status
1653 ehci_root_ctrl_start(usbd_xfer_handle xfer)
1654 {
1655 ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
1656 usb_device_request_t *req;
1657 void *buf = NULL;
1658 int port, i;
1659 int s, len, value, index, l, totlen = 0;
1660 usb_port_status_t ps;
1661 usb_hub_descriptor_t hubd;
1662 usbd_status err;
1663 u_int32_t v;
1664
1665 if (sc->sc_dying)
1666 return (USBD_IOERROR);
1667
1668 #ifdef DIAGNOSTIC
1669 if (!(xfer->rqflags & URQ_REQUEST))
1670
1671 return (USBD_INVAL);
1672 #endif
1673 req = &xfer->request;
1674
1675 DPRINTFN(4,("ehci_root_ctrl_start: type=0x%02x request=%02x\n",
1676 req->bmRequestType, req->bRequest));
1677
1678 len = UGETW(req->wLength);
1679 value = UGETW(req->wValue);
1680 index = UGETW(req->wIndex);
1681
1682 if (len != 0)
1683 buf = KERNADDR(&xfer->dmabuf, 0);
1684
1685 #define C(x,y) ((x) | ((y) << 8))
1686 switch(C(req->bRequest, req->bmRequestType)) {
1687 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
1688 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
1689 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
1690
1691
1692
1693
1694 break;
1695 case C(UR_GET_CONFIG, UT_READ_DEVICE):
1696 if (len > 0) {
1697 *(u_int8_t *)buf = sc->sc_conf;
1698 totlen = 1;
1699 }
1700 break;
1701 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
1702 DPRINTFN(8,("ehci_root_ctrl_start: wValue=0x%04x\n", value));
1703 switch(value >> 8) {
1704 case UDESC_DEVICE:
1705 if ((value & 0xff) != 0) {
1706 err = USBD_IOERROR;
1707 goto ret;
1708 }
1709 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
1710 USETW(ehci_devd.idVendor, sc->sc_id_vendor);
1711 memcpy(buf, &ehci_devd, l);
1712 break;
1713
1714
1715
1716
1717 case UDESC_DEVICE_QUALIFIER:
1718 if ((value & 0xff) != 0) {
1719 err = USBD_IOERROR;
1720 goto ret;
1721 }
1722 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
1723 memcpy(buf, &ehci_odevd, l);
1724 break;
1725
1726
1727
1728
1729 case UDESC_OTHER_SPEED_CONFIGURATION:
1730 case UDESC_CONFIG:
1731 if ((value & 0xff) != 0) {
1732 err = USBD_IOERROR;
1733 goto ret;
1734 }
1735 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
1736 memcpy(buf, &ehci_confd, l);
1737 ((usb_config_descriptor_t *)buf)->bDescriptorType =
1738 value >> 8;
1739 buf = (char *)buf + l;
1740 len -= l;
1741 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
1742 totlen += l;
1743 memcpy(buf, &ehci_ifcd, l);
1744 buf = (char *)buf + l;
1745 len -= l;
1746 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
1747 totlen += l;
1748 memcpy(buf, &ehci_endpd, l);
1749 break;
1750 case UDESC_STRING:
1751 if (len == 0)
1752 break;
1753 *(u_int8_t *)buf = 0;
1754 totlen = 1;
1755 switch (value & 0xff) {
1756 case 0:
1757 totlen = ehci_str(buf, len, "\001");
1758 break;
1759 case 1:
1760 totlen = ehci_str(buf, len, sc->sc_vendor);
1761 break;
1762 case 2:
1763 totlen = ehci_str(buf, len, "EHCI root hub");
1764 break;
1765 }
1766 break;
1767 default:
1768 err = USBD_IOERROR;
1769 goto ret;
1770 }
1771 break;
1772 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
1773 if (len > 0) {
1774 *(u_int8_t *)buf = 0;
1775 totlen = 1;
1776 }
1777 break;
1778 case C(UR_GET_STATUS, UT_READ_DEVICE):
1779 if (len > 1) {
1780 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
1781 totlen = 2;
1782 }
1783 break;
1784 case C(UR_GET_STATUS, UT_READ_INTERFACE):
1785 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
1786 if (len > 1) {
1787 USETW(((usb_status_t *)buf)->wStatus, 0);
1788 totlen = 2;
1789 }
1790 break;
1791 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
1792 if (value >= USB_MAX_DEVICES) {
1793 err = USBD_IOERROR;
1794 goto ret;
1795 }
1796 sc->sc_addr = value;
1797 break;
1798 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
1799 if (value != 0 && value != 1) {
1800 err = USBD_IOERROR;
1801 goto ret;
1802 }
1803 sc->sc_conf = value;
1804 break;
1805 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
1806 break;
1807 case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
1808 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
1809 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
1810 err = USBD_IOERROR;
1811 goto ret;
1812 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
1813 break;
1814 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
1815 break;
1816
1817 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
1818 break;
1819 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
1820 DPRINTFN(8, ("ehci_root_ctrl_start: UR_CLEAR_PORT_FEATURE "
1821 "port=%d feature=%d\n", index, value));
1822 if (index < 1 || index > sc->sc_noport) {
1823 err = USBD_IOERROR;
1824 goto ret;
1825 }
1826 port = EHCI_PORTSC(index);
1827 v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
1828 switch(value) {
1829 case UHF_PORT_ENABLE:
1830 EOWRITE4(sc, port, v &~ EHCI_PS_PE);
1831 break;
1832 case UHF_PORT_SUSPEND:
1833 EOWRITE4(sc, port, v &~ EHCI_PS_SUSP);
1834 break;
1835 case UHF_PORT_POWER:
1836 EOWRITE4(sc, port, v &~ EHCI_PS_PP);
1837 break;
1838 case UHF_PORT_TEST:
1839 DPRINTFN(2,("ehci_root_ctrl_start: "
1840 "clear port test %d\n", index));
1841 break;
1842 case UHF_PORT_INDICATOR:
1843 DPRINTFN(2,("ehci_root_ctrl_start: "
1844 "clear port index %d\n", index));
1845 EOWRITE4(sc, port, v &~ EHCI_PS_PIC);
1846 break;
1847 case UHF_C_PORT_CONNECTION:
1848 EOWRITE4(sc, port, v | EHCI_PS_CSC);
1849 break;
1850 case UHF_C_PORT_ENABLE:
1851 EOWRITE4(sc, port, v | EHCI_PS_PEC);
1852 break;
1853 case UHF_C_PORT_SUSPEND:
1854
1855 break;
1856 case UHF_C_PORT_OVER_CURRENT:
1857 EOWRITE4(sc, port, v | EHCI_PS_OCC);
1858 break;
1859 case UHF_C_PORT_RESET:
1860 sc->sc_isreset = 0;
1861 break;
1862 default:
1863 err = USBD_IOERROR;
1864 goto ret;
1865 }
1866 #if 0
1867 switch(value) {
1868 case UHF_C_PORT_CONNECTION:
1869 case UHF_C_PORT_ENABLE:
1870 case UHF_C_PORT_SUSPEND:
1871 case UHF_C_PORT_OVER_CURRENT:
1872 case UHF_C_PORT_RESET:
1873
1874 if ((OREAD4(sc, port) >> 16) == 0)
1875 ehci_pcd_able(sc, 1);
1876 break;
1877 default:
1878 break;
1879 }
1880 #endif
1881 break;
1882 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
1883 if ((value & 0xff) != 0) {
1884 err = USBD_IOERROR;
1885 goto ret;
1886 }
1887 hubd = ehci_hubd;
1888 hubd.bNbrPorts = sc->sc_noport;
1889 v = EOREAD4(sc, EHCI_HCSPARAMS);
1890 USETW(hubd.wHubCharacteristics,
1891 EHCI_HCS_PPC(v) ? UHD_PWR_INDIVIDUAL : UHD_PWR_NO_SWITCH |
1892 EHCI_HCS_P_INDICATOR(EREAD4(sc, EHCI_HCSPARAMS))
1893 ? UHD_PORT_IND : 0);
1894 hubd.bPwrOn2PwrGood = 200;
1895 for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
1896 hubd.DeviceRemovable[i++] = 0;
1897 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
1898 l = min(len, hubd.bDescLength);
1899 totlen = l;
1900 memcpy(buf, &hubd, l);
1901 break;
1902 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
1903 if (len != 4) {
1904 err = USBD_IOERROR;
1905 goto ret;
1906 }
1907 memset(buf, 0, len);
1908 totlen = len;
1909 break;
1910 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
1911 DPRINTFN(8,("ehci_root_ctrl_start: get port status i=%d\n",
1912 index));
1913 if (index < 1 || index > sc->sc_noport) {
1914 err = USBD_IOERROR;
1915 goto ret;
1916 }
1917 if (len != 4) {
1918 err = USBD_IOERROR;
1919 goto ret;
1920 }
1921 v = EOREAD4(sc, EHCI_PORTSC(index));
1922 DPRINTFN(8,("ehci_root_ctrl_start: port status=0x%04x\n", v));
1923 i = UPS_HIGH_SPEED;
1924 if (v & EHCI_PS_CS) i |= UPS_CURRENT_CONNECT_STATUS;
1925 if (v & EHCI_PS_PE) i |= UPS_PORT_ENABLED;
1926 if (v & EHCI_PS_SUSP) i |= UPS_SUSPEND;
1927 if (v & EHCI_PS_OCA) i |= UPS_OVERCURRENT_INDICATOR;
1928 if (v & EHCI_PS_PR) i |= UPS_RESET;
1929 if (v & EHCI_PS_PP) i |= UPS_PORT_POWER;
1930 USETW(ps.wPortStatus, i);
1931 i = 0;
1932 if (v & EHCI_PS_CSC) i |= UPS_C_CONNECT_STATUS;
1933 if (v & EHCI_PS_PEC) i |= UPS_C_PORT_ENABLED;
1934 if (v & EHCI_PS_OCC) i |= UPS_C_OVERCURRENT_INDICATOR;
1935 if (sc->sc_isreset) i |= UPS_C_PORT_RESET;
1936 USETW(ps.wPortChange, i);
1937 l = min(len, sizeof(ps));
1938 memcpy(buf, &ps, l);
1939 totlen = l;
1940 break;
1941 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
1942 err = USBD_IOERROR;
1943 goto ret;
1944 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
1945 break;
1946 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
1947 if (index < 1 || index > sc->sc_noport) {
1948 err = USBD_IOERROR;
1949 goto ret;
1950 }
1951 port = EHCI_PORTSC(index);
1952 v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
1953 switch(value) {
1954 case UHF_PORT_ENABLE:
1955 EOWRITE4(sc, port, v | EHCI_PS_PE);
1956 break;
1957 case UHF_PORT_SUSPEND:
1958 EOWRITE4(sc, port, v | EHCI_PS_SUSP);
1959 break;
1960 case UHF_PORT_RESET:
1961 DPRINTFN(5,("ehci_root_ctrl_start: reset port %d\n",
1962 index));
1963 if (EHCI_PS_IS_LOWSPEED(v)) {
1964
1965 ehci_disown(sc, index, 1);
1966 break;
1967 }
1968
1969 v &= ~ (EHCI_PS_PE | EHCI_PS_PR);
1970 EOWRITE4(sc, port, v | EHCI_PS_PR);
1971
1972 usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
1973 if (sc->sc_dying) {
1974 err = USBD_IOERROR;
1975 goto ret;
1976 }
1977
1978 EOWRITE4(sc, port, v);
1979
1980 usb_delay_ms(&sc->sc_bus, EHCI_PORT_RESET_COMPLETE);
1981 if (sc->sc_dying) {
1982 err = USBD_IOERROR;
1983 goto ret;
1984 }
1985 v = EOREAD4(sc, port);
1986 DPRINTF(("ehci after reset, status=0x%08x\n", v));
1987 if (v & EHCI_PS_PR) {
1988 printf("%s: port reset timeout\n",
1989 sc->sc_bus.bdev.dv_xname);
1990 return (USBD_TIMEOUT);
1991 }
1992 if (!(v & EHCI_PS_PE)) {
1993
1994 ehci_disown(sc, index, 0);
1995 break;
1996 }
1997 sc->sc_isreset = 1;
1998 DPRINTF(("ehci port %d reset, status = 0x%08x\n",
1999 index, v));
2000 break;
2001 case UHF_PORT_POWER:
2002 DPRINTFN(2,("ehci_root_ctrl_start: "
2003 "set port power %d\n", index));
2004 EOWRITE4(sc, port, v | EHCI_PS_PP);
2005 break;
2006 case UHF_PORT_TEST:
2007 DPRINTFN(2,("ehci_root_ctrl_start: "
2008 "set port test %d\n", index));
2009 break;
2010 case UHF_PORT_INDICATOR:
2011 DPRINTFN(2,("ehci_root_ctrl_start: "
2012 "set port ind %d\n", index));
2013 EOWRITE4(sc, port, v | EHCI_PS_PIC);
2014 break;
2015 default:
2016 err = USBD_IOERROR;
2017 goto ret;
2018 }
2019 break;
2020 case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER):
2021 case C(UR_RESET_TT, UT_WRITE_CLASS_OTHER):
2022 case C(UR_GET_TT_STATE, UT_READ_CLASS_OTHER):
2023 case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER):
2024 break;
2025 default:
2026 err = USBD_IOERROR;
2027 goto ret;
2028 }
2029 xfer->actlen = totlen;
2030 err = USBD_NORMAL_COMPLETION;
2031 ret:
2032 xfer->status = err;
2033 s = splusb();
2034 usb_transfer_complete(xfer);
2035 splx(s);
2036 return (USBD_IN_PROGRESS);
2037 }
2038
2039 void
2040 ehci_disown(ehci_softc_t *sc, int index, int lowspeed)
2041 {
2042 int port;
2043 u_int32_t v;
2044
2045 DPRINTF(("ehci_disown: index=%d lowspeed=%d\n", index, lowspeed));
2046
2047 port = EHCI_PORTSC(index);
2048 v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
2049 EOWRITE4(sc, port, v | EHCI_PS_PO);
2050 }
2051
2052
2053 void
2054 ehci_root_ctrl_abort(usbd_xfer_handle xfer)
2055 {
2056
2057 }
2058
2059
2060 void
2061 ehci_root_ctrl_close(usbd_pipe_handle pipe)
2062 {
2063 DPRINTF(("ehci_root_ctrl_close\n"));
2064
2065 }
2066
2067 void
2068 ehci_root_intr_done(usbd_xfer_handle xfer)
2069 {
2070 }
2071
2072 usbd_status
2073 ehci_root_intr_transfer(usbd_xfer_handle xfer)
2074 {
2075 usbd_status err;
2076
2077
2078 err = usb_insert_transfer(xfer);
2079 if (err)
2080 return (err);
2081
2082
2083 return (ehci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2084 }
2085
2086 usbd_status
2087 ehci_root_intr_start(usbd_xfer_handle xfer)
2088 {
2089 usbd_pipe_handle pipe = xfer->pipe;
2090 ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
2091
2092 if (sc->sc_dying)
2093 return (USBD_IOERROR);
2094
2095 sc->sc_intrxfer = xfer;
2096
2097 return (USBD_IN_PROGRESS);
2098 }
2099
2100
2101 void
2102 ehci_root_intr_abort(usbd_xfer_handle xfer)
2103 {
2104 int s;
2105
2106 if (xfer->pipe->intrxfer == xfer) {
2107 DPRINTF(("ehci_root_intr_abort: remove\n"));
2108 xfer->pipe->intrxfer = NULL;
2109 }
2110 xfer->status = USBD_CANCELLED;
2111 s = splusb();
2112 usb_transfer_complete(xfer);
2113 splx(s);
2114 }
2115
2116
2117 void
2118 ehci_root_intr_close(usbd_pipe_handle pipe)
2119 {
2120 ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
2121
2122 DPRINTF(("ehci_root_intr_close\n"));
2123
2124 sc->sc_intrxfer = NULL;
2125 }
2126
2127 void
2128 ehci_root_ctrl_done(usbd_xfer_handle xfer)
2129 {
2130 }
2131
2132
2133
2134 ehci_soft_qh_t *
2135 ehci_alloc_sqh(ehci_softc_t *sc)
2136 {
2137 ehci_soft_qh_t *sqh;
2138 usbd_status err;
2139 int i, offs;
2140 usb_dma_t dma;
2141
2142 if (sc->sc_freeqhs == NULL) {
2143 DPRINTFN(2, ("ehci_alloc_sqh: allocating chunk\n"));
2144 err = usb_allocmem(&sc->sc_bus, EHCI_SQH_SIZE * EHCI_SQH_CHUNK,
2145 EHCI_PAGE_SIZE, &dma);
2146 #ifdef EHCI_DEBUG
2147 if (err)
2148 printf("ehci_alloc_sqh: usb_allocmem()=%d\n", err);
2149 #endif
2150 if (err)
2151 return (NULL);
2152 for(i = 0; i < EHCI_SQH_CHUNK; i++) {
2153 offs = i * EHCI_SQH_SIZE;
2154 sqh = KERNADDR(&dma, offs);
2155 sqh->physaddr = DMAADDR(&dma, offs);
2156 sqh->next = sc->sc_freeqhs;
2157 sc->sc_freeqhs = sqh;
2158 }
2159 }
2160 sqh = sc->sc_freeqhs;
2161 sc->sc_freeqhs = sqh->next;
2162 memset(&sqh->qh, 0, sizeof(ehci_qh_t));
2163 sqh->next = NULL;
2164 sqh->prev = NULL;
2165 return (sqh);
2166 }
2167
2168 void
2169 ehci_free_sqh(ehci_softc_t *sc, ehci_soft_qh_t *sqh)
2170 {
2171 sqh->next = sc->sc_freeqhs;
2172 sc->sc_freeqhs = sqh;
2173 }
2174
2175 ehci_soft_qtd_t *
2176 ehci_alloc_sqtd(ehci_softc_t *sc)
2177 {
2178 ehci_soft_qtd_t *sqtd;
2179 usbd_status err;
2180 int i, offs;
2181 usb_dma_t dma;
2182 int s;
2183
2184 if (sc->sc_freeqtds == NULL) {
2185 DPRINTFN(2, ("ehci_alloc_sqtd: allocating chunk\n"));
2186 err = usb_allocmem(&sc->sc_bus, EHCI_SQTD_SIZE*EHCI_SQTD_CHUNK,
2187 EHCI_PAGE_SIZE, &dma);
2188 #ifdef EHCI_DEBUG
2189 if (err)
2190 printf("ehci_alloc_sqtd: usb_allocmem()=%d\n", err);
2191 #endif
2192 if (err)
2193 return (NULL);
2194 s = splusb();
2195 for(i = 0; i < EHCI_SQTD_CHUNK; i++) {
2196 offs = i * EHCI_SQTD_SIZE;
2197 sqtd = KERNADDR(&dma, offs);
2198 sqtd->physaddr = DMAADDR(&dma, offs);
2199 sqtd->nextqtd = sc->sc_freeqtds;
2200 sc->sc_freeqtds = sqtd;
2201 }
2202 splx(s);
2203 }
2204
2205 s = splusb();
2206 sqtd = sc->sc_freeqtds;
2207 sc->sc_freeqtds = sqtd->nextqtd;
2208 memset(&sqtd->qtd, 0, sizeof(ehci_qtd_t));
2209 sqtd->nextqtd = NULL;
2210 sqtd->xfer = NULL;
2211 splx(s);
2212
2213 return (sqtd);
2214 }
2215
2216 void
2217 ehci_free_sqtd(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd)
2218 {
2219 int s;
2220
2221 s = splusb();
2222 sqtd->nextqtd = sc->sc_freeqtds;
2223 sc->sc_freeqtds = sqtd;
2224 splx(s);
2225 }
2226
2227 usbd_status
2228 ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc, int alen,
2229 int rd, usbd_xfer_handle xfer, ehci_soft_qtd_t **sp, ehci_soft_qtd_t **ep)
2230 {
2231 ehci_soft_qtd_t *next, *cur;
2232 ehci_physaddr_t dataphys, dataphyspage, dataphyslastpage, nextphys;
2233 u_int32_t qtdstatus;
2234 int len, curlen, mps;
2235 int i, iscontrol, forceshort;
2236 usb_dma_t *dma = &xfer->dmabuf;
2237
2238 DPRINTFN(alen<4*4096,("ehci_alloc_sqtd_chain: start len=%d\n", alen));
2239
2240 len = alen;
2241 iscontrol = (epipe->pipe.endpoint->edesc->bmAttributes & UE_XFERTYPE) ==
2242 UE_CONTROL;
2243
2244 dataphys = DMAADDR(dma, 0);
2245 dataphyslastpage = EHCI_PAGE(dataphys + len - 1);
2246 qtdstatus = EHCI_QTD_ACTIVE |
2247 EHCI_QTD_SET_PID(rd ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT) |
2248 EHCI_QTD_SET_CERR(3);
2249 mps = UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize);
2250 forceshort = ((xfer->flags & USBD_FORCE_SHORT_XFER) || len == 0) &&
2251 len % mps == 0;
2252
2253
2254
2255
2256 if (iscontrol)
2257 qtdstatus |= EHCI_QTD_SET_TOGGLE(1);
2258
2259 cur = ehci_alloc_sqtd(sc);
2260 *sp = cur;
2261 if (cur == NULL)
2262 goto nomem;
2263 for (;;) {
2264 dataphyspage = EHCI_PAGE(dataphys);
2265
2266 if (dataphyslastpage - dataphyspage <
2267 EHCI_QTD_NBUFFERS * EHCI_PAGE_SIZE) {
2268
2269 curlen = len;
2270 } else {
2271
2272 curlen = EHCI_QTD_NBUFFERS * EHCI_PAGE_SIZE -
2273 EHCI_PAGE_OFFSET(dataphys);
2274 #ifdef DIAGNOSTIC
2275 if (curlen > len) {
2276 printf("ehci_alloc_sqtd_chain: curlen=0x%x "
2277 "len=0x%x offs=0x%x\n", curlen, len,
2278 EHCI_PAGE_OFFSET(dataphys));
2279 printf("lastpage=0x%x page=0x%x phys=0x%x\n",
2280 dataphyslastpage, dataphyspage, dataphys);
2281 curlen = len;
2282 }
2283 #endif
2284
2285 curlen -= curlen % mps;
2286 DPRINTFN(1,("ehci_alloc_sqtd_chain: multiple QTDs, "
2287 "curlen=%d\n", curlen));
2288 #ifdef DIAGNOSTIC
2289 if (curlen == 0)
2290 panic("ehci_alloc_std: curlen == 0");
2291 #endif
2292 }
2293 DPRINTFN(4,("ehci_alloc_sqtd_chain: dataphys=0x%08x "
2294 "dataphyslastpage=0x%08x len=%d curlen=%d\n",
2295 dataphys, dataphyslastpage, len, curlen));
2296 len -= curlen;
2297
2298
2299
2300
2301
2302
2303 if (len != 0 || forceshort) {
2304 next = ehci_alloc_sqtd(sc);
2305 if (next == NULL)
2306 goto nomem;
2307 nextphys = htole32(next->physaddr);
2308 } else {
2309 next = NULL;
2310 nextphys = EHCI_NULL;
2311 }
2312
2313 for (i = 0; i * EHCI_PAGE_SIZE <
2314 curlen + EHCI_PAGE_OFFSET(dataphys); i++) {
2315 ehci_physaddr_t a = dataphys + i * EHCI_PAGE_SIZE;
2316 if (i != 0)
2317 a = EHCI_PAGE(a);
2318 cur->qtd.qtd_buffer[i] = htole32(a);
2319 cur->qtd.qtd_buffer_hi[i] = 0;
2320 #ifdef DIAGNOSTIC
2321 if (i >= EHCI_QTD_NBUFFERS) {
2322 printf("ehci_alloc_sqtd_chain: i=%d\n", i);
2323 goto nomem;
2324 }
2325 #endif
2326 }
2327 cur->nextqtd = next;
2328 cur->qtd.qtd_next = cur->qtd.qtd_altnext = nextphys;
2329 cur->qtd.qtd_status = htole32(qtdstatus |
2330 EHCI_QTD_SET_BYTES(curlen));
2331 cur->xfer = xfer;
2332 cur->len = curlen;
2333 DPRINTFN(10,("ehci_alloc_sqtd_chain: cbp=0x%08x end=0x%08x\n",
2334 dataphys, dataphys + curlen));
2335 DPRINTFN(10,("ehci_alloc_sqtd_chain: curlen=%d\n", curlen));
2336 if (iscontrol) {
2337
2338
2339
2340
2341 if ((((curlen + mps - 1) / mps) & 1) || curlen == 0)
2342 qtdstatus ^= EHCI_QTD_TOGGLE_MASK;
2343 }
2344 if (len == 0) {
2345 if (! forceshort)
2346 break;
2347 forceshort = 0;
2348 }
2349 DPRINTFN(10,("ehci_alloc_sqtd_chain: extend chain\n"));
2350 dataphys += curlen;
2351 cur = next;
2352 }
2353 cur->qtd.qtd_status |= htole32(EHCI_QTD_IOC);
2354 *ep = cur;
2355
2356 DPRINTFN(10,("ehci_alloc_sqtd_chain: return sqtd=%p sqtdend=%p\n",
2357 *sp, *ep));
2358
2359 return (USBD_NORMAL_COMPLETION);
2360
2361 nomem:
2362
2363 DPRINTFN(-1,("ehci_alloc_sqtd_chain: no memory\n"));
2364 return (USBD_NOMEM);
2365 }
2366
2367 void
2368 ehci_free_sqtd_chain(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd,
2369 ehci_soft_qtd_t *sqtdend)
2370 {
2371 ehci_soft_qtd_t *p;
2372 int i;
2373
2374 DPRINTFN(10,("ehci_free_sqtd_chain: sqtd=%p sqtdend=%p\n",
2375 sqtd, sqtdend));
2376
2377 for (i = 0; sqtd != sqtdend; sqtd = p, i++) {
2378 p = sqtd->nextqtd;
2379 ehci_free_sqtd(sc, sqtd);
2380 }
2381 }
2382
2383
2384
2385
2386
2387
2388
2389 void
2390 ehci_close_pipe(usbd_pipe_handle pipe, ehci_soft_qh_t *head)
2391 {
2392 struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
2393 ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
2394 ehci_soft_qh_t *sqh = epipe->sqh;
2395 int s;
2396
2397 s = splusb();
2398 ehci_rem_qh(sc, sqh, head);
2399 splx(s);
2400 pipe->endpoint->savedtoggle =
2401 EHCI_QTD_GET_TOGGLE(letoh32(sqh->qh.qh_qtd.qtd_status));
2402 ehci_free_sqh(sc, epipe->sqh);
2403 }
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415 void
2416 ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
2417 {
2418 #define exfer EXFER(xfer)
2419 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
2420 ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
2421 ehci_soft_qh_t *sqh = epipe->sqh;
2422 ehci_soft_qtd_t *sqtd, *snext, **psqtd;
2423 ehci_physaddr_t cur, us, next;
2424 int s;
2425 int hit;
2426 ehci_soft_qh_t *psqh;
2427
2428 DPRINTF(("ehci_abort_xfer: xfer=%p pipe=%p\n", xfer, epipe));
2429
2430 if (sc->sc_dying) {
2431
2432 s = splusb();
2433 xfer->status = status;
2434 timeout_del(&xfer->timeout_handle);
2435 usb_rem_task(epipe->pipe.device, &exfer->abort_task);
2436 usb_transfer_complete(xfer);
2437 splx(s);
2438 return;
2439 }
2440
2441 if (xfer->device->bus->intr_context || !curproc)
2442 panic("ehci_abort_xfer: not in process context");
2443
2444
2445
2446
2447
2448 if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING) {
2449 DPRINTFN(2, ("ehci_abort_xfer: already aborting\n"));
2450
2451 if (status == USBD_TIMEOUT)
2452 return;
2453
2454 xfer->status = status;
2455 DPRINTFN(2, ("ehci_abort_xfer: waiting for abort to finish\n"));
2456 exfer->ehci_xfer_flags |= EHCI_XFER_ABORTWAIT;
2457 while (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING)
2458 tsleep(&exfer->ehci_xfer_flags, PZERO, "ehciaw", 0);
2459 return;
2460 }
2461
2462
2463
2464
2465 s = splusb();
2466 exfer->ehci_xfer_flags |= EHCI_XFER_ABORTING;
2467 xfer->status = status;
2468 timeout_del(&xfer->timeout_handle);
2469 usb_rem_task(epipe->pipe.device, &exfer->abort_task);
2470 splx(s);
2471
2472
2473
2474
2475
2476
2477
2478 psqh = sqh->prev;
2479 ehci_rem_qh(sc, sqh, psqh);
2480
2481
2482
2483
2484
2485
2486
2487
2488 for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) {
2489 sqtd->qtd.qtd_status = htole32(EHCI_QTD_HALTED);
2490 if (sqtd == exfer->sqtdend)
2491 break;
2492 }
2493 ehci_sync_hc(sc);
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503 s = splusb();
2504 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
2505 sc->sc_softwake = 1;
2506 #endif
2507 usb_schedsoftintr(&sc->sc_bus);
2508 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
2509 tsleep(&sc->sc_softwake, PZERO, "ehciab", 0);
2510 #endif
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525 cur = EHCI_LINK_ADDR(letoh32(sqh->qh.qh_curqtd));
2526 hit = 0;
2527
2528
2529 us = exfer->sqtdstart->physaddr;
2530
2531
2532 snext = exfer->sqtdend->nextqtd;
2533 next = snext ? snext->physaddr : EHCI_NULL;
2534
2535
2536
2537
2538
2539 psqtd = &sqh->sqtd;
2540 sqtd = sqh->sqtd;
2541 while (sqtd && sqtd != exfer->sqtdstart) {
2542 hit |= (cur == sqtd->physaddr);
2543 if (EHCI_LINK_ADDR(letoh32(sqtd->qtd.qtd_next)) == us)
2544 sqtd->qtd.qtd_next = next;
2545 if (EHCI_LINK_ADDR(letoh32(sqtd->qtd.qtd_altnext)) == us)
2546 sqtd->qtd.qtd_altnext = next;
2547 psqtd = &sqtd->nextqtd;
2548 sqtd = sqtd->nextqtd;
2549 }
2550
2551 *psqtd = exfer->sqtdend->nextqtd;
2552
2553
2554
2555
2556
2557 if (!hit) {
2558
2559
2560
2561
2562
2563
2564
2565 sqtd = exfer->sqtdstart;
2566 for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) {
2567 if (cur == sqtd->physaddr) {
2568 hit++;
2569 }
2570 if (sqtd == exfer->sqtdend)
2571 break;
2572 }
2573 sqtd = sqtd->nextqtd;
2574
2575
2576
2577
2578 if (hit) {
2579 if (snext) {
2580 ehci_set_qh_qtd(sqh, snext);
2581 } else {
2582
2583 sqh->qh.qh_curqtd = 0;
2584 sqh->qh.qh_qtd.qtd_status = 0;
2585 sqh->qh.qh_qtd.qtd_next =
2586 sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
2587 DPRINTFN(1,("ehci_abort_xfer: no hit\n"));
2588 }
2589 }
2590 }
2591 ehci_add_qh(sqh, psqh);
2592
2593
2594
2595
2596 #ifdef DIAGNOSTIC
2597 exfer->isdone = 1;
2598 #endif
2599
2600 exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTING;
2601 if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTWAIT) {
2602 exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTWAIT;
2603 wakeup(&exfer->ehci_xfer_flags);
2604 }
2605 usb_transfer_complete(xfer);
2606
2607 splx(s);
2608 #undef exfer
2609 }
2610
2611 void
2612 ehci_timeout(void *addr)
2613 {
2614 struct ehci_xfer *exfer = addr;
2615 struct ehci_pipe *epipe = (struct ehci_pipe *)exfer->xfer.pipe;
2616 ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
2617
2618 DPRINTF(("ehci_timeout: exfer=%p\n", exfer));
2619 #ifdef USB_DEBUG
2620 if (ehcidebug > 1)
2621 usbd_dump_pipe(exfer->xfer.pipe);
2622 #endif
2623
2624 if (sc->sc_dying) {
2625 ehci_abort_xfer(&exfer->xfer, USBD_TIMEOUT);
2626 return;
2627 }
2628
2629
2630 usb_add_task(exfer->xfer.pipe->device, &exfer->abort_task);
2631 }
2632
2633 void
2634 ehci_timeout_task(void *addr)
2635 {
2636 usbd_xfer_handle xfer = addr;
2637 int s;
2638
2639 DPRINTF(("ehci_timeout_task: xfer=%p\n", xfer));
2640
2641 s = splusb();
2642 ehci_abort_xfer(xfer, USBD_TIMEOUT);
2643 splx(s);
2644 }
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657 void
2658 ehci_intrlist_timeout(void *arg)
2659 {
2660 ehci_softc_t *sc = arg;
2661 int s = splusb();
2662
2663 DPRINTFN(1, ("ehci_intrlist_timeout\n"));
2664 usb_schedsoftintr(&sc->sc_bus);
2665
2666 splx(s);
2667 }
2668
2669
2670
2671 usbd_status
2672 ehci_device_ctrl_transfer(usbd_xfer_handle xfer)
2673 {
2674 usbd_status err;
2675
2676
2677 err = usb_insert_transfer(xfer);
2678 if (err)
2679 return (err);
2680
2681
2682 return (ehci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2683 }
2684
2685 usbd_status
2686 ehci_device_ctrl_start(usbd_xfer_handle xfer)
2687 {
2688 ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
2689 usbd_status err;
2690
2691 if (sc->sc_dying)
2692 return (USBD_IOERROR);
2693
2694 #ifdef DIAGNOSTIC
2695 if (!(xfer->rqflags & URQ_REQUEST)) {
2696
2697 printf("ehci_device_ctrl_transfer: not a request\n");
2698 return (USBD_INVAL);
2699 }
2700 #endif
2701
2702 err = ehci_device_request(xfer);
2703 if (err)
2704 return (err);
2705
2706 if (sc->sc_bus.use_polling)
2707 ehci_waitintr(sc, xfer);
2708 return (USBD_IN_PROGRESS);
2709 }
2710
2711 void
2712 ehci_device_ctrl_done(usbd_xfer_handle xfer)
2713 {
2714 struct ehci_xfer *ex = EXFER(xfer);
2715 ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
2716
2717
2718 DPRINTFN(10,("ehci_ctrl_done: xfer=%p\n", xfer));
2719
2720 #ifdef DIAGNOSTIC
2721 if (!(xfer->rqflags & URQ_REQUEST)) {
2722 panic("ehci_ctrl_done: not a request");
2723 }
2724 #endif
2725
2726 if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
2727 ehci_del_intr_list(ex);
2728 ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL);
2729 }
2730
2731 DPRINTFN(5, ("ehci_ctrl_done: length=%d\n", xfer->actlen));
2732 }
2733
2734
2735 void
2736 ehci_device_ctrl_abort(usbd_xfer_handle xfer)
2737 {
2738 DPRINTF(("ehci_device_ctrl_abort: xfer=%p\n", xfer));
2739 ehci_abort_xfer(xfer, USBD_CANCELLED);
2740 }
2741
2742
2743 void
2744 ehci_device_ctrl_close(usbd_pipe_handle pipe)
2745 {
2746 ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
2747
2748
2749 DPRINTF(("ehci_device_ctrl_close: pipe=%p\n", pipe));
2750 ehci_close_pipe(pipe, sc->sc_async_head);
2751 }
2752
2753 usbd_status
2754 ehci_device_request(usbd_xfer_handle xfer)
2755 {
2756 #define exfer EXFER(xfer)
2757 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
2758 usb_device_request_t *req = &xfer->request;
2759 usbd_device_handle dev = epipe->pipe.device;
2760 ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
2761 int addr = dev->address;
2762 ehci_soft_qtd_t *setup, *stat, *next;
2763 ehci_soft_qh_t *sqh;
2764 int isread;
2765 int len;
2766 usbd_status err;
2767 int s;
2768
2769 isread = req->bmRequestType & UT_READ;
2770 len = UGETW(req->wLength);
2771
2772 DPRINTFN(3,("ehci_device_request: type=0x%02x, request=0x%02x, "
2773 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
2774 req->bmRequestType, req->bRequest, UGETW(req->wValue),
2775 UGETW(req->wIndex), len, addr,
2776 epipe->pipe.endpoint->edesc->bEndpointAddress));
2777
2778 setup = ehci_alloc_sqtd(sc);
2779 if (setup == NULL) {
2780 err = USBD_NOMEM;
2781 goto bad1;
2782 }
2783 stat = ehci_alloc_sqtd(sc);
2784 if (stat == NULL) {
2785 err = USBD_NOMEM;
2786 goto bad2;
2787 }
2788
2789 sqh = epipe->sqh;
2790 epipe->u.ctl.length = len;
2791
2792
2793
2794
2795
2796 sqh->qh.qh_endp =
2797 (sqh->qh.qh_endp & htole32(~(EHCI_QH_ADDRMASK | EHCI_QH_MPLMASK))) |
2798 htole32(
2799 EHCI_QH_SET_ADDR(addr) |
2800 EHCI_QH_SET_MPL(UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize))
2801 );
2802
2803
2804 if (len != 0) {
2805 ehci_soft_qtd_t *end;
2806
2807 err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
2808 &next, &end);
2809 if (err)
2810 goto bad3;
2811 end->qtd.qtd_status &= htole32(~EHCI_QTD_IOC);
2812 end->nextqtd = stat;
2813 end->qtd.qtd_next =
2814 end->qtd.qtd_altnext = htole32(stat->physaddr);
2815 } else {
2816 next = stat;
2817 }
2818
2819 memcpy(KERNADDR(&epipe->u.ctl.reqdma, 0), req, sizeof(*req));
2820
2821
2822 setup->qtd.qtd_status = htole32(
2823 EHCI_QTD_ACTIVE |
2824 EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) |
2825 EHCI_QTD_SET_CERR(3) |
2826 EHCI_QTD_SET_TOGGLE(0) |
2827 EHCI_QTD_SET_BYTES(sizeof(*req)));
2828 setup->qtd.qtd_buffer[0] = htole32(DMAADDR(&epipe->u.ctl.reqdma, 0));
2829 setup->qtd.qtd_buffer_hi[0] = 0;
2830 setup->nextqtd = next;
2831 setup->qtd.qtd_next = setup->qtd.qtd_altnext = htole32(next->physaddr);
2832 setup->xfer = xfer;
2833 setup->len = sizeof(*req);
2834
2835 stat->qtd.qtd_status = htole32(
2836 EHCI_QTD_ACTIVE |
2837 EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) |
2838 EHCI_QTD_SET_CERR(3) |
2839 EHCI_QTD_SET_TOGGLE(1) |
2840 EHCI_QTD_IOC);
2841 stat->qtd.qtd_buffer[0] = 0;
2842 stat->qtd.qtd_buffer_hi[0] = 0;
2843 stat->nextqtd = NULL;
2844 stat->qtd.qtd_next = stat->qtd.qtd_altnext = EHCI_NULL;
2845 stat->xfer = xfer;
2846 stat->len = 0;
2847
2848 #ifdef EHCI_DEBUG
2849 if (ehcidebug > 5) {
2850 DPRINTF(("ehci_device_request:\n"));
2851 ehci_dump_sqh(sqh);
2852 ehci_dump_sqtds(setup);
2853 }
2854 #endif
2855
2856 exfer->sqtdstart = setup;
2857 exfer->sqtdend = stat;
2858 #ifdef DIAGNOSTIC
2859 if (!exfer->isdone) {
2860 printf("ehci_device_request: not done, exfer=%p\n", exfer);
2861 }
2862 exfer->isdone = 0;
2863 #endif
2864
2865
2866 s = splusb();
2867 ehci_set_qh_qtd(sqh, setup);
2868 if (xfer->timeout && !sc->sc_bus.use_polling) {
2869 timeout_del(&xfer->timeout_handle);
2870 timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
2871 timeout_add(&xfer->timeout_handle, mstohz(xfer->timeout));
2872 }
2873 ehci_add_intr_list(sc, exfer);
2874 xfer->status = USBD_IN_PROGRESS;
2875 splx(s);
2876
2877 #ifdef EHCI_DEBUG
2878 if (ehcidebug > 10) {
2879 DPRINTF(("ehci_device_request: status=%x\n",
2880 EOREAD4(sc, EHCI_USBSTS)));
2881 delay(10000);
2882 ehci_dump_regs(sc);
2883 ehci_dump_sqh(sc->sc_async_head);
2884 ehci_dump_sqh(sqh);
2885 ehci_dump_sqtds(setup);
2886 }
2887 #endif
2888
2889 return (USBD_NORMAL_COMPLETION);
2890
2891 bad3:
2892 ehci_free_sqtd(sc, stat);
2893 bad2:
2894 ehci_free_sqtd(sc, setup);
2895 bad1:
2896 DPRINTFN(-1,("ehci_device_request: no memory\n"));
2897 xfer->status = err;
2898 usb_transfer_complete(xfer);
2899 return (err);
2900 #undef exfer
2901 }
2902
2903
2904
2905 usbd_status
2906 ehci_device_bulk_transfer(usbd_xfer_handle xfer)
2907 {
2908 usbd_status err;
2909
2910
2911 err = usb_insert_transfer(xfer);
2912 if (err)
2913 return (err);
2914
2915
2916 return (ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2917 }
2918
2919 usbd_status
2920 ehci_device_bulk_start(usbd_xfer_handle xfer)
2921 {
2922 #define exfer EXFER(xfer)
2923 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
2924 usbd_device_handle dev = epipe->pipe.device;
2925 ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
2926 ehci_soft_qtd_t *data, *dataend;
2927 ehci_soft_qh_t *sqh;
2928 usbd_status err;
2929 int len, isread, endpt;
2930 int s;
2931
2932 DPRINTFN(2, ("ehci_device_bulk_start: xfer=%p len=%d flags=%d\n",
2933 xfer, xfer->length, xfer->flags));
2934
2935 if (sc->sc_dying)
2936 return (USBD_IOERROR);
2937
2938 #ifdef DIAGNOSTIC
2939 if (xfer->rqflags & URQ_REQUEST)
2940 panic("ehci_device_bulk_start: a request");
2941 #endif
2942
2943 len = xfer->length;
2944 endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
2945 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2946 sqh = epipe->sqh;
2947
2948 epipe->u.bulk.length = len;
2949
2950 err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, &data,
2951 &dataend);
2952 if (err) {
2953 DPRINTFN(-1,("ehci_device_bulk_start: no memory\n"));
2954 xfer->status = err;
2955 usb_transfer_complete(xfer);
2956 return (err);
2957 }
2958
2959 #ifdef EHCI_DEBUG
2960 if (ehcidebug > 5) {
2961 DPRINTF(("ehci_device_bulk_start: data(1)\n"));
2962 ehci_dump_sqh(sqh);
2963 ehci_dump_sqtds(data);
2964 }
2965 #endif
2966
2967
2968 exfer->sqtdstart = data;
2969 exfer->sqtdend = dataend;
2970 #ifdef DIAGNOSTIC
2971 if (!exfer->isdone) {
2972 printf("ehci_device_bulk_start: not done, ex=%p\n", exfer);
2973 }
2974 exfer->isdone = 0;
2975 #endif
2976
2977 s = splusb();
2978 ehci_set_qh_qtd(sqh, data);
2979 if (xfer->timeout && !sc->sc_bus.use_polling) {
2980 timeout_del(&xfer->timeout_handle);
2981 timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
2982 timeout_add(&xfer->timeout_handle, mstohz(xfer->timeout));
2983 }
2984 ehci_add_intr_list(sc, exfer);
2985 xfer->status = USBD_IN_PROGRESS;
2986 splx(s);
2987
2988 #ifdef EHCI_DEBUG
2989 if (ehcidebug > 10) {
2990 DPRINTF(("ehci_device_bulk_start: data(2)\n"));
2991 delay(10000);
2992 DPRINTF(("ehci_device_bulk_start: data(3)\n"));
2993 ehci_dump_regs(sc);
2994 #if 0
2995 printf("async_head:\n");
2996 ehci_dump_sqh(sc->sc_async_head);
2997 #endif
2998 printf("sqh:\n");
2999 ehci_dump_sqh(sqh);
3000 ehci_dump_sqtds(data);
3001 }
3002 #endif
3003
3004 if (sc->sc_bus.use_polling)
3005 ehci_waitintr(sc, xfer);
3006
3007 return (USBD_IN_PROGRESS);
3008 #undef exfer
3009 }
3010
3011 void
3012 ehci_device_bulk_abort(usbd_xfer_handle xfer)
3013 {
3014 DPRINTF(("ehci_device_bulk_abort: xfer=%p\n", xfer));
3015 ehci_abort_xfer(xfer, USBD_CANCELLED);
3016 }
3017
3018
3019
3020
3021 void
3022 ehci_device_bulk_close(usbd_pipe_handle pipe)
3023 {
3024 ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
3025
3026 DPRINTF(("ehci_device_bulk_close: pipe=%p\n", pipe));
3027 ehci_close_pipe(pipe, sc->sc_async_head);
3028 }
3029
3030 void
3031 ehci_device_bulk_done(usbd_xfer_handle xfer)
3032 {
3033 struct ehci_xfer *ex = EXFER(xfer);
3034 ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
3035
3036
3037 DPRINTFN(10,("ehci_bulk_done: xfer=%p, actlen=%d\n",
3038 xfer, xfer->actlen));
3039
3040 if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
3041 ehci_del_intr_list(ex);
3042 ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL);
3043 }
3044
3045 DPRINTFN(5, ("ehci_bulk_done: length=%d\n", xfer->actlen));
3046 }
3047
3048
3049
3050 usbd_status
3051 ehci_device_setintr(ehci_softc_t *sc, ehci_soft_qh_t *sqh, int ival)
3052 {
3053 struct ehci_soft_islot *isp;
3054 int islot, lev;
3055
3056
3057 for (lev = EHCI_IPOLLRATES - 1; lev > 0; lev--)
3058 if (EHCI_ILEV_IVAL(lev) <= ival)
3059 break;
3060
3061
3062
3063 if (cold) {
3064
3065 sc->sc_rand = (sc->sc_rand + 192) % sc->sc_flsize;
3066 islot = EHCI_IQHIDX(lev, sc->sc_rand);
3067 } else
3068 islot = EHCI_IQHIDX(lev, arc4random());
3069
3070 sqh->islot = islot;
3071 isp = &sc->sc_islots[islot];
3072 ehci_add_qh(sqh, isp->sqh);
3073
3074 return (USBD_NORMAL_COMPLETION);
3075 }
3076
3077 usbd_status
3078 ehci_device_intr_transfer(usbd_xfer_handle xfer)
3079 {
3080 usbd_status err;
3081
3082
3083 err = usb_insert_transfer(xfer);
3084 if (err)
3085 return (err);
3086
3087
3088
3089
3090
3091 return (ehci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
3092 }
3093
3094 usbd_status
3095 ehci_device_intr_start(usbd_xfer_handle xfer)
3096 {
3097 #define exfer EXFER(xfer)
3098 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
3099 usbd_device_handle dev = xfer->pipe->device;
3100 ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
3101 ehci_soft_qtd_t *data, *dataend;
3102 ehci_soft_qh_t *sqh;
3103 usbd_status err;
3104 int len, isread, endpt;
3105 int s;
3106
3107 DPRINTFN(2, ("ehci_device_intr_start: xfer=%p len=%d flags=%d\n",
3108 xfer, xfer->length, xfer->flags));
3109
3110 if (sc->sc_dying)
3111 return (USBD_IOERROR);
3112
3113 #ifdef DIAGNOSTIC
3114 if (xfer->rqflags & URQ_REQUEST)
3115 panic("ehci_device_intr_start: a request");
3116 #endif
3117
3118 len = xfer->length;
3119 endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
3120 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3121 sqh = epipe->sqh;
3122
3123 epipe->u.intr.length = len;
3124
3125 err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, &data,
3126 &dataend);
3127 if (err) {
3128 DPRINTFN(-1, ("ehci_device_intr_start: no memory\n"));
3129 xfer->status = err;
3130 usb_transfer_complete(xfer);
3131 return (err);
3132 }
3133
3134 #ifdef EHCI_DEBUG
3135 if (ehcidebug > 5) {
3136 DPRINTF(("ehci_device_intr_start: data(1)\n"));
3137 ehci_dump_sqh(sqh);
3138 ehci_dump_sqtds(data);
3139 }
3140 #endif
3141
3142
3143 exfer->sqtdstart = data;
3144 exfer->sqtdend = dataend;
3145 #ifdef DIAGNOSTIC
3146 if (!exfer->isdone)
3147 printf("ehci_device_intr_start: not done, ex=%p\n", exfer);
3148 exfer->isdone = 0;
3149 #endif
3150
3151 s = splusb();
3152 ehci_set_qh_qtd(sqh, data);
3153 if (xfer->timeout && !sc->sc_bus.use_polling) {
3154 timeout_del(&xfer->timeout_handle);
3155 timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
3156 timeout_add(&xfer->timeout_handle, mstohz(xfer->timeout));
3157 }
3158 ehci_add_intr_list(sc, exfer);
3159 xfer->status = USBD_IN_PROGRESS;
3160 splx(s);
3161
3162 #ifdef EHCI_DEBUG
3163 if (ehcidebug > 10) {
3164 DPRINTF(("ehci_device_intr_start: data(2)\n"));
3165 delay(10000);
3166 DPRINTF(("ehci_device_intr_start: data(3)\n"));
3167 ehci_dump_regs(sc);
3168 printf("sqh:\n");
3169 ehci_dump_sqh(sqh);
3170 ehci_dump_sqtds(data);
3171 }
3172 #endif
3173
3174 if (sc->sc_bus.use_polling)
3175 ehci_waitintr(sc, xfer);
3176
3177 return (USBD_IN_PROGRESS);
3178 #undef exfer
3179 }
3180
3181 void
3182 ehci_device_intr_abort(usbd_xfer_handle xfer)
3183 {
3184 DPRINTFN(1, ("ehci_device_intr_abort: xfer=%p\n", xfer));
3185 if (xfer->pipe->intrxfer == xfer) {
3186 DPRINTFN(1, ("ehci_device_intr_abort: remove\n"));
3187 xfer->pipe->intrxfer = NULL;
3188 }
3189 ehci_abort_xfer(xfer, USBD_CANCELLED);
3190 }
3191
3192 void
3193 ehci_device_intr_close(usbd_pipe_handle pipe)
3194 {
3195 ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
3196 struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
3197 struct ehci_soft_islot *isp;
3198
3199 isp = &sc->sc_islots[epipe->sqh->islot];
3200 ehci_close_pipe(pipe, isp->sqh);
3201 }
3202
3203 void
3204 ehci_device_intr_done(usbd_xfer_handle xfer)
3205 {
3206 #define exfer EXFER(xfer)
3207 struct ehci_xfer *ex = EXFER(xfer);
3208 ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
3209 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
3210 ehci_soft_qtd_t *data, *dataend;
3211 ehci_soft_qh_t *sqh;
3212 usbd_status err;
3213 int len, isread, endpt, s;
3214
3215 DPRINTFN(10, ("ehci_device_intr_done: xfer=%p, actlen=%d\n",
3216 xfer, xfer->actlen));
3217
3218 if (xfer->pipe->repeat) {
3219 ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL);
3220
3221 len = epipe->u.intr.length;
3222 xfer->length = len;
3223 endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
3224 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3225 sqh = epipe->sqh;
3226
3227 err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
3228 &data, &dataend);
3229 if (err) {
3230 DPRINTFN(-1, ("ehci_device_intr_done: no memory\n"));
3231 xfer->status = err;
3232 return;
3233 }
3234
3235
3236 exfer->sqtdstart = data;
3237 exfer->sqtdend = dataend;
3238 #ifdef DIAGNOSTIC
3239 if (!exfer->isdone) {
3240 printf("ehci_device_intr_done: not done, ex=%p\n",
3241 exfer);
3242 }
3243 exfer->isdone = 0;
3244 #endif
3245
3246 s = splusb();
3247 ehci_set_qh_qtd(sqh, data);
3248 if (xfer->timeout && !sc->sc_bus.use_polling) {
3249 timeout_del(&xfer->timeout_handle);
3250 timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
3251 timeout_add(&xfer->timeout_handle,
3252 mstohz(xfer->timeout));
3253 }
3254 splx(s);
3255
3256 xfer->status = USBD_IN_PROGRESS;
3257 } else if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
3258 ehci_del_intr_list(ex);
3259 ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL);
3260 }
3261 #undef exfer
3262 }
3263
3264
3265
3266 usbd_status ehci_device_isoc_transfer(usbd_xfer_handle xfer) { return USBD_IOERROR; }
3267 usbd_status ehci_device_isoc_start(usbd_xfer_handle xfer) { return USBD_IOERROR; }
3268 void ehci_device_isoc_abort(usbd_xfer_handle xfer) { }
3269 void ehci_device_isoc_close(usbd_pipe_handle pipe) { }
3270 void ehci_device_isoc_done(usbd_xfer_handle xfer) { }