/** Copyright 2007 Haiku Inc. All rights reserved.* Distributed under the terms of the MIT License.** Authors:* Niels Sascha Reedijk, niels.reedijk@gmail.com*//*!\page usb_modules Writing drivers for USB devicesThe introduction of USB standardized the way many devices connected to awhole range of different computers and operating systems. It introduced astandard that was capable of getting rid of all the legacy systems, such asthe LPT, the PS/2 and serial ports. The plug and play nature of the standardwas revolutionary at the time of its introduction, and it changed the waywhich operating systems interacted with devices.With the grand standard that USB has become, Haiku has an implementationof it. It supports both the USB 1.1 and USB 2.0 specifications, and whenHaiku R1 is released, it will support the three host controller standards:UHCI, OHCI and EHCI. The modularized design of Haiku's USB stack also pavesthe way for easy implementation of any future specifications, such asWireless USB.\section usb_modules_scope The Scope of this DocumentThis document is written for driver developers that need to interact withUSB devices. The USB specification standardizes the communication betweenthe host controller and the devices, and how devices should transfer data,but it does not prescribe a standard environment that Operating Systemsshould provide to the driver interfaces. As such, every operating system hasits own interface for drivers, and so does Haiku.This document will point driver developers to relevant parts of the USBmodule API and give a general impression of the workings of the USB stack.This document will not give information on the basics of writing drivers, oron how to use modules. Have a look elsewhere in this documentation for that.This document also assumes a basic knowledge of the USB specification, and onhow you are supposed to interact with devices. See \ref usb_modules_resourcesfor tutorials on the web if you are looking for a basic introduction oncommunication with the USB protocol.\section usb_modules_structure Structure of the StackThis section will outline how Haiku's USB stack is structured, and how youcan interact with this stack.The goal of the USB stack is to provide a few basic features for driversinteracting with USB devices. It is important that the stack maintains acontinually updated device grid, so that the driver modules are alwaysaware of the latest status. The stack should also facilitate communicationbetween drivers and the devices, by abstracting the actual transferring ofbits via the host controller hardware in the computer. The stack thereforeshould implement a intuitive interface to give driver developers access toall features and possibilities the USB specification offers, and at the sametime it should abstract many of the small requirements and peculiarities ofthat specification.The stack internally can be divided into two parts. The first part is thecore module. This module, called \c usb_busmanager, performs all theoperations required by the USB specification. For example, it performs thenecessary low-level initialization when new devices are connected, or all therequirements when it comes to performing transfers. The core module alsois the module that provides the abstractions to driver developers. The otherpart of the USB stack are the individual modules that control the differenthost controllers. Haiku supports the three types in existence: UHCI, OHCIand EHCI. These modules perform the communication between the core moduleand the hardware. As driver developer, you won't have to interact with thesemodules: the core module provides all the abstractions you need.Thus, as a driver developer you are interfacing with the \c usb_busmanagermodule. On Haiku, this module implements two API's. The \c v2 API, identicalto the API offered by BeOS R5, can be found in the \c USB2.h file. However,for new drivers, or for ports, the recommended API is the \c v3 API, definedin the USB3.h file. This API is identical to the one provided by Zeta. The\c v2 API should be considered to be deprecated.\section usb_modules_registration Initial Steps: Driver RegistrationIn order to be able to start using the USB stack to communicate with yourdevices, you will need to perform some actions. This section will outlinethose actions and will point you to their appropriate locations.\note The code examples are based on the \c usb_hid driver written byJerome Duval. Have a look at this driver for a complete workingexample.The following example gives an overview of the requirements to open theUSB module, and to start your driver registration in order to receiveconnect and disconnect events.\code// Global variables and constantsusb_module_info *gUsb;const char *kDriverName = "usb_hid";static usb_support_descriptor sSupportedDevices[1] = {{ USB_HID_DEVICE_CLASS, 0, 0, 0, 0 },};// Prototype for the hooks that are called when devices are added or removedstatic status_t hid_device_added(const usb_device *dev, void **cookie);static status_t hid_device_removed(void *cookie);static usb_notify_hooks sNotifyHooks = {hid_device_added,hid_device_removed};// Driver initialization, called by the kernel when the driver is loadedstatus_tinit_driver(void){if (get_module(B_USB_MODULE_NAME, (module_info **)&gUsb) != B_OK)return B_ERROR;gUsb->register_driver(kDriverName, sSupportedDevices,1, NULL);gUsb->install_notify(kDriverName, &sNotifyHooks);return B_OK;}\endcodeBasically, this boils down to three steps. The first step is to acquire theusb_module_info module. This struct contains a set of function pointers thatyou use to communicate with the stack. You can retrieve it like you wouldretrieve any other module.As soon as you have done that you can start registering your driver in thestack. What you do is you pass a unique identifier to identify your driver,zero or more \link usb_support_descriptor support descriptors \endlinkto provide the stack with information on which devices you support, and thenumber of support descriptors you provided. The stack is very flexible withwhat patterns it accepts, so even the most complex driver will be able topass its credentials. Have a look at the \c usb_support_descriptor structand the \c usb_module_info::register_driver() call for all the details.The last step in initialization is to provide the stack with notificationhooks. These are functions in your driver that the stack should call as soonas a device is attached or removed. Please perform this call after yourinternal driver data structures are initialized, because as soon as youperform this call, the usb stack will start searching for already attacheddevices that match the credentials. Have a look at\c usb_module_info::install_notify() and the structure \c usb_notify_hooksfor the details on the signatures of your hooks.\section usb_modules_changes Handling Device ChangesThe USB stack will notify you of device connects and disconnects when theyoccur. You will receive notifications as soon as you have supplied the hooksto the stack, using \c usb_module_info::install_notify() . This section willexplain some of the details when it comes to handling device changes.When a device is added, your supplied usb_notify_hooks::device_added() hookwill be called if its credentials matches one of your support descriptors.Because the stack runs through all the registered drivers, it could be thattwo or more drivers operate on the same device. The stack does not providea locking mechanism to prevent two conflicting drivers to get in each othersway. It is up to the device maker to have supplied such a mechanism.\note In reality, it is very likely that your device will match at least oneother driver, because Haiku supplies the \c usb_raw driver. This driverprovides userland access to the usb devices and therefore it has a blanksupport descriptor that matches everything. The \c usb_raw driver willnot conflict with your device interaction though (except when there is anuserland application that tries to meddle with your device).If your driver is willing to accept the supplied device, and yourdevice_added() hook returns B_OK, the USB stack will ask the kernel to reloadyour published devices, so that your device is visible in userspace in the\c /dev tree.The other event that the stack reports, device disconnection, should behandled by your \c usb_notify_hooks::device_removed() hook. Because "plug andplay" also means "unplug and leave", you should make sure your driver iscapable of cleaning up in the likely event that the user removes theirdevice, even during transfers. In your hook function, you have the ability todo clean up whatever there is to clean up, however, make sure that you cancelall the pending transfers. Use the usb_module_info::cancel_queued_transfers()call for that end. Also, don't forget to free the cookie you supplied in yourdevice_added() hook.\section usb_modules_standard Standard USB OperationsOne of the many conveniences of the Haiku USB API is the fact that many ofthe standard operations can be performed by simple function calls. As such,you won't have to build many of the standard requests the USB specificationdefines by hand. This section will outline all the different conveniences andwill point you to where to look if you do need something more advanced.\subsection usb_modules_standard_descriptors Configurations, Interfaces and DescriptorsMany standard USB operations have to do with configurations, interfaces anddescriptors. All these operations are accessible by convenience functions.The device descriptor is one of the first things you will be interested in ifyou want to check out a device. The device descriptor can be retrieved quiteeasily using the \c usb_module_info::get_device_descriptor() call. Theretrieved descriptor complies to the one dictated by the USB standard.Also important are configurations. Since every device has at least oneconfiguration, you should be able to retrieve and manipulate configurations.You can use \c usb_module_info::get_nth_configuration() to get them. To seta configuration, you should use \c usb_module_info::set_configuration(). Toget the active configuration, use \c usb_module_info::get_configuration().\attention By default, Haiku's stack will set the configuration at offsetzero, which is according to the standard, the default configuration.Do not rely on that if you first get the device, that the currently activeconfiguration is the default configuration though. Another driver mighthave manipulated this device already.Every configuration has associated interfaces. To make life easier, the stackautomatically gets the interface descriptors (and their associatedendpoints), and stores them in the \c usb_configuration_info structure. Thisstructure has a member called \link usb_configuration_info::interface\c interface \endlink which is of the type \c usb_interface_list. That objectcontaints all the interfaces, including a pointer to the interface that iscurrently active. Each interface is described as a \c usb_interface_info,which is a container for the interface, its associated endpoints and anyunparsed descriptors. In order to change the active interface, you can usethe stack's \c usb_module_info::set_alt_interface() call.Endpoints, the basic units with which you can communicate, are stored as\c usb_endpoint_info structures. Each of these structures carries the actualendpoint descriptor, and the accompanying usb_pipe handle that you can use toactually send and receive data.The last point of interest are descriptors. As you have seen, Haiku cachesall the relevant descriptors itself, however, you might want to retrieve anyother type of descriptor that could be relevant for your device. Theconvenience function to use in such a case is the\c usb_module_info::get_descriptor() call. This function takes all theparameters needed to build the actual descriptor, and performs the requestover the default control pipe.\subsection usb_modules_standard_features FeaturesAnother one of the building blocks of USB are features. Every device shouldprovide for a number of standard features, but the USB specification alsoleaves the option to using custom device specific features. Feature requestscan be performed on devices, interfaces and pipes (which are tied toendpoints).To set a feature, you can use the \c usb_module_info::set_feature() call. Toclear a feature, use the \c usb_module_info::clear_feature() call. One of themost used feature calls is the call to clear a \c USB_FEATURE_ENDPOINT_HALT .\subsection usb_modules_standard_other Other Standard CallsTo get the status of a device, an interface or an endpoint, you can use the\c usb_module_info::get_status() call.If you are using isochronous transfers, you can use the\c usb_module_info::set_pipe_policy() to set the properties of theisochronous pipe.\section usb_modules_transfers Data TransfersTransfering data is one of the basic building blocks of the USB protocol.This section will demonstrate how to perform transfers via the four differentprotocols the USB stack offers.But first it is essential to show how to perform the transfers using the\c usb_module_info interface. The interface provides five \c queue_*functions, with the asterix being one of the following: \c bulk, \c bulk_v(bulk transfers using a vector), \c interrupt, \c isochronous or \c request(over the standard control pipe). These five functions work asynchronously,which means that your driver is called back from a different thread when yourtransfer is finished.The five functions share some arguments. The first argument is always thepipe that is associated with the endpoint (except for control transfers,these only work on the device in general). All of the functions accept a databuffer, and the length of that buffer. All of the functions require a\c #usb_callback_func, a function in your driver that can be called in case atransfer is finished. The functions also require a cookie that is provided tothe callback function.The working order is as follows: first you queue a transfer, then you handlethe result in the callback function when it's done. The callback functionwill be called with a \a status argument, in which you can check whether ornot the transfer actually succeeded. See this \link #usb_callback_funcdescription \endlink for how your callback function should behave and whatkind of status there might have been.Finally, before going into the different transfer types, a note on bufferownership. The usb stack keeps the internal buffers tidy, but the buffer youprovide to the \c queue_* functions are yours. You are responsible forallocating and freeing them, and you may do with them whatever you like,\e except between queueing your transfer and the callback. During that periodyou should consider the USB stack the owner of the buffer.\subsection usb_modules_transfers_control Control RequestsControl requests are done over the device wide control pipe which is providedby every device. Haiku's stack has two functions that you can use to performcustom requests (opposed to many of the \ref usb_modules_standard"standard operations"). Control transfers are the only transfers that you canperform synchronously as well as asynchronously. The functions you can useare \c usb_module_info::send_request() for synchronous requests and\c usb_module_info::queue_request() for asynchronous requests.Many of the constants that you should use when performing can be found inthe USB_spec.h file which is automatically included if you include the mainUSB header. Have a look of how to use these constants in the followingexample:\code// Send a request that is defined by the standard of this class. We retrieve// a report from the device on one of its interfaces.// This request is specified by the HID specification.status = usb->send_request(dev,USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_CLASS,USB_REQUEST_HID_GET_REPORT, 0x0100 | report_id,interfaceNumber, device->total_report_size,device->buffer, &actual);\endcode\warning Both the \link usb_module_info::send_request() \a send_request()\endlink and \link usb_module_info::queue_request() \a queue_request()\endlink functions can be used to perform standard usb requests. Avoidlow-level operations, because the stack needs to keep its internaldata structures consistent. If you need to perform one of the\ref usb_modules_standard "standard operations", use the providedconvenience functions.\subsection usb_modules_transfers_interrupt InterruptInterrupt transfers apply to endpoints that receive data, or that can bepolled in several instances of time. The intervals are determined by theendpoint descriptor.To schedule a transfer, use usb_module_info::queue_interrupt(). You only haveto supply a buffer, the stack schedule the transfer in such a way that itwill be performed within a certain timeframe. To create a continuousinterrupt system, you should queue the next transfer in the callback functionof the previous. The stack will make sure that the new transfer will beperformed exactly after the required interval.\subsection usb_modules_transfers_bulk BulkBulk transfers are very similar to control transfers. They will be performedas soon as possible without stalling other transfers, and they transfer data.Bulk transfers are designed to transfer up to large amounts of data asefficiently as possible. Performing bulk transfers isn't difficult, youmerely supply a buffer and the endpoint that should execute the request, andyou're set.Bulk transfers come in two flavours. The first isusb_module_info::queue_bulk(), which takes a standard data buffer. The secondflavour is the usb_module_info::queue_bulk_v() function, which is designed tooperate on (an array of) POSIX vectors. These functions only differ in thebuffer they accept, they function in exactly the same way.\subsection usb_modules_transfers_isochronous IsochronousIsochronous transfers are not implemented on Haiku yet. As soon as they are,this section should contain information on how to queue them.\section usb_modules_cleanup Cleaning UpThis section describes how to gracefully leave the stack after your driver isrequested to shut down.There are truely only two simple actions to perform. The first is touninstall your notification hooks, using\c usb_module_info::uninstall_notify(). The second action is to 'put' themodule.\codevoiduninit_driver(void){usb->uninstall_notify(kDriverName);put_module(B_USB_MODULE_NAME);}\endcode\section usb_modules_resources More ResourcesThis section should list more resources on the web.*/