XHCI get USB device descriptor
This commit is contained in:
63
kernel/device/usb.h
Normal file
63
kernel/device/usb.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#ifndef _KERNEL_DEVICE_USB_H
|
||||
#define _KERNEL_DEVICE_USB_H
|
||||
|
||||
#include <aux/compiler.h>
|
||||
#include <libk/std.h>
|
||||
|
||||
struct usb_desc_hdr {
|
||||
uint8_t length;
|
||||
uint8_t desc_type;
|
||||
} PACKED;
|
||||
|
||||
struct usb_device_desc {
|
||||
struct usb_desc_hdr hdr;
|
||||
uint16_t bcd_usb;
|
||||
uint8_t dev_class;
|
||||
uint8_t dev_subclass;
|
||||
uint8_t dev_proto;
|
||||
uint8_t max_packet_size;
|
||||
uint16_t vendor_id;
|
||||
uint16_t product_id;
|
||||
uint16_t bcd_device;
|
||||
uint8_t manufacturer;
|
||||
uint8_t product;
|
||||
uint8_t serial_num;
|
||||
uint8_t num_configs;
|
||||
} PACKED;
|
||||
|
||||
struct usb_string_lang_desc {
|
||||
struct usb_desc_hdr hdr;
|
||||
uint16_t langs[126];
|
||||
} PACKED;
|
||||
|
||||
struct usb_config_desc {
|
||||
struct usb_desc_hdr hdr;
|
||||
uint16_t total_length;
|
||||
uint8_t num_ifs;
|
||||
uint8_t config_value;
|
||||
uint8_t config;
|
||||
uint8_t attrs;
|
||||
uint8_t max_power;
|
||||
uint8_t data[245];
|
||||
} PACKED;
|
||||
|
||||
struct usb_if_desc {
|
||||
struct usb_desc_hdr hdr;
|
||||
uint8_t if_num;
|
||||
uint8_t alt_setting;
|
||||
uint8_t num_endpoints;
|
||||
uint8_t if_class;
|
||||
uint8_t if_subclass;
|
||||
uint8_t if_proto;
|
||||
uint8_t if1;
|
||||
} PACKED;
|
||||
|
||||
struct usb_endpoint_desc {
|
||||
struct usb_desc_hdr hdr;
|
||||
uint8_t endpoint_addr;
|
||||
uint8_t attrs;
|
||||
uint16_t max_packet_size;
|
||||
uint8_t interval;
|
||||
} PACKED;
|
||||
|
||||
#endif // _KERNEL_DEVICE_USB_H
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <device/def_device_op.h>
|
||||
#include <device/device.h>
|
||||
#include <device/usb.h>
|
||||
#include <device/xhci.h>
|
||||
#include <irq/irq.h>
|
||||
#include <libk/list.h>
|
||||
@@ -181,11 +182,10 @@ static void xhci_port_reset (struct xhci* xhci, uint8_t port) {
|
||||
stall_ms (100);
|
||||
}
|
||||
|
||||
static void xhci_create_plugged_device (struct xhci* xhci, uint8_t port) {
|
||||
struct xhci_plugged_device* pdevice;
|
||||
static void xhci_create_pdevice (struct xhci* xhci, uint8_t port) {
|
||||
struct xhci_pdevice* pdevice;
|
||||
|
||||
list_find (struct xhci_plugged_device, xhci->xhci_plugged_devices, pdevice, port_value, port,
|
||||
plugged_devices_link);
|
||||
list_find (struct xhci_pdevice, xhci->xhci_pdevices, pdevice, port_value, port, pdevices_link);
|
||||
|
||||
if (pdevice != NULL)
|
||||
return;
|
||||
@@ -195,16 +195,15 @@ static void xhci_create_plugged_device (struct xhci* xhci, uint8_t port) {
|
||||
pdevice->port_value = port;
|
||||
pdevice->slot_id = -1;
|
||||
|
||||
list_append (xhci->xhci_plugged_devices, &pdevice->plugged_devices_link);
|
||||
list_append (xhci->xhci_pdevices, &pdevice->pdevices_link);
|
||||
}
|
||||
|
||||
static void xhci_delete_plugged_device (struct xhci* xhci, uint8_t port) {
|
||||
struct xhci_plugged_device* pdevice;
|
||||
static void xhci_delete_pdevice (struct xhci* xhci, uint8_t port) {
|
||||
struct xhci_pdevice* pdevice;
|
||||
|
||||
list_find (struct xhci_plugged_device, xhci->xhci_plugged_devices, pdevice, port_value, port,
|
||||
plugged_devices_link);
|
||||
list_find (struct xhci_pdevice, xhci->xhci_pdevices, pdevice, port_value, port, pdevices_link);
|
||||
|
||||
list_remove (xhci->xhci_plugged_devices, &pdevice->plugged_devices_link);
|
||||
list_remove (xhci->xhci_pdevices, &pdevice->pdevices_link);
|
||||
|
||||
if (pdevice->endpoint0_ring_phys != 0)
|
||||
pmm_free (pdevice->endpoint0_ring_phys, 1);
|
||||
@@ -238,17 +237,26 @@ static void xhci_event_dispatch (struct xhci* xhci, struct xhci_trb* event, uint
|
||||
if ((portsc & (1 << 0))) {
|
||||
DEBUG ("Device attached to port %u!\n", port);
|
||||
|
||||
xhci_create_plugged_device (xhci, port);
|
||||
xhci_create_pdevice (xhci, port);
|
||||
} else {
|
||||
DEBUG ("Device detached from port %u!\n", port);
|
||||
|
||||
xhci_delete_plugged_device (xhci, port);
|
||||
xhci_delete_pdevice (xhci, port);
|
||||
}
|
||||
}
|
||||
|
||||
if ((portsc & (1 << 21)))
|
||||
DEBUG ("Port %u reset done\n", port);
|
||||
} break;
|
||||
case XHCI_TRB_TRANSFER_EVENT: {
|
||||
uint8_t cmpl_code = (event->status >> 24) & 0xFF;
|
||||
uint8_t slot_id = (event->ctrl >> 24) & 0xFF;
|
||||
uint8_t endpoint_id = (event->ctrl >> 16) & 0x1F;
|
||||
|
||||
DEBUG ("transfer completion: code=%u,slot=%u,endpoint_id=%u\n", cmpl_code, slot_id,
|
||||
endpoint_id);
|
||||
xhci->last_cmpl_code = cmpl_code;
|
||||
} break;
|
||||
default:
|
||||
DEBUG ("Unhandled event type %u at %u\n", type, xhci->event_ring_idx);
|
||||
break;
|
||||
@@ -311,6 +319,77 @@ static void xhci_irq (void* arg, void* regs, bool user, struct reschedule_ctx* r
|
||||
spin_unlock (&xhci->device->lock, fd);
|
||||
}
|
||||
|
||||
static void xhci_endpoint0_put_trb (struct xhci_pdevice* pdevice, struct xhci_trb trb) {
|
||||
if (pdevice->endpoint0_ring_idx == pdevice->endpoint0_ring_size - 1) {
|
||||
struct xhci_trb* link = &pdevice->endpoint0_ring[pdevice->endpoint0_ring_idx];
|
||||
link->param = pdevice->endpoint0_ring_phys;
|
||||
link->status = 0;
|
||||
link->ctrl = (XHCI_TRB_LINK << 10) | (1 << 1) | pdevice->endpoint0_cycle_bit;
|
||||
|
||||
pdevice->endpoint0_ring_idx = 0;
|
||||
pdevice->endpoint0_cycle_bit ^= 1;
|
||||
}
|
||||
|
||||
pdevice->endpoint0_ring[pdevice->endpoint0_ring_idx] = trb;
|
||||
pdevice->endpoint0_ring[pdevice->endpoint0_ring_idx].ctrl =
|
||||
(pdevice->endpoint0_ring[pdevice->endpoint0_ring_idx].ctrl & ~1u) |
|
||||
pdevice->endpoint0_cycle_bit;
|
||||
|
||||
pdevice->endpoint0_ring_idx++;
|
||||
}
|
||||
|
||||
static bool xhci_endpoint0_ctrl_in (struct xhci* xhci, struct xhci_pdevice* pdevice,
|
||||
uint8_t request_type, uint8_t request, uint16_t value,
|
||||
uint16_t index, uintptr_t data_phys, uint16_t length,
|
||||
uint64_t* lockflags) {
|
||||
uint64_t setup = ((uint64_t)length << 48) | ((uint64_t)index << 32) | ((uint64_t)value << 16) |
|
||||
((uint64_t)request << 8) | ((uint64_t)request_type);
|
||||
|
||||
struct xhci_trb trb;
|
||||
|
||||
xhci->last_cmpl_code = 0;
|
||||
atomic_store (&xhci->pending, true);
|
||||
|
||||
/* setup stage */
|
||||
memset (&trb, 0, sizeof (trb));
|
||||
trb.param = setup;
|
||||
trb.status = 8;
|
||||
trb.ctrl = (XHCI_TRB_SETUP_STAGE << 10) | (1 << 6) | (1 << 4);
|
||||
xhci_endpoint0_put_trb (pdevice, trb);
|
||||
|
||||
/* data stage */
|
||||
memset (&trb, 0, sizeof (trb));
|
||||
trb.param = data_phys;
|
||||
trb.status = length;
|
||||
trb.ctrl = (XHCI_TRB_DATA_STAGE << 10) | (1 << 16) | (1 << 4);
|
||||
xhci_endpoint0_put_trb (pdevice, trb);
|
||||
|
||||
/* status stage */
|
||||
memset (&trb, 0, sizeof (trb));
|
||||
trb.param = 0;
|
||||
trb.status = 0;
|
||||
trb.ctrl = (XHCI_TRB_STATUS_STAGE << 10) | (1 << 5);
|
||||
xhci_endpoint0_put_trb (pdevice, trb);
|
||||
|
||||
xhci_write32 (xhci->xhci_doorbell_base, pdevice->slot_id * 4, 1);
|
||||
|
||||
int timeout = 100;
|
||||
|
||||
spin_unlock (&xhci->device->lock, *lockflags);
|
||||
|
||||
while (atomic_load (&xhci->pending) && --timeout > 0)
|
||||
stall_ms (10);
|
||||
|
||||
spin_lock (&xhci->device->lock, lockflags);
|
||||
|
||||
if (timeout == 0) {
|
||||
DEBUG ("timed out\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return xhci->last_cmpl_code == 1;
|
||||
}
|
||||
|
||||
static void xhci_send_cmd (struct xhci* xhci, uint64_t param, uint32_t status, uint32_t ctrl,
|
||||
uint64_t* lockflags) {
|
||||
if (xhci->irqs_support) {
|
||||
@@ -437,7 +516,7 @@ static void xhci_reset_ports (struct xhci* xhci) {
|
||||
if ((portsc & (1 << 0))) {
|
||||
DEBUG ("Device connected. resetting\n");
|
||||
xhci_port_reset (xhci, port);
|
||||
xhci_create_plugged_device (xhci, port);
|
||||
xhci_create_pdevice (xhci, port);
|
||||
}
|
||||
|
||||
DEBUG ("PORT %u: USB %u.%u\n", port, major, minor);
|
||||
@@ -452,6 +531,142 @@ static void xhci_reset_ports (struct xhci* xhci) {
|
||||
}
|
||||
}
|
||||
|
||||
static void xhci_pdevice_setup_addressing (struct xhci* xhci, struct xhci_pdevice* pdevice,
|
||||
uint64_t* lockflags) {
|
||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||
|
||||
struct xhci_port* xhci_port;
|
||||
list_find (struct xhci_port, xhci->xhci_ports, xhci_port, port_value, pdevice->port_value,
|
||||
ports_link);
|
||||
|
||||
uint32_t portsc = xhci_portsc_read (xhci, pdevice->port_value);
|
||||
|
||||
uint32_t speed = (portsc >> 10) & 0x0F;
|
||||
|
||||
xhci->last_cmpl_code = 0;
|
||||
xhci_send_cmd (xhci, 0, 0, XHCI_TRB_SLOT_ENAB_CMD << 10, lockflags);
|
||||
|
||||
if (xhci->last_cmpl_code != 1) {
|
||||
DEBUG ("Enable slot failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pdevice->slot_id = xhci->last_slot_id;
|
||||
|
||||
uintptr_t out_ctx_phys = pmm_alloc (1);
|
||||
void* out_ctx_virt = (void*)(out_ctx_phys + (uintptr_t)hhdm->offset);
|
||||
memset (out_ctx_virt, 0, PAGE_SIZE);
|
||||
xhci->xhci_dcbaa[pdevice->slot_id] = out_ctx_phys;
|
||||
|
||||
pdevice->endpoint0_ring_phys = pmm_alloc (1);
|
||||
pdevice->endpoint0_ring =
|
||||
(struct xhci_trb*)(pdevice->endpoint0_ring_phys + (uintptr_t)hhdm->offset);
|
||||
memset (pdevice->endpoint0_ring, 0, PAGE_SIZE);
|
||||
pdevice->endpoint0_ring_size = PAGE_SIZE / sizeof (struct xhci_trb);
|
||||
pdevice->endpoint0_ring_idx = 0;
|
||||
pdevice->endpoint0_cycle_bit = 1;
|
||||
|
||||
uintptr_t input_ctx_phys = pmm_alloc (1);
|
||||
void* input_ctx_virt = (void*)(input_ctx_phys + (uintptr_t)hhdm->offset);
|
||||
memset (input_ctx_virt, 0, PAGE_SIZE);
|
||||
|
||||
if (xhci->xhci_ctx_size == 64) {
|
||||
struct xhci_input_ctx64* ctx64 = input_ctx_virt;
|
||||
|
||||
size_t max_packet_size = (xhci_port->type == XHCI_PORT_USB3) ? 512 : 64;
|
||||
|
||||
/* Add slot and endpoint 0 */
|
||||
ctx64->ctrl.dw[1] = (1 << 0) | (1 << 1);
|
||||
|
||||
ctx64->slot.dw[0] = (1 << 27) | (speed << 20);
|
||||
ctx64->slot.dw[1] = ((pdevice->port_value + 1) << 16);
|
||||
|
||||
ctx64->endpoints[0].dw[0] = 0;
|
||||
ctx64->endpoints[0].dw[1] = 3 | (4 << 3) | (max_packet_size << 16);
|
||||
ctx64->endpoints[0].dw[2] = (uint32_t)pdevice->endpoint0_ring_phys | (1 << 0);
|
||||
ctx64->endpoints[0].dw[3] = (uint32_t)(pdevice->endpoint0_ring_phys >> 32);
|
||||
} else {
|
||||
struct xhci_input_ctx32* ctx32 = input_ctx_virt;
|
||||
|
||||
size_t max_packet_size = (xhci_port->type == XHCI_PORT_USB3) ? 512 : 64;
|
||||
|
||||
ctx32->ctrl.dw[1] = (1 << 0) | (1 << 1);
|
||||
|
||||
ctx32->slot.dw[0] = (1 << 27) | (speed << 20);
|
||||
ctx32->slot.dw[1] = ((pdevice->port_value + 1) << 16);
|
||||
|
||||
ctx32->endpoints[0].dw[1] = 3 | (4 << 3) | (max_packet_size << 16);
|
||||
ctx32->endpoints[0].dw[2] = (uint32_t)pdevice->endpoint0_ring_phys | (1 << 0);
|
||||
ctx32->endpoints[0].dw[3] = (uint32_t)(pdevice->endpoint0_ring_phys >> 32);
|
||||
}
|
||||
|
||||
xhci->last_cmpl_code = 0;
|
||||
uint32_t ctrl = (pdevice->slot_id << 24) | (XHCI_TRB_ADDR_DEV_CMD << 10);
|
||||
xhci_send_cmd (xhci, input_ctx_phys, 0, ctrl, lockflags);
|
||||
|
||||
stall_ms (500);
|
||||
|
||||
if (xhci->last_cmpl_code != 1) {
|
||||
DEBUG ("Failed to address device. port = %u, slot = %u\n", pdevice->port_value,
|
||||
pdevice->slot_id);
|
||||
} else {
|
||||
DEBUG ("Device on port %u addressed on slot %u!\n", pdevice->port_value, pdevice->slot_id);
|
||||
}
|
||||
|
||||
pmm_free (input_ctx_phys, 1);
|
||||
}
|
||||
|
||||
static bool xhci_pdevice_setup_get_info (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, (1 << 8), 0, response_buf_phys,
|
||||
sizeof (struct usb_device_desc), lockflags);
|
||||
|
||||
if (!ok) {
|
||||
pmm_free (response_buf_phys, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct usb_device_desc* usb_desc = response_buf;
|
||||
|
||||
DEBUG ("USB device info: vndr=%04x prdct=%04x class=%02x subclass=%02x mps=%u cfgs=%u\n",
|
||||
usb_desc->vendor_id, usb_desc->product_id, usb_desc->dev_class, usb_desc->dev_subclass,
|
||||
usb_desc->max_packet_size, usb_desc->num_configs);
|
||||
|
||||
pmm_free (response_buf_phys, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void xhci_poll_setup_devices (struct xhci* xhci, uint64_t* lockflags) {
|
||||
struct list_node_link *pdevice_link, *tmp_pdevice_link;
|
||||
|
||||
list_foreach (xhci->xhci_pdevices, pdevice_link, tmp_pdevice_link) {
|
||||
struct xhci_pdevice* pdevice = list_entry (pdevice_link, struct xhci_pdevice, pdevices_link);
|
||||
|
||||
/* slot assigned */
|
||||
if (pdevice->slot_id != -1)
|
||||
continue;
|
||||
|
||||
xhci_pdevice_setup_addressing (xhci, pdevice, lockflags);
|
||||
|
||||
xhci_pdevice_setup_get_info (xhci, pdevice, lockflags);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_DEVICE_OP (xhci_poll_driver) {
|
||||
struct xhci* xhci = device->udata;
|
||||
|
||||
xhci_poll_setup_devices (xhci, lockflags);
|
||||
|
||||
return ST_OK;
|
||||
}
|
||||
|
||||
DEFINE_DEVICE_INIT (xhci_init) {
|
||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||
|
||||
@@ -630,102 +845,3 @@ DEFINE_DEVICE_FINI (xhci_fini) {
|
||||
|
||||
free (xhci);
|
||||
}
|
||||
|
||||
static void xhci_poll_setup_devices (struct xhci* xhci, uint64_t* lockflags) {
|
||||
struct list_node_link *pdevice_link, *tmp_pdevice_link;
|
||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||
|
||||
list_foreach (xhci->xhci_plugged_devices, pdevice_link, tmp_pdevice_link) {
|
||||
struct xhci_plugged_device* pdevice =
|
||||
list_entry (pdevice_link, struct xhci_plugged_device, plugged_devices_link);
|
||||
|
||||
/* slot assigned */
|
||||
if (pdevice->slot_id != -1)
|
||||
continue;
|
||||
|
||||
struct xhci_port* xhci_port;
|
||||
list_find (struct xhci_port, xhci->xhci_ports, xhci_port, port_value, pdevice->port_value,
|
||||
ports_link);
|
||||
|
||||
uint32_t portsc = xhci_portsc_read (xhci, pdevice->port_value);
|
||||
|
||||
uint32_t speed = (portsc >> 10) & 0x0F;
|
||||
|
||||
xhci->last_cmpl_code = 0;
|
||||
xhci_send_cmd (xhci, 0, 0, XHCI_TRB_SLOT_ENAB_CMD << 10, lockflags);
|
||||
|
||||
if (xhci->last_cmpl_code != 1) {
|
||||
DEBUG ("Enable slot failed\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
pdevice->slot_id = xhci->last_slot_id;
|
||||
|
||||
uintptr_t out_ctx_phys = pmm_alloc (1);
|
||||
void* out_ctx_virt = (void*)(out_ctx_phys + (uintptr_t)hhdm->offset);
|
||||
memset (out_ctx_virt, 0, PAGE_SIZE);
|
||||
xhci->xhci_dcbaa[pdevice->slot_id] = out_ctx_phys;
|
||||
|
||||
pdevice->endpoint0_ring_phys = pmm_alloc (1);
|
||||
pdevice->endpoint0_ring =
|
||||
(struct xhci_trb*)(pdevice->endpoint0_ring_phys + (uintptr_t)hhdm->offset);
|
||||
memset (pdevice->endpoint0_ring, 0, PAGE_SIZE);
|
||||
|
||||
uintptr_t input_ctx_phys = pmm_alloc (1);
|
||||
void* input_ctx_virt = (void*)(input_ctx_phys + (uintptr_t)hhdm->offset);
|
||||
memset (input_ctx_virt, 0, PAGE_SIZE);
|
||||
|
||||
if (xhci->xhci_ctx_size == 64) {
|
||||
struct xhci_input_ctx64* ctx64 = input_ctx_virt;
|
||||
|
||||
size_t max_packet_size = (xhci_port->type == XHCI_PORT_USB3) ? 512 : 64;
|
||||
|
||||
/* Add slot and endpoint 0 */
|
||||
ctx64->ctrl.dw[1] = (1 << 0) | (1 << 1);
|
||||
|
||||
ctx64->slot.dw[0] = (1 << 27) | (speed << 20);
|
||||
ctx64->slot.dw[1] = ((pdevice->port_value + 1) << 16);
|
||||
|
||||
ctx64->endpoints[0].dw[0] = 0;
|
||||
ctx64->endpoints[0].dw[1] = 3 | (4 << 3) | (max_packet_size << 16);
|
||||
ctx64->endpoints[0].dw[2] = (uint32_t)pdevice->endpoint0_ring_phys | (1 << 0);
|
||||
ctx64->endpoints[0].dw[3] = (uint32_t)(pdevice->endpoint0_ring_phys >> 32);
|
||||
} else {
|
||||
struct xhci_input_ctx32* ctx32 = input_ctx_virt;
|
||||
|
||||
size_t max_packet_size = (xhci_port->type == XHCI_PORT_USB3) ? 512 : 64;
|
||||
|
||||
ctx32->ctrl.dw[1] = (1 << 0) | (1 << 1);
|
||||
|
||||
ctx32->slot.dw[0] = (1 << 27) | (speed << 20);
|
||||
ctx32->slot.dw[1] = ((pdevice->port_value + 1) << 16);
|
||||
|
||||
ctx32->endpoints[0].dw[1] = 3 | (4 << 3) | (max_packet_size << 16);
|
||||
ctx32->endpoints[0].dw[2] = (uint32_t)pdevice->endpoint0_ring_phys | (1 << 0);
|
||||
ctx32->endpoints[0].dw[3] = (uint32_t)(pdevice->endpoint0_ring_phys >> 32);
|
||||
}
|
||||
|
||||
xhci->last_cmpl_code = 0;
|
||||
uint32_t ctrl = (pdevice->slot_id << 24) | (XHCI_TRB_ADDR_DEV_CMD << 10);
|
||||
xhci_send_cmd (xhci, input_ctx_phys, 0, ctrl, lockflags);
|
||||
|
||||
stall_ms (500);
|
||||
|
||||
if (xhci->last_cmpl_code != 1) {
|
||||
DEBUG ("Failed to address device. port = %u, slot = %u\n", pdevice->port_value,
|
||||
pdevice->slot_id);
|
||||
} else {
|
||||
DEBUG ("Device on port %u addressed on slot %u!\n", pdevice->port_value, pdevice->slot_id);
|
||||
}
|
||||
|
||||
pmm_free (input_ctx_phys, 1);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_DEVICE_OP (xhci_poll_driver) {
|
||||
struct xhci* xhci = device->udata;
|
||||
|
||||
xhci_poll_setup_devices (xhci, lockflags);
|
||||
|
||||
return ST_OK;
|
||||
}
|
||||
|
||||
@@ -58,13 +58,16 @@ struct xhci_port {
|
||||
int type;
|
||||
};
|
||||
|
||||
struct xhci_plugged_device {
|
||||
struct list_node_link plugged_devices_link;
|
||||
struct xhci_pdevice {
|
||||
struct list_node_link pdevices_link;
|
||||
uint8_t port_value;
|
||||
int slot_id;
|
||||
|
||||
struct xhci_trb* endpoint0_ring;
|
||||
uintptr_t endpoint0_ring_phys;
|
||||
uint32_t endpoint0_ring_idx;
|
||||
uint32_t endpoint0_ring_size;
|
||||
uint8_t endpoint0_cycle_bit;
|
||||
};
|
||||
|
||||
struct xhci {
|
||||
@@ -105,7 +108,7 @@ struct xhci {
|
||||
size_t xhci_ctx_size;
|
||||
|
||||
struct list_node_link* xhci_ports;
|
||||
struct list_node_link* xhci_plugged_devices;
|
||||
struct list_node_link* xhci_pdevices;
|
||||
|
||||
atomic_bool pending;
|
||||
uint8_t last_slot_id;
|
||||
|
||||
Reference in New Issue
Block a user