XHCI parse full USB config
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user