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

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

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
3 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
4 * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

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

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ohci.c 227461 2011-11-12 08:16:45Z hselasky $");
29__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ohci.c 228483 2011-12-14 00:28:54Z hselasky $");
30
31/*
32 * USB Open Host Controller driver.
33 *
34 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html
35 * USB spec: http://www.usb.org/developers/docs/usbspec.zip
36 */
37

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

161
162 for (i = 0; i != OHCI_NO_EDS; i++) {
163 cb(bus, sc->sc_hw.intr_start_pc + i, sc->sc_hw.intr_start_pg + i,
164 sizeof(ohci_ed_t), OHCI_ED_ALIGN);
165 }
166}
167
168static usb_error_t
30
31/*
32 * USB Open Host Controller driver.
33 *
34 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html
35 * USB spec: http://www.usb.org/developers/docs/usbspec.zip
36 */
37

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

161
162 for (i = 0; i != OHCI_NO_EDS; i++) {
163 cb(bus, sc->sc_hw.intr_start_pc + i, sc->sc_hw.intr_start_pg + i,
164 sizeof(ohci_ed_t), OHCI_ED_ALIGN);
165 }
166}
167
168static usb_error_t
169ohci_controller_init(ohci_softc_t *sc)
169ohci_controller_init(ohci_softc_t *sc, int do_suspend)
170{
171 struct usb_page_search buf_res;
172 uint32_t i;
173 uint32_t ctl;
174 uint32_t ival;
175 uint32_t hcr;
176 uint32_t fm;
177 uint32_t per;

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

228 return (USB_ERR_IOERROR);
229 }
230#ifdef USB_DEBUG
231 if (ohcidebug > 15) {
232 ohci_dumpregs(sc);
233 }
234#endif
235
170{
171 struct usb_page_search buf_res;
172 uint32_t i;
173 uint32_t ctl;
174 uint32_t ival;
175 uint32_t hcr;
176 uint32_t fm;
177 uint32_t per;

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

228 return (USB_ERR_IOERROR);
229 }
230#ifdef USB_DEBUG
231 if (ohcidebug > 15) {
232 ohci_dumpregs(sc);
233 }
234#endif
235
236 if (do_suspend) {
237 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_SUSPEND);
238 return (USB_ERR_NORMAL_COMPLETION);
239 }
240
236 /* The controller is now in SUSPEND state, we have 2ms to finish. */
237
238 /* set up HC registers */
239 usbd_get_page(&sc->sc_hw.hcca_pc, 0, &buf_res);
240 OWRITE4(sc, OHCI_HCCA, buf_res.physaddr);
241
242 usbd_get_page(&sc->sc_hw.ctrl_start_pc, 0, &buf_res);
243 OWRITE4(sc, OHCI_CONTROL_HEAD_ED, buf_res.physaddr);

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

410 }
411 printf("iso ");
412 ohci_dump_ed(sc->sc_isoc_p_last);
413 }
414#endif
415
416 sc->sc_bus.usbrev = USB_REV_1_0;
417
241 /* The controller is now in SUSPEND state, we have 2ms to finish. */
242
243 /* set up HC registers */
244 usbd_get_page(&sc->sc_hw.hcca_pc, 0, &buf_res);
245 OWRITE4(sc, OHCI_HCCA, buf_res.physaddr);
246
247 usbd_get_page(&sc->sc_hw.ctrl_start_pc, 0, &buf_res);
248 OWRITE4(sc, OHCI_CONTROL_HEAD_ED, buf_res.physaddr);

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

415 }
416 printf("iso ");
417 ohci_dump_ed(sc->sc_isoc_p_last);
418 }
419#endif
420
421 sc->sc_bus.usbrev = USB_REV_1_0;
422
418 if (ohci_controller_init(sc)) {
423 if (ohci_controller_init(sc, 0) != 0)
419 return (USB_ERR_INVAL);
424 return (USB_ERR_INVAL);
420 } else {
421 /* catch any lost interrupts */
422 ohci_do_poll(&sc->sc_bus);
423 return (USB_ERR_NORMAL_COMPLETION);
424 }
425
426 /* catch any lost interrupts */
427 ohci_do_poll(&sc->sc_bus);
428 return (USB_ERR_NORMAL_COMPLETION);
425}
426
427/*
428 * shut down the controller when the system is going down
429 */
430void
431ohci_detach(struct ohci_softc *sc)
432{

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

440 USB_BUS_UNLOCK(&sc->sc_bus);
441
442 /* XXX let stray task complete */
443 usb_pause_mtx(NULL, hz / 20);
444
445 usb_callout_drain(&sc->sc_tmo_rhsc);
446}
447
429}
430
431/*
432 * shut down the controller when the system is going down
433 */
434void
435ohci_detach(struct ohci_softc *sc)
436{

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

444 USB_BUS_UNLOCK(&sc->sc_bus);
445
446 /* XXX let stray task complete */
447 usb_pause_mtx(NULL, hz / 20);
448
449 usb_callout_drain(&sc->sc_tmo_rhsc);
450}
451
448/* NOTE: suspend/resume is called from
449 * interrupt context and cannot sleep!
450 */
451void
452static void
452ohci_suspend(ohci_softc_t *sc)
453{
453ohci_suspend(ohci_softc_t *sc)
454{
454 uint32_t ctl;
455 DPRINTF("\n");
455
456
456 USB_BUS_LOCK(&sc->sc_bus);
457
458#ifdef USB_DEBUG
457#ifdef USB_DEBUG
459 DPRINTF("\n");
460 if (ohcidebug > 2) {
458 if (ohcidebug > 2)
461 ohci_dumpregs(sc);
459 ohci_dumpregs(sc);
462 }
463#endif
464
460#endif
461
465 ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
466 if (sc->sc_control == 0) {
467 /*
468 * Preserve register values, in case that APM BIOS
469 * does not recover them.
470 */
471 sc->sc_control = ctl;
472 sc->sc_intre = OREAD4(sc, OHCI_INTERRUPT_ENABLE);
473 }
474 ctl |= OHCI_HCFS_SUSPEND;
475 OWRITE4(sc, OHCI_CONTROL, ctl);
476
477 usb_pause_mtx(&sc->sc_bus.bus_mtx,
478 USB_MS_TO_TICKS(USB_RESUME_WAIT));
479
480 USB_BUS_UNLOCK(&sc->sc_bus);
462 /* reset HC and leave it suspended */
463 ohci_controller_init(sc, 1);
481}
482
464}
465
483void
466static void
484ohci_resume(ohci_softc_t *sc)
485{
467ohci_resume(ohci_softc_t *sc)
468{
486 uint32_t ctl;
469 DPRINTF("\n");
487
488#ifdef USB_DEBUG
470
471#ifdef USB_DEBUG
489 DPRINTF("\n");
490 if (ohcidebug > 2) {
472 if (ohcidebug > 2)
491 ohci_dumpregs(sc);
473 ohci_dumpregs(sc);
492 }
493#endif
474#endif
475
494 /* some broken BIOSes never initialize the Controller chip */
476 /* some broken BIOSes never initialize the Controller chip */
495 ohci_controller_init(sc);
477 ohci_controller_init(sc, 0);
496
478
497 USB_BUS_LOCK(&sc->sc_bus);
498 if (sc->sc_intre) {
499 OWRITE4(sc, OHCI_INTERRUPT_ENABLE,
500 sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE));
501 }
502 if (sc->sc_control)
503 ctl = sc->sc_control;
504 else
505 ctl = OREAD4(sc, OHCI_CONTROL);
506 ctl |= OHCI_HCFS_RESUME;
507 OWRITE4(sc, OHCI_CONTROL, ctl);
508 usb_pause_mtx(&sc->sc_bus.bus_mtx,
509 USB_MS_TO_TICKS(USB_RESUME_DELAY));
510 ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL;
511 OWRITE4(sc, OHCI_CONTROL, ctl);
512 usb_pause_mtx(&sc->sc_bus.bus_mtx,
513 USB_MS_TO_TICKS(USB_RESUME_RECOVERY));
514 sc->sc_control = sc->sc_intre = 0;
515
516 USB_BUS_UNLOCK(&sc->sc_bus);
517
518 /* catch any lost interrupts */
519 ohci_do_poll(&sc->sc_bus);
520}
521
522#ifdef USB_DEBUG
523static void
524ohci_dumpregs(ohci_softc_t *sc)
525{

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

2708 }
2709
2710 USB_BUS_UNLOCK(udev->bus);
2711
2712 return;
2713}
2714
2715static void
479 /* catch any lost interrupts */
480 ohci_do_poll(&sc->sc_bus);
481}
482
483#ifdef USB_DEBUG
484static void
485ohci_dumpregs(ohci_softc_t *sc)
486{

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

2669 }
2670
2671 USB_BUS_UNLOCK(udev->bus);
2672
2673 return;
2674}
2675
2676static void
2677ohci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
2678{
2679 struct ohci_softc *sc = OHCI_BUS2SC(bus);
2680
2681 switch (state) {
2682 case USB_HW_POWER_SUSPEND:
2683 case USB_HW_POWER_SHUTDOWN:
2684 ohci_suspend(sc);
2685 break;
2686 case USB_HW_POWER_RESUME:
2687 ohci_resume(sc);
2688 break;
2689 default:
2690 break;
2691 }
2692}
2693
2694static void
2716ohci_set_hw_power(struct usb_bus *bus)
2717{
2718 struct ohci_softc *sc = OHCI_BUS2SC(bus);
2719 uint32_t temp;
2720 uint32_t flags;
2721
2722 DPRINTF("\n");
2723

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

2751{
2752 .endpoint_init = ohci_ep_init,
2753 .xfer_setup = ohci_xfer_setup,
2754 .xfer_unsetup = ohci_xfer_unsetup,
2755 .get_dma_delay = ohci_get_dma_delay,
2756 .device_resume = ohci_device_resume,
2757 .device_suspend = ohci_device_suspend,
2758 .set_hw_power = ohci_set_hw_power,
2695ohci_set_hw_power(struct usb_bus *bus)
2696{
2697 struct ohci_softc *sc = OHCI_BUS2SC(bus);
2698 uint32_t temp;
2699 uint32_t flags;
2700
2701 DPRINTF("\n");
2702

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

2730{
2731 .endpoint_init = ohci_ep_init,
2732 .xfer_setup = ohci_xfer_setup,
2733 .xfer_unsetup = ohci_xfer_unsetup,
2734 .get_dma_delay = ohci_get_dma_delay,
2735 .device_resume = ohci_device_resume,
2736 .device_suspend = ohci_device_suspend,
2737 .set_hw_power = ohci_set_hw_power,
2738 .set_hw_power_sleep = ohci_set_hw_power_sleep,
2759 .roothub_exec = ohci_roothub_exec,
2760 .xfer_poll = ohci_do_poll,
2761};
2739 .roothub_exec = ohci_roothub_exec,
2740 .xfer_poll = ohci_do_poll,
2741};