refractor hub

This commit is contained in:
hathach 2013-10-01 11:29:25 +07:00
parent 93821c55ce
commit 14ebd6c4d9
3 changed files with 28 additions and 49 deletions

View File

@ -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
}
}

View File

@ -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;
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 ((usbh_devices[dev_addr].flag_supported_class & BIT_(class_index)) &&
usbh_class_drivers[class_index].close)
{
usbh_class_drivers[class_index].close(dev_addr);
}
}
return false;
}
// 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;
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
}

View File

@ -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
}