# Aros/Developer/USBDriversDev

* Navbar for the Aros wikibook
* Aros User
* Aros User Docs
* Aros User FAQs
* Aros User Applications
* Aros User DOS Shell
* Aros/User/AmigaLegacy
* Aros Dev Docs
* Aros Developer Docs
* Porting Software from AmigaOS/SDL
* For Zune Beginners
* Zune .MUI Classes
* For SDL Beginners
* Aros Developer BuildSystem
* Specific platforms
* Aros x86 Complete System HCL
* Aros x86 Audio/Video Support
* Aros x86 Network Support
* Aros Intel AMD x86 Installing
* Aros Storage Support IDE SATA etc
* Aros Poseidon USB Support
* x86-64 Support
* Motorola 68k Amiga Support
* Linux and FreeBSD Support
* Windows Mingw and MacOSX Support
* Android Support
* Arm Raspberry Pi Support
* PPC Power Architecture
* misc
* Aros Public License

## Introduction

For coding a driver you first need to understand Exec signals, messages, iorequests and lists.
For a driver (device normally) there are only a few "functions" DoIO, SendIO etc. The details are in the IO request fields. Take a look at the VUSBHCI driver. There's no hw stuff, only high level code for Poseidon driver and libusb.
VUSBHCI is also much more readable as everything is in plain sight in structures. You will recognize usb spec things in it and how things are passed around.
Poseidon is the main USB code, it doesn't know by itself anything about the hardware. Driver code is attached to it. Poseidon takes care of all the preferences, classes and drivers. Drivers only try to satisfy higher level requests from Poseidon or it's classes more specifically.
Every driver has to have a roothub as per usb spec. Roothub represents your hw. Roothub has ports, these are the physical ports that the host controller has (doesn't have to be... You could also implement a virtual port and have virtual devices attach)
hub.class calls your roothub and your driver has to respond to roothub requests. It's all in the usb specs. Poseidon doesn't yet know anything about usb 3.x requests. Driver also responds to requests to the physical device and conveys messages between the host and device.
EHCI host controller has to have it's companion controller on corresponding PCI slot otherwise it doesn't know which port is it's companion port and can't release it's port (it needs to know beforehand if that port has a companion port...). On poseidon there's just one PCIUSB driver and all those hosts are on a single driver and some quirks are used for the port forwarding but they doesn't need to be on the same driver. The chipset is able to detect when a port is released and the companion host controller will automaticly take over the port.
The current AROS XHCI driver code can find the USB3 and USB2 ports from the host controller and create a port list for them as well corresponding roothubs. On some motherboards the XHCI might only have USB3 ports on it's controller and a real EHCI chip and the usb data lines are directed via a digital MUX.
The function BOOL PCIXHCI_FindPorts(struct PCIXHCIUnit *unit) from pcixhci_controller.c should be able to detect the usb3.0 and usb2.0 ports from the XHCI controller.
* suggested to use his sata driver's slab memory allocator. Memory allocations are bad in XHCI. That is one issue.
* coded the init routine such that it uses PCI INT (event handler 0 only) With PCI-X other event rings can also be used.
* removal of huge switch statement and adding all the usb3 commands (not all of them are needed at start) and coding the hubss.class to use them.
* the hardware ring buffers need to be implemented correctly.
The driver needs to present two units per controller if the XHCI has both usb3 and usb2 ports. That's because we need to give Poseidon the correct roothub (hub or hubss) and one driver unit can only present one roothub per unit. There's already code present in the VUSBHCI to sort of implement this but there's no code for the usb3 part. Higher level usb3 code can be coded with the VUSBHCI driver even before we have a native XHCI driver via the said hosted driver.
One benefit would be that we should get ISOC transfers as the XHCI takes care of lining them up and there's no need to make an scheduler for the different packets.

## Hosted

These are the steps needed to get hosted usb "working"
* build the hosted version of AROS (It now needs to be build with --enable_usb30_code)
* cd into the build directory
* issue make kernel-usb (if it doesn't build everything then just make the rest)
* issue make kernel-usb-vusbhci
* issue make kernel-fs-fat (if intending to use fat usb sticks)
* issue make kernel-partition (otherwise AROS will crash as it tries to use the partition.library, bug? it should know it hasn't opened it)
* issue make kernel-usb-classes-hubss
Some Linux distribution do not allow the user to access usb devices, so a rule may need to be added in /etc/udev/rules.d
And saved it as "49-all-usb-devices.rules"
* Start hosted AROS and go to prefs and open Trident.
* Go to "Controllers" and press "New" and select "vusbhci.device" as unit number 0. press "Online" and press "Save"
* Go again to "Controllers" and press "New" and select "vusbhci.device", as unit number 1. press "Online" and press "Save"
Unit 0 is now USB2 roothub and unit 1 is USB3 roothub. (hardcoded, the order isn't significant)
Trident needs to be opened everytime you boot into the hosted version of AROS. There's no usbrombootstrap for the hosted version so Trident is used to setup the USB stack.
VUSBHCI.device depends on libusb so it will need the includes for it on Linux side (libusb-dev or something...)
VUSBHCI may output a lot of debug messages at the moment. Those go of course to the console if started from it.
VUSBHCI just means (V)irtual (USB) (H)ost (C)ontroller (I)nterface
There's only one virtual port per virtual host controller (usb2/usb3 (usb3 not implemented yet)). AROS will see the usb device when Trident is started and the device plugged in after. AROS can't take a device already plugged in as the driver uses libusb's plug in event. Linux has already enumerated and reset the device so a bit of hackery is needed on AROS side. VUSHCI driver will not reset the device nor issue it a new address. Otherwise it would confuse Linux. AROS will then own the device and use it as it will.
To start coding for the USB3 (vusbhci.device now doesn't build without it) then AROS build needs to be configured with the "--enable-usb30-code" switch. This will alter the Poseidon USB stack quite a bit to be USB3 aware. There's a lot of work to do to make sure it's solid.

## Classes
### How to create new POSEIDON classes for new hardware

class sources are kept in rom/usb/classes in their own drawers (folders)

#### rndis.class.h
### UVC webcam

Only thing then left to do is to define the uvc api on Aros and code the driver (not like to see v4l(2) on Aros).
Should the uvc.class expose a device or a library? I would like it to expose a library that one can query for attached devices and control the camera(s). It would also need some kind of event handler if some buttons are present on the thing. A device with a fifo like Webcam:cam1 would be nice of course. Leaving all the decoding to ffmpeg or mplayer or whatever... Library is more amiga'ish whilst we can alway write a new webcam tool app with mui using library + lib264.
Proposal for video capturing from web cams:
* Only support web cams and a test pattern. Input only -> webcam.library which one registers different drivers
* webcam.library provides the test pattern itself
On the other hand there is no use for a web cam if its output cannot be tossed around at will. It would need all sort of interfaces and the frame format would also need conversions. MJPEG to RGB etc. Some sort of common video stack is needed.
PS3-eye camera and it uses BULK transfers. Using that camera would be the quickest path capturing video on Aros. PS3 camera has also a extremely high framerate, it could be used for all sort of things like 3D scanning etc. Managed to open the BULK endpoint. Camera outputs YUV and I just write it ARGB on the window. Needs some conversion between. Some artifacts are from the frame header (12 bytes every now and then).
It takes some time until camera shows anything and that's just because I wait for the last frame to arrive before capturing, sometimes it doesn't catch it. Removed uvc header bytes and it all starts to look something recognizable.
There's a sweet spot on the payload size, once you hit it there is no need to sync the frames for raw pixelwrites to rastport.

#### Misc

some or all of the public Poseidon includes are packed with these directives:
Any objections to removing this for ABIv1? in AROS we use native packing where possible.
That would mean code would stop being interchangeable between AROS/OS3/MorphOS/OS4 and would also affect binary compatibility with m68k on PPC. Not a good move IMHO. Perhaps adding some kind of #define or macro to only add the packing if M68K_COMPATIBILITY is enabled would allow better performance in platforms where no m68k transparent emulator would be possible. There's no point in having binary compatibility for USB only. None of the other system structures are packed.
These are raw USB packets. Don't do this, or Poseidon will stop working. MorphOS uses pack(2). Sorry, you're right about the pack(1) instances. However, there are other system structures packed with pack(2), which should be unpacked.