⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

veridian_kernel/drivers/usb/
device.rs

1//! USB device types, descriptors, and bus-level device management
2//!
3//! Contains USB device representations, descriptor structures, and the
4//! [`UsbBus`] implementation that manages device enumeration and the
5//! [`Bus`] trait for integration with the driver framework.
6
7use alloc::{boxed::Box, collections::BTreeMap, format, string::String, vec, vec::Vec};
8
9use spin::RwLock;
10
11use super::{host::UsbHostController, transfer::UsbTransfer};
12use crate::{
13    error::KernelError,
14    services::driver_framework::{Bus, DeviceClass, DeviceId, DeviceInfo, DeviceStatus},
15};
16
17/// USB device speeds
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub enum UsbSpeed {
20    Low,       // 1.5 Mbps
21    Full,      // 12 Mbps
22    High,      // 480 Mbps
23    Super,     // 5 Gbps
24    SuperPlus, // 10 Gbps
25}
26
27/// USB device classes
28#[allow(dead_code)] // Hardware constants per USB specification
29pub mod usb_classes {
30    pub const AUDIO: u8 = 0x01;
31    pub const CDC: u8 = 0x02; // Communications and CDC Control
32    pub const HID: u8 = 0x03; // Human Interface Device
33    pub const PHYSICAL: u8 = 0x05; // Physical
34    pub const IMAGE: u8 = 0x06; // Image
35    pub const PRINTER: u8 = 0x07; // Printer
36    pub const MASS_STORAGE: u8 = 0x08; // Mass Storage
37    pub const HUB: u8 = 0x09; // Hub
38    pub const CDC_DATA: u8 = 0x0A; // CDC-Data
39    pub const SMART_CARD: u8 = 0x0B; // Smart Card
40    pub const CONTENT_SECURITY: u8 = 0x0D; // Content Security
41    pub const VIDEO: u8 = 0x0E; // Video
42    pub const HEALTHCARE: u8 = 0x0F; // Personal Healthcare
43    pub const DIAGNOSTIC: u8 = 0xDC; // Diagnostic Device
44    pub const WIRELESS: u8 = 0xE0; // Wireless Controller
45    pub const MISC: u8 = 0xEF; // Miscellaneous
46    pub const APP_SPECIFIC: u8 = 0xFE; // Application Specific
47    pub const VENDOR_SPECIFIC: u8 = 0xFF; // Vendor Specific
48}
49
50/// USB endpoint types
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub enum UsbEndpointType {
53    Control = 0,
54    Isochronous = 1,
55    Bulk = 2,
56    Interrupt = 3,
57}
58
59/// USB endpoint direction
60#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61pub enum UsbDirection {
62    Out = 0,
63    In = 1,
64}
65
66/// USB endpoint descriptor
67#[derive(Debug, Clone)]
68pub struct UsbEndpoint {
69    pub address: u8,
70    pub direction: UsbDirection,
71    pub endpoint_type: UsbEndpointType,
72    pub max_packet_size: u16,
73    pub interval: u8,
74}
75
76impl UsbEndpoint {
77    pub fn new(address: u8) -> Self {
78        Self {
79            address: address & 0x7F,
80            direction: if address & 0x80 != 0 {
81                UsbDirection::In
82            } else {
83                UsbDirection::Out
84            },
85            endpoint_type: UsbEndpointType::Control,
86            max_packet_size: 8,
87            interval: 0,
88        }
89    }
90}
91
92/// USB interface descriptor
93#[derive(Debug, Clone)]
94pub struct UsbInterface {
95    pub number: u8,
96    pub alternate_setting: u8,
97    pub class: u8,
98    pub subclass: u8,
99    pub protocol: u8,
100    pub endpoints: Vec<UsbEndpoint>,
101}
102
103/// USB configuration descriptor
104#[derive(Debug, Clone)]
105pub struct UsbConfiguration {
106    pub value: u8,
107    pub max_power: u16, // in mA
108    pub self_powered: bool,
109    pub remote_wakeup: bool,
110    pub interfaces: Vec<UsbInterface>,
111}
112
113/// USB device descriptor
114#[derive(Debug, Clone)]
115pub struct UsbDeviceDescriptor {
116    pub vendor_id: u16,
117    pub product_id: u16,
118    pub device_release: u16,
119    pub class: u8,
120    pub subclass: u8,
121    pub protocol: u8,
122    pub max_packet_size: u8,
123    pub manufacturer: String,
124    pub product: String,
125    pub serial_number: String,
126    pub configurations: Vec<UsbConfiguration>,
127}
128
129/// USB device representation
130#[derive(Debug, Clone)]
131pub struct UsbDevice {
132    pub address: u8,
133    pub port: u8,
134    pub speed: UsbSpeed,
135    pub descriptor: UsbDeviceDescriptor,
136    pub current_configuration: Option<u8>,
137    pub connected: bool,
138}
139
140impl UsbDevice {
141    /// Create a new USB device
142    pub fn new(address: u8, port: u8, speed: UsbSpeed) -> Self {
143        Self {
144            address,
145            port,
146            speed,
147            descriptor: UsbDeviceDescriptor {
148                vendor_id: 0,
149                product_id: 0,
150                device_release: 0,
151                class: 0,
152                subclass: 0,
153                protocol: 0,
154                max_packet_size: 8,
155                manufacturer: String::new(),
156                product: String::new(),
157                serial_number: String::new(),
158                configurations: Vec::new(),
159            },
160            current_configuration: None,
161            connected: false,
162        }
163    }
164
165    /// Get device class
166    pub fn get_device_class(&self) -> DeviceClass {
167        match self.descriptor.class {
168            usb_classes::AUDIO => DeviceClass::Audio,
169            usb_classes::HID => DeviceClass::Input,
170            usb_classes::MASS_STORAGE => DeviceClass::Storage,
171            usb_classes::HUB => DeviceClass::USB,
172            usb_classes::VIDEO => DeviceClass::Display,
173            usb_classes::CDC | usb_classes::CDC_DATA => DeviceClass::Network,
174            _ => DeviceClass::Other,
175        }
176    }
177}
178
179/// USB port status
180#[derive(Debug, Clone, Copy)]
181pub struct UsbPortStatus {
182    pub connected: bool,
183    pub enabled: bool,
184    pub suspended: bool,
185    pub reset: bool,
186    pub speed: UsbSpeed,
187    pub power: bool,
188}
189
190/// USB bus implementation
191pub struct UsbBus {
192    /// Host controllers
193    controllers: RwLock<Vec<Box<dyn UsbHostController>>>,
194
195    /// Connected devices
196    devices: RwLock<BTreeMap<u8, UsbDevice>>, // address -> device
197
198    /// Next device address
199    next_address: core::sync::atomic::AtomicU8,
200
201    /// Port to device mapping
202    port_devices: RwLock<BTreeMap<(usize, u8), u8>>, // (controller_index, port) -> address
203}
204
205impl Default for UsbBus {
206    fn default() -> Self {
207        Self::new()
208    }
209}
210
211impl UsbBus {
212    /// Create a new USB bus
213    pub fn new() -> Self {
214        Self {
215            controllers: RwLock::new(Vec::new()),
216            devices: RwLock::new(BTreeMap::new()),
217            next_address: core::sync::atomic::AtomicU8::new(1),
218            port_devices: RwLock::new(BTreeMap::new()),
219        }
220    }
221
222    /// Add a host controller
223    pub fn add_controller(
224        &self,
225        mut controller: Box<dyn UsbHostController>,
226    ) -> Result<(), KernelError> {
227        // Initialize the controller
228        controller.init()?;
229
230        let _controller_name: String = controller.name().into();
231        let controller_index = self.controllers.read().len();
232
233        // Scan ports for devices
234        let _port_count = controller.get_port_count();
235        crate::println!(
236            "[USB] Controller {} has {} ports",
237            _controller_name,
238            _port_count
239        );
240
241        self.controllers.write().push(controller);
242
243        // Scan for connected devices
244        self.scan_controller_ports(controller_index)?;
245
246        crate::println!("[USB] Added USB host controller: {}", _controller_name);
247        Ok(())
248    }
249
250    /// Scan controller ports for devices
251    fn scan_controller_ports(&self, controller_index: usize) -> Result<(), KernelError> {
252        let port_count = {
253            let controllers = self.controllers.read();
254            controllers
255                .get(controller_index)
256                .ok_or(KernelError::NotFound {
257                    resource: "usb controller",
258                    id: controller_index as u64,
259                })?
260                .get_port_count()
261        };
262
263        for port in 1..=port_count {
264            if let Err(_e) = self.scan_port(controller_index, port) {
265                crate::println!("[USB] Failed to scan port {}: {}", port, _e);
266            }
267        }
268
269        Ok(())
270    }
271
272    /// Scan a specific port
273    fn scan_port(&self, controller_index: usize, port: u8) -> Result<(), KernelError> {
274        let status = {
275            let controllers = self.controllers.read();
276            controllers
277                .get(controller_index)
278                .ok_or(KernelError::NotFound {
279                    resource: "usb controller",
280                    id: controller_index as u64,
281                })?
282                .get_port_status(port)?
283        };
284
285        if !status.connected {
286            return Ok(()); // No device connected
287        }
288
289        crate::println!(
290            "[USB] Device detected on controller {} port {}",
291            controller_index,
292            port
293        );
294
295        // Reset and enable port
296        {
297            let mut controllers = self.controllers.write();
298            let controller =
299                controllers
300                    .get_mut(controller_index)
301                    .ok_or(KernelError::NotFound {
302                        resource: "usb controller",
303                        id: controller_index as u64,
304                    })?;
305
306            controller.reset_port(port)?;
307            controller.enable_port(port)?;
308        }
309
310        // Enumerate device
311        let device_address = self.enumerate_device(controller_index, port, status.speed)?;
312
313        // Store port mapping
314        self.port_devices
315            .write()
316            .insert((controller_index, port), device_address);
317
318        Ok(())
319    }
320
321    /// Enumerate a device
322    fn enumerate_device(
323        &self,
324        controller_index: usize,
325        port: u8,
326        speed: UsbSpeed,
327    ) -> Result<u8, KernelError> {
328        // Allocate device address
329        let device_address = self
330            .next_address
331            .fetch_add(1, core::sync::atomic::Ordering::SeqCst);
332
333        // Create device
334        let mut device = UsbDevice::new(device_address, port, speed);
335
336        // Get device descriptor
337        self.read_device_descriptor(controller_index, 0, &mut device)?;
338
339        // Set device address
340        {
341            let mut controllers = self.controllers.write();
342            let controller =
343                controllers
344                    .get_mut(controller_index)
345                    .ok_or(KernelError::NotFound {
346                        resource: "usb controller",
347                        id: controller_index as u64,
348                    })?;
349
350            controller.set_device_address(0, device_address)?;
351        }
352
353        // Read full device descriptor with new address
354        self.read_device_descriptor(controller_index, device_address, &mut device)?;
355
356        // Read configurations
357        self.read_configurations(controller_index, device_address, &mut device)?;
358
359        device.connected = true;
360
361        crate::println!(
362            "[USB] Enumerated device {:04x}:{:04x} at address {}",
363            device.descriptor.vendor_id,
364            device.descriptor.product_id,
365            device_address
366        );
367
368        // Store device
369        self.devices.write().insert(device_address, device);
370
371        Ok(device_address)
372    }
373
374    /// Read device descriptor
375    fn read_device_descriptor(
376        &self,
377        controller_index: usize,
378        address: u8,
379        device: &mut UsbDevice,
380    ) -> Result<(), KernelError> {
381        let transfer = UsbTransfer::Setup {
382            request_type: 0x80, // Device to host, standard, device
383            request: 0x06,      // GET_DESCRIPTOR
384            value: 0x0100,      // Device descriptor
385            index: 0,
386            data: vec![0; 18], // Device descriptor is 18 bytes
387        };
388
389        let response = {
390            let mut controllers = self.controllers.write();
391            let controller =
392                controllers
393                    .get_mut(controller_index)
394                    .ok_or(KernelError::NotFound {
395                        resource: "usb controller",
396                        id: controller_index as u64,
397                    })?;
398
399            controller.transfer(address, transfer)?
400        };
401
402        if response.len() < 18 {
403            return Err(KernelError::HardwareError {
404                device: "usb",
405                code: 3,
406            });
407        }
408
409        // Parse device descriptor
410        device.descriptor.vendor_id = u16::from_le_bytes([response[8], response[9]]);
411        device.descriptor.product_id = u16::from_le_bytes([response[10], response[11]]);
412        device.descriptor.device_release = u16::from_le_bytes([response[12], response[13]]);
413        device.descriptor.class = response[4];
414        device.descriptor.subclass = response[5];
415        device.descriptor.protocol = response[6];
416        device.descriptor.max_packet_size = response[7];
417
418        // Read string descriptors if available
419        if response[14] != 0 {
420            // Manufacturer string index
421            if let Ok(manufacturer) =
422                self.read_string_descriptor(controller_index, address, response[14])
423            {
424                device.descriptor.manufacturer = manufacturer;
425            }
426        }
427
428        if response[15] != 0 {
429            // Product string index
430            if let Ok(product) =
431                self.read_string_descriptor(controller_index, address, response[15])
432            {
433                device.descriptor.product = product;
434            }
435        }
436
437        if response[16] != 0 {
438            // Serial number string index
439            if let Ok(serial) = self.read_string_descriptor(controller_index, address, response[16])
440            {
441                device.descriptor.serial_number = serial;
442            }
443        }
444
445        Ok(())
446    }
447
448    /// Read string descriptor
449    fn read_string_descriptor(
450        &self,
451        controller_index: usize,
452        address: u8,
453        index: u8,
454    ) -> Result<String, KernelError> {
455        let transfer = UsbTransfer::Setup {
456            request_type: 0x80,
457            request: 0x06,
458            value: 0x0300 | (index as u16),
459            index: 0x0409, // English (US)
460            data: vec![0; 255],
461        };
462
463        let response = {
464            let mut controllers = self.controllers.write();
465            let controller =
466                controllers
467                    .get_mut(controller_index)
468                    .ok_or(KernelError::NotFound {
469                        resource: "usb controller",
470                        id: controller_index as u64,
471                    })?;
472
473            controller.transfer(address, transfer)?
474        };
475
476        if response.len() < 2 {
477            return Err(KernelError::HardwareError {
478                device: "usb",
479                code: 4,
480            });
481        }
482
483        let length = response[0] as usize;
484        if length < 2 || response[1] != 0x03 {
485            return Err(KernelError::HardwareError {
486                device: "usb",
487                code: 5,
488            });
489        }
490
491        // Convert UTF-16LE to UTF-8
492        let mut result = String::new();
493        for i in (2..length.min(response.len())).step_by(2) {
494            if i + 1 < response.len() {
495                let code_unit = u16::from_le_bytes([response[i], response[i + 1]]);
496                if let Some(ch) = char::from_u32(code_unit as u32) {
497                    result.push(ch);
498                }
499            }
500        }
501
502        Ok(result)
503    }
504
505    /// Read configurations
506    fn read_configurations(
507        &self,
508        _controller_index: usize,
509        _address: u8,
510        device: &mut UsbDevice,
511    ) -> Result<(), KernelError> {
512        // For now, just create a default configuration
513        let config = UsbConfiguration {
514            value: 1,
515            max_power: 100, // 100 mA
516            self_powered: false,
517            remote_wakeup: false,
518            interfaces: Vec::new(),
519        };
520
521        device.descriptor.configurations.push(config);
522        Ok(())
523    }
524
525    /// Get device by address
526    pub fn get_device(&self, address: u8) -> Option<UsbDevice> {
527        self.devices.read().get(&address).cloned()
528    }
529
530    /// Get all devices
531    pub fn get_all_devices(&self) -> Vec<UsbDevice> {
532        self.devices.read().values().cloned().collect()
533    }
534
535    /// Find devices by class
536    pub fn find_devices_by_class(&self, class: u8) -> Vec<UsbDevice> {
537        self.devices
538            .read()
539            .values()
540            .filter(|dev| dev.descriptor.class == class)
541            .cloned()
542            .collect()
543    }
544}
545
546impl Bus for UsbBus {
547    fn name(&self) -> &str {
548        "usb"
549    }
550
551    fn scan(&mut self) -> Vec<DeviceInfo> {
552        let devices = self.devices.read();
553        let mut device_infos = Vec::new();
554
555        for (address, usb_device) in devices.iter() {
556            let device_id = DeviceId {
557                vendor_id: usb_device.descriptor.vendor_id,
558                device_id: usb_device.descriptor.product_id,
559                class_code: usb_device.descriptor.class,
560                subclass: usb_device.descriptor.subclass,
561                prog_if: usb_device.descriptor.protocol,
562                revision: (usb_device.descriptor.device_release & 0xFF) as u8,
563            };
564
565            let device_info = DeviceInfo {
566                id: *address as u64,
567                name: if !usb_device.descriptor.product.is_empty() {
568                    usb_device.descriptor.product.clone()
569                } else {
570                    format!(
571                        "USB Device {:04x}:{:04x}",
572                        usb_device.descriptor.vendor_id, usb_device.descriptor.product_id
573                    )
574                },
575                class: usb_device.get_device_class(),
576                device_id: Some(device_id),
577                driver: None,
578                bus: String::from("usb"),
579                address: *address as u64,
580                irq: None, // USB devices use the host controller's IRQ
581                dma_channels: Vec::new(),
582                io_ports: Vec::new(),
583                memory_regions: Vec::new(),
584                status: if usb_device.connected {
585                    DeviceStatus::Uninitialized
586                } else {
587                    DeviceStatus::Removed
588                },
589            };
590
591            device_infos.push(device_info);
592        }
593
594        device_infos
595    }
596
597    fn read_config(
598        &self,
599        _device: &DeviceInfo,
600        _offset: u16,
601        _size: u8,
602    ) -> Result<u32, KernelError> {
603        // USB devices don't have traditional config space
604        // This could be used for reading descriptors
605        Err(KernelError::OperationNotSupported {
606            operation: "config space read on USB device",
607        })
608    }
609
610    fn write_config(
611        &mut self,
612        _device: &DeviceInfo,
613        _offset: u16,
614        _value: u32,
615        _size: u8,
616    ) -> Result<(), KernelError> {
617        // USB devices don't have traditional config space
618        Err(KernelError::OperationNotSupported {
619            operation: "config space write on USB device",
620        })
621    }
622
623    fn enable_device(&mut self, device: &DeviceInfo) -> Result<(), KernelError> {
624        let address = device.address as u8;
625
626        if let Some(usb_device) = self.devices.write().get_mut(&address) {
627            // Set configuration 1 if available
628            if !usb_device.descriptor.configurations.is_empty() {
629                usb_device.current_configuration = Some(1);
630                crate::println!("[USB] Enabled device at address {}", address);
631            }
632        }
633
634        Ok(())
635    }
636
637    fn disable_device(&mut self, device: &DeviceInfo) -> Result<(), KernelError> {
638        let address = device.address as u8;
639
640        if let Some(usb_device) = self.devices.write().get_mut(&address) {
641            usb_device.current_configuration = None;
642            crate::println!("[USB] Disabled device at address {}", address);
643        }
644
645        Ok(())
646    }
647}