diff options
Diffstat (limited to 'src/host/hub.c')
| -rw-r--r-- | src/host/hub.c | 159 |
1 files changed, 98 insertions, 61 deletions
diff --git a/src/host/hub.c b/src/host/hub.c index 53eb1d521..9e546f6f7 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -54,7 +54,7 @@ static inline hub_interface_t* get_itf(uint8_t dev_addr) return &hub_data[dev_addr-1-CFG_TUH_DEVICE_MAX]; } -#if CFG_TUSB_DEBUG +#if CFG_TUSB_DEBUG >= 2 static char const* const _hub_feature_str[] = { [HUB_FEATURE_PORT_CONNECTION ] = "PORT_CONNECTION", @@ -77,7 +77,8 @@ static char const* const _hub_feature_str[] = //--------------------------------------------------------------------+ // HUB //--------------------------------------------------------------------+ -bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_complete_cb_t complete_cb) +bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { @@ -93,12 +94,23 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, .wLength = 0 }; + tuh_xfer_t xfer = + { + .daddr = hub_addr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data + }; + TU_LOG2("HUB Clear Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer(hub_addr, &request, NULL, complete_cb) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } -bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_complete_cb_t complete_cb) +bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { @@ -114,17 +126,23 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, t .wLength = 0 }; + tuh_xfer_t xfer = + { + .daddr = hub_addr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data + }; + TU_LOG2("HUB Set Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer(hub_addr, &request, NULL, complete_cb) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } -bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_control_complete_cb_t complete_cb) -{ - return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb); -} - -bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_complete_cb_t complete_cb) +bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { tusb_control_request_t const request = { @@ -140,8 +158,18 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_con .wLength = 4 }; + tuh_xfer_t xfer = + { + .daddr = hub_addr, + .ep_addr = 0, + .setup = &request, + .buffer = resp, + .complete_cb = complete_cb, + .user_data = user_data + }; + TU_LOG2("HUB Get Port Status: addr = %u port = %u\r\n", hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer( hub_addr, &request, resp, complete_cb) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -155,6 +183,8 @@ void hub_init(void) bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { + (void) rhport; + TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass && 0 == itf_desc->bInterfaceSubClass); @@ -171,7 +201,7 @@ bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); - TU_ASSERT(usbh_edpt_open(rhport, dev_addr, desc_ep)); + TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep)); hub_interface_t* p_hub = get_itf(dev_addr); @@ -189,7 +219,7 @@ void hub_close(uint8_t dev_addr) if (p_hub->ep_in) tu_memclr(p_hub, sizeof( hub_interface_t)); } -bool hub_status_pipe_queue(uint8_t dev_addr) +bool hub_edpt_status_xfer(uint8_t dev_addr) { hub_interface_t* hub_itf = get_itf(dev_addr); return usbh_edpt_xfer(dev_addr, hub_itf->ep_in, &hub_itf->status_change, 1); @@ -200,8 +230,8 @@ bool hub_status_pipe_queue(uint8_t dev_addr) // Set Configure //--------------------------------------------------------------------+ -static bool config_set_port_power (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool config_port_power_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static void config_set_port_power (tuh_xfer_t* xfer); +static void config_port_power_complete (tuh_xfer_t* xfer); bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -223,17 +253,27 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) .wLength = sizeof(descriptor_hub_desc_t) }; - TU_ASSERT( tuh_control_xfer(dev_addr, &request, _hub_buffer, config_set_port_power) ); + tuh_xfer_t xfer = + { + .daddr = dev_addr, + .ep_addr = 0, + .setup = &request, + .buffer = _hub_buffer, + .complete_cb = config_set_port_power, + .user_data = 0 + }; + + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } -static bool config_set_port_power (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static void config_set_port_power (tuh_xfer_t* xfer) { - (void) request; - TU_ASSERT(XFER_RESULT_SUCCESS == result); + TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); - hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); // only use number of ports in hub descriptor descriptor_hub_desc_t const* desc_hub = (descriptor_hub_desc_t const*) _hub_buffer; @@ -243,38 +283,38 @@ static bool config_set_port_power (uint8_t dev_addr, tusb_control_request_t cons // Set Port Power to be able to detect connection, starting with port 1 uint8_t const hub_port = 1; - return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete); + hub_port_set_feature(daddr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } -static bool config_port_power_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static void config_port_power_complete (tuh_xfer_t* xfer) { - TU_ASSERT(XFER_RESULT_SUCCESS == result); - hub_interface_t* p_hub = get_itf(dev_addr); + TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); + + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); - if (request->wIndex == p_hub->port_count) + if (xfer->setup->wIndex == p_hub->port_count) { // All ports are power -> queue notification status endpoint and // complete the SET CONFIGURATION - TU_ASSERT( usbh_edpt_xfer(dev_addr, p_hub->ep_in, &p_hub->status_change, 1) ); + TU_ASSERT( usbh_edpt_xfer(daddr, p_hub->ep_in, &p_hub->status_change, 1), ); - usbh_driver_set_config_complete(dev_addr, p_hub->itf_num); + usbh_driver_set_config_complete(daddr, p_hub->itf_num); }else { // power next port - uint8_t const hub_port = (uint8_t) (request->wIndex + 1); - return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete); + uint8_t const hub_port = (uint8_t) (xfer->setup->wIndex + 1); + hub_port_set_feature(daddr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } - - return true; } //--------------------------------------------------------------------+ // Connection Changes //--------------------------------------------------------------------+ -static bool connection_get_status_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool connection_clear_conn_change_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -static bool connection_port_reset_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static void connection_get_status_complete (tuh_xfer_t* xfer); +static void connection_clear_conn_change_complete (tuh_xfer_t* xfer); +static void connection_port_reset_complete (tuh_xfer_t* xfer); // callback as response of interrupt endpoint polling bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -292,7 +332,7 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 { if ( tu_bit_test(p_hub->status_change, port) ) { - hub_port_get_status(dev_addr, port, &p_hub->port_status, connection_get_status_complete); + hub_port_get_status(dev_addr, port, &p_hub->port_status, connection_get_status_complete, 0); break; } } @@ -302,12 +342,13 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 return true; } -static bool connection_get_status_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static void connection_get_status_complete (tuh_xfer_t* xfer) { - TU_ASSERT(result == XFER_RESULT_SUCCESS); + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); - hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) request->wIndex; + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); + uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); // Connection change if (p_hub->port_status.change.connection) @@ -316,7 +357,7 @@ static bool connection_get_status_complete (uint8_t dev_addr, tusb_control_reque //TU_VERIFY(port_status.status_current.port_power && port_status.status_current.port_enable, ); // Acknowledge Port Connection Change - hub_port_clear_feature(dev_addr, port_num, HUB_FEATURE_PORT_CONNECTION_CHANGE, connection_clear_conn_change_complete); + hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_CONNECTION_CHANGE, connection_clear_conn_change_complete, 0); }else { // Other changes are: Enable, Suspend, Over Current, Reset, L1 state @@ -324,65 +365,61 @@ static bool connection_get_status_complete (uint8_t dev_addr, tusb_control_reque // prepare for next hub status // TODO continue with status_change, or maybe we can do it again with status - hub_status_pipe_queue(dev_addr); + hub_edpt_status_xfer(daddr); } - - return true; } -static bool connection_clear_conn_change_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static void connection_clear_conn_change_complete (tuh_xfer_t* xfer) { - TU_ASSERT(result == XFER_RESULT_SUCCESS); + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); - hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) request->wIndex; + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); + uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); if ( p_hub->port_status.status.connection ) { // Reset port if attach event - hub_port_reset(dev_addr, port_num, connection_port_reset_complete); + hub_port_reset(daddr, port_num, connection_port_reset_complete, 0); }else { // submit detach event hcd_event_t event = { - .rhport = usbh_get_rhport(dev_addr), + .rhport = usbh_get_rhport(daddr), .event_id = HCD_EVENT_DEVICE_REMOVE, .connection = { - .hub_addr = dev_addr, + .hub_addr = daddr, .hub_port = port_num } }; hcd_event_handler(&event, false); } - - return true; } -static bool connection_port_reset_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +static void connection_port_reset_complete (tuh_xfer_t* xfer) { - TU_ASSERT(result == XFER_RESULT_SUCCESS); + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); - // hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) request->wIndex; + uint8_t const daddr = xfer->daddr; + // hub_interface_t* p_hub = get_itf(daddr); + uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); // submit attach event hcd_event_t event = { - .rhport = usbh_get_rhport(dev_addr), + .rhport = usbh_get_rhport(daddr), .event_id = HCD_EVENT_DEVICE_ATTACH, .connection = { - .hub_addr = dev_addr, + .hub_addr = daddr, .hub_port = port_num } }; hcd_event_handler(&event, false); - - return true; } #endif |
