Minor fixes and refactoring in preparation for EHCI support.

This commit is contained in:
Martin Whitaker 2022-01-23 17:32:55 +00:00
parent 79ec174a82
commit 5b56d76e03
4 changed files with 45 additions and 24 deletions

View File

@ -11,6 +11,10 @@
#include <stdbool.h>
#include <stdint.h>
// Basic limits.
#define USB_MAX_ADDRESS 127
// Request types.
#define USB_REQ_TO_DEVICE 0x00

View File

@ -136,6 +136,7 @@ static bool build_hub_info(const usb_hcd_t *hcd, const usb_hub_t *parent, int po
return false;
}
ep1->driver_data = ep0->driver_data;
ep1->device_speed = ep0->device_speed;
ep1->device_id = ep0->device_id;
ep1->interface_num = 0;
@ -282,6 +283,7 @@ static bool scan_hub_ports(const usb_hcd_t *hcd, const usb_hub_t *hub, int *num_
for (int port_num = 1; port_num <= hub->num_ports; port_num++) {
// If we've filled the keyboard info table, abort now.
if (*num_keyboards >= max_keyboards) break;
uint32_t port_status;
get_hub_port_status(hcd, hub, port_num, &port_status);
@ -430,21 +432,29 @@ bool assign_usb_address(const usb_hcd_t *hcd, const usb_hub_t *hub, int port_num
uint8_t *data_buffer = hcd->ws->data_buffer;
// If we've run out of USB addresses, abort now.
if (device_id > USB_MAX_ADDRESS) {
return false;
}
// Initialise the control endpoint descriptor.
ep0->device_speed = device_speed;
ep0->device_id = 0;
ep0->interface_num = 0;
ep0->endpoint_num = 0;
ep0->max_packet_size = 8;
ep0->max_packet_size = default_max_packet_size(device_speed);
ep0->interval = 0;
// The device should currently be in Default state. We first fetch the first 8 bytes of the device descriptor to
// discover the maximum packet size for the control endpoint. We then set the device address, which moves the
// device into Address state, and fetch the full device descriptor.
// The device should currently be in Default state. For loww and full speed devices, We first fetch the first
// 8 bytes of the device descriptor to discover the maximum packet size for the control endpoint. We then set
// the device address, which moves the device into Address state, and fetch the full device descriptor.
size_t fetch_length = 8;
goto fetch_descriptor;
size_t fetch_length = sizeof(usb_device_desc_t);
if (device_speed < USB_SPEED_HIGH) {
fetch_length = 8;
goto fetch_descriptor;
}
set_address:
build_setup_packet(&setup_pkt, USB_REQ_TO_DEVICE, USB_SET_ADDRESS, device_id, 0, 0);
@ -551,6 +561,7 @@ bool find_attached_usb_keyboards(const usb_hcd_t *hcd, const usb_hub_t *hub, int
// Complete the new entries in the keyboard info table and configure the keyboard interfaces.
for (int kbd_idx = old_num_keyboards; kbd_idx < new_num_keyboards; kbd_idx++) {
usb_ep_t *kbd = &keyboards[kbd_idx];
kbd->driver_data = ep0.driver_data;
kbd->device_speed = device_speed;
kbd->device_id = device_id;
if (hcd->methods->configure_kbd_ep) {

View File

@ -45,7 +45,7 @@ typedef enum __attribute__ ((packed)) {
* A USB endpoint descriptor (used internally by the various HCI drivers).
*/
typedef struct __attribute__ ((packed)) {
void *driver_data;
uintptr_t driver_data;
usb_speed_t device_speed;
uint8_t device_id;
uint8_t interface_num;
@ -133,6 +133,25 @@ static inline void build_setup_packet(usb_setup_pkt_t *pkt, int type, int reques
pkt->length = length;
}
/* Returns the default maximum packet size for a USB device running at the
* given speed.
*
* Used internally by the various HCI drivers.
*/
static inline int default_max_packet_size(usb_speed_t device_speed)
{
switch (device_speed) {
case USB_SPEED_LOW:
return 8;
case USB_SPEED_FULL:
return 64;
case USB_SPEED_HIGH:
return 64;
default:
return 0;
}
}
/*
* Returns true if size is a valid value for the maximum packet size for a
* USB device running at the given speed.

View File

@ -7,10 +7,10 @@
#include "memrw32.h"
#include "memsize.h"
#include "pmem.h"
#include "usb.h"
#include "memory.h"
#include "unistd.h"
#include "usb.h"
#include "xhci.h"
@ -426,20 +426,6 @@ static int usb_to_xhci_speed(usb_speed_t usb_speed)
}
}
static int default_max_packet_size(usb_speed_t device_speed)
{
switch (device_speed) {
case USB_SPEED_LOW:
return 8;
case USB_SPEED_FULL:
return 64;
case USB_SPEED_HIGH:
return 64;
default:
return 0;
}
}
static int xhci_ep_interval(int config_interval, usb_speed_t device_speed)
{
if (device_speed < USB_SPEED_HIGH) {
@ -777,7 +763,7 @@ static bool assign_address(const usb_hcd_t *hcd, const usb_hub_t *hub, int port_
ep_tr_t *ep_tr = (ep_tr_t *)ws->control_ep_tr_addr;
ep_tr->enqueue_state = EP_TR_SIZE; // cycle = 1, index = 0
ep0->driver_data = (void *)ep_tr;
ep0->driver_data = (uintptr_t)ep_tr;
// Set the device address. For full speed devices we need to read the first 8 bytes of the device descriptor
// to determine the maximum packet size the device supports and update the device context accordingly. For
@ -1002,8 +988,8 @@ bool xhci_init(uintptr_t base_addr, usb_hcd_t *hcd)
xhci_legacy_support_t *legacy_support = (xhci_legacy_support_t *)ext_cap_base;
// Take ownership from the SMM if necessary.
int timer = 1000;
legacy_support->host_owns = 0x1;
while (legacy_support->bios_owns & 0x1) {
legacy_support->host_owns = 0x1;
if (timer == 0) return false;
usleep(1*MILLISEC);
timer--;
@ -1129,6 +1115,7 @@ bool xhci_init(uintptr_t base_addr, usb_hcd_t *hcd)
write64(&op_regs->dcbaap, device_context_index_addr);
write32(&op_regs->config, (read32(&op_regs->config) & 0xfffffc00) | max_slots);
if (!start_host_controller(op_regs)) {
pm_map[0].end += num_pages(sizeof(workspace_t));
pm_map[heap_segment].end = heap_segment_end;
return false;
}