ohci.c revision 1.14 1 /* $NetBSD: ohci.c,v 1.14 1998/12/10 23:16:47 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->
654 bmAttributes & UE_XFERTYPE) {
655 case UE_CONTROL:
656 ohci_ctrl_done(sc, reqh);
657 break;
658 case UE_INTERRUPT:
659 ohci_intr_done(sc, reqh);
660 break;
661 case UE_BULK:
662 ohci_bulk_done(sc, reqh);
663 break;
664 case UE_ISOCHRONOUS:
665 printf("ohci_process_done: ISO done?\n");
666 break;
667 }
668 /* And finally execute callback. */
669 reqh->status = USBD_NORMAL_COMPLETION;
670 reqh->xfercb(reqh);
671 }
672 } else {
673 ohci_soft_td_t *p, *n;
674 struct ohci_pipe *opipe =
675 (struct ohci_pipe *)reqh->pipe;
676 DPRINTFN(-1,("ohci_process_done: error cc=%d (%s)\n",
677 OHCI_TD_GET_CC(std->td->td_flags),
678 ohci_cc_strs[OHCI_TD_GET_CC(std->td->td_flags)]));
679 /*
680 * Endpoint is halted. First unlink all the TDs
681 * belonging to the failed transfer, and then restart
682 * the endpoint.
683 */
684 for (p = std->nexttd; p->reqh == reqh; p = n) {
685 n = p->nexttd;
686 ohci_hash_rem_td(sc, p);
687 ohci_free_std(sc, p);
688 }
689 opipe->sed->ed->ed_headp = p->physaddr;/* clear halt */
690 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
691
692 if (cc == OHCI_CC_STALL)
693 reqh->status = USBD_STALLED;
694 else
695 reqh->status = USBD_IOERROR;
696 reqh->xfercb(reqh);
697 }
698 ohci_hash_rem_td(sc, std);
699 ohci_free_std(sc, std);
700 }
701 }
702
703 void
704 ohci_ctrl_done(sc, reqh)
705 ohci_softc_t *sc;
706 usbd_request_handle reqh;
707 {
708 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
709 u_int len = opipe->u.ctl.length;
710 usb_dma_t *dma;
711
712 DPRINTFN(10,("ohci_ctrl_done: reqh=%p\n", reqh));
713
714 if (!reqh->isreq) {
715 panic("ohci_ctrl_done: not a request\n");
716 return;
717 }
718
719 if (len != 0) {
720 dma = &opipe->u.ctl.datadma;
721 if (reqh->request.bmRequestType & UT_READ)
722 memcpy(reqh->buffer, KERNADDR(dma), len);
723 usb_freemem(sc->sc_dmatag, dma);
724 }
725 untimeout(ohci_timeout, reqh);
726 }
727
728 void
729 ohci_intr_done(sc, reqh)
730 ohci_softc_t *sc;
731 usbd_request_handle reqh;
732 {
733 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
734 usb_dma_t *dma;
735 ohci_soft_ed_t *sed = opipe->sed;
736 ohci_soft_td_t *xfer, *tail;
737
738
739 DPRINTFN(10,("ohci_intr_done: reqh=%p, actlen=%d\n",
740 reqh, reqh->actlen));
741
742 dma = &opipe->u.intr.datadma;
743 memcpy(reqh->buffer, KERNADDR(dma), reqh->actlen);
744
745 if (reqh->pipe->intrreqh == reqh) {
746 xfer = opipe->tail;
747 tail = ohci_alloc_std(sc); /* XXX should reuse TD */
748 if (!tail) {
749 reqh->status = USBD_NOMEM;
750 return;
751 }
752 tail->reqh = 0;
753
754 xfer->td->td_flags = OHCI_TD_IN | OHCI_TD_NOCC |
755 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY;
756 xfer->td->td_cbp = DMAADDR(dma);
757 xfer->nexttd = tail;
758 xfer->td->td_nexttd = tail->physaddr;
759 xfer->td->td_be = xfer->td->td_cbp + reqh->length - 1;
760 xfer->len = reqh->length;
761 xfer->reqh = reqh;
762
763 reqh->actlen = 0;
764 reqh->hcpriv = xfer;
765
766 ohci_hash_add_td(sc, xfer);
767 sed->ed->ed_tailp = tail->physaddr;
768 opipe->tail = tail;
769 } else {
770 usb_freemem(sc->sc_dmatag, dma);
771 }
772 }
773
774 void
775 ohci_bulk_done(sc, reqh)
776 ohci_softc_t *sc;
777 usbd_request_handle reqh;
778 {
779 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
780 usb_dma_t *dma;
781
782
783 DPRINTFN(10,("ohci_bulk_done: reqh=%p, actlen=%d\n",
784 reqh, reqh->actlen));
785
786 dma = &opipe->u.bulk.datadma;
787 if (reqh->request.bmRequestType & UT_READ)
788 memcpy(reqh->buffer, KERNADDR(dma), reqh->actlen);
789 usb_freemem(sc->sc_dmatag, dma);
790 untimeout(ohci_timeout, reqh);
791 }
792
793 void
794 ohci_rhsc(sc, reqh)
795 ohci_softc_t *sc;
796 usbd_request_handle reqh;
797 {
798 usbd_pipe_handle pipe;
799 struct ohci_pipe *opipe;
800 u_char *p;
801 int i, m;
802 int hstatus;
803
804 hstatus = OREAD4(sc, OHCI_RH_STATUS);
805 DPRINTF(("ohci_rhsc: sc=%p reqh=%p hstatus=0x%08x\n",
806 sc, reqh, hstatus));
807
808 if (reqh == 0) {
809 /* Just ignore the change. */
810 return;
811 }
812
813 pipe = reqh->pipe;
814 opipe = (struct ohci_pipe *)pipe;
815
816 p = KERNADDR(&opipe->u.intr.datadma);
817 m = min(sc->sc_noport, reqh->length * 8 - 1);
818 memset(p, 0, reqh->length);
819 for (i = 1; i <= m; i++) {
820 if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16)
821 p[i/8] |= 1 << (i%8);
822 }
823 DPRINTF(("ohci_rhsc: change=0x%02x\n", *p));
824 reqh->actlen = reqh->length;
825 reqh->status = USBD_NORMAL_COMPLETION;
826 reqh->xfercb(reqh);
827
828 if (reqh->pipe->intrreqh != reqh) {
829 sc->sc_intrreqh = 0;
830 usb_freemem(sc->sc_dmatag, &opipe->u.intr.datadma);
831 }
832 }
833
834 /*
835 * Wait here until controller claims to have an interrupt.
836 * Then call ohci_intr and return. Use timeout to avoid waiting
837 * too long.
838 */
839 void
840 ohci_waitintr(sc, reqh)
841 ohci_softc_t *sc;
842 usbd_request_handle reqh;
843 {
844 int timo = reqh->timeout;
845 int usecs;
846 u_int32_t intrs;
847
848 reqh->status = USBD_IN_PROGRESS;
849 for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) {
850 delay(1000);
851 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs;
852 DPRINTFN(10,("ohci_waitintr: 0x%04x\n", intrs));
853 #ifdef USB_DEBUG
854 if (ohcidebug > 15)
855 ohci_dumpregs(sc);
856 #endif
857 if (intrs) {
858 ohci_intr(sc);
859 if (reqh->status != USBD_IN_PROGRESS)
860 return;
861 }
862 }
863 DPRINTF(("ohci_waitintr: timeout\n"));
864 reqh->status = USBD_TIMEOUT;
865 reqh->xfercb(reqh);
866 }
867
868 void
869 ohci_poll(bus)
870 struct usbd_bus *bus;
871 {
872 ohci_softc_t *sc = (ohci_softc_t *)bus;
873
874 if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs)
875 ohci_intr(sc);
876 }
877
878 usbd_status
879 ohci_device_request(reqh)
880 usbd_request_handle reqh;
881 {
882 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
883 usb_device_request_t *req = &reqh->request;
884 usbd_device_handle dev = opipe->pipe.device;
885 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
886 int addr = dev->address;
887 ohci_soft_td_t *setup, *xfer = 0, *stat, *next, *tail;
888 ohci_soft_ed_t *sed;
889 usb_dma_t *dmap;
890 int isread;
891 int len;
892 usbd_status r;
893 int s;
894
895 isread = req->bmRequestType & UT_READ;
896 len = UGETW(req->wLength);
897
898 DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, "
899 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
900 req->bmRequestType, req->bRequest, UGETW(req->wValue),
901 UGETW(req->wIndex), len, addr,
902 opipe->pipe.endpoint->edesc->bEndpointAddress));
903
904 setup = opipe->tail;
905 stat = ohci_alloc_std(sc);
906 if (!stat) {
907 r = USBD_NOMEM;
908 goto bad1;
909 }
910 tail = ohci_alloc_std(sc);
911 if (!tail) {
912 r = USBD_NOMEM;
913 goto bad2;
914 }
915 tail->reqh = 0;
916
917 sed = opipe->sed;
918 dmap = &opipe->u.ctl.datadma;
919 opipe->u.ctl.length = len;
920
921 /* Update device address and length since they may have changed. */
922 /* XXX This only needs to be done once, but it's too early in open. */
923 sed->ed->ed_flags =
924 (sed->ed->ed_flags & ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) |
925 OHCI_ED_SET_FA(addr) |
926 OHCI_ED_SET_MAXP(UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize));
927
928 /* Set up data transaction */
929 if (len != 0) {
930 xfer = ohci_alloc_std(sc);
931 if (!xfer) {
932 r = USBD_NOMEM;
933 goto bad3;
934 }
935 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
936 if (r != USBD_NORMAL_COMPLETION)
937 goto bad4;
938 xfer->td->td_flags =
939 (isread ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC |
940 OHCI_TD_TOGGLE_1 | OHCI_TD_NOINTR;
941 xfer->td->td_cbp = DMAADDR(dmap);
942 xfer->nexttd = stat;
943 xfer->td->td_nexttd = stat->physaddr;
944 xfer->td->td_be = xfer->td->td_cbp + len - 1;
945 xfer->len = len;
946 xfer->reqh = reqh;
947
948 next = xfer;
949 } else
950 next = stat;
951
952 memcpy(KERNADDR(&opipe->u.ctl.reqdma), req, sizeof *req);
953 if (!isread && len != 0)
954 memcpy(KERNADDR(dmap), reqh->buffer, len);
955
956 setup->td->td_flags = OHCI_TD_SETUP | OHCI_TD_NOCC |
957 OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR;
958 setup->td->td_cbp = DMAADDR(&opipe->u.ctl.reqdma);
959 setup->nexttd = next;
960 setup->td->td_nexttd = next->physaddr;
961 setup->td->td_be = setup->td->td_cbp + sizeof *req - 1;
962 setup->len = 0; /* XXX The number of byte we count */
963 setup->reqh = reqh;
964
965 stat->td->td_flags =
966 (isread ? OHCI_TD_OUT : OHCI_TD_IN) | OHCI_TD_NOCC |
967 OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1);
968 stat->td->td_cbp = 0;
969 stat->nexttd = tail;
970 stat->td->td_nexttd = tail->physaddr;
971 stat->td->td_be = 0;
972 stat->len = 0;
973 stat->reqh = reqh;
974
975 reqh->actlen = 0;
976 reqh->hcpriv = stat;
977
978 #if USB_DEBUG
979 if (ohcidebug > 5) {
980 printf("ohci_device_request:\n");
981 ohci_dump_ed(sed);
982 ohci_dump_tds(setup);
983 }
984 #endif
985
986 /* Insert ED in schedule */
987 s = splusb();
988 ohci_hash_add_td(sc, setup);
989 if (len != 0)
990 ohci_hash_add_td(sc, xfer);
991 ohci_hash_add_td(sc, stat);
992 sed->ed->ed_tailp = tail->physaddr;
993 opipe->tail = tail;
994 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
995 if (reqh->timeout && !sc->sc_bus.use_polling)
996 timeout(ohci_timeout, reqh, MS_TO_TICKS(reqh->timeout));
997 splx(s);
998
999 #if USB_DEBUG
1000 if (ohcidebug > 5) {
1001 delay(5000);
1002 printf("ohci_device_request: status=%x\n",
1003 OREAD4(sc, OHCI_COMMAND_STATUS));
1004 ohci_dump_ed(sed);
1005 ohci_dump_tds(setup);
1006 }
1007 #endif
1008
1009 return (USBD_NORMAL_COMPLETION);
1010
1011 bad4:
1012 ohci_free_std(sc, xfer);
1013 bad3:
1014 ohci_free_std(sc, tail);
1015 bad2:
1016 ohci_free_std(sc, stat);
1017 bad1:
1018 return (r);
1019 }
1020
1021 /*
1022 * Add an ED to the schedule. Called at splusb().
1023 */
1024 void
1025 ohci_add_ed(sed, head)
1026 ohci_soft_ed_t *sed;
1027 ohci_soft_ed_t *head;
1028 {
1029 sed->next = head->next;
1030 sed->ed->ed_nexted = head->ed->ed_nexted;
1031 head->next = sed;
1032 head->ed->ed_nexted = sed->physaddr;
1033 }
1034
1035 /*
1036 * Remove an ED from the schedule. Called at splusb().
1037 */
1038 void
1039 ohci_rem_ed(sed, head)
1040 ohci_soft_ed_t *sed;
1041 ohci_soft_ed_t *head;
1042 {
1043 ohci_soft_ed_t *p;
1044
1045 /* XXX */
1046 for (p = head; p && p->next != sed; p = p->next)
1047 ;
1048 if (!p)
1049 panic("ohci_rem_ed: ED not found\n");
1050 p->next = sed->next;
1051 p->ed->ed_nexted = sed->ed->ed_nexted;
1052 }
1053
1054 /*
1055 * When a transfer is completed the TD is added to the done queue by
1056 * the host controller. This queue is the processed by software.
1057 * Unfortunately the queue contains the physical address of the TD
1058 * and we have no simple way to translate this back to a kernel address.
1059 * To make the translation possible (and fast) we use a hash table of
1060 * TDs currently in the schedule. The physical address is used as the
1061 * hash value.
1062 */
1063
1064 #define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE)
1065 /* Called at splusb() */
1066 void
1067 ohci_hash_add_td(sc, std)
1068 ohci_softc_t *sc;
1069 ohci_soft_td_t *std;
1070 {
1071 int h = HASH(std->physaddr);
1072
1073 LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
1074 }
1075
1076 /* Called at splusb() */
1077 void
1078 ohci_hash_rem_td(sc, std)
1079 ohci_softc_t *sc;
1080 ohci_soft_td_t *std;
1081 {
1082 LIST_REMOVE(std, hnext);
1083 }
1084
1085 ohci_soft_td_t *
1086 ohci_hash_find_td(sc, a)
1087 ohci_softc_t *sc;
1088 ohci_physaddr_t a;
1089 {
1090 int h = HASH(a);
1091 ohci_soft_td_t *std;
1092
1093 for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
1094 std != 0;
1095 std = LIST_NEXT(std, hnext))
1096 if (std->physaddr == a)
1097 return (std);
1098 panic("ohci_hash_find_td: addr 0x%08lx not found\n", (u_long)a);
1099 }
1100
1101 void
1102 ohci_timeout(addr)
1103 void *addr;
1104 {
1105 #if 0
1106 usbd_request_handle *reqh = addr;
1107 int s;
1108
1109 DPRINTF(("ohci_timeout: reqh=%p\n", reqh));
1110 s = splusb();
1111 /* XXX need to inactivate TD before calling interrupt routine */
1112 ohci_XXX_done(reqh);
1113 splx(s);
1114 #endif
1115 }
1116
1117 #ifdef USB_DEBUG
1118 void
1119 ohci_dump_tds(std)
1120 ohci_soft_td_t *std;
1121 {
1122 for (; std; std = std->nexttd)
1123 ohci_dump_td(std);
1124 }
1125
1126 void
1127 ohci_dump_td(std)
1128 ohci_soft_td_t *std;
1129 {
1130 printf("TD(%p) at %08lx: %b delay=%d ec=%d cc=%d\ncbp=0x%08lx "
1131 "nexttd=0x%08lx be=0x%08lx\n",
1132 std, (u_long)std->physaddr,
1133 (u_long)std->td->td_flags,
1134 "\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE",
1135 OHCI_TD_GET_DI(std->td->td_flags),
1136 OHCI_TD_GET_EC(std->td->td_flags),
1137 OHCI_TD_GET_CC(std->td->td_flags),
1138 (u_long)std->td->td_cbp,
1139 (u_long)std->td->td_nexttd, (u_long)std->td->td_be);
1140 }
1141
1142 void
1143 ohci_dump_ed(sed)
1144 ohci_soft_ed_t *sed;
1145 {
1146 printf("ED(%p) at %08lx: addr=%d endpt=%d maxp=%d %b\ntailp=0x%08lx "
1147 "headp=%b nexted=0x%08lx\n",
1148 sed, (u_long)sed->physaddr,
1149 OHCI_ED_GET_FA(sed->ed->ed_flags),
1150 OHCI_ED_GET_EN(sed->ed->ed_flags),
1151 OHCI_ED_GET_MAXP(sed->ed->ed_flags),
1152 (u_long)sed->ed->ed_flags,
1153 "\20\14OUT\15IN\16LOWSPEED\17SKIP\18ISO",
1154 (u_long)sed->ed->ed_tailp,
1155 (u_long)sed->ed->ed_headp, "\20\1HALT\2CARRY",
1156 (u_long)sed->ed->ed_nexted);
1157 }
1158 #endif
1159
1160 usbd_status
1161 ohci_open(pipe)
1162 usbd_pipe_handle pipe;
1163 {
1164 usbd_device_handle dev = pipe->device;
1165 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
1166 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
1167 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
1168 u_int8_t addr = dev->address;
1169 ohci_soft_ed_t *sed;
1170 ohci_soft_td_t *std;
1171 usbd_status r;
1172 int s;
1173
1174 DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
1175 pipe, addr, ed->bEndpointAddress, sc->sc_addr));
1176 if (addr == sc->sc_addr) {
1177 switch (ed->bEndpointAddress) {
1178 case USB_CONTROL_ENDPOINT:
1179 pipe->methods = &ohci_root_ctrl_methods;
1180 break;
1181 case UE_IN | OHCI_INTR_ENDPT:
1182 pipe->methods = &ohci_root_intr_methods;
1183 break;
1184 default:
1185 return (USBD_INVAL);
1186 }
1187 } else {
1188 sed = ohci_alloc_sed(sc);
1189 if (sed == 0)
1190 goto bad0;
1191 std = ohci_alloc_std(sc);
1192 if (std == 0)
1193 goto bad1;
1194 opipe->sed = sed;
1195 opipe->tail = std;
1196 sed->ed->ed_flags =
1197 OHCI_ED_SET_FA(addr) |
1198 OHCI_ED_SET_EN(ed->bEndpointAddress) |
1199 OHCI_ED_DIR_TD |
1200 (dev->lowspeed ? OHCI_ED_SPEED : 0) |
1201 ((ed->bmAttributes & UE_XFERTYPE) == UE_ISOCHRONOUS ?
1202 OHCI_ED_FORMAT_ISO : OHCI_ED_FORMAT_GEN) |
1203 OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize));
1204 sed->ed->ed_headp = sed->ed->ed_tailp = std->physaddr;
1205
1206 switch (ed->bmAttributes & UE_XFERTYPE) {
1207 case UE_CONTROL:
1208 pipe->methods = &ohci_device_ctrl_methods;
1209 r = usb_allocmem(sc->sc_dmatag,
1210 sizeof(usb_device_request_t),
1211 0, &opipe->u.ctl.reqdma);
1212 if (r != USBD_NORMAL_COMPLETION)
1213 goto bad;
1214 s = splusb();
1215 ohci_add_ed(sed, sc->sc_ctrl_head);
1216 splx(s);
1217 break;
1218 case UE_INTERRUPT:
1219 pipe->methods = &ohci_device_intr_methods;
1220 return (ohci_device_setintr(sc, opipe, ed->bInterval));
1221 case UE_ISOCHRONOUS:
1222 printf("ohci_open: open iso unimplemented\n");
1223 return (USBD_XXX);
1224 case UE_BULK:
1225 pipe->methods = &ohci_device_bulk_methods;
1226 s = splusb();
1227 ohci_add_ed(sed, sc->sc_bulk_head);
1228 splx(s);
1229 break;
1230 }
1231 }
1232 return (USBD_NORMAL_COMPLETION);
1233
1234 bad:
1235 ohci_free_std(sc, std);
1236 bad1:
1237 ohci_free_sed(sc, sed);
1238 bad0:
1239 return (USBD_NOMEM);
1240
1241 }
1242
1243 /*
1244 * Data structures and routines to emulate the root hub.
1245 */
1246 usb_device_descriptor_t ohci_devd = {
1247 USB_DEVICE_DESCRIPTOR_SIZE,
1248 UDESC_DEVICE, /* type */
1249 {0x00, 0x01}, /* USB version */
1250 UCLASS_HUB, /* class */
1251 USUBCLASS_HUB, /* subclass */
1252 0, /* protocol */
1253 64, /* max packet */
1254 {0},{0},{0x00,0x01}, /* device id */
1255 1,2,0, /* string indicies */
1256 1 /* # of configurations */
1257 };
1258
1259 usb_config_descriptor_t ohci_confd = {
1260 USB_CONFIG_DESCRIPTOR_SIZE,
1261 UDESC_CONFIG,
1262 {USB_CONFIG_DESCRIPTOR_SIZE +
1263 USB_INTERFACE_DESCRIPTOR_SIZE +
1264 USB_ENDPOINT_DESCRIPTOR_SIZE},
1265 1,
1266 1,
1267 0,
1268 UC_SELF_POWERED,
1269 0 /* max power */
1270 };
1271
1272 usb_interface_descriptor_t ohci_ifcd = {
1273 USB_INTERFACE_DESCRIPTOR_SIZE,
1274 UDESC_INTERFACE,
1275 0,
1276 0,
1277 1,
1278 UCLASS_HUB,
1279 USUBCLASS_HUB,
1280 0,
1281 0
1282 };
1283
1284 usb_endpoint_descriptor_t ohci_endpd = {
1285 USB_ENDPOINT_DESCRIPTOR_SIZE,
1286 UDESC_ENDPOINT,
1287 UE_IN | OHCI_INTR_ENDPT,
1288 UE_INTERRUPT,
1289 {8, 0}, /* max packet */
1290 255
1291 };
1292
1293 usb_hub_descriptor_t ohci_hubd = {
1294 USB_HUB_DESCRIPTOR_SIZE,
1295 UDESC_HUB,
1296 0,
1297 {0,0},
1298 0,
1299 0,
1300 {0},
1301 {0},
1302 };
1303
1304 int
1305 ohci_str(p, l, s)
1306 usb_string_descriptor_t *p;
1307 int l;
1308 char *s;
1309 {
1310 int i;
1311
1312 if (l == 0)
1313 return (0);
1314 p->bLength = 2 * strlen(s) + 2;
1315 if (l == 1)
1316 return (1);
1317 p->bDescriptorType = UDESC_STRING;
1318 l -= 2;
1319 for (i = 0; s[i] && l > 1; i++, l -= 2)
1320 USETW2(p->bString[i], 0, s[i]);
1321 return (2*i+2);
1322 }
1323
1324 /*
1325 * Simulate a hardware hub by handling all the necessary requests.
1326 */
1327 usbd_status
1328 ohci_root_ctrl_transfer(reqh)
1329 usbd_request_handle reqh;
1330 {
1331 ohci_softc_t *sc = (ohci_softc_t *)reqh->pipe->device->bus;
1332 usb_device_request_t *req;
1333 void *buf;
1334 int port, i;
1335 int len, value, index, l, totlen = 0;
1336 usb_port_status_t ps;
1337 usb_hub_descriptor_t hubd;
1338 usbd_status r;
1339 u_int32_t v;
1340
1341 if (!reqh->isreq)
1342 /* XXX panic */
1343 return (USBD_INVAL);
1344 req = &reqh->request;
1345 buf = reqh->buffer;
1346
1347 DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n",
1348 req->bmRequestType, req->bRequest));
1349
1350 len = UGETW(req->wLength);
1351 value = UGETW(req->wValue);
1352 index = UGETW(req->wIndex);
1353 #define C(x,y) ((x) | ((y) << 8))
1354 switch(C(req->bRequest, req->bmRequestType)) {
1355 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
1356 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
1357 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
1358 /*
1359 * DEVICE_REMOTE_WAKEUP and ENDPOINT_STALL are no-ops
1360 * for the integrated root hub.
1361 */
1362 break;
1363 case C(UR_GET_CONFIG, UT_READ_DEVICE):
1364 if (len > 0) {
1365 *(u_int8_t *)buf = sc->sc_conf;
1366 totlen = 1;
1367 }
1368 break;
1369 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
1370 DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value));
1371 switch(value >> 8) {
1372 case UDESC_DEVICE:
1373 if ((value & 0xff) != 0) {
1374 r = USBD_IOERROR;
1375 goto ret;
1376 }
1377 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
1378 memcpy(buf, &ohci_devd, l);
1379 break;
1380 case UDESC_CONFIG:
1381 if ((value & 0xff) != 0) {
1382 r = USBD_IOERROR;
1383 goto ret;
1384 }
1385 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
1386 memcpy(buf, &ohci_confd, l);
1387 buf = (char *)buf + l;
1388 len -= l;
1389 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
1390 totlen += l;
1391 memcpy(buf, &ohci_ifcd, l);
1392 buf = (char *)buf + l;
1393 len -= l;
1394 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
1395 totlen += l;
1396 memcpy(buf, &ohci_endpd, l);
1397 break;
1398 case UDESC_STRING:
1399 if (len == 0)
1400 break;
1401 *(u_int8_t *)buf = 0;
1402 totlen = 1;
1403 switch (value & 0xff) {
1404 case 1: /* Vendor */
1405 totlen = ohci_str(buf, len, sc->sc_vendor);
1406 break;
1407 case 2: /* Product */
1408 totlen = ohci_str(buf, len, "OHCI root hub");
1409 break;
1410 }
1411 break;
1412 default:
1413 r = USBD_IOERROR;
1414 goto ret;
1415 }
1416 break;
1417 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
1418 if (len > 0) {
1419 *(u_int8_t *)buf = 0;
1420 totlen = 1;
1421 }
1422 break;
1423 case C(UR_GET_STATUS, UT_READ_DEVICE):
1424 if (len > 1) {
1425 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
1426 totlen = 2;
1427 }
1428 break;
1429 case C(UR_GET_STATUS, UT_READ_INTERFACE):
1430 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
1431 if (len > 1) {
1432 USETW(((usb_status_t *)buf)->wStatus, 0);
1433 totlen = 2;
1434 }
1435 break;
1436 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
1437 if (value >= USB_MAX_DEVICES) {
1438 r = USBD_IOERROR;
1439 goto ret;
1440 }
1441 sc->sc_addr = value;
1442 break;
1443 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
1444 if (value != 0 && value != 1) {
1445 r = USBD_IOERROR;
1446 goto ret;
1447 }
1448 sc->sc_conf = value;
1449 break;
1450 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
1451 break;
1452 case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
1453 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
1454 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
1455 r = USBD_IOERROR;
1456 goto ret;
1457 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
1458 break;
1459 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
1460 break;
1461 /* Hub requests */
1462 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
1463 break;
1464 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
1465 DPRINTFN(8, ("ohci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
1466 "port=%d feature=%d\n",
1467 index, value));
1468 if (index < 1 || index > sc->sc_noport) {
1469 r = USBD_IOERROR;
1470 goto ret;
1471 }
1472 port = OHCI_RH_PORT_STATUS(index);
1473 switch(value) {
1474 case UHF_PORT_ENABLE:
1475 OWRITE4(sc, port, UPS_CURRENT_CONNECT_STATUS);
1476 break;
1477 case UHF_PORT_SUSPEND:
1478 OWRITE4(sc, port, UPS_OVERCURRENT_INDICATOR);
1479 break;
1480 case UHF_PORT_POWER:
1481 OWRITE4(sc, port, UPS_LOW_SPEED);
1482 break;
1483 case UHF_C_PORT_CONNECTION:
1484 OWRITE4(sc, port, UPS_C_CONNECT_STATUS << 16);
1485 break;
1486 case UHF_C_PORT_ENABLE:
1487 OWRITE4(sc, port, UPS_C_PORT_ENABLED << 16);
1488 break;
1489 case UHF_C_PORT_SUSPEND:
1490 OWRITE4(sc, port, UPS_C_SUSPEND << 16);
1491 break;
1492 case UHF_C_PORT_OVER_CURRENT:
1493 OWRITE4(sc, port, UPS_C_OVERCURRENT_INDICATOR << 16);
1494 break;
1495 case UHF_C_PORT_RESET:
1496 OWRITE4(sc, port, UPS_C_PORT_RESET << 16);
1497 break;
1498 default:
1499 r = USBD_IOERROR;
1500 goto ret;
1501 }
1502 switch(value) {
1503 case UHF_C_PORT_CONNECTION:
1504 case UHF_C_PORT_ENABLE:
1505 case UHF_C_PORT_SUSPEND:
1506 case UHF_C_PORT_OVER_CURRENT:
1507 case UHF_C_PORT_RESET:
1508 /* Enable RHSC interrupt if condition is cleared. */
1509 if ((OREAD4(sc, port) >> 16) == 0)
1510 ohci_rhsc_able(sc, 1);
1511 break;
1512 default:
1513 break;
1514 }
1515 break;
1516 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
1517 if (value != 0) {
1518 r = USBD_IOERROR;
1519 goto ret;
1520 }
1521 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
1522 hubd = ohci_hubd;
1523 hubd.bNbrPorts = sc->sc_noport;
1524 USETW(hubd.bHubCharacteristics,
1525 (v & OHCI_NPS ? UHD_PWR_NO_SWITCH :
1526 v & OHCI_PSM ? UHD_PWR_GANGED : UHD_PWR_INDIVIDUAL)
1527 /* XXX overcurrent */
1528 );
1529 hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v);
1530 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
1531 if (sc->sc_noport < 8) {
1532 hubd.DeviceRemovable[0] = (u_int8_t)v;
1533 hubd.PortPowerCtrlMask[0] = (u_int8_t)(v >> 16);
1534 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE;
1535 } else {
1536 hubd.DeviceRemovable[0] = (u_int8_t)v;
1537 hubd.DeviceRemovable[1] = (u_int8_t)(v>>8);
1538 hubd.PortPowerCtrlMask[1] = (u_int8_t)(v >> 16);
1539 hubd.PortPowerCtrlMask[2] = (u_int8_t)(v >> 24);
1540 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + 2;
1541 }
1542 l = min(len, hubd.bDescLength);
1543 totlen = l;
1544 memcpy(buf, &hubd, l);
1545 break;
1546 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
1547 if (len != 4) {
1548 r = USBD_IOERROR;
1549 goto ret;
1550 }
1551 memset(buf, 0, len); /* ? XXX */
1552 totlen = len;
1553 break;
1554 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
1555 DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n",
1556 index));
1557 if (index < 1 || index > sc->sc_noport) {
1558 r = USBD_IOERROR;
1559 goto ret;
1560 }
1561 if (len != 4) {
1562 r = USBD_IOERROR;
1563 goto ret;
1564 }
1565 v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
1566 DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n",
1567 v));
1568 USETW(ps.wPortStatus, v);
1569 USETW(ps.wPortChange, v >> 16);
1570 l = min(len, sizeof ps);
1571 memcpy(buf, &ps, l);
1572 totlen = l;
1573 break;
1574 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
1575 r = USBD_IOERROR;
1576 goto ret;
1577 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
1578 break;
1579 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
1580 if (index < 1 || index > sc->sc_noport) {
1581 r = USBD_IOERROR;
1582 goto ret;
1583 }
1584 port = OHCI_RH_PORT_STATUS(index);
1585 switch(value) {
1586 case UHF_PORT_ENABLE:
1587 OWRITE4(sc, port, UPS_PORT_ENABLED);
1588 break;
1589 case UHF_PORT_SUSPEND:
1590 OWRITE4(sc, port, UPS_SUSPEND);
1591 break;
1592 case UHF_PORT_RESET:
1593 DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n",
1594 index));
1595 OWRITE4(sc, port, UPS_RESET);
1596 for (i = 0; i < 10; i++) {
1597 usbd_delay_ms(&sc->sc_bus, 10);
1598 if ((OREAD4(sc, port) & UPS_RESET) == 0)
1599 break;
1600 }
1601 DPRINTFN(8,("ohci port %d reset, status = 0x%04x\n",
1602 index, OREAD4(sc, port)));
1603 break;
1604 case UHF_PORT_POWER:
1605 DPRINTFN(2,("ohci_root_ctrl_transfer: set port power "
1606 "%d\n", index));
1607 OWRITE4(sc, port, UPS_PORT_POWER);
1608 break;
1609 default:
1610 r = USBD_IOERROR;
1611 goto ret;
1612 }
1613 break;
1614 default:
1615 r = USBD_IOERROR;
1616 goto ret;
1617 }
1618 reqh->actlen = totlen;
1619 r = USBD_NORMAL_COMPLETION;
1620 ret:
1621 reqh->status = r;
1622 reqh->xfercb(reqh);
1623 return (USBD_IN_PROGRESS);
1624 }
1625
1626 /* Abort a root control request. */
1627 void
1628 ohci_root_ctrl_abort(reqh)
1629 usbd_request_handle reqh;
1630 {
1631 /* Nothing to do, all transfers are synchronous. */
1632 }
1633
1634 /* Close the root pipe. */
1635 void
1636 ohci_root_ctrl_close(pipe)
1637 usbd_pipe_handle pipe;
1638 {
1639 DPRINTF(("ohci_root_ctrl_close\n"));
1640 }
1641
1642 usbd_status
1643 ohci_root_intr_transfer(reqh)
1644 usbd_request_handle reqh;
1645 {
1646 usbd_pipe_handle pipe = reqh->pipe;
1647 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
1648 struct ohci_pipe *upipe = (struct ohci_pipe *)pipe;
1649 usb_dma_t *dmap;
1650 usbd_status r;
1651 int len;
1652
1653 len = reqh->length;
1654 dmap = &upipe->u.intr.datadma;
1655 if (len == 0)
1656 return (USBD_INVAL); /* XXX should it be? */
1657
1658 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1659 if (r != USBD_NORMAL_COMPLETION)
1660 return (r);
1661 sc->sc_intrreqh = reqh;
1662
1663 return (USBD_IN_PROGRESS);
1664 }
1665
1666 /* Abort a root interrupt request. */
1667 void
1668 ohci_root_intr_abort(reqh)
1669 usbd_request_handle reqh;
1670 {
1671 /* No need to abort. */
1672 }
1673
1674 /* Close the root pipe. */
1675 void
1676 ohci_root_intr_close(pipe)
1677 usbd_pipe_handle pipe;
1678 {
1679 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
1680 sc->sc_intrreqh = 0;
1681
1682 DPRINTF(("ohci_root_intr_close\n"));
1683 }
1684
1685 /************************/
1686
1687 usbd_status
1688 ohci_device_ctrl_transfer(reqh)
1689 usbd_request_handle reqh;
1690 {
1691 ohci_softc_t *sc = (ohci_softc_t *)reqh->pipe->device->bus;
1692 usbd_status r;
1693
1694 if (!reqh->isreq) {
1695 /* XXX panic */
1696 printf("ohci_device_ctrl_transfer: not a request\n");
1697 return (USBD_INVAL);
1698 }
1699
1700 r = ohci_device_request(reqh);
1701 if (r != USBD_NORMAL_COMPLETION)
1702 return (r);
1703
1704 if (sc->sc_bus.use_polling)
1705 ohci_waitintr(sc, reqh);
1706 return (USBD_IN_PROGRESS);
1707 }
1708
1709 /* Abort a device control request. */
1710 void
1711 ohci_device_ctrl_abort(reqh)
1712 usbd_request_handle reqh;
1713 {
1714 /* XXX inactivate */
1715 usbd_delay_ms(reqh->pipe->device->bus, 1); /* make sure it is donw */
1716 /* XXX call done */
1717 }
1718
1719 /* Close a device control pipe. */
1720 void
1721 ohci_device_ctrl_close(pipe)
1722 usbd_pipe_handle pipe;
1723 {
1724 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
1725 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
1726 ohci_soft_ed_t *sed = opipe->sed;
1727 int s;
1728
1729 s = splusb();
1730 sed->ed->ed_flags |= OHCI_ED_SKIP;
1731 if ((sed->ed->ed_tailp & OHCI_TAILMASK) != sed->ed->ed_headp)
1732 usbd_delay_ms(&sc->sc_bus, 2);
1733 ohci_rem_ed(sed, sc->sc_ctrl_head);
1734 splx(s);
1735 ohci_free_std(sc, opipe->tail);
1736 ohci_free_sed(sc, opipe->sed);
1737 /* XXX free other resources */
1738 }
1739
1740 /************************/
1741
1742 usbd_status
1743 ohci_device_bulk_transfer(reqh)
1744 usbd_request_handle reqh;
1745 {
1746 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
1747 usbd_device_handle dev = opipe->pipe.device;
1748 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
1749 int addr = dev->address;
1750 ohci_soft_td_t *xfer, *tail;
1751 ohci_soft_ed_t *sed;
1752 usb_dma_t *dmap;
1753 usbd_status r;
1754 int s, len, isread;
1755
1756 if (reqh->isreq) {
1757 /* XXX panic */
1758 printf("ohci_device_bulk_transfer: a request\n");
1759 return (USBD_INVAL);
1760 }
1761
1762 len = reqh->length;
1763 dmap = &opipe->u.bulk.datadma;
1764 isread = reqh->pipe->endpoint->edesc->bEndpointAddress & UE_IN;
1765 sed = opipe->sed;
1766
1767 opipe->u.bulk.length = len;
1768
1769 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1770 if (r != USBD_NORMAL_COMPLETION)
1771 goto ret1;
1772
1773 tail = ohci_alloc_std(sc);
1774 if (!tail) {
1775 r = USBD_NOMEM;
1776 goto ret2;
1777 }
1778 tail->reqh = 0;
1779
1780 /* Update device address */
1781 sed->ed->ed_flags =
1782 (sed->ed->ed_flags & ~OHCI_ED_ADDRMASK) |
1783 OHCI_ED_SET_FA(addr);
1784
1785 /* Set up data transaction */
1786 xfer = opipe->tail;
1787 xfer->td->td_flags =
1788 (isread ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC |
1789 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY;
1790 xfer->td->td_cbp = DMAADDR(dmap);
1791 xfer->nexttd = tail;
1792 xfer->td->td_nexttd = tail->physaddr;
1793 xfer->td->td_be = xfer->td->td_cbp + len - 1;
1794 xfer->len = len;
1795 xfer->reqh = reqh;
1796
1797 reqh->actlen = 0;
1798 reqh->hcpriv = xfer;
1799
1800 if (!isread)
1801 memcpy(KERNADDR(dmap), reqh->buffer, len);
1802
1803 /* Insert ED in schedule */
1804 s = splusb();
1805 ohci_hash_add_td(sc, xfer);
1806 sed->ed->ed_tailp = tail->physaddr;
1807 opipe->tail = tail;
1808 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
1809 if (reqh->timeout && !sc->sc_bus.use_polling)
1810 timeout(ohci_timeout, reqh, MS_TO_TICKS(reqh->timeout));
1811 splx(s);
1812
1813 return (USBD_IN_PROGRESS);
1814
1815 ret2:
1816 usb_freemem(sc->sc_dmatag, dmap);
1817 ret1:
1818 return (r);
1819 }
1820
1821 /* Abort a device bulk request. */
1822 void
1823 ohci_device_bulk_abort(reqh)
1824 usbd_request_handle reqh;
1825 {
1826 #if 0
1827 sed->ed->ed_flags |= OHCI_ED_SKIP;
1828 if ((sed->ed->ed_tailp & OHCI_TAILMASK) != sed->ed->ed_headp)
1829 usbd_delay_ms(reqh->pipe->device->bus, 2);
1830 #endif
1831 /* XXX inactivate */
1832 usbd_delay_ms(reqh->pipe->device->bus, 1); /* make sure it is done */
1833 /* XXX call done */
1834 }
1835
1836 /* Close a device bulk pipe. */
1837 void
1838 ohci_device_bulk_close(pipe)
1839 usbd_pipe_handle pipe;
1840 {
1841 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
1842 usbd_device_handle dev = opipe->pipe.device;
1843 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
1844 int s;
1845
1846 s = splusb();
1847 ohci_rem_ed(opipe->sed, sc->sc_bulk_head);
1848 splx(s);
1849 ohci_free_std(sc, opipe->tail);
1850 ohci_free_sed(sc, opipe->sed);
1851 /* XXX free other resources */
1852 }
1853
1854 /************************/
1855
1856 usbd_status
1857 ohci_device_intr_transfer(reqh)
1858 usbd_request_handle reqh;
1859 {
1860 struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
1861 usbd_device_handle dev = opipe->pipe.device;
1862 ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
1863 ohci_soft_ed_t *sed = opipe->sed;
1864 ohci_soft_td_t *xfer, *tail;
1865 usb_dma_t *dmap;
1866 usbd_status r;
1867 int len;
1868 int s;
1869
1870 DPRINTFN(3, ("ohci_device_intr_transfer: reqh=%p buf=%p len=%d "
1871 "flags=%d priv=%p\n",
1872 reqh, reqh->buffer, reqh->length, reqh->flags, reqh->priv));
1873
1874 if (reqh->isreq)
1875 panic("ohci_device_intr_transfer: a request\n");
1876
1877 len = reqh->length;
1878 dmap = &opipe->u.intr.datadma;
1879 if (len == 0)
1880 return (USBD_INVAL); /* XXX should it be? */
1881
1882 xfer = opipe->tail;
1883 tail = ohci_alloc_std(sc);
1884 if (!tail) {
1885 r = USBD_NOMEM;
1886 goto ret1;
1887 }
1888 tail->reqh = 0;
1889
1890 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1891 if (r != USBD_NORMAL_COMPLETION)
1892 goto ret2;
1893
1894 xfer->td->td_flags = OHCI_TD_IN | OHCI_TD_NOCC |
1895 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY;
1896 xfer->td->td_cbp = DMAADDR(dmap);
1897 xfer->nexttd = tail;
1898 xfer->td->td_nexttd = tail->physaddr;
1899 xfer->td->td_be = xfer->td->td_cbp + len - 1;
1900 xfer->len = len;
1901 xfer->reqh = reqh;
1902
1903 reqh->actlen = 0;
1904 reqh->hcpriv = xfer;
1905
1906 #if USB_DEBUG
1907 if (ohcidebug > 5) {
1908 printf("ohci_device_intr_transfer:\n");
1909 ohci_dump_ed(sed);
1910 ohci_dump_tds(xfer);
1911 }
1912 #endif
1913
1914 /* Insert ED in schedule */
1915 s = splusb();
1916 ohci_hash_add_td(sc, xfer);
1917 sed->ed->ed_tailp = tail->physaddr;
1918 opipe->tail = tail;
1919 #if 0
1920 if (reqh->timeout && !sc->sc_bus.use_polling)
1921 timeout(ohci_timeout, reqh, MS_TO_TICKS(reqh->timeout));
1922 #endif
1923 sed->ed->ed_flags &= ~OHCI_ED_SKIP;
1924 splx(s);
1925
1926 #ifdef USB_DEBUG
1927 if (ohcidebug > 5) {
1928 delay(5000);
1929 printf("ohci_device_intr_transfer: status=%x\n",
1930 OREAD4(sc, OHCI_COMMAND_STATUS));
1931 ohci_dump_ed(sed);
1932 ohci_dump_tds(xfer);
1933 }
1934 #endif
1935
1936 return (USBD_IN_PROGRESS);
1937
1938 ret2:
1939 ohci_free_std(sc, xfer);
1940 ret1:
1941 return (r);
1942 }
1943
1944 /* Abort a device control request. */
1945 void
1946 ohci_device_intr_abort(reqh)
1947 usbd_request_handle reqh;
1948 {
1949 /* XXX inactivate */
1950 usbd_delay_ms(reqh->pipe->device->bus, 1); /* make sure it is done */
1951 if (reqh->pipe->intrreqh == reqh) {
1952 DPRINTF(("ohci_device_intr_abort: remove\n"));
1953 reqh->pipe->intrreqh = 0;
1954 ohci_intr_done((ohci_softc_t *)reqh->pipe->device->bus, reqh);
1955 }
1956 }
1957
1958 /* Close a device interrupt pipe. */
1959 void
1960 ohci_device_intr_close(pipe)
1961 usbd_pipe_handle pipe;
1962 {
1963 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
1964 ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
1965 int nslots = opipe->u.intr.nslots;
1966 int pos = opipe->u.intr.pos;
1967 int j;
1968 ohci_soft_ed_t *p, *sed = opipe->sed;
1969 int s;
1970
1971 DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n",
1972 pipe, nslots, pos));
1973 s = splusb();
1974 sed->ed->ed_flags |= OHCI_ED_SKIP;
1975 if ((sed->ed->ed_tailp & OHCI_TAILMASK) != sed->ed->ed_headp)
1976 usbd_delay_ms(&sc->sc_bus, 2);
1977
1978 for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
1979 ;
1980 if (!p)
1981 panic("ohci_device_intr_close: ED not found\n");
1982 p->next = sed->next;
1983 p->ed->ed_nexted = sed->ed->ed_nexted;
1984 splx(s);
1985
1986 for (j = 0; j < nslots; j++)
1987 --sc->sc_bws[pos * nslots + j];
1988
1989 ohci_free_std(sc, opipe->tail);
1990 ohci_free_sed(sc, opipe->sed);
1991 /* XXX free other resources */
1992 }
1993
1994 usbd_status
1995 ohci_device_setintr(sc, opipe, ival)
1996 ohci_softc_t *sc;
1997 struct ohci_pipe *opipe;
1998 int ival;
1999 {
2000 int i, j, s, best;
2001 u_int npoll, slow, shigh, nslots;
2002 u_int bestbw, bw;
2003 ohci_soft_ed_t *hsed, *sed = opipe->sed;
2004
2005 DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe));
2006 if (ival == 0) {
2007 printf("ohci_setintr: 0 interval\n");
2008 return (USBD_INVAL);
2009 }
2010
2011 npoll = OHCI_NO_INTRS;
2012 while (npoll > ival)
2013 npoll /= 2;
2014 DPRINTFN(2, ("ohci_setintr: ival=%d npoll=%d\n", ival, npoll));
2015
2016 /*
2017 * We now know which level in the tree the ED must go into.
2018 * Figure out which slot has most bandwidth left over.
2019 * Slots to examine:
2020 * npoll
2021 * 1 0
2022 * 2 1 2
2023 * 4 3 4 5 6
2024 * 8 7 8 9 10 11 12 13 14
2025 * N (N-1) .. (N-1+N-1)
2026 */
2027 slow = npoll-1;
2028 shigh = slow + npoll;
2029 nslots = OHCI_NO_INTRS / npoll;
2030 for (best = i = slow, bestbw = ~0; i < shigh; i++) {
2031 bw = 0;
2032 for (j = 0; j < nslots; j++)
2033 bw += sc->sc_bws[i * nslots + j];
2034 if (bw < bestbw) {
2035 best = i;
2036 bestbw = bw;
2037 }
2038 }
2039 DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n",
2040 best, slow, shigh, bestbw));
2041
2042 s = splusb();
2043 hsed = sc->sc_eds[best];
2044 sed->next = hsed->next;
2045 sed->ed->ed_nexted = hsed->ed->ed_nexted;
2046 hsed->next = sed;
2047 hsed->ed->ed_nexted = sed->physaddr;
2048 splx(s);
2049
2050 for (j = 0; j < nslots; j++)
2051 ++sc->sc_bws[best * nslots + j];
2052 opipe->u.intr.nslots = nslots;
2053 opipe->u.intr.pos = best;
2054
2055 DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe));
2056 return (USBD_NORMAL_COMPLETION);
2057 }
2058
2059