mirror of
https://github.com/memtest86plus/memtest86plus
synced 2025-03-12 17:02:58 +03:00
Fix EHCI and XHCI drivers to handle USB1 hubs (issue #156)
This commit is contained in:
parent
18f12116c0
commit
f265d1f1c5
@ -405,10 +405,9 @@ static bool assign_address(const usb_hcd_t *hcd, const usb_hub_t *hub, int port_
|
||||
usb_speed_t device_speed, int device_id, usb_ep_t *ep0)
|
||||
{
|
||||
// Store the extra information needed by build_ehci_qhd().
|
||||
ep0->driver_data = port_num << 8;
|
||||
if (hub->level > 0) {
|
||||
ep0->driver_data |= hub->ep0->device_id;
|
||||
}
|
||||
usb_parent_t hs_parent = usb_hs_parent(hub, port_num, device_speed);
|
||||
ep0->driver_data = hs_parent.port_num << 8 | hs_parent.device_id;
|
||||
|
||||
if (!assign_usb_address(hcd, hub, port_num, device_speed, device_id, ep0)) {
|
||||
return false;
|
||||
}
|
||||
@ -558,9 +557,8 @@ bool ehci_init(int bus, int dev, int func, uintptr_t base_addr, usb_hcd_t *hcd)
|
||||
|
||||
// Construct a hub descriptor for the root hub.
|
||||
usb_hub_t root_hub;
|
||||
memset(&root_hub, 0, sizeof(root_hub));
|
||||
root_hub.ep0 = NULL;
|
||||
root_hub.level = 0;
|
||||
root_hub.route = 0;
|
||||
root_hub.num_ports = num_ehci_ports(hcs_params);
|
||||
root_hub.power_up_delay = 10; // 20ms
|
||||
|
||||
|
@ -498,9 +498,8 @@ bool ohci_init(uintptr_t base_addr, usb_hcd_t *hcd)
|
||||
|
||||
// Construct a hub descriptor for the root hub.
|
||||
usb_hub_t root_hub;
|
||||
memset(&root_hub, 0, sizeof(root_hub));
|
||||
root_hub.ep0 = NULL;
|
||||
root_hub.level = 0;
|
||||
root_hub.route = 0;
|
||||
root_hub.num_ports = rh_descriptor_a & 0xf;
|
||||
root_hub.power_up_delay = rh_descriptor_a >> 24;
|
||||
|
||||
|
@ -474,11 +474,9 @@ bool uhci_init(int bus, int dev, int func, uint16_t io_base, usb_hcd_t *hcd)
|
||||
|
||||
// Construct a hub descriptor for the root hub.
|
||||
usb_hub_t root_hub;
|
||||
memset(&root_hub, 0, sizeof(root_hub));
|
||||
root_hub.ep0 = NULL;
|
||||
root_hub.level = 0;
|
||||
root_hub.route = 0;
|
||||
root_hub.num_ports = MAX_UHCI_PORTS;
|
||||
root_hub.power_up_delay = 0;
|
||||
|
||||
usleep(100*MILLISEC); // USB maximum device attach time
|
||||
|
||||
|
@ -136,6 +136,8 @@ static bool build_hub_info(const usb_hcd_t *hcd, const usb_hub_t *parent, int po
|
||||
hub->num_ports = hub_desc.num_ports;
|
||||
hub->tt_think_time = hub_desc.characteristics & 0x0060 >> 5;
|
||||
hub->power_up_delay = hub_desc.power_up_delay;
|
||||
hub->hs_parent = usb_hs_parent(parent, port_num, ep0->device_speed);
|
||||
|
||||
usb_endpoint_desc_t *ep1_desc = find_hub_endpoint_descriptor(hcd->ws->data_buffer, hcd->ws->data_length);
|
||||
if (ep1_desc == NULL) {
|
||||
return false;
|
||||
@ -456,6 +458,20 @@ uint32_t usb_route(const usb_hub_t *hub, int port_num)
|
||||
return hub->route | (port_num << (4 * (hub->level - 1)));
|
||||
}
|
||||
|
||||
usb_parent_t usb_hs_parent(const usb_hub_t *hub, int port_num, usb_speed_t device_speed)
|
||||
{
|
||||
usb_parent_t hs_parent = { 0, 0 };
|
||||
if (device_speed < USB_SPEED_HIGH && hub->level > 0) {
|
||||
if (hub->ep0->device_speed < USB_SPEED_HIGH) {
|
||||
hs_parent = hub->hs_parent;
|
||||
} else {
|
||||
hs_parent.device_id = hub->ep0->device_id;
|
||||
hs_parent.port_num = port_num;
|
||||
}
|
||||
}
|
||||
return hs_parent;
|
||||
}
|
||||
|
||||
bool wait_until_clr(const volatile uint32_t *reg, uint32_t bit_mask, int max_time)
|
||||
{
|
||||
int timer = max_time >> 3;
|
||||
|
@ -62,6 +62,14 @@ typedef struct __attribute__ ((packed)) {
|
||||
uint8_t reserved;
|
||||
} usb_ep_t;
|
||||
|
||||
/**
|
||||
* A USB parent device descriptor (used internally by the various HCI drivers).
|
||||
*/
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
uint8_t device_id;
|
||||
uint8_t port_num;
|
||||
} usb_parent_t;
|
||||
|
||||
/**
|
||||
* A USB hub descriptor (used internally by the various HCI drivers).
|
||||
*/
|
||||
@ -72,6 +80,8 @@ typedef struct __attribute__ ((packed)) {
|
||||
uint8_t num_ports;
|
||||
uint8_t tt_think_time;
|
||||
uint8_t power_up_delay;
|
||||
usb_parent_t hs_parent;
|
||||
uint16_t reserved;
|
||||
} usb_hub_t;
|
||||
|
||||
/**
|
||||
@ -210,6 +220,17 @@ static inline bool valid_usb_config_descriptor(const uint8_t *buffer)
|
||||
*/
|
||||
uint32_t usb_route(const usb_hub_t *hub, int port_num);
|
||||
|
||||
/**
|
||||
* Returns the high-speed parent device ID and port number (as defined by
|
||||
* the EHCI and XHCI specifications) for the device attached to the hub
|
||||
* port specified by hub and port_num. Returns zero values if the device
|
||||
* is operating at high speed (as specified by device_speed) or is directly
|
||||
* attached to a root hub port.
|
||||
*
|
||||
* Used internally by the various HCI drivers.
|
||||
*/
|
||||
usb_parent_t usb_hs_parent(const usb_hub_t *hub, int port_num, usb_speed_t device_speed);
|
||||
|
||||
/**
|
||||
* Waits for all the bits set in bit_mask to be cleared in the register pointed
|
||||
* to by reg or for max_time microseconds to elapse.
|
||||
|
@ -729,10 +729,9 @@ static bool assign_address(const usb_hcd_t *hcd, const usb_hub_t *hub, int port_
|
||||
uint32_t route = usb_route(hub, port_num);
|
||||
slot_context->params1 |= route & 0xfffff;
|
||||
slot_context->root_hub_port_num = route >> 24;
|
||||
if (device_speed < USB_SPEED_HIGH && hub->ep0->device_speed == USB_SPEED_HIGH) {
|
||||
slot_context->parent_slot_id = hub->ep0->device_id;
|
||||
slot_context->parent_port_num = port_num;
|
||||
}
|
||||
usb_parent_t hs_parent = usb_hs_parent(hub, port_num, device_speed);
|
||||
slot_context->parent_slot_id = hs_parent.device_id;
|
||||
slot_context->parent_port_num = hs_parent.port_num;
|
||||
} else {
|
||||
slot_context->root_hub_port_num = port_num;
|
||||
}
|
||||
@ -818,7 +817,7 @@ static bool configure_interrupt_endpoint(workspace_t *ws, const usb_ep_t *ep, in
|
||||
xhci_slot_context_t *slot_context = (xhci_slot_context_t *)(ws->input_context_addr + ws->context_size);
|
||||
slot_context->params1 = ep_id << 27 | hub_flag << 26 | (slot_context->params1 & 0x00ffffff);
|
||||
slot_context->num_ports = num_ports;
|
||||
slot_context->params2 = tt_think_time;
|
||||
slot_context->params2 = ep->device_speed == USB_SPEED_HIGH ? tt_think_time : 0;
|
||||
|
||||
xhci_ep_context_t *ep_context = (xhci_ep_context_t *)(ws->input_context_addr + (1 + ep_id) * ws->context_size);
|
||||
ep_context->params1 = 0;
|
||||
@ -1093,11 +1092,9 @@ bool xhci_init(uintptr_t base_addr, usb_hcd_t *hcd)
|
||||
|
||||
// Construct a hub descriptor for the root hub.
|
||||
usb_hub_t root_hub;
|
||||
memset(&root_hub, 0, sizeof(root_hub));
|
||||
root_hub.ep0 = NULL;
|
||||
root_hub.level = 0;
|
||||
root_hub.route = 0;
|
||||
root_hub.num_ports = cap_regs->hcs_params1 & 0xff;
|
||||
root_hub.power_up_delay = 0;
|
||||
|
||||
usleep(100*MILLISEC); // USB maximum device attach time.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user