From 3d886f2039a1b7646fb762fc4f34d99dc609998f Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Tue, 7 Apr 2026 13:32:27 +0200 Subject: [PATCH] XHCI Improve error handling during device setup --- kernel/device/usb/xhci.c | 60 ++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/kernel/device/usb/xhci.c b/kernel/device/usb/xhci.c index 313d633..4acf6cf 100644 --- a/kernel/device/usb/xhci.c +++ b/kernel/device/usb/xhci.c @@ -544,7 +544,7 @@ static uint8_t xhci_get_device_ctx_idx (struct usb_endpoint_desc* endpoint) { return (endpoint_num * 2) + (in ? 1 : 0); } -static void xhci_usb_device_setup_init_endpoints (struct xhci* xhci, +static bool xhci_usb_device_setup_init_endpoints (struct xhci* xhci, struct xhci_usb_device* usb_device, uint64_t* lockflags) { struct limine_hhdm_response* hhdm = limine_hhdm_request.response; @@ -668,27 +668,32 @@ static void xhci_usb_device_setup_init_endpoints (struct xhci* xhci, uint32_t ctrl = (usb_device->slot_id << 24) | (XHCI_TRB_CFG_ENDP_CMD << XHCI_GTRB_TRB_TYPE); xhci_send_cmd (xhci, input_ctx_phys, 0, ctrl, lockflags); - if (xhci->last_cmpl_code != 1) - DEBUG ("Failed to configure endpoints for this device\n"); - else - DEBUG ("Successfully configured endpoints for this device\n"); - pmm_free (input_ctx_phys, 1); + + if (xhci->last_cmpl_code != 1) { + DEBUG ("Failed to configure endpoints for this device\n"); + return false; + } else { + DEBUG ("Successfully configured endpoints for this device\n"); + return true; + } } -static void xhci_usb_device_setup_set_config (struct xhci* xhci, struct xhci_usb_device* usb_device, +static bool xhci_usb_device_setup_set_config (struct xhci* xhci, struct xhci_usb_device* usb_device, uint8_t config_val, uint64_t* lockflags) { bool ok = xhci_endpoint0_ctrl_out (xhci, usb_device, 0x00, 0x09, config_val, 0, 0, 0, lockflags); if (!ok) { DEBUG ("Failed to set the config!\n"); - return; + return false; } DEBUG ("Config set!\n"); + + return true; } -static void xhci_usb_device_setup_addressing (struct xhci* xhci, struct xhci_usb_device* usb_device, +static bool xhci_usb_device_setup_addressing (struct xhci* xhci, struct xhci_usb_device* usb_device, uint64_t* lockflags) { struct limine_hhdm_response* hhdm = limine_hhdm_request.response; @@ -705,7 +710,7 @@ static void xhci_usb_device_setup_addressing (struct xhci* xhci, struct xhci_usb if (xhci->last_cmpl_code != 1) { DEBUG ("Enable slot failed\n"); - return; + return false; } usb_device->slot_id = xhci->last_slot_id; @@ -765,15 +770,17 @@ static void xhci_usb_device_setup_addressing (struct xhci* xhci, struct xhci_usb uint32_t ctrl = (usb_device->slot_id << 24) | (XHCI_TRB_ADDR_DEV_CMD << XHCI_GTRB_TRB_TYPE); xhci_send_cmd (xhci, input_ctx_phys, 0, ctrl, lockflags); + pmm_free (input_ctx_phys, 1); + if (xhci->last_cmpl_code != 1) { DEBUG ("Failed to address device. port = %u, slot = %u\n", usb_device->xhci_port->port_value, usb_device->slot_id); + return false; } else { DEBUG ("Device on port %u addressed on slot %u!\n", usb_device->xhci_port->port_value, usb_device->slot_id); + return true; } - - pmm_free (input_ctx_phys, 1); } static bool xhci_usb_device_setup_get_info (struct xhci* xhci, struct xhci_usb_device* usb_device, @@ -935,6 +942,7 @@ static void xhci_poll_setup_init_ifs (struct xhci* xhci, struct xhci_usb_device* static void xhci_poll_setup_devices (struct xhci* xhci, uint64_t* lockflags) { struct list_node_link *usb_device_link, *tmp_usb_device_link; + bool ok; list_foreach (xhci->xhci_usb_devices, usb_device_link, tmp_usb_device_link) { struct xhci_usb_device* usb_device = @@ -944,14 +952,26 @@ static void xhci_poll_setup_devices (struct xhci* xhci, uint64_t* lockflags) { if (usb_device->slot_id != -1) continue; - xhci_usb_device_setup_addressing (xhci, usb_device, lockflags); - xhci_usb_device_setup_get_info (xhci, usb_device, lockflags); - xhci_usb_device_setup_get_config (xhci, usb_device, lockflags); - xhci_usb_device_setup_get_config_full (xhci, usb_device, lockflags); - xhci_usb_device_setup_set_config (xhci, usb_device, usb_device->config_desc.config_value, - lockflags); - xhci_usb_device_setup_init_endpoints (xhci, usb_device, lockflags); - xhci_poll_setup_init_ifs (xhci, usb_device, lockflags); + ok = xhci_usb_device_setup_addressing (xhci, usb_device, lockflags); + + if (ok) + ok = xhci_usb_device_setup_get_info (xhci, usb_device, lockflags); + + if (ok) + ok = xhci_usb_device_setup_get_config (xhci, usb_device, lockflags); + + if (ok) + ok = xhci_usb_device_setup_get_config_full (xhci, usb_device, lockflags); + + if (ok) + ok = xhci_usb_device_setup_set_config (xhci, usb_device, usb_device->config_desc.config_value, + lockflags); + + if (ok) + ok = xhci_usb_device_setup_init_endpoints (xhci, usb_device, lockflags); + + if (ok) + xhci_poll_setup_init_ifs (xhci, usb_device, lockflags); } }