Skip to content

Commit 2a31fec

Browse files
usb improvements
1 parent 256185f commit 2a31fec

File tree

11 files changed

+1051
-704
lines changed

11 files changed

+1051
-704
lines changed

include/debugger.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ typedef struct stack_frame {
3636
* @param address a pointer to some memory address
3737
* @param length represents the number of bytes of memory that should be dumped.
3838
*/
39-
void dump_hex(void* address, uint64_t length);
39+
void dump_hex(const void* address, uint64_t length);
4040

4141
// Initialise debugger, read symbols from boot device. These are used for backtraces.
4242
void init_debug();
@@ -53,4 +53,6 @@ uint32_t gdb_trace(const char* str);
5353

5454
const char* findsymbol(uint64_t address, uint64_t* offset);
5555

56-
uint64_t findsymbol_addr(const char *name);
56+
uint64_t findsymbol_addr(const char *name);
57+
58+
bool running_under_qemu(void);

include/usb_core.h

Lines changed: 138 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,71 +4,166 @@
44
#include <stdint.h>
55
#include <stddef.h>
66

7-
/* ---- USB basics ---- */
8-
7+
/**
8+
* @enum usb_ep_type_t
9+
* @brief USB endpoint transfer type codes.
10+
*/
911
typedef enum {
10-
USB_EP_CONTROL = 0,
11-
USB_EP_ISOCH = 1,
12-
USB_EP_BULK = 2,
13-
USB_EP_INTERRUPT = 3
12+
/** Control endpoint (EP0, setup/data/status). */
13+
USB_EP_CONTROL = 0,
14+
/** Isochronous endpoint (time-sensitive streaming). */
15+
USB_EP_ISOCH = 1,
16+
/** Bulk endpoint (large, burst transfers). */
17+
USB_EP_BULK = 2,
18+
/** Interrupt endpoint (periodic, low-latency). */
19+
USB_EP_INTERRUPT= 3
1420
} usb_ep_type_t;
1521

16-
/* Minimal endpoint model (xHCI uses “EPID” numbering: 1=EP0, 2/3=EP1 OUT/IN, …) */
22+
/**
23+
* @struct usb_endpoint
24+
* @brief Minimal endpoint model for xHCI and class drivers.
25+
*
26+
* xHCI uses “EPID” numbering:
27+
* - 1 = EP0 (control)
28+
* - 2 = EP1 OUT
29+
* - 3 = EP1 IN
30+
* - ...
31+
*/
1732
typedef struct usb_endpoint {
18-
uint8_t epid; /* xHCI endpoint ID (1 = EP0) */
19-
uint16_t mps; /* max packet size */
20-
uint8_t type; /* usb_ep_type_t */
21-
uint8_t dir_in; /* 1 = IN, 0 = OUT (for control this is 0) */
33+
/** xHCI endpoint ID. */
34+
uint8_t epid;
35+
/** Maximum packet size. */
36+
uint16_t mps;
37+
/** Endpoint type (see @ref usb_ep_type_t). */
38+
uint8_t type;
39+
/** Direction: 1 = IN (device->host), 0 = OUT (host->device). */
40+
uint8_t dir_in;
2241
} usb_endpoint_t;
2342

24-
/* Device record published by HCDs (xhci, ehci, uhci…) */
43+
/**
44+
* @struct usb_dev
45+
* @brief Published record for a USB device enumerated by the HCD.
46+
*
47+
* Carries class/interface identity and endpoint 0 information.
48+
*/
2549
typedef struct usb_dev {
26-
void *hc; /* host controller opaque pointer (xhci_hc*) */
27-
uint8_t slot_id; /* xHCI slot ID */
28-
uint8_t address; /* USB address (post-set-address) */
29-
30-
uint16_t vid, pid; /* vendor/product */
31-
uint8_t dev_class; /* bInterfaceClass (from selected interface) */
32-
uint8_t dev_subclass; /* bInterfaceSubClass */
33-
uint8_t dev_proto; /* bInterfaceProtocol */
34-
35-
usb_endpoint_t ep0; /* default control endpoint */
50+
/** Host controller opaque pointer (xhci_hc*). */
51+
void *hc;
52+
/** Assigned xHCI Slot ID (1..max_slots). */
53+
uint8_t slot_id;
54+
/** Assigned USB device address (after SET_ADDRESS). */
55+
uint8_t address;
56+
57+
/** Vendor ID from device descriptor. */
58+
uint16_t vid;
59+
/** Product ID from device descriptor. */
60+
uint16_t pid;
61+
/** Interface class code (bInterfaceClass). */
62+
uint8_t dev_class;
63+
/** Interface subclass code (bInterfaceSubClass). */
64+
uint8_t dev_subclass;
65+
/** Interface protocol code (bInterfaceProtocol). */
66+
uint8_t dev_proto;
67+
/** Interface number (bInterfaceNumber). */
68+
uint8_t iface_num;
69+
70+
/** Default control endpoint (EP0). */
71+
usb_endpoint_t ep0;
3672
} usb_dev_t;
3773

38-
/* ------------------------------------------------------------------
39-
* Core API consumed by HCDs (xHCI) and class drivers (HID, MSC, …)
40-
* ------------------------------------------------------------------ */
41-
42-
/* Called by the HCD when a new device is successfully enumerated. */
74+
/* ============================================================
75+
* Core USB framework API (shared by HCDs and class drivers)
76+
* ============================================================ */
77+
78+
/**
79+
* @brief Notify the core that a new device has been enumerated.
80+
*
81+
* Called by host controller drivers once device enumeration succeeds.
82+
* Dispatches to registered class driver handlers.
83+
*
84+
* @param dev Pointer to published device record.
85+
*/
4386
void usb_core_device_added(const usb_dev_t *dev);
4487

45-
/* Lookup helpers used by class drivers. */
88+
/** @brief Standard class code for HID devices. */
4689
#define USB_CLASS_HID 0x03
4790

48-
/* --- USB class driver callbacks --- */
49-
50-
struct usb_dev; /* forward declaration only */
51-
91+
/**
92+
* @typedef device_notify_change_t
93+
* @brief Callback type for class drivers on add/remove.
94+
*
95+
* @param dev Pointer to device being added or removed.
96+
*/
97+
typedef void (*device_notify_change_t)(const struct usb_dev *dev);
98+
99+
/**
100+
* @struct usb_class_ops
101+
* @brief Registration block for a USB class driver.
102+
*/
52103
struct usb_class_ops {
104+
/** Name string for diagnostics/logging. */
53105
const char *name;
54-
55-
void (*on_device_added)(const struct usb_dev *dev);
56-
57-
void (*on_device_removed)(const struct usb_dev *dev);
106+
/** Called when a matching device is added. */
107+
device_notify_change_t on_device_added;
108+
/** Called when a matching device is removed. */
109+
device_notify_change_t on_device_removed;
58110
};
59111

60-
int usb_core_register_class(uint8_t class_code, const struct usb_class_ops *ops);
61-
62-
/* Return pointer to first device with matching class/subclass/proto (0xFF = don't care). */
112+
/**
113+
* @brief Register a new class driver.
114+
*
115+
* @param class_code Class code to match (e.g. @ref USB_CLASS_HID).
116+
* @param ops Operations block with callbacks.
117+
* @return true if registered, false if failed (e.g. duplicate).
118+
*/
119+
bool usb_core_register_class(uint8_t class_code, const struct usb_class_ops *ops);
120+
121+
/**
122+
* @brief Find the first device matching class/subclass/proto.
123+
*
124+
* 0xFF can be used as a wildcard (“don’t care”).
125+
*
126+
* @param cls Class code.
127+
* @param subcls Subclass code.
128+
* @param proto Protocol code.
129+
* @return Pointer to matching device, or NULL if none.
130+
*/
63131
usb_dev_t *usb_core_find_by_class(uint8_t cls, uint8_t subcls, uint8_t proto);
64132

65-
/* Simple iterator over all devices (index 0..n-1). Returns NULL when out of range. */
133+
/**
134+
* @brief Get device by index.
135+
*
136+
* @param index Zero-based index of enumerated device.
137+
* @return Pointer to device or NULL if out of range.
138+
*/
66139
usb_dev_t *usb_core_get_index(size_t index);
67140

68-
/* Count of currently registered devices. */
141+
/**
142+
* @brief Count the number of currently registered devices.
143+
* @return Device count.
144+
*/
69145
size_t usb_core_device_count(void);
70146

71-
/* Optional: textual dump for debugging. */
147+
/**
148+
* @brief Dump current USB devices and class drivers to log.
149+
*/
72150
void usb_core_dump(void);
73151

74-
void usb_core_init(void);
152+
/**
153+
* @brief Initialise USB core subsystem (class driver registry etc).
154+
*/
155+
void usb_core_init(void);
156+
157+
/**
158+
* @brief Re-scan all enumerated devices against the registered class drivers.
159+
*
160+
* This function replays class-driver binding for any devices that were
161+
* previously enumerated but not yet delivered to a matching driver.
162+
* It is typically called after a new class driver is registered
163+
* (e.g. usb_hid_init) so that existing devices can be bound
164+
* without requiring re-enumeration at the hardware level.
165+
*
166+
* Devices already marked as bound are skipped, so drivers will not
167+
* receive duplicate add-notifications.
168+
*/
169+
void usb_core_rescan(void);

include/usb_hid.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,21 @@
44
#include "usb_core.h"
55
#include "usb_xhci.h"
66

7+
/** @brief HID Boot Interface Subclass code. */
78
#define USB_SUBCLASS_BOOT 0x01
9+
/** @brief HID Boot Protocol code for keyboards. */
810
#define USB_PROTO_KEYBOARD 0x01
911

12+
/** @brief USB HID 'boot' protocol */
13+
#define HID_PROTO_BOOT 0x0000
14+
15+
/** @brief USB HID 'report' protocol */
16+
#define HID_PROTO_REPORT 0x0001
17+
18+
/**
19+
* @brief Initialise the HID class driver.
20+
*
21+
* Registers HID class ops with the USB core.
22+
* Currently implements Boot Keyboard support only.
23+
*/
1024
void usb_hid_init(void);

0 commit comments

Comments
 (0)