Browse Source

refractor hub

hathach 12 years ago
parent
commit
14ebd6c4d9
3 changed files with 26 additions and 47 deletions
  1. 1 1
      tinyusb/host/ehci/ehci.c
  2. 24 45
      tinyusb/host/usbh.c
  3. 1 1
      tinyusb/host/usbh_hcd.h

+ 1 - 1
tinyusb/host/ehci/ehci.c

@@ -567,7 +567,7 @@ static void port_connect_status_change_isr(uint8_t hostid)
     usbh_device_plugged_isr(hostid, 0, 0);
   }else // device unplugged
   {
-    usbh_device_unplugged_isr(hostid);
+    usbh_hcd_rhport_unplugged_isr(hostid);
     regs->usb_cmd_bit.advacne_async = 1; // Async doorbell check EHCI 4.8.2 for operational details
   }
 }

+ 24 - 45
tinyusb/host/usbh.c

@@ -279,42 +279,48 @@ void usbh_device_plugged_isr(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port)
                   &(usbh_enumerate_t){ .core_id = hostid, .hub_addr = hub_addr, .hub_port = hub_port} );
 }
 
-
-void usbh_device_unplugged_isr(uint8_t hostid)
+// a device unplugged on hostid, hub_addr, hub_port
+// return true if found and unmounted device, false if cannot find
+bool usbh_device_unplugged(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port)
 {
   //------------- find the device address that is unplugged -------------//
   uint8_t dev_addr = 0;
   while ( dev_addr <= TUSB_CFG_HOST_DEVICE_MAX &&
-          !(usbh_devices[dev_addr].core_id  == hostid &&
-            usbh_devices[dev_addr].hub_addr == 0 &&
-            usbh_devices[dev_addr].hub_port == 0 &&
+          !(usbh_devices[dev_addr].core_id  == hostid   &&
+            usbh_devices[dev_addr].hub_addr == hub_addr &&
+            usbh_devices[dev_addr].hub_port == hub_port &&
             usbh_devices[dev_addr].state    != TUSB_DEVICE_STATE_UNPLUG ) )
   {
     dev_addr++;
   }
 
   if (dev_addr > TUSB_CFG_HOST_DEVICE_MAX) // unplug unmounted device
-    return;
+  {
+    return false;
+  }
 
-  if (dev_addr > 0) // device can still be unplugged when not set new address
+  // if device unplugged is not a hub TODO handle hub unplugged
+  for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++)
   {
-    // if device unplugged is not a hub TODO handle hub unplugged
-    for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++)
+    if ((usbh_devices[dev_addr].flag_supported_class & BIT_(class_index)) &&
+        usbh_class_drivers[class_index].close)
     {
-      if ((usbh_devices[dev_addr].flag_supported_class & BIT_(class_index)) &&
-          usbh_class_drivers[class_index].close)
-      {
-        usbh_class_drivers[class_index].close(dev_addr);
-      }
+      usbh_class_drivers[class_index].close(dev_addr);
     }
   }
-
   usbh_pipe_control_close(dev_addr);
 
   // set to REMOVING to allow HCD to clean up its cached data for this device
   // HCD must set this device's state to TUSB_DEVICE_STATE_UNPLUG when done
   usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_REMOVING;
   usbh_devices[dev_addr].flag_supported_class = 0;
+
+  return true;
+}
+
+void usbh_hcd_rhport_unplugged_isr(uint8_t hostid)
+{
+  (void) usbh_device_unplugged(hostid, 0, 0);
 }
 
 //--------------------------------------------------------------------+
@@ -351,6 +357,7 @@ tusb_error_t enumeration_body_subtask(void)
   usbh_devices[0].core_id  = enum_entry.core_id; // TODO refractor integrate to device_pool
   usbh_devices[0].hub_addr = enum_entry.hub_addr;
   usbh_devices[0].hub_port = enum_entry.hub_port;
+  usbh_devices[0].state    = TUSB_DEVICE_STATE_UNPLUG;
 
   if ( usbh_devices[0].hub_addr != 0) // connected/disconnected via hub
   {
@@ -371,39 +378,11 @@ tusb_error_t enumeration_body_subtask(void)
 
     if ( ! ((hub_port_status_response_t *) enum_data_buffer)->status_current.connect_status )
     { // Device is disconnected via Hub
-      uint8_t dev_addr = 1;
-      while ( dev_addr <= TUSB_CFG_HOST_DEVICE_MAX &&
-              !(usbh_devices[dev_addr].core_id  == usbh_devices[0].core_id &&
-                usbh_devices[dev_addr].hub_addr == usbh_devices[0].hub_addr &&
-                usbh_devices[dev_addr].hub_port == usbh_devices[0].hub_port &&
-                usbh_devices[dev_addr].state    != TUSB_DEVICE_STATE_UNPLUG ) )
+      if ( usbh_device_unplugged(usbh_devices[0].core_id, usbh_devices[0].hub_addr, usbh_devices[0].hub_port) )
       {
-        dev_addr++;
+        hcd_hub_advance_asyn(usbh_devices[0].core_id); // TODO hack
       }
 
-      if (dev_addr > TUSB_CFG_HOST_DEVICE_MAX) // unplug unmounted device
-      {
-        SUBTASK_EXIT(TUSB_ERROR_NONE);
-      }
-
-      // if device unplugged is not a hub TODO handle hub unplugged
-      for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++)
-      {
-        if ((usbh_devices[dev_addr].flag_supported_class & BIT_(class_index)) &&
-            usbh_class_drivers[class_index].close)
-        {
-          usbh_class_drivers[class_index].close(dev_addr);
-        }
-      }
-      usbh_pipe_control_close(dev_addr);
-
-      // set to REMOVING to allow HCD to clean up its cached data for this device
-      // HCD must set this device's state to TUSB_DEVICE_STATE_UNPLUG when done
-      usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_REMOVING;
-      usbh_devices[dev_addr].flag_supported_class = 0;
-
-      hcd_hub_advance_asyn(usbh_devices[0].core_id); // TODO hack
-
       (void) hub_status_pipe_queue( usbh_devices[0].hub_addr ); // done with hub, waiting for next data on status pipe
       SUBTASK_EXIT(TUSB_ERROR_NONE); // restart task
     }

+ 1 - 1
tinyusb/host/usbh_hcd.h

@@ -116,7 +116,7 @@ extern usbh_device_info_t usbh_devices[TUSB_CFG_HOST_DEVICE_MAX+1]; // including
 //--------------------------------------------------------------------+
 void usbh_xfer_isr(pipe_handle_t pipe_hdl, uint8_t class_code, tusb_event_t event, uint32_t xferred_bytes);
 void usbh_device_plugged_isr(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port);
-void usbh_device_unplugged_isr(uint8_t hostid);
+void usbh_hcd_rhport_unplugged_isr(uint8_t hostid);
 
 #ifdef __cplusplus
  }