FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/ohci.c
1 /* $NetBSD: ohci.c,v 1.138 2003/02/08 03:32:50 ichiro Exp $ */
2
3 /* Also, already ported:
4 * $NetBSD: ohci.c,v 1.140 2003/05/13 04:42:00 gson Exp $
5 * $NetBSD: ohci.c,v 1.141 2003/09/10 20:08:29 mycroft Exp $
6 * $NetBSD: ohci.c,v 1.142 2003/10/11 03:04:26 toshii Exp $
7 * $NetBSD: ohci.c,v 1.143 2003/10/18 04:50:35 simonb Exp $
8 * $NetBSD: ohci.c,v 1.144 2003/11/23 19:18:06 augustss Exp $
9 * $NetBSD: ohci.c,v 1.145 2003/11/23 19:20:25 augustss Exp $
10 * $NetBSD: ohci.c,v 1.146 2003/12/29 08:17:10 toshii Exp $
11 * $NetBSD: ohci.c,v 1.147 2004/06/22 07:20:35 mycroft Exp $
12 * $NetBSD: ohci.c,v 1.148 2004/06/22 18:27:46 mycroft Exp $
13 */
14
15 #include <sys/cdefs.h>
16 __FBSDID("$FreeBSD: src/sys/dev/usb/ohci.c,v 1.173 2008/07/17 22:40:23 luoqi Exp $");
17
18 /*-
19 * Copyright (c) 1998 The NetBSD Foundation, Inc.
20 * All rights reserved.
21 *
22 * This code is derived from software contributed to The NetBSD Foundation
23 * by Lennart Augustsson (lennart@augustsson.net) at
24 * Carlstedt Research & Technology.
25 *
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
28 * are met:
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 * This product includes software developed by the NetBSD
37 * Foundation, Inc. and its contributors.
38 * 4. Neither the name of The NetBSD Foundation nor the names of its
39 * contributors may be used to endorse or promote products derived
40 * from this software without specific prior written permission.
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
43 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
44 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
45 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
46 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
47 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
48 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
49 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
50 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
52 * POSSIBILITY OF SUCH DAMAGE.
53 */
54
55 /*
56 * USB Open Host Controller driver.
57 *
58 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html
59 * USB spec: http://www.usb.org/developers/docs/usbspec.zip
60 */
61
62 #include <sys/param.h>
63 #include <sys/systm.h>
64 #include <sys/malloc.h>
65 #include <sys/kernel.h>
66 #include <sys/endian.h>
67 #include <sys/module.h>
68 #include <sys/bus.h>
69 #if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
70 #include <machine/cpu.h>
71 #endif
72 #include <sys/proc.h>
73 #include <sys/queue.h>
74 #include <sys/sysctl.h>
75
76 #include <machine/bus.h>
77 #include <machine/endian.h>
78
79 #include <dev/usb/usb.h>
80 #include <dev/usb/usbdi.h>
81 #include <dev/usb/usbdivar.h>
82 #include <dev/usb/usb_mem.h>
83 #include <dev/usb/usb_quirks.h>
84
85 #include <dev/usb/ohcireg.h>
86 #include <dev/usb/ohcivar.h>
87
88 #define delay(d) DELAY(d)
89
90 #ifdef USB_DEBUG
91 #define DPRINTF(x) if (ohcidebug) printf x
92 #define DPRINTFN(n,x) if (ohcidebug>(n)) printf x
93 int ohcidebug = 0;
94 SYSCTL_NODE(_hw_usb, OID_AUTO, ohci, CTLFLAG_RW, 0, "USB ohci");
95 SYSCTL_INT(_hw_usb_ohci, OID_AUTO, debug, CTLFLAG_RW,
96 &ohcidebug, 0, "ohci debug level");
97 #define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
98 #else
99 #define DPRINTF(x)
100 #define DPRINTFN(n,x)
101 #endif
102
103 struct ohci_pipe;
104
105 static ohci_soft_ed_t *ohci_alloc_sed(ohci_softc_t *);
106 static void ohci_free_sed(ohci_softc_t *, ohci_soft_ed_t *);
107
108 static ohci_soft_td_t *ohci_alloc_std(ohci_softc_t *);
109 static void ohci_free_std(ohci_softc_t *, ohci_soft_td_t *);
110
111 static ohci_soft_itd_t *ohci_alloc_sitd(ohci_softc_t *);
112 static void ohci_free_sitd(ohci_softc_t *,ohci_soft_itd_t *);
113
114 #if 0
115 static void ohci_free_std_chain(ohci_softc_t *, ohci_soft_td_t *,
116 ohci_soft_td_t *);
117 #endif
118 static usbd_status ohci_alloc_std_chain(struct ohci_pipe *,
119 ohci_softc_t *, int, int, usbd_xfer_handle,
120 ohci_soft_td_t *, ohci_soft_td_t **);
121
122 #if defined(__NetBSD__) || defined(__OpenBSD__)
123 static void ohci_shutdown(void *v);
124 static void ohci_power(int, void *);
125 #endif
126 static usbd_status ohci_open(usbd_pipe_handle);
127 static void ohci_poll(struct usbd_bus *);
128 static void ohci_softintr(void *);
129 static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle);
130 static void ohci_add_done(ohci_softc_t *, ohci_physaddr_t);
131 static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle);
132
133 static usbd_status ohci_device_request(usbd_xfer_handle xfer);
134 static void ohci_add_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
135 static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
136 static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *);
137 static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *);
138 static ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t);
139 static void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *);
140 static void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *);
141 static ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t);
142
143 static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe);
144 static void ohci_device_isoc_enter(usbd_xfer_handle);
145
146 static usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
147 static void ohci_freem(struct usbd_bus *, usb_dma_t *);
148
149 static usbd_xfer_handle ohci_allocx(struct usbd_bus *);
150 static void ohci_freex(struct usbd_bus *, usbd_xfer_handle);
151
152 static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle);
153 static usbd_status ohci_root_ctrl_start(usbd_xfer_handle);
154 static void ohci_root_ctrl_abort(usbd_xfer_handle);
155 static void ohci_root_ctrl_close(usbd_pipe_handle);
156 static void ohci_root_ctrl_done(usbd_xfer_handle);
157
158 static usbd_status ohci_root_intr_transfer(usbd_xfer_handle);
159 static usbd_status ohci_root_intr_start(usbd_xfer_handle);
160 static void ohci_root_intr_abort(usbd_xfer_handle);
161 static void ohci_root_intr_close(usbd_pipe_handle);
162 static void ohci_root_intr_done(usbd_xfer_handle);
163
164 static usbd_status ohci_device_ctrl_transfer(usbd_xfer_handle);
165 static usbd_status ohci_device_ctrl_start(usbd_xfer_handle);
166 static void ohci_device_ctrl_abort(usbd_xfer_handle);
167 static void ohci_device_ctrl_close(usbd_pipe_handle);
168 static void ohci_device_ctrl_done(usbd_xfer_handle);
169
170 static usbd_status ohci_device_bulk_transfer(usbd_xfer_handle);
171 static usbd_status ohci_device_bulk_start(usbd_xfer_handle);
172 static void ohci_device_bulk_abort(usbd_xfer_handle);
173 static void ohci_device_bulk_close(usbd_pipe_handle);
174 static void ohci_device_bulk_done(usbd_xfer_handle);
175
176 static usbd_status ohci_device_intr_transfer(usbd_xfer_handle);
177 static usbd_status ohci_device_intr_start(usbd_xfer_handle);
178 static void ohci_device_intr_abort(usbd_xfer_handle);
179 static void ohci_device_intr_close(usbd_pipe_handle);
180 static void ohci_device_intr_done(usbd_xfer_handle);
181
182 static usbd_status ohci_device_isoc_transfer(usbd_xfer_handle);
183 static usbd_status ohci_device_isoc_start(usbd_xfer_handle);
184 static void ohci_device_isoc_abort(usbd_xfer_handle);
185 static void ohci_device_isoc_close(usbd_pipe_handle);
186 static void ohci_device_isoc_done(usbd_xfer_handle);
187
188 static usbd_status ohci_device_setintr(ohci_softc_t *sc,
189 struct ohci_pipe *pipe, int ival);
190 static usbd_status ohci_device_intr_insert(ohci_softc_t *sc,
191 usbd_xfer_handle xfer);
192
193 static int ohci_str(usb_string_descriptor_t *, int, const char *);
194
195 static void ohci_timeout(void *);
196 static void ohci_timeout_task(void *);
197 static void ohci_rhsc_able(ohci_softc_t *, int);
198 static void ohci_rhsc_enable(void *);
199
200 static void ohci_close_pipe(usbd_pipe_handle, ohci_soft_ed_t *);
201 static void ohci_abort_xfer(usbd_xfer_handle, usbd_status);
202
203 static void ohci_device_clear_toggle(usbd_pipe_handle pipe);
204 static void ohci_noop(usbd_pipe_handle pipe);
205
206 static usbd_status ohci_controller_init(ohci_softc_t *sc);
207
208 #ifdef USB_DEBUG
209 static void ohci_dumpregs(ohci_softc_t *);
210 static void ohci_dump_tds(ohci_soft_td_t *);
211 static void ohci_dump_td(ohci_soft_td_t *);
212 static void ohci_dump_ed(ohci_soft_ed_t *);
213 static void ohci_dump_itd(ohci_soft_itd_t *);
214 static void ohci_dump_itds(ohci_soft_itd_t *);
215 #endif
216
217 #define OBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
218 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
219 #define OWRITE1(sc, r, x) \
220 do { OBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
221 #define OWRITE2(sc, r, x) \
222 do { OBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
223 #define OWRITE4(sc, r, x) \
224 do { OBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
225 #define OREAD1(sc, r) (OBARR(sc), bus_space_read_1((sc)->iot, (sc)->ioh, (r)))
226 #define OREAD2(sc, r) (OBARR(sc), bus_space_read_2((sc)->iot, (sc)->ioh, (r)))
227 #define OREAD4(sc, r) (OBARR(sc), bus_space_read_4((sc)->iot, (sc)->ioh, (r)))
228
229 /* Reverse the bits in a value 0 .. 31 */
230 static u_int8_t revbits[OHCI_NO_INTRS] =
231 { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c,
232 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e,
233 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d,
234 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f };
235
236 struct ohci_pipe {
237 struct usbd_pipe pipe;
238 ohci_soft_ed_t *sed;
239 u_int32_t aborting;
240 union {
241 ohci_soft_td_t *td;
242 ohci_soft_itd_t *itd;
243 } tail;
244 /* Info needed for different pipe kinds. */
245 union {
246 /* Control pipe */
247 struct {
248 usb_dma_t reqdma;
249 u_int length;
250 ohci_soft_td_t *setup, *data, *stat;
251 } ctl;
252 /* Interrupt pipe */
253 struct {
254 int nslots;
255 int pos;
256 } intr;
257 /* Bulk pipe */
258 struct {
259 u_int length;
260 int isread;
261 } bulk;
262 /* Iso pipe */
263 struct iso {
264 int next, inuse;
265 } iso;
266 } u;
267 };
268
269 #define OHCI_INTR_ENDPT 1
270
271 static struct usbd_bus_methods ohci_bus_methods = {
272 ohci_open,
273 ohci_softintr,
274 ohci_poll,
275 ohci_allocm,
276 ohci_freem,
277 ohci_allocx,
278 ohci_freex,
279 };
280
281 static struct usbd_pipe_methods ohci_root_ctrl_methods = {
282 ohci_root_ctrl_transfer,
283 ohci_root_ctrl_start,
284 ohci_root_ctrl_abort,
285 ohci_root_ctrl_close,
286 ohci_noop,
287 ohci_root_ctrl_done,
288 };
289
290 static struct usbd_pipe_methods ohci_root_intr_methods = {
291 ohci_root_intr_transfer,
292 ohci_root_intr_start,
293 ohci_root_intr_abort,
294 ohci_root_intr_close,
295 ohci_noop,
296 ohci_root_intr_done,
297 };
298
299 static struct usbd_pipe_methods ohci_device_ctrl_methods = {
300 ohci_device_ctrl_transfer,
301 ohci_device_ctrl_start,
302 ohci_device_ctrl_abort,
303 ohci_device_ctrl_close,
304 ohci_noop,
305 ohci_device_ctrl_done,
306 };
307
308 static struct usbd_pipe_methods ohci_device_intr_methods = {
309 ohci_device_intr_transfer,
310 ohci_device_intr_start,
311 ohci_device_intr_abort,
312 ohci_device_intr_close,
313 ohci_device_clear_toggle,
314 ohci_device_intr_done,
315 };
316
317 static struct usbd_pipe_methods ohci_device_bulk_methods = {
318 ohci_device_bulk_transfer,
319 ohci_device_bulk_start,
320 ohci_device_bulk_abort,
321 ohci_device_bulk_close,
322 ohci_device_clear_toggle,
323 ohci_device_bulk_done,
324 };
325
326 static struct usbd_pipe_methods ohci_device_isoc_methods = {
327 ohci_device_isoc_transfer,
328 ohci_device_isoc_start,
329 ohci_device_isoc_abort,
330 ohci_device_isoc_close,
331 ohci_noop,
332 ohci_device_isoc_done,
333 };
334
335 int
336 ohci_detach(struct ohci_softc *sc, int flags)
337 {
338 int i, rv = 0;
339
340 sc->sc_dying = 1;
341 callout_stop(&sc->sc_tmo_rhsc);
342
343 #if defined(__NetBSD__) || defined(__OpenBSD__)
344 powerhook_disestablish(sc->sc_powerhook);
345 shutdownhook_disestablish(sc->sc_shutdownhook);
346 #endif
347
348 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
349 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
350
351 usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
352
353 for (i = 0; i < OHCI_NO_EDS; i++)
354 ohci_free_sed(sc, sc->sc_eds[i]);
355 ohci_free_sed(sc, sc->sc_isoc_head);
356 ohci_free_sed(sc, sc->sc_bulk_head);
357 ohci_free_sed(sc, sc->sc_ctrl_head);
358 usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
359
360 return (rv);
361 }
362
363 ohci_soft_ed_t *
364 ohci_alloc_sed(ohci_softc_t *sc)
365 {
366 ohci_soft_ed_t *sed;
367 usbd_status err;
368 int i, offs;
369 usb_dma_t dma;
370
371 if (sc->sc_freeeds == NULL) {
372 DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n"));
373 err = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK,
374 OHCI_ED_ALIGN, &dma);
375 if (err)
376 return (NULL);
377 for(i = 0; i < OHCI_SED_CHUNK; i++) {
378 offs = i * OHCI_SED_SIZE;
379 sed = KERNADDR(&dma, offs);
380 sed->physaddr = DMAADDR(&dma, offs);
381 sed->next = sc->sc_freeeds;
382 sc->sc_freeeds = sed;
383 }
384 }
385 sed = sc->sc_freeeds;
386 sc->sc_freeeds = sed->next;
387 memset(&sed->ed, 0, sizeof(ohci_ed_t));
388 sed->next = 0;
389 return (sed);
390 }
391
392 void
393 ohci_free_sed(ohci_softc_t *sc, ohci_soft_ed_t *sed)
394 {
395 sed->next = sc->sc_freeeds;
396 sc->sc_freeeds = sed;
397 }
398
399 ohci_soft_td_t *
400 ohci_alloc_std(ohci_softc_t *sc)
401 {
402 ohci_soft_td_t *std;
403 usbd_status err;
404 int i, offs;
405 usb_dma_t dma;
406 int s;
407
408 if (sc->sc_freetds == NULL) {
409 DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n"));
410 err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK,
411 OHCI_TD_ALIGN, &dma);
412 if (err)
413 return (NULL);
414 s = splusb();
415 for(i = 0; i < OHCI_STD_CHUNK; i++) {
416 offs = i * OHCI_STD_SIZE;
417 std = KERNADDR(&dma, offs);
418 std->physaddr = DMAADDR(&dma, offs);
419 std->nexttd = sc->sc_freetds;
420 sc->sc_freetds = std;
421 }
422 splx(s);
423 }
424
425 s = splusb();
426 std = sc->sc_freetds;
427 sc->sc_freetds = std->nexttd;
428 memset(&std->td, 0, sizeof(ohci_td_t));
429 std->nexttd = NULL;
430 std->xfer = NULL;
431 ohci_hash_add_td(sc, std);
432 splx(s);
433
434 return (std);
435 }
436
437 void
438 ohci_free_std(ohci_softc_t *sc, ohci_soft_td_t *std)
439 {
440 int s;
441
442 s = splusb();
443 ohci_hash_rem_td(sc, std);
444 std->nexttd = sc->sc_freetds;
445 sc->sc_freetds = std;
446 splx(s);
447 }
448
449 usbd_status
450 ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc,
451 int alen, int rd, usbd_xfer_handle xfer,
452 ohci_soft_td_t *sp, ohci_soft_td_t **ep)
453 {
454 ohci_soft_td_t *next, *cur, *end;
455 ohci_physaddr_t dataphys, physend;
456 u_int32_t tdflags;
457 int offset = 0;
458 int len, maxp, curlen, curlen2, seg, segoff;
459 struct usb_dma_mapping *dma = &xfer->dmamap;
460 u_int16_t flags = xfer->flags;
461
462 DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen));
463
464 len = alen;
465 cur = sp;
466 end = NULL;
467
468 maxp = UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize);
469 tdflags = htole32(
470 (rd ? OHCI_TD_IN : OHCI_TD_OUT) |
471 (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) |
472 OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_SET_DI(6));
473
474 seg = 0;
475 segoff = 0;
476 while (len > 0) {
477 next = ohci_alloc_std(sc);
478 if (next == NULL)
479 goto nomem;
480
481 /*
482 * The OHCI hardware can handle at most one 4k crossing.
483 * The OHCI spec says: If during the data transfer the buffer
484 * address contained in the HC's working copy of
485 * CurrentBufferPointer crosses a 4K boundary, the upper 20
486 * bits of Buffer End are copied to the working value of
487 * CurrentBufferPointer causing the next buffer address to
488 * be the 0th byte in the same 4K page that contains the
489 * last byte of the buffer (the 4K boundary crossing may
490 * occur within a data packet transfer.)
491 */
492 KASSERT(seg < dma->nsegs, ("ohci_alloc_std_chain: overrun"));
493 dataphys = dma->segs[seg].ds_addr + segoff;
494 curlen = dma->segs[seg].ds_len - segoff;
495 if (curlen > len)
496 curlen = len;
497 physend = dataphys + curlen - 1;
498 if (OHCI_PAGE(dataphys) != OHCI_PAGE(physend)) {
499 /* Truncate to two OHCI pages if there are more. */
500 if (curlen > 2 * OHCI_PAGE_SIZE -
501 OHCI_PAGE_OFFSET(dataphys))
502 curlen = 2 * OHCI_PAGE_SIZE -
503 OHCI_PAGE_OFFSET(dataphys);
504 if (curlen < len)
505 curlen -= curlen % maxp;
506 physend = dataphys + curlen - 1;
507 } else if (OHCI_PAGE_OFFSET(physend + 1) == 0 && curlen < len &&
508 curlen + segoff == dma->segs[seg].ds_len) {
509 /* We can possibly include another segment. */
510 KASSERT(seg + 1 < dma->nsegs,
511 ("ohci_alloc_std_chain: overrun2"));
512 seg++;
513
514 /* Determine how much of the second segment to use. */
515 curlen2 = dma->segs[seg].ds_len;
516 if (curlen + curlen2 > len)
517 curlen2 = len - curlen;
518 if (OHCI_PAGE(dma->segs[seg].ds_addr) !=
519 OHCI_PAGE(dma->segs[seg].ds_addr + curlen2 - 1))
520 curlen2 = OHCI_PAGE_SIZE -
521 OHCI_PAGE_OFFSET(dma->segs[seg].ds_addr);
522 if (curlen + curlen2 < len)
523 curlen2 -= (curlen + curlen2) % maxp;
524
525 if (curlen2 > 0) {
526 /* We can include a second segment */
527 segoff = curlen2;
528 physend = dma->segs[seg].ds_addr + curlen2 - 1;
529 curlen += curlen2;
530 } else {
531 /* Second segment not usable now. */
532 seg--;
533 segoff += curlen;
534 }
535 } else {
536 /* Simple case where there is just one OHCI page. */
537 segoff += curlen;
538 }
539 if (curlen == 0 && len != 0) {
540 /*
541 * A maxp length packet would need to be split.
542 * This shouldn't be possible if PAGE_SIZE >= 4k
543 * and the buffer is contiguous in virtual memory.
544 */
545 panic("ohci_alloc_std_chain: XXX need to copy");
546 }
547 if (segoff >= dma->segs[seg].ds_len) {
548 KASSERT(segoff == dma->segs[seg].ds_len,
549 ("ohci_alloc_std_chain: overlap"));
550 seg++;
551 segoff = 0;
552 }
553 DPRINTFN(4,("ohci_alloc_std_chain: dataphys=0x%08x "
554 "len=%d curlen=%d\n",
555 dataphys, len, curlen));
556 len -= curlen;
557
558 cur->td.td_flags = tdflags;
559 cur->td.td_cbp = htole32(dataphys);
560 cur->nexttd = next;
561 cur->td.td_nexttd = htole32(next->physaddr);
562 cur->td.td_be = htole32(physend);
563 cur->len = curlen;
564 cur->flags = OHCI_ADD_LEN;
565 cur->xfer = xfer;
566 DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n",
567 dataphys, dataphys + curlen - 1));
568 if (len < 0)
569 panic("Length went negative: %d curlen %d dma %p offset %08x", len, curlen, dma, (int)0);
570
571 DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n"));
572 offset += curlen;
573 end = cur;
574 cur = next;
575 }
576 if (((flags & USBD_FORCE_SHORT_XFER) || alen == 0) &&
577 alen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize) == 0) {
578 /* Force a 0 length transfer at the end. */
579 next = ohci_alloc_std(sc);
580 if (next == NULL)
581 goto nomem;
582
583 cur->td.td_flags = tdflags;
584 cur->td.td_cbp = 0; /* indicate 0 length packet */
585 cur->nexttd = next;
586 cur->td.td_nexttd = htole32(next->physaddr);
587 cur->td.td_be = ~0;
588 cur->len = 0;
589 cur->flags = 0;
590 cur->xfer = xfer;
591 DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n"));
592 end = cur;
593 }
594 *ep = end;
595
596 return (USBD_NORMAL_COMPLETION);
597
598 nomem:
599 /* XXX free chain */
600 return (USBD_NOMEM);
601 }
602
603 #if 0
604 static void
605 ohci_free_std_chain(ohci_softc_t *sc, ohci_soft_td_t *std,
606 ohci_soft_td_t *stdend)
607 {
608 ohci_soft_td_t *p;
609
610 for (; std != stdend; std = p) {
611 p = std->nexttd;
612 ohci_free_std(sc, std);
613 }
614 }
615 #endif
616
617 ohci_soft_itd_t *
618 ohci_alloc_sitd(ohci_softc_t *sc)
619 {
620 ohci_soft_itd_t *sitd;
621 usbd_status err;
622 int i, s, offs;
623 usb_dma_t dma;
624
625 if (sc->sc_freeitds == NULL) {
626 DPRINTFN(2, ("ohci_alloc_sitd: allocating chunk\n"));
627 err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * OHCI_SITD_CHUNK,
628 OHCI_ITD_ALIGN, &dma);
629 if (err)
630 return (NULL);
631 s = splusb();
632 for(i = 0; i < OHCI_SITD_CHUNK; i++) {
633 offs = i * OHCI_SITD_SIZE;
634 sitd = KERNADDR(&dma, offs);
635 sitd->physaddr = DMAADDR(&dma, offs);
636 sitd->nextitd = sc->sc_freeitds;
637 sc->sc_freeitds = sitd;
638 }
639 splx(s);
640 }
641
642 s = splusb();
643 sitd = sc->sc_freeitds;
644 sc->sc_freeitds = sitd->nextitd;
645 memset(&sitd->itd, 0, sizeof(ohci_itd_t));
646 sitd->nextitd = NULL;
647 sitd->xfer = NULL;
648 ohci_hash_add_itd(sc, sitd);
649 splx(s);
650
651 #ifdef DIAGNOSTIC
652 sitd->isdone = 0;
653 #endif
654
655 return (sitd);
656 }
657
658 void
659 ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
660 {
661 int s;
662
663 DPRINTFN(10,("ohci_free_sitd: sitd=%p\n", sitd));
664
665 #ifdef DIAGNOSTIC
666 if (!sitd->isdone) {
667 panic("ohci_free_sitd: sitd=%p not done", sitd);
668 return;
669 }
670 /* Warn double free */
671 sitd->isdone = 0;
672 #endif
673
674 s = splusb();
675 ohci_hash_rem_itd(sc, sitd);
676 sitd->nextitd = sc->sc_freeitds;
677 sc->sc_freeitds = sitd;
678 splx(s);
679 }
680
681 usbd_status
682 ohci_init(ohci_softc_t *sc)
683 {
684 ohci_soft_ed_t *sed, *psed;
685 usbd_status err;
686 int i;
687 u_int32_t rev;
688
689 DPRINTF(("ohci_init: start\n"));
690 printf("%s:", device_get_nameunit(sc->sc_bus.bdev));
691 rev = OREAD4(sc, OHCI_REVISION);
692 printf(" OHCI version %d.%d%s\n", OHCI_REV_HI(rev), OHCI_REV_LO(rev),
693 OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
694
695 if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) {
696 printf("%s: unsupported OHCI revision\n",
697 device_get_nameunit(sc->sc_bus.bdev));
698 sc->sc_bus.usbrev = USBREV_UNKNOWN;
699 return (USBD_INVAL);
700 }
701 sc->sc_bus.usbrev = USBREV_1_0;
702
703 for (i = 0; i < OHCI_HASH_SIZE; i++)
704 LIST_INIT(&sc->sc_hash_tds[i]);
705 for (i = 0; i < OHCI_HASH_SIZE; i++)
706 LIST_INIT(&sc->sc_hash_itds[i]);
707
708 STAILQ_INIT(&sc->sc_free_xfers);
709
710 /* XXX determine alignment by R/W */
711 /* Allocate the HCCA area. */
712 err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
713 OHCI_HCCA_ALIGN, &sc->sc_hccadma);
714 if (err)
715 return (err);
716 sc->sc_hcca = KERNADDR(&sc->sc_hccadma, 0);
717 memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE);
718
719 sc->sc_eintrs = OHCI_NORMAL_INTRS;
720
721 /* Allocate dummy ED that starts the control list. */
722 sc->sc_ctrl_head = ohci_alloc_sed(sc);
723 if (sc->sc_ctrl_head == NULL) {
724 err = USBD_NOMEM;
725 goto bad1;
726 }
727 sc->sc_ctrl_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
728
729 /* Allocate dummy ED that starts the bulk list. */
730 sc->sc_bulk_head = ohci_alloc_sed(sc);
731 if (sc->sc_bulk_head == NULL) {
732 err = USBD_NOMEM;
733 goto bad2;
734 }
735 sc->sc_bulk_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
736
737 /* Allocate dummy ED that starts the isochronous list. */
738 sc->sc_isoc_head = ohci_alloc_sed(sc);
739 if (sc->sc_isoc_head == NULL) {
740 err = USBD_NOMEM;
741 goto bad3;
742 }
743 sc->sc_isoc_head->ed.ed_flags |= htole32(OHCI_ED_SKIP);
744
745 /* Allocate all the dummy EDs that make up the interrupt tree. */
746 for (i = 0; i < OHCI_NO_EDS; i++) {
747 sed = ohci_alloc_sed(sc);
748 if (sed == NULL) {
749 while (--i >= 0)
750 ohci_free_sed(sc, sc->sc_eds[i]);
751 err = USBD_NOMEM;
752 goto bad4;
753 }
754 /* All ED fields are set to 0. */
755 sc->sc_eds[i] = sed;
756 sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
757 if (i != 0)
758 psed = sc->sc_eds[(i-1) / 2];
759 else
760 psed= sc->sc_isoc_head;
761 sed->next = psed;
762 sed->ed.ed_nexted = htole32(psed->physaddr);
763 }
764 /*
765 * Fill HCCA interrupt table. The bit reversal is to get
766 * the tree set up properly to spread the interrupts.
767 */
768 for (i = 0; i < OHCI_NO_INTRS; i++)
769 sc->sc_hcca->hcca_interrupt_table[revbits[i]] =
770 htole32(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr);
771
772 #ifdef USB_DEBUG
773 if (ohcidebug > 15) {
774 for (i = 0; i < OHCI_NO_EDS; i++) {
775 printf("ed#%d ", i);
776 ohci_dump_ed(sc->sc_eds[i]);
777 }
778 printf("iso ");
779 ohci_dump_ed(sc->sc_isoc_head);
780 }
781 #endif
782
783 err = ohci_controller_init(sc);
784 if (err != USBD_NORMAL_COMPLETION)
785 goto bad5;
786
787 /* Set up the bus struct. */
788 sc->sc_bus.methods = &ohci_bus_methods;
789 sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
790
791 #if defined(__NetBSD__) || defined(__OpenBSD__)
792 sc->sc_powerhook = powerhook_establish(ohci_power, sc);
793 sc->sc_shutdownhook = shutdownhook_establish(ohci_shutdown, sc);
794 #endif
795
796 callout_init(&sc->sc_tmo_rhsc, 0);
797
798 return (USBD_NORMAL_COMPLETION);
799
800 bad5:
801 for (i = 0; i < OHCI_NO_EDS; i++)
802 ohci_free_sed(sc, sc->sc_eds[i]);
803 bad4:
804 ohci_free_sed(sc, sc->sc_isoc_head);
805 bad3:
806 ohci_free_sed(sc, sc->sc_bulk_head);
807 bad2:
808 ohci_free_sed(sc, sc->sc_ctrl_head);
809 bad1:
810 usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
811 return (err);
812 }
813
814 static usbd_status
815 ohci_controller_init(ohci_softc_t *sc)
816 {
817 int i;
818 u_int32_t ctl, ival, hcr, fm, per, desca;
819
820 /* Determine in what context we are running. */
821 ctl = OREAD4(sc, OHCI_CONTROL);
822 if (ctl & OHCI_IR) {
823 /* SMM active, request change */
824 DPRINTF(("ohci_init: SMM active, request owner change\n"));
825 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_OCR);
826 for (i = 0; i < 100 && (ctl & OHCI_IR); i++) {
827 usb_delay_ms(&sc->sc_bus, 1);
828 ctl = OR |