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