XHCI parse full USB config
All checks were successful
Build ISO image / build-and-deploy (push) Successful in 3m1s
Build documentation / build-and-deploy (push) Successful in 3m5s

This commit is contained in:
2026-04-02 00:00:35 +02:00
parent 1a81a46803
commit 024512c5e4
3 changed files with 109 additions and 2 deletions

View File

@@ -4,6 +4,21 @@
#include <aux/compiler.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 {
uint8_t length;
uint8_t desc_type;

View File

@@ -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->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);
return true;
}
@@ -900,10 +973,9 @@ static void xhci_poll_setup_devices (struct xhci* xhci, uint64_t* lockflags) {
continue;
xhci_pdevice_setup_addressing (xhci, pdevice, lockflags);
xhci_pdevice_setup_get_info (xhci, pdevice, lockflags);
xhci_pdevice_setup_get_config (xhci, pdevice, lockflags);
xhci_pdevice_setup_get_config_full (xhci, pdevice, lockflags);
}
}

View File

@@ -67,13 +67,33 @@ struct xhci_ring {
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 list_node_link pdevices_link;
struct xhci_port* xhci_port;
int slot_id;
struct xhci_ring endpoint0_ring;
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 {