Deleted Added
full compact
ehci.c (227461) ehci.c (228483)
1/*-
2 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
3 * Copyright (c) 2004 The NetBSD Foundation, Inc. All rights reserved.
4 * Copyright (c) 2004 Lennart Augustsson. All rights reserved.
5 * Copyright (c) 2004 Charles M. Hannum. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 30 unchanged lines hidden (view full) ---

39 */
40
41/*
42 * TODO:
43 * 1) command failures are not recovered correctly
44 */
45
46#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
3 * Copyright (c) 2004 The NetBSD Foundation, Inc. All rights reserved.
4 * Copyright (c) 2004 Lennart Augustsson. All rights reserved.
5 * Copyright (c) 2004 Charles M. Hannum. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 30 unchanged lines hidden (view full) ---

39 */
40
41/*
42 * TODO:
43 * 1) command failures are not recovered correctly
44 */
45
46#include <sys/cdefs.h>
47__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ehci.c 227461 2011-11-12 08:16:45Z hselasky $");
47__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ehci.c 228483 2011-12-14 00:28:54Z hselasky $");
48
49#include <sys/stdint.h>
50#include <sys/stddef.h>
51#include <sys/param.h>
52#include <sys/queue.h>
53#include <sys/types.h>
54#include <sys/systm.h>
55#include <sys/kernel.h>

--- 127 unchanged lines hidden (view full) ---

183usb_error_t
184ehci_reset(ehci_softc_t *sc)
185{
186 uint32_t hcr;
187 int i;
188
189 EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
190 for (i = 0; i < 100; i++) {
48
49#include <sys/stdint.h>
50#include <sys/stddef.h>
51#include <sys/param.h>
52#include <sys/queue.h>
53#include <sys/types.h>
54#include <sys/systm.h>
55#include <sys/kernel.h>

--- 127 unchanged lines hidden (view full) ---

183usb_error_t
184ehci_reset(ehci_softc_t *sc)
185{
186 uint32_t hcr;
187 int i;
188
189 EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
190 for (i = 0; i < 100; i++) {
191 usb_pause_mtx(NULL, hz / 1000);
191 usb_pause_mtx(NULL, hz / 128);
192 hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET;
193 if (!hcr) {
194 if (sc->sc_flags & (EHCI_SCFLG_SETMODE | EHCI_SCFLG_BIGEMMIO)) {
195 /*
196 * Force USBMODE as requested. Controllers
197 * may have multiple operating modes.
198 */
199 uint32_t usbmode = EOREAD4(sc, EHCI_USBMODE);

--- 7 unchanged lines hidden (view full) ---

207 device_printf(sc->sc_bus.bdev,
208 "set big-endian mode\n");
209 }
210 EOWRITE4(sc, EHCI_USBMODE, usbmode);
211 }
212 return (0);
213 }
214 }
192 hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET;
193 if (!hcr) {
194 if (sc->sc_flags & (EHCI_SCFLG_SETMODE | EHCI_SCFLG_BIGEMMIO)) {
195 /*
196 * Force USBMODE as requested. Controllers
197 * may have multiple operating modes.
198 */
199 uint32_t usbmode = EOREAD4(sc, EHCI_USBMODE);

--- 7 unchanged lines hidden (view full) ---

207 device_printf(sc->sc_bus.bdev,
208 "set big-endian mode\n");
209 }
210 EOWRITE4(sc, EHCI_USBMODE, usbmode);
211 }
212 return (0);
213 }
214 }
215 device_printf(sc->sc_bus.bdev, "reset timeout\n");
215 device_printf(sc->sc_bus.bdev, "Reset timeout\n");
216 return (USB_ERR_IOERROR);
217}
218
219static usb_error_t
220ehci_hcreset(ehci_softc_t *sc)
221{
222 uint32_t hcr;
223 int i;
224
225 EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */
226 for (i = 0; i < 100; i++) {
216 return (USB_ERR_IOERROR);
217}
218
219static usb_error_t
220ehci_hcreset(ehci_softc_t *sc)
221{
222 uint32_t hcr;
223 int i;
224
225 EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */
226 for (i = 0; i < 100; i++) {
227 usb_pause_mtx(NULL, hz / 1000);
227 usb_pause_mtx(NULL, hz / 128);
228 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
229 if (hcr)
230 break;
231 }
232 if (!hcr)
233 /*
234 * Fall through and try reset anyway even though
235 * Table 2-9 in the EHCI spec says this will result
236 * in undefined behavior.
237 */
238 device_printf(sc->sc_bus.bdev, "stop timeout\n");
239
228 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
229 if (hcr)
230 break;
231 }
232 if (!hcr)
233 /*
234 * Fall through and try reset anyway even though
235 * Table 2-9 in the EHCI spec says this will result
236 * in undefined behavior.
237 */
238 device_printf(sc->sc_bus.bdev, "stop timeout\n");
239
240 return ehci_reset(sc);
240 return (ehci_reset(sc));
241}
242
241}
242
243static int
244ehci_init_sub(struct ehci_softc *sc)
245{
246 struct usb_page_search buf_res;
247 uint32_t cparams;
248 uint32_t hcr;
249 uint8_t i;
250
251 cparams = EREAD4(sc, EHCI_HCCPARAMS);
252
253 DPRINTF("cparams=0x%x\n", cparams);
254
255 if (EHCI_HCC_64BIT(cparams)) {
256 DPRINTF("HCC uses 64-bit structures\n");
257
258 /* MUST clear segment register if 64 bit capable */
259 EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
260 }
261
262 usbd_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res);
263 EOWRITE4(sc, EHCI_PERIODICLISTBASE, buf_res.physaddr);
264
265 usbd_get_page(&sc->sc_hw.async_start_pc, 0, &buf_res);
266 EOWRITE4(sc, EHCI_ASYNCLISTADDR, buf_res.physaddr | EHCI_LINK_QH);
267
268 /* enable interrupts */
269 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
270
271 /* turn on controller */
272 EOWRITE4(sc, EHCI_USBCMD,
273 EHCI_CMD_ITC_1 | /* 1 microframes interrupt delay */
274 (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |
275 EHCI_CMD_ASE |
276 EHCI_CMD_PSE |
277 EHCI_CMD_RS);
278
279 /* Take over port ownership */
280 EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
281
282 for (i = 0; i < 100; i++) {
283 usb_pause_mtx(NULL, hz / 128);
284 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
285 if (!hcr) {
286 break;
287 }
288 }
289 if (hcr) {
290 device_printf(sc->sc_bus.bdev, "Run timeout\n");
291 return (USB_ERR_IOERROR);
292 }
293 return (USB_ERR_NORMAL_COMPLETION);
294}
295
243usb_error_t
244ehci_init(ehci_softc_t *sc)
245{
246 struct usb_page_search buf_res;
247 uint32_t version;
248 uint32_t sparams;
296usb_error_t
297ehci_init(ehci_softc_t *sc)
298{
299 struct usb_page_search buf_res;
300 uint32_t version;
301 uint32_t sparams;
249 uint32_t cparams;
250 uint32_t hcr;
251 uint16_t i;
252 uint16_t x;
253 uint16_t y;
254 uint16_t bit;
255 usb_error_t err = 0;
256
257 DPRINTF("start\n");
258

--- 15 unchanged lines hidden (view full) ---

274 version = EHCI_HCIVERSION(EREAD4(sc, EHCI_CAPLEN_HCIVERSION));
275 device_printf(sc->sc_bus.bdev, "EHCI version %x.%x\n",
276 version >> 8, version & 0xff);
277
278 sparams = EREAD4(sc, EHCI_HCSPARAMS);
279 DPRINTF("sparams=0x%x\n", sparams);
280
281 sc->sc_noport = EHCI_HCS_N_PORTS(sparams);
302 uint16_t i;
303 uint16_t x;
304 uint16_t y;
305 uint16_t bit;
306 usb_error_t err = 0;
307
308 DPRINTF("start\n");
309

--- 15 unchanged lines hidden (view full) ---

325 version = EHCI_HCIVERSION(EREAD4(sc, EHCI_CAPLEN_HCIVERSION));
326 device_printf(sc->sc_bus.bdev, "EHCI version %x.%x\n",
327 version >> 8, version & 0xff);
328
329 sparams = EREAD4(sc, EHCI_HCSPARAMS);
330 DPRINTF("sparams=0x%x\n", sparams);
331
332 sc->sc_noport = EHCI_HCS_N_PORTS(sparams);
282 cparams = EREAD4(sc, EHCI_HCCPARAMS);
283 DPRINTF("cparams=0x%x\n", cparams);
284
285 if (EHCI_HCC_64BIT(cparams)) {
286 DPRINTF("HCC uses 64-bit structures\n");
287
288 /* MUST clear segment register if 64 bit capable */
289 EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
290 }
291 sc->sc_bus.usbrev = USB_REV_2_0;
292
293 /* Reset the controller */
294 DPRINTF("%s: resetting\n", device_get_nameunit(sc->sc_bus.bdev));
295
296 err = ehci_hcreset(sc);
297 if (err) {
298 device_printf(sc->sc_bus.bdev, "reset timeout\n");

--- 160 unchanged lines hidden (view full) ---

459 * pframes -> high speed isochronous ->
460 * full speed isochronous -> interrupt QH's
461 */
462 for (i = 0; i < EHCI_FRAMELIST_COUNT; i++) {
463 pframes[i] = sc->sc_isoc_hs_p_last
464 [i & (EHCI_VIRTUAL_FRAMELIST_COUNT - 1)]->itd_self;
465 }
466 }
333 sc->sc_bus.usbrev = USB_REV_2_0;
334
335 /* Reset the controller */
336 DPRINTF("%s: resetting\n", device_get_nameunit(sc->sc_bus.bdev));
337
338 err = ehci_hcreset(sc);
339 if (err) {
340 device_printf(sc->sc_bus.bdev, "reset timeout\n");

--- 160 unchanged lines hidden (view full) ---

501 * pframes -> high speed isochronous ->
502 * full speed isochronous -> interrupt QH's
503 */
504 for (i = 0; i < EHCI_FRAMELIST_COUNT; i++) {
505 pframes[i] = sc->sc_isoc_hs_p_last
506 [i & (EHCI_VIRTUAL_FRAMELIST_COUNT - 1)]->itd_self;
507 }
508 }
467 /* setup sync list pointer */
468 EOWRITE4(sc, EHCI_PERIODICLISTBASE, buf_res.physaddr);
469
470 usbd_get_page(&sc->sc_hw.async_start_pc, 0, &buf_res);
471
472 if (1) {
473
474 ehci_qh_t *qh;
475
476 qh = buf_res.buffer;
477

--- 28 unchanged lines hidden (view full) ---

506 usb_bus_mem_flush_all(&sc->sc_bus, &ehci_iterate_hw_softc);
507
508#ifdef USB_DEBUG
509 if (ehcidebug) {
510 ehci_dump_sqh(sc, sc->sc_async_p_last);
511 }
512#endif
513
509 usbd_get_page(&sc->sc_hw.async_start_pc, 0, &buf_res);
510
511 if (1) {
512
513 ehci_qh_t *qh;
514
515 qh = buf_res.buffer;
516

--- 28 unchanged lines hidden (view full) ---

545 usb_bus_mem_flush_all(&sc->sc_bus, &ehci_iterate_hw_softc);
546
547#ifdef USB_DEBUG
548 if (ehcidebug) {
549 ehci_dump_sqh(sc, sc->sc_async_p_last);
550 }
551#endif
552
514 /* setup async list pointer */
515 EOWRITE4(sc, EHCI_ASYNCLISTADDR, buf_res.physaddr | EHCI_LINK_QH);
553 /* finial setup */
554 err = ehci_init_sub(sc);
516
555
517
518 /* enable interrupts */
519 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
520
521 /* turn on controller */
522 EOWRITE4(sc, EHCI_USBCMD,
523 EHCI_CMD_ITC_1 | /* 1 microframes interrupt delay */
524 (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |
525 EHCI_CMD_ASE |
526 EHCI_CMD_PSE |
527 EHCI_CMD_RS);
528
529 /* Take over port ownership */
530 EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
531
532 for (i = 0; i < 100; i++) {
533 usb_pause_mtx(NULL, hz / 1000);
534 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
535 if (!hcr) {
536 break;
537 }
538 }
539 if (hcr) {
540 device_printf(sc->sc_bus.bdev, "run timeout\n");
541 return (USB_ERR_IOERROR);
542 }
543
544 if (!err) {
545 /* catch any lost interrupts */
546 ehci_do_poll(&sc->sc_bus);
547 }
548 return (err);
549}
550
551/*

--- 16 unchanged lines hidden (view full) ---

568
569 /* XXX let stray task complete */
570 usb_pause_mtx(NULL, hz / 20);
571
572 usb_callout_drain(&sc->sc_tmo_pcd);
573 usb_callout_drain(&sc->sc_tmo_poll);
574}
575
556 if (!err) {
557 /* catch any lost interrupts */
558 ehci_do_poll(&sc->sc_bus);
559 }
560 return (err);
561}
562
563/*

--- 16 unchanged lines hidden (view full) ---

580
581 /* XXX let stray task complete */
582 usb_pause_mtx(NULL, hz / 20);
583
584 usb_callout_drain(&sc->sc_tmo_pcd);
585 usb_callout_drain(&sc->sc_tmo_poll);
586}
587
576void
588static void
577ehci_suspend(ehci_softc_t *sc)
578{
589ehci_suspend(ehci_softc_t *sc)
590{
579 uint32_t cmd;
580 uint32_t hcr;
581 uint8_t i;
591 DPRINTF("stopping the HC\n");
582
592
583 USB_BUS_LOCK(&sc->sc_bus);
584
585 for (i = 1; i <= sc->sc_noport; i++) {
586 cmd = EOREAD4(sc, EHCI_PORTSC(i));
587 if (((cmd & EHCI_PS_PO) == 0) &&
588 ((cmd & EHCI_PS_PE) == EHCI_PS_PE)) {
589 EOWRITE4(sc, EHCI_PORTSC(i),
590 cmd | EHCI_PS_SUSP);
591 }
592 }
593
594 sc->sc_cmd = EOREAD4(sc, EHCI_USBCMD);
595
596 cmd = sc->sc_cmd & ~(EHCI_CMD_ASE | EHCI_CMD_PSE);
597 EOWRITE4(sc, EHCI_USBCMD, cmd);
598
599 for (i = 0; i < 100; i++) {
600 hcr = EOREAD4(sc, EHCI_USBSTS) &
601 (EHCI_STS_ASS | EHCI_STS_PSS);
602
603 if (hcr == 0) {
604 break;
605 }
606 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
607 }
608
609 if (hcr != 0) {
610 device_printf(sc->sc_bus.bdev, "reset timeout\n");
611 }
612 cmd &= ~EHCI_CMD_RS;
613 EOWRITE4(sc, EHCI_USBCMD, cmd);
614
615 for (i = 0; i < 100; i++) {
616 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
617 if (hcr == EHCI_STS_HCH) {
618 break;
619 }
620 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
621 }
622
623 if (hcr != EHCI_STS_HCH) {
624 device_printf(sc->sc_bus.bdev,
625 "config timeout\n");
626 }
627 USB_BUS_UNLOCK(&sc->sc_bus);
593 /* reset HC */
594 ehci_hcreset(sc);
628}
629
595}
596
630void
597static void
631ehci_resume(ehci_softc_t *sc)
632{
598ehci_resume(ehci_softc_t *sc)
599{
633 struct usb_page_search buf_res;
634 uint32_t cmd;
635 uint32_t hcr;
636 uint8_t i;
600 /* reset HC */
601 ehci_hcreset(sc);
637
602
638 USB_BUS_LOCK(&sc->sc_bus);
603 /* setup HC */
604 ehci_init_sub(sc);
639
605
640 /* restore things in case the bios doesn't */
641 EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
642
643 usbd_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res);
644 EOWRITE4(sc, EHCI_PERIODICLISTBASE, buf_res.physaddr);
645
646 usbd_get_page(&sc->sc_hw.async_start_pc, 0, &buf_res);
647 EOWRITE4(sc, EHCI_ASYNCLISTADDR, buf_res.physaddr | EHCI_LINK_QH);
648
649 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
650
651 hcr = 0;
652 for (i = 1; i <= sc->sc_noport; i++) {
653 cmd = EOREAD4(sc, EHCI_PORTSC(i));
654 if (((cmd & EHCI_PS_PO) == 0) &&
655 ((cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP)) {
656 EOWRITE4(sc, EHCI_PORTSC(i),
657 cmd | EHCI_PS_FPR);
658 hcr = 1;
659 }
660 }
661
662 if (hcr) {
663 usb_pause_mtx(&sc->sc_bus.bus_mtx,
664 USB_MS_TO_TICKS(USB_RESUME_WAIT));
665
666 for (i = 1; i <= sc->sc_noport; i++) {
667 cmd = EOREAD4(sc, EHCI_PORTSC(i));
668 if (((cmd & EHCI_PS_PO) == 0) &&
669 ((cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP)) {
670 EOWRITE4(sc, EHCI_PORTSC(i),
671 cmd & ~EHCI_PS_FPR);
672 }
673 }
674 }
675 EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);
676
677 for (i = 0; i < 100; i++) {
678 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
679 if (hcr != EHCI_STS_HCH) {
680 break;
681 }
682 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
683 }
684 if (hcr == EHCI_STS_HCH) {
685 device_printf(sc->sc_bus.bdev, "config timeout\n");
686 }
687
688 USB_BUS_UNLOCK(&sc->sc_bus);
689
690 usb_pause_mtx(NULL,
691 USB_MS_TO_TICKS(USB_RESUME_WAIT));
692
693 /* catch any lost interrupts */
694 ehci_do_poll(&sc->sc_bus);
695}
696
606 /* catch any lost interrupts */
607 ehci_do_poll(&sc->sc_bus);
608}
609
697void
698ehci_shutdown(ehci_softc_t *sc)
699{
700 DPRINTF("stopping the HC\n");
701
702 if (ehci_hcreset(sc)) {
703 DPRINTF("reset failed!\n");
704 }
705}
706
707#ifdef USB_DEBUG
708static void
709ehci_dump_regs(ehci_softc_t *sc)
710{
711 uint32_t i;
712
713 i = EOREAD4(sc, EHCI_USBCMD);
714 printf("cmd=0x%08x\n", i);

--- 3188 unchanged lines hidden (view full) ---

3903 if (methods == &ehci_device_intr_methods) {
3904 EHCI_REMOVE_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
3905 sc->sc_intr_p_last[xfer->qh_pos]);
3906 }
3907 }
3908 }
3909
3910 USB_BUS_UNLOCK(udev->bus);
610#ifdef USB_DEBUG
611static void
612ehci_dump_regs(ehci_softc_t *sc)
613{
614 uint32_t i;
615
616 i = EOREAD4(sc, EHCI_USBCMD);
617 printf("cmd=0x%08x\n", i);

--- 3188 unchanged lines hidden (view full) ---

3806 if (methods == &ehci_device_intr_methods) {
3807 EHCI_REMOVE_QH(xfer->qh_start[xfer->flags_int.curr_dma_set],
3808 sc->sc_intr_p_last[xfer->qh_pos]);
3809 }
3810 }
3811 }
3812
3813 USB_BUS_UNLOCK(udev->bus);
3814}
3911
3815
3912 return;
3816static void
3817ehci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
3818{
3819 struct ehci_softc *sc = EHCI_BUS2SC(bus);
3820
3821 switch (state) {
3822 case USB_HW_POWER_SUSPEND:
3823 case USB_HW_POWER_SHUTDOWN:
3824 ehci_suspend(sc);
3825 break;
3826 case USB_HW_POWER_RESUME:
3827 ehci_resume(sc);
3828 break;
3829 default:
3830 break;
3831 }
3913}
3914
3915static void
3916ehci_set_hw_power(struct usb_bus *bus)
3917{
3918 ehci_softc_t *sc = EHCI_BUS2SC(bus);
3919 uint32_t temp;
3920 uint32_t flags;

--- 29 unchanged lines hidden (view full) ---

3950{
3951 .endpoint_init = ehci_ep_init,
3952 .xfer_setup = ehci_xfer_setup,
3953 .xfer_unsetup = ehci_xfer_unsetup,
3954 .get_dma_delay = ehci_get_dma_delay,
3955 .device_resume = ehci_device_resume,
3956 .device_suspend = ehci_device_suspend,
3957 .set_hw_power = ehci_set_hw_power,
3832}
3833
3834static void
3835ehci_set_hw_power(struct usb_bus *bus)
3836{
3837 ehci_softc_t *sc = EHCI_BUS2SC(bus);
3838 uint32_t temp;
3839 uint32_t flags;

--- 29 unchanged lines hidden (view full) ---

3869{
3870 .endpoint_init = ehci_ep_init,
3871 .xfer_setup = ehci_xfer_setup,
3872 .xfer_unsetup = ehci_xfer_unsetup,
3873 .get_dma_delay = ehci_get_dma_delay,
3874 .device_resume = ehci_device_resume,
3875 .device_suspend = ehci_device_suspend,
3876 .set_hw_power = ehci_set_hw_power,
3877 .set_hw_power_sleep = ehci_set_hw_power_sleep,
3958 .roothub_exec = ehci_roothub_exec,
3959 .xfer_poll = ehci_do_poll,
3960};
3878 .roothub_exec = ehci_roothub_exec,
3879 .xfer_poll = ehci_do_poll,
3880};