ohci.c revision 1.52 1 /* $NetBSD: ohci.c,v 1.52 1999/10/13 08:10:55 augustss Exp $ */
2
3 /*
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (augustss (at) carlstedt.se) at
9 * Carlstedt Research & Technology.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*
41 * USB Open Host Controller driver.
42 *
43 * OHCI spec: ftp://ftp.compaq.com/pub/supportinformation/papers/hcir1_0a.exe
44 * USB spec: http://www.usb.org/developers/data/usb11.pdf
45 */
46
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/kernel.h>
50 #include <sys/malloc.h>
51 #if defined(__NetBSD__) || defined(__OpenBSD__)
52 #include <sys/device.h>
53 #elif defined(__FreeBSD__)
54 #include <sys/module.h>
55 #include <sys/bus.h>
56 #include <machine/bus_pio.h>
57 #include <machine/bus_memio.h>
58 #endif
59 #include <sys/proc.h>
60 #include <sys/queue.h>
61 #include <sys/select.h>
62
63 #include <machine/bus.h>
64 #include <machine/endian.h>
65
66 #include <dev/usb/usb.h>
67 #include <dev/usb/usbdi.h>
68 #include <dev/usb/usbdivar.h>
69 #include <dev/usb/usb_mem.h>
70 #include <dev/usb/usb_quirks.h>
71
72 #include <dev/usb/ohcireg.h>
73 #include <dev/usb/ohcivar.h>
74
75 #if defined(__FreeBSD__)
76 #include <machine/clock.h>
77 #define delay(d) DELAY(d)
78 #endif
79
80 #if defined(__OpenBSD__)
81 struct cfdriver ohci_cd = {
82 NULL, "ohci", DV_DULL
83 };
84 #endif
85
86 #ifdef OHCI_DEBUG
87 #define DPRINTF(x) if (ohcidebug) logprintf x
88 #define DPRINTFN(n,x) if (ohcidebug>(n)) logprintf x
89 int ohcidebug = 0;
90 #else
91 #define DPRINTF(x)
92 #define DPRINTFN(n,x)
93 #endif
94
95 /*
96 * The OHCI controller is little endian, so on big endian machines
97 * the data strored in memory needs to be swapped.
98 */
99 #if BYTE_ORDER == BIG_ENDIAN
100 #define LE(x) (bswap32(x))
101 #else
102 #define LE(x) (x)
103 #endif
104
105 struct ohci_pipe;
106
107 ohci_soft_ed_t *ohci_alloc_sed __P((ohci_softc_t *));
108 void ohci_free_sed __P((ohci_softc_t *, ohci_soft_ed_t *));
109
110 ohci_soft_td_t *ohci_alloc_std __P((ohci_softc_t *));
111 void ohci_free_std __P((ohci_softc_t *, ohci_soft_td_t *));
112
113 void ohci_free_std_chain __P((ohci_softc_t *,
114 ohci_soft_td_t *, ohci_soft_td_t *));
115 usbd_status ohci_alloc_std_chain __P((struct ohci_pipe *, ohci_softc_t *,
116 int, int, int, usb_dma_t *,
117 ohci_soft_td_t *,
118 ohci_soft_td_t **));
119
120 void ohci_power __P((int, void *));
121 usbd_status ohci_open __P((usbd_pipe_handle));
122 void ohci_poll __P((struct usbd_bus *));
123 void ohci_waitintr __P((ohci_softc_t *, usbd_request_handle));
124 void ohci_rhsc __P((ohci_softc_t *, usbd_request_handle));
125 void ohci_process_done __P((ohci_softc_t *, ohci_physaddr_t));
126
127 usbd_status ohci_device_request __P((usbd_request_handle reqh));
128 void ohci_add_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *));
129 void ohci_rem_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *));
130 void ohci_hash_add_td __P((ohci_softc_t *, ohci_soft_td_t *));
131 void ohci_hash_rem_td __P((ohci_softc_t *, ohci_soft_td_t *));
132 ohci_soft_td_t *ohci_hash_find_td __P((ohci_softc_t *, ohci_physaddr_t));
133
134 usbd_status ohci_allocm __P((struct usbd_bus *, usb_dma_t *, u_int32_t));
135 void ohci_freem __P((struct usbd_bus *, usb_dma_t *));
136
137 usbd_status ohci_root_ctrl_transfer __P((usbd_request_handle));
138 usbd_status ohci_root_ctrl_start __P((usbd_request_handle));
139 void ohci_root_ctrl_abort __P((usbd_request_handle));
140 void ohci_root_ctrl_close __P((usbd_pipe_handle));
141
142 usbd_status ohci_root_intr_transfer __P((usbd_request_handle));
143 usbd_status ohci_root_intr_start __P((usbd_request_handle));
144 void ohci_root_intr_abort __P((usbd_request_handle));
145 void ohci_root_intr_close __P((usbd_pipe_handle));
146 void ohci_root_intr_done __P((usbd_request_handle));
147
148 usbd_status ohci_device_ctrl_transfer __P((usbd_request_handle));
149 usbd_status ohci_device_ctrl_start __P((usbd_request_handle));
150 void ohci_device_ctrl_abort __P((usbd_request_handle));
151 void ohci_device_ctrl_close __P((usbd_pipe_handle));
152 void ohci_device_ctrl_done __P((usbd_request_handle));
153
154 usbd_status ohci_device_bulk_transfer __P((usbd_request_handle));
155 usbd_status ohci_device_bulk_start __P((usbd_request_handle));
156 void ohci_device_bulk_abort __P((usbd_request_handle));
157 void ohci_device_bulk_close __P((usbd_pipe_handle));
158 void ohci_device_bulk_done __P((usbd_request_handle));
159
160 usbd_status ohci_device_intr_transfer __P((usbd_request_handle));
161 usbd_status ohci_device_intr_start __P((usbd_request_handle));
162 void ohci_device_intr_abort __P((usbd_request_handle));
163 void ohci_device_intr_close __P((usbd_pipe_handle));
164 void ohci_device_intr_done __P((usbd_request_handle));
165
166 usbd_status ohci_device_isoc_transfer __P((usbd_request_handle));
167 usbd_status ohci_device_isoc_start __P((usbd_request_handle));
168 void ohci_device_isoc_abort __P((usbd_request_handle));
169 void ohci_device_isoc_close __P((usbd_pipe_handle));
170 void ohci_device_isoc_done __P((usbd_request_handle));
171
172 usbd_status ohci_device_setintr __P((ohci_softc_t *sc,
173 struct ohci_pipe *pipe, int ival));
174
175 int ohci_str __P((usb_string_descriptor_t *, int, char *));
176
177 void ohci_timeout __P((void *));
178 void ohci_rhsc_able __P((ohci_softc_t *, int));
179
180 void ohci_close_pipe __P((usbd_pipe_handle pipe,
181 ohci_soft_ed_t *head));
182 void ohci_abort_req __P((usbd_request_handle reqh,
183 usbd_status status));
184 void ohci_abort_req_end __P((void *));
185
186 void ohci_device_clear_toggle __P((usbd_pipe_handle pipe));
187 void ohci_noop __P((usbd_pipe_handle pipe));
188
189 #ifdef OHCI_DEBUG
190 ohci_softc_t *thesc;
191 void ohci_dumpregs __P((ohci_softc_t *));
192 void ohci_dump_tds __P((ohci_soft_td_t *));
193 void ohci_dump_td __P((ohci_soft_td_t *));
194 void ohci_dump_ed __P((ohci_soft_ed_t *));
195 #endif
196
197 #define OWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
198 #define OREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r))
199 #define OREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r))
200
201 /* Reverse the bits in a value 0 .. 31 */
202 static u_int8_t revbits[OHCI_NO_INTRS] =
203 { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c,
204 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e,
205 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d,
206 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f };
207
208 struct ohci_pipe {
209 struct usbd_pipe pipe;
210 ohci_soft_ed_t *sed;
211 ohci_soft_td_t *tail;
212 /* Info needed for different pipe kinds. */
213 union {
214 /* Control pipe */
215 struct {
216 usb_dma_t reqdma;
217 u_int length;
218 ohci_soft_td_t *setup, *data, *stat;
219 } ctl;
220 /* Interrupt pipe */
221 struct {
222 int nslots;
223 int pos;
224 } intr;
225 /* Bulk pipe */
226 struct {
227 u_int length;
228 int isread;
229 } bulk;
230 /* Iso pipe */
231 struct iso {
232 int xxxxx;
233 } iso;
234 } u;
235 };
236
237 #define OHCI_INTR_ENDPT 1
238
239 struct usbd_bus_methods ohci_bus_methods = {
240 ohci_open,
241 ohci_poll,
242 ohci_allocm,
243 ohci_freem,
244 };
245
246 struct usbd_pipe_methods ohci_root_ctrl_methods = {
247 ohci_root_ctrl_transfer,
248 ohci_root_ctrl_start,
249 ohci_root_ctrl_abort,
250 ohci_root_ctrl_close,
251 ohci_noop,
252 0,
253 };
254
255 struct usbd_pipe_methods ohci_root_intr_methods = {
256 ohci_root_intr_transfer,
257 ohci_root_intr_start,
258 ohci_root_intr_abort,
259 ohci_root_intr_close,
260 ohci_noop,
261 ohci_root_intr_done,
262 };
263
264 struct usbd_pipe_methods ohci_device_ctrl_methods = {
265 ohci_device_ctrl_transfer,
266 ohci_device_ctrl_start,
267 ohci_device_ctrl_abort,
268 ohci_device_ctrl_close,
269 ohci_noop,
270 ohci_device_ctrl_done,
271 };
272
273 struct usbd_pipe_methods ohci_device_intr_methods = {
274 ohci_device_intr_transfer,
275 ohci_device_intr_start,
276 ohci_device_intr_abort,
277 ohci_device_intr_close,
278 ohci_device_clear_toggle,
279 ohci_device_intr_done,
280 };
281
282 struct usbd_pipe_methods ohci_device_bulk_methods = {
283 ohci_device_bulk_transfer,
284 ohci_device_bulk_start,
285 ohci_device_bulk_abort,
286 ohci_device_bulk_close,
287 ohci_device_clear_toggle,
288 ohci_device_bulk_done,
289 };
290
291 #if 0
292 struct usbd_pipe_methods ohci_device_isoc_methods = {
293 ohci_device_isoc_transfer,
294 ohci_device_isoc_start,
295 ohci_device_isoc_abort,
296 ohci_device_isoc_close,
297 ohci_noop,
298 ohci_device_isoc_done,
299 };
300 #endif
301
302 int
303 ohci_activate(self, act)
304 device_ptr_t self;
305 enum devact act;
306 {
307 struct ohci_softc *sc = (struct ohci_softc *)self;
308 int rv = 0;
309
310 switch (act) {
311 case DVACT_ACTIVATE:
312 return (EOPNOTSUPP);
313 break;
314
315 case DVACT_DEACTIVATE:
316 if (sc->sc_child != NULL)
317 rv = config_deactivate(sc->sc_child);
318 break;
319 }
320 return (rv);
321 }
322
323 int
324 ohci_detach(sc, flags)
325 struct ohci_softc *sc;
326 int flags;
327 {
328 int rv = 0;
329
330 if (sc->sc_child != NULL)
331 rv = config_detach(sc->sc_child, flags);
332
333 if (rv != 0)
334 return (rv);
335
336 powerhook_disestablish(sc->sc_powerhook);
337 /* free data structures XXX */
338
339 return (rv);
340 }
341
342 ohci_soft_ed_t *
343 ohci_alloc_sed(sc)
344 ohci_softc_t *sc;
345 {
346 ohci_soft_ed_t *sed;
347 usbd_status r;
348 int i, offs;
349 usb_dma_t dma;
350
351 if (!sc->sc_freeeds) {
352 DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n"));
353 r = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK,
354 OHCI_ED_ALIGN, &dma);
355 if (r != USBD_NORMAL_COMPLETION)
356 return (0);
357 for(i = 0; i < OHCI_SED_CHUNK; i++) {
358 offs = i * OHCI_SED_SIZE;
359 sed = (ohci_soft_ed_t *)((char *)KERNADDR(&dma) +offs);
360 sed->physaddr = DMAADDR(&dma) + offs;
361 sed->next = sc->sc_freeeds;
362 sc->sc_freeeds = sed;
363 }
364 }
365 sed = sc->sc_freeeds;
366 sc->sc_freeeds = sed->next;
367 memset(&sed->ed, 0, sizeof(ohci_ed_t));
368 sed->next = 0;
369 return (sed);
370 }
371
372 void
373 ohci_free_sed(sc, sed)
374 ohci_softc_t *sc;
375 ohci_soft_ed_t *sed;
376 {
377 sed->next = sc->sc_freeeds;
378 sc->sc_freeeds = sed;
379 }
380
381 ohci_soft_td_t *
382 ohci_alloc_std(sc)
383 ohci_softc_t *sc;
384 {
385 ohci_soft_td_t *std;
386 usbd_status r;
387 int i, offs;
388 usb_dma_t dma;
389
390 if (!sc->sc_freetds) {
391 DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n"));
392 r = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK,
393 OHCI_TD_ALIGN, &dma);
394 if (r != USBD_NORMAL_COMPLETION)
395 return (0);
396 for(i = 0; i < OHCI_STD_CHUNK; i++) {
397 offs = i * OHCI_STD_SIZE;
398 std = (ohci_soft_td_t *)((char *)KERNADDR(&dma) +offs);
399 std->physaddr = DMAADDR(&dma) + offs;
400 std->nexttd = sc->sc_freetds;
401 sc->sc_freetds = std;
402 }
403 }
404 std = sc->sc_freetds;
405 sc->sc_freetds = std->nexttd;
406 memset(&std->td, 0, sizeof(ohci_td_t));
407 std->nexttd = 0;
408 return (std);
409 }
410
411 void
412 ohci_free_std(sc, std)
413 ohci_softc_t *sc;
414 ohci_soft_td_t *std;
415 {
416 std->nexttd = sc->sc_freetds;
417 sc->sc_freetds = std;
418 }
419
420 usbd_status
421 ohci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep)
422 struct ohci_pipe *upipe;
423 ohci_softc_t *sc;
424 int len, rd, shortok;
425 usb_dma_t *dma;
426 ohci_soft_td_t *sp, **ep;
427 {
428 ohci_soft_td_t *next, *cur;
429 ohci_physaddr_t dataphys, dataphysend;
430 u_int32_t intr;
431 int curlen;
432
433 DPRINTFN(len >= 4096,("ohci_alloc_std_chain: start len=%d\n", len));
434 cur = sp;
435 dataphys = DMAADDR(dma);
436 dataphysend = OHCI_PAGE(dataphys + len - 1);
437 for (;;) {
438 next = ohci_alloc_std(sc);
439 if (next == 0) {
440 /* XXX free chain */
441 return (USBD_NOMEM);
442 }
443
444 /* The OHCI hardware can handle at most one page crossing. */
445 if (OHCI_PAGE(dataphys) == dataphysend ||
446 OHCI_PAGE(dataphys) + OHCI_PAGE_SIZE == dataphysend) {
447 /* we can handle it in this TD */
448 curlen = len;
449 } else {
450 /* must use multiple TDs, fill as much as possible. */
451 curlen = 2 * OHCI_PAGE_SIZE -
452 (dataphys & (OHCI_PAGE_SIZE-1));
453 }
454 DPRINTFN(4,("ohci_alloc_std_chain: dataphys=0x%08x "
455 "dataphysend=0x%08x len=%d curlen=%d\n",
456 dataphys, dataphysend,
457 len, curlen));
458 len -= curlen;
459
460 intr = len == 0 ? OHCI_TD_SET_DI(1) : OHCI_TD_NOINTR;
461 cur->td.td_flags = LE(
462 (rd ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC |
463 intr | OHCI_TD_TOGGLE_CARRY |
464 (shortok ? OHCI_TD_R : 0));
465 cur->td.td_cbp = LE(dataphys);
466 cur->nexttd = next;
467 cur->td.td_nexttd = LE(next->physaddr);
468 cur->td.td_be = LE(dataphys + curlen - 1);
469 cur->len = curlen;
470 cur->flags = OHCI_ADD_LEN;
471 DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n",
472 dataphys, dataphys + curlen - 1));
473 if (len == 0)
474 break;
475 DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n"));
476 dataphys += curlen;
477 cur = next;
478 }
479 cur->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
480 *ep = next;
481
482 return (USBD_NORMAL_COMPLETION);
483 }
484
485 void
486 ohci_free_std_chain(sc, std, stdend)
487 ohci_softc_t *sc;
488 ohci_soft_td_t *std;
489 ohci_soft_td_t *stdend;
490 {
491 ohci_soft_td_t *p;
492
493 for (; std != stdend; std = p) {
494 p = std->nexttd;
495 ohci_free_std(sc, std);
496 }
497 }
498
499 usbd_status
500 ohci_init(sc)
501 ohci_softc_t *sc;
502 {
503 ohci_soft_ed_t *sed, *psed;
504 usbd_status r;
505 int rev;
506 int i;
507 u_int32_t s, ctl, ival, hcr, fm, per;
508
509 DPRINTF(("ohci_init: start\n"));
510 rev = OREAD4(sc, OHCI_REVISION);
511 #if defined(__OpenBSD__)
512 printf(", OHCI version %d.%d%s\n",
513 #else
514 printf("%s: OHCI version %d.%d%s\n", USBDEVNAME(sc->sc_bus.bdev),
515 #endif
516 OHCI_REV_HI(rev), OHCI_REV_LO(rev),
517 OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
518 if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) {
519 printf("%s: unsupported OHCI revision\n",
520 USBDEVNAME(sc->sc_bus.bdev));
521 return (USBD_INVAL);
522 }
523
524 for (i = 0; i < OHCI_HASH_SIZE; i++)
525 LIST_INIT(&sc->sc_hash_tds[i]);
526
527 /* Allocate the HCCA area. */
528 r = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
529 OHCI_HCCA_ALIGN, &sc->sc_hccadma);
530 if (r != USBD_NORMAL_COMPLETION)
531 return (r);
532 sc->sc_hcca = (struct ohci_hcca *)KERNADDR(&sc->sc_hccadma);
533 memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE);
534
535 sc->sc_eintrs = OHCI_NORMAL_INTRS;
536
537 sc->sc_ctrl_head = ohci_alloc_sed(sc);
538 if (!sc->sc_ctrl_head) {
539 r = USBD_NOMEM;
540 goto bad1;
541 }
542 sc->sc_ctrl_head->ed.ed_flags |= LE(OHCI_ED_SKIP);
543
544 sc->sc_bulk_head = ohci_alloc_sed(sc);
545 if (!sc->sc_bulk_head) {
546 r = USBD_NOMEM;
547 goto bad2;
548 }
549 sc->sc_bulk_head->ed.ed_flags |= LE(OHCI_ED_SKIP);
550
551 /* Allocate all the dummy EDs that make up the interrupt tree. */
552 for (i = 0; i < OHCI_NO_EDS; i++) {
553 sed = ohci_alloc_sed(sc);
554 if (!sed) {
555 while (--i >= 0)
556 ohci_free_sed(sc, sc->sc_eds[i]);
557 r = USBD_NOMEM;
558 goto bad3;
559 }
560 /* All ED fields are set to 0. */
561 sc->sc_eds[i] = sed;
562 sed->ed.ed_flags |= LE(OHCI_ED_SKIP);
563 if (i != 0) {
564 psed = sc->sc_eds[(i-1) / 2];
565 sed->next = psed;
566 sed->ed.ed_nexted = LE(psed->physaddr);
567 }
568 }
569 /*
570 * Fill HCCA interrupt table. The bit reversal is to get
571 * the tree set up properly to spread the interrupts.
572 */
573 for (i = 0; i < OHCI_NO_INTRS; i++)
574 sc->sc_hcca->hcca_interrupt_table[revbits[i]] =
575 LE(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr);
576
577 /* Determine in what context we are running. */
578 ctl = OREAD4(sc, OHCI_CONTROL);
579 if (ctl & OHCI_IR) {
580 /* SMM active, request change */
581 DPRINTF(("ohci_init: SMM active, request owner change\n"));
582 s = OREAD4(sc, OHCI_COMMAND_STATUS);
583 OWRITE4(sc, OHCI_COMMAND_STATUS, s | OHCI_OCR);
584 for (i = 0; i < 100 && (ctl & OHCI_IR); i++) {
585 delay(1000);
586 ctl = OREAD4(sc, OHCI_CONTROL);
587 }
588 if ((ctl & OHCI_IR) == 0) {
589 printf("%s: SMM does not respond, resetting\n",
590 USBDEVNAME(sc->sc_bus.bdev));
591 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
592 goto reset;
593 }
594 } else if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_RESET) {
595 /* BIOS started controller. */
596 DPRINTF(("ohci_init: BIOS active\n"));
597 if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_OPERATIONAL) {
598 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_OPERATIONAL);
599 delay(USB_RESUME_DELAY * 1000);
600 }
601 } else {
602 DPRINTF(("ohci_init: cold started\n"));
603 reset:
604 /* Controller was cold started. */
605 delay(USB_BUS_RESET_DELAY * 1000);
606 }
607
608 /*
609 * This reset should not be necessary according to the OHCI spec, but
610 * without it some controllers do not start.
611 */
612 DPRINTF(("%s: resetting\n", USBDEVNAME(sc->sc_bus.bdev)));
613 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
614 delay(USB_BUS_RESET_DELAY * 1000);
615
616 /* We now own the host controller and the bus has been reset. */
617 ival = OHCI_GET_IVAL(OREAD4(sc, OHCI_FM_INTERVAL));
618
619 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_HCR); /* Reset HC */
620 /* Nominal time for a reset is 10 us. */
621 for (i = 0; i < 10; i++) {
622 delay(10);
623 hcr = OREAD4(sc, OHCI_COMMAND_STATUS) & OHCI_HCR;
624 if (!hcr)
625 break;
626 }
627 if (hcr) {
628 printf("%s: reset timeout\n", USBDEVNAME(sc->sc_bus.bdev));
629 r = USBD_IOERROR;
630 goto bad3;
631 }
632 #ifdef OHCI_DEBUG
633 thesc = sc;
634 if (ohcidebug > 15)
635 ohci_dumpregs(sc);
636 #endif
637
638 /* The controller is now in suspend state, we have 2ms to finish. */
639
640 /* Set up HC registers. */
641 OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma));
642 OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
643 OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
644 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
645 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
646 ctl = OREAD4(sc, OHCI_CONTROL);
647 ctl &= ~(OHCI_CBSR_MASK | OHCI_LES | OHCI_HCFS_MASK | OHCI_IR);
648 ctl |= OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE |
649 OHCI_RATIO_1_4 | OHCI_HCFS_OPERATIONAL;
650 /* And finally start it! */
651 OWRITE4(sc, OHCI_CONTROL, ctl);
652
653 /*
654 * The controller is now OPERATIONAL. Set a some final
655 * registers that should be set earlier, but that the
656 * controller ignores when in the SUSPEND state.
657 */
658 fm = (OREAD4(sc, OHCI_FM_INTERVAL) & OHCI_FIT) ^ OHCI_FIT;
659 fm |= OHCI_FSMPS(ival) | ival;
660 OWRITE4(sc, OHCI_FM_INTERVAL, fm);
661 per = OHCI_PERIODIC(ival); /* 90% periodic */
662 OWRITE4(sc, OHCI_PERIODIC_START, per);
663
664 OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */
665
666 sc->sc_noport = OHCI_GET_NDP(OREAD4(sc, OHCI_RH_DESCRIPTOR_A));
667
668 #ifdef OHCI_DEBUG
669 if (ohcidebug > 5)
670 ohci_dumpregs(sc);
671 #endif
672
673 /* Set up the bus struct. */
674 sc->sc_bus.methods = &ohci_bus_methods;
675 sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
676
677 sc->sc_powerhook = powerhook_establish(ohci_power, sc);
678
679 return (USBD_NORMAL_COMPLETION);
680
681 bad3:
682 ohci_free_sed(sc, sc->sc_ctrl_head);
683 bad2:
684 ohci_free_sed(sc, sc->sc_bulk_head);
685 bad1:
686 usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
687 return (r);
688 }
689
690 usbd_status
691 ohci_allocm(bus, dma, size)
692 struct usbd_bus *bus;
693 usb_dma_t *dma;
694 u_int32_t size;
695 {
696 #if defined(__NetBSD__) || defined(__OpenBSD__)
697 struct ohci_softc *sc = (struct ohci_softc *)bus;
698 #endif
699
700 return (usb_allocmem(&sc->sc_bus, size, 0, dma));
701 }
702
703 void
704 ohci_freem(bus, dma)
705 struct usbd_bus *bus;
706 usb_dma_t *dma;
707 {
708 #if defined(__NetBSD__) || defined(__OpenBSD__)
709 struct ohci_softc *sc = (struct ohci_softc *)bus;
710 #endif
711
712 usb_freemem(&sc->sc_bus, dma);
713 }
714
715 #if defined(__NetBSD__)
716 void
717 ohci_power(why, v)
718 int why;
719 void *v;
720 {
721 #ifdef OHCI_DEBUG
722 ohci_softc_t *sc = v;
723
724 DPRINTF(("ohci_power: sc=%p, why=%d\n", sc, why));
725 /* XXX should suspend/resume */
726 ohci_dumpregs(sc);
727 #endif
728 }
729 #endif /* defined(__NetBSD__) */
730
731 #ifdef OHCI_DEBUG
732 void ohcidump(void);
733 void ohcidump(void) { ohci_dumpregs(thesc); }
734
735 void
736 ohci_dumpregs(sc)
737 ohci_softc_t *sc;
738 {
739 DPRINTF(("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n",
740 OREAD4(sc, OHCI_REVISION),
741 OREAD4(sc, OHCI_CONTROL),
742 OREAD4(sc, OHCI_COMMAND_STATUS)));
743 DPRINTF((" intrstat=0x%08x intre=0x%08x intrd=0x%08x\n",
744 OREAD4(sc, OHCI_INTERRUPT_STATUS),
745 OREAD4(sc, OHCI_INTERRUPT_ENABLE),
746 OREAD4(sc, OHCI_INTERRUPT_DISABLE)));
747 DPRINTF((" hcca=0x%08x percur=0x%08x ctrlhd=0x%08x\n",
748 OREAD4(sc, OHCI_HCCA),
749 OREAD4(sc, OHCI_PERIOD_CURRENT_ED),
750 OREAD4(sc, OHCI_CONTROL_HEAD_ED)));
751 DPRINTF((" ctrlcur=0x%08x bulkhd=0x%08x bulkcur=0x%08x\n",
752 OREAD4(sc, OHCI_CONTROL_CURRENT_ED),
753 OREAD4(sc, OHCI_BULK_HEAD_ED),
754 OREAD4(sc, OHCI_BULK_CURRENT_ED)));
755 DPRINTF((" done=0x%08x fmival=0x%08x fmrem=0x%08x\n",
756 OREAD4(sc, OHCI_DONE_HEAD),
757 OREAD4(sc, OHCI_FM_INTERVAL),
758 OREAD4(sc, OHCI_FM_REMAINING)));
759 DPRINTF((" fmnum=0x%08x perst=0x%08x lsthrs=0x%08x\n",
760 OREAD4(sc, OHCI_FM_NUMBER),
761 OREAD4(sc, OHCI_PERIODIC_START),
762 OREAD4(sc, OHCI_LS_THRESHOLD)));
763 DPRINTF((" desca=0x%08x descb=0x%08x stat=0x%08x\n",
764 OREAD4(sc, OHCI_RH_DESCRIPTOR_A),
765 OREAD4(sc, OHCI_RH_DESCRIPTOR_B),
766 OREAD4(sc, OHCI_RH_STATUS)));
767 DPRINTF((" port1=0x%08x port2=0x%08x\n",
768 OREAD4(sc, OHCI_RH_PORT_STATUS(1)),
769 OREAD4(sc, OHCI_RH_PORT_STATUS(2))));
770 DPRINTF((" HCCA: frame_number=0x%04x done_head=0x%08x\n",
771 LE(sc->sc_hcca->hcca_frame_number),
772 LE(sc->sc_hcca->hcca_done_head)));
773 }
774 #endif
775
776 int
777 ohci_intr(p)
778 void *p;
779 {
780 ohci_softc_t *sc = p;
781 u_int32_t intrs, eintrs;
782 ohci_physaddr_t done;
783
784 /* In case the interrupt occurs before initialization has completed. */
785 if (sc == NULL || sc->sc_hcca == NULL) {
786 #ifdef DIAGNOSTIC
787 printf("ohci_intr: sc->sc_hcca == NULL\n");
788 #endif
789 return (0);
790 }
791
792 intrs = 0;
793 done = LE(sc->sc_hcca->hcca_done_head);
794 if (done != 0) {
795 sc->sc_hcca->hcca_done_head = 0;
796 if (done & ~OHCI_DONE_INTRS)
797 intrs = OHCI_WDH;
798 if (done & OHCI_DONE_INTRS)
799 intrs |= OREAD4(sc, OHCI_INTERRUPT_STATUS);
800 } else
801 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS);
802 if (!intrs)
803 return (0);
804 intrs &= ~OHCI_MIE;
805 OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs); /* Acknowledge */
806 eintrs = intrs & sc->sc_eintrs;
807 if (!eintrs)
808 return (0);
809
810 sc->sc_bus.intr_context++;
811 sc->sc_bus.no_intrs++;
812 DPRINTFN(7, ("ohci_intr: sc=%p intrs=%x(%x) eintr=%x\n",
813 sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS),
814 (u_int)eintrs));
815
816 if (eintrs & OHCI_SO) {
817 printf("%s: scheduling overrun\n",USBDEVNAME(sc->sc_bus.bdev));
818 /* XXX do what */
819 intrs &= ~OHCI_SO;
820 }
821 if (eintrs & OHCI_WDH) {
822 ohci_process_done(sc, done &~ OHCI_DONE_INTRS);
823 intrs &= ~OHCI_WDH;
824 }
825 if (eintrs & OHCI_RD) {
826 printf("%s: resume detect\n", USBDEVNAME(sc->sc_bus.bdev));
827 /* XXX process resume detect */
828 }
829 if (eintrs & OHCI_UE) {
830 printf("%s: unrecoverable error, controller halted\n",
831 USBDEVNAME(sc->sc_bus.bdev));
832 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
833 /* XXX what else */
834 }
835 if (eintrs & OHCI_RHSC) {
836 ohci_rhsc(sc, sc->sc_intrreqh);
837 intrs &= ~OHCI_RHSC;
838
839 /*
840 * Disable RHSC interrupt for now, because it will be
841 * on until the port has been reset.
842 */
843 ohci_rhsc_able(sc, 0);
844 }
845
846 sc->sc_bus.intr_context--;
847
848 /* Block unprocessed interrupts. XXX */
849 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, intrs);
850 sc->sc_eintrs &= ~intrs;
851
852 return (1);
853 }
854
855 void
856 ohci_rhsc_able(sc, on)
857 ohci_softc_t *sc;
858 int on;
859 {
860 DPRINTFN(4, ("ohci_rhsc_able: on=%d\n", on));
861 if (on) {
862 sc->sc_eintrs |= OHCI_RHSC;
863 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC);
864 } else {
865 sc->sc_eintrs &= ~OHCI_RHSC;
866 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_RHSC);
867 }
868 }
869
870 #ifdef OHCI_DEBUG
871 char *ohci_cc_strs[] = {
872 "NO_ERROR",
873 "CRC",
874 "BIT_STUFFING",
875 "DATA_TOGGLE_MISMATCH",
876 "STALL",
877 "DEVICE_NOT_RESPONDING",
878 "PID_CHECK_FAILURE",
879 "UNEXPECTED_PID",
880 "DATA_OVERRUN",
881 "DATA_UNDERRUN",
882 "BUFFER_OVERRUN",
883 "BUFFER_UNDERRUN",
884 "NOT_ACCESSED",
885 };
886 #endif
887
888 void
889 ohci_process_done(sc, done)
890 ohci_softc_t *sc;
891 ohci_physaddr_t done;
892 {
893 ohci_soft_td_t *std, *sdone, *stdnext;
894 usbd_request_handle reqh;
895 int len, cc;
896
897 DPRINTFN(10,("ohci_process_done: done=0x%08lx\n", (u_long)done));
898
899 /* Reverse the done list. */
900 for (sdone = 0; done; done = LE(std->td.td_nexttd)) {
901 std = ohci_hash_find_td(sc, done);
902 std->dnext = sdone;
903 sdone = std;
904 }
905
906 #ifdef OHCI_DEBUG
907 if (ohcidebug > 10) {
908 DPRINTF(("ohci_process_done: TD done:\n"));
909 ohci_dump_tds(sdone);
910 }
911 #endif
912
913 for (std = sdone; std; std = stdnext) {
914 reqh = std->reqh;
915 stdnext = std->dnext;
916 DPRINTFN(10, ("ohci_process_done: std=%p reqh=%p hcpriv=%p\n",
917 std, reqh, reqh->hcpriv));
918 cc = OHCI_TD_GET_CC(LE(std->td.td_flags));
919 usb_untimeout(ohci_timeout, reqh, reqh->timo_handle);
920 if (reqh->status == USBD_CANCELLED ||
921 reqh->status == USBD_TIMEOUT) {
922 DPRINTF(("ohci_process_done: cancel/timeout %p\n",
923 reqh));
924 /* Handled by abort routine. */
925 } else if (cc == OHCI_CC_NO_ERROR) {
926 len = std->len;
927 if (std->td.td_cbp != 0)
928 len -= LE(std->td.td_be) -
929 LE(std->td.td_cbp) + 1;
930 if (std->flags & OHCI_ADD_LEN)
931 reqh->actlen += len;
932 if (std->flags & OHCI_CALL_DONE) {
933 reqh->status = USBD_NORMAL_COMPLETION;
934 usb_transfer_complete(reqh);
935 }
936 ohci_hash_rem_td(sc, std);
937 ohci_free_std(sc, std);
938 } else {
939 /*
940 * Endpoint is halted. First unlink all the TDs
941 * belonging to the failed transfer, and then restart
942 * the endpoint.
943 */
944 ohci_soft_td_t *p, *n;
945 struct ohci_pipe *opipe =
946 (struct ohci_pipe *)reqh->pipe;
947
948 DPRINTFN(-1,("ohci_process_done: error cc=%d (%s)\n",
949 OHCI_TD_GET_CC(LE(std->td.td_flags)),
950 ohci_cc_strs[OHCI_TD_GET_CC(LE(std->td.td_flags))]));
951
952 /* remove TDs */
953 for (p = std; p->reqh == reqh; p = n) {
954 n = p->nexttd;
955 ohci_hash_rem_td(sc, p);
956 ohci_free_std(sc, p);
957 }
958
959 /* clear halt */
960 opipe->sed->ed.ed_headp = LE(p->physaddr);
961 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
962
963 if (cc == OHCI_CC_STALL)
964 reqh->status = USBD_STALLED;
965 else
966 reqh->status = USBD_IOERROR;
967 usb_transfer_complete(reqh);
968 }
969 }
970 }
971
972 void
973 ohci_device_ctrl_done(reqh)
974 usbd_request_handle reqh;
975 {
976 DPRINTFN(10,("ohci_ctrl_done: reqh=%p\n", reqh));
977
978 #ifdef DIAGNOSTIC
979 if (!(reqh->rqflags & URQ_REQUEST)) {
980 panic("ohci_ctrl_done: not a request\n");
981 }
982 #endif
983 reqh->hcpriv = 0;
984 }
985
986 void
987 ohci_device_intr_done(reqh)
988 usbd_request_handle reqh;
989 {
990 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
991 ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
992 ohci_soft_ed_t *sed = opipe->sed;
993 ohci_soft_td_t *data, *tail;
994
995
996 DPRINTFN(10,("ohci_intr_done: reqh=%p, actlen=%d\n",
997 reqh, reqh->actlen));
998
999 reqh->hcpriv = 0;
1000
1001 if (reqh->pipe->repeat) {
1002 data = opipe->tail;
1003 tail = ohci_alloc_std(sc); /* XXX should reuse TD */
1004 if (!tail) {
1005 reqh->status = USBD_NOMEM;
1006 return;
1007 }
1008 tail->reqh = 0;
1009
1010 data->td.td_flags = LE(
1011 OHCI_TD_IN | OHCI_TD_NOCC |
1012 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
1013 if (reqh->flags & USBD_SHORT_XFER_OK)
1014 data->td.td_flags |= LE(OHCI_TD_R);
1015 data->td.td_cbp = LE(DMAADDR(&reqh->dmabuf));
1016 data->nexttd = tail;
1017 data->td.td_nexttd = LE(tail->physaddr);
1018 data->td.td_be = LE(LE(data->td.td_cbp) + reqh->length - 1);
1019 data->len = reqh->length;
1020 data->reqh = reqh;
1021 data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
1022 reqh->hcpriv = data;
1023 reqh->actlen = 0;
1024
1025 ohci_hash_add_td(sc, data);
1026 sed->ed.ed_tailp = LE(tail->physaddr);
1027 opipe->tail = tail;
1028 }
1029 }
1030
1031 void
1032 ohci_device_bulk_done(reqh)
1033 usbd_request_handle reqh;
1034 {
1035 DPRINTFN(10,("ohci_bulk_done: reqh=%p, actlen=%d\n",
1036 reqh, reqh->actlen));
1037
1038 reqh->hcpriv = 0;
1039 }
1040
1041 void
1042 ohci_rhsc(sc, reqh)
1043 ohci_softc_t *sc;
1044 usbd_request_handle reqh;
1045 {
1046 usbd_pipe_handle pipe;
1047 struct ohci_pipe *opipe;
1048 u_char *p;
1049 int i, m;
1050 int hstatus;
1051
1052 hstatus = OREAD4(sc, OHCI_RH_STATUS);
1053 DPRINTF(("ohci_rhsc: sc=%p reqh=%p hstatus=0x%08x\n",
1054 sc, reqh, hstatus));
1055
1056 if (reqh == 0) {
1057 /* Just ignore the change. */
1058 return;
1059 }
1060
1061 pipe = reqh->pipe;
1062 opipe = (struct ohci_pipe *)pipe;
1063
1064 p = KERNADDR(&reqh->dmabuf);
1065 m = min(sc->sc_noport, reqh->length * 8 - 1);
1066 memset(p, 0, reqh->length);
1067 for (i = 1; i <= m; i++) {
1068 if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16)
1069 p[i/8] |= 1 << (i%8);
1070 }
1071 DPRINTF(("ohci_rhsc: change=0x%02x\n", *p));
1072 reqh->actlen = reqh->length;
1073 reqh->status = USBD_NORMAL_COMPLETION;
1074
1075 usb_transfer_complete(reqh);
1076 }
1077
1078 void
1079 ohci_root_intr_done(reqh)
1080 usbd_request_handle reqh;
1081 {
1082 reqh->hcpriv = 0;
1083 }
1084
1085 /*
1086 * Wait here until controller claims to have an interrupt.
1087 * Then call ohci_intr and return. Use timeout to avoid waiting
1088 * too long.
1089 */
1090 void
1091 ohci_waitintr(sc, reqh)
1092 ohci_softc_t *sc;
1093 usbd_request_handle reqh;
1094 {
1095 int timo = reqh->timeout;
1096 int usecs;
1097 u_int32_t intrs;
1098
1099 reqh->status = USBD_IN_PROGRESS;
1100 for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) {
1101 usb_delay_ms(&sc->sc_bus, 1);
1102 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs;
1103 DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs));
1104 #ifdef OHCI_DEBUG
1105 if (ohcidebug > 15)
1106 ohci_dumpregs(sc);
1107 #endif
1108 if (intrs) {
1109 ohci_intr(sc);
1110 if (reqh->status != USBD_IN_PROGRESS)
1111 return;
1112 }
1113 }
1114
1115 /* Timeout */
1116 DPRINTF(("ohci_waitintr: timeout\n"));
1117 reqh->status = USBD_TIMEOUT;
1118 usb_transfer_complete(reqh);
1119 /* XXX should free TD */
1120 }
1121
1122 void
1123 ohci_poll(bus)
1124 struct usbd_bus *bus;
1125 {
1126 ohci_softc_t *sc = (ohci_softc_t *)bus;
1127
1128 if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs)
1129 ohci_intr(sc);
1130 }
1131
1132 usbd_status
1133 ohci_device_request(reqh)
1134 usbd_request_handle reqh;
1135 {
1136 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
1137 usb_device_request_t *req = &reqh->request;
1138 usbd_device_handle dev = opipe->pipe.device;
1139 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
1140 int addr = dev->address;
1141 ohci_soft_td_t *setup, *data = 0, *stat, *next, *tail;
1142 ohci_soft_ed_t *sed;
1143 int isread;
1144 int len;
1145 usbd_status r;
1146 int s;
1147
1148 isread = req->bmRequestType & UT_READ;
1149 len = UGETW(req->wLength);
1150
1151 DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, "
1152 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
1153 req->bmRequestType, req->bRequest, UGETW(req->wValue),
1154 UGETW(req->wIndex), len, addr,
1155 opipe->pipe.endpoint->edesc->bEndpointAddress));
1156
1157 setup = opipe->tail;
1158 stat = ohci_alloc_std(sc);
1159 if (!stat) {
1160 r = USBD_NOMEM;
1161 goto bad1;
1162 }
1163 tail = ohci_alloc_std(sc);
1164 if (!tail) {
1165 r = USBD_NOMEM;
1166 goto bad2;
1167 }
1168 tail->reqh = 0;
1169
1170 sed = opipe->sed;
1171 opipe->u.ctl.length = len;
1172
1173 /* Update device address and length since they may have changed. */
1174 /* XXX This only needs to be done once, but it's too early in open. */
1175 sed->ed.ed_flags = LE(
1176 (LE(sed->ed.ed_flags) & ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) |
1177 OHCI_ED_SET_FA(addr) |
1178 OHCI_ED_SET_MAXP(UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize)));
1179
1180 /* Set up data transaction */
1181 if (len != 0) {
1182 data = ohci_alloc_std(sc);
1183 if (!data) {
1184 r = USBD_NOMEM;
1185 goto bad3;
1186 }
1187 data->td.td_flags = LE(
1188 (isread ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC |
1189 OHCI_TD_TOGGLE_1 | OHCI_TD_NOINTR |
1190 (reqh->flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0));
1191 data->td.td_cbp = LE(DMAADDR(&reqh->dmabuf));
1192 data->nexttd = stat;
1193 data->td.td_nexttd = LE(stat->physaddr);
1194 data->td.td_be = LE(LE(data->td.td_cbp) + len - 1);
1195 data->len = len;
1196 data->reqh = reqh;
1197 data->flags = OHCI_ADD_LEN;
1198
1199 next = data;
1200 stat->flags = OHCI_CALL_DONE;
1201 } else {
1202 next = stat;
1203 /* XXX ADD_LEN? */
1204 stat->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
1205 }
1206
1207 memcpy(KERNADDR(&opipe->u.ctl.reqdma), req, sizeof *req);
1208
1209 setup->td.td_flags = LE(OHCI_TD_SETUP | OHCI_TD_NOCC |
1210 OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR);
1211 setup->td.td_cbp = LE(DMAADDR(&opipe->u.ctl.reqdma));
1212 setup->nexttd = next;
1213 setup->td.td_nexttd = LE(next->physaddr);
1214 setup->td.td_be = LE(LE(setup->td.td_cbp) + sizeof *req - 1);
1215 setup->len = 0; /* XXX The number of byte we count */
1216 setup->reqh = reqh;
1217 setup->flags = 0;
1218 reqh->hcpriv = setup;
1219
1220 stat->td.td_flags = LE(
1221 (isread ? OHCI_TD_OUT : OHCI_TD_IN) | OHCI_TD_NOCC |
1222 OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1));
1223 stat->td.td_cbp = 0;
1224 stat->nexttd = tail;
1225 stat->td.td_nexttd = LE(tail->physaddr);
1226 stat->td.td_be = 0;
1227 stat->len = 0;
1228 stat->reqh = reqh;
1229
1230 #ifdef OHCI_DEBUG
1231 if (ohcidebug > 5) {
1232 DPRINTF(("ohci_device_request:\n"));
1233 ohci_dump_ed(sed);
1234 ohci_dump_tds(setup);
1235 }
1236 #endif
1237
1238 /* Insert ED in schedule */
1239 s = splusb();
1240 ohci_hash_add_td(sc, setup);
1241 if (len != 0)
1242 ohci_hash_add_td(sc, data);
1243 ohci_hash_add_td(sc, stat);
1244 sed->ed.ed_tailp = LE(tail->physaddr);
1245 opipe->tail = tail;
1246 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
1247 if (reqh->timeout && !sc->sc_bus.use_polling) {
1248 usb_timeout(ohci_timeout, reqh,
1249 MS_TO_TICKS(reqh->timeout), reqh->timo_handle);
1250 }
1251 splx(s);
1252
1253 #ifdef OHCI_DEBUG
1254 if (ohcidebug > 5) {
1255 delay(5000);
1256 DPRINTF(("ohci_device_request: status=%x\n",
1257 OREAD4(sc, OHCI_COMMAND_STATUS)));
1258 ohci_dump_ed(sed);
1259 ohci_dump_tds(setup);
1260 }
1261 #endif
1262
1263 return (USBD_NORMAL_COMPLETION);
1264
1265 bad3:
1266 ohci_free_std(sc, tail);
1267 bad2:
1268 ohci_free_std(sc, stat);
1269 bad1:
1270 return (r);
1271 }
1272
1273 /*
1274 * Add an ED to the schedule. Called at splusb().
1275 */
1276 void
1277 ohci_add_ed(sed, head)
1278 ohci_soft_ed_t *sed;
1279 ohci_soft_ed_t *head;
1280 {
1281 SPLUSBCHECK;
1282 sed->next = head->next;
1283 sed->ed.ed_nexted = head->ed.ed_nexted;
1284 head->next = sed;
1285 head->ed.ed_nexted = LE(sed->physaddr);
1286 }
1287
1288 /*
1289 * Remove an ED from the schedule. Called at splusb().
1290 */
1291 void
1292 ohci_rem_ed(sed, head)
1293 ohci_soft_ed_t *sed;
1294 ohci_soft_ed_t *head;
1295 {
1296 ohci_soft_ed_t *p;
1297
1298 SPLUSBCHECK;
1299
1300 /* XXX */
1301 for (p = head; p && p->next != sed; p = p->next)
1302 ;
1303 if (!p)
1304 panic("ohci_rem_ed: ED not found\n");
1305 p->next = sed->next;
1306 p->ed.ed_nexted = sed->ed.ed_nexted;
1307 }
1308
1309 /*
1310 * When a transfer is completed the TD is added to the done queue by
1311 * the host controller. This queue is the processed by software.
1312 * Unfortunately the queue contains the physical address of the TD
1313 * and we have no simple way to translate this back to a kernel address.
1314 * To make the translation possible (and fast) we use a hash table of
1315 * TDs currently in the schedule. The physical address is used as the
1316 * hash value.
1317 */
1318
1319 #define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE)
1320 /* Called at splusb() */
1321 void
1322 ohci_hash_add_td(sc, std)
1323 ohci_softc_t *sc;
1324 ohci_soft_td_t *std;
1325 {
1326 int h = HASH(std->physaddr);
1327
1328 SPLUSBCHECK;
1329
1330 LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
1331 }
1332
1333 /* Called at splusb() */
1334 void
1335 ohci_hash_rem_td(sc, std)
1336 ohci_softc_t *sc;
1337 ohci_soft_td_t *std;
1338 {
1339 SPLUSBCHECK;
1340
1341 LIST_REMOVE(std, hnext);
1342 }
1343
1344 ohci_soft_td_t *
1345 ohci_hash_find_td(sc, a)
1346 ohci_softc_t *sc;
1347 ohci_physaddr_t a;
1348 {
1349 int h = HASH(a);
1350 ohci_soft_td_t *std;
1351
1352 for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
1353 std != 0;
1354 std = LIST_NEXT(std, hnext))
1355 if (std->physaddr == a)
1356 return (std);
1357 panic("ohci_hash_find_td: addr 0x%08lx not found\n", (u_long)a);
1358 }
1359
1360 void
1361 ohci_timeout(addr)
1362 void *addr;
1363 {
1364 usbd_request_handle reqh = addr;
1365 int s;
1366
1367 DPRINTF(("ohci_timeout: reqh=%p\n", reqh));
1368
1369 s = splusb();
1370 reqh->device->bus->intr_context++;
1371 ohci_abort_req(reqh, USBD_TIMEOUT);
1372 reqh->device->bus->intr_context--;
1373 splx(s);
1374 }
1375
1376 #ifdef OHCI_DEBUG
1377 void
1378 ohci_dump_tds(std)
1379 ohci_soft_td_t *std;
1380 {
1381 for (; std; std = std->nexttd)
1382 ohci_dump_td(std);
1383 }
1384
1385 void
1386 ohci_dump_td(std)
1387 ohci_soft_td_t *std;
1388 {
1389 DPRINTF(("TD(%p) at %08lx: %b delay=%d ec=%d cc=%d\ncbp=0x%08lx "
1390 "nexttd=0x%08lx be=0x%08lx\n",
1391 std, (u_long)std->physaddr,
1392 (int)LE(std->td.td_flags),
1393 "\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE",
1394 OHCI_TD_GET_DI(LE(std->td.td_flags)),
1395 OHCI_TD_GET_EC(LE(std->td.td_flags)),
1396 OHCI_TD_GET_CC(LE(std->td.td_flags)),
1397 (u_long)LE(std->td.td_cbp),
1398 (u_long)LE(std->td.td_nexttd), (u_long)LE(std->td.td_be)));
1399 }
1400
1401 void
1402 ohci_dump_ed(sed)
1403 ohci_soft_ed_t *sed;
1404 {
1405 DPRINTF(("ED(%p) at %08lx: addr=%d endpt=%d maxp=%d %b\ntailp=0x%08lx "
1406 "headp=%b nexted=0x%08lx\n",
1407 sed, (u_long)sed->physaddr,
1408 OHCI_ED_GET_FA(LE(sed->ed.ed_flags)),
1409 OHCI_ED_GET_EN(LE(sed->ed.ed_flags)),
1410 OHCI_ED_GET_MAXP(LE(sed->ed.ed_flags)),
1411 (int)LE(sed->ed.ed_flags),
1412 "\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO",
1413 (u_long)LE(sed->ed.ed_tailp),
1414 (u_long)LE(sed->ed.ed_headp),
1415 "\20\1HALT\2CARRY",
1416 (u_long)LE(sed->ed.ed_nexted)));
1417 }
1418 #endif
1419
1420 usbd_status
1421 ohci_open(pipe)
1422 usbd_pipe_handle pipe;
1423 {
1424 usbd_device_handle dev = pipe->device;
1425 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
1426 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
1427 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
1428 u_int8_t addr = dev->address;
1429 ohci_soft_ed_t *sed;
1430 ohci_soft_td_t *std;
1431 usbd_status r;
1432 int s;
1433
1434 DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
1435 pipe, addr, ed->bEndpointAddress, sc->sc_addr));
1436 if (addr == sc->sc_addr) {
1437 switch (ed->bEndpointAddress) {
1438 case USB_CONTROL_ENDPOINT:
1439 pipe->methods = &ohci_root_ctrl_methods;
1440 break;
1441 case UE_DIR_IN | OHCI_INTR_ENDPT:
1442 pipe->methods = &ohci_root_intr_methods;
1443 break;
1444 default:
1445 return (USBD_INVAL);
1446 }
1447 } else {
1448 sed = ohci_alloc_sed(sc);
1449 if (sed == 0)
1450 goto bad0;
1451 std = ohci_alloc_std(sc);
1452 if (std == 0)
1453 goto bad1;
1454 opipe->sed = sed;
1455 opipe->tail = std;
1456 sed->ed.ed_flags = LE(
1457 OHCI_ED_SET_FA(addr) |
1458 OHCI_ED_SET_EN(ed->bEndpointAddress) |
1459 OHCI_ED_DIR_TD |
1460 (dev->lowspeed ? OHCI_ED_SPEED : 0) |
1461 ((ed->bmAttributes & UE_XFERTYPE) == UE_ISOCHRONOUS ?
1462 OHCI_ED_FORMAT_ISO : OHCI_ED_FORMAT_GEN) |
1463 OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize)));
1464 sed->ed.ed_headp = sed->ed.ed_tailp = LE(std->physaddr);
1465
1466 switch (ed->bmAttributes & UE_XFERTYPE) {
1467 case UE_CONTROL:
1468 pipe->methods = &ohci_device_ctrl_methods;
1469 r = usb_allocmem(&sc->sc_bus,
1470 sizeof(usb_device_request_t),
1471 0, &opipe->u.ctl.reqdma);
1472 if (r != USBD_NORMAL_COMPLETION)
1473 goto bad;
1474 s = splusb();
1475 ohci_add_ed(sed, sc->sc_ctrl_head);
1476 splx(s);
1477 break;
1478 case UE_INTERRUPT:
1479 pipe->methods = &ohci_device_intr_methods;
1480 return (ohci_device_setintr(sc, opipe, ed->bInterval));
1481 case UE_ISOCHRONOUS:
1482 printf("ohci_open: open iso unimplemented\n");
1483 return (USBD_INVAL);
1484 case UE_BULK:
1485 pipe->methods = &ohci_device_bulk_methods;
1486 s = splusb();
1487 ohci_add_ed(sed, sc->sc_bulk_head);
1488 splx(s);
1489 break;
1490 }
1491 }
1492 return (USBD_NORMAL_COMPLETION);
1493
1494 bad:
1495 ohci_free_std(sc, std);
1496 bad1:
1497 ohci_free_sed(sc, sed);
1498 bad0:
1499 return (USBD_NOMEM);
1500
1501 }
1502
1503 /*
1504 * Close a reqular pipe.
1505 * Assumes that there are no pending transactions.
1506 */
1507 void
1508 ohci_close_pipe(pipe, head)
1509 usbd_pipe_handle pipe;
1510 ohci_soft_ed_t *head;
1511 {
1512 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
1513 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
1514 ohci_soft_ed_t *sed = opipe->sed;
1515 int s;
1516
1517 s = splusb();
1518 #ifdef DIAGNOSTIC
1519 sed->ed.ed_flags |= LE(OHCI_ED_SKIP);
1520 if ((sed->ed.ed_tailp & LE(OHCI_TAILMASK)) !=
1521 (sed->ed.ed_headp & LE(OHCI_TAILMASK))) {
1522 ohci_physaddr_t td = sed->ed.ed_headp;
1523 ohci_soft_td_t *std;
1524 for (std = LIST_FIRST(&sc->sc_hash_tds[HASH(td)]);
1525 std != 0;
1526 std = LIST_NEXT(std, hnext))
1527 if (std->physaddr == td)
1528 break;
1529 printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x "
1530 "tl=0x%x pipe=%p, std=%p\n", sed,
1531 (int)LE(sed->ed.ed_headp), (int)LE(sed->ed.ed_tailp),
1532 pipe, std);
1533 usb_delay_ms(&sc->sc_bus, 2);
1534 if ((sed->ed.ed_tailp & LE(OHCI_TAILMASK)) !=
1535 (sed->ed.ed_headp & LE(OHCI_TAILMASK)))
1536 printf("ohci_close_pipe: pipe still not empty\n");
1537 }
1538 #endif
1539 ohci_rem_ed(sed, head);
1540 splx(s);
1541 ohci_free_std(sc, opipe->tail);
1542 ohci_free_sed(sc, opipe->sed);
1543 }
1544
1545 /*
1546 * Abort a device request.
1547 * If this routine is called at splusb() it guarantees that the request
1548 * will be removed from the hardware scheduling and that the callback
1549 * for it will be called with USBD_CANCELLED status.
1550 * It's impossible to guarantee that the requested transfer will not
1551 * have happened since the hardware runs concurrently.
1552 * If the transaction has already happened we rely on the ordinary
1553 * interrupt processing to process it.
1554 */
1555 void
1556 ohci_abort_req(reqh, status)
1557 usbd_request_handle reqh;
1558 usbd_status status;
1559 {
1560 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
1561 ohci_soft_ed_t *sed;
1562
1563 DPRINTF(("ohci_abort_req: reqh=%p pipe=%p\n", reqh, opipe));
1564
1565 reqh->status = status;
1566
1567 usb_untimeout(ohci_timeout, reqh, reqh->timo_handle);
1568
1569 sed = opipe->sed;
1570 DPRINTFN(1,("ohci_abort_req: stop ed=%p\n", sed));
1571 sed->ed.ed_flags |= LE(OHCI_ED_SKIP); /* force hardware skip */
1572
1573 if (reqh->device->bus->intr_context) {
1574 /* We have no process context, so we can't use tsleep(). */
1575 timeout(ohci_abort_req_end, reqh, hz / USB_FRAMES_PER_SECOND);
1576 } else {
1577 usb_delay_ms(opipe->pipe.device->bus, 1);
1578 ohci_abort_req_end(reqh);
1579 }
1580 }
1581
1582 void
1583 ohci_abort_req_end(v)
1584 void *v;
1585 {
1586 usbd_request_handle reqh = v;
1587 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
1588 ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
1589 ohci_soft_ed_t *sed;
1590 ohci_soft_td_t *p, *n;
1591 int s;
1592
1593 s = splusb();
1594
1595 p = reqh->hcpriv;
1596 #ifdef DIAGNOSTIC
1597 if (!p) {
1598 printf("ohci_abort_req: hcpriv==0\n");
1599 return;
1600 }
1601 #endif
1602 for (; p->reqh == reqh; p = n) {
1603 n = p->nexttd;
1604 ohci_hash_rem_td(sc, p);
1605 ohci_free_std(sc, p);
1606 }
1607
1608 sed = opipe->sed;
1609 DPRINTFN(2,("ohci_abort_req: set hd=%x, tl=%x\n",
1610 (int)LE(p->physaddr), (int)LE(sed->ed.ed_tailp)));
1611 sed->ed.ed_headp = p->physaddr; /* unlink TDs */
1612 sed->ed.ed_flags &= LE(~OHCI_ED_SKIP); /* remove hardware skip */
1613
1614 usb_transfer_complete(reqh);
1615
1616 splx(s);
1617 }
1618
1619 /*
1620 * Data structures and routines to emulate the root hub.
1621 */
1622 usb_device_descriptor_t ohci_devd = {
1623 USB_DEVICE_DESCRIPTOR_SIZE,
1624 UDESC_DEVICE, /* type */
1625 {0x00, 0x01}, /* USB version */
1626 UCLASS_HUB, /* class */
1627 USUBCLASS_HUB, /* subclass */
1628 0, /* protocol */
1629 64, /* max packet */
1630 {0},{0},{0x00,0x01}, /* device id */
1631 1,2,0, /* string indicies */
1632 1 /* # of configurations */
1633 };
1634
1635 usb_config_descriptor_t ohci_confd = {
1636 USB_CONFIG_DESCRIPTOR_SIZE,
1637 UDESC_CONFIG,
1638 {USB_CONFIG_DESCRIPTOR_SIZE +
1639 USB_INTERFACE_DESCRIPTOR_SIZE +
1640 USB_ENDPOINT_DESCRIPTOR_SIZE},
1641 1,
1642 1,
1643 0,
1644 UC_SELF_POWERED,
1645 0 /* max power */
1646 };
1647
1648 usb_interface_descriptor_t ohci_ifcd = {
1649 USB_INTERFACE_DESCRIPTOR_SIZE,
1650 UDESC_INTERFACE,
1651 0,
1652 0,
1653 1,
1654 UCLASS_HUB,
1655 USUBCLASS_HUB,
1656 0,
1657 0
1658 };
1659
1660 usb_endpoint_descriptor_t ohci_endpd = {
1661 USB_ENDPOINT_DESCRIPTOR_SIZE,
1662 UDESC_ENDPOINT,
1663 UE_DIR_IN | OHCI_INTR_ENDPT,
1664 UE_INTERRUPT,
1665 {8, 0}, /* max packet */
1666 255
1667 };
1668
1669 usb_hub_descriptor_t ohci_hubd = {
1670 USB_HUB_DESCRIPTOR_SIZE,
1671 UDESC_HUB,
1672 0,
1673 {0,0},
1674 0,
1675 0,
1676 {0},
1677 };
1678
1679 int
1680 ohci_str(p, l, s)
1681 usb_string_descriptor_t *p;
1682 int l;
1683 char *s;
1684 {
1685 int i;
1686
1687 if (l == 0)
1688 return (0);
1689 p->bLength = 2 * strlen(s) + 2;
1690 if (l == 1)
1691 return (1);
1692 p->bDescriptorType = UDESC_STRING;
1693 l -= 2;
1694 for (i = 0; s[i] && l > 1; i++, l -= 2)
1695 USETW2(p->bString[i], 0, s[i]);
1696 return (2*i+2);
1697 }
1698
1699 /*
1700 * Simulate a hardware hub by handling all the necessary requests.
1701 */
1702 usbd_status
1703 ohci_root_ctrl_transfer(reqh)
1704 usbd_request_handle reqh;
1705 {
1706 usbd_status r;
1707
1708 /* Insert last in queue. */
1709 r = usb_insert_transfer(reqh);
1710 if (r != USBD_NORMAL_COMPLETION)
1711 return (r);
1712
1713 /* Pipe isn't running, start first */
1714 return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
1715 }
1716
1717 usbd_status
1718 ohci_root_ctrl_start(reqh)
1719 usbd_request_handle reqh;
1720 {
1721 ohci_softc_t *sc = (ohci_softc_t *)reqh->pipe->device->bus;
1722 usb_device_request_t *req;
1723 void *buf = NULL;
1724 int port, i;
1725 int s, len, value, index, l, totlen = 0;
1726 usb_port_status_t ps;
1727 usb_hub_descriptor_t hubd;
1728 usbd_status r;
1729 u_int32_t v;
1730
1731 #ifdef DIAGNOSTIC
1732 if (!(reqh->rqflags & URQ_REQUEST))
1733 /* XXX panic */
1734 return (USBD_INVAL);
1735 #endif
1736 req = &reqh->request;
1737
1738 DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n",
1739 req->bmRequestType, req->bRequest));
1740
1741 len = UGETW(req->wLength);
1742 value = UGETW(req->wValue);
1743 index = UGETW(req->wIndex);
1744
1745 if (len != 0)
1746 buf = KERNADDR(&reqh->dmabuf);
1747
1748 #define C(x,y) ((x) | ((y) << 8))
1749 switch(C(req->bRequest, req->bmRequestType)) {
1750 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
1751 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
1752 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
1753 /*
1754 * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
1755 * for the integrated root hub.
1756 */
1757 break;
1758 case C(UR_GET_CONFIG, UT_READ_DEVICE):
1759 if (len > 0) {
1760 *(u_int8_t *)buf = sc->sc_conf;
1761 totlen = 1;
1762 }
1763 break;
1764 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
1765 DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value));
1766 switch(value >> 8) {
1767 case UDESC_DEVICE:
1768 if ((value & 0xff) != 0) {
1769 r = USBD_IOERROR;
1770 goto ret;
1771 }
1772 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
1773 USETW(ohci_devd.idVendor, sc->sc_id_vendor);
1774 memcpy(buf, &ohci_devd, l);
1775 break;
1776 case UDESC_CONFIG:
1777 if ((value & 0xff) != 0) {
1778 r = USBD_IOERROR;
1779 goto ret;
1780 }
1781 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
1782 memcpy(buf, &ohci_confd, l);
1783 buf = (char *)buf + l;
1784 len -= l;
1785 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
1786 totlen += l;
1787 memcpy(buf, &ohci_ifcd, l);
1788 buf = (char *)buf + l;
1789 len -= l;
1790 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
1791 totlen += l;
1792 memcpy(buf, &ohci_endpd, l);
1793 break;
1794 case UDESC_STRING:
1795 if (len == 0)
1796 break;
1797 *(u_int8_t *)buf = 0;
1798 totlen = 1;
1799 switch (value & 0xff) {
1800 case 1: /* Vendor */
1801 totlen = ohci_str(buf, len, sc->sc_vendor);
1802 break;
1803 case 2: /* Product */
1804 totlen = ohci_str(buf, len, "OHCI root hub");
1805 break;
1806 }
1807 break;
1808 default:
1809 r = USBD_IOERROR;
1810 goto ret;
1811 }
1812 break;
1813 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
1814 if (len > 0) {
1815 *(u_int8_t *)buf = 0;
1816 totlen = 1;
1817 }
1818 break;
1819 case C(UR_GET_STATUS, UT_READ_DEVICE):
1820 if (len > 1) {
1821 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
1822 totlen = 2;
1823 }
1824 break;
1825 case C(UR_GET_STATUS, UT_READ_INTERFACE):
1826 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
1827 if (len > 1) {
1828 USETW(((usb_status_t *)buf)->wStatus, 0);
1829 totlen = 2;
1830 }
1831 break;
1832 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
1833 if (value >= USB_MAX_DEVICES) {
1834 r = USBD_IOERROR;
1835 goto ret;
1836 }
1837 sc->sc_addr = value;
1838 break;
1839 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
1840 if (value != 0 && value != 1) {
1841 r = USBD_IOERROR;
1842 goto ret;
1843 }
1844 sc->sc_conf = value;
1845 break;
1846 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
1847 break;
1848 case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
1849 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
1850 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
1851 r = USBD_IOERROR;
1852 goto ret;
1853 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
1854 break;
1855 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
1856 break;
1857 /* Hub requests */
1858 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
1859 break;
1860 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
1861 DPRINTFN(8, ("ohci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
1862 "port=%d feature=%d\n",
1863 index, value));
1864 if (index < 1 || index > sc->sc_noport) {
1865 r = USBD_IOERROR;
1866 goto ret;
1867 }
1868 port = OHCI_RH_PORT_STATUS(index);
1869 switch(value) {
1870 case UHF_PORT_ENABLE:
1871 OWRITE4(sc, port, UPS_CURRENT_CONNECT_STATUS);
1872 break;
1873 case UHF_PORT_SUSPEND:
1874 OWRITE4(sc, port, UPS_OVERCURRENT_INDICATOR);
1875 break;
1876 case UHF_PORT_POWER:
1877 OWRITE4(sc, port, UPS_LOW_SPEED);
1878 break;
1879 case UHF_C_PORT_CONNECTION:
1880 OWRITE4(sc, port, UPS_C_CONNECT_STATUS << 16);
1881 break;
1882 case UHF_C_PORT_ENABLE:
1883 OWRITE4(sc, port, UPS_C_PORT_ENABLED << 16);
1884 break;
1885 case UHF_C_PORT_SUSPEND:
1886 OWRITE4(sc, port, UPS_C_SUSPEND << 16);
1887 break;
1888 case UHF_C_PORT_OVER_CURRENT:
1889 OWRITE4(sc, port, UPS_C_OVERCURRENT_INDICATOR << 16);
1890 break;
1891 case UHF_C_PORT_RESET:
1892 OWRITE4(sc, port, UPS_C_PORT_RESET << 16);
1893 break;
1894 default:
1895 r = USBD_IOERROR;
1896 goto ret;
1897 }
1898 switch(value) {
1899 case UHF_C_PORT_CONNECTION:
1900 case UHF_C_PORT_ENABLE:
1901 case UHF_C_PORT_SUSPEND:
1902 case UHF_C_PORT_OVER_CURRENT:
1903 case UHF_C_PORT_RESET:
1904 /* Enable RHSC interrupt if condition is cleared. */
1905 if ((OREAD4(sc, port) >> 16) == 0)
1906 ohci_rhsc_able(sc, 1);
1907 break;
1908 default:
1909 break;
1910 }
1911 break;
1912 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
1913 if (value != 0) {
1914 r = USBD_IOERROR;
1915 goto ret;
1916 }
1917 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
1918 hubd = ohci_hubd;
1919 hubd.bNbrPorts = sc->sc_noport;
1920 USETW(hubd.wHubCharacteristics,
1921 (v & OHCI_NPS ? UHD_PWR_NO_SWITCH :
1922 v & OHCI_PSM ? UHD_PWR_GANGED : UHD_PWR_INDIVIDUAL)
1923 /* XXX overcurrent */
1924 );
1925 hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v);
1926 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
1927 for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
1928 hubd.DeviceRemovable[i++] = (u_int8_t)v;
1929 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
1930 l = min(len, hubd.bDescLength);
1931 totlen = l;
1932 memcpy(buf, &hubd, l);
1933 break;
1934 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
1935 if (len != 4) {
1936 r = USBD_IOERROR;
1937 goto ret;
1938 }
1939 memset(buf, 0, len); /* ? XXX */
1940 totlen = len;
1941 break;
1942 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
1943 DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n",
1944 index));
1945 if (index < 1 || index > sc->sc_noport) {
1946 r = USBD_IOERROR;
1947 goto ret;
1948 }
1949 if (len != 4) {
1950 r = USBD_IOERROR;
1951 goto ret;
1952 }
1953 v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
1954 DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n",
1955 v));
1956 USETW(ps.wPortStatus, v);
1957 USETW(ps.wPortChange, v >> 16);
1958 l = min(len, sizeof ps);
1959 memcpy(buf, &ps, l);
1960 totlen = l;
1961 break;
1962 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
1963 r = USBD_IOERROR;
1964 goto ret;
1965 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
1966 break;
1967 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
1968 if (index < 1 || index > sc->sc_noport) {
1969 r = USBD_IOERROR;
1970 goto ret;
1971 }
1972 port = OHCI_RH_PORT_STATUS(index);
1973 switch(value) {
1974 case UHF_PORT_ENABLE:
1975 OWRITE4(sc, port, UPS_PORT_ENABLED);
1976 break;
1977 case UHF_PORT_SUSPEND:
1978 OWRITE4(sc, port, UPS_SUSPEND);
1979 break;
1980 case UHF_PORT_RESET:
1981 DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n",
1982 index));
1983 OWRITE4(sc, port, UPS_RESET);
1984 for (i = 0; i < 10; i++) {
1985 usb_delay_ms(&sc->sc_bus, 10);
1986 if ((OREAD4(sc, port) & UPS_RESET) == 0)
1987 break;
1988 }
1989 DPRINTFN(8,("ohci port %d reset, status = 0x%04x\n",
1990 index, OREAD4(sc, port)));
1991 break;
1992 case UHF_PORT_POWER:
1993 DPRINTFN(2,("ohci_root_ctrl_transfer: set port power "
1994 "%d\n", index));
1995 OWRITE4(sc, port, UPS_PORT_POWER);
1996 break;
1997 default:
1998 r = USBD_IOERROR;
1999 goto ret;
2000 }
2001 break;
2002 default:
2003 r = USBD_IOERROR;
2004 goto ret;
2005 }
2006 reqh->actlen = totlen;
2007 r = USBD_NORMAL_COMPLETION;
2008 ret:
2009 reqh->status = r;
2010 s = splusb();
2011 usb_transfer_complete(reqh);
2012 splx(s);
2013 return (USBD_IN_PROGRESS);
2014 }
2015
2016 /* Abort a root control request. */
2017 void
2018 ohci_root_ctrl_abort(reqh)
2019 usbd_request_handle reqh;
2020 {
2021 /* Nothing to do, all transfers are synchronous. */
2022 }
2023
2024 /* Close the root pipe. */
2025 void
2026 ohci_root_ctrl_close(pipe)
2027 usbd_pipe_handle pipe;
2028 {
2029 DPRINTF(("ohci_root_ctrl_close\n"));
2030 /* Nothing to do. */
2031 }
2032
2033 usbd_status
2034 ohci_root_intr_transfer(reqh)
2035 usbd_request_handle reqh;
2036 {
2037 usbd_status r;
2038
2039 /* Insert last in queue. */
2040 r = usb_insert_transfer(reqh);
2041 if (r != USBD_NORMAL_COMPLETION)
2042 return (r);
2043
2044 /* Pipe isn't running, start first */
2045 return (ohci_root_intr_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
2046 }
2047
2048 usbd_status
2049 ohci_root_intr_start(reqh)
2050 usbd_request_handle reqh;
2051 {
2052 usbd_pipe_handle pipe = reqh->pipe;
2053 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
2054
2055 sc->sc_intrreqh = reqh;
2056
2057 return (USBD_IN_PROGRESS);
2058 }
2059
2060 /* Abort a root interrupt request. */
2061 void
2062 ohci_root_intr_abort(reqh)
2063 usbd_request_handle reqh;
2064 {
2065 if (reqh->pipe->intrreqh == reqh) {
2066 DPRINTF(("ohci_root_intr_abort: remove\n"));
2067 reqh->pipe->intrreqh = 0;
2068 }
2069 reqh->status = USBD_CANCELLED;
2070 usb_transfer_complete(reqh);
2071 }
2072
2073 /* Close the root pipe. */
2074 void
2075 ohci_root_intr_close(pipe)
2076 usbd_pipe_handle pipe;
2077 {
2078 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
2079
2080 DPRINTF(("ohci_root_intr_close\n"));
2081
2082 sc->sc_intrreqh = 0;
2083 }
2084
2085 /************************/
2086
2087 usbd_status
2088 ohci_device_ctrl_transfer(reqh)
2089 usbd_request_handle reqh;
2090 {
2091 usbd_status r;
2092
2093 /* Insert last in queue. */
2094 r = usb_insert_transfer(reqh);
2095 if (r != USBD_NORMAL_COMPLETION)
2096 return (r);
2097
2098 /* Pipe isn't running, start first */
2099 return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
2100 }
2101
2102 usbd_status
2103 ohci_device_ctrl_start(reqh)
2104 usbd_request_handle reqh;
2105 {
2106 ohci_softc_t *sc = (ohci_softc_t *)reqh->pipe->device->bus;
2107 usbd_status r;
2108
2109 #ifdef DIAGNOSTIC
2110 if (!(reqh->rqflags & URQ_REQUEST)) {
2111 /* XXX panic */
2112 printf("ohci_device_ctrl_transfer: not a request\n");
2113 return (USBD_INVAL);
2114 }
2115 #endif
2116
2117 r = ohci_device_request(reqh);
2118 if (r != USBD_NORMAL_COMPLETION)
2119 return (r);
2120
2121 if (sc->sc_bus.use_polling)
2122 ohci_waitintr(sc, reqh);
2123 return (USBD_IN_PROGRESS);
2124 }
2125
2126 /* Abort a device control request. */
2127 void
2128 ohci_device_ctrl_abort(reqh)
2129 usbd_request_handle reqh;
2130 {
2131 DPRINTF(("ohci_device_ctrl_abort: reqh=%p\n", reqh));
2132 ohci_abort_req(reqh, USBD_CANCELLED);
2133 }
2134
2135 /* Close a device control pipe. */
2136 void
2137 ohci_device_ctrl_close(pipe)
2138 usbd_pipe_handle pipe;
2139 {
2140 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
2141
2142 DPRINTF(("ohci_device_ctrl_close: pipe=%p\n", pipe));
2143 ohci_close_pipe(pipe, sc->sc_ctrl_head);
2144 }
2145
2146 /************************/
2147
2148 void
2149 ohci_device_clear_toggle(pipe)
2150 usbd_pipe_handle pipe;
2151 {
2152 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2153
2154 opipe->sed->ed.ed_tailp &= LE(~OHCI_TOGGLECARRY);
2155 }
2156
2157 void
2158 ohci_noop(pipe)
2159 usbd_pipe_handle pipe;
2160 {
2161 }
2162
2163 usbd_status
2164 ohci_device_bulk_transfer(reqh)
2165 usbd_request_handle reqh;
2166 {
2167 usbd_status r;
2168
2169 /* Insert last in queue. */
2170 r = usb_insert_transfer(reqh);
2171 if (r != USBD_NORMAL_COMPLETION)
2172 return (r);
2173
2174 /* Pipe isn't running, start first */
2175 return (ohci_device_bulk_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
2176 }
2177
2178 usbd_status
2179 ohci_device_bulk_start(reqh)
2180 usbd_request_handle reqh;
2181 {
2182 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
2183 usbd_device_handle dev = opipe->pipe.device;
2184 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
2185 int addr = dev->address;
2186 ohci_soft_td_t *data, *tail, *tdp;
2187 ohci_soft_ed_t *sed;
2188 int s, len, isread, endpt;
2189 usbd_status r;
2190
2191 #ifdef DIAGNOSTIC
2192 if (reqh->rqflags & URQ_REQUEST) {
2193 /* XXX panic */
2194 printf("ohci_device_bulk_start: a request\n");
2195 return (USBD_INVAL);
2196 }
2197 #endif
2198
2199 len = reqh->length;
2200 endpt = reqh->pipe->endpoint->edesc->bEndpointAddress;
2201 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2202 sed = opipe->sed;
2203
2204 DPRINTFN(4,("ohci_device_bulk_start: reqh=%p len=%d isread=%d "
2205 "flags=%d endpt=%d\n", reqh, len, isread, reqh->flags,
2206 endpt));
2207
2208 opipe->u.bulk.isread = isread;
2209 opipe->u.bulk.length = len;
2210
2211 /* Update device address */
2212 sed->ed.ed_flags = LE(
2213 (LE(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) |
2214 OHCI_ED_SET_FA(addr));
2215
2216 /* Allocate a chain of new TDs (including a new tail). */
2217 data = opipe->tail;
2218 r = ohci_alloc_std_chain(opipe, sc, len, isread,
2219 reqh->flags & USBD_SHORT_XFER_OK,
2220 &reqh->dmabuf, data, &tail);
2221 if (r != USBD_NORMAL_COMPLETION)
2222 return (r);
2223
2224 tail->reqh = 0;
2225 reqh->hcpriv = data;
2226
2227 DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x "
2228 "td_cbp=0x%08x td_be=0x%08x\n",
2229 (int)LE(sed->ed.ed_flags), (int)LE(data->td.td_flags),
2230 (int)LE(data->td.td_cbp), (int)LE(data->td.td_be)));
2231
2232 #ifdef OHCI_DEBUG
2233 if (ohcidebug > 4) {
2234 ohci_dump_ed(sed);
2235 ohci_dump_tds(data);
2236 }
2237 #endif
2238
2239 /* Insert ED in schedule */
2240 s = splusb();
2241 for (tdp = data; tdp != tail; tdp = tdp->nexttd) {
2242 tdp->reqh = reqh;
2243 ohci_hash_add_td(sc, tdp);
2244 }
2245 sed->ed.ed_tailp = LE(tail->physaddr);
2246 opipe->tail = tail;
2247 sed->ed.ed_flags &= LE(~OHCI_ED_SKIP);
2248 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
2249 if (reqh->timeout && !sc->sc_bus.use_polling) {
2250 usb_timeout(ohci_timeout, reqh,
2251 MS_TO_TICKS(reqh->timeout), reqh->timo_handle);
2252 }
2253
2254 #if 0
2255 /* This goes wrong if we are too slow. */
2256 if (ohcidebug > 5) {
2257 delay(5000);
2258 DPRINTF(("ohci_device_intr_transfer: status=%x\n",
2259 OREAD4(sc, OHCI_COMMAND_STATUS)));
2260 ohci_dump_ed(sed);
2261 ohci_dump_tds(data);
2262 }
2263 #endif
2264
2265 splx(s);
2266
2267 return (USBD_IN_PROGRESS);
2268 }
2269
2270 void
2271 ohci_device_bulk_abort(reqh)
2272 usbd_request_handle reqh;
2273 {
2274 DPRINTF(("ohci_device_bulk_abort: reqh=%p\n", reqh));
2275 ohci_abort_req(reqh, USBD_CANCELLED);
2276 }
2277
2278 /*
2279 * Close a device bulk pipe.
2280 */
2281 void
2282 ohci_device_bulk_close(pipe)
2283 usbd_pipe_handle pipe;
2284 {
2285 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
2286
2287 DPRINTF(("ohci_device_bulk_close: pipe=%p\n", pipe));
2288 ohci_close_pipe(pipe, sc->sc_bulk_head);
2289 }
2290
2291 /************************/
2292
2293 usbd_status
2294 ohci_device_intr_transfer(reqh)
2295 usbd_request_handle reqh;
2296 {
2297 usbd_status r;
2298
2299 /* Insert last in queue. */
2300 r = usb_insert_transfer(reqh);
2301 if (r != USBD_NORMAL_COMPLETION)
2302 return (r);
2303
2304 /* Pipe isn't running, start first */
2305 return (ohci_device_intr_start(SIMPLEQ_FIRST(&reqh->pipe->queue)));
2306 }
2307
2308 usbd_status
2309 ohci_device_intr_start(reqh)
2310 usbd_request_handle reqh;
2311 {
2312 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
2313 usbd_device_handle dev = opipe->pipe.device;
2314 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
2315 ohci_soft_ed_t *sed = opipe->sed;
2316 ohci_soft_td_t *data, *tail;
2317 int len;
2318 int s;
2319
2320 DPRINTFN(3, ("ohci_device_intr_transfer: reqh=%p len=%d "
2321 "flags=%d priv=%p\n",
2322 reqh, reqh->length, reqh->flags, reqh->priv));
2323
2324 #ifdef DIAGNOSTIC
2325 if (reqh->rqflags & URQ_REQUEST)
2326 panic("ohci_device_intr_transfer: a request\n");
2327 #endif
2328
2329 len = reqh->length;
2330
2331 data = opipe->tail;
2332 tail = ohci_alloc_std(sc);
2333 if (!tail)
2334 return (USBD_NOMEM);
2335 tail->reqh = 0;
2336
2337 data->td.td_flags = LE(
2338 OHCI_TD_IN | OHCI_TD_NOCC |
2339 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
2340 if (reqh->flags & USBD_SHORT_XFER_OK)
2341 data->td.td_flags |= LE(OHCI_TD_R);
2342 data->td.td_cbp = LE(DMAADDR(&reqh->dmabuf));
2343 data->nexttd = tail;
2344 data->td.td_nexttd = LE(tail->physaddr);
2345 data->td.td_be = LE(LE(data->td.td_cbp) + len - 1);
2346 data->len = len;
2347 data->reqh = reqh;
2348 data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
2349 reqh->hcpriv = data;
2350
2351 #ifdef OHCI_DEBUG
2352 if (ohcidebug > 5) {
2353 DPRINTF(("ohci_device_intr_transfer:\n"));
2354 ohci_dump_ed(sed);
2355 ohci_dump_tds(data);
2356 }
2357 #endif
2358
2359 /* Insert ED in schedule */
2360 s = splusb();
2361 ohci_hash_add_td(sc, data);
2362 sed->ed.ed_tailp = LE(tail->physaddr);
2363 opipe->tail = tail;
2364 sed->ed.ed_flags &= LE(~OHCI_ED_SKIP);
2365
2366 #if 0
2367 /*
2368 * This goes horribly wrong, printing thousands of descriptors,
2369 * because false references are followed due to the fact that the
2370 * TD is gone.
2371 */
2372 if (ohcidebug > 5) {
2373 delay(5000);
2374 DPRINTF(("ohci_device_intr_transfer: status=%x\n",
2375 OREAD4(sc, OHCI_COMMAND_STATUS)));
2376 ohci_dump_ed(sed);
2377 ohci_dump_tds(data);
2378 }
2379 #endif
2380 splx(s);
2381
2382 return (USBD_IN_PROGRESS);
2383 }
2384
2385 /* Abort a device control request. */
2386 void
2387 ohci_device_intr_abort(reqh)
2388 usbd_request_handle reqh;
2389 {
2390 if (reqh->pipe->intrreqh == reqh) {
2391 DPRINTF(("ohci_device_intr_abort: remove\n"));
2392 reqh->pipe->intrreqh = 0;
2393 }
2394 ohci_abort_req(reqh, USBD_CANCELLED);
2395 }
2396
2397 /* Close a device interrupt pipe. */
2398 void
2399 ohci_device_intr_close(pipe)
2400 usbd_pipe_handle pipe;
2401 {
2402 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2403 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
2404 int nslots = opipe->u.intr.nslots;
2405 int pos = opipe->u.intr.pos;
2406 int j;
2407 ohci_soft_ed_t *p, *sed = opipe->sed;
2408 int s;
2409
2410 DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n",
2411 pipe, nslots, pos));
2412 s = splusb();
2413 sed->ed.ed_flags |= LE(OHCI_ED_SKIP);
2414 if ((sed->ed.ed_tailp & LE(OHCI_TAILMASK)) !=
2415 (sed->ed.ed_headp & LE(OHCI_TAILMASK)))
2416 usb_delay_ms(&sc->sc_bus, 2);
2417
2418 for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
2419 ;
2420 if (!p)
2421 panic("ohci_device_intr_close: ED not found\n");
2422 p->next = sed->next;
2423 p->ed.ed_nexted = sed->ed.ed_nexted;
2424 splx(s);
2425
2426 for (j = 0; j < nslots; j++)
2427 --sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS];
2428
2429 ohci_free_std(sc, opipe->tail);
2430 ohci_free_sed(sc, opipe->sed);
2431 }
2432
2433 usbd_status
2434 ohci_device_setintr(sc, opipe, ival)
2435 ohci_softc_t *sc;
2436 struct ohci_pipe *opipe;
2437 int ival;
2438 {
2439 int i, j, s, best;
2440 u_int npoll, slow, shigh, nslots;
2441 u_int bestbw, bw;
2442 ohci_soft_ed_t *hsed, *sed = opipe->sed;
2443
2444 DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe));
2445 if (ival == 0) {
2446 printf("ohci_setintr: 0 interval\n");
2447 return (USBD_INVAL);
2448 }
2449
2450 npoll = OHCI_NO_INTRS;
2451 while (npoll > ival)
2452 npoll /= 2;
2453 DPRINTFN(2, ("ohci_setintr: ival=%d npoll=%d\n", ival, npoll));
2454
2455 /*
2456 * We now know which level in the tree the ED must go into.
2457 * Figure out which slot has most bandwidth left over.
2458 * Slots to examine:
2459 * npoll
2460 * 1 0
2461 * 2 1 2
2462 * 4 3 4 5 6
2463 * 8 7 8 9 10 11 12 13 14
2464 * N (N-1) .. (N-1+N-1)
2465 */
2466 slow = npoll-1;
2467 shigh = slow + npoll;
2468 nslots = OHCI_NO_INTRS / npoll;
2469 for (best = i = slow, bestbw = ~0; i < shigh; i++) {
2470 bw = 0;
2471 for (j = 0; j < nslots; j++)
2472 bw += sc->sc_bws[(i * nslots + j) % OHCI_NO_INTRS];
2473 if (bw < bestbw) {
2474 best = i;
2475 bestbw = bw;
2476 }
2477 }
2478 DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n",
2479 best, slow, shigh, bestbw));
2480
2481 s = splusb();
2482 hsed = sc->sc_eds[best];
2483 sed->next = hsed->next;
2484 sed->ed.ed_nexted = hsed->ed.ed_nexted;
2485 hsed->next = sed;
2486 hsed->ed.ed_nexted = LE(sed->physaddr);
2487 splx(s);
2488
2489 for (j = 0; j < nslots; j++)
2490 ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS];
2491 opipe->u.intr.nslots = nslots;
2492 opipe->u.intr.pos = best;
2493
2494 DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe));
2495 return (USBD_NORMAL_COMPLETION);
2496 }
2497
2498