mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
hub: always power on
This commit is contained in:
@@ -9,8 +9,7 @@
|
||||
#define USB_HUB_REQUEST_CLEAR_FEATURE 1
|
||||
#define USB_HUB_REQUEST_SET_FEATURE 3
|
||||
|
||||
#define USB_HUB_POWER_SWITCHING_MODE_MASK 0x0003
|
||||
#define USB_HUB_POWER_SWITCHING_MODE_NONE (1 << 1)
|
||||
#define USB_HUB_MIN_POWER_GOOD_US 100000
|
||||
|
||||
typedef struct {
|
||||
uint64_t in_buffer;
|
||||
@@ -281,7 +280,9 @@ static void power_on_callback(usb_device_t *dev, void *ctx, usb_status_t status,
|
||||
if (++data->ports_powered == data->usb_hub->port_count) {
|
||||
usb_hub_desc_t *desc = (usb_hub_desc_t *)dev->hub_desc;
|
||||
size_t power_good_us = (size_t)desc->bPwrOn2PwrGood * 2000;
|
||||
if (power_good_us)
|
||||
// External hubs need at least 100 ms for port power to stabilize.
|
||||
if (power_good_us < USB_HUB_MIN_POWER_GOOD_US)
|
||||
power_good_us = USB_HUB_MIN_POWER_GOOD_US;
|
||||
sched_sleep_us(power_good_us);
|
||||
initial_status_scan(dev, data);
|
||||
} else if (power_port(dev, data->ports_powered, data)) {
|
||||
@@ -293,13 +294,6 @@ static int power_port(usb_device_t *dev, int port, hub_driver_data_t *data) {
|
||||
return hub_port_control_xfer(data->usb_hub->device, USB_HUB_REQUEST_SET_FEATURE, USB_HUB_FEATURE_PORT_POWER, port, NULL, 0, power_on_callback, data);
|
||||
}
|
||||
|
||||
static bool hub_advertises_port_power_switching(usb_device_t *dev) {
|
||||
usb_hub_desc_t *desc = (usb_hub_desc_t *)dev->hub_desc;
|
||||
uint16_t power_mode = desc->wHubCharacteristics & USB_HUB_POWER_SWITCHING_MODE_MASK;
|
||||
|
||||
return (power_mode & USB_HUB_POWER_SWITCHING_MODE_NONE) == 0;
|
||||
}
|
||||
|
||||
static void get_hub_name(usb_device_t *dev, char *buffer, size_t buffer_size) {
|
||||
uint8_t major = (dev->desc.bcdUSB >> 8) & 0x0f;
|
||||
uint8_t minor_tens = (dev->desc.bcdUSB >> 4) & 0x0f;
|
||||
@@ -386,12 +380,9 @@ static int hub_attach(usb_device_t *dev, usb_interface_t *interface) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (hub_advertises_port_power_switching(dev)) {
|
||||
// Some hubs emulate power switching but still require PORT_POWER requests.
|
||||
if (power_port(dev, 0, hub_driver_data))
|
||||
printf("hub: failed to power first port\n");
|
||||
} else {
|
||||
initial_status_scan(dev, hub_driver_data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user