The RISC OS 5 USB stack consists of the following software components: * The *USBDriver* module, which implements the core of the stack. It also provides USB keyboard, hub, and mouse support, along with the DeviceFS interface that external programs must use to communicate with USB devices * The *EHCIDriver* module, which is a driver for USB controllers which comply with the _Enhanced Host Controller Interface_ specification. EHCI controllers support USB 2. * The *OHCIDriver* module, which is a driver for USB controllers which comply with the _Open Host Controller Interface_ specification. OHCI controllers only support USB 1. * The *[[MUSBDriver]]* module, which is a driver for the Mentor MUSBMHDRC USB OTG controller. The MUSBMHDRC supports USB2 in both host and peripheral modes, although peripheral-mode support in the current driver is very basic. * The *DWCDriver* module, which is a driver for the Synopsys DWC OTG controller. The DWC supports USB2 in both host and peripheral modes, although peripheral-mode support is currently disabled in the driver as there are now hardware targets which can use it. * The *XHCIDriver* module, which is a driver for USB controllers which comply with the _eXtensible Host Controller Interface_ specification. XHCI controllers support USB 3, though currently the rest of the RISC OS 5 USB stack does not. h2(#code). Source code * USBDriver is built by the "RiscOS/Sources/HWSupport/USB/USBDriver":https://gitlab.riscosopen.org/RiscOS/Sources/HWSupport/USB/USBDriver/ component in gitlab. ** The _build_ folder contains the RISC OS module frontend and makefile, while the _dev_ folder contains the bulk of the mostly unmodified NetBSD code. *** _build.c.usbmodule_ provides the frontend USB module. *** _build.c.port_ is a file that helps bridge the RISC OS and NetBSD worlds. ** _build.c.usbkboard_ and _build.c.usbmouse_ are part of USBDriver and provide RISC OS frontends to NetBSD's USB keyboard & mouse support ** The _machine_ and _sys_ folders contain various headers that are required. ** The code also relies upon various other BSD-derived header files that are supplied by the internet stack ("RiscOS/Sources/Lib/TCPIPLibs":https://gitlab.riscosopen.org/RiscOS/Sources/Lib/TCPIPLibs/) * DWCDriver is built by the "RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver":https://gitlab.riscosopen.org/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver/ component in gitlab. ** The code depends upon header files provided by both the main USB drivers and the TCPIPLibs component. * EHCIDriver is built by the "RiscOS/Sources/HWSupport/USB/Controllers/EHCIDriver":https://gitlab.riscosopen.org/RiscOS/Sources/HWSupport/USB/Controllers/EHCIDriver/ component in gitlab. ** The code depends upon header files provided by both the main USB drivers and the TCPIPLibs component. * MUSBDriver is built by the "RiscOS/Sources/HWSupport/USB/Controllers/MUSBDriver":https://gitlab.riscosopen.org/RiscOS/Sources/HWSupport/USB/Controllers/MUSBDriver/ component in gitlab. ** The code depends upon header files provided by both the main USB drivers and the TCPIPLibs component. * OHCIDriver is built by the "RiscOS/Sources/HWSupport/USB/Controllers/OHCIDriver":https://gitlab.riscosopen.org/RiscOS/Sources/HWSupport/USB/Controllers/OHCIDriver/ component in gitlab. ** The code depends upon header files provided by both the main USB drivers and the TCPIPLibs component. * XHCIDriver is built by the "RiscOS/Sources/HWSupport/USB/Controllers/XHCIDriver":https://gitlab.riscosopen.org/RiscOS/Sources/HWSupport/USB/Controllers/XHCIDriver/ component in gitlab. ** The code depends upon header files provided by both the main USB drivers and the TCPIPLibs component. h3(#debugging). Debugging Debug versions of the modules can be built by adding @DEBUG=TRUE@ to the @-options@ string in the components file. Debug output is handled by the DebugLib library; check each module's initialisation to make sure a suitable output device is in use. The USB modules can produce a large quantity of debug output, often from within interrupt handlers. A device which provides low-latency output and works correctly with interrupts disabled is therefore desirable (e.g. the DADebug module). *Note:* For debugging ROM builds of the modules, as well as adding DADebug to the ROM, you'll need to make sure it's listed in the [[HAL_KbdScanDependencies|keyboard scan dependencies]] (assuming the USB modules are listed there) h4. Debug commands When debugging is enabled, each module provides a few extra *commands. Check the *help text or the CMHG files for details. h4. Debug logging level The debug level can be altered at runtime via *commands, or set at load time by altering the module's initialisation function. Generally speaking, if the debug level is above 10, you can expect to receive a lot of output. h3(#internalapi). Internal API *TODO* - This is probably out of date since the EHCI code was updated to the latest BSD version. The USB hardware drivers register themselves with the main USB module by using the [[USBDriver_RegisterBus]] SWI. The hardware driver supplies the USB module with a pointer to its @usbd_bus@ struct (see NetBSD.dev.usb.h.usbdivar), and the USB module responds with a pointer to its @device@ struct (see NetBSD.sys.h.device; not to be confused with the HAL device struct!) Presently the only purpose the @device@ struct services is to allow the USB modules to deregister themselves with the USB driver on shutdown. All communication from USBDriver to the hardware drivers is done via function pointers contained in the @usbd_bus@ struct, and all communication between the hardware driver and the USBDriver is done via SWI calls. h3(#notes). Notes on specific function calls h4. splusb(), splx() These functions in *.c.port are used by the NetBSD sources to disable & restore interrupts. Note that splusb() is actually #defined to splbio(). h4. tsleep() This function in *.c.port is used by the USB drivers whenever they want to block waiting for an interrupt-triggered event to occur (e.g. completion of a USB transfer) h4. malloc_contig(), free_contig() These functions in *.c.port use the PCI module to allocate & free noncacheable, nonbufferable blocks of memory suitable for use as DMA buffers. The PCI module ensures that only contiguous physical pages are used, greatly simplifying the process of setting up DMA transfers.