The RISC OS 5 USB stack consists of the following software components:
Rhenium is the codename of one of the projects that Castle/Pace/Tematic worked on. In the context of the main USB drivers, specifying -DRHENIUM
as part of the options line, CFLAGS and CMHGFLAGS (i.e. -options CFLAGS="-DRHENIUM " -DRHENIUM CMHGFLAGS="-DRHENIUM "
) enables code which allows the EHCIDriver and OHCIDriver modules to utilise EHCI & OHCI controllers that are exposed by the HAL USB API (ordinarily, the modules only look for certain PCI devices).
The MUSBDriver module does not need the RHENIUM flag specifying, as it uses the HAL API by default.
Debug versions of the modules can be built by adding the following to the -options
strings:
Module | Options |
---|---|
USBDriver | CDEBUG="-DDEBUGLIB -DUSB_DEBUG -DOHCI_DEBUG -DEHCI_DEBUG" |
EHCIDriver | CDEBUG="-DDEBUGLIB -DUSB_DEBUG -DOHCI_DEBUG -DEHCI_DEBUG" |
OHCIDriver | CDEBUG="-DDEBUGLIB -DUSB_DEBUG -DOHCI_DEBUG -DEHCI_DEBUG" |
OHCIHeaders | CDEBUG="-DDEBUGLIB -DUSB_DEBUG -DOHCI_DEBUG -DEHCI_DEBUG" |
MUSBDriver | COPTIONS="-fn -g -DDEBUGLIB -DMUSB_DEBUG" CDEBUG="-DDEBUGLIB -DMUSB_DEBUG" |
Debug output is handled by the DebugLib library; check the 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 desireable (e.g. the DADebug module).
When debugging is enabled, each module provides a few extra *commands. Check the *help text or the CMHG files for details.
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.
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.
These functions in *.c.port are used by the NetBSD sources to disable & restore interrupts. Note that splusb() is actually #defined to splbio().
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)
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.