From 5c428d35a61f7d877cba19d9e094bd519ae91997 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 29 May 2023 13:27:20 +0700 Subject: [PATCH] check status_change is not zero first --- src/host/hub.c | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/host/hub.c b/src/host/hub.c index 5b2db547d..0807c2023 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -327,51 +327,45 @@ 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) -{ +bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) xferred_bytes; // TODO can be more than 1 for hub with lots of ports (void) ep_addr; TU_ASSERT(result == XFER_RESULT_SUCCESS); hub_interface_t* p_hub = get_itf(dev_addr); - TU_LOG2(" Hub Status Change = 0x%02X\r\n", p_hub->status_change); + uint8_t const status_change = p_hub->status_change; + TU_LOG2(" Hub Status Change = 0x%02X\r\n", status_change); - // Hub bit 0 is for the hub device events - if (tu_bit_test(p_hub->status_change, 0)) - { - if (hub_port_get_status(dev_addr, 0, &p_hub->hub_status, hub_get_status_complete, 0) == false) - { + if ( status_change == 0 ) { + // The status change event was neither for the hub, nor for any of its ports. + // This shouldn't happen, but it does with some devices. + // Initiate the next interrupt poll here. + hub_edpt_status_xfer(dev_addr); + return true; + } + + if (tu_bit_test(status_change, 0)) { + // Hub bit 0 is for the hub device events + if (hub_port_get_status(dev_addr, 0, &p_hub->hub_status, hub_get_status_complete, 0) == false) { //Hub status control transfer failed, retry hub_edpt_status_xfer(dev_addr); } } - else - { + else { // Hub bits 1 to n are hub port events - for (uint8_t port=1; port <= p_hub->port_count; port++) - { - if ( tu_bit_test(p_hub->status_change, port) ) - { - if (hub_port_get_status(dev_addr, port, &p_hub->port_status, hub_port_get_status_complete, 0) == false) - { + for (uint8_t port=1; port <= p_hub->port_count; port++) { + if ( tu_bit_test(status_change, port) ) { + if (hub_port_get_status(dev_addr, port, &p_hub->port_status, hub_port_get_status_complete, 0) == false) { //Hub status control transfer failed, retry hub_edpt_status_xfer(dev_addr); } break; } } - - // The status change event was neither for the hub, nor for any of - // its ports. (For example `p_hub->status_change == 0`.) This - // shouldn't happen, but it does with some devices. Initiate the - // next interrupt poll here, because we've scheduled no other work - // whose completion can initiate it. - hub_edpt_status_xfer(dev_addr); } // NOTE: next status transfer is queued by usbh.c after handling this request - return true; }