[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/ohci.c

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

  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