Deleted Added
sdiff udiff text old ( 227461 ) new ( 228483 )
full compact
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 $");
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);
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");
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);
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);
241}
242
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;
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);
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 }
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
514 /* setup async list pointer */
515 EOWRITE4(sc, EHCI_ASYNCLISTADDR, buf_res.physaddr | EHCI_LINK_QH);
516
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
576void
577ehci_suspend(ehci_softc_t *sc)
578{
579 uint32_t cmd;
580 uint32_t hcr;
581 uint8_t i;
582
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);
628}
629
630void
631ehci_resume(ehci_softc_t *sc)
632{
633 struct usb_page_search buf_res;
634 uint32_t cmd;
635 uint32_t hcr;
636 uint8_t i;
637
638 USB_BUS_LOCK(&sc->sc_bus);
639
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
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);
3911
3912 return;
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,
3958 .roothub_exec = ehci_roothub_exec,
3959 .xfer_poll = ehci_do_poll,
3960};