ohci.c revision 1.13 1 /* $NetBSD: ohci.c,v 1.13 1998/12/08 14:34:08 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: http://www.intel.com/design/usb/ohci11d.pdf
44 * USB spec: http://www.teleport.com/cgi-bin/mailmerge.cgi/~usb/cgiform.tpl
45 */
46
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/kernel.h>
50 #include <sys/malloc.h>
51 #include <sys/device.h>
52 #include <sys/proc.h>
53 #include <sys/queue.h>
54 #include <sys/select.h>
55
56 #include <machine/bus.h>
57
58 #include <dev/usb/usb.h>
59 #include <dev/usb/usbdi.h>
60 #include <dev/usb/usbdivar.h>
61 #include <dev/usb/usb_quirks.h>
62 #include <dev/usb/usb_mem.h>
63
64 #include <dev/usb/ohcireg.h>
65 #include <dev/usb/ohcivar.h>
66
67 int ohcidebug = 0;
68
69 struct ohci_pipe;
70
71 ohci_soft_ed_t *ohci_alloc_sed __P((ohci_softc_t *));
72 void ohci_free_sed __P((ohci_softc_t *, ohci_soft_ed_t *));
73
74 ohci_soft_td_t *ohci_alloc_std __P((ohci_softc_t *));
75 void ohci_free_std __P((ohci_softc_t *, ohci_soft_td_t *));
76
77 usbd_status ohci_open __P((usbd_pipe_handle));
78 void ohci_poll __P((struct usbd_bus *));
79 void ohci_waitintr __P((ohci_softc_t *, usbd_request_handle));
80 void ohci_rhsc __P((ohci_softc_t *, usbd_request_handle));
81 void ohci_process_done __P((ohci_softc_t *, ohci_physaddr_t));
82 void ohci_ctrl_done __P((ohci_softc_t *, usbd_request_handle));
83 void ohci_intr_done __P((ohci_softc_t *, usbd_request_handle));
84 void ohci_bulk_done __P((ohci_softc_t *, usbd_request_handle));
85
86 usbd_status ohci_device_request __P((usbd_request_handle reqh));
87 void ohci_add_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *));
88 void ohci_rem_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *));
89 void ohci_hash_add_td __P((ohci_softc_t *, ohci_soft_td_t *));
90 void ohci_hash_rem_td __P((ohci_softc_t *, ohci_soft_td_t *));
91 ohci_soft_td_t *ohci_hash_find_td __P((ohci_softc_t *, ohci_physaddr_t));
92
93 usbd_status ohci_root_ctrl_transfer __P((usbd_request_handle));
94 void ohci_root_ctrl_abort __P((usbd_request_handle));
95 void ohci_root_ctrl_close __P((usbd_pipe_handle));
96
97 usbd_status ohci_root_intr_transfer __P((usbd_request_handle));
98 void ohci_root_intr_abort __P((usbd_request_handle));
99 void ohci_root_intr_close __P((usbd_pipe_handle));
100
101 usbd_status ohci_device_ctrl_transfer __P((usbd_request_handle));
102 void ohci_device_ctrl_abort __P((usbd_request_handle));
103 void ohci_device_ctrl_close __P((usbd_pipe_handle));
104
105 usbd_status ohci_device_bulk_transfer __P((usbd_request_handle));
106 void ohci_device_bulk_abort __P((usbd_request_handle));
107 void ohci_device_bulk_close __P((usbd_pipe_handle));
108
109 usbd_status ohci_device_intr_transfer __P((usbd_request_handle));
110 void ohci_device_intr_abort __P((usbd_request_handle));
111 void ohci_device_intr_close __P((usbd_pipe_handle));
112 usbd_status ohci_device_setintr __P((ohci_softc_t *sc,
113 struct ohci_pipe *pipe, int ival));
114
115 int ohci_str __P((usb_string_descriptor_t *, int, char *));
116
117 void ohci_timeout __P((void *));
118 void ohci_rhsc_able __P((ohci_softc_t *, int));
119
120 #ifdef USB_DEBUG
121 ohci_softc_t *thesc;
122 void ohci_dumpregs __P((ohci_softc_t *));
123 void ohci_dump_tds __P((ohci_soft_td_t *));
124 void ohci_dump_td __P((ohci_soft_td_t *));
125 void ohci_dump_ed __P((ohci_soft_ed_t *));
126 #endif
127
128 #define OWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
129 #define OREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r))
130 #define OREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r))
131
132 /* Reverse the bits in a value 0 .. 31 */
133 static u_int8_t revbits[OHCI_NO_INTRS] =
134 { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c,
135 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e,
136 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d,
137 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f };
138
139 struct ohci_pipe {
140 struct usbd_pipe pipe;
141 ohci_soft_ed_t *sed;
142 ohci_soft_td_t *tail;
143 /* Info needed for different pipe kinds. */
144 union {
145 /* Control pipe */
146 struct {
147 usb_dma_t datadma;
148 usb_dma_t reqdma;
149 u_int length;
150 ohci_soft_td_t *setup, *xfer, *stat;
151 } ctl;
152 /* Interrupt pipe */
153 struct {
154 usb_dma_t datadma;
155 int nslots;
156 int pos;
157 } intr;
158 /* Bulk pipe */
159 struct {
160 usb_dma_t datadma;
161 u_int length;
162 } bulk;
163 } u;
164 };
165
166 #define OHCI_INTR_ENDPT 1
167
168 struct usbd_methods ohci_root_ctrl_methods = {
169 ohci_root_ctrl_transfer,
170 ohci_root_ctrl_abort,
171 ohci_root_ctrl_close,
172 0,
173 };
174
175 struct usbd_methods ohci_root_intr_methods = {
176 ohci_root_intr_transfer,
177 ohci_root_intr_abort,
178 ohci_root_intr_close,
179 0,
180 };
181
182 struct usbd_methods ohci_device_ctrl_methods = {
183 ohci_device_ctrl_transfer,
184 ohci_device_ctrl_abort,
185 ohci_device_ctrl_close,
186 0,
187 };
188
189 struct usbd_methods ohci_device_intr_methods = {
190 ohci_device_intr_transfer,
191 ohci_device_intr_abort,
192 ohci_device_intr_close,
193 };
194
195 struct usbd_methods ohci_device_bulk_methods = {
196 ohci_device_bulk_transfer,
197 ohci_device_bulk_abort,
198 ohci_device_bulk_close,
199 0,
200 };
201
202 ohci_soft_ed_t *
203 ohci_alloc_sed(sc)
204 ohci_softc_t *sc;
205 {
206 ohci_soft_ed_t *sed;
207 usbd_status r;
208 int i, offs;
209 usb_dma_t dma;
210
211 if (!sc->sc_freeeds) {
212 DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n"));
213 sed = malloc(sizeof(ohci_soft_ed_t) * OHCI_ED_CHUNK,
214 M_USBDEV, M_NOWAIT);
215 if (!sed)
216 return 0;
217 r = usb_allocmem(sc->sc_dmatag, OHCI_ED_SIZE * OHCI_ED_CHUNK,
218 OHCI_ED_ALIGN, &dma);
219 if (r != USBD_NORMAL_COMPLETION) {
220 free(sed, M_USBDEV);
221 return 0;
222 }
223 for(i = 0; i < OHCI_ED_CHUNK; i++, sed++) {
224 offs = i * OHCI_ED_SIZE;
225 sed->physaddr = DMAADDR(&dma) + offs;
226 sed->ed = (ohci_ed_t *)
227 ((char *)KERNADDR(&dma) + offs);
228 sed->next = sc->sc_freeeds;
229 sc->sc_freeeds = sed;
230 }
231 }
232 sed = sc->sc_freeeds;
233 sc->sc_freeeds = sed->next;
234 memset(sed->ed, 0, OHCI_ED_SIZE);
235 sed->next = 0;
236 return sed;
237 }
238
239 void
240 ohci_free_sed(sc, sed)
241 ohci_softc_t *sc;
242 ohci_soft_ed_t *sed;
243 {
244 sed->next = sc->sc_freeeds;
245 sc->sc_freeeds = sed;
246 }
247
248 ohci_soft_td_t *
249 ohci_alloc_std(sc)
250 ohci_softc_t *sc;
251 {
252 ohci_soft_td_t *std;
253 usbd_status r;
254 int i, offs;
255 usb_dma_t dma;
256
257 if (!sc->sc_freetds) {
258 DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n"));
259 std = malloc(sizeof(ohci_soft_td_t) * OHCI_TD_CHUNK,
260 M_USBDEV, M_NOWAIT);
261 if (!std)
262 return 0;
263 r = usb_allocmem(sc->sc_dmatag, OHCI_TD_SIZE * OHCI_TD_CHUNK,
264 OHCI_TD_ALIGN, &dma);
265 if (r != USBD_NORMAL_COMPLETION) {
266 free(std, M_USBDEV);
267 return 0;
268 }
269 for(i = 0; i < OHCI_TD_CHUNK; i++, std++) {
270 offs = i * OHCI_TD_SIZE;
271 std->physaddr = DMAADDR(&dma) + offs;
272 std->td = (ohci_td_t *)
273 ((char *)KERNADDR(&dma) + offs);
274 std->nexttd = sc->sc_freetds;
275 sc->sc_freetds = std;
276 }
277 }
278 std = sc->sc_freetds;
279 sc->sc_freetds = std->nexttd;
280 memset(std->td, 0, OHCI_TD_SIZE);
281 std->nexttd = 0;
282 return (std);
283 }
284
285 void
286 ohci_free_std(sc, std)
287 ohci_softc_t *sc;
288 ohci_soft_td_t *std;
289 {
290 std->nexttd = sc->sc_freetds;
291 sc->sc_freetds = std;
292 }
293
294 usbd_status
295 ohci_init(sc)
296 ohci_softc_t *sc;
297 {
298 ohci_soft_ed_t *sed, *psed;
299 usbd_status r;
300 int rev;
301 int i;
302 u_int32_t s, ctl, ival, hcr, fm, per;
303
304 DPRINTF(("ohci_init: start\n"));
305 rev = OREAD4(sc, OHCI_REVISION);
306 printf("%s: OHCI version %d.%d%s\n", sc->sc_bus.bdev.dv_xname,
307 OHCI_REV_HI(rev), OHCI_REV_LO(rev),
308 OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
309 if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) {
310 printf("%s: unsupported OHCI revision\n",
311 sc->sc_bus.bdev.dv_xname);
312 return (USBD_INVAL);
313 }
314
315 for (i = 0; i < OHCI_HASH_SIZE; i++)
316 LIST_INIT(&sc->sc_hash_tds[i]);
317
318 /* Allocate the HCCA area. */
319 r = usb_allocmem(sc->sc_dmatag, OHCI_HCCA_SIZE,
320 OHCI_HCCA_ALIGN, &sc->sc_hccadma);
321 if (r != USBD_NORMAL_COMPLETION)
322 return (r);
323 sc->sc_hcca = (struct ohci_hcca *)KERNADDR(&sc->sc_hccadma);
324 memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE);
325
326 sc->sc_eintrs = OHCI_NORMAL_INTRS;
327
328 sc->sc_ctrl_head = ohci_alloc_sed(sc);
329 if (!sc->sc_ctrl_head) {
330 r = USBD_NOMEM;
331 goto bad1;
332 }
333 sc->sc_ctrl_head->ed->ed_flags |= OHCI_ED_SKIP;
334 sc->sc_bulk_head = ohci_alloc_sed(sc);
335 if (!sc->sc_bulk_head) {
336 r = USBD_NOMEM;
337 goto bad2;
338 }
339 sc->sc_bulk_head->ed->ed_flags |= OHCI_ED_SKIP;
340
341 /* Allocate all the dummy EDs that make up the interrupt tree. */
342 for (i = 0; i < OHCI_NO_EDS; i++) {
343 sed = ohci_alloc_sed(sc);
344 if (!sed) {
345 while (--i >= 0)
346 ohci_free_sed(sc, sc->sc_eds[i]);
347 r = USBD_NOMEM;
348 goto bad3;
349 }
350 /* All ED fields are set to 0. */
351 sc->sc_eds[i] = sed;
352 sed->ed->ed_flags |= OHCI_ED_SKIP;
353 if (i != 0) {
354 psed = sc->sc_eds[(i-1) / 2];
355 sed->next = psed;
356 sed->ed->ed_nexted = psed->physaddr;
357 }
358 }
359 /*
360 * Fill HCCA interrupt table. The bit reversal is to get
361 * the tree set up properly to spread the interrupts.
362 */
363 for (i = 0; i < OHCI_NO_INTRS; i++)
364 sc->sc_hcca->hcca_interrupt_table[revbits[i]] =
365 sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr;
366
367 /* Determine in what context we are running. */
368 ctl = OREAD4(sc, OHCI_CONTROL);
369 if (ctl & OHCI_IR) {
370 /* SMM active, request change */
371 DPRINTF(("ohci_init: SMM active, request owner change\n"));
372 s = OREAD4(sc, OHCI_COMMAND_STATUS);
373 OWRITE4(sc, OHCI_COMMAND_STATUS, s | OHCI_OCR);
374 for (i = 0; i < 100 && (ctl & OHCI_IR); i++) {
375 delay(1000);
376 ctl = OREAD4(sc, OHCI_CONTROL);
377 }
378 if ((ctl & OHCI_IR) == 0) {
379 printf("%s: SMM does not respond, resetting\n",
380 sc->sc_bus.bdev.dv_xname);
381 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
382 goto reset;
383 }
384 } else if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_RESET) {
385 /* BIOS started controller. */
386 DPRINTF(("ohci_init: BIOS active\n"));
387 if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_OPERATIONAL) {
388 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_OPERATIONAL);
389 delay(USB_RESUME_DELAY * 1000);
390 }
391 } else {
392 DPRINTF(("ohci_init: cold started\n"));
393 reset:
394 /* Controller was cold started. */
395 delay(USB_RESET_DELAY * 1000);
396 }
397
398 /* We now own the host controller and the bus has been reset. */
399 ival = OHCI_GET_IVAL(OREAD4(sc, OHCI_FM_INTERVAL));
400
401 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_HCR); /* Reset HC */
402 /* Nominal time for a reset is 10 us. */
403 for (i = 0; i < 10; i++) {
404 delay(10);
405 hcr = OREAD4(sc, OHCI_COMMAND_STATUS) & OHCI_HCR;
406 if (!hcr)
407 break;
408 }
409 if (hcr) {
410 printf("%s: reset timeout\n", sc->sc_bus.bdev.dv_xname);
411 r = USBD_IOERROR;
412 goto bad3;
413 }
414 #ifdef USB_DEBUG
415 thesc = sc;
416 if (ohcidebug > 15)
417 ohci_dumpregs(sc);
418 #endif
419
420 /* The controller is now in suspend state, we have 2ms to finish. */
421
422 /* Set up HC registers. */
423 OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma));
424 OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
425 OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
426 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
427 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
428 ctl = OREAD4(sc, OHCI_CONTROL);
429 ctl &= ~(OHCI_CBSR_MASK | OHCI_LES | OHCI_HCFS_MASK | OHCI_IR);
430 ctl |= OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE |
431 OHCI_RATIO_1_4 | OHCI_HCFS_OPERATIONAL;
432 /* And finally start it! */
433 OWRITE4(sc, OHCI_CONTROL, ctl);
434
435 /*
436 * The controller is now OPERATIONAL. Set a some final
437 * registers that should be set earlier, but that the
438 * controller ignores when in the SUSPEND state.
439 */
440 fm = (OREAD4(sc, OHCI_FM_INTERVAL) & OHCI_FIT) ^ OHCI_FIT;
441 fm |= OHCI_FSMPS(ival) | ival;
442 OWRITE4(sc, OHCI_FM_INTERVAL, fm);
443 per = OHCI_PERIODIC(ival); /* 90% periodic */
444 OWRITE4(sc, OHCI_PERIODIC_START, per);
445
446 OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */
447
448 sc->sc_noport = OHCI_GET_NDP(OREAD4(sc, OHCI_RH_DESCRIPTOR_A));
449 printf("%s: %d downstream port%s\n",
450 sc->sc_bus.bdev.dv_xname, sc->sc_noport,
451 sc->sc_noport != 1 ? "s" : "");
452
453 #ifdef USB_DEBUG
454 if (ohcidebug > 5)
455 ohci_dumpregs(sc);
456 #endif
457
458 /* Set up the bus struct. */
459 sc->sc_bus.open_pipe = ohci_open;
460 sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
461 sc->sc_bus.do_poll = ohci_poll;
462
463 return (USBD_NORMAL_COMPLETION);
464
465 bad3:
466 ohci_free_sed(sc, sc->sc_ctrl_head);
467 bad2:
468 ohci_free_sed(sc, sc->sc_bulk_head);
469 bad1:
470 usb_freemem(sc->sc_dmatag, &sc->sc_hccadma);
471 return (r);
472 }
473
474 #ifdef USB_DEBUG
475 void ohcidump(void);
476 void ohcidump(void) { ohci_dumpregs(thesc); }
477
478 void
479 ohci_dumpregs(sc)
480 ohci_softc_t *sc;
481 {
482 printf("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n",
483 OREAD4(sc, OHCI_REVISION),
484 OREAD4(sc, OHCI_CONTROL),
485 OREAD4(sc, OHCI_COMMAND_STATUS));
486 printf(" intrstat=0x%08x intre=0x%08x intrd=0x%08x\n",
487 OREAD4(sc, OHCI_INTERRUPT_STATUS),
488 OREAD4(sc, OHCI_INTERRUPT_ENABLE),
489 OREAD4(sc, OHCI_INTERRUPT_DISABLE));
490 printf(" hcca=0x%08x percur=0x%08x ctrlhd=0x%08x\n",
491 OREAD4(sc, OHCI_HCCA),
492 OREAD4(sc, OHCI_PERIOD_CURRENT_ED),
493 OREAD4(sc, OHCI_CONTROL_HEAD_ED));
494 printf(" ctrlcur=0x%08x bulkhd=0x%08x bulkcur=0x%08x\n",
495 OREAD4(sc, OHCI_CONTROL_CURRENT_ED),
496 OREAD4(sc, OHCI_BULK_HEAD_ED),
497 OREAD4(sc, OHCI_BULK_CURRENT_ED));
498 printf(" done=0x%08x fmival=0x%08x fmrem=0x%08x\n",
499 OREAD4(sc, OHCI_DONE_HEAD),
500 OREAD4(sc, OHCI_FM_INTERVAL),
501 OREAD4(sc, OHCI_FM_REMAINING));
502 printf(" fmnum=0x%08x perst=0x%08x lsthrs=0x%08x\n",
503 OREAD4(sc, OHCI_FM_NUMBER),
504 OREAD4(sc, OHCI_PERIODIC_START),
505 OREAD4(sc, OHCI_LS_THRESHOLD));
506 printf(" desca=0x%08x descb=0x%08x stat=0x%08x\n",
507 OREAD4(sc, OHCI_RH_DESCRIPTOR_A),
508 OREAD4(sc, OHCI_RH_DESCRIPTOR_B),
509 OREAD4(sc, OHCI_RH_STATUS));
510 printf(" port1=0x%08x port2=0x%08x\n",
511 OREAD4(sc, OHCI_RH_PORT_STATUS(1)),
512 OREAD4(sc, OHCI_RH_PORT_STATUS(2)));
513 printf(" HCCA: frame_number=0x%04x done_head=0x%08x\n",
514 sc->sc_hcca->hcca_frame_number,
515 sc->sc_hcca->hcca_done_head);
516 }
517 #endif
518
519 int
520 ohci_intr(p)
521 void *p;
522 {
523 ohci_softc_t *sc = p;
524 u_int32_t intrs, eintrs;
525 ohci_physaddr_t done;
526
527 done = sc->sc_hcca->hcca_done_head;
528 if (done != 0) {
529 intrs = OHCI_WDH;
530 if (done & OHCI_DONE_INTRS)
531 intrs |= OREAD4(sc, OHCI_INTERRUPT_STATUS);
532 } else
533 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS);
534 if (!intrs)
535 return (0);
536 intrs &= ~OHCI_MIE;
537 OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs); /* Acknowledge */
538 eintrs = intrs & sc->sc_eintrs;
539 if (!eintrs)
540 return (0);
541
542 sc->sc_intrs++;
543 DPRINTFN(7, ("ohci_intr: sc=%p intrs=%x(%x) eintr=%x\n",
544 sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS),
545 (u_int)eintrs));
546
547 if (eintrs & OHCI_SO) {
548 printf("%s: scheduling overrun\n", sc->sc_bus.bdev.dv_xname);
549 /* XXX do what */
550 intrs &= ~OHCI_SO;
551 }
552 if (eintrs & OHCI_WDH) {
553 ohci_process_done(sc, done &~ OHCI_DONE_INTRS);
554 sc->sc_hcca->hcca_done_head = 0;
555 intrs &= ~OHCI_WDH;
556 }
557 if (eintrs & OHCI_RD) {
558 /* XXX process resume detect */
559 }
560 if (eintrs & OHCI_UE) {
561 printf("%s: unrecoverable error, controller halted\n",
562 sc->sc_bus.bdev.dv_xname);
563 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
564 /* XXX what else */
565 }
566 if (eintrs & OHCI_RHSC) {
567 ohci_rhsc(sc, sc->sc_intrreqh);
568 intrs &= ~OHCI_RHSC;
569
570 /*
571 * Disable RHSC interrupt for now, because it will be
572 * on until the port has been reset.
573 */
574 ohci_rhsc_able(sc, 0);
575 }
576
577 /* Block unprocessed interrupts. XXX */
578 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, intrs);
579 sc->sc_eintrs &= ~intrs;
580
581 return (1);
582 }
583
584 void
585 ohci_rhsc_able(sc, on)
586 ohci_softc_t *sc;
587 int on;
588 {
589 DPRINTFN(4, ("ohci_rhsc_able: on=%d\n", on));
590 if (on) {
591 sc->sc_eintrs |= OHCI_RHSC;
592 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC);
593 } else {
594 sc->sc_eintrs &= ~OHCI_RHSC;
595 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_RHSC);
596 }
597 }
598
599 #ifdef USB_DEBUG
600 char *ohci_cc_strs[] = {
601 "NO_ERROR",
602 "CRC",
603 "BIT_STUFFING",
604 "DATA_TOGGLE_MISMATCH",
605 "STALL",
606 "DEVICE_NOT_RESPONDING",
607 "PID_CHECK_FAILURE",
608 "UNEXPECTED_PID",
609 "DATA_OVERRUN",
610 "DATA_UNDERRUN",
611 "BUFFER_OVERRUN",
612 "BUFFER_UNDERRUN",
613 "NOT_ACCESSED",
614 };
615 #endif
616
617 void
618 ohci_process_done(sc, done)
619 ohci_softc_t *sc;
620 ohci_physaddr_t done;
621 {
622 ohci_soft_td_t *std, *sdone;
623 usbd_request_handle reqh;
624 int len, cc;
625
626 DPRINTFN(10,("ohci_process_done: done=0x%08lx\n", (u_long)done));
627
628 /* Reverse the done list. */
629 for (sdone = 0; done; done = std->td->td_nexttd) {
630 std = ohci_hash_find_td(sc, done);
631 std->dnext = sdone;
632 sdone = std;
633 }
634
635 #ifdef USB_DEBUG
636 if (ohcidebug > 10) {
637 printf("ohci_process_done: TD done:\n");
638 ohci_dump_tds(sdone);
639 }
640 #endif
641
642 for (std = sdone; std; std = std->dnext) {
643 reqh = std->reqh;
644 DPRINTFN(10, ("ohci_process_done: std=%p reqh=%p\n",std,reqh));
645 cc = OHCI_TD_GET_CC(std->td->td_flags);
646 if (cc == OHCI_CC_NO_ERROR) {
647 if (std->td->td_cbp == 0)
648 len = std->len;
649 else
650 len = std->td->td_be - std->td->td_cbp + 1;
651 reqh->actlen += len;
652 if (reqh->hcpriv == std) {
653 switch (reqh->pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
654 case UE_CONTROL:
655 ohci_ctrl_done(sc, reqh);
656 break;
657 case UE_INTERRUPT:
658 ohci_intr_done(sc, reqh);
659 break;
660 case UE_BULK:
661 ohci_bulk_done(sc, reqh);
662 break;
663 case UE_ISOCHRONOUS:
664 printf("ohci_process_done: ISO done?\n");
665 break;
666 }
667 /* And finally execute callback. */
668 reqh->status = USBD_NORMAL_COMPLETION;
669 reqh->xfercb(reqh);
670 }
671 } else {
672 ohci_soft_td_t *p, *n;
673 struct ohci_pipe *opipe =
674 (struct ohci_pipe *)reqh->pipe;
675 DPRINTFN(-1,("ohci_process_done: error cc=%d (%s)\n",
676 OHCI_TD_GET_CC(std->td->td_flags),
677 ohci_cc_strs[OHCI_TD_GET_CC(std->td->td_flags)]));
678 /*
679 * Endpoint is halted. First unlink all the TDs
680 * belonging to the failed transfer, and then restart
681 * the endpoint.
682 */
683 for (p = std->nexttd; p->reqh == reqh; p = n) {
684 n = p->nexttd;
685 ohci_hash_rem_td(sc, p);
686 ohci_free_std(sc, p);
687 }
688 opipe->sed->ed->ed_headp = p->physaddr;/* clear halt */
689 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
690
691 if (cc == OHCI_CC_STALL)
692 reqh->status = USBD_STALLED;
693 else
694 reqh->status = USBD_IOERROR;
695 reqh->xfercb(reqh);
696 }
697 ohci_hash_rem_td(sc, std);
698 ohci_free_std(sc, std);
699 }
700 }
701
702 void
703 ohci_ctrl_done(sc, reqh)
704 ohci_softc_t *sc;
705 usbd_request_handle reqh;
706 {
707 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
708 u_int len = opipe->u.ctl.length;
709 usb_dma_t *dma;
710
711 DPRINTFN(10,("ohci_ctrl_done: reqh=%p\n", reqh));
712
713 if (!reqh->isreq) {
714 panic("ohci_ctrl_done: not a request\n");
715 return;
716 }
717
718 if (len != 0) {
719 dma = &opipe->u.ctl.datadma;
720 if (reqh->request.bmRequestType & UT_READ)
721 memcpy(reqh->buffer, KERNADDR(dma), len);
722 usb_freemem(sc->sc_dmatag, dma);
723 }
724 untimeout(ohci_timeout, reqh);
725 }
726
727 void
728 ohci_intr_done(sc, reqh)
729 ohci_softc_t *sc;
730 usbd_request_handle reqh;
731 {
732 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
733 usb_dma_t *dma;
734 ohci_soft_ed_t *sed = opipe->sed;
735 ohci_soft_td_t *xfer, *tail;
736
737
738 DPRINTFN(10,("ohci_intr_done: reqh=%p, actlen=%d\n",
739 reqh, reqh->actlen));
740
741 dma = &opipe->u.intr.datadma;
742 memcpy(reqh->buffer, KERNADDR(dma), reqh->actlen);
743
744 if (reqh->pipe->intrreqh == reqh) {
745 xfer = opipe->tail;
746 tail = ohci_alloc_std(sc); /* XXX should reuse TD */
747 if (!tail) {
748 reqh->status = USBD_NOMEM;
749 return;
750 }
751 tail->reqh = 0;
752
753 xfer->td->td_flags = OHCI_TD_IN | OHCI_TD_NOCC |
754 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY;
755 xfer->td->td_cbp = DMAADDR(dma);
756 xfer->nexttd = tail;
757 xfer->td->td_nexttd = tail->physaddr;
758 xfer->td->td_be = xfer->td->td_cbp + reqh->length - 1;
759 xfer->len = reqh->length;
760 xfer->reqh = reqh;
761
762 reqh->actlen = 0;
763 reqh->hcpriv = xfer;
764
765 ohci_hash_add_td(sc, xfer);
766 sed->ed->ed_tailp = tail->physaddr;
767 opipe->tail = tail;
768 } else {
769 usb_freemem(sc->sc_dmatag, dma);
770 }
771 }
772
773 void
774 ohci_bulk_done(sc, reqh)
775 ohci_softc_t *sc;
776 usbd_request_handle reqh;
777 {
778 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
779 usb_dma_t *dma;
780
781
782 DPRINTFN(10,("ohci_bulk_done: reqh=%p, actlen=%d\n",
783 reqh, reqh->actlen));
784
785 dma = &opipe->u.bulk.datadma;
786 if (reqh->request.bmRequestType & UT_READ)
787 memcpy(reqh->buffer, KERNADDR(dma), reqh->actlen);
788 usb_freemem(sc->sc_dmatag, dma);
789 untimeout(ohci_timeout, reqh);
790 }
791
792 void
793 ohci_rhsc(sc, reqh)
794 ohci_softc_t *sc;
795 usbd_request_handle reqh;
796 {
797 usbd_pipe_handle pipe;
798 struct ohci_pipe *opipe;
799 u_char *p;
800 int i, m;
801 int hstatus;
802
803 hstatus = OREAD4(sc, OHCI_RH_STATUS);
804 DPRINTF(("ohci_rhsc: sc=%p reqh=%p hstatus=0x%08x\n",
805 sc, reqh, hstatus));
806
807 if (reqh == 0) {
808 /* Just ignore the change. */
809 return;
810 }
811
812 pipe = reqh->pipe;
813 opipe = (struct ohci_pipe *)pipe;
814
815 p = KERNADDR(&opipe->u.intr.datadma);
816 m = min(sc->sc_noport, reqh->length * 8 - 1);
817 memset(p, 0, reqh->length);
818 for (i = 1; i <= m; i++) {
819 if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16)
820 p[i/8] |= 1 << (i%8);
821 }
822 DPRINTF(("ohci_rhsc: change=0x%02x\n", *p));
823 reqh->actlen = reqh->length;
824 reqh->status = USBD_NORMAL_COMPLETION;
825 reqh->xfercb(reqh);
826
827 if (reqh->pipe->intrreqh != reqh) {
828 sc->sc_intrreqh = 0;
829 usb_freemem(sc->sc_dmatag, &opipe->u.intr.datadma);
830 }
831 }
832
833 /*
834 * Wait here until controller claims to have an interrupt.
835 * Then call ohci_intr and return. Use timeout to avoid waiting
836 * too long.
837 */
838 void
839 ohci_waitintr(sc, reqh)
840 ohci_softc_t *sc;
841 usbd_request_handle reqh;
842 {
843 int timo = reqh->timeout;
844 int usecs;
845 u_int32_t intrs;
846
847 reqh->status = USBD_IN_PROGRESS;
848 for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) {
849 delay(1000);
850 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs;
851 DPRINTFN(10,("ohci_waitintr: 0x%04x\n", intrs));
852 #ifdef USB_DEBUG
853 if (ohcidebug > 15)
854 ohci_dumpregs(sc);
855 #endif
856 if (intrs) {
857 ohci_intr(sc);
858 if (reqh->status != USBD_IN_PROGRESS)
859 return;
860 }
861 }
862 DPRINTF(("ohci_waitintr: timeout\n"));
863 reqh->status = USBD_TIMEOUT;
864 reqh->xfercb(reqh);
865 }
866
867 void
868 ohci_poll(bus)
869 struct usbd_bus *bus;
870 {
871 ohci_softc_t *sc = (ohci_softc_t *)bus;
872
873 if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs)
874 ohci_intr(sc);
875 }
876
877 usbd_status
878 ohci_device_request(reqh)
879 usbd_request_handle reqh;
880 {
881 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
882 usb_device_request_t *req = &reqh->request;
883 usbd_device_handle dev = opipe->pipe.device;
884 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
885 int addr = dev->address;
886 ohci_soft_td_t *setup, *xfer = 0, *stat, *next, *tail;
887 ohci_soft_ed_t *sed;
888 usb_dma_t *dmap;
889 int isread;
890 int len;
891 usbd_status r;
892 int s;
893
894 isread = req->bmRequestType & UT_READ;
895 len = UGETW(req->wLength);
896
897 DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
898 req->bmRequestType, req->bRequest, UGETW(req->wValue),
899 UGETW(req->wIndex), len, addr,
900 opipe->pipe.endpoint->edesc->bEndpointAddress));
901
902 setup = opipe->tail;
903 stat = ohci_alloc_std(sc);
904 if (!stat) {
905 r = USBD_NOMEM;
906 goto bad1;
907 }
908 tail = ohci_alloc_std(sc);
909 if (!tail) {
910 r = USBD_NOMEM;
911 goto bad2;
912 }
913 tail->reqh = 0;
914
915 sed = opipe->sed;
916 dmap = &opipe->u.ctl.datadma;
917 opipe->u.ctl.length = len;
918
919 /* Update device address and length since they may have changed. */
920 /* XXX This only needs to be done once, but it's too early in open. */
921 sed->ed->ed_flags =
922 (sed->ed->ed_flags & ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) |
923 OHCI_ED_SET_FA(addr) |
924 OHCI_ED_SET_MAXP(UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize));
925
926 /* Set up data transaction */
927 if (len != 0) {
928 xfer = ohci_alloc_std(sc);
929 if (!xfer) {
930 r = USBD_NOMEM;
931 goto bad3;
932 }
933 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
934 if (r != USBD_NORMAL_COMPLETION)
935 goto bad4;
936 xfer->td->td_flags =
937 (isread ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC |
938 OHCI_TD_TOGGLE_1 | OHCI_TD_NOINTR;
939 xfer->td->td_cbp = DMAADDR(dmap);
940 xfer->nexttd = stat;
941 xfer->td->td_nexttd = stat->physaddr;
942 xfer->td->td_be = xfer->td->td_cbp + len - 1;
943 xfer->len = len;
944 xfer->reqh = reqh;
945
946 next = xfer;
947 } else
948 next = stat;
949
950 memcpy(KERNADDR(&opipe->u.ctl.reqdma), req, sizeof *req);
951 if (!isread && len != 0)
952 memcpy(KERNADDR(dmap), reqh->buffer, len);
953
954 setup->td->td_flags = OHCI_TD_SETUP | OHCI_TD_NOCC |
955 OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR;
956 setup->td->td_cbp = DMAADDR(&opipe->u.ctl.reqdma);
957 setup->nexttd = next;
958 setup->td->td_nexttd = next->physaddr;
959 setup->td->td_be = setup->td->td_cbp + sizeof *req - 1;
960 setup->len = 0; /* XXX The number of byte we count */
961 setup->reqh = reqh;
962
963 stat->td->td_flags =
964 (isread ? OHCI_TD_OUT : OHCI_TD_IN) | OHCI_TD_NOCC |
965 OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1);
966 stat->td->td_cbp = 0;
967 stat->nexttd = tail;
968 stat->td->td_nexttd = tail->physaddr;
969 stat->td->td_be = 0;
970 stat->len = 0;
971 stat->reqh = reqh;
972
973 reqh->actlen = 0;
974 reqh->hcpriv = stat;
975
976 #if USB_DEBUG
977 if (ohcidebug > 5) {
978 printf("ohci_device_request:\n");
979 ohci_dump_ed(sed);
980 ohci_dump_tds(setup);
981 }
982 #endif
983
984 /* Insert ED in schedule */
985 s = splusb();
986 ohci_hash_add_td(sc, setup);
987 if (len != 0)
988 ohci_hash_add_td(sc, xfer);
989 ohci_hash_add_td(sc, stat);
990 sed->ed->ed_tailp = tail->physaddr;
991 opipe->tail = tail;
992 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
993 if (reqh->timeout && !sc->sc_bus.use_polling)
994 timeout(ohci_timeout, reqh, MS_TO_TICKS(reqh->timeout));
995 splx(s);
996
997 #if USB_DEBUG
998 if (ohcidebug > 5) {
999 delay(5000);
1000 printf("ohci_device_request: status=%x\n",
1001 OREAD4(sc, OHCI_COMMAND_STATUS));
1002 ohci_dump_ed(sed);
1003 ohci_dump_tds(setup);
1004 }
1005 #endif
1006
1007 return (USBD_NORMAL_COMPLETION);
1008
1009 bad4:
1010 ohci_free_std(sc, xfer);
1011 bad3:
1012 ohci_free_std(sc, tail);
1013 bad2:
1014 ohci_free_std(sc, stat);
1015 bad1:
1016 return (r);
1017 }
1018
1019 /*
1020 * Add an ED to the schedule. Called at splusb().
1021 */
1022 void
1023 ohci_add_ed(sed, head)
1024 ohci_soft_ed_t *sed;
1025 ohci_soft_ed_t *head;
1026 {
1027 sed->next = head->next;
1028 sed->ed->ed_nexted = head->ed->ed_nexted;
1029 head->next = sed;
1030 head->ed->ed_nexted = sed->physaddr;
1031 }
1032
1033 /*
1034 * Remove an ED from the schedule. Called at splusb().
1035 */
1036 void
1037 ohci_rem_ed(sed, head)
1038 ohci_soft_ed_t *sed;
1039 ohci_soft_ed_t *head;
1040 {
1041 ohci_soft_ed_t *p;
1042
1043 /* XXX */
1044 for (p = head; p && p->next != sed; p = p->next)
1045 ;
1046 if (!p)
1047 panic("ohci_rem_ed: ED not found\n");
1048 p->next = sed->next;
1049 p->ed->ed_nexted = sed->ed->ed_nexted;
1050 }
1051
1052 /*
1053 * When a transfer is completed the TD is added to the done queue by
1054 * the host controller. This queue is the processed by software.
1055 * Unfortunately the queue contains the physical address of the TD
1056 * and we have no simple way to translate this back to a kernel address.
1057 * To make the translation possible (and fast) we use a hash table of
1058 * TDs currently in the schedule. The physical address is used as the
1059 * hash value.
1060 */
1061
1062 #define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE)
1063 /* Called at splusb() */
1064 void
1065 ohci_hash_add_td(sc, std)
1066 ohci_softc_t *sc;
1067 ohci_soft_td_t *std;
1068 {
1069 int h = HASH(std->physaddr);
1070
1071 LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
1072 }
1073
1074 /* Called at splusb() */
1075 void
1076 ohci_hash_rem_td(sc, std)
1077 ohci_softc_t *sc;
1078 ohci_soft_td_t *std;
1079 {
1080 LIST_REMOVE(std, hnext);
1081 }
1082
1083 ohci_soft_td_t *
1084 ohci_hash_find_td(sc, a)
1085 ohci_softc_t *sc;
1086 ohci_physaddr_t a;
1087 {
1088 int h = HASH(a);
1089 ohci_soft_td_t *std;
1090
1091 for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
1092 std != 0;
1093 std = LIST_NEXT(std, hnext))
1094 if (std->physaddr == a)
1095 return (std);
1096 panic("ohci_hash_find_td: addr 0x%08lx not found\n", (u_long)a);
1097 }
1098
1099 void
1100 ohci_timeout(addr)
1101 void *addr;
1102 {
1103 #if 0
1104 usbd_request_handle *reqh = addr;
1105 int s;
1106
1107 DPRINTF(("ohci_timeout: reqh=%p\n", reqh));
1108 s = splusb();
1109 /* XXX need to inactivate TD before calling interrupt routine */
1110 ohci_XXX_done(reqh);
1111 splx(s);
1112 #endif
1113 }
1114
1115 #ifdef USB_DEBUG
1116 void
1117 ohci_dump_tds(std)
1118 ohci_soft_td_t *std;
1119 {
1120 for (; std; std = std->nexttd)
1121 ohci_dump_td(std);
1122 }
1123
1124 void
1125 ohci_dump_td(std)
1126 ohci_soft_td_t *std;
1127 {
1128 printf("TD(%p) at %08lx: %b delay=%d ec=%d cc=%d\ncbp=0x%08lx nexttd=0x%08lx be=0x%08lx\n",
1129 std, (u_long)std->physaddr,
1130 (u_long)std->td->td_flags,
1131 "\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE",
1132 OHCI_TD_GET_DI(std->td->td_flags),
1133 OHCI_TD_GET_EC(std->td->td_flags),
1134 OHCI_TD_GET_CC(std->td->td_flags),
1135 (u_long)std->td->td_cbp,
1136 (u_long)std->td->td_nexttd, (u_long)std->td->td_be);
1137 }
1138
1139 void
1140 ohci_dump_ed(sed)
1141 ohci_soft_ed_t *sed;
1142 {
1143 printf("ED(%p) at %08lx: addr=%d endpt=%d maxp=%d %b\ntailp=0x%08lx headp=%b nexted=0x%08lx\n",
1144 sed, (u_long)sed->physaddr,
1145 OHCI_ED_GET_FA(sed->ed->ed_flags),
1146 OHCI_ED_GET_EN(sed->ed->ed_flags),
1147 OHCI_ED_GET_MAXP(sed->ed->ed_flags),
1148 (u_long)sed->ed->ed_flags,
1149 "\20\14OUT\15IN\16LOWSPEED\17SKIP\18ISO",
1150 (u_long)sed->ed->ed_tailp,
1151 (u_long)sed->ed->ed_headp, "\20\1HALT\2CARRY",
1152 (u_long)sed->ed->ed_nexted);
1153 }
1154 #endif
1155
1156 usbd_status
1157 ohci_open(pipe)
1158 usbd_pipe_handle pipe;
1159 {
1160 usbd_device_handle dev = pipe->device;
1161 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
1162 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
1163 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
1164 u_int8_t addr = dev->address;
1165 ohci_soft_ed_t *sed;
1166 ohci_soft_td_t *std;
1167 usbd_status r;
1168 int s;
1169
1170 DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
1171 pipe, addr, ed->bEndpointAddress, sc->sc_addr));
1172 if (addr == sc->sc_addr) {
1173 switch (ed->bEndpointAddress) {
1174 case USB_CONTROL_ENDPOINT:
1175 pipe->methods = &ohci_root_ctrl_methods;
1176 break;
1177 case UE_IN | OHCI_INTR_ENDPT:
1178 pipe->methods = &ohci_root_intr_methods;
1179 break;
1180 default:
1181 return (USBD_INVAL);
1182 }
1183 } else {
1184 sed = ohci_alloc_sed(sc);
1185 if (sed == 0)
1186 goto bad0;
1187 std = ohci_alloc_std(sc);
1188 if (std == 0)
1189 goto bad1;
1190 opipe->sed = sed;
1191 opipe->tail = std;
1192 sed->ed->ed_flags =
1193 OHCI_ED_SET_FA(addr) |
1194 OHCI_ED_SET_EN(ed->bEndpointAddress) |
1195 OHCI_ED_DIR_TD |
1196 (dev->lowspeed ? OHCI_ED_SPEED : 0) |
1197 ((ed->bmAttributes & UE_XFERTYPE) == UE_ISOCHRONOUS ?
1198 OHCI_ED_FORMAT_ISO : OHCI_ED_FORMAT_GEN) |
1199 OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize));
1200 sed->ed->ed_headp = sed->ed->ed_tailp = std->physaddr;
1201
1202 switch (ed->bmAttributes & UE_XFERTYPE) {
1203 case UE_CONTROL:
1204 pipe->methods = &ohci_device_ctrl_methods;
1205 r = usb_allocmem(sc->sc_dmatag,
1206 sizeof(usb_device_request_t),
1207 0, &opipe->u.ctl.reqdma);
1208 if (r != USBD_NORMAL_COMPLETION)
1209 goto bad;
1210 s = splusb();
1211 ohci_add_ed(sed, sc->sc_ctrl_head);
1212 splx(s);
1213 break;
1214 case UE_INTERRUPT:
1215 pipe->methods = &ohci_device_intr_methods;
1216 return (ohci_device_setintr(sc, opipe, ed->bInterval));
1217 case UE_ISOCHRONOUS:
1218 printf("ohci_open: open iso unimplemented\n");
1219 return (USBD_XXX);
1220 case UE_BULK:
1221 pipe->methods = &ohci_device_bulk_methods;
1222 s = splusb();
1223 ohci_add_ed(sed, sc->sc_bulk_head);
1224 splx(s);
1225 break;
1226 }
1227 }
1228 return (USBD_NORMAL_COMPLETION);
1229
1230 bad:
1231 ohci_free_std(sc, std);
1232 bad1:
1233 ohci_free_sed(sc, sed);
1234 bad0:
1235 return (USBD_NOMEM);
1236
1237 }
1238
1239 /*
1240 * Data structures and routines to emulate the root hub.
1241 */
1242 usb_device_descriptor_t ohci_devd = {
1243 USB_DEVICE_DESCRIPTOR_SIZE,
1244 UDESC_DEVICE, /* type */
1245 {0x00, 0x01}, /* USB version */
1246 UCLASS_HUB, /* class */
1247 USUBCLASS_HUB, /* subclass */
1248 0, /* protocol */
1249 64, /* max packet */
1250 {0},{0},{0x00,0x01}, /* device id */
1251 1,2,0, /* string indicies */
1252 1 /* # of configurations */
1253 };
1254
1255 usb_config_descriptor_t ohci_confd = {
1256 USB_CONFIG_DESCRIPTOR_SIZE,
1257 UDESC_CONFIG,
1258 {USB_CONFIG_DESCRIPTOR_SIZE +
1259 USB_INTERFACE_DESCRIPTOR_SIZE +
1260 USB_ENDPOINT_DESCRIPTOR_SIZE},
1261 1,
1262 1,
1263 0,
1264 UC_SELF_POWERED,
1265 0 /* max power */
1266 };
1267
1268 usb_interface_descriptor_t ohci_ifcd = {
1269 USB_INTERFACE_DESCRIPTOR_SIZE,
1270 UDESC_INTERFACE,
1271 0,
1272 0,
1273 1,
1274 UCLASS_HUB,
1275 USUBCLASS_HUB,
1276 0,
1277 0
1278 };
1279
1280 usb_endpoint_descriptor_t ohci_endpd = {
1281 USB_ENDPOINT_DESCRIPTOR_SIZE,
1282 UDESC_ENDPOINT,
1283 UE_IN | OHCI_INTR_ENDPT,
1284 UE_INTERRUPT,
1285 {8, 0}, /* max packet */
1286 255
1287 };
1288
1289 usb_hub_descriptor_t ohci_hubd = {
1290 USB_HUB_DESCRIPTOR_SIZE,
1291 UDESC_HUB,
1292 0,
1293 {0,0},
1294 0,
1295 0,
1296 {0},
1297 {0},
1298 };
1299
1300 int
1301 ohci_str(p, l, s)
1302 usb_string_descriptor_t *p;
1303 int l;
1304 char *s;
1305 {
1306 int i;
1307
1308 if (l == 0)
1309 return (0);
1310 p->bLength = 2 * strlen(s) + 2;
1311 if (l == 1)
1312 return (1);
1313 p->bDescriptorType = UDESC_STRING;
1314 l -= 2;
1315 for (i = 0; s[i] && l > 1; i++, l -= 2)
1316 USETW2(p->bString[i], 0, s[i]);
1317 return (2*i+2);
1318 }
1319
1320 /*
1321 * Simulate a hardware hub by handling all the necessary requests.
1322 */
1323 usbd_status
1324 ohci_root_ctrl_transfer(reqh)
1325 usbd_request_handle reqh;
1326 {
1327 ohci_softc_t *sc = (ohci_softc_t *)reqh->pipe->device->bus;
1328 usb_device_request_t *req;
1329 void *buf;
1330 int port, i;
1331 int len, value, index, l, totlen = 0;
1332 usb_port_status_t ps;
1333 usb_hub_descriptor_t hubd;
1334 usbd_status r;
1335 u_int32_t v;
1336
1337 if (!reqh->isreq)
1338 /* XXX panic */
1339 return (USBD_INVAL);
1340 req = &reqh->request;
1341 buf = reqh->buffer;
1342
1343 DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n",
1344 req->bmRequestType, req->bRequest));
1345
1346 len = UGETW(req->wLength);
1347 value = UGETW(req->wValue);
1348 index = UGETW(req->wIndex);
1349 #define C(x,y) ((x) | ((y) << 8))
1350 switch(C(req->bRequest, req->bmRequestType)) {
1351 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
1352 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
1353 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
1354 /*
1355 * DEVICE_REMOTE_WAKEUP and ENDPOINT_STALL are no-ops
1356 * for the integrated root hub.
1357 */
1358 break;
1359 case C(UR_GET_CONFIG, UT_READ_DEVICE):
1360 if (len > 0) {
1361 *(u_int8_t *)buf = sc->sc_conf;
1362 totlen = 1;
1363 }
1364 break;
1365 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
1366 DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value));
1367 switch(value >> 8) {
1368 case UDESC_DEVICE:
1369 if ((value & 0xff) != 0) {
1370 r = USBD_IOERROR;
1371 goto ret;
1372 }
1373 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
1374 memcpy(buf, &ohci_devd, l);
1375 break;
1376 case UDESC_CONFIG:
1377 if ((value & 0xff) != 0) {
1378 r = USBD_IOERROR;
1379 goto ret;
1380 }
1381 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
1382 memcpy(buf, &ohci_confd, l);
1383 buf = (char *)buf + l;
1384 len -= l;
1385 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
1386 totlen += l;
1387 memcpy(buf, &ohci_ifcd, l);
1388 buf = (char *)buf + l;
1389 len -= l;
1390 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
1391 totlen += l;
1392 memcpy(buf, &ohci_endpd, l);
1393 break;
1394 case UDESC_STRING:
1395 if (len == 0)
1396 break;
1397 *(u_int8_t *)buf = 0;
1398 totlen = 1;
1399 switch (value & 0xff) {
1400 case 1: /* Vendor */
1401 totlen = ohci_str(buf, len, sc->sc_vendor);
1402 break;
1403 case 2: /* Product */
1404 totlen = ohci_str(buf, len, "OHCI root hub");
1405 break;
1406 }
1407 break;
1408 default:
1409 r = USBD_IOERROR;
1410 goto ret;
1411 }
1412 break;
1413 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
1414 if (len > 0) {
1415 *(u_int8_t *)buf = 0;
1416 totlen = 1;
1417 }
1418 break;
1419 case C(UR_GET_STATUS, UT_READ_DEVICE):
1420 if (len > 1) {
1421 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
1422 totlen = 2;
1423 }
1424 break;
1425 case C(UR_GET_STATUS, UT_READ_INTERFACE):
1426 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
1427 if (len > 1) {
1428 USETW(((usb_status_t *)buf)->wStatus, 0);
1429 totlen = 2;
1430 }
1431 break;
1432 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
1433 if (value >= USB_MAX_DEVICES) {
1434 r = USBD_IOERROR;
1435 goto ret;
1436 }
1437 sc->sc_addr = value;
1438 break;
1439 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
1440 if (value != 0 && value != 1) {
1441 r = USBD_IOERROR;
1442 goto ret;
1443 }
1444 sc->sc_conf = value;
1445 break;
1446 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
1447 break;
1448 case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
1449 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
1450 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
1451 r = USBD_IOERROR;
1452 goto ret;
1453 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
1454 break;
1455 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
1456 break;
1457 /* Hub requests */
1458 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
1459 break;
1460 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
1461 DPRINTFN(8, ("ohci_root_ctrl_control: UR_CLEAR_PORT_FEATURE port=%d feature=%d\n",
1462 index, value));
1463 if (index < 1 || index > sc->sc_noport) {
1464 r = USBD_IOERROR;
1465 goto ret;
1466 }
1467 port = OHCI_RH_PORT_STATUS(index);
1468 switch(value) {
1469 case UHF_PORT_ENABLE:
1470 OWRITE4(sc, port, UPS_CURRENT_CONNECT_STATUS);
1471 break;
1472 case UHF_PORT_SUSPEND:
1473 OWRITE4(sc, port, UPS_OVERCURRENT_INDICATOR);
1474 break;
1475 case UHF_PORT_POWER:
1476 OWRITE4(sc, port, UPS_LOW_SPEED);
1477 break;
1478 case UHF_C_PORT_CONNECTION:
1479 OWRITE4(sc, port, UPS_C_CONNECT_STATUS << 16);
1480 break;
1481 case UHF_C_PORT_ENABLE:
1482 OWRITE4(sc, port, UPS_C_PORT_ENABLED << 16);
1483 break;
1484 case UHF_C_PORT_SUSPEND:
1485 OWRITE4(sc, port, UPS_C_SUSPEND << 16);
1486 break;
1487 case UHF_C_PORT_OVER_CURRENT:
1488 OWRITE4(sc, port, UPS_C_OVERCURRENT_INDICATOR << 16);
1489 break;
1490 case UHF_C_PORT_RESET:
1491 OWRITE4(sc, port, UPS_C_PORT_RESET << 16);
1492 break;
1493 default:
1494 r = USBD_IOERROR;
1495 goto ret;
1496 }
1497 switch(value) {
1498 case UHF_C_PORT_CONNECTION:
1499 case UHF_C_PORT_ENABLE:
1500 case UHF_C_PORT_SUSPEND:
1501 case UHF_C_PORT_OVER_CURRENT:
1502 case UHF_C_PORT_RESET:
1503 /* Enable RHSC interrupt if condition is cleared. */
1504 if ((OREAD4(sc, port) >> 16) == 0)
1505 ohci_rhsc_able(sc, 1);
1506 break;
1507 default:
1508 break;
1509 }
1510 break;
1511 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
1512 if (value != 0) {
1513 r = USBD_IOERROR;
1514 goto ret;
1515 }
1516 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
1517 hubd = ohci_hubd;
1518 hubd.bNbrPorts = sc->sc_noport;
1519 USETW(hubd.bHubCharacteristics,
1520 (v & OHCI_NPS ? UHD_PWR_NO_SWITCH :
1521 v & OHCI_PSM ? UHD_PWR_GANGED : UHD_PWR_INDIVIDUAL)
1522 /* XXX overcurrent */
1523 );
1524 hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v);
1525 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
1526 if (sc->sc_noport < 8) {
1527 hubd.DeviceRemovable[0] = (u_int8_t)v;
1528 hubd.PortPowerCtrlMask[0] = (u_int8_t)(v >> 16);
1529 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE;
1530 } else {
1531 hubd.DeviceRemovable[0] = (u_int8_t)v;
1532 hubd.DeviceRemovable[1] = (u_int8_t)(v>>8);
1533 hubd.PortPowerCtrlMask[1] = (u_int8_t)(v >> 16);
1534 hubd.PortPowerCtrlMask[2] = (u_int8_t)(v >> 24);
1535 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + 2;
1536 }
1537 l = min(len, hubd.bDescLength);
1538 totlen = l;
1539 memcpy(buf, &hubd, l);
1540 break;
1541 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
1542 if (len != 4) {
1543 r = USBD_IOERROR;
1544 goto ret;
1545 }
1546 memset(buf, 0, len); /* ? XXX */
1547 totlen = len;
1548 break;
1549 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
1550 DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n",
1551 index));
1552 if (index < 1 || index > sc->sc_noport) {
1553 r = USBD_IOERROR;
1554 goto ret;
1555 }
1556 if (len != 4) {
1557 r = USBD_IOERROR;
1558 goto ret;
1559 }
1560 v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
1561 DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n",
1562 v));
1563 USETW(ps.wPortStatus, v);
1564 USETW(ps.wPortChange, v >> 16);
1565 l = min(len, sizeof ps);
1566 memcpy(buf, &ps, l);
1567 totlen = l;
1568 break;
1569 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
1570 r = USBD_IOERROR;
1571 goto ret;
1572 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
1573 break;
1574 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
1575 if (index < 1 || index > sc->sc_noport) {
1576 r = USBD_IOERROR;
1577 goto ret;
1578 }
1579 port = OHCI_RH_PORT_STATUS(index);
1580 switch(value) {
1581 case UHF_PORT_ENABLE:
1582 OWRITE4(sc, port, UPS_PORT_ENABLED);
1583 break;
1584 case UHF_PORT_SUSPEND:
1585 OWRITE4(sc, port, UPS_SUSPEND);
1586 break;
1587 case UHF_PORT_RESET:
1588 DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n", index));
1589 OWRITE4(sc, port, UPS_RESET);
1590 for (i = 0; i < 10; i++) {
1591 usbd_delay_ms(&sc->sc_bus, 10);
1592 if ((OREAD4(sc, port) & UPS_RESET) == 0)
1593 break;
1594 }
1595 DPRINTFN(8,("ohci port %d reset, status = 0x%04x\n",
1596 index, OREAD4(sc, port)));
1597 break;
1598 case UHF_PORT_POWER:
1599 DPRINTFN(2,("ohci_root_ctrl_transfer: set port power %d\n", index));
1600 OWRITE4(sc, port, UPS_PORT_POWER);
1601 break;
1602 default:
1603 r = USBD_IOERROR;
1604 goto ret;
1605 }
1606 break;
1607 default:
1608 r = USBD_IOERROR;
1609 goto ret;
1610 }
1611 reqh->actlen = totlen;
1612 r = USBD_NORMAL_COMPLETION;
1613 ret:
1614 reqh->status = r;
1615 reqh->xfercb(reqh);
1616 return (USBD_IN_PROGRESS);
1617 }
1618
1619 /* Abort a root control request. */
1620 void
1621 ohci_root_ctrl_abort(reqh)
1622 usbd_request_handle reqh;
1623 {
1624 /* Nothing to do, all transfers are synchronous. */
1625 }
1626
1627 /* Close the root pipe. */
1628 void
1629 ohci_root_ctrl_close(pipe)
1630 usbd_pipe_handle pipe;
1631 {
1632 DPRINTF(("ohci_root_ctrl_close\n"));
1633 }
1634
1635 usbd_status
1636 ohci_root_intr_transfer(reqh)
1637 usbd_request_handle reqh;
1638 {
1639 usbd_pipe_handle pipe = reqh->pipe;
1640 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
1641 struct ohci_pipe *upipe = (struct ohci_pipe *)pipe;
1642 usb_dma_t *dmap;
1643 usbd_status r;
1644 int len;
1645
1646 len = reqh->length;
1647 dmap = &upipe->u.intr.datadma;
1648 if (len == 0)
1649 return (USBD_INVAL); /* XXX should it be? */
1650
1651 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1652 if (r != USBD_NORMAL_COMPLETION)
1653 return (r);
1654 sc->sc_intrreqh = reqh;
1655
1656 return (USBD_IN_PROGRESS);
1657 }
1658
1659 /* Abort a root interrupt request. */
1660 void
1661 ohci_root_intr_abort(reqh)
1662 usbd_request_handle reqh;
1663 {
1664 /* No need to abort. */
1665 }
1666
1667 /* Close the root pipe. */
1668 void
1669 ohci_root_intr_close(pipe)
1670 usbd_pipe_handle pipe;
1671 {
1672 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
1673 sc->sc_intrreqh = 0;
1674
1675 DPRINTF(("ohci_root_intr_close\n"));
1676 }
1677
1678 /************************/
1679
1680 usbd_status
1681 ohci_device_ctrl_transfer(reqh)
1682 usbd_request_handle reqh;
1683 {
1684 ohci_softc_t *sc = (ohci_softc_t *)reqh->pipe->device->bus;
1685 usbd_status r;
1686
1687 if (!reqh->isreq) {
1688 /* XXX panic */
1689 printf("ohci_device_ctrl_transfer: not a request\n");
1690 return (USBD_INVAL);
1691 }
1692
1693 r = ohci_device_request(reqh);
1694 if (r != USBD_NORMAL_COMPLETION)
1695 return (r);
1696
1697 if (sc->sc_bus.use_polling)
1698 ohci_waitintr(sc, reqh);
1699 return (USBD_IN_PROGRESS);
1700 }
1701
1702 /* Abort a device control request. */
1703 void
1704 ohci_device_ctrl_abort(reqh)
1705 usbd_request_handle reqh;
1706 {
1707 /* XXX inactivate */
1708 usbd_delay_ms(reqh->pipe->device->bus, 1); /* make sure it is finished */
1709 /* XXX call done */
1710 }
1711
1712 /* Close a device control pipe. */
1713 void
1714 ohci_device_ctrl_close(pipe)
1715 usbd_pipe_handle pipe;
1716 {
1717 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
1718 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
1719 ohci_soft_ed_t *sed = opipe->sed;
1720 int s;
1721
1722 s = splusb();
1723 sed->ed->ed_flags |= OHCI_ED_SKIP;
1724 if ((sed->ed->ed_tailp & OHCI_TAILMASK) != sed->ed->ed_headp)
1725 usbd_delay_ms(&sc->sc_bus, 2);
1726 ohci_rem_ed(sed, sc->sc_ctrl_head);
1727 splx(s);
1728 ohci_free_std(sc, opipe->tail);
1729 ohci_free_sed(sc, opipe->sed);
1730 /* XXX free other resources */
1731 }
1732
1733 /************************/
1734
1735 usbd_status
1736 ohci_device_bulk_transfer(reqh)
1737 usbd_request_handle reqh;
1738 {
1739 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
1740 usbd_device_handle dev = opipe->pipe.device;
1741 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
1742 int addr = dev->address;
1743 ohci_soft_td_t *xfer, *tail;
1744 ohci_soft_ed_t *sed;
1745 usb_dma_t *dmap;
1746 usbd_status r;
1747 int s, len, isread;
1748
1749 if (reqh->isreq) {
1750 /* XXX panic */
1751 printf("ohci_device_bulk_transfer: a request\n");
1752 return (USBD_INVAL);
1753 }
1754
1755 len = reqh->length;
1756 dmap = &opipe->u.bulk.datadma;
1757 isread = reqh->pipe->endpoint->edesc->bEndpointAddress & UE_IN;
1758 sed = opipe->sed;
1759
1760 opipe->u.bulk.length = len;
1761
1762 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1763 if (r != USBD_NORMAL_COMPLETION)
1764 goto ret1;
1765
1766 tail = ohci_alloc_std(sc);
1767 if (!tail) {
1768 r = USBD_NOMEM;
1769 goto ret2;
1770 }
1771 tail->reqh = 0;
1772
1773 /* Update device address */
1774 sed->ed->ed_flags =
1775 (sed->ed->ed_flags & ~OHCI_ED_ADDRMASK) |
1776 OHCI_ED_SET_FA(addr);
1777
1778 /* Set up data transaction */
1779 xfer = opipe->tail;
1780 xfer->td->td_flags =
1781 (isread ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC |
1782 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY;
1783 xfer->td->td_cbp = DMAADDR(dmap);
1784 xfer->nexttd = tail;
1785 xfer->td->td_nexttd = tail->physaddr;
1786 xfer->td->td_be = xfer->td->td_cbp + len - 1;
1787 xfer->len = len;
1788 xfer->reqh = reqh;
1789
1790 reqh->actlen = 0;
1791 reqh->hcpriv = xfer;
1792
1793 if (!isread)
1794 memcpy(KERNADDR(dmap), reqh->buffer, len);
1795
1796 /* Insert ED in schedule */
1797 s = splusb();
1798 ohci_hash_add_td(sc, xfer);
1799 sed->ed->ed_tailp = tail->physaddr;
1800 opipe->tail = tail;
1801 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
1802 if (reqh->timeout && !sc->sc_bus.use_polling)
1803 timeout(ohci_timeout, reqh, MS_TO_TICKS(reqh->timeout));
1804 splx(s);
1805
1806 return (USBD_IN_PROGRESS);
1807
1808 ret2:
1809 usb_freemem(sc->sc_dmatag, dmap);
1810 ret1:
1811 return (r);
1812 }
1813
1814 /* Abort a device bulk request. */
1815 void
1816 ohci_device_bulk_abort(reqh)
1817 usbd_request_handle reqh;
1818 {
1819 #if 0
1820 sed->ed->ed_flags |= OHCI_ED_SKIP;
1821 if ((sed->ed->ed_tailp & OHCI_TAILMASK) != sed->ed->ed_headp)
1822 usbd_delay_ms(reqh->pipe->device->bus, 2);
1823 #endif
1824 /* XXX inactivate */
1825 usbd_delay_ms(reqh->pipe->device->bus, 1); /* make sure it is finished */
1826 /* XXX call done */
1827 }
1828
1829 /* Close a device bulk pipe. */
1830 void
1831 ohci_device_bulk_close(pipe)
1832 usbd_pipe_handle pipe;
1833 {
1834 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
1835 usbd_device_handle dev = opipe->pipe.device;
1836 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
1837 int s;
1838
1839 s = splusb();
1840 ohci_rem_ed(opipe->sed, sc->sc_bulk_head);
1841 splx(s);
1842 ohci_free_std(sc, opipe->tail);
1843 ohci_free_sed(sc, opipe->sed);
1844 /* XXX free other resources */
1845 }
1846
1847 /************************/
1848
1849 usbd_status
1850 ohci_device_intr_transfer(reqh)
1851 usbd_request_handle reqh;
1852 {
1853 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
1854 usbd_device_handle dev = opipe->pipe.device;
1855 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
1856 ohci_soft_ed_t *sed = opipe->sed;
1857 ohci_soft_td_t *xfer, *tail;
1858 usb_dma_t *dmap;
1859 usbd_status r;
1860 int len;
1861 int s;
1862
1863 DPRINTFN(3, ("ohci_device_intr_transfer: reqh=%p buf=%p len=%d flags=%d priv=%p\n",
1864 reqh, reqh->buffer, reqh->length, reqh->flags, reqh->priv));
1865
1866 if (reqh->isreq)
1867 panic("ohci_device_intr_transfer: a request\n");
1868
1869 len = reqh->length;
1870 dmap = &opipe->u.intr.datadma;
1871 if (len == 0)
1872 return (USBD_INVAL); /* XXX should it be? */
1873
1874 xfer = opipe->tail;
1875 tail = ohci_alloc_std(sc);
1876 if (!tail) {
1877 r = USBD_NOMEM;
1878 goto ret1;
1879 }
1880 tail->reqh = 0;
1881
1882 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1883 if (r != USBD_NORMAL_COMPLETION)
1884 goto ret2;
1885
1886 xfer->td->td_flags = OHCI_TD_IN | OHCI_TD_NOCC |
1887 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY;
1888 xfer->td->td_cbp = DMAADDR(dmap);
1889 xfer->nexttd = tail;
1890 xfer->td->td_nexttd = tail->physaddr;
1891 xfer->td->td_be = xfer->td->td_cbp + len - 1;
1892 xfer->len = len;
1893 xfer->reqh = reqh;
1894
1895 reqh->actlen = 0;
1896 reqh->hcpriv = xfer;
1897
1898 #if USB_DEBUG
1899 if (ohcidebug > 5) {
1900 printf("ohci_device_intr_transfer:\n");
1901 ohci_dump_ed(sed);
1902 ohci_dump_tds(xfer);
1903 }
1904 #endif
1905
1906 /* Insert ED in schedule */
1907 s = splusb();
1908 ohci_hash_add_td(sc, xfer);
1909 sed->ed->ed_tailp = tail->physaddr;
1910 opipe->tail = tail;
1911 #if 0
1912 if (reqh->timeout && !sc->sc_bus.use_polling)
1913 timeout(ohci_timeout, reqh, MS_TO_TICKS(reqh->timeout));
1914 #endif
1915 sed->ed->ed_flags &= ~OHCI_ED_SKIP;
1916 splx(s);
1917
1918 #ifdef USB_DEBUG
1919 if (ohcidebug > 5) {
1920 delay(5000);
1921 printf("ohci_device_intr_transfer: status=%x\n",
1922 OREAD4(sc, OHCI_COMMAND_STATUS));
1923 ohci_dump_ed(sed);
1924 ohci_dump_tds(xfer);
1925 }
1926 #endif
1927
1928 return (USBD_IN_PROGRESS);
1929
1930 ret2:
1931 ohci_free_std(sc, xfer);
1932 ret1:
1933 return (r);
1934 }
1935
1936 /* Abort a device control request. */
1937 void
1938 ohci_device_intr_abort(reqh)
1939 usbd_request_handle reqh;
1940 {
1941 /* XXX inactivate */
1942 usbd_delay_ms(reqh->pipe->device->bus, 1); /* make sure it is finished */
1943 if (reqh->pipe->intrreqh == reqh) {
1944 DPRINTF(("ohci_device_intr_abort: remove\n"));
1945 reqh->pipe->intrreqh = 0;
1946 ohci_intr_done((ohci_softc_t *)reqh->pipe->device->bus, reqh);
1947 }
1948 }
1949
1950 /* Close a device interrupt pipe. */
1951 void
1952 ohci_device_intr_close(pipe)
1953 usbd_pipe_handle pipe;
1954 {
1955 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
1956 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
1957 int nslots = opipe->u.intr.nslots;
1958 int pos = opipe->u.intr.pos;
1959 int j;
1960 ohci_soft_ed_t *p, *sed = opipe->sed;
1961 int s;
1962
1963 DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n",
1964 pipe, nslots, pos));
1965 s = splusb();
1966 sed->ed->ed_flags |= OHCI_ED_SKIP;
1967 if ((sed->ed->ed_tailp & OHCI_TAILMASK) != sed->ed->ed_headp)
1968 usbd_delay_ms(&sc->sc_bus, 2);
1969
1970 for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
1971 ;
1972 if (!p)
1973 panic("ohci_device_intr_close: ED not found\n");
1974 p->next = sed->next;
1975 p->ed->ed_nexted = sed->ed->ed_nexted;
1976 splx(s);
1977
1978 for (j = 0; j < nslots; j++)
1979 --sc->sc_bws[pos * nslots + j];
1980
1981 ohci_free_std(sc, opipe->tail);
1982 ohci_free_sed(sc, opipe->sed);
1983 /* XXX free other resources */
1984 }
1985
1986 usbd_status
1987 ohci_device_setintr(sc, opipe, ival)
1988 ohci_softc_t *sc;
1989 struct ohci_pipe *opipe;
1990 int ival;
1991 {
1992 int i, j, s, best;
1993 u_int npoll, slow, shigh, nslots;
1994 u_int bestbw, bw;
1995 ohci_soft_ed_t *hsed, *sed = opipe->sed;
1996
1997 DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe));
1998 if (ival == 0) {
1999 printf("ohci_setintr: 0 interval\n");
2000 return (USBD_INVAL);
2001 }
2002
2003 npoll = OHCI_NO_INTRS;
2004 while (npoll > ival)
2005 npoll /= 2;
2006 DPRINTFN(2, ("ohci_setintr: ival=%d npoll=%d\n", ival, npoll));
2007
2008 /*
2009 * We now know which level in the tree the ED must go into.
2010 * Figure out which slot has most bandwidth left over.
2011 * Slots to examine:
2012 * npoll
2013 * 1 0
2014 * 2 1 2
2015 * 4 3 4 5 6
2016 * 8 7 8 9 10 11 12 13 14
2017 * N (N-1) .. (N-1+N-1)
2018 */
2019 slow = npoll-1;
2020 shigh = slow + npoll;
2021 nslots = OHCI_NO_INTRS / npoll;
2022 for (best = i = slow, bestbw = ~0; i < shigh; i++) {
2023 bw = 0;
2024 for (j = 0; j < nslots; j++)
2025 bw += sc->sc_bws[i * nslots + j];
2026 if (bw < bestbw) {
2027 best = i;
2028 bestbw = bw;
2029 }
2030 }
2031 DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n",
2032 best, slow, shigh, bestbw));
2033
2034 s = splusb();
2035 hsed = sc->sc_eds[best];
2036 sed->next = hsed->next;
2037 sed->ed->ed_nexted = hsed->ed->ed_nexted;
2038 hsed->next = sed;
2039 hsed->ed->ed_nexted = sed->physaddr;
2040 splx(s);
2041
2042 for (j = 0; j < nslots; j++)
2043 ++sc->sc_bws[best * nslots + j];
2044 opipe->u.intr.nslots = nslots;
2045 opipe->u.intr.pos = best;
2046
2047 DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe));
2048 return (USBD_NORMAL_COMPLETION);
2049 }
2050
2051