XHCI parse full USB config
This commit is contained in:
@@ -4,6 +4,21 @@
|
|||||||
#include <aux/compiler.h>
|
#include <aux/compiler.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
|
/* descriptor types */
|
||||||
|
|
||||||
|
#define USB_DESC_DEVICE 1
|
||||||
|
#define USB_DESC_CONFIG 2
|
||||||
|
#define USB_DESC_STRING 3
|
||||||
|
#define USB_DESC_IF 4
|
||||||
|
#define USB_DESC_ENDPOINT 5
|
||||||
|
#define USB_DESC_IF_POWER 8
|
||||||
|
#define USB_DESC_OTG 9
|
||||||
|
#define USB_DESC_DEBUG 10
|
||||||
|
#define USB_DESC_IF_ASSOC 11
|
||||||
|
#define USB_DESC_BOS 15
|
||||||
|
#define USB_DESC_DEV_CAPABILITY 16
|
||||||
|
#define USB_DESC_SS_USB_EP_COMP 48
|
||||||
|
|
||||||
struct usb_desc_hdr {
|
struct usb_desc_hdr {
|
||||||
uint8_t length;
|
uint8_t length;
|
||||||
uint8_t desc_type;
|
uint8_t desc_type;
|
||||||
|
|||||||
@@ -885,6 +885,79 @@ static bool xhci_pdevice_setup_get_config (struct xhci* xhci, struct xhci_pdevic
|
|||||||
usb_config->total_length, usb_config->num_ifs, usb_config->config_value,
|
usb_config->total_length, usb_config->num_ifs, usb_config->config_value,
|
||||||
usb_config->config, usb_config->attrs, usb_config->max_power);
|
usb_config->config, usb_config->attrs, usb_config->max_power);
|
||||||
|
|
||||||
|
pdevice->config_desc = *usb_config;
|
||||||
|
|
||||||
|
pmm_free (response_buf_phys, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool xhci_pdevice_setup_get_config_full (struct xhci* xhci, struct xhci_pdevice* pdevice,
|
||||||
|
uint64_t* lockflags) {
|
||||||
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
|
||||||
|
uintptr_t response_buf_phys = pmm_alloc (1);
|
||||||
|
|
||||||
|
void* response_buf = (void*)(response_buf_phys + (uintptr_t)hhdm->offset);
|
||||||
|
memset (response_buf, 0, PAGE_SIZE);
|
||||||
|
|
||||||
|
bool ok = xhci_endpoint0_ctrl_in (xhci, pdevice, 0x80, 6, (2 << 8), 0, response_buf_phys,
|
||||||
|
pdevice->config_desc.total_length, lockflags);
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
pmm_free (response_buf_phys, 1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* ptr = (uint8_t*)response_buf;
|
||||||
|
uint8_t* end = ptr + pdevice->config_desc.total_length;
|
||||||
|
|
||||||
|
while (ptr < end) {
|
||||||
|
struct usb_desc_hdr* hdr = (struct usb_desc_hdr*)ptr;
|
||||||
|
|
||||||
|
if (hdr->length == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (hdr->desc_type) {
|
||||||
|
case USB_DESC_CONFIG: {
|
||||||
|
struct xhci_pdevice_dconfig* dconfig = malloc (sizeof (*dconfig));
|
||||||
|
memset (dconfig, 0, sizeof (*dconfig));
|
||||||
|
dconfig->desc = *(struct usb_config_desc*)ptr;
|
||||||
|
list_append (pdevice->dconfigs, &dconfig->configs_link);
|
||||||
|
|
||||||
|
DEBUG (
|
||||||
|
"Found USB device config: total_len=%u num_ifs=%u, cfgval=%u cfg=%u attrs=%02x maxpow=%u\n",
|
||||||
|
dconfig->desc.total_length, dconfig->desc.num_ifs, dconfig->desc.config_value,
|
||||||
|
dconfig->desc.config, dconfig->desc.attrs, dconfig->desc.max_power);
|
||||||
|
} break;
|
||||||
|
case USB_DESC_IF: {
|
||||||
|
struct xhci_pdevice_dif* dif = malloc (sizeof (*dif));
|
||||||
|
memset (dif, 0, sizeof (*dif));
|
||||||
|
dif->desc = *(struct usb_if_desc*)ptr;
|
||||||
|
list_append (pdevice->difs, &dif->ifs_link);
|
||||||
|
|
||||||
|
DEBUG (
|
||||||
|
"Found USB device interface: ifnum=%u altsetting=%u eps=%u ifclass=%u ifsubclass=%u ifproto=%u if=%u\n",
|
||||||
|
dif->desc.if_num, dif->desc.alt_setting, dif->desc.num_endpoints, dif->desc.if_class,
|
||||||
|
dif->desc.if_subclass, dif->desc.if1);
|
||||||
|
} break;
|
||||||
|
case USB_DESC_ENDPOINT: {
|
||||||
|
struct xhci_pdevice_dendpoint* dendpoint = malloc (sizeof (*dendpoint));
|
||||||
|
memset (dendpoint, 0, sizeof (*dendpoint));
|
||||||
|
dendpoint->desc = *(struct usb_endpoint_desc*)ptr;
|
||||||
|
list_append (pdevice->dendpoints, &dendpoint->endpoints_link);
|
||||||
|
|
||||||
|
DEBUG ("Found USB device endpoint: addr=%u attrs=%u maxpkt=%u intvl=%u\n",
|
||||||
|
dendpoint->desc.endpoint_addr, dendpoint->desc.attrs, dendpoint->desc.max_packet_size,
|
||||||
|
dendpoint->desc.interval);
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
DEBUG ("Found unknown USB descriptor of type %u\n", hdr->desc_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += hdr->length;
|
||||||
|
}
|
||||||
|
|
||||||
pmm_free (response_buf_phys, 1);
|
pmm_free (response_buf_phys, 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -900,10 +973,9 @@ static void xhci_poll_setup_devices (struct xhci* xhci, uint64_t* lockflags) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
xhci_pdevice_setup_addressing (xhci, pdevice, lockflags);
|
xhci_pdevice_setup_addressing (xhci, pdevice, lockflags);
|
||||||
|
|
||||||
xhci_pdevice_setup_get_info (xhci, pdevice, lockflags);
|
xhci_pdevice_setup_get_info (xhci, pdevice, lockflags);
|
||||||
|
|
||||||
xhci_pdevice_setup_get_config (xhci, pdevice, lockflags);
|
xhci_pdevice_setup_get_config (xhci, pdevice, lockflags);
|
||||||
|
xhci_pdevice_setup_get_config_full (xhci, pdevice, lockflags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,13 +67,33 @@ struct xhci_ring {
|
|||||||
uint8_t cycle_bit;
|
uint8_t cycle_bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct xhci_pdevice_dconfig {
|
||||||
|
struct usb_config_desc desc;
|
||||||
|
struct list_node_link configs_link;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct xhci_pdevice_dif {
|
||||||
|
struct usb_if_desc desc;
|
||||||
|
struct list_node_link ifs_link;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct xhci_pdevice_dendpoint {
|
||||||
|
struct usb_endpoint_desc desc;
|
||||||
|
struct list_node_link endpoints_link;
|
||||||
|
};
|
||||||
|
|
||||||
struct xhci_pdevice {
|
struct xhci_pdevice {
|
||||||
struct list_node_link pdevices_link;
|
struct list_node_link pdevices_link;
|
||||||
struct xhci_port* xhci_port;
|
struct xhci_port* xhci_port;
|
||||||
int slot_id;
|
int slot_id;
|
||||||
|
|
||||||
struct xhci_ring endpoint0_ring;
|
struct xhci_ring endpoint0_ring;
|
||||||
|
|
||||||
struct usb_device_desc device_desc;
|
struct usb_device_desc device_desc;
|
||||||
|
struct usb_config_desc config_desc;
|
||||||
|
struct list_node_link* dconfigs;
|
||||||
|
struct list_node_link* difs;
|
||||||
|
struct list_node_link* dendpoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xhci_port_status_change {
|
struct xhci_port_status_change {
|
||||||
|
|||||||
Reference in New Issue
Block a user