This source file includes following definitions.
- ohci_activate
- ohci_detach
- ohci_alloc_sed
- ohci_free_sed
- ohci_alloc_std
- ohci_free_std
- ohci_alloc_std_chain
- ohci_free_std_chain
- ohci_alloc_sitd
- ohci_free_sitd
- ohci_checkrev
- ohci_handover
- ohci_init
- ohci_allocm
- ohci_freem
- ohci_allocx
- ohci_freex
- ohci_shutdown
- ohci_power
- ohci_dumpregs
- ohci_intr
- ohci_intr1
- ohci_rhsc_able
- ohci_rhsc_enable
- ohci_add_done
- ohci_softintr
- ohci_device_ctrl_done
- ohci_device_intr_done
- ohci_device_bulk_done
- ohci_rhsc
- ohci_root_intr_done
- ohci_root_ctrl_done
- ohci_waitintr
- ohci_poll
- ohci_device_request
- ohci_add_ed
- ohci_rem_ed
- ohci_hash_add_td
- ohci_hash_rem_td
- ohci_hash_find_td
- ohci_hash_add_itd
- ohci_hash_rem_itd
- ohci_hash_find_itd
- ohci_timeout
- ohci_timeout_task
- ohci_dump_tds
- ohci_dump_td
- ohci_dump_itd
- ohci_dump_itds
- ohci_dump_ed
- ohci_open
- ohci_close_pipe
- ohci_abort_xfer
- ohci_str
- ohci_root_ctrl_transfer
- ohci_root_ctrl_start
- ohci_root_ctrl_abort
- ohci_root_ctrl_close
- ohci_root_intr_transfer
- ohci_root_intr_start
- ohci_root_intr_abort
- ohci_root_intr_close
- ohci_device_ctrl_transfer
- ohci_device_ctrl_start
- ohci_device_ctrl_abort
- ohci_device_ctrl_close
- ohci_device_clear_toggle
- ohci_noop
- ohci_device_bulk_transfer
- ohci_device_bulk_start
- ohci_device_bulk_abort
- ohci_device_bulk_close
- ohci_device_intr_transfer
- ohci_device_intr_start
- ohci_device_intr_abort
- ohci_device_intr_close
- ohci_device_setintr
- ohci_device_isoc_transfer
- ohci_device_isoc_enter
- ohci_device_isoc_start
- ohci_device_isoc_abort
- ohci_device_isoc_done
- ohci_setup_isoc
- ohci_device_isoc_close
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 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/malloc.h>
52 #include <sys/kernel.h>
53 #include <sys/device.h>
54 #include <sys/selinfo.h>
55 #include <sys/proc.h>
56 #include <sys/queue.h>
57
58 #include <machine/bus.h>
59 #include <machine/endian.h>
60
61 #include <dev/usb/usb.h>
62 #include <dev/usb/usbdi.h>
63 #include <dev/usb/usbdivar.h>
64 #include <dev/usb/usb_mem.h>
65 #include <dev/usb/usb_quirks.h>
66
67 #include <dev/usb/ohcireg.h>
68 #include <dev/usb/ohcivar.h>
69
70 struct cfdriver ohci_cd = {
71 NULL, "ohci", DV_DULL
72 };
73
74 #ifdef OHCI_DEBUG
75 #define DPRINTF(x) do { if (ohcidebug) printf x; } while (0)
76 #define DPRINTFN(n,x) do { if (ohcidebug>(n)) printf x; } while (0)
77 int ohcidebug = 0;
78 #define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
79 #else
80 #define DPRINTF(x)
81 #define DPRINTFN(n,x)
82 #endif
83
84 #define mstohz(ms) ((ms) * hz / 1000)
85
86
87
88
89
90
91 struct ohci_pipe;
92
93 ohci_soft_ed_t *ohci_alloc_sed(ohci_softc_t *);
94 void ohci_free_sed(ohci_softc_t *, ohci_soft_ed_t *);
95
96 ohci_soft_td_t *ohci_alloc_std(ohci_softc_t *);
97 void ohci_free_std(ohci_softc_t *, ohci_soft_td_t *);
98
99 ohci_soft_itd_t *ohci_alloc_sitd(ohci_softc_t *);
100 void ohci_free_sitd(ohci_softc_t *,ohci_soft_itd_t *);
101
102 #if 0
103 void ohci_free_std_chain(ohci_softc_t *, ohci_soft_td_t *,
104 ohci_soft_td_t *);
105 #endif
106 usbd_status ohci_alloc_std_chain(struct ohci_pipe *,
107 ohci_softc_t *, int, int, usbd_xfer_handle,
108 ohci_soft_td_t *, ohci_soft_td_t **);
109
110 void ohci_shutdown(void *v);
111 usbd_status ohci_open(usbd_pipe_handle);
112 void ohci_poll(struct usbd_bus *);
113 void ohci_softintr(void *);
114 void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle);
115 void ohci_add_done(ohci_softc_t *, ohci_physaddr_t);
116 void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle);
117
118 usbd_status ohci_device_request(usbd_xfer_handle xfer);
119 void ohci_add_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
120 void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
121 void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *);
122 void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *);
123 ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t);
124 void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *);
125 void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *);
126 ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t);
127
128 usbd_status ohci_setup_isoc(usbd_pipe_handle pipe);
129 void ohci_device_isoc_enter(usbd_xfer_handle);
130
131 usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
132 void ohci_freem(struct usbd_bus *, usb_dma_t *);
133
134 usbd_xfer_handle ohci_allocx(struct usbd_bus *);
135 void ohci_freex(struct usbd_bus *, usbd_xfer_handle);
136
137 usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle);
138 usbd_status ohci_root_ctrl_start(usbd_xfer_handle);
139 void ohci_root_ctrl_abort(usbd_xfer_handle);
140 void ohci_root_ctrl_close(usbd_pipe_handle);
141 void ohci_root_ctrl_done(usbd_xfer_handle);
142
143 usbd_status ohci_root_intr_transfer(usbd_xfer_handle);
144 usbd_status ohci_root_intr_start(usbd_xfer_handle);
145 void ohci_root_intr_abort(usbd_xfer_handle);
146 void ohci_root_intr_close(usbd_pipe_handle);
147 void ohci_root_intr_done(usbd_xfer_handle);
148
149 usbd_status ohci_device_ctrl_transfer(usbd_xfer_handle);
150 usbd_status ohci_device_ctrl_start(usbd_xfer_handle);
151 void ohci_device_ctrl_abort(usbd_xfer_handle);
152 void ohci_device_ctrl_close(usbd_pipe_handle);
153 void ohci_device_ctrl_done(usbd_xfer_handle);
154
155 usbd_status ohci_device_bulk_transfer(usbd_xfer_handle);
156 usbd_status ohci_device_bulk_start(usbd_xfer_handle);
157 void ohci_device_bulk_abort(usbd_xfer_handle);
158 void ohci_device_bulk_close(usbd_pipe_handle);
159 void ohci_device_bulk_done(usbd_xfer_handle);
160
161 usbd_status ohci_device_intr_transfer(usbd_xfer_handle);
162 usbd_status ohci_device_intr_start(usbd_xfer_handle);
163 void ohci_device_intr_abort(usbd_xfer_handle);
164 void ohci_device_intr_close(usbd_pipe_handle);
165 void ohci_device_intr_done(usbd_xfer_handle);
166
167 usbd_status ohci_device_isoc_transfer(usbd_xfer_handle);
168 usbd_status ohci_device_isoc_start(usbd_xfer_handle);
169 void ohci_device_isoc_abort(usbd_xfer_handle);
170 void ohci_device_isoc_close(usbd_pipe_handle);
171 void ohci_device_isoc_done(usbd_xfer_handle);
172
173 usbd_status ohci_device_setintr(ohci_softc_t *sc,
174 struct ohci_pipe *pipe, int ival);
175
176 int ohci_str(usb_string_descriptor_t *, int, const char *);
177
178 void ohci_timeout(void *);
179 void ohci_timeout_task(void *);
180 void ohci_rhsc_able(ohci_softc_t *, int);
181 void ohci_rhsc_enable(void *);
182
183 void ohci_close_pipe(usbd_pipe_handle, ohci_soft_ed_t *);
184 void ohci_abort_xfer(usbd_xfer_handle, usbd_status);
185
186 void ohci_device_clear_toggle(usbd_pipe_handle pipe);
187 void ohci_noop(usbd_pipe_handle pipe);
188
189 #ifdef OHCI_DEBUG
190 void ohci_dumpregs(ohci_softc_t *);
191 void ohci_dump_tds(ohci_soft_td_t *);
192 void ohci_dump_td(ohci_soft_td_t *);
193 void ohci_dump_ed(ohci_soft_ed_t *);
194 void ohci_dump_itd(ohci_soft_itd_t *);
195 void ohci_dump_itds(ohci_soft_itd_t *);
196 #endif
197
198 #define OBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
199 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
200 #define OWRITE1(sc, r, x) \
201 do { OBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
202 #define OWRITE2(sc, r, x) \
203 do { OBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
204 #define OWRITE4(sc, r, x) \
205 do { OBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
206 #define OREAD1(sc, r) (OBARR(sc), bus_space_read_1((sc)->iot, (sc)->ioh, (r)))
207 #define OREAD2(sc, r) (OBARR(sc), bus_space_read_2((sc)->iot, (sc)->ioh, (r)))
208 #define OREAD4(sc, r) (OBARR(sc), bus_space_read_4((sc)->iot, (sc)->ioh, (r)))
209
210
211 u_int8_t revbits[OHCI_NO_INTRS] =
212 { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c,
213 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e,
214 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d,
215 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f };
216
217 struct ohci_pipe {
218 struct usbd_pipe pipe;
219 ohci_soft_ed_t *sed;
220 union {
221 ohci_soft_td_t *td;
222 ohci_soft_itd_t *itd;
223 } tail;
224
225 union {
226
227 struct {
228 usb_dma_t reqdma;
229 u_int length;
230 ohci_soft_td_t *setup, *data, *stat;
231 } ctl;
232
233 struct {
234 int nslots;
235 int pos;
236 } intr;
237
238 struct {
239 u_int length;
240 int isread;
241 } bulk;
242
243 struct iso {
244 int next, inuse;
245 } iso;
246 } u;
247 };
248
249 #define OHCI_INTR_ENDPT 1
250
251 struct usbd_bus_methods ohci_bus_methods = {
252 ohci_open,
253 ohci_softintr,
254 ohci_poll,
255 ohci_allocm,
256 ohci_freem,
257 ohci_allocx,
258 ohci_freex,
259 };
260
261 struct usbd_pipe_methods ohci_root_ctrl_methods = {
262 ohci_root_ctrl_transfer,
263 ohci_root_ctrl_start,
264 ohci_root_ctrl_abort,
265 ohci_root_ctrl_close,
266 ohci_noop,
267 ohci_root_ctrl_done,
268 };
269
270 struct usbd_pipe_methods ohci_root_intr_methods = {
271 ohci_root_intr_transfer,
272 ohci_root_intr_start,
273 ohci_root_intr_abort,
274 ohci_root_intr_close,
275 ohci_noop,
276 ohci_root_intr_done,
277 };
278
279 struct usbd_pipe_methods ohci_device_ctrl_methods = {
280 ohci_device_ctrl_transfer,
281 ohci_device_ctrl_start,
282 ohci_device_ctrl_abort,
283 ohci_device_ctrl_close,
284 ohci_noop,
285 ohci_device_ctrl_done,
286 };
287
288 struct usbd_pipe_methods ohci_device_intr_methods = {
289 ohci_device_intr_transfer,
290 ohci_device_intr_start,
291 ohci_device_intr_abort,
292 ohci_device_intr_close,
293 ohci_device_clear_toggle,
294 ohci_device_intr_done,
295 };
296
297 struct usbd_pipe_methods ohci_device_bulk_methods = {
298 ohci_device_bulk_transfer,
299 ohci_device_bulk_start,
300 ohci_device_bulk_abort,
301 ohci_device_bulk_close,
302 ohci_device_clear_toggle,
303 ohci_device_bulk_done,
304 };
305
306 struct usbd_pipe_methods ohci_device_isoc_methods = {
307 ohci_device_isoc_transfer,
308 ohci_device_isoc_start,
309 ohci_device_isoc_abort,
310 ohci_device_isoc_close,
311 ohci_noop,
312 ohci_device_isoc_done,
313 };
314
315 int
316 ohci_activate(struct device *self, enum devact act)
317 {
318 struct ohci_softc *sc = (struct ohci_softc *)self;
319 int rv = 0;
320
321 switch (act) {
322 case DVACT_ACTIVATE:
323 break;
324
325 case DVACT_DEACTIVATE:
326 if (sc->sc_child != NULL)
327 rv = config_deactivate(sc->sc_child);
328 sc->sc_dying = 1;
329 break;
330 }
331 return (rv);
332 }
333
334 int
335 ohci_detach(struct ohci_softc *sc, int flags)
336 {
337 int rv = 0;
338
339 if (sc->sc_child != NULL)
340 rv = config_detach(sc->sc_child, flags);
341
342 if (rv != 0)
343 return (rv);
344
345 timeout_del(&sc->sc_tmo_rhsc);
346
347 if (sc->sc_shutdownhook != NULL)
348 shutdownhook_disestablish(sc->sc_shutdownhook);
349
350 usb_delay_ms(&sc->sc_bus, 300);
351
352
353
354 return (rv);
355 }
356
357 ohci_soft_ed_t *
358 ohci_alloc_sed(ohci_softc_t *sc)
359 {
360 ohci_soft_ed_t *sed;
361 usbd_status err;
362 int i, offs;
363 usb_dma_t dma;
364
365 if (sc->sc_freeeds == NULL) {
366 DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n"));
367 err = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK,
368 OHCI_ED_ALIGN, &dma);
369 if (err)
370 return (0);
371 for(i = 0; i < OHCI_SED_CHUNK; i++) {
372 offs = i * OHCI_SED_SIZE;
373 sed = KERNADDR(&dma, offs);
374 sed->physaddr = DMAADDR(&dma, offs);
375 sed->next = sc->sc_freeeds;
376 sc->sc_freeeds = sed;
377 }
378 }
379 sed = sc->sc_freeeds;
380 sc->sc_freeeds = sed->next;
381 memset(&sed->ed, 0, sizeof(ohci_ed_t));
382 sed->next = 0;
383 return (sed);
384 }
385
386 void
387 ohci_free_sed(ohci_softc_t *sc, ohci_soft_ed_t *sed)
388 {
389 sed->next = sc->sc_freeeds;
390 sc->sc_freeeds = sed;
391 }
392
393 ohci_soft_td_t *
394 ohci_alloc_std(ohci_softc_t *sc)
395 {
396 ohci_soft_td_t *std;
397 usbd_status err;
398 int i, offs;
399 usb_dma_t dma;
400 int s;
401
402 if (sc->sc_freetds == NULL) {
403 DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n"));
404 err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK,
405 OHCI_TD_ALIGN, &dma);
406 if (err)
407 return (NULL);
408 s = splusb();
409 for(i = 0; i < OHCI_STD_CHUNK; i++) {
410 offs = i * OHCI_STD_SIZE;
411 std = KERNADDR(&dma, offs);
412 std->physaddr = DMAADDR(&dma, offs);
413 std->nexttd = sc->sc_freetds;
414 sc->sc_freetds = std;
415 }
416 splx(s);
417 }
418
419 s = splusb();
420 std = sc->sc_freetds;
421 sc->sc_freetds = std->nexttd;
422 memset(&std->td, 0, sizeof(ohci_td_t));
423 std->nexttd = NULL;
424 std->xfer = NULL;
425 ohci_hash_add_td(sc, std);
426 splx(s);
427
428 return (std);
429 }
430
431 void
432 ohci_free_std(ohci_softc_t *sc, ohci_soft_td_t *std)
433 {
434 int s;
435
436 s = splusb();
437 ohci_hash_rem_td(sc, std);
438 std->nexttd = sc->sc_freetds;
439 sc->sc_freetds = std;
440 splx(s);
441 }
442
443 usbd_status
444 ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc,
445 int alen, int rd, usbd_xfer_handle xfer,
446 ohci_soft_td_t *sp, ohci_soft_td_t **ep)
447 {
448 ohci_soft_td_t *next, *cur;
449 ohci_physaddr_t dataphys, dataphysend;
450 u_int32_t tdflags;
451 int len, curlen;
452 usb_dma_t *dma = &xfer->dmabuf;
453 u_int16_t flags = xfer->flags;
454
455 DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen));
456
457 len = alen;
458 cur = sp;
459 dataphys = DMAADDR(dma, 0);
460 dataphysend = OHCI_PAGE(dataphys + len - 1);
461 tdflags = htole32(
462 (rd ? OHCI_TD_IN : OHCI_TD_OUT) |
463 (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) |
464 OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR);
465
466 for (;;) {
467 next = ohci_alloc_std(sc);
468 if (next == NULL)
469 goto nomem;
470
471
472 if (OHCI_PAGE(dataphys) == dataphysend ||
473 OHCI_PAGE(dataphys) + OHCI_PAGE_SIZE == dataphysend) {
474
475 curlen = len;
476 } else {
477
478 curlen = 2 * OHCI_PAGE_SIZE -
479 (dataphys & (OHCI_PAGE_SIZE-1));
480
481 curlen -= curlen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize);
482 #ifdef DIAGNOSTIC
483 if (curlen == 0)
484 panic("ohci_alloc_std: curlen == 0");
485 #endif
486 }
487 DPRINTFN(4,("ohci_alloc_std_chain: dataphys=0x%08x "
488 "dataphysend=0x%08x len=%d curlen=%d\n",
489 dataphys, dataphysend,
490 len, curlen));
491 len -= curlen;
492
493 cur->td.td_flags = tdflags;
494 cur->td.td_cbp = htole32(dataphys);
495 cur->nexttd = next;
496 cur->td.td_nexttd = htole32(next->physaddr);
497 cur->td.td_be = htole32(dataphys + curlen - 1);
498 cur->len = curlen;
499 cur->flags = OHCI_ADD_LEN;
500 cur->xfer = xfer;
501 DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n",
502 dataphys, dataphys + curlen - 1));
503 if (len == 0)
504 break;
505 DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n"));
506 dataphys += curlen;
507 cur = next;
508 }
509 if (!rd && (flags & USBD_FORCE_SHORT_XFER) &&
510 alen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize) == 0) {
511
512
513 cur = next;
514 next = ohci_alloc_std(sc);
515 if (next == NULL)
516 goto nomem;
517
518 cur->td.td_flags = tdflags;
519 cur->td.td_cbp = 0;
520 cur->nexttd = next;
521 cur->td.td_nexttd = htole32(next->physaddr);
522 cur->td.td_be = ~0;
523 cur->len = 0;
524 cur->flags = 0;
525 cur->xfer = xfer;
526 DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n"));
527 }
528 *ep = cur;
529
530 return (USBD_NORMAL_COMPLETION);
531
532 nomem:
533
534 return (USBD_NOMEM);
535 }
536
537 #if 0
538 void
539 ohci_free_std_chain(ohci_softc_t *sc, ohci_soft_td_t *std,
540 ohci_soft_td_t *stdend)
541 {
542 ohci_soft_td_t *p;
543
544 for (; std != stdend; std = p) {
545 p = std->nexttd;
546 ohci_free_std(sc, std);
547 }
548 }
549 #endif
550
551 ohci_soft_itd_t *
552 ohci_alloc_sitd(ohci_softc_t *sc)
553 {
554 ohci_soft_itd_t *sitd;
555 usbd_status err;
556 int i, s, offs;
557 usb_dma_t dma;
558
559 if (sc->sc_freeitds == NULL) {
560 DPRINTFN(2, ("ohci_alloc_sitd: allocating chunk\n"));
561 err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * OHCI_SITD_CHUNK,
562 OHCI_ITD_ALIGN, &dma);
563 if (err)
564 return (NULL);
565 s = splusb();
566 for(i = 0; i < OHCI_SITD_CHUNK; i++) {
567 offs = i * OHCI_SITD_SIZE;
568 sitd = KERNADDR(&dma, offs);
569 sitd->physaddr = DMAADDR(&dma, offs);
570 sitd->nextitd = sc->sc_freeitds;
571 sc->sc_freeitds = sitd;
572 }
573 splx(s);
574 }
575
576 s = splusb();
577 sitd = sc->sc_freeitds;
578 sc->sc_freeitds = sitd->nextitd;
579 memset(&sitd->itd, 0, sizeof(ohci_itd_t));
580 sitd->nextitd = NULL;
581 sitd->xfer = NULL;
582 ohci_hash_add_itd(sc, sitd);
583 splx(s);
584
585 #ifdef DIAGNOSTIC
586 sitd->isdone = 0;
587 #endif
588
589 return (sitd);
590 }
591
592 void
593 ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
594 {
595 int s;
596
597 DPRINTFN(10,("ohci_free_sitd: sitd=%p\n", sitd));
598
599 #ifdef DIAGNOSTIC
600 if (!sitd->isdone) {
601 panic("ohci_free_sitd: sitd=%p not done", sitd);
602 return;
603 }
604
605 sitd->isdone = 0;
606 #endif
607
608 s = splusb();
609 ohci_hash_rem_itd(sc, sitd);
610 sitd->nextitd = sc->sc_freeitds;
611 sc->sc_freeitds = sitd;
612 splx(s);
613 }
614
615 usbd_status
616 ohci_checkrev(ohci_softc_t *sc)
617 {
618 u_int32_t rev;
619
620 printf(",");
621 rev = OREAD4(sc, OHCI_REVISION);
622 printf(" version %d.%d%s\n", OHCI_REV_HI(rev), OHCI_REV_LO(rev),
623 OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
624
625 if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) {
626 printf("%s: unsupported OHCI revision\n",
627 sc->sc_bus.bdev.dv_xname);
628 sc->sc_bus.usbrev = USBREV_UNKNOWN;
629 return (USBD_INVAL);
630 }
631 sc->sc_bus.usbrev = USBREV_1_0;
632
633 return (USBD_NORMAL_COMPLETION);
634 }
635
636 usbd_status
637 ohci_handover(ohci_softc_t *sc)
638 {
639 u_int32_t s, ctl;
640 int i;
641
642 ctl = OREAD4(sc, OHCI_CONTROL);
643 if (ctl & OHCI_IR) {
644
645 DPRINTF(("ohci_handover: SMM active, request owner change\n"));
646 if ((sc->sc_intre & (OHCI_OC | OHCI_MIE)) ==
647 (OHCI_OC | OHCI_MIE))
648 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_MIE);
649 s = OREAD4(sc, OHCI_COMMAND_STATUS);
650 OWRITE4(sc, OHCI_COMMAND_STATUS, s | OHCI_OCR);
651 for (i = 0; i < 100 && (ctl & OHCI_IR); i++) {
652 usb_delay_ms(&sc->sc_bus, 1);
653 ctl = OREAD4(sc, OHCI_CONTROL);
654 }
655 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_MIE);
656 if (ctl & OHCI_IR) {
657 printf("%s: SMM does not respond, will reset\n",
658 sc->sc_bus.bdev.dv_xname);
659 }
660 }
661
662 return (USBD_NORMAL_COMPLETION);
663 }
664
665 usbd_status
666 ohci_init(ohci_softc_t *sc)
667 {
668 ohci_soft_ed_t *sed, *psed;
669 usbd_status err;
670 int i;
671 u_int32_t ctl, rwc, ival, hcr, fm, per, desca, descb;
672
673 DPRINTF(("ohci_init: start\n"));
674
675 for (i = 0; i < OHCI_HASH_SIZE; i++)
676 LIST_INIT(&sc->sc_hash_tds[i]);
677 for (i = 0; i < OHCI_HASH_SIZE; i++)
678 LIST_INIT(&sc->sc_hash_itds[i]);
679
680 SIMPLEQ_INIT(&sc->sc_free_xfers);
681
682
683
684 err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
685 OHCI_HCCA_ALIGN, &sc->sc_hccadma);
686 if (err)
687 return (err);
688 sc->sc_hcca = KERNADDR(&sc->sc_hccadma, 0);
689 memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE);
690
691 sc->sc_eintrs = OHCI_NORMAL_INTRS;
692
693
694 sc->sc_ctrl_head = ohci_alloc_sed(sc);
695 if (sc->sc_ctrl_head == NULL) {
696 err = USBD_NOMEM;
697 goto bad1;
698 }
699 sc->sc_ctrl_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
700
701
702 sc->sc_bulk_head = ohci_alloc_sed(sc);
703 if (sc->sc_bulk_head == NULL) {
704 err = USBD_NOMEM;
705 goto bad2;
706 }
707 sc->sc_bulk_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
708
709
710 sc->sc_isoc_head = ohci_alloc_sed(sc);
711 if (sc->sc_isoc_head == NULL) {
712 err = USBD_NOMEM;
713 goto bad3;
714 }
715 sc->sc_isoc_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
716
717
718 for (i = 0; i < OHCI_NO_EDS; i++) {
719 sed = ohci_alloc_sed(sc);
720 if (sed == NULL) {
721 while (--i >= 0)
722 ohci_free_sed(sc, sc->sc_eds[i]);
723 err = USBD_NOMEM;
724 goto bad4;
725 }
726
727 sc->sc_eds[i] = sed;
728 sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
729 if (i != 0)
730 psed = sc->sc_eds[(i-1) / 2];
731 else
732 psed= sc->sc_isoc_head;
733 sed->next = psed;
734 sed->ed.ed_nexted = htole32(psed->physaddr);
735 }
736
737
738
739
740 for (i = 0; i < OHCI_NO_INTRS; i++)
741 sc->sc_hcca->hcca_interrupt_table[revbits[i]] =
742 htole32(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr);
743
744 #ifdef OHCI_DEBUG
745 if (ohcidebug > 15) {
746 for (i = 0; i < OHCI_NO_EDS; i++) {
747 printf("ed#%d ", i);
748 ohci_dump_ed(sc->sc_eds[i]);
749 }
750 printf("iso ");
751 ohci_dump_ed(sc->sc_isoc_head);
752 }
753 #endif
754
755 ctl = OREAD4(sc, OHCI_CONTROL);
756 rwc = ctl & OHCI_RWC;
757 fm = OREAD4(sc, OHCI_FM_INTERVAL);
758 desca = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
759 descb = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
760
761
762 if (ctl & OHCI_IR) {
763 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET | rwc);
764 goto reset;
765 #if 0
766
767 } else if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_RESET) {
768
769 DPRINTF(("ohci_init: BIOS active\n"));
770 if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_OPERATIONAL) {
771 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_OPERATIONAL | rwc);
772 usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
773 }
774 #endif
775 } else {
776 DPRINTF(("ohci_init: cold started\n"));
777 reset:
778
779 usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
780 }
781
782
783
784
785
786 DPRINTF(("%s: resetting\n", sc->sc_bus.bdev.dv_xname));
787 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET | rwc);
788 usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
789
790
791
792 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_HCR);
793
794 for (i = 0; i < 10; i++) {
795 delay(10);
796 hcr = OREAD4(sc, OHCI_COMMAND_STATUS) & OHCI_HCR;
797 if (!hcr)
798 break;
799 }
800 if (hcr) {
801 printf("%s: reset timeout\n", sc->sc_bus.bdev.dv_xname);
802 err = USBD_IOERROR;
803 goto bad5;
804 }
805 #ifdef OHCI_DEBUG
806 if (ohcidebug > 15)
807 ohci_dumpregs(sc);
808 #endif
809
810
811
812
813 OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
814 OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
815 OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
816
817 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
818
819 ctl = OREAD4(sc, OHCI_CONTROL);
820 ctl &= ~(OHCI_CBSR_MASK | OHCI_LES | OHCI_HCFS_MASK | OHCI_IR);
821 ctl |= OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE |
822 OHCI_RATIO_1_4 | OHCI_HCFS_OPERATIONAL | rwc;
823
824 OWRITE4(sc, OHCI_CONTROL, ctl);
825
826
827
828
829
830
831 ival = OHCI_GET_IVAL(fm);
832 fm = (OREAD4(sc, OHCI_FM_REMAINING) & OHCI_FIT) ^ OHCI_FIT;
833 fm |= OHCI_FSMPS(ival) | ival;
834 OWRITE4(sc, OHCI_FM_INTERVAL, fm);
835 per = OHCI_PERIODIC(ival);
836 OWRITE4(sc, OHCI_PERIODIC_START, per);
837
838
839 OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca | OHCI_NOCP);
840 OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC);
841 usb_delay_ms(&sc->sc_bus, OHCI_ENABLE_POWER_DELAY);
842 OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca);
843 OWRITE4(sc, OHCI_RH_DESCRIPTOR_B, descb);
844 usb_delay_ms(&sc->sc_bus, OHCI_GET_POTPGT(desca) * UHD_PWRON_FACTOR);
845
846
847
848
849
850 sc->sc_noport = 0;
851 for (i = 0; i < 10 && sc->sc_noport == 0; i++) {
852 usb_delay_ms(&sc->sc_bus, OHCI_READ_DESC_DELAY);
853 sc->sc_noport = OHCI_GET_NDP(OREAD4(sc, OHCI_RH_DESCRIPTOR_A));
854 }
855
856 #ifdef OHCI_DEBUG
857 if (ohcidebug > 5)
858 ohci_dumpregs(sc);
859 #endif
860
861
862 sc->sc_bus.methods = &ohci_bus_methods;
863 sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
864
865 sc->sc_control = sc->sc_intre = 0;
866 sc->sc_shutdownhook = shutdownhook_establish(ohci_shutdown, sc);
867
868 timeout_set(&sc->sc_tmo_rhsc, NULL, NULL);
869
870
871 DPRINTFN(1,("ohci_init: enabling\n"));
872 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
873
874 return (USBD_NORMAL_COMPLETION);
875
876 bad5:
877 for (i = 0; i < OHCI_NO_EDS; i++)
878 ohci_free_sed(sc, sc->sc_eds[i]);
879 bad4:
880 ohci_free_sed(sc, sc->sc_isoc_head);
881 bad3:
882 ohci_free_sed(sc, sc->sc_bulk_head);
883 bad2:
884 ohci_free_sed(sc, sc->sc_ctrl_head);
885 bad1:
886 usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
887 return (err);
888 }
889
890 usbd_status
891 ohci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
892 {
893 struct ohci_softc *sc = (struct ohci_softc *)bus;
894
895 return (usb_allocmem(&sc->sc_bus, size, 0, dma));
896 }
897
898 void
899 ohci_freem(struct usbd_bus *bus, usb_dma_t *dma)
900 {
901 struct ohci_softc *sc = (struct ohci_softc *)bus;
902
903 usb_freemem(&sc->sc_bus, dma);
904 }
905
906 usbd_xfer_handle
907 ohci_allocx(struct usbd_bus *bus)
908 {
909 struct ohci_softc *sc = (struct ohci_softc *)bus;
910 usbd_xfer_handle xfer;
911
912 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
913 if (xfer != NULL) {
914 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
915 #ifdef DIAGNOSTIC
916 if (xfer->busy_free != XFER_FREE) {
917 printf("ohci_allocx: xfer=%p not free, 0x%08x\n", xfer,
918 xfer->busy_free);
919 }
920 #endif
921 } else {
922 xfer = malloc(sizeof(struct ohci_xfer), M_USB, M_NOWAIT);
923 }
924 if (xfer != NULL) {
925 memset(xfer, 0, sizeof (struct ohci_xfer));
926 #ifdef DIAGNOSTIC
927 xfer->busy_free = XFER_BUSY;
928 #endif
929 }
930 return (xfer);
931 }
932
933 void
934 ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
935 {
936 struct ohci_softc *sc = (struct ohci_softc *)bus;
937
938 #ifdef DIAGNOSTIC
939 if (xfer->busy_free != XFER_BUSY) {
940 printf("ohci_freex: xfer=%p not busy, 0x%08x\n", xfer,
941 xfer->busy_free);
942 return;
943 }
944 xfer->busy_free = XFER_FREE;
945 #endif
946 SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
947 }
948
949
950
951
952 void
953 ohci_shutdown(void *v)
954 {
955 ohci_softc_t *sc = v;
956
957 DPRINTF(("ohci_shutdown: stopping the HC\n"));
958 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
959 }
960
961
962
963
964
965
966
967
968 void
969 ohci_power(int why, void *v)
970 {
971 ohci_softc_t *sc = v;
972 u_int32_t reg;
973 int s;
974
975 #ifdef OHCI_DEBUG
976 DPRINTF(("ohci_power: sc=%p, why=%d\n", sc, why));
977 ohci_dumpregs(sc);
978 #endif
979
980 s = splhardusb();
981 switch (why) {
982 case PWR_SUSPEND:
983 case PWR_STANDBY:
984 sc->sc_bus.use_polling++;
985 reg = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
986 if (sc->sc_control == 0) {
987
988
989
990
991 sc->sc_control = reg;
992 sc->sc_intre = OREAD4(sc, OHCI_INTERRUPT_ENABLE);
993 sc->sc_ival = OHCI_GET_IVAL(OREAD4(sc,
994 OHCI_FM_INTERVAL));
995 }
996 reg |= OHCI_HCFS_SUSPEND;
997 OWRITE4(sc, OHCI_CONTROL, reg);
998 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
999 sc->sc_bus.use_polling--;
1000 break;
1001 case PWR_RESUME:
1002 sc->sc_bus.use_polling++;
1003
1004
1005 OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
1006 OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
1007 OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
1008 if (sc->sc_intre)
1009 OWRITE4(sc, OHCI_INTERRUPT_ENABLE,
1010 sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE));
1011 if (sc->sc_control)
1012 reg = sc->sc_control;
1013 else
1014 reg = OREAD4(sc, OHCI_CONTROL);
1015 reg |= OHCI_HCFS_RESUME;
1016 OWRITE4(sc, OHCI_CONTROL, reg);
1017 usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
1018 reg = (reg & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL;
1019 OWRITE4(sc, OHCI_CONTROL, reg);
1020
1021 reg = (OREAD4(sc, OHCI_FM_REMAINING) & OHCI_FIT) ^ OHCI_FIT;
1022 reg |= OHCI_FSMPS(sc->sc_ival) | sc->sc_ival;
1023 OWRITE4(sc, OHCI_FM_INTERVAL, reg);
1024 OWRITE4(sc, OHCI_PERIODIC_START, OHCI_PERIODIC(sc->sc_ival));
1025
1026
1027 reg = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
1028 OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, reg | OHCI_NOCP);
1029 OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC);
1030 usb_delay_ms(&sc->sc_bus, OHCI_ENABLE_POWER_DELAY);
1031 OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, reg);
1032
1033 usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
1034 sc->sc_control = sc->sc_intre = sc->sc_ival = 0;
1035 sc->sc_bus.use_polling--;
1036 break;
1037 }
1038 splx(s);
1039 }
1040
1041 #ifdef OHCI_DEBUG
1042 void
1043 ohci_dumpregs(ohci_softc_t *sc)
1044 {
1045 DPRINTF(("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n",
1046 OREAD4(sc, OHCI_REVISION),
1047 OREAD4(sc, OHCI_CONTROL),
1048 OREAD4(sc, OHCI_COMMAND_STATUS)));
1049 DPRINTF((" intrstat=0x%08x intre=0x%08x intrd=0x%08x\n",
1050 OREAD4(sc, OHCI_INTERRUPT_STATUS),
1051 OREAD4(sc, OHCI_INTERRUPT_ENABLE),
1052 OREAD4(sc, OHCI_INTERRUPT_DISABLE)));
1053 DPRINTF((" hcca=0x%08x percur=0x%08x ctrlhd=0x%08x\n",
1054 OREAD4(sc, OHCI_HCCA),
1055 OREAD4(sc, OHCI_PERIOD_CURRENT_ED),
1056 OREAD4(sc, OHCI_CONTROL_HEAD_ED)));
1057 DPRINTF((" ctrlcur=0x%08x bulkhd=0x%08x bulkcur=0x%08x\n",
1058 OREAD4(sc, OHCI_CONTROL_CURRENT_ED),
1059 OREAD4(sc, OHCI_BULK_HEAD_ED),
1060 OREAD4(sc, OHCI_BULK_CURRENT_ED)));
1061 DPRINTF((" done=0x%08x fmival=0x%08x fmrem=0x%08x\n",
1062 OREAD4(sc, OHCI_DONE_HEAD),
1063 OREAD4(sc, OHCI_FM_INTERVAL),
1064 OREAD4(sc, OHCI_FM_REMAINING)));
1065 DPRINTF((" fmnum=0x%08x perst=0x%08x lsthrs=0x%08x\n",
1066 OREAD4(sc, OHCI_FM_NUMBER),
1067 OREAD4(sc, OHCI_PERIODIC_START),
1068 OREAD4(sc, OHCI_LS_THRESHOLD)));
1069 DPRINTF((" desca=0x%08x descb=0x%08x stat=0x%08x\n",
1070 OREAD4(sc, OHCI_RH_DESCRIPTOR_A),
1071 OREAD4(sc, OHCI_RH_DESCRIPTOR_B),
1072 OREAD4(sc, OHCI_RH_STATUS)));
1073 DPRINTF((" port1=0x%08x port2=0x%08x\n",
1074 OREAD4(sc, OHCI_RH_PORT_STATUS(1)),
1075 OREAD4(sc, OHCI_RH_PORT_STATUS(2))));
1076 DPRINTF((" HCCA: frame_number=0x%04x done_head=0x%08x\n",
1077 letoh32(sc->sc_hcca->hcca_frame_number),
1078 letoh32(sc->sc_hcca->hcca_done_head)));
1079 }
1080 #endif
1081
1082 int ohci_intr1(ohci_softc_t *);
1083
1084 int
1085 ohci_intr(void *p)
1086 {
1087 ohci_softc_t *sc = p;
1088
1089 if (sc == NULL || sc->sc_dying)
1090 return (0);
1091
1092
1093 if (!cold && sc->sc_bus.use_polling) {
1094 #ifdef DIAGNOSTIC
1095 static struct timeval ohci_intr_tv;
1096 if ((OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs) &&
1097 usbd_ratecheck(&ohci_intr_tv))
1098 DPRINTFN(16,
1099 ("ohci_intr: ignored interrupt while polling\n"));
1100 #endif
1101 return (0);
1102 }
1103
1104 return (ohci_intr1(sc));
1105 }
1106
1107 int
1108 ohci_intr1(ohci_softc_t *sc)
1109 {
1110 u_int32_t intrs, eintrs;
1111 ohci_physaddr_t done;
1112
1113 DPRINTFN(14,("ohci_intr1: enter\n"));
1114
1115
1116 if (sc == NULL || sc->sc_hcca == NULL) {
1117 #ifdef DIAGNOSTIC
1118 printf("ohci_intr: sc->sc_hcca == NULL\n");
1119 #endif
1120 return (0);
1121 }
1122
1123 intrs = 0;
1124 done = letoh32(sc->sc_hcca->hcca_done_head);
1125 if (done != 0) {
1126 if (done & ~OHCI_DONE_INTRS)
1127 intrs = OHCI_WDH;
1128 if (done & OHCI_DONE_INTRS)
1129 intrs |= OREAD4(sc, OHCI_INTERRUPT_STATUS);
1130 sc->sc_hcca->hcca_done_head = 0;
1131 } else {
1132 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS);
1133
1134 if (intrs & OHCI_WDH) {
1135 done = letoh32(sc->sc_hcca->hcca_done_head);
1136 sc->sc_hcca->hcca_done_head = 0;
1137 }
1138 }
1139
1140 if (!intrs)
1141 return (0);
1142
1143 intrs &= ~OHCI_MIE;
1144 OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs);
1145 eintrs = intrs & sc->sc_eintrs;
1146 if (!eintrs)
1147 return (0);
1148
1149 sc->sc_bus.intr_context++;
1150 sc->sc_bus.no_intrs++;
1151 DPRINTFN(7, ("ohci_intr: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n",
1152 sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS),
1153 (u_int)eintrs));
1154
1155 if (eintrs & OHCI_SO) {
1156 sc->sc_overrun_cnt++;
1157 if (usbd_ratecheck(&sc->sc_overrun_ntc)) {
1158 printf("%s: %u scheduling overruns\n",
1159 sc->sc_bus.bdev.dv_xname, sc->sc_overrun_cnt);
1160 sc->sc_overrun_cnt = 0;
1161 }
1162
1163 eintrs &= ~OHCI_SO;
1164 }
1165 if (eintrs & OHCI_WDH) {
1166 ohci_add_done(sc, done &~ OHCI_DONE_INTRS);
1167 usb_schedsoftintr(&sc->sc_bus);
1168 eintrs &= ~OHCI_WDH;
1169 }
1170 if (eintrs & OHCI_RD) {
1171 printf("%s: resume detect\n", sc->sc_bus.bdev.dv_xname);
1172
1173 }
1174 if (eintrs & OHCI_UE) {
1175 printf("%s: unrecoverable error, controller halted\n",
1176 sc->sc_bus.bdev.dv_xname);
1177 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
1178
1179 }
1180 if (eintrs & OHCI_RHSC) {
1181 ohci_rhsc(sc, sc->sc_intrxfer);
1182
1183
1184
1185
1186 ohci_rhsc_able(sc, 0);
1187 DPRINTFN(2, ("%s: rhsc interrupt disabled\n",
1188 sc->sc_bus.bdev.dv_xname));
1189
1190
1191 timeout_del(&sc->sc_tmo_rhsc);
1192 timeout_set(&sc->sc_tmo_rhsc, ohci_rhsc_enable, sc);
1193 timeout_add(&sc->sc_tmo_rhsc, hz);
1194 eintrs &= ~OHCI_RHSC;
1195 }
1196
1197 sc->sc_bus.intr_context--;
1198
1199 if (eintrs != 0) {
1200
1201 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, eintrs);
1202 sc->sc_eintrs &= ~eintrs;
1203 printf("%s: blocking intrs 0x%x\n",
1204 sc->sc_bus.bdev.dv_xname, eintrs);
1205 }
1206
1207 return (1);
1208 }
1209
1210 void
1211 ohci_rhsc_able(ohci_softc_t *sc, int on)
1212 {
1213 DPRINTFN(4, ("ohci_rhsc_able: on=%d\n", on));
1214 if (on) {
1215 sc->sc_eintrs |= OHCI_RHSC;
1216 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC);
1217 } else {
1218 sc->sc_eintrs &= ~OHCI_RHSC;
1219 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_RHSC);
1220 }
1221 }
1222
1223 void
1224 ohci_rhsc_enable(void *v_sc)
1225 {
1226 ohci_softc_t *sc = v_sc;
1227 int s;
1228
1229 s = splhardusb();
1230 ohci_rhsc(sc, sc->sc_intrxfer);
1231 DPRINTFN(2, ("%s: rhsc interrupt enabled\n",
1232 sc->sc_bus.bdev.dv_xname));
1233
1234 ohci_rhsc_able(sc, 1);
1235 splx(s);
1236 }
1237
1238 #ifdef OHCI_DEBUG
1239 char *ohci_cc_strs[] = {
1240 "NO_ERROR",
1241 "CRC",
1242 "BIT_STUFFING",
1243 "DATA_TOGGLE_MISMATCH",
1244 "STALL",
1245 "DEVICE_NOT_RESPONDING",
1246 "PID_CHECK_FAILURE",
1247 "UNEXPECTED_PID",
1248 "DATA_OVERRUN",
1249 "DATA_UNDERRUN",
1250 "BUFFER_OVERRUN",
1251 "BUFFER_UNDERRUN",
1252 "reserved",
1253 "reserved",
1254 "NOT_ACCESSED",
1255 "NOT_ACCESSED",
1256 };
1257 #endif
1258
1259 void
1260 ohci_add_done(ohci_softc_t *sc, ohci_physaddr_t done)
1261 {
1262 ohci_soft_itd_t *sitd, *sidone, **ip;
1263 ohci_soft_td_t *std, *sdone, **p;
1264
1265
1266 for (sdone = NULL, sidone = NULL; done != 0; ) {
1267 std = ohci_hash_find_td(sc, done);
1268 if (std != NULL) {
1269 std->dnext = sdone;
1270 done = letoh32(std->td.td_nexttd);
1271 sdone = std;
1272 DPRINTFN(10,("add TD %p\n", std));
1273 continue;
1274 }
1275 sitd = ohci_hash_find_itd(sc, done);
1276 if (sitd != NULL) {
1277 sitd->dnext = sidone;
1278 done = letoh32(sitd->itd.itd_nextitd);
1279 sidone = sitd;
1280 DPRINTFN(5,("add ITD %p\n", sitd));
1281 continue;
1282 }
1283 panic("ohci_add_done: addr 0x%08lx not found", (u_long)done);
1284 }
1285
1286
1287
1288 for (p = &sc->sc_sdone; *p != NULL; p = &(*p)->dnext)
1289 ;
1290 *p = sdone;
1291 for (ip = &sc->sc_sidone; *ip != NULL; ip = &(*ip)->dnext)
1292 ;
1293 *ip = sidone;
1294 }
1295
1296 void
1297 ohci_softintr(void *v)
1298 {
1299 ohci_softc_t *sc = v;
1300 ohci_soft_itd_t *sitd, *sidone, *sitdnext;
1301 ohci_soft_td_t *std, *sdone, *stdnext;
1302 usbd_xfer_handle xfer;
1303 struct ohci_pipe *opipe;
1304 int len, cc, s;
1305 int i, j, actlen, iframes, uedir;
1306
1307 DPRINTFN(10,("ohci_softintr: enter\n"));
1308
1309 sc->sc_bus.intr_context++;
1310
1311 s = splhardusb();
1312 sdone = sc->sc_sdone;
1313 sc->sc_sdone = NULL;
1314 sidone = sc->sc_sidone;
1315 sc->sc_sidone = NULL;
1316 splx(s);
1317
1318 DPRINTFN(10,("ohci_softintr: sdone=%p sidone=%p\n", sdone, sidone));
1319
1320 #ifdef OHCI_DEBUG
1321 if (ohcidebug > 10) {
1322 DPRINTF(("ohci_process_done: TD done:\n"));
1323 ohci_dump_tds(sdone);
1324 }
1325 #endif
1326
1327 for (std = sdone; std; std = stdnext) {
1328 xfer = std->xfer;
1329 stdnext = std->dnext;
1330 DPRINTFN(10, ("ohci_process_done: std=%p xfer=%p hcpriv=%p\n",
1331 std, xfer, xfer ? xfer->hcpriv : 0));
1332 if (xfer == NULL) {
1333
1334
1335
1336
1337
1338
1339 continue;
1340 }
1341 if (xfer->status == USBD_CANCELLED ||
1342 xfer->status == USBD_TIMEOUT) {
1343 DPRINTF(("ohci_process_done: cancel/timeout %p\n",
1344 xfer));
1345
1346 continue;
1347 }
1348 timeout_del(&xfer->timeout_handle);
1349
1350 len = std->len;
1351 if (std->td.td_cbp != 0)
1352 len -= letoh32(std->td.td_be) -
1353 letoh32(std->td.td_cbp) + 1;
1354 DPRINTFN(10, ("ohci_process_done: len=%d, flags=0x%x\n", len,
1355 std->flags));
1356 if (std->flags & OHCI_ADD_LEN)
1357 xfer->actlen += len;
1358
1359 cc = OHCI_TD_GET_CC(letoh32(std->td.td_flags));
1360 if (cc == OHCI_CC_NO_ERROR) {
1361 if (std->flags & OHCI_CALL_DONE) {
1362 xfer->status = USBD_NORMAL_COMPLETION;
1363 s = splusb();
1364 usb_transfer_complete(xfer);
1365 splx(s);
1366 }
1367 ohci_free_std(sc, std);
1368 } else {
1369
1370
1371
1372
1373
1374 ohci_soft_td_t *p, *n;
1375 opipe = (struct ohci_pipe *)xfer->pipe;
1376
1377 DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n",
1378 OHCI_TD_GET_CC(letoh32(std->td.td_flags)),
1379 ohci_cc_strs[OHCI_TD_GET_CC(letoh32(std->td.td_flags))]));
1380
1381
1382 for (p = std; p->xfer == xfer; p = n) {
1383 n = p->nexttd;
1384 ohci_free_std(sc, p);
1385 }
1386
1387
1388 opipe->sed->ed.ed_headp = htole32(p->physaddr);
1389 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
1390
1391 if (cc == OHCI_CC_STALL)
1392 xfer->status = USBD_STALLED;
1393 else
1394 xfer->status = USBD_IOERROR;
1395 s = splusb();
1396 usb_transfer_complete(xfer);
1397 splx(s);
1398 }
1399 }
1400
1401 #ifdef OHCI_DEBUG
1402 if (ohcidebug > 10) {
1403 DPRINTF(("ohci_softintr: ITD done:\n"));
1404 ohci_dump_itds(sidone);
1405 }
1406 #endif
1407
1408 for (sitd = sidone; sitd != NULL; sitd = sitdnext) {
1409 xfer = sitd->xfer;
1410 sitdnext = sitd->dnext;
1411 DPRINTFN(1, ("ohci_process_done: sitd=%p xfer=%p hcpriv=%p\n",
1412 sitd, xfer, xfer ? xfer->hcpriv : 0));
1413 if (xfer == NULL)
1414 continue;
1415 if (xfer->status == USBD_CANCELLED ||
1416 xfer->status == USBD_TIMEOUT) {
1417 DPRINTF(("ohci_process_done: cancel/timeout %p\n",
1418 xfer));
1419
1420 continue;
1421 }
1422 #ifdef DIAGNOSTIC
1423 if (sitd->isdone)
1424 printf("ohci_softintr: sitd=%p is done\n", sitd);
1425 sitd->isdone = 1;
1426 #endif
1427 if (sitd->flags & OHCI_CALL_DONE) {
1428 ohci_soft_itd_t *next;
1429
1430 opipe = (struct ohci_pipe *)xfer->pipe;
1431 opipe->u.iso.inuse -= xfer->nframes;
1432 uedir = UE_GET_DIR(xfer->pipe->endpoint->edesc->
1433 bEndpointAddress);
1434 xfer->status = USBD_NORMAL_COMPLETION;
1435 actlen = 0;
1436 for (i = 0, sitd = xfer->hcpriv;;
1437 sitd = next) {
1438 next = sitd->nextitd;
1439 if (OHCI_ITD_GET_CC(letoh32(sitd->
1440 itd.itd_flags)) != OHCI_CC_NO_ERROR)
1441 xfer->status = USBD_IOERROR;
1442
1443
1444 if (uedir == UE_DIR_IN &&
1445 xfer->status == USBD_NORMAL_COMPLETION) {
1446 iframes = OHCI_ITD_GET_FC(letoh32(
1447 sitd->itd.itd_flags));
1448 for (j = 0; j < iframes; i++, j++) {
1449 len = letoh16(sitd->
1450 itd.itd_offset[j]);
1451 if ((OHCI_ITD_PSW_GET_CC(len) &
1452 OHCI_CC_NOT_ACCESSED_MASK)
1453 == OHCI_CC_NOT_ACCESSED)
1454 len = 0;
1455 else
1456 len = OHCI_ITD_PSW_LENGTH(len);
1457 xfer->frlengths[i] = len;
1458 actlen += len;
1459 }
1460 }
1461 if (sitd->flags & OHCI_CALL_DONE)
1462 break;
1463 ohci_free_sitd(sc, sitd);
1464 }
1465 ohci_free_sitd(sc, sitd);
1466 if (uedir == UE_DIR_IN &&
1467 xfer->status == USBD_NORMAL_COMPLETION)
1468 xfer->actlen = actlen;
1469 xfer->hcpriv = NULL;
1470
1471 s = splusb();
1472 usb_transfer_complete(xfer);
1473 splx(s);
1474 }
1475 }
1476
1477 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
1478 if (sc->sc_softwake) {
1479 sc->sc_softwake = 0;
1480 wakeup(&sc->sc_softwake);
1481 }
1482 #endif
1483
1484 sc->sc_bus.intr_context--;
1485 DPRINTFN(10,("ohci_softintr: done:\n"));
1486 }
1487
1488 void
1489 ohci_device_ctrl_done(usbd_xfer_handle xfer)
1490 {
1491 DPRINTFN(10,("ohci_device_ctrl_done: xfer=%p\n", xfer));
1492
1493 #ifdef DIAGNOSTIC
1494 if (!(xfer->rqflags & URQ_REQUEST)) {
1495 panic("ohci_device_ctrl_done: not a request");
1496 }
1497 #endif
1498 }
1499
1500 void
1501 ohci_device_intr_done(usbd_xfer_handle xfer)
1502 {
1503 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
1504 ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
1505 ohci_soft_ed_t *sed = opipe->sed;
1506 ohci_soft_td_t *data, *tail;
1507
1508
1509 DPRINTFN(10, ("ohci_device_intr_done: xfer=%p, actlen=%d\n", xfer,
1510 xfer->actlen));
1511
1512 if (xfer->pipe->repeat) {
1513 data = opipe->tail.td;
1514 tail = ohci_alloc_std(sc);
1515 if (tail == NULL) {
1516 xfer->status = USBD_NOMEM;
1517 return;
1518 }
1519 tail->xfer = NULL;
1520
1521 data->td.td_flags = htole32(
1522 OHCI_TD_IN | OHCI_TD_NOCC |
1523 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
1524 if (xfer->flags & USBD_SHORT_XFER_OK)
1525 data->td.td_flags |= htole32(OHCI_TD_R);
1526 data->td.td_cbp = htole32(DMAADDR(&xfer->dmabuf, 0));
1527 data->nexttd = tail;
1528 data->td.td_nexttd = htole32(tail->physaddr);
1529 data->td.td_be = htole32(letoh32(data->td.td_cbp) +
1530 xfer->length - 1);
1531 data->len = xfer->length;
1532 data->xfer = xfer;
1533 data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
1534 xfer->hcpriv = data;
1535 xfer->actlen = 0;
1536
1537 sed->ed.ed_tailp = htole32(tail->physaddr);
1538 opipe->tail.td = tail;
1539 }
1540 }
1541
1542 void
1543 ohci_device_bulk_done(usbd_xfer_handle xfer)
1544 {
1545 DPRINTFN(10, ("ohci_device_bulk_done: xfer=%p, actlen=%d\n", xfer,
1546 xfer->actlen));
1547 }
1548
1549 void
1550 ohci_rhsc(ohci_softc_t *sc, usbd_xfer_handle xfer)
1551 {
1552 usbd_pipe_handle pipe;
1553 u_char *p;
1554 int i, m;
1555 int hstatus;
1556
1557 hstatus = OREAD4(sc, OHCI_RH_STATUS);
1558 DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n",
1559 sc, xfer, hstatus));
1560
1561 if (xfer == NULL) {
1562
1563 return;
1564 }
1565
1566 pipe = xfer->pipe;
1567
1568 p = KERNADDR(&xfer->dmabuf, 0);
1569 m = min(sc->sc_noport, xfer->length * 8 - 1);
1570 memset(p, 0, xfer->length);
1571 for (i = 1; i <= m; i++) {
1572
1573 if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16)
1574 p[i/8] |= 1 << (i%8);
1575 }
1576 DPRINTF(("ohci_rhsc: change=0x%02x\n", *p));
1577 xfer->actlen = xfer->length;
1578 xfer->status = USBD_NORMAL_COMPLETION;
1579
1580 usb_transfer_complete(xfer);
1581 }
1582
1583 void
1584 ohci_root_intr_done(usbd_xfer_handle xfer)
1585 {
1586 }
1587
1588 void
1589 ohci_root_ctrl_done(usbd_xfer_handle xfer)
1590 {
1591 }
1592
1593
1594
1595
1596
1597
1598 void
1599 ohci_waitintr(ohci_softc_t *sc, usbd_xfer_handle xfer)
1600 {
1601 int timo;
1602 u_int32_t intrs;
1603
1604 xfer->status = USBD_IN_PROGRESS;
1605 for (timo = xfer->timeout; timo >= 0; timo--) {
1606 usb_delay_ms(&sc->sc_bus, 1);
1607 if (sc->sc_dying)
1608 break;
1609 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs;
1610 DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs));
1611 #ifdef OHCI_DEBUG
1612 if (ohcidebug > 15)
1613 ohci_dumpregs(sc);
1614 #endif
1615 if (intrs) {
1616 ohci_intr1(sc);
1617 if (xfer->status != USBD_IN_PROGRESS)
1618 return;
1619 }
1620 }
1621
1622
1623 DPRINTF(("ohci_waitintr: timeout\n"));
1624 xfer->status = USBD_TIMEOUT;
1625 usb_transfer_complete(xfer);
1626
1627 }
1628
1629 void
1630 ohci_poll(struct usbd_bus *bus)
1631 {
1632 ohci_softc_t *sc = (ohci_softc_t *)bus;
1633 #ifdef OHCI_DEBUG
1634 static int last;
1635 int new;
1636 new = OREAD4(sc, OHCI_INTERRUPT_STATUS);
1637 if (new != last) {
1638 DPRINTFN(10,("ohci_poll: intrs=0x%04x\n", new));
1639 last = new;
1640 }
1641 #endif
1642
1643 if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs)
1644 ohci_intr1(sc);
1645 }
1646
1647 usbd_status
1648 ohci_device_request(usbd_xfer_handle xfer)
1649 {
1650 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
1651 usb_device_request_t *req = &xfer->request;
1652 usbd_device_handle dev = opipe->pipe.device;
1653 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
1654 int addr = dev->address;
1655 ohci_soft_td_t *setup, *stat, *next, *tail;
1656 ohci_soft_ed_t *sed;
1657 int isread;
1658 int len;
1659 usbd_status err;
1660 int s;
1661
1662 isread = req->bmRequestType & UT_READ;
1663 len = UGETW(req->wLength);
1664
1665 DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, "
1666 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
1667 req->bmRequestType, req->bRequest, UGETW(req->wValue),
1668 UGETW(req->wIndex), len, addr,
1669 opipe->pipe.endpoint->edesc->bEndpointAddress));
1670
1671 setup = opipe->tail.td;
1672 stat = ohci_alloc_std(sc);
1673 if (stat == NULL) {
1674 err = USBD_NOMEM;
1675 goto bad1;
1676 }
1677 tail = ohci_alloc_std(sc);
1678 if (tail == NULL) {
1679 err = USBD_NOMEM;
1680 goto bad2;
1681 }
1682 tail->xfer = NULL;
1683
1684 sed = opipe->sed;
1685 opipe->u.ctl.length = len;
1686
1687
1688
1689
1690
1691 sed->ed.ed_flags = htole32(
1692 (letoh32(sed->ed.ed_flags) & ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) |
1693 OHCI_ED_SET_FA(addr) |
1694 OHCI_ED_SET_MAXP(UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize)));
1695
1696 next = stat;
1697
1698
1699 if (len != 0) {
1700 ohci_soft_td_t *std = stat;
1701
1702 err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer,
1703 std, &stat);
1704 stat = stat->nexttd;
1705 if (err)
1706 goto bad3;
1707
1708 std->td.td_flags &= htole32(~OHCI_TD_TOGGLE_MASK);
1709 std->td.td_flags |= htole32(OHCI_TD_TOGGLE_1);
1710 }
1711
1712 memcpy(KERNADDR(&opipe->u.ctl.reqdma, 0), req, sizeof *req);
1713
1714 setup->td.td_flags = htole32(OHCI_TD_SETUP | OHCI_TD_NOCC |
1715 OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR);
1716 setup->td.td_cbp = htole32(DMAADDR(&opipe->u.ctl.reqdma, 0));
1717 setup->nexttd = next;
1718 setup->td.td_nexttd = htole32(next->physaddr);
1719 setup->td.td_be = htole32(letoh32(setup->td.td_cbp) + sizeof *req - 1);
1720 setup->len = 0;
1721 setup->xfer = xfer;
1722 setup->flags = 0;
1723 xfer->hcpriv = setup;
1724
1725 stat->td.td_flags = htole32(
1726 (isread ? OHCI_TD_OUT : OHCI_TD_IN) |
1727 OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1));
1728 stat->td.td_cbp = 0;
1729 stat->nexttd = tail;
1730 stat->td.td_nexttd = htole32(tail->physaddr);
1731 stat->td.td_be = 0;
1732 stat->flags = OHCI_CALL_DONE;
1733 stat->len = 0;
1734 stat->xfer = xfer;
1735
1736 #ifdef OHCI_DEBUG
1737 if (ohcidebug > 5) {
1738 DPRINTF(("ohci_device_request:\n"));
1739 ohci_dump_ed(sed);
1740 ohci_dump_tds(setup);
1741 }
1742 #endif
1743
1744
1745 s = splusb();
1746 sed->ed.ed_tailp = htole32(tail->physaddr);
1747 opipe->tail.td = tail;
1748 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
1749 if (xfer->timeout && !sc->sc_bus.use_polling) {
1750 timeout_del(&xfer->timeout_handle);
1751 timeout_set(&xfer->timeout_handle, ohci_timeout, xfer);
1752 timeout_add(&xfer->timeout_handle, mstohz(xfer->timeout));
1753 }
1754 splx(s);
1755
1756 #ifdef OHCI_DEBUG
1757 if (ohcidebug > 20) {
1758 delay(10000);
1759 DPRINTF(("ohci_device_request: status=%x\n",
1760 OREAD4(sc, OHCI_COMMAND_STATUS)));
1761 ohci_dumpregs(sc);
1762 printf("ctrl head:\n");
1763 ohci_dump_ed(sc->sc_ctrl_head);
1764 printf("sed:\n");
1765 ohci_dump_ed(sed);
1766 ohci_dump_tds(setup);
1767 }
1768 #endif
1769
1770 return (USBD_NORMAL_COMPLETION);
1771
1772 bad3:
1773 ohci_free_std(sc, tail);
1774 bad2:
1775 ohci_free_std(sc, stat);
1776 bad1:
1777 return (err);
1778 }
1779
1780
1781
1782
1783 void
1784 ohci_add_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
1785 {
1786 DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head));
1787
1788 SPLUSBCHECK;
1789 sed->next = head->next;
1790 sed->ed.ed_nexted = head->ed.ed_nexted;
1791 head->next = sed;
1792 head->ed.ed_nexted = htole32(sed->physaddr);
1793 }
1794
1795
1796
1797
1798 void
1799 ohci_rem_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
1800 {
1801 ohci_soft_ed_t *p;
1802
1803 SPLUSBCHECK;
1804
1805
1806 for (p = head; p != NULL && p->next != sed; p = p->next)
1807 ;
1808 if (p == NULL)
1809 panic("ohci_rem_ed: ED not found");
1810 p->next = sed->next;
1811 p->ed.ed_nexted = sed->ed.ed_nexted;
1812 }
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824 #define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE)
1825
1826 void
1827 ohci_hash_add_td(ohci_softc_t *sc, ohci_soft_td_t *std)
1828 {
1829 int h = HASH(std->physaddr);
1830
1831 SPLUSBCHECK;
1832
1833 LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
1834 }
1835
1836
1837 void
1838 ohci_hash_rem_td(ohci_softc_t *sc, ohci_soft_td_t *std)
1839 {
1840 SPLUSBCHECK;
1841
1842 LIST_REMOVE(std, hnext);
1843 }
1844
1845 ohci_soft_td_t *
1846 ohci_hash_find_td(ohci_softc_t *sc, ohci_physaddr_t a)
1847 {
1848 int h = HASH(a);
1849 ohci_soft_td_t *std;
1850
1851 for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
1852 std != NULL;
1853 std = LIST_NEXT(std, hnext))
1854 if (std->physaddr == a)
1855 return (std);
1856 return (NULL);
1857 }
1858
1859
1860 void
1861 ohci_hash_add_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
1862 {
1863 int h = HASH(sitd->physaddr);
1864
1865 SPLUSBCHECK;
1866
1867 DPRINTFN(10,("ohci_hash_add_itd: sitd=%p physaddr=0x%08lx\n",
1868 sitd, (u_long)sitd->physaddr));
1869
1870 LIST_INSERT_HEAD(&sc->sc_hash_itds[h], sitd, hnext);
1871 }
1872
1873
1874 void
1875 ohci_hash_rem_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
1876 {
1877 SPLUSBCHECK;
1878
1879 DPRINTFN(10,("ohci_hash_rem_itd: sitd=%p physaddr=0x%08lx\n",
1880 sitd, (u_long)sitd->physaddr));
1881
1882 LIST_REMOVE(sitd, hnext);
1883 }
1884
1885 ohci_soft_itd_t *
1886 ohci_hash_find_itd(ohci_softc_t *sc, ohci_physaddr_t a)
1887 {
1888 int h = HASH(a);
1889 ohci_soft_itd_t *sitd;
1890
1891 for (sitd = LIST_FIRST(&sc->sc_hash_itds[h]);
1892 sitd != NULL;
1893 sitd = LIST_NEXT(sitd, hnext))
1894 if (sitd->physaddr == a)
1895 return (sitd);
1896 return (NULL);
1897 }
1898
1899 void
1900 ohci_timeout(void *addr)
1901 {
1902 struct ohci_xfer *oxfer = addr;
1903 struct ohci_pipe *opipe = (struct ohci_pipe *)oxfer->xfer.pipe;
1904 ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
1905
1906 DPRINTF(("ohci_timeout: oxfer=%p\n", oxfer));
1907
1908 if (sc->sc_dying) {
1909 ohci_abort_xfer(&oxfer->xfer, USBD_TIMEOUT);
1910 return;
1911 }
1912
1913
1914 usb_init_task(&oxfer->abort_task, ohci_timeout_task, addr);
1915 usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task);
1916 }
1917
1918 void
1919 ohci_timeout_task(void *addr)
1920 {
1921 usbd_xfer_handle xfer = addr;
1922 int s;
1923
1924 DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer));
1925
1926 s = splusb();
1927 ohci_abort_xfer(xfer, USBD_TIMEOUT);
1928 splx(s);
1929 }
1930
1931 #ifdef OHCI_DEBUG
1932 void
1933 ohci_dump_tds(ohci_soft_td_t *std)
1934 {
1935 for (; std; std = std->nexttd)
1936 ohci_dump_td(std);
1937 }
1938
1939 void
1940 ohci_dump_td(ohci_soft_td_t *std)
1941 {
1942 char sbuf[128];
1943
1944 bitmask_snprintf((u_int32_t)letoh32(std->td.td_flags),
1945 "\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE",
1946 sbuf, sizeof(sbuf));
1947
1948 printf("TD(%p) at %08lx: %s delay=%d ec=%d cc=%d\ncbp=0x%08lx "
1949 "nexttd=0x%08lx be=0x%08lx\n",
1950 std, (u_long)std->physaddr, sbuf,
1951 OHCI_TD_GET_DI(letoh32(std->td.td_flags)),
1952 OHCI_TD_GET_EC(letoh32(std->td.td_flags)),
1953 OHCI_TD_GET_CC(letoh32(std->td.td_flags)),
1954 (u_long)letoh32(std->td.td_cbp),
1955 (u_long)letoh32(std->td.td_nexttd),
1956 (u_long)letoh32(std->td.td_be));
1957 }
1958
1959 void
1960 ohci_dump_itd(ohci_soft_itd_t *sitd)
1961 {
1962 int i;
1963
1964 printf("ITD(%p) at %08lx: sf=%d di=%d fc=%d cc=%d\n"
1965 "bp0=0x%08lx next=0x%08lx be=0x%08lx\n",
1966 sitd, (u_long)sitd->physaddr,
1967 OHCI_ITD_GET_SF(letoh32(sitd->itd.itd_flags)),
1968 OHCI_ITD_GET_DI(letoh32(sitd->itd.itd_flags)),
1969 OHCI_ITD_GET_FC(letoh32(sitd->itd.itd_flags)),
1970 OHCI_ITD_GET_CC(letoh32(sitd->itd.itd_flags)),
1971 (u_long)letoh32(sitd->itd.itd_bp0),
1972 (u_long)letoh32(sitd->itd.itd_nextitd),
1973 (u_long)letoh32(sitd->itd.itd_be));
1974 for (i = 0; i < OHCI_ITD_NOFFSET; i++)
1975 printf("offs[%d]=0x%04x ", i,
1976 (u_int)letoh16(sitd->itd.itd_offset[i]));
1977 printf("\n");
1978 }
1979
1980 void
1981 ohci_dump_itds(ohci_soft_itd_t *sitd)
1982 {
1983 for (; sitd; sitd = sitd->nextitd)
1984 ohci_dump_itd(sitd);
1985 }
1986
1987 void
1988 ohci_dump_ed(ohci_soft_ed_t *sed)
1989 {
1990 char sbuf[128], sbuf2[128];
1991
1992 bitmask_snprintf((u_int32_t)letoh32(sed->ed.ed_flags),
1993 "\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO",
1994 sbuf, sizeof(sbuf));
1995 bitmask_snprintf((u_int32_t)letoh32(sed->ed.ed_headp),
1996 "\20\1HALT\2CARRY", sbuf2, sizeof(sbuf2));
1997
1998 printf("ED(%p) at 0x%08lx: addr=%d endpt=%d maxp=%d flags=%s\n"
1999 "tailp=0x%08lx headflags=%s headp=0x%08lx nexted=0x%08lx\n",
2000 sed, (u_long)sed->physaddr,
2001 OHCI_ED_GET_FA(letoh32(sed->ed.ed_flags)),
2002 OHCI_ED_GET_EN(letoh32(sed->ed.ed_flags)),
2003 OHCI_ED_GET_MAXP(letoh32(sed->ed.ed_flags)), sbuf,
2004 (u_long)letoh32(sed->ed.ed_tailp), sbuf2,
2005 (u_long)letoh32(sed->ed.ed_headp),
2006 (u_long)letoh32(sed->ed.ed_nexted));
2007 }
2008 #endif
2009
2010 usbd_status
2011 ohci_open(usbd_pipe_handle pipe)
2012 {
2013 usbd_device_handle dev = pipe->device;
2014 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
2015 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
2016 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2017 u_int8_t addr = dev->address;
2018 u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
2019 ohci_soft_ed_t *sed;
2020 ohci_soft_td_t *std;
2021 ohci_soft_itd_t *sitd;
2022 ohci_physaddr_t tdphys;
2023 u_int32_t fmt;
2024 usbd_status err;
2025 int s;
2026 int ival;
2027
2028 DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
2029 pipe, addr, ed->bEndpointAddress, sc->sc_addr));
2030
2031 if (sc->sc_dying)
2032 return (USBD_IOERROR);
2033
2034 std = NULL;
2035 sed = NULL;
2036
2037 if (addr == sc->sc_addr) {
2038 switch (ed->bEndpointAddress) {
2039 case USB_CONTROL_ENDPOINT:
2040 pipe->methods = &ohci_root_ctrl_methods;
2041 break;
2042 case UE_DIR_IN | OHCI_INTR_ENDPT:
2043 pipe->methods = &ohci_root_intr_methods;
2044 break;
2045 default:
2046 return (USBD_INVAL);
2047 }
2048 } else {
2049 sed = ohci_alloc_sed(sc);
2050 if (sed == NULL)
2051 goto bad0;
2052 opipe->sed = sed;
2053 if (xfertype == UE_ISOCHRONOUS) {
2054 sitd = ohci_alloc_sitd(sc);
2055 if (sitd == NULL)
2056 goto bad1;
2057 opipe->tail.itd = sitd;
2058 tdphys = sitd->physaddr;
2059 fmt = OHCI_ED_FORMAT_ISO;
2060 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
2061 fmt |= OHCI_ED_DIR_IN;
2062 else
2063 fmt |= OHCI_ED_DIR_OUT;
2064 } else {
2065 std = ohci_alloc_std(sc);
2066 if (std == NULL)
2067 goto bad1;
2068 opipe->tail.td = std;
2069 tdphys = std->physaddr;
2070 fmt = OHCI_ED_FORMAT_GEN | OHCI_ED_DIR_TD;
2071 }
2072 sed->ed.ed_flags = htole32(
2073 OHCI_ED_SET_FA(addr) |
2074 OHCI_ED_SET_EN(UE_GET_ADDR(ed->bEndpointAddress)) |
2075 (dev->speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) |
2076 fmt | OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize)));
2077 sed->ed.ed_headp = htole32(tdphys |
2078 (pipe->endpoint->savedtoggle ? OHCI_TOGGLECARRY : 0));
2079 sed->ed.ed_tailp = htole32(tdphys);
2080
2081 switch (xfertype) {
2082 case UE_CONTROL:
2083 pipe->methods = &ohci_device_ctrl_methods;
2084 err = usb_allocmem(&sc->sc_bus,
2085 sizeof(usb_device_request_t),
2086 0, &opipe->u.ctl.reqdma);
2087 if (err)
2088 goto bad;
2089 s = splusb();
2090 ohci_add_ed(sed, sc->sc_ctrl_head);
2091 splx(s);
2092 break;
2093 case UE_INTERRUPT:
2094 pipe->methods = &ohci_device_intr_methods;
2095 ival = pipe->interval;
2096 if (ival == USBD_DEFAULT_INTERVAL)
2097 ival = ed->bInterval;
2098 return (ohci_device_setintr(sc, opipe, ival));
2099 case UE_ISOCHRONOUS:
2100 pipe->methods = &ohci_device_isoc_methods;
2101 return (ohci_setup_isoc(pipe));
2102 case UE_BULK:
2103 pipe->methods = &ohci_device_bulk_methods;
2104 s = splusb();
2105 ohci_add_ed(sed, sc->sc_bulk_head);
2106 splx(s);
2107 break;
2108 }
2109 }
2110 return (USBD_NORMAL_COMPLETION);
2111
2112 bad:
2113 if (std != NULL)
2114 ohci_free_std(sc, std);
2115 bad1:
2116 if (sed != NULL)
2117 ohci_free_sed(sc, sed);
2118 bad0:
2119 return (USBD_NOMEM);
2120
2121 }
2122
2123
2124
2125
2126
2127 void
2128 ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head)
2129 {
2130 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2131 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
2132 ohci_soft_ed_t *sed = opipe->sed;
2133 int s;
2134
2135 s = splusb();
2136 #ifdef DIAGNOSTIC
2137 sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
2138 if ((letoh32(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
2139 (letoh32(sed->ed.ed_headp) & OHCI_HEADMASK)) {
2140 ohci_soft_td_t *std;
2141 std = ohci_hash_find_td(sc, letoh32(sed->ed.ed_headp));
2142 printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x "
2143 "tl=0x%x pipe=%p, std=%p\n", sed,
2144 (int)letoh32(sed->ed.ed_headp),
2145 (int)letoh32(sed->ed.ed_tailp),
2146 pipe, std);
2147 #ifdef USB_DEBUG
2148 usbd_dump_pipe(&opipe->pipe);
2149 #endif
2150 #ifdef OHCI_DEBUG
2151 ohci_dump_ed(sed);
2152 if (std)
2153 ohci_dump_td(std);
2154 #endif
2155 usb_delay_ms(&sc->sc_bus, 2);
2156 if ((letoh32(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
2157 (letoh32(sed->ed.ed_headp) & OHCI_HEADMASK))
2158 printf("ohci_close_pipe: pipe still not empty\n");
2159 }
2160 #endif
2161 ohci_rem_ed(sed, head);
2162
2163 usb_delay_ms(&sc->sc_bus, 1);
2164 splx(s);
2165 pipe->endpoint->savedtoggle =
2166 (letoh32(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0;
2167 ohci_free_sed(sc, opipe->sed);
2168 }
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180 void
2181 ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
2182 {
2183 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
2184 ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
2185 ohci_soft_ed_t *sed = opipe->sed;
2186 ohci_soft_td_t *p, *n;
2187 ohci_physaddr_t headp;
2188 int s, hit;
2189
2190 DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,
2191 sed));
2192
2193 if (sc->sc_dying) {
2194
2195 s = splusb();
2196 xfer->status = status;
2197 timeout_del(&xfer->timeout_handle);
2198 usb_transfer_complete(xfer);
2199 splx(s);
2200 return;
2201 }
2202
2203 if (xfer->device->bus->intr_context || !curproc)
2204 panic("ohci_abort_xfer: not in process context");
2205
2206
2207
2208
2209 s = splusb();
2210 xfer->status = status;
2211 timeout_del(&xfer->timeout_handle);
2212 splx(s);
2213 DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
2214 sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
2215
2216
2217
2218
2219
2220
2221 usb_delay_ms(opipe->pipe.device->bus, 20);
2222 s = splusb();
2223 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
2224 sc->sc_softwake = 1;
2225 #endif
2226 usb_schedsoftintr(&sc->sc_bus);
2227 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
2228 tsleep(&sc->sc_softwake, PZERO, "ohciab", 0);
2229 #endif
2230 splx(s);
2231
2232
2233
2234
2235
2236
2237
2238
2239 s = splusb();
2240 p = xfer->hcpriv;
2241 #ifdef DIAGNOSTIC
2242 if (p == NULL) {
2243 splx(s);
2244 printf("ohci_abort_xfer: hcpriv is NULL\n");
2245 return;
2246 }
2247 #endif
2248 #ifdef OHCI_DEBUG
2249 if (ohcidebug > 1) {
2250 DPRINTF(("ohci_abort_xfer: sed=\n"));
2251 ohci_dump_ed(sed);
2252 ohci_dump_tds(p);
2253 }
2254 #endif
2255 headp = letoh32(sed->ed.ed_headp) & OHCI_HEADMASK;
2256 hit = 0;
2257 for (; p->xfer == xfer; p = n) {
2258 hit |= headp == p->physaddr;
2259 n = p->nexttd;
2260 if (OHCI_TD_GET_CC(letoh32(p->td.td_flags)) ==
2261 OHCI_CC_NOT_ACCESSED)
2262 ohci_free_std(sc, p);
2263 }
2264
2265 if (hit) {
2266 DPRINTFN(1,("ohci_abort_xfer: set hd=0x%08x, tl=0x%08x\n",
2267 (int)p->physaddr, (int)letoh32(sed->ed.ed_tailp)));
2268 sed->ed.ed_headp = htole32(p->physaddr);
2269 } else {
2270 DPRINTFN(1,("ohci_abort_xfer: no hit\n"));
2271 }
2272
2273
2274
2275
2276 sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
2277
2278
2279
2280
2281 usb_transfer_complete(xfer);
2282
2283 splx(s);
2284 }
2285
2286
2287
2288
2289 usb_device_descriptor_t ohci_devd = {
2290 USB_DEVICE_DESCRIPTOR_SIZE,
2291 UDESC_DEVICE,
2292 {0x00, 0x01},
2293 UDCLASS_HUB,
2294 UDSUBCLASS_HUB,
2295 UDPROTO_FSHUB,
2296 64,
2297 {0},{0},{0x00,0x01},
2298 1,2,0,
2299 1
2300 };
2301
2302 usb_config_descriptor_t ohci_confd = {
2303 USB_CONFIG_DESCRIPTOR_SIZE,
2304 UDESC_CONFIG,
2305 {USB_CONFIG_DESCRIPTOR_SIZE +
2306 USB_INTERFACE_DESCRIPTOR_SIZE +
2307 USB_ENDPOINT_DESCRIPTOR_SIZE},
2308 1,
2309 1,
2310 0,
2311 UC_SELF_POWERED,
2312 0
2313 };
2314
2315 usb_interface_descriptor_t ohci_ifcd = {
2316 USB_INTERFACE_DESCRIPTOR_SIZE,
2317 UDESC_INTERFACE,
2318 0,
2319 0,
2320 1,
2321 UICLASS_HUB,
2322 UISUBCLASS_HUB,
2323 UIPROTO_FSHUB,
2324 0
2325 };
2326
2327 usb_endpoint_descriptor_t ohci_endpd = {
2328 USB_ENDPOINT_DESCRIPTOR_SIZE,
2329 UDESC_ENDPOINT,
2330 UE_DIR_IN | OHCI_INTR_ENDPT,
2331 UE_INTERRUPT,
2332 {8, 0},
2333 255
2334 };
2335
2336 usb_hub_descriptor_t ohci_hubd = {
2337 USB_HUB_DESCRIPTOR_SIZE,
2338 UDESC_HUB,
2339 0,
2340 {0,0},
2341 0,
2342 0,
2343 {0},
2344 };
2345
2346 int
2347 ohci_str(usb_string_descriptor_t *p, int l, const char *s)
2348 {
2349 int i;
2350
2351 if (l == 0)
2352 return (0);
2353 p->bLength = 2 * strlen(s) + 2;
2354 if (l == 1)
2355 return (1);
2356 p->bDescriptorType = UDESC_STRING;
2357 l -= 2;
2358 for (i = 0; s[i] && l > 1; i++, l -= 2)
2359 USETW2(p->bString[i], 0, s[i]);
2360 return (2*i+2);
2361 }
2362
2363
2364
2365
2366 usbd_status
2367 ohci_root_ctrl_transfer(usbd_xfer_handle xfer)
2368 {
2369 usbd_status err;
2370
2371
2372 err = usb_insert_transfer(xfer);
2373 if (err)
2374 return (err);
2375
2376
2377 return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2378 }
2379
2380 usbd_status
2381 ohci_root_ctrl_start(usbd_xfer_handle xfer)
2382 {
2383 ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
2384 usb_device_request_t *req;
2385 void *buf = NULL;
2386 int port, i;
2387 int s, len, value, index, l, totlen = 0;
2388 usb_port_status_t ps;
2389 usb_hub_descriptor_t hubd;
2390 usbd_status err;
2391 u_int32_t v;
2392
2393 if (sc->sc_dying)
2394 return (USBD_IOERROR);
2395
2396 #ifdef DIAGNOSTIC
2397 if (!(xfer->rqflags & URQ_REQUEST))
2398
2399 return (USBD_INVAL);
2400 #endif
2401 req = &xfer->request;
2402
2403 DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n",
2404 req->bmRequestType, req->bRequest));
2405
2406 len = UGETW(req->wLength);
2407 value = UGETW(req->wValue);
2408 index = UGETW(req->wIndex);
2409
2410 if (len != 0)
2411 buf = KERNADDR(&xfer->dmabuf, 0);
2412
2413 #define C(x,y) ((x) | ((y) << 8))
2414 switch(C(req->bRequest, req->bmRequestType)) {
2415 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
2416 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
2417 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
2418
2419
2420
2421
2422 break;
2423 case C(UR_GET_CONFIG, UT_READ_DEVICE):
2424 if (len > 0) {
2425 *(u_int8_t *)buf = sc->sc_conf;
2426 totlen = 1;
2427 }
2428 break;
2429 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
2430 DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value));
2431 switch(value >> 8) {
2432 case UDESC_DEVICE:
2433 if ((value & 0xff) != 0) {
2434 err = USBD_IOERROR;
2435 goto ret;
2436 }
2437 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
2438 USETW(ohci_devd.idVendor, sc->sc_id_vendor);
2439 memcpy(buf, &ohci_devd, l);
2440 break;
2441 case UDESC_CONFIG:
2442 if ((value & 0xff) != 0) {
2443 err = USBD_IOERROR;
2444 goto ret;
2445 }
2446 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
2447 memcpy(buf, &ohci_confd, l);
2448 buf = (char *)buf + l;
2449 len -= l;
2450 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
2451 totlen += l;
2452 memcpy(buf, &ohci_ifcd, l);
2453 buf = (char *)buf + l;
2454 len -= l;
2455 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
2456 totlen += l;
2457 memcpy(buf, &ohci_endpd, l);
2458 break;
2459 case UDESC_STRING:
2460 if (len == 0)
2461 break;
2462 *(u_int8_t *)buf = 0;
2463 totlen = 1;
2464 switch (value & 0xff) {
2465 case 0:
2466 totlen = ohci_str(buf, len, "\001");
2467 break;
2468 case 1:
2469 totlen = ohci_str(buf, len, sc->sc_vendor);
2470 break;
2471 case 2:
2472 totlen = ohci_str(buf, len, "OHCI root hub");
2473 break;
2474 }
2475 break;
2476 default:
2477 err = USBD_IOERROR;
2478 goto ret;
2479 }
2480 break;
2481 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
2482 if (len > 0) {
2483 *(u_int8_t *)buf = 0;
2484 totlen = 1;
2485 }
2486 break;
2487 case C(UR_GET_STATUS, UT_READ_DEVICE):
2488 if (len > 1) {
2489 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
2490 totlen = 2;
2491 }
2492 break;
2493 case C(UR_GET_STATUS, UT_READ_INTERFACE):
2494 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
2495 if (len > 1) {
2496 USETW(((usb_status_t *)buf)->wStatus, 0);
2497 totlen = 2;
2498 }
2499 break;
2500 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
2501 if (value >= USB_MAX_DEVICES) {
2502 err = USBD_IOERROR;
2503 goto ret;
2504 }
2505 sc->sc_addr = value;
2506 break;
2507 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
2508 if (value != 0 && value != 1) {
2509 err = USBD_IOERROR;
2510 goto ret;
2511 }
2512 sc->sc_conf = value;
2513 break;
2514 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
2515 break;
2516 case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
2517 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
2518 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
2519 err = USBD_IOERROR;
2520 goto ret;
2521 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
2522 break;
2523 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
2524 break;
2525
2526 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
2527 break;
2528 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
2529 DPRINTFN(8, ("ohci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
2530 "port=%d feature=%d\n",
2531 index, value));
2532 if (index < 1 || index > sc->sc_noport) {
2533 err = USBD_IOERROR;
2534 goto ret;
2535 }
2536 port = OHCI_RH_PORT_STATUS(index);
2537 switch(value) {
2538 case UHF_PORT_ENABLE:
2539 OWRITE4(sc, port, UPS_CURRENT_CONNECT_STATUS);
2540 break;
2541 case UHF_PORT_SUSPEND:
2542 OWRITE4(sc, port, UPS_OVERCURRENT_INDICATOR);
2543 break;
2544 case UHF_PORT_POWER:
2545
2546 OWRITE4(sc, port, UPS_LOW_SPEED);
2547 break;
2548 case UHF_C_PORT_CONNECTION:
2549 OWRITE4(sc, port, UPS_C_CONNECT_STATUS << 16);
2550 break;
2551 case UHF_C_PORT_ENABLE:
2552 OWRITE4(sc, port, UPS_C_PORT_ENABLED << 16);
2553 break;
2554 case UHF_C_PORT_SUSPEND:
2555 OWRITE4(sc, port, UPS_C_SUSPEND << 16);
2556 break;
2557 case UHF_C_PORT_OVER_CURRENT:
2558 OWRITE4(sc, port, UPS_C_OVERCURRENT_INDICATOR << 16);
2559 break;
2560 case UHF_C_PORT_RESET:
2561 OWRITE4(sc, port, UPS_C_PORT_RESET << 16);
2562 break;
2563 default:
2564 err = USBD_IOERROR;
2565 goto ret;
2566 }
2567 switch(value) {
2568 case UHF_C_PORT_CONNECTION:
2569 case UHF_C_PORT_ENABLE:
2570 case UHF_C_PORT_SUSPEND:
2571 case UHF_C_PORT_OVER_CURRENT:
2572 case UHF_C_PORT_RESET:
2573
2574 if ((OREAD4(sc, port) >> 16) == 0)
2575 ohci_rhsc_able(sc, 1);
2576 break;
2577 default:
2578 break;
2579 }
2580 break;
2581 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
2582 if ((value & 0xff) != 0) {
2583 err = USBD_IOERROR;
2584 goto ret;
2585 }
2586 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
2587 hubd = ohci_hubd;
2588 hubd.bNbrPorts = sc->sc_noport;
2589 USETW(hubd.wHubCharacteristics,
2590 (v & OHCI_NPS ? UHD_PWR_NO_SWITCH :
2591 v & OHCI_PSM ? UHD_PWR_GANGED : UHD_PWR_INDIVIDUAL)
2592
2593 );
2594 hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v);
2595 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
2596 for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
2597 hubd.DeviceRemovable[i++] = (u_int8_t)v;
2598 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
2599 l = min(len, hubd.bDescLength);
2600 totlen = l;
2601 memcpy(buf, &hubd, l);
2602 break;
2603 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
2604 if (len != 4) {
2605 err = USBD_IOERROR;
2606 goto ret;
2607 }
2608 memset(buf, 0, len);
2609 totlen = len;
2610 break;
2611 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
2612 DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n",
2613 index));
2614 if (index < 1 || index > sc->sc_noport) {
2615 err = USBD_IOERROR;
2616 goto ret;
2617 }
2618 if (len != 4) {
2619 err = USBD_IOERROR;
2620 goto ret;
2621 }
2622 v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
2623 DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n",
2624 v));
2625 USETW(ps.wPortStatus, v);
2626 USETW(ps.wPortChange, v >> 16);
2627 l = min(len, sizeof ps);
2628 memcpy(buf, &ps, l);
2629 totlen = l;
2630 break;
2631 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
2632 err = USBD_IOERROR;
2633 goto ret;
2634 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
2635 break;
2636 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
2637 if (index < 1 || index > sc->sc_noport) {
2638 err = USBD_IOERROR;
2639 goto ret;
2640 }
2641 port = OHCI_RH_PORT_STATUS(index);
2642 switch(value) {
2643 case UHF_PORT_ENABLE:
2644 OWRITE4(sc, port, UPS_PORT_ENABLED);
2645 break;
2646 case UHF_PORT_SUSPEND:
2647 OWRITE4(sc, port, UPS_SUSPEND);
2648 break;
2649 case UHF_PORT_RESET:
2650 DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n",
2651 index));
2652 OWRITE4(sc, port, UPS_RESET);
2653 for (i = 0; i < 5; i++) {
2654 usb_delay_ms(&sc->sc_bus,
2655 USB_PORT_ROOT_RESET_DELAY);
2656 if (sc->sc_dying) {
2657 err = USBD_IOERROR;
2658 goto ret;
2659 }
2660 if ((OREAD4(sc, port) & UPS_RESET) == 0)
2661 break;
2662 }
2663 DPRINTFN(8,("ohci port %d reset, status = 0x%04x\n",
2664 index, OREAD4(sc, port)));
2665 break;
2666 case UHF_PORT_POWER:
2667 DPRINTFN(2,("ohci_root_ctrl_transfer: set port power "
2668 "%d\n", index));
2669 OWRITE4(sc, port, UPS_PORT_POWER);
2670 break;
2671 default:
2672 err = USBD_IOERROR;
2673 goto ret;
2674 }
2675 break;
2676 default:
2677 err = USBD_IOERROR;
2678 goto ret;
2679 }
2680 xfer->actlen = totlen;
2681 err = USBD_NORMAL_COMPLETION;
2682 ret:
2683 xfer->status = err;
2684 s = splusb();
2685 usb_transfer_complete(xfer);
2686 splx(s);
2687 return (USBD_IN_PROGRESS);
2688 }
2689
2690
2691 void
2692 ohci_root_ctrl_abort(usbd_xfer_handle xfer)
2693 {
2694
2695 }
2696
2697
2698 void
2699 ohci_root_ctrl_close(usbd_pipe_handle pipe)
2700 {
2701 DPRINTF(("ohci_root_ctrl_close\n"));
2702
2703 }
2704
2705 usbd_status
2706 ohci_root_intr_transfer(usbd_xfer_handle xfer)
2707 {
2708 usbd_status err;
2709
2710
2711 err = usb_insert_transfer(xfer);
2712 if (err)
2713 return (err);
2714
2715
2716 return (ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2717 }
2718
2719 usbd_status
2720 ohci_root_intr_start(usbd_xfer_handle xfer)
2721 {
2722 usbd_pipe_handle pipe = xfer->pipe;
2723 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
2724
2725 if (sc->sc_dying)
2726 return (USBD_IOERROR);
2727
2728 sc->sc_intrxfer = xfer;
2729
2730 return (USBD_IN_PROGRESS);
2731 }
2732
2733
2734 void
2735 ohci_root_intr_abort(usbd_xfer_handle xfer)
2736 {
2737 int s;
2738
2739 if (xfer->pipe->intrxfer == xfer) {
2740 DPRINTF(("ohci_root_intr_abort: remove\n"));
2741 xfer->pipe->intrxfer = NULL;
2742 }
2743 xfer->status = USBD_CANCELLED;
2744 s = splusb();
2745 usb_transfer_complete(xfer);
2746 splx(s);
2747 }
2748
2749
2750 void
2751 ohci_root_intr_close(usbd_pipe_handle pipe)
2752 {
2753 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
2754
2755 DPRINTF(("ohci_root_intr_close\n"));
2756
2757 sc->sc_intrxfer = NULL;
2758 }
2759
2760
2761
2762 usbd_status
2763 ohci_device_ctrl_transfer(usbd_xfer_handle xfer)
2764 {
2765 usbd_status err;
2766
2767
2768 err = usb_insert_transfer(xfer);
2769 if (err)
2770 return (err);
2771
2772
2773 return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2774 }
2775
2776 usbd_status
2777 ohci_device_ctrl_start(usbd_xfer_handle xfer)
2778 {
2779 ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
2780 usbd_status err;
2781
2782 if (sc->sc_dying)
2783 return (USBD_IOERROR);
2784
2785 #ifdef DIAGNOSTIC
2786 if (!(xfer->rqflags & URQ_REQUEST)) {
2787
2788 printf("ohci_device_ctrl_transfer: not a request\n");
2789 return (USBD_INVAL);
2790 }
2791 #endif
2792
2793 err = ohci_device_request(xfer);
2794 if (err)
2795 return (err);
2796
2797 if (sc->sc_bus.use_polling)
2798 ohci_waitintr(sc, xfer);
2799
2800 return (USBD_IN_PROGRESS);
2801 }
2802
2803
2804 void
2805 ohci_device_ctrl_abort(usbd_xfer_handle xfer)
2806 {
2807 DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer));
2808 ohci_abort_xfer(xfer, USBD_CANCELLED);
2809 }
2810
2811
2812 void
2813 ohci_device_ctrl_close(usbd_pipe_handle pipe)
2814 {
2815 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2816 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
2817
2818 DPRINTF(("ohci_device_ctrl_close: pipe=%p\n", pipe));
2819 ohci_close_pipe(pipe, sc->sc_ctrl_head);
2820 ohci_free_std(sc, opipe->tail.td);
2821 }
2822
2823
2824
2825 void
2826 ohci_device_clear_toggle(usbd_pipe_handle pipe)
2827 {
2828 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2829
2830 opipe->sed->ed.ed_headp &= htole32(~OHCI_TOGGLECARRY);
2831 }
2832
2833 void
2834 ohci_noop(usbd_pipe_handle pipe)
2835 {
2836 }
2837
2838 usbd_status
2839 ohci_device_bulk_transfer(usbd_xfer_handle xfer)
2840 {
2841 usbd_status err;
2842
2843
2844 err = usb_insert_transfer(xfer);
2845 if (err)
2846 return (err);
2847
2848
2849 return (ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2850 }
2851
2852 usbd_status
2853 ohci_device_bulk_start(usbd_xfer_handle xfer)
2854 {
2855 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
2856 usbd_device_handle dev = opipe->pipe.device;
2857 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
2858 int addr = dev->address;
2859 ohci_soft_td_t *data, *tail, *tdp;
2860 ohci_soft_ed_t *sed;
2861 int s, len, isread, endpt;
2862 usbd_status err;
2863
2864 if (sc->sc_dying)
2865 return (USBD_IOERROR);
2866
2867 #ifdef DIAGNOSTIC
2868 if (xfer->rqflags & URQ_REQUEST) {
2869
2870 printf("ohci_device_bulk_start: a request\n");
2871 return (USBD_INVAL);
2872 }
2873 #endif
2874
2875 len = xfer->length;
2876 endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
2877 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2878 sed = opipe->sed;
2879
2880 DPRINTFN(4,("ohci_device_bulk_start: xfer=%p len=%d isread=%d "
2881 "flags=%d endpt=%d\n", xfer, len, isread, xfer->flags,
2882 endpt));
2883
2884 opipe->u.bulk.isread = isread;
2885 opipe->u.bulk.length = len;
2886
2887
2888 sed->ed.ed_flags = htole32(
2889 (letoh32(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) |
2890 OHCI_ED_SET_FA(addr));
2891
2892
2893 data = opipe->tail.td;
2894 err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer,
2895 data, &tail);
2896
2897 tail->td.td_flags &= htole32(~OHCI_TD_INTR_MASK);
2898 tail->td.td_flags |= htole32(OHCI_TD_SET_DI(1));
2899 tail->flags |= OHCI_CALL_DONE;
2900 tail = tail->nexttd;
2901 if (err)
2902 return (err);
2903
2904 tail->xfer = NULL;
2905 xfer->hcpriv = data;
2906
2907 DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x "
2908 "td_cbp=0x%08x td_be=0x%08x\n",
2909 (int)letoh32(sed->ed.ed_flags),
2910 (int)letoh32(data->td.td_flags),
2911 (int)letoh32(data->td.td_cbp),
2912 (int)letoh32(data->td.td_be)));
2913
2914 #ifdef OHCI_DEBUG
2915 if (ohcidebug > 5) {
2916 ohci_dump_ed(sed);
2917 ohci_dump_tds(data);
2918 }
2919 #endif
2920
2921
2922 s = splusb();
2923 for (tdp = data; tdp != tail; tdp = tdp->nexttd) {
2924 tdp->xfer = xfer;
2925 }
2926 sed->ed.ed_tailp = htole32(tail->physaddr);
2927 opipe->tail.td = tail;
2928 sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
2929 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
2930 if (xfer->timeout && !sc->sc_bus.use_polling) {
2931 timeout_del(&xfer->timeout_handle);
2932 timeout_set(&xfer->timeout_handle, ohci_timeout, xfer);
2933 timeout_add(&xfer->timeout_handle, mstohz(xfer->timeout));
2934 }
2935
2936 #if 0
2937
2938 if (ohcidebug > 10) {
2939 delay(10000);
2940 DPRINTF(("ohci_device_intr_transfer: status=%x\n",
2941 OREAD4(sc, OHCI_COMMAND_STATUS)));
2942 ohci_dump_ed(sed);
2943 ohci_dump_tds(data);
2944 }
2945 #endif
2946
2947 splx(s);
2948
2949 if (sc->sc_bus.use_polling)
2950 ohci_waitintr(sc, xfer);
2951
2952 return (USBD_IN_PROGRESS);
2953 }
2954
2955 void
2956 ohci_device_bulk_abort(usbd_xfer_handle xfer)
2957 {
2958 DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer));
2959 ohci_abort_xfer(xfer, USBD_CANCELLED);
2960 }
2961
2962
2963
2964
2965 void
2966 ohci_device_bulk_close(usbd_pipe_handle pipe)
2967 {
2968 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2969 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
2970
2971 DPRINTF(("ohci_device_bulk_close: pipe=%p\n", pipe));
2972 ohci_close_pipe(pipe, sc->sc_bulk_head);
2973 ohci_free_std(sc, opipe->tail.td);
2974 }
2975
2976
2977
2978 usbd_status
2979 ohci_device_intr_transfer(usbd_xfer_handle xfer)
2980 {
2981 usbd_status err;
2982
2983
2984 err = usb_insert_transfer(xfer);
2985 if (err)
2986 return (err);
2987
2988
2989 return (ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2990 }
2991
2992 usbd_status
2993 ohci_device_intr_start(usbd_xfer_handle xfer)
2994 {
2995 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
2996 usbd_device_handle dev = opipe->pipe.device;
2997 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
2998 ohci_soft_ed_t *sed = opipe->sed;
2999 ohci_soft_td_t *data, *tail;
3000 int s, len, isread, endpt;
3001
3002 if (sc->sc_dying)
3003 return (USBD_IOERROR);
3004
3005 DPRINTFN(3, ("ohci_device_intr_transfer: xfer=%p len=%d "
3006 "flags=%d priv=%p\n",
3007 xfer, xfer->length, xfer->flags, xfer->priv));
3008
3009 #ifdef DIAGNOSTIC
3010 if (xfer->rqflags & URQ_REQUEST)
3011 panic("ohci_device_intr_transfer: a request");
3012 #endif
3013
3014 len = xfer->length;
3015 endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
3016 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3017
3018 data = opipe->tail.td;
3019 tail = ohci_alloc_std(sc);
3020 if (tail == NULL)
3021 return (USBD_NOMEM);
3022 tail->xfer = NULL;
3023
3024 data->td.td_flags = htole32(
3025 isread ? OHCI_TD_IN : OHCI_TD_OUT |
3026 OHCI_TD_NOCC |
3027 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
3028 if (xfer->flags & USBD_SHORT_XFER_OK)
3029 data->td.td_flags |= htole32(OHCI_TD_R);
3030 data->td.td_cbp = htole32(DMAADDR(&xfer->dmabuf, 0));
3031 data->nexttd = tail;
3032 data->td.td_nexttd = htole32(tail->physaddr);
3033 data->td.td_be = htole32(letoh32(data->td.td_cbp) + len - 1);
3034 data->len = len;
3035 data->xfer = xfer;
3036 data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
3037 xfer->hcpriv = data;
3038
3039 #ifdef OHCI_DEBUG
3040 if (ohcidebug > 5) {
3041 DPRINTF(("ohci_device_intr_transfer:\n"));
3042 ohci_dump_ed(sed);
3043 ohci_dump_tds(data);
3044 }
3045 #endif
3046
3047
3048 s = splusb();
3049 sed->ed.ed_tailp = htole32(tail->physaddr);
3050 opipe->tail.td = tail;
3051 sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
3052
3053 #if 0
3054
3055
3056
3057
3058
3059 if (ohcidebug > 5) {
3060 usb_delay_ms(&sc->sc_bus, 5);
3061 DPRINTF(("ohci_device_intr_transfer: status=%x\n",
3062 OREAD4(sc, OHCI_COMMAND_STATUS)));
3063 ohci_dump_ed(sed);
3064 ohci_dump_tds(data);
3065 }
3066 #endif
3067 splx(s);
3068
3069 return (USBD_IN_PROGRESS);
3070 }
3071
3072
3073 void
3074 ohci_device_intr_abort(usbd_xfer_handle xfer)
3075 {
3076 if (xfer->pipe->intrxfer == xfer) {
3077 DPRINTF(("ohci_device_intr_abort: remove\n"));
3078 xfer->pipe->intrxfer = NULL;
3079 }
3080 ohci_abort_xfer(xfer, USBD_CANCELLED);
3081 }
3082
3083
3084 void
3085 ohci_device_intr_close(usbd_pipe_handle pipe)
3086 {
3087 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
3088 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
3089 int nslots = opipe->u.intr.nslots;
3090 int pos = opipe->u.intr.pos;
3091 int j;
3092 ohci_soft_ed_t *p, *sed = opipe->sed;
3093 int s;
3094
3095 DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n",
3096 pipe, nslots, pos));
3097 s = splusb();
3098 sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
3099 if ((letoh32(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
3100 (letoh32(sed->ed.ed_headp) & OHCI_HEADMASK))
3101 usb_delay_ms(&sc->sc_bus, 2);
3102
3103 for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
3104 ;
3105 #ifdef DIAGNOSTIC
3106 if (p == NULL)
3107 panic("ohci_device_intr_close: ED not found");
3108 #endif
3109 p->next = sed->next;
3110 p->ed.ed_nexted = sed->ed.ed_nexted;
3111 splx(s);
3112
3113 for (j = 0; j < nslots; j++)
3114 --sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS];
3115
3116 ohci_free_std(sc, opipe->tail.td);
3117 ohci_free_sed(sc, opipe->sed);
3118 }
3119
3120 usbd_status
3121 ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival)
3122 {
3123 int i, j, s, best;
3124 u_int npoll, slow, shigh, nslots;
3125 u_int bestbw, bw;
3126 ohci_soft_ed_t *hsed, *sed = opipe->sed;
3127
3128 DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe));
3129 if (ival == 0) {
3130 printf("ohci_setintr: 0 interval\n");
3131 return (USBD_INVAL);
3132 }
3133
3134 npoll = OHCI_NO_INTRS;
3135 while (npoll > ival)
3136 npoll /= 2;
3137 DPRINTFN(2, ("ohci_setintr: ival=%d npoll=%d\n", ival, npoll));
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150 slow = npoll-1;
3151 shigh = slow + npoll;
3152 nslots = OHCI_NO_INTRS / npoll;
3153 for (best = i = slow, bestbw = ~0; i < shigh; i++) {
3154 bw = 0;
3155 for (j = 0; j < nslots; j++)
3156 bw += sc->sc_bws[(i * nslots + j) % OHCI_NO_INTRS];
3157 if (bw < bestbw) {
3158 best = i;
3159 bestbw = bw;
3160 }
3161 }
3162 DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n",
3163 best, slow, shigh, bestbw));
3164
3165 s = splusb();
3166 hsed = sc->sc_eds[best];
3167 sed->next = hsed->next;
3168 sed->ed.ed_nexted = hsed->ed.ed_nexted;
3169 hsed->next = sed;
3170 hsed->ed.ed_nexted = htole32(sed->physaddr);
3171 splx(s);
3172
3173 for (j = 0; j < nslots; j++)
3174 ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS];
3175 opipe->u.intr.nslots = nslots;
3176 opipe->u.intr.pos = best;
3177
3178 DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe));
3179 return (USBD_NORMAL_COMPLETION);
3180 }
3181
3182
3183
3184 usbd_status
3185 ohci_device_isoc_transfer(usbd_xfer_handle xfer)
3186 {
3187 usbd_status err;
3188
3189 DPRINTFN(5,("ohci_device_isoc_transfer: xfer=%p\n", xfer));
3190
3191
3192 err = usb_insert_transfer(xfer);
3193
3194
3195 if (err && err != USBD_IN_PROGRESS)
3196 return (err);
3197
3198
3199
3200
3201 ohci_device_isoc_enter(xfer);
3202
3203
3204 if (!err)
3205 ohci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
3206
3207 return (err);
3208 }
3209
3210 void
3211 ohci_device_isoc_enter(usbd_xfer_handle xfer)
3212 {
3213 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3214 usbd_device_handle dev = opipe->pipe.device;
3215 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
3216 ohci_soft_ed_t *sed = opipe->sed;
3217 struct iso *iso = &opipe->u.iso;
3218 ohci_soft_itd_t *sitd, *nsitd;
3219 ohci_physaddr_t buf, offs, noffs, bp0;
3220 int i, ncur, nframes;
3221 int s;
3222
3223 DPRINTFN(1,("ohci_device_isoc_enter: used=%d next=%d xfer=%p "
3224 "nframes=%d\n",
3225 iso->inuse, iso->next, xfer, xfer->nframes));
3226
3227 if (sc->sc_dying)
3228 return;
3229
3230 if (iso->next == -1) {
3231
3232 iso->next = letoh32(sc->sc_hcca->hcca_frame_number) + 5;
3233 DPRINTFN(2,("ohci_device_isoc_enter: start next=%d\n",
3234 iso->next));
3235 }
3236
3237 sitd = opipe->tail.itd;
3238 buf = DMAADDR(&xfer->dmabuf, 0);
3239 bp0 = OHCI_PAGE(buf);
3240 offs = OHCI_PAGE_OFFSET(buf);
3241 nframes = xfer->nframes;
3242 xfer->hcpriv = sitd;
3243 for (i = ncur = 0; i < nframes; i++, ncur++) {
3244 noffs = offs + xfer->frlengths[i];
3245 if (ncur == OHCI_ITD_NOFFSET ||
3246 OHCI_PAGE(buf + noffs) > bp0 + OHCI_PAGE_SIZE) {
3247
3248
3249 nsitd = ohci_alloc_sitd(sc);
3250 if (nsitd == NULL) {
3251
3252 printf("%s: isoc TD alloc failed\n",
3253 sc->sc_bus.bdev.dv_xname);
3254 return;
3255 }
3256
3257
3258 sitd->itd.itd_flags = htole32(
3259 OHCI_ITD_NOCC |
3260 OHCI_ITD_SET_SF(iso->next) |
3261 OHCI_ITD_SET_DI(6) |
3262 OHCI_ITD_SET_FC(ncur));
3263 sitd->itd.itd_bp0 = htole32(bp0);
3264 sitd->nextitd = nsitd;
3265 sitd->itd.itd_nextitd = htole32(nsitd->physaddr);
3266 sitd->itd.itd_be = htole32(bp0 + offs - 1);
3267 sitd->xfer = xfer;
3268 sitd->flags = 0;
3269
3270 sitd = nsitd;
3271 iso->next = iso->next + ncur;
3272 bp0 = OHCI_PAGE(buf + offs);
3273 ncur = 0;
3274 }
3275 sitd->itd.itd_offset[ncur] = htole16(OHCI_ITD_MK_OFFS(offs));
3276 offs = noffs;
3277 }
3278 nsitd = ohci_alloc_sitd(sc);
3279 if (nsitd == NULL) {
3280
3281 printf("%s: isoc TD alloc failed\n",
3282 sc->sc_bus.bdev.dv_xname);
3283 return;
3284 }
3285
3286 sitd->itd.itd_flags = htole32(
3287 OHCI_ITD_NOCC |
3288 OHCI_ITD_SET_SF(iso->next) |
3289 OHCI_ITD_SET_DI(0) |
3290 OHCI_ITD_SET_FC(ncur));
3291 sitd->itd.itd_bp0 = htole32(bp0);
3292 sitd->nextitd = nsitd;
3293 sitd->itd.itd_nextitd = htole32(nsitd->physaddr);
3294 sitd->itd.itd_be = htole32(bp0 + offs - 1);
3295 sitd->xfer = xfer;
3296 sitd->flags = OHCI_CALL_DONE;
3297
3298 iso->next = iso->next + ncur;
3299 iso->inuse += nframes;
3300
3301 xfer->actlen = offs;
3302
3303 xfer->status = USBD_IN_PROGRESS;
3304
3305 #ifdef OHCI_DEBUG
3306 if (ohcidebug > 5) {
3307 DPRINTF(("ohci_device_isoc_enter: frame=%d\n",
3308 letoh32(sc->sc_hcca->hcca_frame_number)));
3309 ohci_dump_itds(xfer->hcpriv);
3310 ohci_dump_ed(sed);
3311 }
3312 #endif
3313
3314 s = splusb();
3315 sed->ed.ed_tailp = htole32(nsitd->physaddr);
3316 opipe->tail.itd = nsitd;
3317 sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
3318 splx(s);
3319
3320 #ifdef OHCI_DEBUG
3321 if (ohcidebug > 5) {
3322 delay(150000);
3323 DPRINTF(("ohci_device_isoc_enter: after frame=%d\n",
3324 letoh32(sc->sc_hcca->hcca_frame_number)));
3325 ohci_dump_itds(xfer->hcpriv);
3326 ohci_dump_ed(sed);
3327 }
3328 #endif
3329 }
3330
3331 usbd_status
3332 ohci_device_isoc_start(usbd_xfer_handle xfer)
3333 {
3334 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3335 ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
3336
3337 DPRINTFN(5,("ohci_device_isoc_start: xfer=%p\n", xfer));
3338
3339 if (sc->sc_dying)
3340 return (USBD_IOERROR);
3341
3342 #ifdef DIAGNOSTIC
3343 if (xfer->status != USBD_IN_PROGRESS)
3344 printf("ohci_device_isoc_start: not in progress %p\n", xfer);
3345 #endif
3346
3347
3348
3349 return (USBD_IN_PROGRESS);
3350 }
3351
3352 void
3353 ohci_device_isoc_abort(usbd_xfer_handle xfer)
3354 {
3355 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3356 ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
3357 ohci_soft_ed_t *sed;
3358 ohci_soft_itd_t *sitd;
3359 int s;
3360
3361 s = splusb();
3362
3363 DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer));
3364
3365
3366 if (xfer->status != USBD_NOT_STARTED &&
3367 xfer->status != USBD_IN_PROGRESS) {
3368 splx(s);
3369 printf("ohci_device_isoc_abort: early return\n");
3370 return;
3371 }
3372
3373
3374 xfer->status = USBD_CANCELLED;
3375
3376 sed = opipe->sed;
3377 sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
3378
3379 sitd = xfer->hcpriv;
3380 #ifdef DIAGNOSTIC
3381 if (sitd == NULL) {
3382 splx(s);
3383 printf("ohci_device_isoc_abort: hcpriv==0\n");
3384 return;
3385 }
3386 #endif
3387 for (; sitd->xfer == xfer; sitd = sitd->nextitd) {
3388 #ifdef DIAGNOSTIC
3389 DPRINTFN(1,("abort sets done sitd=%p\n", sitd));
3390 sitd->isdone = 1;
3391 #endif
3392 }
3393
3394 splx(s);
3395
3396 usb_delay_ms(&sc->sc_bus, OHCI_ITD_NOFFSET);
3397
3398 s = splusb();
3399
3400
3401 usb_transfer_complete(xfer);
3402
3403 sed->ed.ed_headp = htole32(sitd->physaddr);
3404 sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
3405
3406 splx(s);
3407 }
3408
3409 void
3410 ohci_device_isoc_done(usbd_xfer_handle xfer)
3411 {
3412 DPRINTFN(1,("ohci_device_isoc_done: xfer=%p\n", xfer));
3413 }
3414
3415 usbd_status
3416 ohci_setup_isoc(usbd_pipe_handle pipe)
3417 {
3418 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
3419 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
3420 struct iso *iso = &opipe->u.iso;
3421 int s;
3422
3423 iso->next = -1;
3424 iso->inuse = 0;
3425
3426 s = splusb();
3427 ohci_add_ed(opipe->sed, sc->sc_isoc_head);
3428 splx(s);
3429
3430 return (USBD_NORMAL_COMPLETION);
3431 }
3432
3433 void
3434 ohci_device_isoc_close(usbd_pipe_handle pipe)
3435 {
3436 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
3437 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
3438
3439 DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe));
3440 ohci_close_pipe(pipe, sc->sc_isoc_head);
3441 #ifdef DIAGNOSTIC
3442 opipe->tail.itd->isdone = 1;
3443 #endif
3444 ohci_free_sitd(sc, opipe->tail.itd);
3445 }