summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2023-05-29 13:47:23 +0700
committerGitHub <[email protected]>2023-05-29 13:47:23 +0700
commitddc029ce54913fa898c5225a2e87f136a6b81060 (patch)
treef96f9c08e5aa8de6e5d151d276d7a8447f7a7d20 /src
parent069e1ef84f495d2cdd4e5b2fb056a882d2f07787 (diff)
parent20ef6c4ef7f7fa7130352ae0c0984692a9719b35 (diff)
Merge pull request #2016 from ipopov/master
Even when we get an empty "status change" interrupt from the hub, schedule another interrupt poll
Diffstat (limited to 'src')
-rw-r--r--src/host/hub.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/src/host/hub.c b/src/host/hub.c
index 85bf22b3e..182bd6ce8 100644
--- a/src/host/hub.c
+++ b/src/host/hub.c
@@ -327,34 +327,35 @@ 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.
+ return hub_edpt_status_xfer(dev_addr);
+ }
+
+ 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);
}
@@ -364,7 +365,6 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32
}
// NOTE: next status transfer is queued by usbh.c after handling this request
-
return true;
}