diff --git a/sys/dev/usb/controller/at91dci.c b/sys/dev/usb/controller/at91dci.c index 615bba94f5ae..b855a5b6265f 100644 --- a/sys/dev/usb/controller/at91dci.c +++ b/sys/dev/usb/controller/at91dci.c @@ -88,8 +88,6 @@ struct usb2_pipe_methods at91dci_device_bulk_methods; struct usb2_pipe_methods at91dci_device_ctrl_methods; struct usb2_pipe_methods at91dci_device_intr_methods; struct usb2_pipe_methods at91dci_device_isoc_fs_methods; -struct usb2_pipe_methods at91dci_root_ctrl_methods; -struct usb2_pipe_methods at91dci_root_intr_methods; static at91dci_cmd_t at91dci_setup_rx; static at91dci_cmd_t at91dci_data_rx; @@ -97,11 +95,8 @@ static at91dci_cmd_t at91dci_data_tx; static at91dci_cmd_t at91dci_data_tx_sync; static void at91dci_device_done(struct usb2_xfer *, usb2_error_t); static void at91dci_do_poll(struct usb2_bus *); -static void at91dci_root_ctrl_poll(struct at91dci_softc *); static void at91dci_standard_done(struct usb2_xfer *); - -static usb2_sw_transfer_func_t at91dci_root_intr_done; -static usb2_sw_transfer_func_t at91dci_root_ctrl_done; +static void at91dci_root_intr(struct at91dci_softc *sc); /* * NOTE: Some of the bits in the CSR register have inverse meaning so @@ -256,10 +251,8 @@ at91dci_pull_down(struct at91dci_softc *sc) } static void -at91dci_wakeup_peer(struct usb2_xfer *xfer) +at91dci_wakeup_peer(struct at91dci_softc *sc) { - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); - if (!(sc->sc_flags.status_suspend)) { return; } @@ -736,9 +729,7 @@ at91dci_vbus_interrupt(struct at91dci_softc *sc, uint8_t is_on) sc->sc_flags.status_vbus = 1; /* complete root HUB interrupt endpoint */ - - usb2_sw_transfer(&sc->sc_root_intr, - &at91dci_root_intr_done); + at91dci_root_intr(sc); } } else { if (sc->sc_flags.status_vbus) { @@ -749,9 +740,7 @@ at91dci_vbus_interrupt(struct at91dci_softc *sc, uint8_t is_on) sc->sc_flags.change_connect = 1; /* complete root HUB interrupt endpoint */ - - usb2_sw_transfer(&sc->sc_root_intr, - &at91dci_root_intr_done); + at91dci_root_intr(sc); } } USB_BUS_UNLOCK(&sc->sc_bus); @@ -828,9 +817,7 @@ at91dci_interrupt(struct at91dci_softc *sc) } } /* complete root HUB interrupt endpoint */ - - usb2_sw_transfer(&sc->sc_root_intr, - &at91dci_root_intr_done); + at91dci_root_intr(sc); } /* check for any endpoint interrupts */ @@ -1070,31 +1057,17 @@ at91dci_start_standard_chain(struct usb2_xfer *xfer) } static void -at91dci_root_intr_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) +at91dci_root_intr(struct at91dci_softc *sc) { - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); - DPRINTFN(9, "\n"); USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_PRE_DATA) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - at91dci_device_done(xfer, std->err); - } - goto done; - } - /* setup buffer */ - std->ptr = sc->sc_hub_idata; - std->len = sizeof(sc->sc_hub_idata); - /* set port bit */ sc->sc_hub_idata[0] = 0x02; /* we only have one port */ -done: - return; + uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata, + sizeof(sc->sc_hub_idata)); } static usb2_error_t @@ -1488,7 +1461,6 @@ at91dci_do_poll(struct usb2_bus *bus) USB_BUS_LOCK(&sc->sc_bus); at91dci_interrupt_poll(sc); - at91dci_root_ctrl_poll(sc); USB_BUS_UNLOCK(&sc->sc_bus); } @@ -1696,31 +1668,9 @@ struct usb2_pipe_methods at91dci_device_isoc_fs_methods = /*------------------------------------------------------------------------* * at91dci root control support *------------------------------------------------------------------------* - * simulate a hardware HUB by handling - * all the necessary requests + * Simulate a hardware HUB by handling all the necessary requests. *------------------------------------------------------------------------*/ -static void -at91dci_root_ctrl_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -at91dci_root_ctrl_close(struct usb2_xfer *xfer) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_ctrl.xfer == xfer) { - sc->sc_root_ctrl.xfer = NULL; - } - at91dci_device_done(xfer, USB_ERR_CANCELLED); -} - -/* - * USB descriptors for the virtual Root HUB: - */ - static const struct usb2_device_descriptor at91dci_devd = { .bLength = sizeof(struct usb2_device_descriptor), .bDescriptorType = UDESC_DEVICE, @@ -1765,7 +1715,6 @@ static const struct at91dci_config_desc at91dci_confd = { .bInterfaceSubClass = UISUBCLASS_HUB, .bInterfaceProtocol = UIPROTO_HSHUBSTT, }, - .endpd = { .bLength = sizeof(struct usb2_endpoint_descriptor), .bDescriptorType = UDESC_ENDPOINT, @@ -1805,44 +1754,15 @@ USB_MAKE_STRING_DESC(STRING_VENDOR, at91dci_vendor); USB_MAKE_STRING_DESC(STRING_PRODUCT, at91dci_product); static void -at91dci_root_ctrl_enter(struct usb2_xfer *xfer) +at91dci_roothub_exec(struct usb2_bus *bus) { - return; -} - -static void -at91dci_root_ctrl_start(struct usb2_xfer *xfer) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); - - sc->sc_root_ctrl.xfer = xfer; - - usb2_bus_roothub_exec(xfer->xroot->bus); -} - -static void -at91dci_root_ctrl_task(struct usb2_bus *bus) -{ - at91dci_root_ctrl_poll(AT9100_DCI_BUS2SC(bus)); -} - -static void -at91dci_root_ctrl_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); + struct at91dci_softc *sc = AT9100_DCI_BUS2SC(bus); + struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req; uint16_t value; uint16_t index; USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_SETUP) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - at91dci_device_done(xfer, std->err); - } - goto done; - } /* buffer reset */ std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0); std->len = 0; @@ -2101,7 +2021,7 @@ at91dci_root_ctrl_done(struct usb2_xfer *xfer, switch (value) { case UHF_PORT_SUSPEND: - at91dci_wakeup_peer(xfer); + at91dci_wakeup_peer(sc); break; case UHF_PORT_ENABLE: @@ -2224,67 +2144,6 @@ at91dci_root_ctrl_done(struct usb2_xfer *xfer, return; } -static void -at91dci_root_ctrl_poll(struct at91dci_softc *sc) -{ - usb2_sw_transfer(&sc->sc_root_ctrl, - &at91dci_root_ctrl_done); -} - -struct usb2_pipe_methods at91dci_root_ctrl_methods = -{ - .open = at91dci_root_ctrl_open, - .close = at91dci_root_ctrl_close, - .enter = at91dci_root_ctrl_enter, - .start = at91dci_root_ctrl_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 0, -}; - -/*------------------------------------------------------------------------* - * at91dci root interrupt support - *------------------------------------------------------------------------*/ -static void -at91dci_root_intr_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -at91dci_root_intr_close(struct usb2_xfer *xfer) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_intr.xfer == xfer) { - sc->sc_root_intr.xfer = NULL; - } - at91dci_device_done(xfer, USB_ERR_CANCELLED); -} - -static void -at91dci_root_intr_enter(struct usb2_xfer *xfer) -{ - return; -} - -static void -at91dci_root_intr_start(struct usb2_xfer *xfer) -{ - struct at91dci_softc *sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); - - sc->sc_root_intr.xfer = xfer; -} - -struct usb2_pipe_methods at91dci_root_intr_methods = -{ - .open = at91dci_root_intr_open, - .close = at91dci_root_intr_close, - .enter = at91dci_root_intr_enter, - .start = at91dci_root_intr_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 1, -}; - static void at91dci_xfer_setup(struct usb2_setup_params *parm) { @@ -2411,24 +2270,7 @@ at91dci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *ede edesc->bEndpointAddress, udev->flags.usb2_mode, sc->sc_rt_addr); - if (udev->device_index == sc->sc_rt_addr) { - - if (udev->flags.usb2_mode != USB_MODE_HOST) { - /* not supported */ - return; - } - switch (edesc->bEndpointAddress) { - case USB_CONTROL_ENDPOINT: - pipe->methods = &at91dci_root_ctrl_methods; - break; - case UE_DIR_IN | AT9100_DCI_INTR_ENDPT: - pipe->methods = &at91dci_root_intr_methods; - break; - default: - /* do nothing */ - break; - } - } else { + if (udev->device_index != sc->sc_rt_addr) { if (udev->flags.usb2_mode != USB_MODE_DEVICE) { /* not supported */ @@ -2466,5 +2308,5 @@ struct usb2_bus_methods at91dci_bus_methods = .get_hw_ep_profile = &at91dci_get_hw_ep_profile, .set_stall = &at91dci_set_stall, .clear_stall = &at91dci_clear_stall, - .roothub_exec = &at91dci_root_ctrl_task, + .roothub_exec = &at91dci_roothub_exec, }; diff --git a/sys/dev/usb/controller/at91dci.h b/sys/dev/usb/controller/at91dci.h index 6464ad79faa2..5b7e35dd933a 100644 --- a/sys/dev/usb/controller/at91dci.h +++ b/sys/dev/usb/controller/at91dci.h @@ -204,8 +204,6 @@ struct at91dci_softc { struct usb2_bus sc_bus; union at91dci_hub_temp sc_hub_temp; LIST_HEAD(, usb2_xfer) sc_interrupt_list_head; - struct usb2_sw_transfer sc_root_ctrl; - struct usb2_sw_transfer sc_root_intr; struct usb2_device *sc_devices[AT91_MAX_DEVICES]; struct resource *sc_io_res; diff --git a/sys/dev/usb/controller/atmegadci.c b/sys/dev/usb/controller/atmegadci.c index f9261e7d60af..d52e661e41eb 100644 --- a/sys/dev/usb/controller/atmegadci.c +++ b/sys/dev/usb/controller/atmegadci.c @@ -81,8 +81,6 @@ struct usb2_pipe_methods atmegadci_device_bulk_methods; struct usb2_pipe_methods atmegadci_device_ctrl_methods; struct usb2_pipe_methods atmegadci_device_intr_methods; struct usb2_pipe_methods atmegadci_device_isoc_fs_methods; -struct usb2_pipe_methods atmegadci_root_ctrl_methods; -struct usb2_pipe_methods atmegadci_root_intr_methods; static atmegadci_cmd_t atmegadci_setup_rx; static atmegadci_cmd_t atmegadci_data_rx; @@ -90,11 +88,8 @@ static atmegadci_cmd_t atmegadci_data_tx; static atmegadci_cmd_t atmegadci_data_tx_sync; static void atmegadci_device_done(struct usb2_xfer *, usb2_error_t); static void atmegadci_do_poll(struct usb2_bus *); -static void atmegadci_root_ctrl_poll(struct atmegadci_softc *); static void atmegadci_standard_done(struct usb2_xfer *); - -static usb2_sw_transfer_func_t atmegadci_root_intr_done; -static usb2_sw_transfer_func_t atmegadci_root_ctrl_done; +static void atmegadci_root_intr(struct atmegadci_softc *sc); /* * Here is a list of what the chip supports: @@ -201,9 +196,8 @@ atmegadci_pull_down(struct atmegadci_softc *sc) } static void -atmegadci_wakeup_peer(struct usb2_xfer *xfer) +atmegadci_wakeup_peer(struct atmegadci_softc *sc) { - struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus); uint8_t temp; if (!sc->sc_flags.status_suspend) { @@ -625,8 +619,7 @@ atmegadci_vbus_interrupt(struct atmegadci_softc *sc, uint8_t is_on) /* complete root HUB interrupt endpoint */ - usb2_sw_transfer(&sc->sc_root_intr, - &atmegadci_root_intr_done); + atmegadci_root_intr(sc); } } else { if (sc->sc_flags.status_vbus) { @@ -638,8 +631,7 @@ atmegadci_vbus_interrupt(struct atmegadci_softc *sc, uint8_t is_on) /* complete root HUB interrupt endpoint */ - usb2_sw_transfer(&sc->sc_root_intr, - &atmegadci_root_intr_done); + atmegadci_root_intr(sc); } } } @@ -676,8 +668,7 @@ atmegadci_interrupt(struct atmegadci_softc *sc) ATMEGA_UDINT_EORSTE); /* complete root HUB interrupt endpoint */ - usb2_sw_transfer(&sc->sc_root_intr, - &atmegadci_root_intr_done); + atmegadci_root_intr(sc); } /* * If resume and suspend is set at the same time we interpret @@ -699,8 +690,7 @@ atmegadci_interrupt(struct atmegadci_softc *sc) ATMEGA_UDINT_EORSTE); /* complete root HUB interrupt endpoint */ - usb2_sw_transfer(&sc->sc_root_intr, - &atmegadci_root_intr_done); + atmegadci_root_intr(sc); } } else if (status & ATMEGA_UDINT_SUSPI) { @@ -717,8 +707,7 @@ atmegadci_interrupt(struct atmegadci_softc *sc) ATMEGA_UDINT_EORSTE); /* complete root HUB interrupt endpoint */ - usb2_sw_transfer(&sc->sc_root_intr, - &atmegadci_root_intr_done); + atmegadci_root_intr(sc); } } /* check VBUS */ @@ -953,32 +942,18 @@ atmegadci_start_standard_chain(struct usb2_xfer *xfer) } static void -atmegadci_root_intr_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) +atmegadci_root_intr(struct atmegadci_softc *sc) { - struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus); - DPRINTFN(9, "\n"); USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_PRE_DATA) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - atmegadci_device_done(xfer, std->err); - } - goto done; - } - /* setup buffer */ - std->ptr = sc->sc_hub_idata; - std->len = sizeof(sc->sc_hub_idata); - /* set port bit */ sc->sc_hub_idata[0] = 0x02; /* we only have one port */ -done: - return; -} + uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata, + sizeof(sc->sc_hub_idata)); + } static usb2_error_t atmegadci_standard_done_sub(struct usb2_xfer *xfer) @@ -1363,7 +1338,6 @@ atmegadci_do_poll(struct usb2_bus *bus) USB_BUS_LOCK(&sc->sc_bus); atmegadci_interrupt_poll(sc); - atmegadci_root_ctrl_poll(sc); USB_BUS_UNLOCK(&sc->sc_bus); } @@ -1575,27 +1549,9 @@ struct usb2_pipe_methods atmegadci_device_isoc_fs_methods = /*------------------------------------------------------------------------* * at91dci root control support *------------------------------------------------------------------------* - * simulate a hardware HUB by handling - * all the necessary requests + * Simulate a hardware HUB by handling all the necessary requests. *------------------------------------------------------------------------*/ -static void -atmegadci_root_ctrl_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -atmegadci_root_ctrl_close(struct usb2_xfer *xfer) -{ - struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_ctrl.xfer == xfer) { - sc->sc_root_ctrl.xfer = NULL; - } - atmegadci_device_done(xfer, USB_ERR_CANCELLED); -} - /* * USB descriptors for the virtual Root HUB: */ @@ -1644,7 +1600,6 @@ static const struct atmegadci_config_desc atmegadci_confd = { .bInterfaceSubClass = UISUBCLASS_HUB, .bInterfaceProtocol = UIPROTO_HSHUBSTT, }, - .endpd = { .bLength = sizeof(struct usb2_endpoint_descriptor), .bDescriptorType = UDESC_ENDPOINT, @@ -1684,45 +1639,16 @@ USB_MAKE_STRING_DESC(STRING_VENDOR, atmegadci_vendor); USB_MAKE_STRING_DESC(STRING_PRODUCT, atmegadci_product); static void -atmegadci_root_ctrl_enter(struct usb2_xfer *xfer) +atmegadci_roothub_exec(struct usb2_bus *bus) { - return; -} - -static void -atmegadci_root_ctrl_start(struct usb2_xfer *xfer) -{ - struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus); - - sc->sc_root_ctrl.xfer = xfer; - - usb2_bus_roothub_exec(xfer->xroot->bus); -} - -static void -atmegadci_root_ctrl_task(struct usb2_bus *bus) -{ - atmegadci_root_ctrl_poll(ATMEGA_BUS2SC(bus)); -} - -static void -atmegadci_root_ctrl_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) -{ - struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus); + struct atmegadci_softc *sc = ATMEGA_BUS2SC(bus); + struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req; uint16_t value; uint16_t index; uint8_t temp; USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_SETUP) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - atmegadci_device_done(xfer, std->err); - } - goto done; - } /* buffer reset */ std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0); std->len = 0; @@ -1981,7 +1907,7 @@ atmegadci_root_ctrl_done(struct usb2_xfer *xfer, switch (value) { case UHF_PORT_SUSPEND: - atmegadci_wakeup_peer(xfer); + atmegadci_wakeup_peer(sc); break; case UHF_PORT_ENABLE: @@ -2129,67 +2055,6 @@ atmegadci_root_ctrl_done(struct usb2_xfer *xfer, return; } -static void -atmegadci_root_ctrl_poll(struct atmegadci_softc *sc) -{ - usb2_sw_transfer(&sc->sc_root_ctrl, - &atmegadci_root_ctrl_done); -} - -struct usb2_pipe_methods atmegadci_root_ctrl_methods = -{ - .open = atmegadci_root_ctrl_open, - .close = atmegadci_root_ctrl_close, - .enter = atmegadci_root_ctrl_enter, - .start = atmegadci_root_ctrl_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 0, -}; - -/*------------------------------------------------------------------------* - * at91dci root interrupt support - *------------------------------------------------------------------------*/ -static void -atmegadci_root_intr_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -atmegadci_root_intr_close(struct usb2_xfer *xfer) -{ - struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_intr.xfer == xfer) { - sc->sc_root_intr.xfer = NULL; - } - atmegadci_device_done(xfer, USB_ERR_CANCELLED); -} - -static void -atmegadci_root_intr_enter(struct usb2_xfer *xfer) -{ - return; -} - -static void -atmegadci_root_intr_start(struct usb2_xfer *xfer) -{ - struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus); - - sc->sc_root_intr.xfer = xfer; -} - -struct usb2_pipe_methods atmegadci_root_intr_methods = -{ - .open = atmegadci_root_intr_open, - .close = atmegadci_root_intr_close, - .enter = atmegadci_root_intr_enter, - .start = atmegadci_root_intr_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 1, -}; - static void atmegadci_xfer_setup(struct usb2_setup_params *parm) { @@ -2313,24 +2178,7 @@ atmegadci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *e edesc->bEndpointAddress, udev->flags.usb2_mode, sc->sc_rt_addr, udev->device_index); - if (udev->device_index == sc->sc_rt_addr) { - - if (udev->flags.usb2_mode != USB_MODE_HOST) { - /* not supported */ - return; - } - switch (edesc->bEndpointAddress) { - case USB_CONTROL_ENDPOINT: - pipe->methods = &atmegadci_root_ctrl_methods; - break; - case UE_DIR_IN | ATMEGA_INTR_ENDPT: - pipe->methods = &atmegadci_root_intr_methods; - break; - default: - /* do nothing */ - break; - } - } else { + if (udev->device_index != sc->sc_rt_addr) { if (udev->flags.usb2_mode != USB_MODE_DEVICE) { /* not supported */ @@ -2368,5 +2216,5 @@ struct usb2_bus_methods atmegadci_bus_methods = .get_hw_ep_profile = &atmegadci_get_hw_ep_profile, .set_stall = &atmegadci_set_stall, .clear_stall = &atmegadci_clear_stall, - .roothub_exec = &atmegadci_root_ctrl_task, + .roothub_exec = &atmegadci_roothub_exec, }; diff --git a/sys/dev/usb/controller/atmegadci.h b/sys/dev/usb/controller/atmegadci.h index 1e7d9646c856..6f8c656dc998 100644 --- a/sys/dev/usb/controller/atmegadci.h +++ b/sys/dev/usb/controller/atmegadci.h @@ -34,10 +34,6 @@ #define ATMEGA_MAX_DEVICES (USB_MIN_DEVICES + 1) -#ifndef ATMEGA_HAVE_BUS_SPACE -#define ATMEGA_HAVE_BUS_SPACE 1 -#endif - #define ATMEGA_UEINT 0xF4 #define ATMEGA_UEINT_MASK(n) (1 << (n)) /* endpoint interrupt mask */ @@ -241,8 +237,6 @@ struct atmegadci_softc { struct usb2_bus sc_bus; union atmegadci_hub_temp sc_hub_temp; LIST_HEAD(, usb2_xfer) sc_interrupt_list_head; - struct usb2_sw_transfer sc_root_ctrl; - struct usb2_sw_transfer sc_root_intr; /* must be set by by the bus interface layer */ atmegadci_clocks_t *sc_clocks_on; @@ -251,11 +245,10 @@ struct atmegadci_softc { struct usb2_device *sc_devices[ATMEGA_MAX_DEVICES]; struct resource *sc_irq_res; void *sc_intr_hdl; -#if (ATMEGA_HAVE_BUS_SPACE != 0) struct resource *sc_io_res; bus_space_tag_t sc_io_tag; bus_space_handle_t sc_io_hdl; -#endif + uint8_t sc_rt_addr; /* root hub address */ uint8_t sc_dv_addr; /* device address */ uint8_t sc_conf; /* root hub config */ diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c index cc17d439a8c4..09793bbc7e46 100644 --- a/sys/dev/usb/controller/ehci.c +++ b/sys/dev/usb/controller/ehci.c @@ -93,17 +93,12 @@ extern struct usb2_pipe_methods ehci_device_ctrl_methods; extern struct usb2_pipe_methods ehci_device_intr_methods; extern struct usb2_pipe_methods ehci_device_isoc_fs_methods; extern struct usb2_pipe_methods ehci_device_isoc_hs_methods; -extern struct usb2_pipe_methods ehci_root_ctrl_methods; -extern struct usb2_pipe_methods ehci_root_intr_methods; static void ehci_do_poll(struct usb2_bus *bus); -static void ehci_root_ctrl_poll(ehci_softc_t *sc); static void ehci_device_done(struct usb2_xfer *xfer, usb2_error_t error); static uint8_t ehci_check_transfer(struct usb2_xfer *xfer); static void ehci_timeout(void *arg); - -static usb2_sw_transfer_func_t ehci_root_intr_done; -static usb2_sw_transfer_func_t ehci_root_ctrl_done; +static void ehci_root_intr(ehci_softc_t *sc); struct ehci_std_temp { ehci_softc_t *sc; @@ -1415,8 +1410,7 @@ ehci_pcd_enable(ehci_softc_t *sc) /* acknowledge any PCD interrupt */ EOWRITE4(sc, EHCI_USBSTS, EHCI_STS_PCD); - usb2_sw_transfer(&sc->sc_root_intr, - &ehci_root_intr_done); + ehci_root_intr(sc); } static void @@ -1486,8 +1480,7 @@ ehci_interrupt(ehci_softc_t *sc) sc->sc_eintrs &= ~EHCI_STS_PCD; EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); - usb2_sw_transfer(&sc->sc_root_intr, - &ehci_root_intr_done); + ehci_root_intr(sc); /* do not allow RHSC interrupts > 1 per second */ usb2_callout_reset(&sc->sc_tmo_pcd, hz, @@ -1531,7 +1524,6 @@ ehci_do_poll(struct usb2_bus *bus) USB_BUS_LOCK(&sc->sc_bus); ehci_interrupt_poll(sc); - ehci_root_ctrl_poll(sc); USB_BUS_UNLOCK(&sc->sc_bus); } @@ -1979,28 +1971,15 @@ ehci_setup_standard_chain(struct usb2_xfer *xfer, ehci_qh_t **qh_last) } static void -ehci_root_intr_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) +ehci_root_intr(ehci_softc_t *sc) { - ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); uint16_t i; uint16_t m; USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_PRE_DATA) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - ehci_device_done(xfer, std->err); - } - goto done; - } - /* setup buffer */ - std->ptr = sc->sc_hub_idata; - std->len = sizeof(sc->sc_hub_idata); - /* clear any old interrupt data */ - bzero(sc->sc_hub_idata, sizeof(sc->sc_hub_idata)); + memset(sc->sc_hub_idata, 0, sizeof(sc->sc_hub_idata)); /* set bits */ m = (sc->sc_noport + 1); @@ -2014,8 +1993,8 @@ ehci_root_intr_done(struct usb2_xfer *xfer, DPRINTF("port %d changed\n", i); } } -done: - return; + uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata, + sizeof(sc->sc_hub_idata)); } static void @@ -2932,31 +2911,9 @@ struct usb2_pipe_methods ehci_device_isoc_hs_methods = /*------------------------------------------------------------------------* * ehci root control support *------------------------------------------------------------------------* - * simulate a hardware hub by handling - * all the necessary requests + * Simulate a hardware hub by handling all the necessary requests. *------------------------------------------------------------------------*/ -static void -ehci_root_ctrl_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -ehci_root_ctrl_close(struct usb2_xfer *xfer) -{ - ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_ctrl.xfer == xfer) { - sc->sc_root_ctrl.xfer = NULL; - } - ehci_device_done(xfer, USB_ERR_CANCELLED); -} - -/* data structures and routines - * to emulate the root hub: - */ - static const struct usb2_device_descriptor ehci_devd = { @@ -2997,7 +2954,6 @@ static const struct ehci_config_desc ehci_confd = { .bmAttributes = UC_SELF_POWERED, .bMaxPower = 0 /* max power */ }, - .ifcd = { .bLength = sizeof(struct usb2_interface_descriptor), .bDescriptorType = UDESC_INTERFACE, @@ -3007,7 +2963,6 @@ static const struct ehci_config_desc ehci_confd = { .bInterfaceProtocol = UIPROTO_HSHUBSTT, 0 }, - .endpd = { .bLength = sizeof(struct usb2_endpoint_descriptor), .bDescriptorType = UDESC_ENDPOINT, @@ -3044,34 +2999,10 @@ ehci_disown(ehci_softc_t *sc, uint16_t index, uint8_t lowspeed) } static void -ehci_root_ctrl_enter(struct usb2_xfer *xfer) +ehci_roothub_exec(struct usb2_bus *bus) { - return; -} - -static void -ehci_root_ctrl_start(struct usb2_xfer *xfer) -{ - ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); - - DPRINTF("\n"); - - sc->sc_root_ctrl.xfer = xfer; - - usb2_bus_roothub_exec(xfer->xroot->bus); -} - -static void -ehci_root_ctrl_task(struct usb2_bus *bus) -{ - ehci_root_ctrl_poll(EHCI_BUS2SC(bus)); -} - -static void -ehci_root_ctrl_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) -{ - ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); + ehci_softc_t *sc = EHCI_BUS2SC(bus); + struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req; char *ptr; uint32_t port; uint32_t v; @@ -3082,13 +3013,6 @@ ehci_root_ctrl_done(struct usb2_xfer *xfer, USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_SETUP) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - ehci_device_done(xfer, std->err); - } - goto done; - } /* buffer reset */ std->ptr = sc->sc_hub_desc.temp; std->len = 0; @@ -3461,67 +3385,6 @@ ehci_root_ctrl_done(struct usb2_xfer *xfer, return; } -static void -ehci_root_ctrl_poll(ehci_softc_t *sc) -{ - usb2_sw_transfer(&sc->sc_root_ctrl, - &ehci_root_ctrl_done); -} - -struct usb2_pipe_methods ehci_root_ctrl_methods = -{ - .open = ehci_root_ctrl_open, - .close = ehci_root_ctrl_close, - .enter = ehci_root_ctrl_enter, - .start = ehci_root_ctrl_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 0, -}; - -/*------------------------------------------------------------------------* - * ehci root interrupt support - *------------------------------------------------------------------------*/ -static void -ehci_root_intr_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -ehci_root_intr_close(struct usb2_xfer *xfer) -{ - ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_intr.xfer == xfer) { - sc->sc_root_intr.xfer = NULL; - } - ehci_device_done(xfer, USB_ERR_CANCELLED); -} - -static void -ehci_root_intr_enter(struct usb2_xfer *xfer) -{ - return; -} - -static void -ehci_root_intr_start(struct usb2_xfer *xfer) -{ - ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); - - sc->sc_root_intr.xfer = xfer; -} - -struct usb2_pipe_methods ehci_root_intr_methods = -{ - .open = ehci_root_intr_open, - .close = ehci_root_intr_close, - .enter = ehci_root_intr_enter, - .start = ehci_root_intr_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 1, -}; - static void ehci_xfer_setup(struct usb2_setup_params *parm) { @@ -3794,19 +3657,8 @@ ehci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc, /* not supported */ return; } - if (udev->device_index == sc->sc_addr) { - switch (edesc->bEndpointAddress) { - case USB_CONTROL_ENDPOINT: - pipe->methods = &ehci_root_ctrl_methods; - break; - case UE_DIR_IN | EHCI_INTR_ENDPT: - pipe->methods = &ehci_root_intr_methods; - break; - default: - /* do nothing */ - break; - } - } else { + if (udev->device_index != sc->sc_addr) { + if ((udev->speed != USB_SPEED_HIGH) && ((udev->hs_hub_addr == 0) || (udev->hs_port_no == 0) || @@ -3964,5 +3816,5 @@ struct usb2_bus_methods ehci_bus_methods = .device_resume = ehci_device_resume, .device_suspend = ehci_device_suspend, .set_hw_power = ehci_set_hw_power, - .roothub_exec = ehci_root_ctrl_task, + .roothub_exec = ehci_roothub_exec, }; diff --git a/sys/dev/usb/controller/ehci.h b/sys/dev/usb/controller/ehci.h index ddb2d9c6b006..d69891be8721 100644 --- a/sys/dev/usb/controller/ehci.h +++ b/sys/dev/usb/controller/ehci.h @@ -457,8 +457,6 @@ typedef struct ehci_softc { struct usb2_bus sc_bus; /* base device */ struct usb2_callout sc_tmo_pcd; union ehci_hub_desc sc_hub_desc; - struct usb2_sw_transfer sc_root_ctrl; - struct usb2_sw_transfer sc_root_intr; struct usb2_device *sc_devices[EHCI_MAX_DEVICES]; struct resource *sc_io_res; diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c index 23af416b17a2..f16d47e5785b 100644 --- a/sys/dev/usb/controller/musb_otg.c +++ b/sys/dev/usb/controller/musb_otg.c @@ -80,8 +80,6 @@ struct usb2_pipe_methods musbotg_device_bulk_methods; struct usb2_pipe_methods musbotg_device_ctrl_methods; struct usb2_pipe_methods musbotg_device_intr_methods; struct usb2_pipe_methods musbotg_device_isoc_methods; -struct usb2_pipe_methods musbotg_root_ctrl_methods; -struct usb2_pipe_methods musbotg_root_intr_methods; static musbotg_cmd_t musbotg_setup_rx; static musbotg_cmd_t musbotg_setup_data_rx; @@ -91,12 +89,9 @@ static musbotg_cmd_t musbotg_data_rx; static musbotg_cmd_t musbotg_data_tx; static void musbotg_device_done(struct usb2_xfer *, usb2_error_t); static void musbotg_do_poll(struct usb2_bus *); -static void musbotg_root_ctrl_poll(struct musbotg_softc *); static void musbotg_standard_done(struct usb2_xfer *); static void musbotg_interrupt_poll(struct musbotg_softc *); - -static usb2_sw_transfer_func_t musbotg_root_intr_done; -static usb2_sw_transfer_func_t musbotg_root_ctrl_done; +static void musbotg_root_intr(struct musbotg_softc *); /* * Here is a configuration that the chip supports. @@ -201,9 +196,8 @@ musbotg_pull_down(struct musbotg_softc *sc) } static void -musbotg_wakeup_peer(struct usb2_xfer *xfer) +musbotg_wakeup_peer(struct musbotg_softc *sc) { - struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus); uint8_t temp; if (!(sc->sc_flags.status_suspend)) { @@ -965,9 +959,7 @@ musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on) sc->sc_flags.status_vbus = 1; /* complete root HUB interrupt endpoint */ - - usb2_sw_transfer(&sc->sc_root_intr, - &musbotg_root_intr_done); + musbotg_root_intr(sc); } } else { if (sc->sc_flags.status_vbus) { @@ -978,9 +970,7 @@ musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on) sc->sc_flags.change_connect = 1; /* complete root HUB interrupt endpoint */ - - usb2_sw_transfer(&sc->sc_root_intr, - &musbotg_root_intr_done); + musbotg_root_intr(sc); } } @@ -1074,9 +1064,7 @@ musbotg_interrupt(struct musbotg_softc *sc) } } /* complete root HUB interrupt endpoint */ - - usb2_sw_transfer(&sc->sc_root_intr, - &musbotg_root_intr_done); + musbotg_root_intr(sc); } /* check for any endpoint interrupts */ @@ -1320,31 +1308,17 @@ musbotg_start_standard_chain(struct usb2_xfer *xfer) } static void -musbotg_root_intr_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) +musbotg_root_intr(struct musbotg_softc *sc) { - struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus); - DPRINTFN(8, "\n"); USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_PRE_DATA) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - musbotg_device_done(xfer, std->err); - } - goto done; - } - /* setup buffer */ - std->ptr = sc->sc_hub_idata; - std->len = sizeof(sc->sc_hub_idata); - /* set port bit */ sc->sc_hub_idata[0] = 0x02; /* we only have one port */ -done: - return; + uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata, + sizeof(sc->sc_hub_idata)); } static usb2_error_t @@ -1887,7 +1861,6 @@ musbotg_do_poll(struct usb2_bus *bus) USB_BUS_LOCK(&sc->sc_bus); musbotg_interrupt_poll(sc); - musbotg_root_ctrl_poll(sc); USB_BUS_UNLOCK(&sc->sc_bus); } @@ -2102,29 +2075,8 @@ struct usb2_pipe_methods musbotg_device_isoc_methods = /*------------------------------------------------------------------------* * musbotg root control support *------------------------------------------------------------------------* - * simulate a hardware HUB by handling - * all the necessary requests + * Simulate a hardware HUB by handling all the necessary requests. *------------------------------------------------------------------------*/ -static void -musbotg_root_ctrl_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -musbotg_root_ctrl_close(struct usb2_xfer *xfer) -{ - struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_ctrl.xfer == xfer) { - sc->sc_root_ctrl.xfer = NULL; - } - musbotg_device_done(xfer, USB_ERR_CANCELLED); -} - -/* - * USB descriptors for the virtual Root HUB: - */ static const struct usb2_device_descriptor musbotg_devd = { .bLength = sizeof(struct usb2_device_descriptor), @@ -2170,7 +2122,6 @@ static const struct musbotg_config_desc musbotg_confd = { .bInterfaceSubClass = UISUBCLASS_HUB, .bInterfaceProtocol = UIPROTO_HSHUBSTT, }, - .endpd = { .bLength = sizeof(struct usb2_endpoint_descriptor), .bDescriptorType = UDESC_ENDPOINT, @@ -2211,44 +2162,15 @@ USB_MAKE_STRING_DESC(STRING_VENDOR, musbotg_vendor); USB_MAKE_STRING_DESC(STRING_PRODUCT, musbotg_product); static void -musbotg_root_ctrl_enter(struct usb2_xfer *xfer) +musbotg_roothub_exec(struct usb2_bus *bus) { - return; -} - -static void -musbotg_root_ctrl_start(struct usb2_xfer *xfer) -{ - struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus); - - sc->sc_root_ctrl.xfer = xfer; - - usb2_bus_roothub_exec(xfer->xroot->bus); -} - -static void -musbotg_root_ctrl_task(struct usb2_bus *bus) -{ - musbotg_root_ctrl_poll(MUSBOTG_BUS2SC(bus)); -} - -static void -musbotg_root_ctrl_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) -{ - struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus); + struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus); + struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req; uint16_t value; uint16_t index; USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_SETUP) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - musbotg_device_done(xfer, std->err); - } - goto done; - } /* buffer reset */ std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0); std->len = 0; @@ -2507,7 +2429,7 @@ musbotg_root_ctrl_done(struct usb2_xfer *xfer, switch (value) { case UHF_PORT_SUSPEND: - musbotg_wakeup_peer(xfer); + musbotg_wakeup_peer(sc); break; case UHF_PORT_ENABLE: @@ -2633,67 +2555,6 @@ musbotg_root_ctrl_done(struct usb2_xfer *xfer, return; } -static void -musbotg_root_ctrl_poll(struct musbotg_softc *sc) -{ - usb2_sw_transfer(&sc->sc_root_ctrl, - &musbotg_root_ctrl_done); -} - -struct usb2_pipe_methods musbotg_root_ctrl_methods = -{ - .open = musbotg_root_ctrl_open, - .close = musbotg_root_ctrl_close, - .enter = musbotg_root_ctrl_enter, - .start = musbotg_root_ctrl_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 0, -}; - -/*------------------------------------------------------------------------* - * musbotg root interrupt support - *------------------------------------------------------------------------*/ -static void -musbotg_root_intr_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -musbotg_root_intr_close(struct usb2_xfer *xfer) -{ - struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_intr.xfer == xfer) { - sc->sc_root_intr.xfer = NULL; - } - musbotg_device_done(xfer, USB_ERR_CANCELLED); -} - -static void -musbotg_root_intr_enter(struct usb2_xfer *xfer) -{ - return; -} - -static void -musbotg_root_intr_start(struct usb2_xfer *xfer) -{ - struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus); - - sc->sc_root_intr.xfer = xfer; -} - -struct usb2_pipe_methods musbotg_root_intr_methods = -{ - .open = musbotg_root_intr_open, - .close = musbotg_root_intr_close, - .enter = musbotg_root_intr_enter, - .start = musbotg_root_intr_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 1, -}; - static void musbotg_xfer_setup(struct usb2_setup_params *parm) { @@ -2818,24 +2679,7 @@ musbotg_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *ede edesc->bEndpointAddress, udev->flags.usb2_mode, sc->sc_rt_addr); - if (udev->device_index == sc->sc_rt_addr) { - - if (udev->flags.usb2_mode != USB_MODE_HOST) { - /* not supported */ - return; - } - switch (edesc->bEndpointAddress) { - case USB_CONTROL_ENDPOINT: - pipe->methods = &musbotg_root_ctrl_methods; - break; - case UE_DIR_IN | MUSBOTG_INTR_ENDPT: - pipe->methods = &musbotg_root_intr_methods; - break; - default: - /* do nothing */ - break; - } - } else { + if (udev->device_index != sc->sc_rt_addr) { if (udev->flags.usb2_mode != USB_MODE_DEVICE) { /* not supported */ @@ -2874,5 +2718,5 @@ struct usb2_bus_methods musbotg_bus_methods = .get_hw_ep_profile = &musbotg_get_hw_ep_profile, .set_stall = &musbotg_set_stall, .clear_stall = &musbotg_clear_stall, - .roothub_exec = &musbotg_root_ctrl_task, + .roothub_exec = &musbotg_roothub_exec, }; diff --git a/sys/dev/usb/controller/musb_otg.h b/sys/dev/usb/controller/musb_otg.h index 0d880e1fd4dc..8d0e668d260c 100644 --- a/sys/dev/usb/controller/musb_otg.h +++ b/sys/dev/usb/controller/musb_otg.h @@ -363,8 +363,6 @@ struct musbotg_flags { struct musbotg_softc { struct usb2_bus sc_bus; union musbotg_hub_temp sc_hub_temp; - struct usb2_sw_transfer sc_root_ctrl; - struct usb2_sw_transfer sc_root_intr; struct usb2_hw_ep_profile sc_hw_ep_profile[16]; struct usb2_device *sc_devices[MUSB2_MAX_DEVICES]; diff --git a/sys/dev/usb/controller/ohci.c b/sys/dev/usb/controller/ohci.c index f99fffbde360..114311d3b4b6 100644 --- a/sys/dev/usb/controller/ohci.c +++ b/sys/dev/usb/controller/ohci.c @@ -93,17 +93,12 @@ extern struct usb2_pipe_methods ohci_device_bulk_methods; extern struct usb2_pipe_methods ohci_device_ctrl_methods; extern struct usb2_pipe_methods ohci_device_intr_methods; extern struct usb2_pipe_methods ohci_device_isoc_methods; -extern struct usb2_pipe_methods ohci_root_ctrl_methods; -extern struct usb2_pipe_methods ohci_root_intr_methods; -static void ohci_root_ctrl_poll(struct ohci_softc *sc); static void ohci_do_poll(struct usb2_bus *bus); static void ohci_device_done(struct usb2_xfer *xfer, usb2_error_t error); - -static usb2_sw_transfer_func_t ohci_root_intr_done; -static usb2_sw_transfer_func_t ohci_root_ctrl_done; static void ohci_timeout(void *arg); static uint8_t ohci_check_transfer(struct usb2_xfer *xfer); +static void ohci_root_intr(ohci_softc_t *sc); struct ohci_std_temp { struct usb2_page_cache *pc; @@ -1104,8 +1099,7 @@ ohci_rhsc_enable(ohci_softc_t *sc) /* acknowledge any RHSC interrupt */ OWRITE4(sc, OHCI_INTERRUPT_STATUS, OHCI_RHSC); - usb2_sw_transfer(&sc->sc_root_intr, - &ohci_root_intr_done); + ohci_root_intr(sc); } static void @@ -1219,8 +1213,7 @@ ohci_interrupt(ohci_softc_t *sc) sc->sc_eintrs &= ~OHCI_RHSC; OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_RHSC); - usb2_sw_transfer(&sc->sc_root_intr, - &ohci_root_intr_done); + ohci_root_intr(sc); /* do not allow RHSC interrupts > 1 per second */ usb2_callout_reset(&sc->sc_tmo_rhsc, hz, @@ -1265,7 +1258,6 @@ ohci_do_poll(struct usb2_bus *bus) USB_BUS_LOCK(&sc->sc_bus); ohci_interrupt_poll(sc); - ohci_root_ctrl_poll(sc); USB_BUS_UNLOCK(&sc->sc_bus); } @@ -1618,33 +1610,20 @@ ohci_setup_standard_chain(struct usb2_xfer *xfer, ohci_ed_t **ed_last) } static void -ohci_root_intr_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) +ohci_root_intr(ohci_softc_t *sc) { - ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus); uint32_t hstatus; uint16_t i; uint16_t m; USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_PRE_DATA) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - ohci_device_done(xfer, std->err); - } - goto done; - } - /* setup buffer */ - std->ptr = sc->sc_hub_idata; - std->len = sizeof(sc->sc_hub_idata); - /* clear any old interrupt data */ - bzero(sc->sc_hub_idata, sizeof(sc->sc_hub_idata)); + memset(sc->sc_hub_idata, 0, sizeof(sc->sc_hub_idata)); hstatus = OREAD4(sc, OHCI_RH_STATUS); - DPRINTF("sc=%p xfer=%p hstatus=0x%08x\n", - sc, xfer, hstatus); + DPRINTF("sc=%p hstatus=0x%08x\n", + sc, hstatus); /* set bits */ m = (sc->sc_noport + 1); @@ -1658,8 +1637,9 @@ ohci_root_intr_done(struct usb2_xfer *xfer, DPRINTF("port %d changed\n", i); } } -done: - return; + + uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata, + sizeof(sc->sc_hub_idata)); } /* NOTE: "done" can be run two times in a row, @@ -2074,30 +2054,9 @@ struct usb2_pipe_methods ohci_device_isoc_methods = /*------------------------------------------------------------------------* * ohci root control support *------------------------------------------------------------------------* - * simulate a hardware hub by handling - * all the necessary requests + * Simulate a hardware hub by handling all the necessary requests. *------------------------------------------------------------------------*/ -static void -ohci_root_ctrl_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -ohci_root_ctrl_close(struct usb2_xfer *xfer) -{ - ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_ctrl.xfer == xfer) { - sc->sc_root_ctrl.xfer = NULL; - } - ohci_device_done(xfer, USB_ERR_CANCELLED); -} - -/* data structures and routines - * to emulate the root hub: - */ static const struct usb2_device_descriptor ohci_devd = { @@ -2126,7 +2085,6 @@ struct ohci_config_desc ohci_confd = .bmAttributes = UC_SELF_POWERED, .bMaxPower = 0, /* max power */ }, - .ifcd = { .bLength = sizeof(struct usb2_interface_descriptor), .bDescriptorType = UDESC_INTERFACE, @@ -2135,7 +2093,6 @@ struct ohci_config_desc ohci_confd = .bInterfaceSubClass = UISUBCLASS_HUB, .bInterfaceProtocol = UIPROTO_FSHUB, }, - .endpd = { .bLength = sizeof(struct usb2_endpoint_descriptor), .bDescriptorType = UDESC_ENDPOINT, @@ -2159,32 +2116,10 @@ struct usb2_hub_descriptor ohci_hubd = }; static void -ohci_root_ctrl_enter(struct usb2_xfer *xfer) +ohci_roothub_exec(struct usb2_bus *bus) { - return; -} - -static void -ohci_root_ctrl_start(struct usb2_xfer *xfer) -{ - ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus); - - sc->sc_root_ctrl.xfer = xfer; - - usb2_bus_roothub_exec(xfer->xroot->bus); -} - -static void -ohci_root_ctrl_task(struct usb2_bus *bus) -{ - ohci_root_ctrl_poll(OHCI_BUS2SC(bus)); -} - -static void -ohci_root_ctrl_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) -{ - ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus); + ohci_softc_t *sc = OHCI_BUS2SC(bus); + struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req; char *ptr; uint32_t port; uint32_t v; @@ -2194,13 +2129,6 @@ ohci_root_ctrl_done(struct usb2_xfer *xfer, USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_SETUP) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - ohci_device_done(xfer, std->err); - } - goto done; - } /* buffer reset */ std->ptr = sc->sc_hub_desc.temp; std->len = 0; @@ -2473,67 +2401,6 @@ ohci_root_ctrl_done(struct usb2_xfer *xfer, return; } -static void -ohci_root_ctrl_poll(struct ohci_softc *sc) -{ - usb2_sw_transfer(&sc->sc_root_ctrl, - &ohci_root_ctrl_done); -} - -struct usb2_pipe_methods ohci_root_ctrl_methods = -{ - .open = ohci_root_ctrl_open, - .close = ohci_root_ctrl_close, - .enter = ohci_root_ctrl_enter, - .start = ohci_root_ctrl_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 0, -}; - -/*------------------------------------------------------------------------* - * ohci root interrupt support - *------------------------------------------------------------------------*/ -static void -ohci_root_intr_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -ohci_root_intr_close(struct usb2_xfer *xfer) -{ - ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_intr.xfer == xfer) { - sc->sc_root_intr.xfer = NULL; - } - ohci_device_done(xfer, USB_ERR_CANCELLED); -} - -static void -ohci_root_intr_enter(struct usb2_xfer *xfer) -{ - return; -} - -static void -ohci_root_intr_start(struct usb2_xfer *xfer) -{ - ohci_softc_t *sc = OHCI_BUS2SC(xfer->xroot->bus); - - sc->sc_root_intr.xfer = xfer; -} - -struct usb2_pipe_methods ohci_root_intr_methods = -{ - .open = ohci_root_intr_open, - .close = ohci_root_intr_close, - .enter = ohci_root_intr_enter, - .start = ohci_root_intr_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 1, -}; - static void ohci_xfer_setup(struct usb2_setup_params *parm) { @@ -2713,19 +2580,7 @@ ohci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc, /* not supported */ return; } - if (udev->device_index == sc->sc_addr) { - switch (edesc->bEndpointAddress) { - case USB_CONTROL_ENDPOINT: - pipe->methods = &ohci_root_ctrl_methods; - break; - case UE_DIR_IN | OHCI_INTR_ENDPT: - pipe->methods = &ohci_root_intr_methods; - break; - default: - /* do nothing */ - break; - } - } else { + if (udev->device_index != sc->sc_addr) { switch (edesc->bmAttributes & UE_XFERTYPE) { case UE_CONTROL: pipe->methods = &ohci_device_ctrl_methods; @@ -2884,5 +2739,5 @@ struct usb2_bus_methods ohci_bus_methods = .device_resume = ohci_device_resume, .device_suspend = ohci_device_suspend, .set_hw_power = ohci_set_hw_power, - .roothub_exec = ohci_root_ctrl_task, + .roothub_exec = ohci_roothub_exec, }; diff --git a/sys/dev/usb/controller/ohci.h b/sys/dev/usb/controller/ohci.h index 47d3be332fc5..8586cace2292 100644 --- a/sys/dev/usb/controller/ohci.h +++ b/sys/dev/usb/controller/ohci.h @@ -322,8 +322,6 @@ typedef struct ohci_softc { struct usb2_bus sc_bus; /* base device */ struct usb2_callout sc_tmo_rhsc; union ohci_hub_desc sc_hub_desc; - struct usb2_sw_transfer sc_root_ctrl; - struct usb2_sw_transfer sc_root_intr; struct usb2_device *sc_devices[OHCI_MAX_DEVICES]; struct resource *sc_io_res; diff --git a/sys/dev/usb/controller/uhci.c b/sys/dev/usb/controller/uhci.c index 7ed55db9f0d5..1b96b7c4f078 100644 --- a/sys/dev/usb/controller/uhci.c +++ b/sys/dev/usb/controller/uhci.c @@ -132,16 +132,13 @@ extern struct usb2_pipe_methods uhci_device_bulk_methods; extern struct usb2_pipe_methods uhci_device_ctrl_methods; extern struct usb2_pipe_methods uhci_device_intr_methods; extern struct usb2_pipe_methods uhci_device_isoc_methods; -extern struct usb2_pipe_methods uhci_root_ctrl_methods; -extern struct usb2_pipe_methods uhci_root_intr_methods; -static void uhci_root_ctrl_poll(struct uhci_softc *); static void uhci_do_poll(struct usb2_bus *); static void uhci_device_done(struct usb2_xfer *, usb2_error_t); static void uhci_transfer_intr_enqueue(struct usb2_xfer *); -static void uhci_root_intr_check(void *); static void uhci_timeout(void *); static uint8_t uhci_check_transfer(struct usb2_xfer *); +static void uhci_root_intr(uhci_softc_t *sc); void uhci_iterate_hw_softc(struct usb2_bus *bus, usb2_bus_mem_sub_cb_t *cb) @@ -317,6 +314,13 @@ uhci_reset(uhci_softc_t *sc) UWRITE4(sc, UHCI_FLBASEADDR, buf_res.physaddr); UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum); UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof); + + USB_BUS_UNLOCK(&sc->sc_bus); + + /* stop root interrupt */ + usb2_callout_drain(&sc->sc_root_intr); + + USB_BUS_LOCK(&sc->sc_bus); } static void @@ -358,7 +362,8 @@ uhci_start(uhci_softc_t *sc) "cannot start HC controller\n"); done: - return; + /* start root interrupt */ + uhci_root_intr(sc); } static struct uhci_qh * @@ -408,12 +413,13 @@ uhci_init(uhci_softc_t *sc) DPRINTF("start\n"); + usb2_callout_init_mtx(&sc->sc_root_intr, &sc->sc_bus.bus_mtx, 0); + #if USB_DEBUG if (uhcidebug > 2) { uhci_dumpregs(sc); } #endif - sc->sc_saved_sof = 0x40; /* default value */ sc->sc_saved_frnum = 0; /* default frame number */ @@ -1505,7 +1511,6 @@ uhci_do_poll(struct usb2_bus *bus) USB_BUS_LOCK(&sc->sc_bus); uhci_interrupt_poll(sc); - uhci_root_ctrl_poll(sc); USB_BUS_UNLOCK(&sc->sc_bus); } @@ -2307,31 +2312,9 @@ struct usb2_pipe_methods uhci_device_isoc_methods = /*------------------------------------------------------------------------* * uhci root control support *------------------------------------------------------------------------* - * simulate a hardware hub by handling - * all the necessary requests + * Simulate a hardware hub by handling all the necessary requests. *------------------------------------------------------------------------*/ -static void -uhci_root_ctrl_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -uhci_root_ctrl_close(struct usb2_xfer *xfer) -{ - uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_ctrl.xfer == xfer) { - sc->sc_root_ctrl.xfer = NULL; - } - uhci_device_done(xfer, USB_ERR_CANCELLED); -} - -/* data structures and routines - * to emulate the root hub: - */ - static const struct usb2_device_descriptor uhci_devd = { @@ -2358,7 +2341,6 @@ static const struct uhci_config_desc uhci_confd = { .bmAttributes = UC_SELF_POWERED, .bMaxPower = 0 /* max power */ }, - .ifcd = { .bLength = sizeof(struct usb2_interface_descriptor), .bDescriptorType = UDESC_INTERFACE, @@ -2367,7 +2349,6 @@ static const struct uhci_config_desc uhci_confd = { .bInterfaceSubClass = UISUBCLASS_HUB, .bInterfaceProtocol = UIPROTO_FSHUB, }, - .endpd = { .bLength = sizeof(struct usb2_endpoint_descriptor), .bDescriptorType = UDESC_ENDPOINT, @@ -2511,34 +2492,10 @@ uhci_portreset(uhci_softc_t *sc, uint16_t index) } static void -uhci_root_ctrl_enter(struct usb2_xfer *xfer) +uhci_roothub_exec(struct usb2_bus *bus) { - return; -} - -static void -uhci_root_ctrl_start(struct usb2_xfer *xfer) -{ - uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus); - - DPRINTF("\n"); - - sc->sc_root_ctrl.xfer = xfer; - - usb2_bus_roothub_exec(xfer->xroot->bus); -} - -static void -uhci_root_ctrl_task(struct usb2_bus *bus) -{ - uhci_root_ctrl_poll(UHCI_BUS2SC(bus)); -} - -static void -uhci_root_ctrl_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) -{ - uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus); + uhci_softc_t *sc = UHCI_BUS2SC(bus); + struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req; char *ptr; uint16_t x; uint16_t port; @@ -2549,13 +2506,6 @@ uhci_root_ctrl_done(struct usb2_xfer *xfer, USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_SETUP) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - uhci_device_done(xfer, std->err); - } - goto done; - } /* buffer reset */ std->ptr = sc->sc_hub_desc.temp; std->len = 0; @@ -2856,92 +2806,13 @@ uhci_root_ctrl_done(struct usb2_xfer *xfer, return; } -static void -uhci_root_ctrl_poll(struct uhci_softc *sc) -{ - usb2_sw_transfer(&sc->sc_root_ctrl, - &uhci_root_ctrl_done); -} - -struct usb2_pipe_methods uhci_root_ctrl_methods = -{ - .open = uhci_root_ctrl_open, - .close = uhci_root_ctrl_close, - .enter = uhci_root_ctrl_enter, - .start = uhci_root_ctrl_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 0, -}; - -/*------------------------------------------------------------------------* - * uhci root interrupt support - *------------------------------------------------------------------------*/ -static void -uhci_root_intr_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -uhci_root_intr_close(struct usb2_xfer *xfer) -{ - uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_intr.xfer == xfer) { - sc->sc_root_intr.xfer = NULL; - } - uhci_device_done(xfer, USB_ERR_CANCELLED); -} - -static void -uhci_root_intr_enter(struct usb2_xfer *xfer) -{ - return; -} - -static void -uhci_root_intr_start(struct usb2_xfer *xfer) -{ - uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus); - - sc->sc_root_intr.xfer = xfer; - - usb2_transfer_timeout_ms(xfer, - &uhci_root_intr_check, xfer->interval); -} - -static void -uhci_root_intr_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) -{ - uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus); - - USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - - if (std->state != USB_SW_TR_PRE_DATA) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer is transferred */ - uhci_device_done(xfer, std->err); - } - goto done; - } - /* setup buffer */ - std->ptr = sc->sc_hub_idata; - std->len = sizeof(sc->sc_hub_idata); -done: - return; -} - /* - * this routine is executed periodically and simulates interrupts - * from the root controller interrupt pipe for port status change + * This routine is executed periodically and simulates interrupts from + * the root controller interrupt pipe for port status change: */ static void -uhci_root_intr_check(void *arg) +uhci_root_intr(uhci_softc_t *sc) { - struct usb2_xfer *xfer = arg; - uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus); - DPRINTFN(21, "\n"); USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); @@ -2956,27 +2827,17 @@ uhci_root_intr_check(void *arg) UHCI_PORTSC_OCIC | UHCI_PORTSC_RD)) { sc->sc_hub_idata[0] |= 1 << 2; } - if (sc->sc_hub_idata[0] == 0) { - /* - * no change or controller not running, try again in a while - */ - uhci_root_intr_start(xfer); - } else { - usb2_sw_transfer(&sc->sc_root_intr, - &uhci_root_intr_done); + + /* restart timer */ + usb2_callout_reset(&sc->sc_root_intr, hz, + (void *)&uhci_root_intr, sc); + + if (sc->sc_hub_idata[0] != 0) { + uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata, + sizeof(sc->sc_hub_idata)); } } -struct usb2_pipe_methods uhci_root_intr_methods = -{ - .open = uhci_root_intr_open, - .close = uhci_root_intr_close, - .enter = uhci_root_intr_enter, - .start = uhci_root_intr_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 1, -}; - static void uhci_xfer_setup(struct usb2_setup_params *parm) { @@ -3188,19 +3049,7 @@ uhci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc, /* not supported */ return; } - if (udev->device_index == sc->sc_addr) { - switch (edesc->bEndpointAddress) { - case USB_CONTROL_ENDPOINT: - pipe->methods = &uhci_root_ctrl_methods; - break; - case UE_DIR_IN | UHCI_INTR_ENDPT: - pipe->methods = &uhci_root_intr_methods; - break; - default: - /* do nothing */ - break; - } - } else { + if (udev->device_index != sc->sc_addr) { switch (edesc->bmAttributes & UE_XFERTYPE) { case UE_CONTROL: pipe->methods = &uhci_device_ctrl_methods; @@ -3374,5 +3223,5 @@ struct usb2_bus_methods uhci_bus_methods = .device_resume = uhci_device_resume, .device_suspend = uhci_device_suspend, .set_hw_power = uhci_set_hw_power, - .roothub_exec = uhci_root_ctrl_task, + .roothub_exec = uhci_roothub_exec, }; diff --git a/sys/dev/usb/controller/uhci.h b/sys/dev/usb/controller/uhci.h index c652dd866438..652c6dcd7d52 100644 --- a/sys/dev/usb/controller/uhci.h +++ b/sys/dev/usb/controller/uhci.h @@ -271,19 +271,19 @@ typedef struct uhci_softc { struct uhci_hw_softc sc_hw; struct usb2_bus sc_bus; /* base device */ union uhci_hub_desc sc_hub_desc; - struct usb2_sw_transfer sc_root_ctrl; - struct usb2_sw_transfer sc_root_intr; + struct usb2_callout sc_root_intr; struct usb2_device *sc_devices[UHCI_MAX_DEVICES]; - struct uhci_td *sc_isoc_p_last[UHCI_VFRAMELIST_COUNT]; /* pointer to last TD - * for isochronous */ - struct uhci_qh *sc_intr_p_last[UHCI_IFRAMELIST_COUNT]; /* pointer to last QH - * for interrupt */ - struct uhci_qh *sc_ls_ctl_p_last; /* pointer to last QH for low - * speed control */ - struct uhci_qh *sc_fs_ctl_p_last; /* pointer to last QH for full - * speed control */ - struct uhci_qh *sc_bulk_p_last; /* pointer to last QH for bulk */ + /* pointer to last TD for isochronous */ + struct uhci_td *sc_isoc_p_last[UHCI_VFRAMELIST_COUNT]; + /* pointer to last QH for interrupt */ + struct uhci_qh *sc_intr_p_last[UHCI_IFRAMELIST_COUNT]; + /* pointer to last QH for low speed control */ + struct uhci_qh *sc_ls_ctl_p_last; + /* pointer to last QH for full speed control */ + struct uhci_qh *sc_fs_ctl_p_last; + /* pointer to last QH for bulk */ + struct uhci_qh *sc_bulk_p_last; struct uhci_qh *sc_reclaim_qh_p; struct uhci_qh *sc_last_qh_p; struct uhci_td *sc_last_td_p; diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c index 7ae0ce83605e..33df798ae697 100644 --- a/sys/dev/usb/controller/usb_controller.c +++ b/sys/dev/usb/controller/usb_controller.c @@ -49,7 +49,6 @@ static device_detach_t usb2_detach; static void usb2_attach_sub(device_t, struct usb2_bus *); static void usb2_post_init(void *); -static void usb2_bus_roothub(struct usb2_proc_msg *pm); /* static variables */ @@ -166,10 +165,6 @@ usb2_detach(device_t dev) usb2_proc_free(&bus->giant_callback_proc); usb2_proc_free(&bus->non_giant_callback_proc); - /* Get rid of USB roothub process */ - - usb2_proc_free(&bus->roothub_proc); - /* Get rid of USB explore process */ usb2_proc_free(&bus->explore_proc); @@ -403,12 +398,7 @@ usb2_attach_sub(device_t dev, struct usb2_bus *bus) bus->attach_msg[1].hdr.pm_callback = &usb2_bus_attach; bus->attach_msg[1].bus = bus; - bus->roothub_msg[0].hdr.pm_callback = &usb2_bus_roothub; - bus->roothub_msg[0].bus = bus; - bus->roothub_msg[1].hdr.pm_callback = &usb2_bus_roothub; - bus->roothub_msg[1].bus = bus; - - /* Create USB explore, roothub and callback processes */ + /* Create USB explore and callback processes */ if (usb2_proc_create(&bus->giant_callback_proc, &bus->bus_mtx, pname, USB_PRI_MED)) { @@ -418,10 +408,6 @@ usb2_attach_sub(device_t dev, struct usb2_bus *bus) &bus->bus_mtx, pname, USB_PRI_HIGH)) { printf("WARNING: Creation of USB non-Giant " "callback process failed.\n"); - } else if (usb2_proc_create(&bus->roothub_proc, - &bus->bus_mtx, pname, USB_PRI_HIGH)) { - printf("WARNING: Creation of USB roothub " - "process failed.\n"); } else if (usb2_proc_create(&bus->explore_proc, &bus->bus_mtx, pname, USB_PRI_MED)) { printf("WARNING: Creation of USB explore " @@ -597,38 +583,3 @@ usb2_bus_mem_free_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb) mtx_destroy(&bus->bus_mtx); } - -/*------------------------------------------------------------------------* - * usb2_bus_roothub - * - * This function is used to execute roothub control requests on the - * roothub and is called from the roothub process. - *------------------------------------------------------------------------*/ -static void -usb2_bus_roothub(struct usb2_proc_msg *pm) -{ - struct usb2_bus *bus; - - bus = ((struct usb2_bus_msg *)pm)->bus; - - USB_BUS_LOCK_ASSERT(bus, MA_OWNED); - - (bus->methods->roothub_exec) (bus); -} - -/*------------------------------------------------------------------------* - * usb2_bus_roothub_exec - * - * This function is used to schedule the "roothub_done" bus callback - * method. The bus lock must be locked when calling this function. - *------------------------------------------------------------------------*/ -void -usb2_bus_roothub_exec(struct usb2_bus *bus) -{ - USB_BUS_LOCK_ASSERT(bus, MA_OWNED); - - if (usb2_proc_msignal(&bus->roothub_proc, - &bus->roothub_msg[0], &bus->roothub_msg[1])) { - /* ignore */ - } -} diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c index bcf877ea8c65..0009664d5620 100644 --- a/sys/dev/usb/controller/uss820dci.c +++ b/sys/dev/usb/controller/uss820dci.c @@ -77,8 +77,6 @@ struct usb2_pipe_methods uss820dci_device_bulk_methods; struct usb2_pipe_methods uss820dci_device_ctrl_methods; struct usb2_pipe_methods uss820dci_device_intr_methods; struct usb2_pipe_methods uss820dci_device_isoc_fs_methods; -struct usb2_pipe_methods uss820dci_root_ctrl_methods; -struct usb2_pipe_methods uss820dci_root_intr_methods; static uss820dci_cmd_t uss820dci_setup_rx; static uss820dci_cmd_t uss820dci_data_rx; @@ -86,14 +84,11 @@ static uss820dci_cmd_t uss820dci_data_tx; static uss820dci_cmd_t uss820dci_data_tx_sync; static void uss820dci_device_done(struct usb2_xfer *, usb2_error_t); static void uss820dci_do_poll(struct usb2_bus *); -static void uss820dci_root_ctrl_poll(struct uss820dci_softc *); static void uss820dci_standard_done(struct usb2_xfer *); static void uss820dci_intr_set(struct usb2_xfer *, uint8_t); static void uss820dci_update_shared_1(struct uss820dci_softc *, uint8_t, uint8_t, uint8_t); - -static usb2_sw_transfer_func_t uss820dci_root_intr_done; -static usb2_sw_transfer_func_t uss820dci_root_ctrl_done; +static void uss820dci_root_intr(struct uss820dci_softc *); /* * Here is a list of what the USS820D chip can support. The main @@ -786,9 +781,7 @@ uss820dci_interrupt(struct uss820dci_softc *sc) DPRINTF("real bus interrupt 0x%02x\n", ssr); /* complete root HUB interrupt endpoint */ - - usb2_sw_transfer(&sc->sc_root_intr, - &uss820dci_root_intr_done); + uss820dci_root_intr(sc); } } /* acknowledge all SBI interrupts */ @@ -1047,31 +1040,17 @@ uss820dci_start_standard_chain(struct usb2_xfer *xfer) } static void -uss820dci_root_intr_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) +uss820dci_root_intr(struct uss820dci_softc *sc) { - struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); - DPRINTFN(9, "\n"); USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_PRE_DATA) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - uss820dci_device_done(xfer, std->err); - } - goto done; - } - /* setup buffer */ - std->ptr = sc->sc_hub_idata; - std->len = sizeof(sc->sc_hub_idata); - /* set port bit */ sc->sc_hub_idata[0] = 0x02; /* we only have one port */ -done: - return; + uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata, + sizeof(sc->sc_hub_idata)); } static usb2_error_t @@ -1525,7 +1504,6 @@ uss820dci_do_poll(struct usb2_bus *bus) USB_BUS_LOCK(&sc->sc_bus); uss820dci_interrupt_poll(sc); - uss820dci_root_ctrl_poll(sc); USB_BUS_UNLOCK(&sc->sc_bus); } @@ -1733,31 +1711,9 @@ struct usb2_pipe_methods uss820dci_device_isoc_fs_methods = /*------------------------------------------------------------------------* * at91dci root control support *------------------------------------------------------------------------* - * simulate a hardware HUB by handling - * all the necessary requests + * Simulate a hardware HUB by handling all the necessary requests. *------------------------------------------------------------------------*/ -static void -uss820dci_root_ctrl_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -uss820dci_root_ctrl_close(struct usb2_xfer *xfer) -{ - struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_ctrl.xfer == xfer) { - sc->sc_root_ctrl.xfer = NULL; - } - uss820dci_device_done(xfer, USB_ERR_CANCELLED); -} - -/* - * USB descriptors for the virtual Root HUB: - */ - static const struct usb2_device_descriptor uss820dci_devd = { .bLength = sizeof(struct usb2_device_descriptor), .bDescriptorType = UDESC_DEVICE, @@ -1842,44 +1798,15 @@ USB_MAKE_STRING_DESC(STRING_VENDOR, uss820dci_vendor); USB_MAKE_STRING_DESC(STRING_PRODUCT, uss820dci_product); static void -uss820dci_root_ctrl_enter(struct usb2_xfer *xfer) +uss820dci_roothub_exec(struct usb2_bus *bus) { - return; -} - -static void -uss820dci_root_ctrl_start(struct usb2_xfer *xfer) -{ - struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); - - sc->sc_root_ctrl.xfer = xfer; - - usb2_bus_roothub_exec(xfer->xroot->bus); -} - -static void -uss820dci_root_ctrl_task(struct usb2_bus *bus) -{ - uss820dci_root_ctrl_poll(USS820_DCI_BUS2SC(bus)); -} - -static void -uss820dci_root_ctrl_done(struct usb2_xfer *xfer, - struct usb2_sw_transfer *std) -{ - struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); + struct uss820dci_softc *sc = USS820_DCI_BUS2SC(bus); + struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req; uint16_t value; uint16_t index; USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); - if (std->state != USB_SW_TR_SETUP) { - if (std->state == USB_SW_TR_PRE_CALLBACK) { - /* transfer transferred */ - uss820dci_device_done(xfer, std->err); - } - goto done; - } /* buffer reset */ std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0); std->len = 0; @@ -2252,67 +2179,6 @@ uss820dci_root_ctrl_done(struct usb2_xfer *xfer, return; } -static void -uss820dci_root_ctrl_poll(struct uss820dci_softc *sc) -{ - usb2_sw_transfer(&sc->sc_root_ctrl, - &uss820dci_root_ctrl_done); -} - -struct usb2_pipe_methods uss820dci_root_ctrl_methods = -{ - .open = uss820dci_root_ctrl_open, - .close = uss820dci_root_ctrl_close, - .enter = uss820dci_root_ctrl_enter, - .start = uss820dci_root_ctrl_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 0, -}; - -/*------------------------------------------------------------------------* - * at91dci root interrupt support - *------------------------------------------------------------------------*/ -static void -uss820dci_root_intr_open(struct usb2_xfer *xfer) -{ - return; -} - -static void -uss820dci_root_intr_close(struct usb2_xfer *xfer) -{ - struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); - - if (sc->sc_root_intr.xfer == xfer) { - sc->sc_root_intr.xfer = NULL; - } - uss820dci_device_done(xfer, USB_ERR_CANCELLED); -} - -static void -uss820dci_root_intr_enter(struct usb2_xfer *xfer) -{ - return; -} - -static void -uss820dci_root_intr_start(struct usb2_xfer *xfer) -{ - struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); - - sc->sc_root_intr.xfer = xfer; -} - -struct usb2_pipe_methods uss820dci_root_intr_methods = -{ - .open = uss820dci_root_intr_open, - .close = uss820dci_root_intr_close, - .enter = uss820dci_root_intr_enter, - .start = uss820dci_root_intr_start, - .enter_is_cancelable = 1, - .start_is_cancelable = 1, -}; - static void uss820dci_xfer_setup(struct usb2_setup_params *parm) { @@ -2452,24 +2318,7 @@ uss820dci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *e edesc->bEndpointAddress, udev->flags.usb2_mode, sc->sc_rt_addr); - if (udev->device_index == sc->sc_rt_addr) { - - if (udev->flags.usb2_mode != USB_MODE_HOST) { - /* not supported */ - return; - } - switch (edesc->bEndpointAddress) { - case USB_CONTROL_ENDPOINT: - pipe->methods = &uss820dci_root_ctrl_methods; - break; - case UE_DIR_IN | USS820_DCI_INTR_ENDPT: - pipe->methods = &uss820dci_root_intr_methods; - break; - default: - /* do nothing */ - break; - } - } else { + if (udev->device_index != sc->sc_rt_addr) { if (udev->flags.usb2_mode != USB_MODE_DEVICE) { /* not supported */ @@ -2507,5 +2356,5 @@ struct usb2_bus_methods uss820dci_bus_methods = .get_hw_ep_profile = &uss820dci_get_hw_ep_profile, .set_stall = &uss820dci_set_stall, .clear_stall = &uss820dci_clear_stall, - .roothub_exec = &uss820dci_root_ctrl_task, + .roothub_exec = &uss820dci_roothub_exec, }; diff --git a/sys/dev/usb/controller/uss820dci.h b/sys/dev/usb/controller/uss820dci.h index fcddb4a4beb4..637f562b9a83 100644 --- a/sys/dev/usb/controller/uss820dci.h +++ b/sys/dev/usb/controller/uss820dci.h @@ -345,8 +345,6 @@ struct uss820dci_softc { struct usb2_bus sc_bus; union uss820_hub_temp sc_hub_temp; LIST_HEAD(, usb2_xfer) sc_interrupt_list_head; - struct usb2_sw_transfer sc_root_ctrl; - struct usb2_sw_transfer sc_root_intr; struct usb2_device *sc_devices[USS820_MAX_DEVICES]; struct resource *sc_io_res; diff --git a/sys/dev/usb/usb_bus.h b/sys/dev/usb/usb_bus.h index 8a4575fadf65..ac849504c90d 100644 --- a/sys/dev/usb/usb_bus.h +++ b/sys/dev/usb/usb_bus.h @@ -44,6 +44,17 @@ struct usb2_bus_stat { uint32_t uds_requests[4]; }; +/* + * The following structure is used to keep the state of a standard + * root transfer. + */ +struct usb2_sw_transfer { + struct usb2_device_request req; + uint8_t *ptr; + uint16_t len; + usb2_error_t err; +}; + /* * The following structure defines an USB BUS. There is one USB BUS * for every Host or Device controller. @@ -52,7 +63,7 @@ struct usb2_bus { struct usb2_bus_stat stats_err; struct usb2_bus_stat stats_ok; struct usb2_process explore_proc; - struct usb2_process roothub_proc; + struct usb2_sw_transfer roothub_req; struct root_hold_token *bus_roothold; /* * There are two callback processes. One for Giant locked @@ -64,7 +75,6 @@ struct usb2_bus { struct usb2_bus_msg explore_msg[2]; struct usb2_bus_msg detach_msg[2]; struct usb2_bus_msg attach_msg[2]; - struct usb2_bus_msg roothub_msg[2]; /* * This mutex protects the USB hardware: */ diff --git a/sys/dev/usb/usb_controller.h b/sys/dev/usb/usb_controller.h index 24a95bd0220e..16adbbd6aad5 100644 --- a/sys/dev/usb/usb_controller.h +++ b/sys/dev/usb/usb_controller.h @@ -190,7 +190,6 @@ struct usb2_temp_setup { void usb2_bus_mem_flush_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb); uint8_t usb2_bus_mem_alloc_all(struct usb2_bus *bus, bus_dma_tag_t dmat, usb2_bus_mem_cb_t *cb); void usb2_bus_mem_free_all(struct usb2_bus *bus, usb2_bus_mem_cb_t *cb); -void usb2_bus_roothub_exec(struct usb2_bus *bus); uint16_t usb2_isoc_time_expand(struct usb2_bus *bus, uint16_t isoc_time_curr); uint16_t usb2_fs_isoc_schedule_isoc_time_expand(struct usb2_device *udev, struct usb2_fs_isoc_schedule **pp_start, struct usb2_fs_isoc_schedule **pp_end, uint16_t isoc_time); uint8_t usb2_fs_isoc_schedule_alloc(struct usb2_fs_isoc_schedule *fss, uint8_t *pstart, uint16_t len); diff --git a/sys/dev/usb/usb_core.h b/sys/dev/usb/usb_core.h index 71bd1e091ce4..50051e3cf740 100644 --- a/sys/dev/usb/usb_core.h +++ b/sys/dev/usb/usb_core.h @@ -114,7 +114,7 @@ /* * The following macro defines if USB transaction translator support - * shall be compiled for the USB HUB and USB controller drivers. + * shall be supported for the USB HUB and USB controller drivers. */ #ifndef USB_HAVE_TT_SUPPORT #define USB_HAVE_TT_SUPPORT 1 @@ -122,12 +122,20 @@ /* * The following macro defines if the USB power daemon shall - * be compiled for the USB core. + * be supported in the USB core. */ #ifndef USB_HAVE_POWERD #define USB_HAVE_POWERD 1 #endif +/* + * The following macro defines if the USB autoinstall detection shall + * be supported in the USB core. + */ +#ifndef USB_HAVE_MSCTEST +#define USB_HAVE_MSCTEST 1 +#endif + #ifndef USB_TD_GET_PROC #define USB_TD_GET_PROC(td) (td)->td_proc #endif diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index f497b12bc3d4..8d4e573fad06 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -305,16 +305,16 @@ usb2_init_pipe(struct usb2_device *udev, uint8_t iface_index, (methods->pipe_init) (udev, edesc, pipe); - /* check for invalid pipe */ - if (pipe->methods == NULL) - return; - /* initialise USB pipe structure */ pipe->edesc = edesc; pipe->iface_index = iface_index; TAILQ_INIT(&pipe->pipe_q.head); pipe->pipe_q.command = &usb2_pipe_start; + /* the pipe is not supported by the hardware */ + if (pipe->methods == NULL) + return; + /* clear stall, if any */ if (methods->clear_stall != NULL) { USB_BUS_LOCK(udev->bus); diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index d12cfeb513c9..9b37d4c85b2a 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -62,10 +62,12 @@ SYSCTL_INT(_hw_usb2_uhub, OID_AUTO, debug, CTLFLAG_RW, &uhub_debug, 0, "Debug level"); #endif +#if USB_HAVE_POWERD static int usb2_power_timeout = 30; /* seconds */ SYSCTL_INT(_hw_usb2, OID_AUTO, power_timeout, CTLFLAG_RW, &usb2_power_timeout, 0, "USB power timeout"); +#endif struct uhub_current_state { uint16_t port_change; @@ -123,23 +125,24 @@ static const struct usb2_config uhub_config[UHUB_N_TRANSFER] = { */ static devclass_t uhub_devclass; -static driver_t uhub_driver = -{ +static device_method_t uhub_methods[] = { + DEVMETHOD(device_probe, uhub_probe), + DEVMETHOD(device_attach, uhub_attach), + DEVMETHOD(device_detach, uhub_detach), + + DEVMETHOD(device_suspend, uhub_suspend), + DEVMETHOD(device_resume, uhub_resume), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + + DEVMETHOD(bus_child_location_str, uhub_child_location_string), + DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string), + DEVMETHOD(bus_driver_added, uhub_driver_added), + {0, 0} +}; + +static driver_t uhub_driver = { .name = "uhub", - .methods = (device_method_t[]){ - DEVMETHOD(device_probe, uhub_probe), - DEVMETHOD(device_attach, uhub_attach), - DEVMETHOD(device_detach, uhub_detach), - - DEVMETHOD(device_suspend, uhub_suspend), - DEVMETHOD(device_resume, uhub_resume), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - DEVMETHOD(bus_child_location_str, uhub_child_location_string), - DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string), - DEVMETHOD(bus_driver_added, uhub_driver_added), - {0, 0} - }, + .methods = uhub_methods, .size = sizeof(struct uhub_softc) }; @@ -500,6 +503,21 @@ uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno) return (err); } +/*------------------------------------------------------------------------* + * uhub_root_interrupt + * + * This function is called when a Root HUB interrupt has + * happened. "ptr" and "len" makes up the Root HUB interrupt + * packet. This function is called having the "bus_mtx" locked. + *------------------------------------------------------------------------*/ +void +uhub_root_intr(struct usb2_bus *bus, const uint8_t *ptr, uint8_t len) +{ + USB_BUS_LOCK_ASSERT(bus, MA_OWNED); + + usb2_needs_explore(bus, 0); +} + /*------------------------------------------------------------------------* * uhub_explore * @@ -731,8 +749,14 @@ uhub_attach(device_t dev) /* set up interrupt pipe */ iface_index = 0; - err = usb2_transfer_setup(udev, &iface_index, sc->sc_xfer, - uhub_config, UHUB_N_TRANSFER, sc, &Giant); + if (udev->parent_hub == NULL) { + /* root HUB is special */ + err = 0; + } else { + /* normal HUB */ + err = usb2_transfer_setup(udev, &iface_index, sc->sc_xfer, + uhub_config, UHUB_N_TRANSFER, sc, &Giant); + } if (err) { DPRINTFN(0, "cannot setup interrupt transfer, " "errstr=%s!\n", usb2_errstr(err)); @@ -804,11 +828,13 @@ uhub_attach(device_t dev) "removable, %s powered\n", nports, (nports != 1) ? "s" : "", removable, udev->flags.self_powered ? "self" : "bus"); - /* start the interrupt endpoint */ + /* Start the interrupt endpoint, if any */ - USB_XFER_LOCK(sc->sc_xfer[0]); - usb2_transfer_start(sc->sc_xfer[0]); - USB_XFER_UNLOCK(sc->sc_xfer[0]); + if (sc->sc_xfer[0] != NULL) { + USB_XFER_LOCK(sc->sc_xfer[0]); + usb2_transfer_start(sc->sc_xfer[0]); + USB_XFER_UNLOCK(sc->sc_xfer[0]); + } /* Enable automatic power save on all USB HUBs */ @@ -1359,13 +1385,25 @@ usb2_bus_port_set_device(struct usb2_bus *bus, struct usb2_port *up, void usb2_needs_explore(struct usb2_bus *bus, uint8_t do_probe) { + uint8_t do_unlock; + DPRINTF("\n"); if (bus == NULL) { DPRINTF("No bus pointer!\n"); return; } - USB_BUS_LOCK(bus); + if ((bus->devices == NULL) || + (bus->devices[USB_ROOT_HUB_ADDR] == NULL)) { + DPRINTF("No root HUB\n"); + return; + } + if (mtx_owned(&bus->bus_mtx)) { + do_unlock = 0; + } else { + USB_BUS_LOCK(bus); + do_unlock = 1; + } if (do_probe) { bus->do_probe = 1; } @@ -1373,7 +1411,9 @@ usb2_needs_explore(struct usb2_bus *bus, uint8_t do_probe) &bus->explore_msg[0], &bus->explore_msg[1])) { /* ignore */ } - USB_BUS_UNLOCK(bus); + if (do_unlock) { + USB_BUS_UNLOCK(bus); + } } /*------------------------------------------------------------------------* diff --git a/sys/dev/usb/usb_hub.h b/sys/dev/usb/usb_hub.h index 62ab0d733840..833b8ba1c1f6 100644 --- a/sys/dev/usb/usb_hub.h +++ b/sys/dev/usb/usb_hub.h @@ -78,5 +78,6 @@ void usb2_needs_explore(struct usb2_bus *bus, uint8_t do_probe); void usb2_needs_explore_all(void); void usb2_bus_power_update(struct usb2_bus *bus); void usb2_bus_powerd(struct usb2_bus *bus); +void uhub_root_intr(struct usb2_bus *, const uint8_t *, uint8_t); #endif /* _USB2_HUB_H_ */ diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c index 05b8c90553fa..be92c04ddcbf 100644 --- a/sys/dev/usb/usb_request.c +++ b/sys/dev/usb/usb_request.c @@ -262,9 +262,9 @@ usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx, * Set "actlen" to a known value in case the caller does not * check the return value: */ - if (actlen) { + if (actlen) *actlen = 0; - } + #if (USB_HAVE_USER_IO == 0) if (flags & USB_USER_DATA_PTR) return (USB_ERR_INVAL); @@ -273,14 +273,13 @@ usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx, DPRINTF("USB device mode\n"); (usb2_temp_get_desc_p) (udev, req, &desc, &temp); if (length > temp) { - if (!(flags & USB_SHORT_XFER_OK)) { + if (!(flags & USB_SHORT_XFER_OK)) return (USB_ERR_SHORT_XFER); - } length = temp; } - if (actlen) { + if (actlen) *actlen = length; - } + if (length > 0) { #if USB_HAVE_USER_IO if (flags & USB_USER_DATA_PTR) { @@ -306,6 +305,59 @@ usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx, sx_xlock(udev->default_sx); + if (udev->parent_hub == NULL) { + struct usb2_sw_transfer *std = &udev->bus->roothub_req; + + /* root HUB code - stripped down */ + + if (req->bmRequestType & UT_READ) { + std->ptr = NULL; + } else { + if (length != 0) { + DPRINTFN(1, "Root HUB does not support " + "writing data!\n"); + err = USB_ERR_INVAL; + goto done; + } + } + /* setup request */ + std->req = *req; + std->err = 0; + std->len = 0; + + USB_BUS_LOCK(udev->bus); + (udev->bus->methods->roothub_exec) (udev->bus); + USB_BUS_UNLOCK(udev->bus); + + err = std->err; + if (err) + goto done; + + if (length > std->len) { + length = std->len; + if (!(flags & USB_SHORT_XFER_OK)) { + err = USB_ERR_SHORT_XFER; + goto done; + } + } + + if (actlen) + *actlen = length; + + if (length > 0) { +#if USB_HAVE_USER_IO + if (flags & USB_USER_DATA_PTR) { + if (copyout(std->ptr, data, length)) { + err = USB_ERR_INVAL; + goto done; + } + } else +#endif + bcopy(std->ptr, data, length); + } + goto done; + } + /* * Setup a new USB transfer or use the existing one, if any: */ diff --git a/sys/dev/usb/usb_sw_transfer.c b/sys/dev/usb/usb_sw_transfer.c index 9fcb69a65bd3..03f14a2c584f 100644 --- a/sys/dev/usb/usb_sw_transfer.c +++ b/sys/dev/usb/usb_sw_transfer.c @@ -24,146 +24,3 @@ * SUCH DAMAGE. */ -#include -#include -#include - -#define USB_DEBUG_VAR usb2_debug - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/*------------------------------------------------------------------------* - * usb2_sw_transfer - factored out code - * - * This function is basically used for the Virtual Root HUB, and can - * emulate control, bulk and interrupt endpoints. Data is exchanged - * using the "std->ptr" and "std->len" fields, that allows kernel - * virtual memory to be transferred. All state is kept in the - * structure pointed to by the "std" argument passed to this - * function. The "func" argument points to a function that is called - * back in the various states, so that the application using this - * function can get a chance to select the outcome. The "func" - * function is allowed to sleep, exiting all mutexes. If this function - * will sleep the "enter" and "start" methods must be marked - * non-cancelable, hence there is no extra cancelled checking in this - * function. - *------------------------------------------------------------------------*/ -void -usb2_sw_transfer(struct usb2_sw_transfer *std, - usb2_sw_transfer_func_t *func) -{ - struct usb2_xfer *xfer; - usb2_frlength_t len; - uint8_t shortpkt = 0; - - xfer = std->xfer; - if (xfer == NULL) { - /* the transfer is gone */ - DPRINTF("xfer gone\n"); - return; - } - USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED); - - std->xfer = NULL; - - /* check for control transfer */ - if (xfer->flags_int.control_xfr) { - /* check if we are transferring the SETUP packet */ - if (xfer->flags_int.control_hdr) { - - /* copy out the USB request */ - - if (xfer->frlengths[0] == sizeof(std->req)) { - usb2_copy_out(xfer->frbuffers, 0, - &std->req, sizeof(std->req)); - } else { - std->err = USB_ERR_INVAL; - goto done; - } - - xfer->aframes = 1; - - std->err = 0; - std->state = USB_SW_TR_SETUP; - - (func) (xfer, std); - - if (std->err) { - goto done; - } - } else { - /* skip the first frame in this case */ - xfer->aframes = 1; - } - } - std->err = 0; - std->state = USB_SW_TR_PRE_DATA; - - (func) (xfer, std); - - if (std->err) { - goto done; - } - /* Transfer data. Iterate accross all frames. */ - while (xfer->aframes != xfer->nframes) { - - len = xfer->frlengths[xfer->aframes]; - - if (len > std->len) { - len = std->len; - shortpkt = 1; - } - if (len > 0) { - if ((xfer->endpoint & (UE_DIR_IN | UE_DIR_OUT)) == UE_DIR_IN) { - usb2_copy_in(xfer->frbuffers + xfer->aframes, 0, - std->ptr, len); - } else { - usb2_copy_out(xfer->frbuffers + xfer->aframes, 0, - std->ptr, len); - } - } - std->ptr += len; - std->len -= len; - xfer->frlengths[xfer->aframes] = len; - xfer->aframes++; - - if (shortpkt) { - break; - } - } - - std->err = 0; - std->state = USB_SW_TR_POST_DATA; - - (func) (xfer, std); - - if (std->err) { - goto done; - } - /* check if the control transfer is complete */ - if (xfer->flags_int.control_xfr && - !xfer->flags_int.control_act) { - - std->err = 0; - std->state = USB_SW_TR_STATUS; - - (func) (xfer, std); - - if (std->err) { - goto done; - } - } -done: - DPRINTF("done err=%s\n", usb2_errstr(std->err)); - std->state = USB_SW_TR_PRE_CALLBACK; - (func) (xfer, std); -} diff --git a/sys/dev/usb/usb_sw_transfer.h b/sys/dev/usb/usb_sw_transfer.h index d2da0eb54c92..29192a4d8f53 100644 --- a/sys/dev/usb/usb_sw_transfer.h +++ b/sys/dev/usb/usb_sw_transfer.h @@ -27,36 +27,4 @@ #ifndef _USB2_SW_TRANSFER_H_ #define _USB2_SW_TRANSFER_H_ -/* Software transfer function state argument values */ - -enum { - USB_SW_TR_SETUP, - USB_SW_TR_STATUS, - USB_SW_TR_PRE_DATA, - USB_SW_TR_POST_DATA, - USB_SW_TR_PRE_CALLBACK, -}; - -struct usb2_sw_transfer; - -typedef void (usb2_sw_transfer_func_t)(struct usb2_xfer *, struct usb2_sw_transfer *); - -/* - * The following structure is used to keep the state of a standard - * root transfer. - */ -struct usb2_sw_transfer { - struct usb2_device_request req; - struct usb2_xfer *xfer; - uint8_t *ptr; - uint16_t len; - uint8_t state; - usb2_error_t err; -}; - -/* prototypes */ - -void usb2_sw_transfer(struct usb2_sw_transfer *std, - usb2_sw_transfer_func_t *func); - #endif /* _USB2_SW_TRANSFER_H_ */ diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index 10b0b9cf24a0..4ffc03f6c1ef 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -846,7 +846,7 @@ usb2_transfer_setup(struct usb2_device *udev, pipe = usb2_get_pipe(udev, ifaces[setup->if_index], setup); - if (!pipe) { + if ((pipe == NULL) || (pipe->methods == NULL)) { if (setup->flags.no_pipe_ok) continue; if ((setup->usb_mode != USB_MODE_MAX) && @@ -2547,6 +2547,9 @@ usb2_default_transfer_setup(struct usb2_device *udev) uint8_t no_resetup; uint8_t iface_index; + /* check for root HUB */ + if (udev->parent_hub == NULL) + return; repeat: xfer = udev->default_xfer[0];