uhci.c revision 1.32 1 /* $NetBSD: uhci.c,v 1.32 1999/07/12 05:22:50 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 Universal Host Controller driver.
42 * Handles e.g. PIIX3 and PIIX4.
43 *
44 * Data sheets: ftp://download.intel.com/design/intarch/datashts/29055002.pdf
45 * ftp://download.intel.com/design/intarch/datashts/29056201.pdf
46 * UHCI spec: http://www.intel.com/design/usb/uhci11d.pdf
47 * USB spec: http://www.usb.org/developers/data/usb11.pdf
48 */
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/kernel.h>
53 #include <sys/malloc.h>
54 #if defined(__NetBSD__)
55 #include <sys/device.h>
56 #elif defined(__FreeBSD__)
57 #include <sys/module.h>
58 #include <sys/bus.h>
59 #endif
60 #include <sys/proc.h>
61 #include <sys/queue.h>
62 #include <sys/select.h>
63
64 #include <machine/bus.h>
65
66 #include <dev/usb/usb.h>
67 #include <dev/usb/usbdi.h>
68 #include <dev/usb/usbdivar.h>
69 #include <dev/usb/usb_mem.h>
70 #include <dev/usb/usb_quirks.h>
71
72 #include <dev/usb/uhcireg.h>
73 #include <dev/usb/uhcivar.h>
74
75 #if defined(__FreeBSD__)
76 #include <machine/clock.h>
77
78 #define delay(d) DELAY(d)
79 #endif
80
81 #define MS_TO_TICKS(ms) ((ms) * hz / 1000)
82
83 struct uhci_pipe {
84 struct usbd_pipe pipe;
85 uhci_intr_info_t *iinfo;
86 int nexttoggle;
87 /* Info needed for different pipe kinds. */
88 union {
89 /* Control pipe */
90 struct {
91 uhci_soft_qh_t *sqh;
92 usb_dma_t reqdma;
93 usb_dma_t datadma;
94 uhci_soft_td_t *setup, *stat;
95 u_int length;
96 } ctl;
97 /* Interrupt pipe */
98 struct {
99 usb_dma_t datadma;
100 int npoll;
101 uhci_soft_qh_t **qhs;
102 } intr;
103 /* Bulk pipe */
104 struct {
105 uhci_soft_qh_t *sqh;
106 usb_dma_t datadma;
107 u_int length;
108 int isread;
109 } bulk;
110 /* Iso pipe */
111 struct iso {
112 u_int bufsize;
113 u_int nbuf;
114 usb_dma_t *bufs;
115 uhci_soft_td_t **stds;
116 } iso;
117 } u;
118 };
119
120 /*
121 * The uhci_intr_info free list can be global since they contain
122 * no dma specific data. The other free lists do.
123 */
124 LIST_HEAD(, uhci_intr_info) uhci_ii_free;
125
126 void uhci_busreset __P((uhci_softc_t *));
127 void uhci_power __P((int, void *));
128 usbd_status uhci_run __P((uhci_softc_t *, int run));
129 uhci_soft_td_t *uhci_alloc_std __P((uhci_softc_t *));
130 void uhci_free_std __P((uhci_softc_t *, uhci_soft_td_t *));
131 uhci_soft_qh_t *uhci_alloc_sqh __P((uhci_softc_t *));
132 void uhci_free_sqh __P((uhci_softc_t *, uhci_soft_qh_t *));
133 uhci_intr_info_t *uhci_alloc_intr_info __P((uhci_softc_t *));
134 void uhci_free_intr_info __P((uhci_intr_info_t *ii));
135 #if 0
136 void uhci_enter_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *,
137 uhci_intr_info_t *));
138 void uhci_exit_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *));
139 #endif
140
141 void uhci_free_std_chain __P((uhci_softc_t *,
142 uhci_soft_td_t *, uhci_soft_td_t *));
143 usbd_status uhci_alloc_std_chain __P((struct uhci_pipe *, uhci_softc_t *,
144 int, int, int, usb_dma_t *,
145 uhci_soft_td_t **,
146 uhci_soft_td_t **));
147 void uhci_timo __P((void *));
148 void uhci_waitintr __P((uhci_softc_t *, usbd_request_handle));
149 void uhci_check_intr __P((uhci_softc_t *, uhci_intr_info_t *));
150 void uhci_ii_done __P((uhci_intr_info_t *, int));
151 void uhci_timeout __P((void *));
152 void uhci_wakeup_ctrl __P((void *, int, int, void *, int));
153 void uhci_lock_frames __P((uhci_softc_t *));
154 void uhci_unlock_frames __P((uhci_softc_t *));
155 void uhci_add_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *));
156 void uhci_add_bulk __P((uhci_softc_t *, uhci_soft_qh_t *));
157 void uhci_remove_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *));
158 void uhci_remove_bulk __P((uhci_softc_t *, uhci_soft_qh_t *));
159 int uhci_str __P((usb_string_descriptor_t *, int, char *));
160
161 void uhci_wakeup_cb __P((usbd_request_handle reqh));
162
163 usbd_status uhci_device_ctrl_transfer __P((usbd_request_handle));
164 usbd_status uhci_device_ctrl_start __P((usbd_request_handle));
165 void uhci_device_ctrl_abort __P((usbd_request_handle));
166 void uhci_device_ctrl_close __P((usbd_pipe_handle));
167 usbd_status uhci_device_intr_transfer __P((usbd_request_handle));
168 usbd_status uhci_device_intr_start __P((usbd_request_handle));
169 void uhci_device_intr_abort __P((usbd_request_handle));
170 void uhci_device_intr_close __P((usbd_pipe_handle));
171 usbd_status uhci_device_bulk_transfer __P((usbd_request_handle));
172 usbd_status uhci_device_bulk_start __P((usbd_request_handle));
173 void uhci_device_bulk_abort __P((usbd_request_handle));
174 void uhci_device_bulk_close __P((usbd_pipe_handle));
175 usbd_status uhci_device_isoc_transfer __P((usbd_request_handle));
176 usbd_status uhci_device_isoc_start __P((usbd_request_handle));
177 void uhci_device_isoc_abort __P((usbd_request_handle));
178 void uhci_device_isoc_close __P((usbd_pipe_handle));
179 usbd_status uhci_device_isoc_setbuf __P((usbd_pipe_handle, u_int, u_int));
180
181 usbd_status uhci_root_ctrl_transfer __P((usbd_request_handle));
182 usbd_status uhci_root_ctrl_start __P((usbd_request_handle));
183 void uhci_root_ctrl_abort __P((usbd_request_handle));
184 void uhci_root_ctrl_close __P((usbd_pipe_handle));
185 usbd_status uhci_root_intr_transfer __P((usbd_request_handle));
186 usbd_status uhci_root_intr_start __P((usbd_request_handle));
187 void uhci_root_intr_abort __P((usbd_request_handle));
188 void uhci_root_intr_close __P((usbd_pipe_handle));
189
190 usbd_status uhci_open __P((usbd_pipe_handle));
191 void uhci_poll __P((struct usbd_bus *));
192
193 usbd_status uhci_device_request __P((usbd_request_handle reqh));
194 void uhci_ctrl_done __P((uhci_intr_info_t *ii));
195 void uhci_bulk_done __P((uhci_intr_info_t *ii));
196
197 void uhci_add_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *));
198 void uhci_remove_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *));
199 usbd_status uhci_device_setintr __P((uhci_softc_t *sc,
200 struct uhci_pipe *pipe, int ival));
201 void uhci_intr_done __P((uhci_intr_info_t *ii));
202 void uhci_isoc_done __P((uhci_intr_info_t *ii));
203
204 #ifdef USB_DEBUG
205 static void uhci_dumpregs __P((uhci_softc_t *));
206 void uhci_dump_tds __P((uhci_soft_td_t *));
207 void uhci_dump_qh __P((uhci_soft_qh_t *));
208 void uhci_dump __P((void));
209 void uhci_dump_td __P((uhci_soft_td_t *));
210 #endif
211
212 #if defined(__NetBSD__)
213 #define UWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x))
214 #define UWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
215 #define UREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r))
216 #define UREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r))
217 #elif defined(__FreeBSD__)
218 #define UWRITE2(sc,r,x) outw((sc)->sc_iobase + (r), (x))
219 #define UWRITE4(sc,r,x) outl((sc)->sc_iobase + (r), (x))
220 #define UREAD2(sc,r) inw((sc)->sc_iobase + (r))
221 #define UREAD4(sc,r) inl((sc)->sc_iobase + (r))
222 #endif
223
224 #define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd)
225 #define UHCISTS(sc) UREAD2(sc, UHCI_STS)
226
227 #define UHCI_RESET_TIMEOUT 100 /* reset timeout */
228
229 #define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK)
230
231 #define UHCI_INTR_ENDPT 1
232
233 struct usbd_methods uhci_root_ctrl_methods = {
234 uhci_root_ctrl_transfer,
235 uhci_root_ctrl_start,
236 uhci_root_ctrl_abort,
237 uhci_root_ctrl_close,
238 0,
239 };
240
241 struct usbd_methods uhci_root_intr_methods = {
242 uhci_root_intr_transfer,
243 uhci_root_intr_start,
244 uhci_root_intr_abort,
245 uhci_root_intr_close,
246 0,
247 };
248
249 struct usbd_methods uhci_device_ctrl_methods = {
250 uhci_device_ctrl_transfer,
251 uhci_device_ctrl_start,
252 uhci_device_ctrl_abort,
253 uhci_device_ctrl_close,
254 0,
255 };
256
257 struct usbd_methods uhci_device_intr_methods = {
258 uhci_device_intr_transfer,
259 uhci_device_intr_start,
260 uhci_device_intr_abort,
261 uhci_device_intr_close,
262 0,
263 };
264
265 struct usbd_methods uhci_device_bulk_methods = {
266 uhci_device_bulk_transfer,
267 uhci_device_bulk_start,
268 uhci_device_bulk_abort,
269 uhci_device_bulk_close,
270 0,
271 };
272
273 struct usbd_methods uhci_device_isoc_methods = {
274 uhci_device_isoc_transfer,
275 uhci_device_isoc_start,
276 uhci_device_isoc_abort,
277 uhci_device_isoc_close,
278 uhci_device_isoc_setbuf,
279 };
280
281 void
282 uhci_busreset(sc)
283 uhci_softc_t *sc;
284 {
285 UHCICMD(sc, UHCI_CMD_GRESET); /* global reset */
286 usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); /* wait a little */
287 UHCICMD(sc, 0); /* do nothing */
288 }
289
290 usbd_status
291 uhci_init(sc)
292 uhci_softc_t *sc;
293 {
294 usbd_status r;
295 int i, j;
296 uhci_soft_qh_t *csqh, *bsqh, *sqh;
297 uhci_soft_td_t *std;
298
299 DPRINTFN(1,("uhci_init: start\n"));
300
301 #if defined(USB_DEBUG)
302 if (uhcidebug > 2)
303 uhci_dumpregs(sc);
304 #endif
305
306 uhci_run(sc, 0); /* stop the controller */
307 UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
308
309 uhci_busreset(sc);
310
311 /* Allocate and initialize real frame array. */
312 r = usb_allocmem(sc->sc_dmatag,
313 UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
314 UHCI_FRAMELIST_ALIGN, &sc->sc_dma);
315 if (r != USBD_NORMAL_COMPLETION)
316 return (r);
317 sc->sc_pframes = KERNADDR(&sc->sc_dma);
318 UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */
319 UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma)); /* set frame list */
320
321 /* Allocate the dummy QH where bulk traffic will be queued. */
322 bsqh = uhci_alloc_sqh(sc);
323 if (!bsqh)
324 return (USBD_NOMEM);
325 bsqh->qh->qh_hlink = UHCI_PTR_T; /* end of QH chain */
326 bsqh->qh->qh_elink = UHCI_PTR_T;
327 sc->sc_bulk_start = sc->sc_bulk_end = bsqh;
328
329 /* Allocate the dummy QH where control traffic will be queued. */
330 csqh = uhci_alloc_sqh(sc);
331 if (!csqh)
332 return (USBD_NOMEM);
333 csqh->qh->hlink = bsqh;
334 csqh->qh->qh_hlink = bsqh->physaddr | UHCI_PTR_Q;
335 csqh->qh->qh_elink = UHCI_PTR_T;
336 sc->sc_ctl_start = sc->sc_ctl_end = csqh;
337
338 /*
339 * Make all (virtual) frame list pointers point to the interrupt
340 * queue heads and the interrupt queue heads at the control
341 * queue head and point the physical frame list to the virtual.
342 */
343 for(i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
344 std = uhci_alloc_std(sc);
345 sqh = uhci_alloc_sqh(sc);
346 if (!std || !sqh)
347 return (USBD_NOMEM);
348 std->td->link.sqh = sqh;
349 std->td->td_link = sqh->physaddr | UHCI_PTR_Q;
350 std->td->td_status = UHCI_TD_IOS; /* iso, inactive */
351 std->td->td_token = 0;
352 std->td->td_buffer = 0;
353 sqh->qh->hlink = csqh;
354 sqh->qh->qh_hlink = csqh->physaddr | UHCI_PTR_Q;
355 sqh->qh->elink = 0;
356 sqh->qh->qh_elink = UHCI_PTR_T;
357 sc->sc_vframes[i].htd = std;
358 sc->sc_vframes[i].etd = std;
359 sc->sc_vframes[i].hqh = sqh;
360 sc->sc_vframes[i].eqh = sqh;
361 for (j = i;
362 j < UHCI_FRAMELIST_COUNT;
363 j += UHCI_VFRAMELIST_COUNT)
364 sc->sc_pframes[j] = std->physaddr;
365 }
366
367 LIST_INIT(&sc->sc_intrhead);
368
369 /* Set up the bus struct. */
370 sc->sc_bus.open_pipe = uhci_open;
371 sc->sc_bus.pipe_size = sizeof(struct uhci_pipe);
372 sc->sc_bus.do_poll = uhci_poll;
373
374 sc->sc_suspend = PWR_RESUME;
375 (void)powerhook_establish(uhci_power, sc);
376
377 DPRINTFN(1,("uhci_init: enabling\n"));
378 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
379 UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */
380
381 return (uhci_run(sc, 1)); /* and here we go... */
382 }
383
384 /*
385 * Handle suspend/resume.
386 *
387 * Must use delay() here since we are called from an interrupt
388 * context, but since we are close to being inactive anyway
389 * it doesn't matter.
390 */
391 void
392 uhci_power(why, v)
393 int why;
394 void *v;
395 {
396 uhci_softc_t *sc = v;
397 int cmd;
398 int s;
399
400 s = splusb();
401 cmd = UREAD2(sc, UHCI_CMD);
402
403 DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n",
404 sc, why, sc->sc_suspend, cmd));
405
406 if (why != PWR_RESUME) {
407 #if defined(USB_DEBUG)
408 if (uhcidebug > 2)
409 uhci_dumpregs(sc);
410 #endif
411 if (sc->sc_has_timo)
412 usb_untimeout(uhci_timo, sc->sc_has_timo,
413 sc->sc_has_timo->timo_handle);
414 uhci_run(sc, 0); /* stop the controller */
415 UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter global suspend */
416 delay(USB_RESUME_WAIT * 1000);
417 sc->sc_suspend = why;
418 DPRINTF(("uhci_power: cmd=0x%x\n", UREAD2(sc, UHCI_CMD)));
419 } else {
420 /*
421 * XXX We should really do much more here in case the
422 * controller registers have been lost and BIOS has
423 * not restored them.
424 */
425 sc->sc_suspend = why;
426 if (cmd & UHCI_CMD_RS)
427 uhci_run(sc, 0); /* in case BIOS has started it */
428 UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force global resume */
429 delay(USB_RESUME_DELAY * 1000);
430 UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */
431 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
432 UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */
433 uhci_run(sc, 1); /* and start traffic again */
434 delay(USB_RESUME_RECOVERY * 1000);
435 if (sc->sc_has_timo)
436 usb_timeout(uhci_timo, sc->sc_has_timo,
437 sc->sc_ival, sc->sc_has_timo->timo_handle);
438 #if defined(USB_DEBUG)
439 if (uhcidebug > 2)
440 uhci_dumpregs(sc);
441 #endif
442 }
443 splx(s);
444 }
445
446 #ifdef USB_DEBUG
447 static void
448 uhci_dumpregs(sc)
449 uhci_softc_t *sc;
450 {
451 printf("%s regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, "
452 "flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n",
453 USBDEVNAME(sc->sc_bus.bdev),
454 UREAD2(sc, UHCI_CMD),
455 UREAD2(sc, UHCI_STS),
456 UREAD2(sc, UHCI_INTR),
457 UREAD2(sc, UHCI_FRNUM),
458 UREAD4(sc, UHCI_FLBASEADDR),
459 UREAD2(sc, UHCI_SOF),
460 UREAD2(sc, UHCI_PORTSC1),
461 UREAD2(sc, UHCI_PORTSC2));
462 }
463
464 int uhci_longtd = 1;
465
466 void
467 uhci_dump_td(p)
468 uhci_soft_td_t *p;
469 {
470 printf("TD(%p) at %08lx = link=0x%08lx status=0x%08lx "
471 "token=0x%08lx buffer=0x%08lx\n",
472 p, (long)p->physaddr,
473 (long)p->td->td_link,
474 (long)p->td->td_status,
475 (long)p->td->td_token,
476 (long)p->td->td_buffer);
477 if (uhci_longtd)
478 printf(" %b %b,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d,"
479 "D=%d,maxlen=%d\n",
480 (int)p->td->td_link,
481 "\20\1T\2Q\3VF",
482 (int)p->td->td_status,
483 "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27"
484 "STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD",
485 UHCI_TD_GET_ERRCNT(p->td->td_status),
486 UHCI_TD_GET_ACTLEN(p->td->td_status),
487 UHCI_TD_GET_PID(p->td->td_token),
488 UHCI_TD_GET_DEVADDR(p->td->td_token),
489 UHCI_TD_GET_ENDPT(p->td->td_token),
490 UHCI_TD_GET_DT(p->td->td_token),
491 UHCI_TD_GET_MAXLEN(p->td->td_token));
492 }
493
494 void
495 uhci_dump_qh(p)
496 uhci_soft_qh_t *p;
497 {
498 printf("QH(%p) at %08x: hlink=%08x elink=%08x\n", p, (int)p->physaddr,
499 p->qh->qh_hlink, p->qh->qh_elink);
500 }
501
502
503 #if 0
504 void
505 uhci_dump()
506 {
507 uhci_softc_t *sc = uhci;
508
509 uhci_dumpregs(sc);
510 printf("intrs=%d\n", sc->sc_intrs);
511 printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);
512 uhci_dump_qh(sc->sc_ctl_start->qh->hlink);
513 }
514 #endif
515
516 void
517 uhci_dump_tds(std)
518 uhci_soft_td_t *std;
519 {
520 uhci_soft_td_t *p;
521
522 for(p = std; p; p = p->td->link.std)
523 uhci_dump_td(p);
524 }
525 #endif
526
527 /*
528 * This routine is executed periodically and simulates interrupts
529 * from the root controller interrupt pipe for port status change.
530 */
531 void
532 uhci_timo(addr)
533 void *addr;
534 {
535 usbd_request_handle reqh = addr;
536 usbd_pipe_handle pipe = reqh->pipe;
537 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
538 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
539 int s;
540 u_char *p;
541
542 DPRINTFN(15, ("uhci_timo\n"));
543
544 p = KERNADDR(&upipe->u.intr.datadma);
545 p[0] = 0;
546 if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
547 p[0] |= 1<<1;
548 if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
549 p[0] |= 1<<2;
550 s = splusb();
551 if (p[0] != 0) {
552 reqh->actlen = 1;
553 reqh->status = USBD_NORMAL_COMPLETION;
554 reqh->xfercb(reqh);
555 }
556 if (reqh->pipe->repeat) {
557 usb_timeout(uhci_timo, reqh, sc->sc_ival, reqh->timo_handle);
558 } else {
559 usb_freemem(sc->sc_dmatag, &upipe->u.intr.datadma);
560 usb_start_next(reqh->pipe);
561 }
562 splx(s);
563 }
564
565
566 void
567 uhci_lock_frames(sc)
568 uhci_softc_t *sc;
569 {
570 int s = splusb();
571 while (sc->sc_vflock) {
572 sc->sc_vflock |= UHCI_WANT_LOCK;
573 tsleep(&sc->sc_vflock, PRIBIO, "uhcqhl", 0);
574 }
575 sc->sc_vflock = UHCI_HAS_LOCK;
576 splx(s);
577 }
578
579 void
580 uhci_unlock_frames(sc)
581 uhci_softc_t *sc;
582 {
583 int s = splusb();
584 sc->sc_vflock &= ~UHCI_HAS_LOCK;
585 if (sc->sc_vflock & UHCI_WANT_LOCK)
586 wakeup(&sc->sc_vflock);
587 splx(s);
588 }
589
590 /*
591 * Allocate an interrupt information struct. A free list is kept
592 * for fast allocation.
593 */
594 uhci_intr_info_t *
595 uhci_alloc_intr_info(sc)
596 uhci_softc_t *sc;
597 {
598 uhci_intr_info_t *ii;
599
600 ii = LIST_FIRST(&uhci_ii_free);
601 if (ii)
602 LIST_REMOVE(ii, list);
603 else {
604 ii = malloc(sizeof(uhci_intr_info_t), M_USBHC, M_NOWAIT);
605 }
606 ii->sc = sc;
607 return ii;
608 }
609
610 void
611 uhci_free_intr_info(ii)
612 uhci_intr_info_t *ii;
613 {
614 LIST_INSERT_HEAD(&uhci_ii_free, ii, list); /* and put on free list */
615 }
616
617 /* Add control QH, called at splusb(). */
618 void
619 uhci_add_ctrl(sc, sqh)
620 uhci_softc_t *sc;
621 uhci_soft_qh_t *sqh;
622 {
623 uhci_qh_t *eqh;
624
625 DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh));
626 eqh = sc->sc_ctl_end->qh;
627 sqh->qh->hlink = eqh->hlink;
628 sqh->qh->qh_hlink = eqh->qh_hlink;
629 eqh->hlink = sqh;
630 eqh->qh_hlink = sqh->physaddr | UHCI_PTR_Q;
631 sc->sc_ctl_end = sqh;
632 }
633
634 /* Remove control QH, called at splusb(). */
635 void
636 uhci_remove_ctrl(sc, sqh)
637 uhci_softc_t *sc;
638 uhci_soft_qh_t *sqh;
639 {
640 uhci_soft_qh_t *pqh;
641
642 DPRINTFN(10, ("uhci_remove_ctrl: sqh=%p\n", sqh));
643 for (pqh = sc->sc_ctl_start; pqh->qh->hlink != sqh; pqh=pqh->qh->hlink)
644 #if defined(DIAGNOSTIC) || defined(USB_DEBUG)
645 if (pqh->qh->qh_hlink & UHCI_PTR_T) {
646 printf("uhci_remove_ctrl: QH not found\n");
647 return;
648 }
649 #else
650 ;
651 #endif
652 pqh->qh->hlink = sqh->qh->hlink;
653 pqh->qh->qh_hlink = sqh->qh->qh_hlink;
654 if (sc->sc_ctl_end == sqh)
655 sc->sc_ctl_end = pqh;
656 }
657
658 /* Add bulk QH, called at splusb(). */
659 void
660 uhci_add_bulk(sc, sqh)
661 uhci_softc_t *sc;
662 uhci_soft_qh_t *sqh;
663 {
664 uhci_qh_t *eqh;
665
666 DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
667 eqh = sc->sc_bulk_end->qh;
668 sqh->qh->hlink = eqh->hlink;
669 sqh->qh->qh_hlink = eqh->qh_hlink;
670 eqh->hlink = sqh;
671 eqh->qh_hlink = sqh->physaddr | UHCI_PTR_Q;
672 sc->sc_bulk_end = sqh;
673 }
674
675 /* Remove bulk QH, called at splusb(). */
676 void
677 uhci_remove_bulk(sc, sqh)
678 uhci_softc_t *sc;
679 uhci_soft_qh_t *sqh;
680 {
681 uhci_soft_qh_t *pqh;
682
683 DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh));
684 for (pqh = sc->sc_bulk_start;
685 pqh->qh->hlink != sqh;
686 pqh = pqh->qh->hlink)
687 #if defined(DIAGNOSTIC) || defined(USB_DEBUG)
688 if (pqh->qh->qh_hlink & UHCI_PTR_T) {
689 printf("uhci_remove_bulk: QH not found\n");
690 return;
691 }
692 #else
693 ;
694 #endif
695 pqh->qh->hlink = sqh->qh->hlink;
696 pqh->qh->qh_hlink = sqh->qh->qh_hlink;
697 if (sc->sc_bulk_end == sqh)
698 sc->sc_bulk_end = pqh;
699 }
700
701 int
702 uhci_intr(p)
703 void *p;
704 {
705 uhci_softc_t *sc = p;
706 int status, ret;
707 uhci_intr_info_t *ii;
708
709 sc->sc_intrs++;
710 #if defined(USB_DEBUG)
711 if (uhcidebug > 9) {
712 printf("uhci_intr %p\n", sc);
713 uhci_dumpregs(sc);
714 }
715 #endif
716 status = UREAD2(sc, UHCI_STS);
717 #ifdef DIAGNOSTIC
718 if (sc->sc_suspend != PWR_RESUME)
719 printf("uhci_intr: suspended sts=0x%x\n", status);
720 #endif
721 ret = 0;
722 if (status & UHCI_STS_USBINT) {
723 UWRITE2(sc, UHCI_STS, UHCI_STS_USBINT); /* acknowledge */
724 ret = 1;
725 }
726 if (status & UHCI_STS_USBEI) {
727 UWRITE2(sc, UHCI_STS, UHCI_STS_USBEI); /* acknowledge */
728 ret = 1;
729 }
730 if (status & UHCI_STS_RD) {
731 UWRITE2(sc, UHCI_STS, UHCI_STS_RD); /* acknowledge */
732 printf("%s: resume detect\n", USBDEVNAME(sc->sc_bus.bdev));
733 ret = 1;
734 }
735 if (status & UHCI_STS_HSE) {
736 UWRITE2(sc, UHCI_STS, UHCI_STS_HSE); /* acknowledge */
737 printf("%s: Host System Error\n", USBDEVNAME(sc->sc_bus.bdev));
738 ret = 1;
739 }
740 if (status & UHCI_STS_HCPE) {
741 UWRITE2(sc, UHCI_STS, UHCI_STS_HCPE); /* acknowledge */
742 printf("%s: Host System Error\n", USBDEVNAME(sc->sc_bus.bdev));
743 ret = 1;
744 }
745 if (status & UHCI_STS_HCH)
746 printf("%s: controller halted\n", USBDEVNAME(sc->sc_bus.bdev));
747 if (!ret)
748 return 0;
749
750 /*
751 * Interrupts on UHCI really suck. When the host controller
752 * interrupts because a transfer is completed there is no
753 * way of knowing which transfer it was. You can scan down
754 * the TDs and QHs of the previous frame to limit the search,
755 * but that assumes that the interrupt was not delayed by more
756 * than 1 ms, which may not always be true (e.g. after debug
757 * output on a slow console).
758 * We scan all interrupt descriptors to see if any have
759 * completed.
760 */
761 for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list))
762 uhci_check_intr(sc, ii);
763
764 DPRINTFN(10, ("uhci_intr: exit\n"));
765 return 1;
766 }
767
768 /* Check for an interrupt. */
769 void
770 uhci_check_intr(sc, ii)
771 uhci_softc_t *sc;
772 uhci_intr_info_t *ii;
773 {
774 struct uhci_pipe *upipe;
775 uhci_soft_td_t *std, *lstd;
776 u_int32_t status;
777
778 DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii));
779 #ifdef DIAGNOSTIC
780 if (!ii) {
781 printf("uhci_check_intr: no ii? %p\n", ii);
782 return;
783 }
784 #endif
785 if (!ii->stdstart)
786 return;
787 lstd = ii->stdend;
788 #ifdef DIAGNOSTIC
789 if (!lstd) {
790 printf("uhci_check_intr: std==0\n");
791 return;
792 }
793 #endif
794 /*
795 * If the last TD is still active we need to check whether there
796 * is a an error somewhere in the middle, or whether there was a
797 * short packet (SPD and not ACTIVE).
798 */
799 if (lstd->td->td_status & UHCI_TD_ACTIVE) {
800 DPRINTFN(15, ("uhci_check_intr: active ii=%p\n", ii));
801 for (std = ii->stdstart; std != lstd; std = std->td->link.std){
802 status = std->td->td_status;
803 if ((status & UHCI_TD_STALLED) ||
804 (status & (UHCI_TD_SPD | UHCI_TD_ACTIVE)) ==
805 UHCI_TD_SPD)
806 goto done;
807 }
808 DPRINTFN(15, ("uhci_check_intr: ii=%p std=%p still active\n",
809 ii, ii->stdstart));
810 return;
811 }
812 done:
813 usb_untimeout(uhci_timeout, ii, ii->timeout_handle);
814 upipe = (struct uhci_pipe *)ii->reqh->pipe;
815 upipe->pipe.endpoint->toggle = upipe->nexttoggle;
816 uhci_ii_done(ii, 0);
817 }
818
819 void
820 uhci_ii_done(ii, timo)
821 uhci_intr_info_t *ii;
822 int timo;
823 {
824 usbd_request_handle reqh = ii->reqh;
825 uhci_soft_td_t *std;
826 u_int32_t status;
827 int actlen;
828
829 DPRINTFN(10, ("uhci_ii_done: ii=%p ready %d\n", ii, timo));
830
831 #ifdef DIAGNOSTIC
832 {
833 int s = splhigh();
834 if (ii->isdone) {
835 splx(s);
836 printf("uhci_ii_done: is done!\n");
837 return;
838 }
839 ii->isdone = 1;
840 splx(s);
841 }
842 #endif
843
844 /* The transfer is done, compute actual length and status. */
845 /* XXX Should stop at first inactive to get toggle right. */
846 /* XXX Is this correct for control xfers? */
847 actlen = 0;
848 for (std = ii->stdstart; std; std = std->td->link.std) {
849 status = std->td->td_status;
850 if (status & UHCI_TD_ACTIVE)
851 break;
852 if (UHCI_TD_GET_PID(std->td->td_token) != UHCI_TD_PID_SETUP)
853 actlen += UHCI_TD_GET_ACTLEN(status);
854 }
855 status &= UHCI_TD_ERROR;
856 DPRINTFN(10, ("uhci_check_intr: actlen=%d, status=0x%x\n",
857 actlen, status));
858 reqh->actlen = actlen;
859 if (status != 0) {
860 DPRINTFN(-1+((status&UHCI_TD_STALLED)!=0),
861 ("uhci_ii_done: error, addr=%d, endpt=0x%02x, "
862 "status 0x%b\n",
863 reqh->pipe->device->address,
864 reqh->pipe->endpoint->edesc->bEndpointAddress,
865 (int)status,
866 "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27"
867 "STALLED\30ACTIVE"));
868 if (status == UHCI_TD_STALLED)
869 reqh->status = USBD_STALLED;
870 else
871 reqh->status = USBD_IOERROR; /* more info XXX */
872 } else {
873 reqh->status = USBD_NORMAL_COMPLETION;
874 }
875 if (timo) {
876 /* We got a timeout. Make sure transaction is not active. */
877 reqh->status = USBD_TIMEOUT;
878 for (std = ii->stdstart; std != 0; std = std->td->link.std)
879 std->td->td_status &= ~UHCI_TD_ACTIVE;
880 /* XXX should we wait 1 ms */
881 }
882 DPRINTFN(5, ("uhci_ii_done: calling handler ii=%p\n", ii));
883
884 switch (reqh->pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
885 case UE_CONTROL:
886 uhci_ctrl_done(ii);
887 usb_start_next(reqh->pipe);
888 break;
889 case UE_ISOCHRONOUS:
890 uhci_isoc_done(ii);
891 usb_start_next(reqh->pipe);
892 break;
893 case UE_BULK:
894 uhci_bulk_done(ii);
895 usb_start_next(reqh->pipe);
896 break;
897 case UE_INTERRUPT:
898 uhci_intr_done(ii);
899 break;
900 }
901
902 /* And finally execute callback. */
903 reqh->xfercb(reqh);
904 }
905
906 /*
907 * Called when a request does not complete.
908 */
909 void
910 uhci_timeout(addr)
911 void *addr;
912 {
913 uhci_intr_info_t *ii = addr;
914 int s;
915
916 DPRINTF(("uhci_timeout: ii=%p\n", ii));
917 s = splusb();
918 uhci_ii_done(ii, 1);
919 splx(s);
920 }
921
922 /*
923 * Wait here until controller claims to have an interrupt.
924 * Then call uhci_intr and return. Use timeout to avoid waiting
925 * too long.
926 * Only used during boot when interrupts are not enabled yet.
927 */
928 void
929 uhci_waitintr(sc, reqh)
930 uhci_softc_t *sc;
931 usbd_request_handle reqh;
932 {
933 int timo = reqh->timeout;
934 uhci_intr_info_t *ii;
935
936 DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo));
937
938 reqh->status = USBD_IN_PROGRESS;
939 for (; timo >= 0; timo--) {
940 usb_delay_ms(&sc->sc_bus, 1);
941 DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
942 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) {
943 uhci_intr(sc);
944 if (reqh->status != USBD_IN_PROGRESS)
945 return;
946 }
947 }
948
949 /* Timeout */
950 DPRINTF(("uhci_waitintr: timeout\n"));
951 for (ii = LIST_FIRST(&sc->sc_intrhead);
952 ii && ii->reqh != reqh;
953 ii = LIST_NEXT(ii, list))
954 ;
955 if (ii)
956 uhci_ii_done(ii, 1);
957 else
958 panic("uhci_waitintr: lost intr_info\n");
959 }
960
961 void
962 uhci_poll(bus)
963 struct usbd_bus *bus;
964 {
965 uhci_softc_t *sc = (uhci_softc_t *)bus;
966
967 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT)
968 uhci_intr(sc);
969 }
970
971 #if 0
972 void
973 uhci_reset(p)
974 void *p;
975 {
976 uhci_softc_t *sc = p;
977 int n;
978
979 UHCICMD(sc, UHCI_CMD_HCRESET);
980 /* The reset bit goes low when the controller is done. */
981 for (n = 0; n < UHCI_RESET_TIMEOUT &&
982 (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++)
983 delay(100);
984 if (n >= UHCI_RESET_TIMEOUT)
985 printf("%s: controller did not reset\n",
986 USBDEVNAME(sc->sc_bus.bdev));
987 }
988 #endif
989
990 usbd_status
991 uhci_run(sc, run)
992 uhci_softc_t *sc;
993 int run;
994 {
995 int s, n, running;
996
997 run = run != 0;
998 s = splusb();
999 DPRINTF(("uhci_run: setting run=%d\n", run));
1000 UHCICMD(sc, run ? UHCI_CMD_RS : 0);
1001 for(n = 0; n < 10; n++) {
1002 running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH);
1003 /* return when we've entered the state we want */
1004 if (run == running) {
1005 splx(s);
1006 DPRINTF(("uhci_run: done cmd=0x%x sts=0x%x\n",
1007 UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS)));
1008 return (USBD_NORMAL_COMPLETION);
1009 }
1010 usb_delay_ms(&sc->sc_bus, 1);
1011 }
1012 splx(s);
1013 printf("%s: cannot %s\n", USBDEVNAME(sc->sc_bus.bdev),
1014 run ? "start" : "stop");
1015 return (USBD_IOERROR);
1016 }
1017
1018 /*
1019 * Memory management routines.
1020 * uhci_alloc_std allocates TDs
1021 * uhci_alloc_sqh allocates QHs
1022 * These two routines do their own free list management,
1023 * partly for speed, partly because allocating DMAable memory
1024 * has page size granularaity so much memory would be wasted if
1025 * only one TD/QH (32 bytes) was placed in each allocated chunk.
1026 */
1027
1028 uhci_soft_td_t *
1029 uhci_alloc_std(sc)
1030 uhci_softc_t *sc;
1031 {
1032 uhci_soft_td_t *std;
1033 usbd_status r;
1034 int i;
1035 usb_dma_t dma;
1036
1037 if (!sc->sc_freetds) {
1038 DPRINTFN(2,("uhci_alloc_std: allocating chunk\n"));
1039 std = malloc(sizeof(uhci_soft_td_t) * UHCI_TD_CHUNK,
1040 M_USBHC, M_NOWAIT);
1041 if (!std)
1042 return (0);
1043 r = usb_allocmem(sc->sc_dmatag, UHCI_TD_SIZE * UHCI_TD_CHUNK,
1044 UHCI_TD_ALIGN, &dma);
1045 if (r != USBD_NORMAL_COMPLETION) {
1046 free(std, M_USBHC);
1047 return (0);
1048 }
1049 for(i = 0; i < UHCI_TD_CHUNK; i++, std++) {
1050 std->physaddr = DMAADDR(&dma) + i * UHCI_TD_SIZE;
1051 std->td = (uhci_td_t *)
1052 ((char *)KERNADDR(&dma) + i * UHCI_TD_SIZE);
1053 std->td->link.std = sc->sc_freetds;
1054 sc->sc_freetds = std;
1055 }
1056 }
1057 std = sc->sc_freetds;
1058 sc->sc_freetds = std->td->link.std;
1059 memset(std->td, 0, UHCI_TD_SIZE);
1060 return std;
1061 }
1062
1063 void
1064 uhci_free_std(sc, std)
1065 uhci_softc_t *sc;
1066 uhci_soft_td_t *std;
1067 {
1068 #ifdef DIAGNOSTIC
1069 #define TD_IS_FREE 0x12345678
1070 if (std->td->td_token == TD_IS_FREE) {
1071 printf("uhci_free_std: freeing free TD %p\n", std);
1072 return;
1073 }
1074 std->td->td_token = TD_IS_FREE;
1075 #endif
1076 std->td->link.std = sc->sc_freetds;
1077 sc->sc_freetds = std;
1078 }
1079
1080 uhci_soft_qh_t *
1081 uhci_alloc_sqh(sc)
1082 uhci_softc_t *sc;
1083 {
1084 uhci_soft_qh_t *sqh;
1085 usbd_status r;
1086 int i, offs;
1087 usb_dma_t dma;
1088
1089 if (!sc->sc_freeqhs) {
1090 DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n"));
1091 sqh = malloc(sizeof(uhci_soft_qh_t) * UHCI_QH_CHUNK,
1092 M_USBHC, M_NOWAIT);
1093 if (!sqh)
1094 return 0;
1095 r = usb_allocmem(sc->sc_dmatag, UHCI_QH_SIZE * UHCI_QH_CHUNK,
1096 UHCI_QH_ALIGN, &dma);
1097 if (r != USBD_NORMAL_COMPLETION) {
1098 free(sqh, M_USBHC);
1099 return 0;
1100 }
1101 for(i = 0; i < UHCI_QH_CHUNK; i++, sqh++) {
1102 offs = i * UHCI_QH_SIZE;
1103 sqh->physaddr = DMAADDR(&dma) + offs;
1104 sqh->qh = (uhci_qh_t *)
1105 ((char *)KERNADDR(&dma) + offs);
1106 sqh->qh->hlink = sc->sc_freeqhs;
1107 sc->sc_freeqhs = sqh;
1108 }
1109 }
1110 sqh = sc->sc_freeqhs;
1111 sc->sc_freeqhs = sqh->qh->hlink;
1112 memset(sqh->qh, 0, UHCI_QH_SIZE);
1113 return (sqh);
1114 }
1115
1116 void
1117 uhci_free_sqh(sc, sqh)
1118 uhci_softc_t *sc;
1119 uhci_soft_qh_t *sqh;
1120 {
1121 sqh->qh->hlink = sc->sc_freeqhs;
1122 sc->sc_freeqhs = sqh;
1123 }
1124
1125 #if 0
1126 /*
1127 * Enter a list of transfers onto a control queue.
1128 * Called at splusb()
1129 */
1130 void
1131 uhci_enter_ctl_q(sc, sqh, ii)
1132 uhci_softc_t *sc;
1133 uhci_soft_qh_t *sqh;
1134 uhci_intr_info_t *ii;
1135 {
1136 DPRINTFN(5, ("uhci_enter_ctl_q: sqh=%p\n", sqh));
1137
1138 }
1139 #endif
1140
1141 void
1142 uhci_free_std_chain(sc, std, stdend)
1143 uhci_softc_t *sc;
1144 uhci_soft_td_t *std;
1145 uhci_soft_td_t *stdend;
1146 {
1147 uhci_soft_td_t *p;
1148
1149 for (; std != stdend; std = p) {
1150 p = std->td->link.std;
1151 uhci_free_std(sc, std);
1152 }
1153 }
1154
1155 usbd_status
1156 uhci_alloc_std_chain(upipe, sc, len, rd, spd, dma, sp, ep)
1157 struct uhci_pipe *upipe;
1158 uhci_softc_t *sc;
1159 int len, rd, spd;
1160 usb_dma_t *dma;
1161 uhci_soft_td_t **sp, **ep;
1162 {
1163 uhci_soft_td_t *p, *lastp;
1164 uhci_physaddr_t lastlink;
1165 int i, ntd, l, tog, maxp;
1166 u_int32_t status;
1167 int addr = upipe->pipe.device->address;
1168 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
1169
1170 DPRINTFN(15, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d ls=%d "
1171 "spd=%d\n", addr, UE_GET_ADDR(endpt), len,
1172 upipe->pipe.device->lowspeed, spd));
1173 if (len == 0) {
1174 *sp = *ep = 0;
1175 DPRINTFN(-1,("uhci_alloc_std_chain: len=0\n"));
1176 return (USBD_NORMAL_COMPLETION);
1177 }
1178 maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize);
1179 if (maxp == 0) {
1180 printf("uhci_alloc_std_chain: maxp=0\n");
1181 return (USBD_INVAL);
1182 }
1183 ntd = (len + maxp - 1) / maxp;
1184 tog = upipe->pipe.endpoint->toggle;
1185 if (ntd % 2 == 0)
1186 tog ^= 1;
1187 upipe->nexttoggle = tog ^ 1;
1188 lastp = 0;
1189 lastlink = UHCI_PTR_T;
1190 ntd--;
1191 status = UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE;
1192 if (upipe->pipe.device->lowspeed)
1193 status |= UHCI_TD_LS;
1194 if (spd)
1195 status |= UHCI_TD_SPD;
1196 for (i = ntd; i >= 0; i--) {
1197 p = uhci_alloc_std(sc);
1198 if (!p) {
1199 uhci_free_std_chain(sc, lastp, 0);
1200 return (USBD_NOMEM);
1201 }
1202 p->td->link.std = lastp;
1203 p->td->td_link = lastlink;
1204 lastp = p;
1205 lastlink = p->physaddr;
1206 p->td->td_status = status;
1207 if (i == ntd) {
1208 /* last TD */
1209 l = len % maxp;
1210 if (l == 0) l = maxp;
1211 *ep = p;
1212 } else
1213 l = maxp;
1214 p->td->td_token =
1215 rd ? UHCI_TD_IN (l, endpt, addr, tog) :
1216 UHCI_TD_OUT(l, endpt, addr, tog);
1217 p->td->td_buffer = DMAADDR(dma) + i * maxp;
1218 tog ^= 1;
1219 }
1220 *sp = lastp;
1221 /*upipe->pipe.endpoint->toggle = tog;*/
1222 DPRINTFN(10, ("uhci_alloc_std_chain: oldtog=%d newtog=%d\n",
1223 upipe->pipe.endpoint->toggle, upipe->nexttoggle));
1224 return (USBD_NORMAL_COMPLETION);
1225 }
1226
1227 usbd_status
1228 uhci_device_bulk_transfer(reqh)
1229 usbd_request_handle reqh;
1230 {
1231 int s;
1232 usbd_status r;
1233
1234 s = splusb();
1235 r = usb_insert_transfer(reqh);
1236 splx(s);
1237 if (r != USBD_NORMAL_COMPLETION)
1238 return (r);
1239 else
1240 return (uhci_device_bulk_start(reqh));
1241 }
1242
1243 usbd_status
1244 uhci_device_bulk_start(reqh)
1245 usbd_request_handle reqh;
1246 {
1247 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1248 usbd_device_handle dev = upipe->pipe.device;
1249 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1250 uhci_intr_info_t *ii = upipe->iinfo;
1251 uhci_soft_td_t *xfer, *xferend;
1252 uhci_soft_qh_t *sqh;
1253 usb_dma_t *dmap;
1254 usbd_status r;
1255 int len, isread;
1256 int s;
1257
1258 DPRINTFN(3, ("uhci_device_bulk_transfer: reqh=%p buf=%p len=%d "
1259 "flags=%d\n",
1260 reqh, reqh->buffer, reqh->length, reqh->flags));
1261
1262 if (reqh->isreq)
1263 panic("uhci_device_bulk_transfer: a request\n");
1264
1265 len = reqh->length;
1266 dmap = &upipe->u.bulk.datadma;
1267 isread = reqh->pipe->endpoint->edesc->bEndpointAddress & UE_IN;
1268 sqh = upipe->u.bulk.sqh;
1269
1270 upipe->u.bulk.isread = isread;
1271 upipe->u.bulk.length = len;
1272
1273 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1274 if (r != USBD_NORMAL_COMPLETION)
1275 goto ret1;
1276 r = uhci_alloc_std_chain(upipe, sc, len, isread,
1277 reqh->flags & USBD_SHORT_XFER_OK,
1278 dmap, &xfer, &xferend);
1279 if (r != USBD_NORMAL_COMPLETION)
1280 goto ret2;
1281 xferend->td->td_status |= UHCI_TD_IOC;
1282
1283 if (!isread && len != 0)
1284 memcpy(KERNADDR(dmap), reqh->buffer, len);
1285
1286 #ifdef USB_DEBUG
1287 if (uhcidebug > 10) {
1288 printf("uhci_device_bulk_transfer: xfer(1)\n");
1289 uhci_dump_tds(xfer);
1290 }
1291 #endif
1292
1293 /* Set up interrupt info. */
1294 ii->reqh = reqh;
1295 ii->stdstart = xfer;
1296 ii->stdend = xferend;
1297 #ifdef DIAGNOSTIC
1298 ii->isdone = 0;
1299 #endif
1300
1301 sqh->qh->elink = xfer;
1302 sqh->qh->qh_elink = xfer->physaddr;
1303 sqh->intr_info = ii;
1304
1305 s = splusb();
1306 uhci_add_bulk(sc, sqh);
1307 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
1308
1309 if (reqh->timeout && !sc->sc_bus.use_polling) {
1310 usb_timeout(uhci_timeout, ii,
1311 MS_TO_TICKS(reqh->timeout), ii->timeout_handle);
1312 }
1313 splx(s);
1314
1315 #ifdef USB_DEBUG
1316 if (uhcidebug > 10) {
1317 printf("uhci_device_bulk_transfer: xfer(2)\n");
1318 uhci_dump_tds(xfer);
1319 }
1320 #endif
1321
1322 if (sc->sc_bus.use_polling)
1323 uhci_waitintr(sc, reqh);
1324
1325 return (USBD_IN_PROGRESS);
1326
1327 ret2:
1328 if (len != 0)
1329 usb_freemem(sc->sc_dmatag, dmap);
1330 ret1:
1331 return (r);
1332 }
1333
1334 /* Abort a device bulk request. */
1335 void
1336 uhci_device_bulk_abort(reqh)
1337 usbd_request_handle reqh;
1338 {
1339 /* XXX inactivate */
1340 usb_delay_ms(reqh->pipe->device->bus, 1);/* make sure it is done */
1341 /* XXX call done */
1342 }
1343
1344 /* Close a device bulk pipe. */
1345 void
1346 uhci_device_bulk_close(pipe)
1347 usbd_pipe_handle pipe;
1348 {
1349 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1350 usbd_device_handle dev = upipe->pipe.device;
1351 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1352
1353 uhci_free_sqh(sc, upipe->u.bulk.sqh);
1354 uhci_free_intr_info(upipe->iinfo);
1355 /* XXX free other resources */
1356 }
1357
1358 usbd_status
1359 uhci_device_ctrl_transfer(reqh)
1360 usbd_request_handle reqh;
1361 {
1362 int s;
1363 usbd_status r;
1364
1365 s = splusb();
1366 r = usb_insert_transfer(reqh);
1367 splx(s);
1368 if (r != USBD_NORMAL_COMPLETION)
1369 return (r);
1370 else
1371 return (uhci_device_ctrl_start(reqh));
1372 }
1373
1374 usbd_status
1375 uhci_device_ctrl_start(reqh)
1376 usbd_request_handle reqh;
1377 {
1378 uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus;
1379 usbd_status r;
1380
1381 if (!reqh->isreq)
1382 panic("uhci_device_ctrl_transfer: not a request\n");
1383
1384 r = uhci_device_request(reqh);
1385 if (r != USBD_NORMAL_COMPLETION)
1386 return (r);
1387
1388 if (sc->sc_bus.use_polling)
1389 uhci_waitintr(sc, reqh);
1390 return (USBD_IN_PROGRESS);
1391 }
1392
1393 usbd_status
1394 uhci_device_intr_transfer(reqh)
1395 usbd_request_handle reqh;
1396 {
1397 int s;
1398 usbd_status r;
1399
1400 s = splusb();
1401 r = usb_insert_transfer(reqh);
1402 splx(s);
1403 if (r != USBD_NORMAL_COMPLETION)
1404 return (r);
1405 else
1406 return (uhci_device_intr_start(reqh));
1407 }
1408
1409 usbd_status
1410 uhci_device_intr_start(reqh)
1411 usbd_request_handle reqh;
1412 {
1413 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1414 usbd_device_handle dev = upipe->pipe.device;
1415 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1416 uhci_intr_info_t *ii = upipe->iinfo;
1417 uhci_soft_td_t *xfer, *xferend;
1418 uhci_soft_qh_t *sqh;
1419 usb_dma_t *dmap;
1420 usbd_status r;
1421 int len, i;
1422 int s;
1423
1424 DPRINTFN(3, ("uhci_device_intr_transfer: reqh=%p buf=%p len=%d "
1425 "flags=%d\n",
1426 reqh, reqh->buffer, reqh->length, reqh->flags));
1427
1428 if (reqh->isreq)
1429 panic("uhci_device_intr_transfer: a request\n");
1430
1431 len = reqh->length;
1432 dmap = &upipe->u.intr.datadma;
1433 if (len == 0)
1434 return (USBD_INVAL); /* XXX should it be? */
1435
1436 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1437 if (r != USBD_NORMAL_COMPLETION)
1438 goto ret1;
1439 r = uhci_alloc_std_chain(upipe, sc, len, 1,
1440 reqh->flags & USBD_SHORT_XFER_OK,
1441 dmap, &xfer, &xferend);
1442 if (r != USBD_NORMAL_COMPLETION)
1443 goto ret2;
1444 xferend->td->td_status |= UHCI_TD_IOC;
1445
1446 #ifdef USB_DEBUG
1447 if (uhcidebug > 10) {
1448 printf("uhci_device_intr_transfer: xfer(1)\n");
1449 uhci_dump_tds(xfer);
1450 uhci_dump_qh(upipe->u.intr.qhs[0]);
1451 }
1452 #endif
1453
1454 s = splusb();
1455 /* Set up interrupt info. */
1456 ii->reqh = reqh;
1457 ii->stdstart = xfer;
1458 ii->stdend = xferend;
1459 #ifdef DIAGNOSTIC
1460 ii->isdone = 0;
1461 #endif
1462
1463 DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n",
1464 upipe->u.intr.qhs[0]));
1465 for (i = 0; i < upipe->u.intr.npoll; i++) {
1466 sqh = upipe->u.intr.qhs[i];
1467 sqh->qh->elink = xfer;
1468 sqh->qh->qh_elink = xfer->physaddr;
1469 }
1470 splx(s);
1471
1472 #ifdef USB_DEBUG
1473 if (uhcidebug > 10) {
1474 printf("uhci_device_intr_transfer: xfer(2)\n");
1475 uhci_dump_tds(xfer);
1476 uhci_dump_qh(upipe->u.intr.qhs[0]);
1477 }
1478 #endif
1479
1480 return (USBD_IN_PROGRESS);
1481
1482 ret2:
1483 if (len != 0)
1484 usb_freemem(sc->sc_dmatag, dmap);
1485 ret1:
1486 return (r);
1487 }
1488
1489 /* Abort a device control request. */
1490 void
1491 uhci_device_ctrl_abort(reqh)
1492 usbd_request_handle reqh;
1493 {
1494 /* XXX inactivate */
1495 usb_delay_ms(reqh->pipe->device->bus, 1); /* make sure it is done */
1496 /* XXX call done */
1497 }
1498
1499 /* Close a device control pipe. */
1500 void
1501 uhci_device_ctrl_close(pipe)
1502 usbd_pipe_handle pipe;
1503 {
1504 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1505
1506 uhci_free_intr_info(upipe->iinfo);
1507 /* XXX free other resources */
1508 }
1509
1510 /* Abort a device interrupt request. */
1511 void
1512 uhci_device_intr_abort(reqh)
1513 usbd_request_handle reqh;
1514 {
1515 struct uhci_pipe *upipe;
1516
1517 DPRINTFN(1, ("uhci_device_intr_abort: reqh=%p\n", reqh));
1518 /* XXX inactivate */
1519 usb_delay_ms(reqh->pipe->device->bus, 2); /* make sure it is done */
1520 if (reqh->pipe->repeat) {
1521 DPRINTF(("uhci_device_intr_abort: remove\n"));
1522 reqh->pipe->repeat = 0;
1523 upipe = (struct uhci_pipe *)reqh->pipe;
1524 uhci_intr_done(upipe->u.intr.qhs[0]->intr_info);
1525 }
1526 }
1527
1528 /* Close a device interrupt pipe. */
1529 void
1530 uhci_device_intr_close(pipe)
1531 usbd_pipe_handle pipe;
1532 {
1533 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1534 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
1535 int i, s, npoll;
1536
1537 upipe->iinfo->stdstart = 0; /* inactive */
1538
1539 /* Unlink descriptors from controller data structures. */
1540 npoll = upipe->u.intr.npoll;
1541 uhci_lock_frames(sc);
1542 for (i = 0; i < npoll; i++)
1543 uhci_remove_intr(sc, upipe->u.intr.qhs[i]->pos,
1544 upipe->u.intr.qhs[i]);
1545 uhci_unlock_frames(sc);
1546
1547 /*
1548 * We now have to wait for any activity on the physical
1549 * descriptors to stop.
1550 */
1551 usb_delay_ms(&sc->sc_bus, 2);
1552
1553 for(i = 0; i < npoll; i++)
1554 uhci_free_sqh(sc, upipe->u.intr.qhs[i]);
1555 free(upipe->u.intr.qhs, M_USBHC);
1556
1557 s = splusb();
1558 LIST_REMOVE(upipe->iinfo, list); /* remove from active list */
1559 splx(s);
1560 uhci_free_intr_info(upipe->iinfo);
1561
1562 /* XXX free other resources */
1563 }
1564
1565 usbd_status
1566 uhci_device_request(reqh)
1567 usbd_request_handle reqh;
1568 {
1569 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1570 usb_device_request_t *req = &reqh->request;
1571 usbd_device_handle dev = upipe->pipe.device;
1572 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1573 int addr = dev->address;
1574 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
1575 uhci_intr_info_t *ii = upipe->iinfo;
1576 uhci_soft_td_t *setup, *xfer, *stat, *next, *xferend;
1577 uhci_soft_qh_t *sqh;
1578 usb_dma_t *dmap;
1579 int len;
1580 u_int32_t ls;
1581 usbd_status r;
1582 int isread;
1583 int s;
1584
1585 DPRINTFN(3,("uhci_device_control type=0x%02x, request=0x%02x, "
1586 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
1587 req->bmRequestType, req->bRequest, UGETW(req->wValue),
1588 UGETW(req->wIndex), UGETW(req->wLength),
1589 addr, endpt));
1590
1591 ls = dev->lowspeed ? UHCI_TD_LS : 0;
1592 isread = req->bmRequestType & UT_READ;
1593 len = UGETW(req->wLength);
1594
1595 setup = upipe->u.ctl.setup;
1596 stat = upipe->u.ctl.stat;
1597 sqh = upipe->u.ctl.sqh;
1598 dmap = &upipe->u.ctl.datadma;
1599
1600 /* Set up data transaction */
1601 if (len != 0) {
1602 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1603 if (r != USBD_NORMAL_COMPLETION)
1604 goto ret1;
1605 upipe->pipe.endpoint->toggle = 1;
1606 r = uhci_alloc_std_chain(upipe, sc, len, isread,
1607 reqh->flags & USBD_SHORT_XFER_OK,
1608 dmap, &xfer, &xferend);
1609 if (r != USBD_NORMAL_COMPLETION)
1610 goto ret2;
1611 next = xfer;
1612 xferend->td->link.std = stat;
1613 xferend->td->td_link = stat->physaddr;
1614 } else {
1615 next = stat;
1616 }
1617 upipe->u.ctl.length = len;
1618
1619 memcpy(KERNADDR(&upipe->u.ctl.reqdma), req, sizeof *req);
1620 if (!isread && len != 0)
1621 memcpy(KERNADDR(dmap), reqh->buffer, len);
1622
1623 setup->td->link.std = next;
1624 setup->td->td_link = next->physaddr;
1625 setup->td->td_status = UHCI_TD_SET_ERRCNT(2) | ls | UHCI_TD_ACTIVE;
1626 setup->td->td_token = UHCI_TD_SETUP(sizeof *req, endpt, addr);
1627 setup->td->td_buffer = DMAADDR(&upipe->u.ctl.reqdma);
1628
1629 stat->td->link.std = 0;
1630 stat->td->td_link = UHCI_PTR_T;
1631 stat->td->td_status = UHCI_TD_SET_ERRCNT(2) | ls |
1632 UHCI_TD_ACTIVE | UHCI_TD_IOC;
1633 stat->td->td_token =
1634 isread ? UHCI_TD_OUT(0, endpt, addr, 1) :
1635 UHCI_TD_IN (0, endpt, addr, 1);
1636 stat->td->td_buffer = 0;
1637
1638 #ifdef USB_DEBUG
1639 if (uhcidebug > 20) {
1640 printf("uhci_device_request: setup\n");
1641 uhci_dump_td(setup);
1642 printf("uhci_device_request: stat\n");
1643 uhci_dump_td(stat);
1644 }
1645 #endif
1646
1647 /* Set up interrupt info. */
1648 ii->reqh = reqh;
1649 ii->stdstart = setup;
1650 ii->stdend = stat;
1651 #ifdef DIAGNOSTIC
1652 ii->isdone = 0;
1653 #endif
1654
1655 sqh->qh->elink = setup;
1656 sqh->qh->qh_elink = setup->physaddr;
1657 sqh->intr_info = ii;
1658
1659 s = splusb();
1660 uhci_add_ctrl(sc, sqh);
1661 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
1662 #ifdef USB_DEBUG
1663 if (uhcidebug > 12) {
1664 uhci_soft_td_t *std;
1665 uhci_soft_qh_t *xqh;
1666 uhci_soft_qh_t *sxqh;
1667 int maxqh = 0;
1668 uhci_physaddr_t link;
1669 printf("uhci_enter_ctl_q: follow from [0]\n");
1670 for (std = sc->sc_vframes[0].htd, link = 0;
1671 (link & UHCI_PTR_Q) == 0;
1672 std = std->td->link.std) {
1673 link = std->td->td_link;
1674 uhci_dump_td(std);
1675 }
1676 for (sxqh = xqh = (uhci_soft_qh_t *)std;
1677 xqh;
1678 xqh = (maxqh++ == 5 || xqh->qh->hlink==sxqh ||
1679 xqh->qh->hlink==xqh ? NULL : xqh->qh->hlink)) {
1680 uhci_dump_qh(xqh);
1681 uhci_dump_qh(sxqh);
1682 }
1683 printf("Enqueued QH:\n");
1684 uhci_dump_qh(sqh);
1685 uhci_dump_tds(sqh->qh->elink);
1686 }
1687 #endif
1688 if (reqh->timeout && !sc->sc_bus.use_polling) {
1689 usb_timeout(uhci_timeout, ii,
1690 MS_TO_TICKS(reqh->timeout), ii->timeout_handle);
1691 }
1692 splx(s);
1693
1694 return (USBD_NORMAL_COMPLETION);
1695
1696 ret2:
1697 if (len != 0)
1698 usb_freemem(sc->sc_dmatag, dmap);
1699 ret1:
1700 return (r);
1701 }
1702
1703 usbd_status
1704 uhci_device_isoc_transfer(reqh)
1705 usbd_request_handle reqh;
1706 {
1707 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1708 #ifdef USB_DEBUG
1709 usbd_device_handle dev = upipe->pipe.device;
1710 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1711 #endif
1712
1713 DPRINTFN(1,("uhci_device_isoc_transfer: sc=%p\n", sc));
1714 if (upipe->u.iso.bufsize == 0)
1715 return (USBD_INVAL);
1716
1717 /* XXX copy data */
1718 return (USBD_XXX);
1719 }
1720
1721 usbd_status
1722 uhci_device_isoc_start(reqh)
1723 usbd_request_handle reqh;
1724 {
1725 return (USBD_XXX);
1726 }
1727
1728 void
1729 uhci_device_isoc_abort(reqh)
1730 usbd_request_handle reqh;
1731 {
1732 /* XXX Can't abort a single request. */
1733 }
1734
1735 void
1736 uhci_device_isoc_close(pipe)
1737 usbd_pipe_handle pipe;
1738 {
1739 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1740 usbd_device_handle dev = upipe->pipe.device;
1741 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1742 struct iso *iso;
1743 int i;
1744
1745 /*
1746 * Make sure all TDs are marked as inactive.
1747 * Wait for completion.
1748 * Unschedule.
1749 * Deallocate.
1750 */
1751 iso = &upipe->u.iso;
1752
1753 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++)
1754 iso->stds[i]->td->td_status &= ~UHCI_TD_ACTIVE;
1755 usb_delay_ms(&sc->sc_bus, 2); /* wait for completion */
1756
1757 uhci_lock_frames(sc);
1758 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
1759 uhci_soft_td_t *std, *vstd;
1760
1761 std = iso->stds[i];
1762 for (vstd = sc->sc_vframes[i % UHCI_VFRAMELIST_COUNT].htd;
1763 vstd && vstd->td->link.std != std;
1764 vstd = vstd->td->link.std)
1765 ;
1766 if (!vstd) {
1767 /*panic*/
1768 printf("uhci_device_isoc_close: %p not found\n", std);
1769 uhci_unlock_frames(sc);
1770 return;
1771 }
1772 vstd->td->link = std->td->link;
1773 vstd->td->td_link = std->td->td_link;
1774 uhci_free_std(sc, std);
1775 }
1776 uhci_unlock_frames(sc);
1777
1778 for (i = 0; i < iso->nbuf; i++)
1779 usb_freemem(sc->sc_dmatag, &iso->bufs[i]);
1780 free(iso->stds, M_USBHC);
1781 free(iso->bufs, M_USBHC);
1782
1783 /* XXX what else? */
1784 }
1785
1786 usbd_status
1787 uhci_device_isoc_setbuf(pipe, bufsize, nbuf)
1788 usbd_pipe_handle pipe;
1789 u_int bufsize;
1790 u_int nbuf;
1791 {
1792 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1793 usbd_device_handle dev = upipe->pipe.device;
1794 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1795 int addr = upipe->pipe.device->address;
1796 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
1797 int rd = upipe->pipe.endpoint->edesc->bEndpointAddress & UE_IN;
1798 struct iso *iso;
1799 int i;
1800 usbd_status r;
1801
1802 /*
1803 * For simplicity the number of buffers must fit nicely in the frame
1804 * list.
1805 */
1806 if (UHCI_VFRAMELIST_COUNT % nbuf != 0)
1807 return (USBD_INVAL);
1808
1809 iso = &upipe->u.iso;
1810 iso->bufsize = bufsize;
1811 iso->nbuf = nbuf;
1812
1813 /* Allocate memory for buffers. */
1814 iso->bufs = malloc(nbuf * sizeof(usb_dma_t), M_USBHC, M_WAITOK);
1815 iso->stds = malloc(UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *),
1816 M_USBHC, M_WAITOK);
1817
1818 for (i = 0; i < nbuf; i++) {
1819 r = usb_allocmem(sc->sc_dmatag, bufsize, 0, &iso->bufs[i]);
1820 if (r != USBD_NORMAL_COMPLETION) {
1821 nbuf = i;
1822 goto bad1;
1823 }
1824 }
1825
1826 /* Allocate the TDs. */
1827 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
1828 iso->stds[i] = uhci_alloc_std(sc);
1829 if (iso->stds[i] == 0)
1830 goto bad2;
1831 }
1832
1833 /* XXX check schedule */
1834
1835 /* XXX interrupts */
1836
1837 /* Insert TDs into schedule, all marked inactive. */
1838 uhci_lock_frames(sc);
1839 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
1840 uhci_soft_td_t *std, *vstd;
1841
1842 std = iso->stds[i];
1843 std->td->td_status = UHCI_TD_IOS; /* iso, inactive */
1844 std->td->td_token =
1845 rd ? UHCI_TD_IN (0, endpt, addr, 0) :
1846 UHCI_TD_OUT(0, endpt, addr, 0);
1847 std->td->td_buffer = DMAADDR(&iso->bufs[i % nbuf]);
1848
1849 vstd = sc->sc_vframes[i % UHCI_VFRAMELIST_COUNT].htd;
1850 std->td->link = vstd->td->link;
1851 std->td->td_link = vstd->td->td_link;
1852 vstd->td->link.std = std;
1853 vstd->td->td_link = std->physaddr;
1854 }
1855 uhci_unlock_frames(sc);
1856
1857 return (USBD_NORMAL_COMPLETION);
1858
1859 bad2:
1860 while (--i >= 0)
1861 uhci_free_std(sc, iso->stds[i]);
1862 bad1:
1863 for (i = 0; i < nbuf; i++)
1864 usb_freemem(sc->sc_dmatag, &iso->bufs[i]);
1865 free(iso->stds, M_USBHC);
1866 free(iso->bufs, M_USBHC);
1867 return (USBD_NOMEM);
1868 }
1869
1870 void
1871 uhci_isoc_done(ii)
1872 uhci_intr_info_t *ii;
1873 {
1874 }
1875
1876 void
1877 uhci_intr_done(ii)
1878 uhci_intr_info_t *ii;
1879 {
1880 uhci_softc_t *sc = ii->sc;
1881 usbd_request_handle reqh = ii->reqh;
1882 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1883 usb_dma_t *dma;
1884 uhci_soft_qh_t *sqh;
1885 int i, npoll;
1886
1887 DPRINTFN(5, ("uhci_intr_done: length=%d\n", reqh->actlen));
1888
1889 dma = &upipe->u.intr.datadma;
1890 memcpy(reqh->buffer, KERNADDR(dma), reqh->actlen);
1891 npoll = upipe->u.intr.npoll;
1892 for(i = 0; i < npoll; i++) {
1893 sqh = upipe->u.intr.qhs[i];
1894 sqh->qh->elink = 0;
1895 sqh->qh->qh_elink = UHCI_PTR_T;
1896 }
1897 uhci_free_std_chain(sc, ii->stdstart, 0);
1898
1899 /* XXX Wasteful. */
1900 if (reqh->pipe->repeat) {
1901 uhci_soft_td_t *xfer, *xferend;
1902
1903 /* This alloc cannot fail since we freed the chain above. */
1904 uhci_alloc_std_chain(upipe, sc, reqh->length, 1,
1905 reqh->flags & USBD_SHORT_XFER_OK,
1906 dma, &xfer, &xferend);
1907 xferend->td->td_status |= UHCI_TD_IOC;
1908
1909 #ifdef USB_DEBUG
1910 if (uhcidebug > 10) {
1911 printf("uhci_device_intr_done: xfer(1)\n");
1912 uhci_dump_tds(xfer);
1913 uhci_dump_qh(upipe->u.intr.qhs[0]);
1914 }
1915 #endif
1916
1917 ii->stdstart = xfer;
1918 ii->stdend = xferend;
1919 #ifdef DIAGNOSTIC
1920 ii->isdone = 0;
1921 #endif
1922 for (i = 0; i < npoll; i++) {
1923 sqh = upipe->u.intr.qhs[i];
1924 sqh->qh->elink = xfer;
1925 sqh->qh->qh_elink = xfer->physaddr;
1926 }
1927 } else {
1928 usb_freemem(sc->sc_dmatag, dma);
1929 ii->stdstart = 0; /* mark as inactive */
1930 usb_start_next(reqh->pipe);
1931 }
1932 }
1933
1934 /* Deallocate request data structures */
1935 void
1936 uhci_ctrl_done(ii)
1937 uhci_intr_info_t *ii;
1938 {
1939 uhci_softc_t *sc = ii->sc;
1940 usbd_request_handle reqh = ii->reqh;
1941 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1942 u_int len = upipe->u.ctl.length;
1943 usb_dma_t *dma;
1944 uhci_td_t *htd = ii->stdstart->td;
1945
1946 #ifdef DIAGNOSTIC
1947 if (!reqh->isreq)
1948 panic("uhci_ctrl_done: not a request\n");
1949 #endif
1950
1951 LIST_REMOVE(ii, list); /* remove from active list */
1952
1953 uhci_remove_ctrl(sc, upipe->u.ctl.sqh);
1954
1955 if (len != 0) {
1956 dma = &upipe->u.ctl.datadma;
1957 if (reqh->request.bmRequestType & UT_READ)
1958 memcpy(reqh->buffer, KERNADDR(dma), len);
1959 uhci_free_std_chain(sc, htd->link.std, ii->stdend);
1960 usb_freemem(sc->sc_dmatag, dma);
1961 }
1962 DPRINTFN(5, ("uhci_ctrl_done: length=%d\n", reqh->actlen));
1963 }
1964
1965 /* Deallocate request data structures */
1966 void
1967 uhci_bulk_done(ii)
1968 uhci_intr_info_t *ii;
1969 {
1970 uhci_softc_t *sc = ii->sc;
1971 usbd_request_handle reqh = ii->reqh;
1972 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1973 uhci_soft_td_t *std;
1974 u_int datalen = upipe->u.bulk.length;
1975 usb_dma_t *dma;
1976
1977 LIST_REMOVE(ii, list); /* remove from active list */
1978
1979 uhci_remove_bulk(sc, upipe->u.bulk.sqh);
1980
1981 /* find the toggle for the last transfer and invert it */
1982 for (std = ii->stdstart; std; std = std->td->link.std) {
1983 if (std->td->td_status & UHCI_TD_ACTIVE)
1984 break;
1985 upipe->nexttoggle = UHCI_TD_GET_DT(std->td->td_token);
1986 }
1987 upipe->nexttoggle ^= 1;
1988
1989 /* copy the data from dma memory to userland storage */
1990 dma = &upipe->u.bulk.datadma;
1991 if (upipe->u.bulk.isread)
1992 memcpy(reqh->buffer, KERNADDR(dma), datalen);
1993 uhci_free_std_chain(sc, ii->stdstart, 0);
1994 usb_freemem(sc->sc_dmatag, dma);
1995
1996 DPRINTFN(4, ("uhci_bulk_done: length=%d\n", reqh->actlen));
1997 }
1998
1999 /* Add interrupt QH, called with vflock. */
2000 void
2001 uhci_add_intr(sc, n, sqh)
2002 uhci_softc_t *sc;
2003 int n;
2004 uhci_soft_qh_t *sqh;
2005 {
2006 struct uhci_vframe *vf = &sc->sc_vframes[n];
2007 uhci_qh_t *eqh;
2008
2009 DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", n, sqh));
2010 eqh = vf->eqh->qh;
2011 sqh->qh->hlink = eqh->hlink;
2012 sqh->qh->qh_hlink = eqh->qh_hlink;
2013 eqh->hlink = sqh;
2014 eqh->qh_hlink = sqh->physaddr | UHCI_PTR_Q;
2015 vf->eqh = sqh;
2016 vf->bandwidth++;
2017 }
2018
2019 /* Remove interrupt QH, called with vflock. */
2020 void
2021 uhci_remove_intr(sc, n, sqh)
2022 uhci_softc_t *sc;
2023 int n;
2024 uhci_soft_qh_t *sqh;
2025 {
2026 struct uhci_vframe *vf = &sc->sc_vframes[n];
2027 uhci_soft_qh_t *pqh;
2028
2029 DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", n, sqh));
2030
2031 for (pqh = vf->hqh; pqh->qh->hlink != sqh; pqh = pqh->qh->hlink)
2032 #if defined(DIAGNOSTIC) || defined(USB_DEBUG)
2033 if (pqh->qh->qh_hlink & UHCI_PTR_T) {
2034 printf("uhci_remove_intr: QH not found\n");
2035 return;
2036 }
2037 #else
2038 ;
2039 #endif
2040 pqh->qh->hlink = sqh->qh->hlink;
2041 pqh->qh->qh_hlink = sqh->qh->qh_hlink;
2042 if (vf->eqh == sqh)
2043 vf->eqh = pqh;
2044 vf->bandwidth--;
2045 }
2046
2047 usbd_status
2048 uhci_device_setintr(sc, upipe, ival)
2049 uhci_softc_t *sc;
2050 struct uhci_pipe *upipe;
2051 int ival;
2052 {
2053 uhci_soft_qh_t *sqh;
2054 int i, npoll, s;
2055 u_int bestbw, bw, bestoffs, offs;
2056
2057 DPRINTFN(2, ("uhci_setintr: pipe=%p\n", upipe));
2058 if (ival == 0) {
2059 printf("uhci_setintr: 0 interval\n");
2060 return (USBD_INVAL);
2061 }
2062
2063 if (ival > UHCI_VFRAMELIST_COUNT)
2064 ival = UHCI_VFRAMELIST_COUNT;
2065 npoll = (UHCI_VFRAMELIST_COUNT + ival - 1) / ival;
2066 DPRINTFN(2, ("uhci_setintr: ival=%d npoll=%d\n", ival, npoll));
2067
2068 upipe->u.intr.npoll = npoll;
2069 upipe->u.intr.qhs =
2070 malloc(npoll * sizeof(uhci_soft_qh_t *), M_USBHC, M_WAITOK);
2071
2072 /*
2073 * Figure out which offset in the schedule that has most
2074 * bandwidth left over.
2075 */
2076 #define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1))
2077 for (bestoffs = offs = 0, bestbw = ~0; offs < ival; offs++) {
2078 for (bw = i = 0; i < npoll; i++)
2079 bw += sc->sc_vframes[MOD(i * ival + offs)].bandwidth;
2080 if (bw < bestbw) {
2081 bestbw = bw;
2082 bestoffs = offs;
2083 }
2084 }
2085 DPRINTFN(1, ("uhci_setintr: bw=%d offs=%d\n", bestbw, bestoffs));
2086
2087 upipe->iinfo->stdstart = 0;
2088 for(i = 0; i < npoll; i++) {
2089 upipe->u.intr.qhs[i] = sqh = uhci_alloc_sqh(sc);
2090 sqh->qh->elink = 0;
2091 sqh->qh->qh_elink = UHCI_PTR_T;
2092 sqh->pos = MOD(i * ival + bestoffs);
2093 sqh->intr_info = upipe->iinfo;
2094 }
2095 #undef MOD
2096
2097 s = splusb();
2098 LIST_INSERT_HEAD(&sc->sc_intrhead, upipe->iinfo, list);
2099 splx(s);
2100
2101 uhci_lock_frames(sc);
2102 /* Enter QHs into the controller data structures. */
2103 for(i = 0; i < npoll; i++)
2104 uhci_add_intr(sc, upipe->u.intr.qhs[i]->pos,
2105 upipe->u.intr.qhs[i]);
2106 uhci_unlock_frames(sc);
2107
2108 DPRINTFN(5, ("uhci_setintr: returns %p\n", upipe));
2109 return (USBD_NORMAL_COMPLETION);
2110 }
2111
2112 /* Open a new pipe. */
2113 usbd_status
2114 uhci_open(pipe)
2115 usbd_pipe_handle pipe;
2116 {
2117 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
2118 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2119 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
2120 usbd_status r;
2121
2122 DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
2123 pipe, pipe->device->address,
2124 ed->bEndpointAddress, sc->sc_addr));
2125 if (pipe->device->address == sc->sc_addr) {
2126 switch (ed->bEndpointAddress) {
2127 case USB_CONTROL_ENDPOINT:
2128 pipe->methods = &uhci_root_ctrl_methods;
2129 break;
2130 case UE_IN | UHCI_INTR_ENDPT:
2131 pipe->methods = &uhci_root_intr_methods;
2132 break;
2133 default:
2134 return (USBD_INVAL);
2135 }
2136 } else {
2137 upipe->iinfo = uhci_alloc_intr_info(sc);
2138 if (upipe->iinfo == 0)
2139 return (USBD_NOMEM);
2140 switch (ed->bmAttributes & UE_XFERTYPE) {
2141 case UE_CONTROL:
2142 pipe->methods = &uhci_device_ctrl_methods;
2143 upipe->u.ctl.sqh = uhci_alloc_sqh(sc);
2144 if (upipe->u.ctl.sqh == 0)
2145 goto bad;
2146 upipe->u.ctl.setup = uhci_alloc_std(sc);
2147 if (upipe->u.ctl.setup == 0) {
2148 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2149 goto bad;
2150 }
2151 upipe->u.ctl.stat = uhci_alloc_std(sc);
2152 if (upipe->u.ctl.stat == 0) {
2153 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2154 uhci_free_std(sc, upipe->u.ctl.setup);
2155 goto bad;
2156 }
2157 r = usb_allocmem(sc->sc_dmatag,
2158 sizeof(usb_device_request_t),
2159 0, &upipe->u.ctl.reqdma);
2160 if (r != USBD_NORMAL_COMPLETION) {
2161 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2162 uhci_free_std(sc, upipe->u.ctl.setup);
2163 uhci_free_std(sc, upipe->u.ctl.stat);
2164 goto bad;
2165 }
2166 break;
2167 case UE_INTERRUPT:
2168 pipe->methods = &uhci_device_intr_methods;
2169 return (uhci_device_setintr(sc, upipe, ed->bInterval));
2170 case UE_ISOCHRONOUS:
2171 pipe->methods = &uhci_device_isoc_methods;
2172 upipe->u.iso.nbuf = 0;
2173 return (USBD_NORMAL_COMPLETION);
2174 case UE_BULK:
2175 pipe->methods = &uhci_device_bulk_methods;
2176 upipe->u.bulk.sqh = uhci_alloc_sqh(sc);
2177 if (upipe->u.bulk.sqh == 0)
2178 goto bad;
2179 break;
2180 }
2181 }
2182 return (USBD_NORMAL_COMPLETION);
2183
2184 bad:
2185 uhci_free_intr_info(upipe->iinfo);
2186 return (USBD_NOMEM);
2187 }
2188
2189 /*
2190 * Data structures and routines to emulate the root hub.
2191 */
2192 usb_device_descriptor_t uhci_devd = {
2193 USB_DEVICE_DESCRIPTOR_SIZE,
2194 UDESC_DEVICE, /* type */
2195 {0x00, 0x01}, /* USB version */
2196 UCLASS_HUB, /* class */
2197 USUBCLASS_HUB, /* subclass */
2198 0, /* protocol */
2199 64, /* max packet */
2200 {0},{0},{0x00,0x01}, /* device id */
2201 1,2,0, /* string indicies */
2202 1 /* # of configurations */
2203 };
2204
2205 usb_config_descriptor_t uhci_confd = {
2206 USB_CONFIG_DESCRIPTOR_SIZE,
2207 UDESC_CONFIG,
2208 {USB_CONFIG_DESCRIPTOR_SIZE +
2209 USB_INTERFACE_DESCRIPTOR_SIZE +
2210 USB_ENDPOINT_DESCRIPTOR_SIZE},
2211 1,
2212 1,
2213 0,
2214 UC_SELF_POWERED,
2215 0 /* max power */
2216 };
2217
2218 usb_interface_descriptor_t uhci_ifcd = {
2219 USB_INTERFACE_DESCRIPTOR_SIZE,
2220 UDESC_INTERFACE,
2221 0,
2222 0,
2223 1,
2224 UCLASS_HUB,
2225 USUBCLASS_HUB,
2226 0,
2227 0
2228 };
2229
2230 usb_endpoint_descriptor_t uhci_endpd = {
2231 USB_ENDPOINT_DESCRIPTOR_SIZE,
2232 UDESC_ENDPOINT,
2233 UE_IN | UHCI_INTR_ENDPT,
2234 UE_INTERRUPT,
2235 {8},
2236 255
2237 };
2238
2239 usb_hub_descriptor_t uhci_hubd_piix = {
2240 USB_HUB_DESCRIPTOR_SIZE,
2241 UDESC_HUB,
2242 2,
2243 { UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0 },
2244 50, /* power on to power good */
2245 0,
2246 { 0x00 }, /* both ports are removable */
2247 };
2248
2249 int
2250 uhci_str(p, l, s)
2251 usb_string_descriptor_t *p;
2252 int l;
2253 char *s;
2254 {
2255 int i;
2256
2257 if (l == 0)
2258 return (0);
2259 p->bLength = 2 * strlen(s) + 2;
2260 if (l == 1)
2261 return (1);
2262 p->bDescriptorType = UDESC_STRING;
2263 l -= 2;
2264 for (i = 0; s[i] && l > 1; i++, l -= 2)
2265 USETW2(p->bString[i], 0, s[i]);
2266 return (2*i+2);
2267 }
2268
2269 /*
2270 * Simulate a hardware hub by handling all the necessary requests.
2271 */
2272 usbd_status
2273 uhci_root_ctrl_transfer(reqh)
2274 usbd_request_handle reqh;
2275 {
2276 int s;
2277 usbd_status r;
2278
2279 s = splusb();
2280 r = usb_insert_transfer(reqh);
2281 splx(s);
2282 if (r != USBD_NORMAL_COMPLETION)
2283 return (r);
2284 else
2285 return (uhci_root_ctrl_start(reqh));
2286 }
2287
2288 usbd_status
2289 uhci_root_ctrl_start(reqh)
2290 usbd_request_handle reqh;
2291 {
2292 uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus;
2293 usb_device_request_t *req;
2294 void *buf;
2295 int port, x;
2296 int len, value, index, status, change, l, totlen = 0;
2297 usb_port_status_t ps;
2298 usbd_status r;
2299
2300 if (!reqh->isreq)
2301 panic("uhci_root_ctrl_transfer: not a request\n");
2302 req = &reqh->request;
2303 buf = reqh->buffer;
2304
2305 DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n",
2306 req->bmRequestType, req->bRequest));
2307
2308 len = UGETW(req->wLength);
2309 value = UGETW(req->wValue);
2310 index = UGETW(req->wIndex);
2311 #define C(x,y) ((x) | ((y) << 8))
2312 switch(C(req->bRequest, req->bmRequestType)) {
2313 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
2314 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
2315 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
2316 /*
2317 * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
2318 * for the integrated root hub.
2319 */
2320 break;
2321 case C(UR_GET_CONFIG, UT_READ_DEVICE):
2322 if (len > 0) {
2323 *(u_int8_t *)buf = sc->sc_conf;
2324 totlen = 1;
2325 }
2326 break;
2327 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
2328 DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value));
2329 switch(value >> 8) {
2330 case UDESC_DEVICE:
2331 if ((value & 0xff) != 0) {
2332 r = USBD_IOERROR;
2333 goto ret;
2334 }
2335 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
2336 USETW(uhci_devd.idVendor, sc->sc_id_vendor);
2337 memcpy(buf, &uhci_devd, l);
2338 break;
2339 case UDESC_CONFIG:
2340 if ((value & 0xff) != 0) {
2341 r = USBD_IOERROR;
2342 goto ret;
2343 }
2344 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
2345 memcpy(buf, &uhci_confd, l);
2346 buf = (char *)buf + l;
2347 len -= l;
2348 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
2349 totlen += l;
2350 memcpy(buf, &uhci_ifcd, l);
2351 buf = (char *)buf + l;
2352 len -= l;
2353 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
2354 totlen += l;
2355 memcpy(buf, &uhci_endpd, l);
2356 break;
2357 case UDESC_STRING:
2358 if (len == 0)
2359 break;
2360 *(u_int8_t *)buf = 0;
2361 totlen = 1;
2362 switch (value & 0xff) {
2363 case 1: /* Vendor */
2364 totlen = uhci_str(buf, len, sc->sc_vendor);
2365 break;
2366 case 2: /* Product */
2367 totlen = uhci_str(buf, len, "UHCI root hub");
2368 break;
2369 }
2370 break;
2371 default:
2372 r = USBD_IOERROR;
2373 goto ret;
2374 }
2375 break;
2376 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
2377 if (len > 0) {
2378 *(u_int8_t *)buf = 0;
2379 totlen = 1;
2380 }
2381 break;
2382 case C(UR_GET_STATUS, UT_READ_DEVICE):
2383 if (len > 1) {
2384 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
2385 totlen = 2;
2386 }
2387 break;
2388 case C(UR_GET_STATUS, UT_READ_INTERFACE):
2389 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
2390 if (len > 1) {
2391 USETW(((usb_status_t *)buf)->wStatus, 0);
2392 totlen = 2;
2393 }
2394 break;
2395 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
2396 if (value >= USB_MAX_DEVICES) {
2397 r = USBD_IOERROR;
2398 goto ret;
2399 }
2400 sc->sc_addr = value;
2401 break;
2402 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
2403 if (value != 0 && value != 1) {
2404 r = USBD_IOERROR;
2405 goto ret;
2406 }
2407 sc->sc_conf = value;
2408 break;
2409 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
2410 break;
2411 case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
2412 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
2413 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
2414 r = USBD_IOERROR;
2415 goto ret;
2416 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
2417 break;
2418 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
2419 break;
2420 /* Hub requests */
2421 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
2422 break;
2423 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
2424 DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
2425 "port=%d feature=%d\n",
2426 index, value));
2427 if (index == 1)
2428 port = UHCI_PORTSC1;
2429 else if (index == 2)
2430 port = UHCI_PORTSC2;
2431 else {
2432 r = USBD_IOERROR;
2433 goto ret;
2434 }
2435 switch(value) {
2436 case UHF_PORT_ENABLE:
2437 x = UREAD2(sc, port);
2438 UWRITE2(sc, port, x & ~UHCI_PORTSC_PE);
2439 break;
2440 case UHF_PORT_SUSPEND:
2441 x = UREAD2(sc, port);
2442 UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP);
2443 break;
2444 case UHF_PORT_RESET:
2445 x = UREAD2(sc, port);
2446 UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
2447 break;
2448 case UHF_C_PORT_CONNECTION:
2449 x = UREAD2(sc, port);
2450 UWRITE2(sc, port, x | UHCI_PORTSC_CSC);
2451 break;
2452 case UHF_C_PORT_ENABLE:
2453 x = UREAD2(sc, port);
2454 UWRITE2(sc, port, x | UHCI_PORTSC_POEDC);
2455 break;
2456 case UHF_C_PORT_OVER_CURRENT:
2457 x = UREAD2(sc, port);
2458 UWRITE2(sc, port, x | UHCI_PORTSC_OCIC);
2459 break;
2460 case UHF_C_PORT_RESET:
2461 sc->sc_isreset = 0;
2462 r = USBD_NORMAL_COMPLETION;
2463 goto ret;
2464 case UHF_PORT_CONNECTION:
2465 case UHF_PORT_OVER_CURRENT:
2466 case UHF_PORT_POWER:
2467 case UHF_PORT_LOW_SPEED:
2468 case UHF_C_PORT_SUSPEND:
2469 default:
2470 r = USBD_IOERROR;
2471 goto ret;
2472 }
2473 break;
2474 case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
2475 if (index == 1)
2476 port = UHCI_PORTSC1;
2477 else if (index == 2)
2478 port = UHCI_PORTSC2;
2479 else {
2480 r = USBD_IOERROR;
2481 goto ret;
2482 }
2483 if (len > 0) {
2484 *(u_int8_t *)buf =
2485 (UREAD2(sc, port) & UHCI_PORTSC_LS) >>
2486 UHCI_PORTSC_LS_SHIFT;
2487 totlen = 1;
2488 }
2489 break;
2490 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
2491 if (value != 0) {
2492 r = USBD_IOERROR;
2493 goto ret;
2494 }
2495 l = min(len, USB_HUB_DESCRIPTOR_SIZE);
2496 totlen = l;
2497 memcpy(buf, &uhci_hubd_piix, l);
2498 break;
2499 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
2500 if (len != 4) {
2501 r = USBD_IOERROR;
2502 goto ret;
2503 }
2504 memset(buf, 0, len);
2505 totlen = len;
2506 break;
2507 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
2508 if (index == 1)
2509 port = UHCI_PORTSC1;
2510 else if (index == 2)
2511 port = UHCI_PORTSC2;
2512 else {
2513 r = USBD_IOERROR;
2514 goto ret;
2515 }
2516 if (len != 4) {
2517 r = USBD_IOERROR;
2518 goto ret;
2519 }
2520 x = UREAD2(sc, port);
2521 status = change = 0;
2522 if (x & UHCI_PORTSC_CCS )
2523 status |= UPS_CURRENT_CONNECT_STATUS;
2524 if (x & UHCI_PORTSC_CSC )
2525 change |= UPS_C_CONNECT_STATUS;
2526 if (x & UHCI_PORTSC_PE )
2527 status |= UPS_PORT_ENABLED;
2528 if (x & UHCI_PORTSC_POEDC)
2529 change |= UPS_C_PORT_ENABLED;
2530 if (x & UHCI_PORTSC_OCI )
2531 status |= UPS_OVERCURRENT_INDICATOR;
2532 if (x & UHCI_PORTSC_OCIC )
2533 change |= UPS_C_OVERCURRENT_INDICATOR;
2534 if (x & UHCI_PORTSC_SUSP )
2535 status |= UPS_SUSPEND;
2536 if (x & UHCI_PORTSC_LSDA )
2537 status |= UPS_LOW_SPEED;
2538 status |= UPS_PORT_POWER;
2539 if (sc->sc_isreset)
2540 change |= UPS_C_PORT_RESET;
2541 USETW(ps.wPortStatus, status);
2542 USETW(ps.wPortChange, change);
2543 l = min(len, sizeof ps);
2544 memcpy(buf, &ps, l);
2545 totlen = l;
2546 break;
2547 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
2548 r = USBD_IOERROR;
2549 goto ret;
2550 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
2551 break;
2552 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
2553 if (index == 1)
2554 port = UHCI_PORTSC1;
2555 else if (index == 2)
2556 port = UHCI_PORTSC2;
2557 else {
2558 r = USBD_IOERROR;
2559 goto ret;
2560 }
2561 switch(value) {
2562 case UHF_PORT_ENABLE:
2563 x = UREAD2(sc, port);
2564 UWRITE2(sc, port, x | UHCI_PORTSC_PE);
2565 break;
2566 case UHF_PORT_SUSPEND:
2567 x = UREAD2(sc, port);
2568 UWRITE2(sc, port, x | UHCI_PORTSC_SUSP);
2569 break;
2570 case UHF_PORT_RESET:
2571 x = UREAD2(sc, port);
2572 UWRITE2(sc, port, x | UHCI_PORTSC_PR);
2573 usb_delay_ms(&sc->sc_bus, 10);
2574 UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
2575 delay(100);
2576 x = UREAD2(sc, port);
2577 UWRITE2(sc, port, x | UHCI_PORTSC_PE);
2578 delay(100);
2579 DPRINTFN(3,("uhci port %d reset, status = 0x%04x\n",
2580 index, UREAD2(sc, port)));
2581 sc->sc_isreset = 1;
2582 break;
2583 case UHF_C_PORT_CONNECTION:
2584 case UHF_C_PORT_ENABLE:
2585 case UHF_C_PORT_OVER_CURRENT:
2586 case UHF_PORT_CONNECTION:
2587 case UHF_PORT_OVER_CURRENT:
2588 case UHF_PORT_POWER:
2589 case UHF_PORT_LOW_SPEED:
2590 case UHF_C_PORT_SUSPEND:
2591 case UHF_C_PORT_RESET:
2592 default:
2593 r = USBD_IOERROR;
2594 goto ret;
2595 }
2596 break;
2597 default:
2598 r = USBD_IOERROR;
2599 goto ret;
2600 }
2601 reqh->actlen = totlen;
2602 r = USBD_NORMAL_COMPLETION;
2603 ret:
2604 reqh->status = r;
2605 reqh->xfercb(reqh);
2606 usb_start_next(reqh->pipe);
2607 return (USBD_IN_PROGRESS);
2608 }
2609
2610 /* Abort a root control request. */
2611 void
2612 uhci_root_ctrl_abort(reqh)
2613 usbd_request_handle reqh;
2614 {
2615 /* Nothing to do, all transfers are syncronous. */
2616 }
2617
2618 /* Close the root pipe. */
2619 void
2620 uhci_root_ctrl_close(pipe)
2621 usbd_pipe_handle pipe;
2622 {
2623 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
2624
2625 usb_untimeout(uhci_timo, pipe->intrreqh, pipe->intrreqh->timo_handle);
2626 sc->sc_has_timo = 0;
2627 DPRINTF(("uhci_root_ctrl_close\n"));
2628 }
2629
2630 /* Abort a root interrupt request. */
2631 void
2632 uhci_root_intr_abort(reqh)
2633 usbd_request_handle reqh;
2634 {
2635 uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus;
2636
2637 usb_untimeout(uhci_timo, reqh, reqh->timo_handle);
2638 sc->sc_has_timo = 0;
2639 }
2640
2641 usbd_status
2642 uhci_root_intr_transfer(reqh)
2643 usbd_request_handle reqh;
2644 {
2645 int s;
2646 usbd_status r;
2647
2648 s = splusb();
2649 r = usb_insert_transfer(reqh);
2650 splx(s);
2651 if (r != USBD_NORMAL_COMPLETION)
2652 return (r);
2653 else
2654 return (uhci_root_intr_start(reqh));
2655 }
2656
2657 /* Start a transfer on the root interrupt pipe */
2658 usbd_status
2659 uhci_root_intr_start(reqh)
2660 usbd_request_handle reqh;
2661 {
2662 usbd_pipe_handle pipe = reqh->pipe;
2663 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
2664 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2665 usb_dma_t *dmap;
2666 usbd_status r;
2667 int len;
2668
2669 DPRINTFN(3, ("uhci_root_intr_transfer: reqh=%p buf=%p len=%d "
2670 "flags=%d\n",
2671 reqh, reqh->buffer, reqh->length, reqh->flags));
2672
2673 len = reqh->length;
2674 dmap = &upipe->u.intr.datadma;
2675 if (len == 0)
2676 return (USBD_INVAL); /* XXX should it be? */
2677
2678 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
2679 if (r != USBD_NORMAL_COMPLETION)
2680 return (r);
2681
2682 sc->sc_ival = MS_TO_TICKS(reqh->pipe->endpoint->edesc->bInterval);
2683 usb_timeout(uhci_timo, reqh, sc->sc_ival, reqh->timo_handle);
2684 sc->sc_has_timo = reqh;
2685 return (USBD_IN_PROGRESS);
2686 }
2687
2688 /* Close the root interrupt pipe. */
2689 void
2690 uhci_root_intr_close(pipe)
2691 usbd_pipe_handle pipe;
2692 {
2693 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
2694
2695 usb_untimeout(uhci_timo, pipe->intrreqh, pipe->intrreqh->timo_handle);
2696 sc->sc_has_timo = 0;
2697 DPRINTF(("uhci_root_intr_close\n"));
2698 }
2699
2700