From 0d975479fb1d5043a6ba532bd75f7e91ef43525b Mon Sep 17 00:00:00 2001 From: Niels Sascha Reedijk Date: Thu, 17 May 2007 16:08:33 +0000 Subject: [PATCH] First iteration of the documentation that describes how to write drivers that use the USB module. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21162 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- docs/user/drivers/USB3.dox | 1146 +++++++++++++++++------------ docs/user/drivers/usb_modules.dox | 404 +++++++++- 2 files changed, 1055 insertions(+), 495 deletions(-) diff --git a/docs/user/drivers/USB3.dox b/docs/user/drivers/USB3.dox index f19a7efac2..b2f87af0e2 100644 --- a/docs/user/drivers/USB3.dox +++ b/docs/user/drivers/USB3.dox @@ -1,477 +1,669 @@ -/* - * Copyright 2007, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Documentation by: - * Niels Sascha Reedijk - * Corresponds to: - * /trunk/headers/os/drivers/USB3.h rev 19915 - */ - -/*! - \file USB3.h - \ingroup drivers - \brief Interface for the USB module. -*/ - -/*! - \typedef struct usb_module_info usb_module_info - \brief The main interface object. See the usb_module_info documentation. -*/ - -/*! - \typedef uint32 usb_id - \brief Uniquely identify various USB objects that are used in the module. -*/ - -/*! - \typedef usb_id usb_device - \brief Uniquely identify USB devices. -*/ - -/*! - \typedef usb_id usb_interface - \brief Uniquely identify USB interfaces. -*/ - -/*! - \typedef usb_id usb_pipe - \brief Uniquely identify USB pipes. -*/ - -/*! - \typedef struct usb_endpoint_info usb_endpoint_info - \brief Container for USB endpoint descriptors. - \see Documentation for usb_endpoint_info. -*/ - -/*! - \typedef struct usb_interface_info usb_interface_info - \brief Container for USB interface descriptors. - \see Documentation for usb_interface_info. -*/ - -/*! - \typedef usb_interface_list usb_interface_list - \brief Container that holds a list of USB interface descriptors. - \see Documentation for usb_interface_list. -*/ - -/*! - \typedef struct usb_configuration_info usb_configuration_info - \brief Container for USB configuration descriptors. - \see Documentation for usb_configuration_info. -*/ - -///// usb_notify_hooks ///// - -/*! - \struct usb_notify_hooks - \brief Hooks that the USB stack can callback in case of events. -*/ - -/*! - \fn status_t (*usb_notify_hooks::device_added)(usb_device device, void **cookie) - \brief Called by the stack in case a device is added. - - As soon as you have registered hooks using the - usb_module_info::install_notify() method, this hook will be called as soon as - a device is inserted that matches your provided usb_support_descriptor. - - \param device A unique id that identifies this USB device. - \param[in] cookie You can store a pointer to an object in this variable. - When the device is removed, this cookie will be provided to you. - \return You should return \c B_OK in case of success. If you return an error - value, the \a device id will become invalid and you will not be notified if - this device is removed. - \see device_removed() -*/ - -/*! - \var status_t (*usb_notify_hooks::device_removed)(void *cookie) - \brief Called by the stack in case a device you are using is removed. - - If you have accepted a device in the device_added() hook, this hook will - be called as soon as the device is removed. - - \param cookie The cookie you provided in the device_added() hook. Make sure - that you free the cookie, if necessary. - \return Currently the return value of this hook is ignored. It is recommended - to return \c B_OK though. -*/ - -///// usb_support_descriptor ///// - -/*! - \struct usb_support_descriptor - \brief Description of device descriptor that the driver can handle. - - Support descriptors can be used to match any form of class, subclass or - protocol, or a vendor and/or product. If any field has the value \c 0, it - is treated as a wildcard. - - For example, if you want to watch for all the hubs, which have a device - class of \c 0x09, you would pass this descriptor: - - \code - usb_support_descriptor hub_devs = { 9, 0, 0, 0, 0 }; - \endcode - - See usb_module_info::register_driver() for more information on how to use - this object. -*/ - -/*! - \var usb_support_descriptor::dev_class - \brief The supported device classes. -*/ - -/*! - \var usb_support_descriptor::dev_subclass - \brief The suported device subclasses. -*/ - -/*! - \var usb_support_descriptor::dev_protocol - \brief The supported device protocols. -*/ - -/*! - \var usb_support_descriptor::vendor - \brief The supported device vendor. -*/ - -/*! - \var usb_support_descriptor::product - \brief The supported device products. -*/ - -///// usb_endpoint_info ///// - -///// usb_interface_info ///// - -///// usb_interface_list ///// - -///// usb_configuration_info ///// - -///// usb_iso_packet_descriptor ///// - -///// usb_callback_func ///// - -/*! - \typedef typedef void (*usb_callback_func)(void *cookie, status_t status, void *data, size_t actualLength) - \brief Callback function for asynchronous transfers. - - \param cookie The cookie you supplied when you queued the transfer. - \param status The status of the transfer (whether it succeeded or not). - \param data The provided buffer. - \param actualLength The amount of bytes read or written during the transfer. -*/ - -///// usb_module_info ///// - -/*! - \struct usb_module_info - \brief Interface for drivers to interact with Haiku's USB stack. -*/ - -/*! - \var usb_module_info::binfo - \brief Instance of the bus_manager_info object. -*/ - -/*! - \fn status_t (*usb_module_info::register_driver)(const char *driverName, const usb_support_descriptor *supportDescriptors, size_t supportDescriptorCount, const char *optionalRepublishDriverName) - \brief Register your driver. - - To let the USB stack know that a driver is available to support devices, a - driver needs to register itself first. To let the stack know which devices - it needs to notify the driver of, have a look at usb_support_descriptor. - - It is possible to supply a list of support constructors. You should allocate - an array of support constructors, and give the amount of constructors in the - array using the \a supportDescriptorCount parameter. - - In case your driver supports all devices, or more likely, in case you want to - monitor all devices plugged in and removed, it is safe to pass \c NULL to the - \a supportDescriptors paramater and zero (0) to \a supportDescriptorCount. - - \param driverName A unique name that identifies your driver. Avoid names like - \c webcam or \c mouse, instead use vendor names and device types to avoid - nameclashes. The install_notify() and uninstall_notify() functions use the - driver name as an identifier. - \param supportDescriptors An array of the type usb_support_descriptor. Pass - the amount of objects in the next parameter. - \param supportDescriptorCount The number of objects in the array supplied in - the previous parameter. - \param optionalRepublishDriverName Undocumented parameter. It is safe to - pass \c NULL. - \retval B_OK The driver is registered. You can now call install_notify() - \retval B_BAD_VALUE You passed \c NULL as \a driverName. - \retval B_ERROR General internal error in the USB stack. You may retry the - request in this case. - \retval B_NO_MEMORY Error allocating some internal objects. The system is - out of memory. -*/ - -/*! - \fn status_t (*usb_module_info::install_notify)(const char *driverName, const usb_notify_hooks *hooks) - \brief Install notify hooks for your driver. - - After your driver is registered, you need to pass hooks to your driver that - are called whenever a device that matches your \link usb_support_descriptor - support descriptor \endlink . - - As soon as the hooks are installed you'll receive callbacks for devices that - are already attached, so make sure your driver is initialized properly when - calling this method. - - \param driverName The name you passed in register_driver(). - \param hooks The hooks the stack should call in case the status of devices - that match your support descriptor changes. - \retval B_OK Hooks are installed succesfully. - \retval B_NAME_NOT_FOUND Invalid \a driverName. - - \see usb_notify_hooks for information on how your hooks should behave. - \see uninstall_notify() -*/ - -/*! - \fn status_t (*usb_module_info::uninstall_notify)(const char *driverName) - \brief Uninstall notify hooks for your driver. - - If your driver needs to stop, you can uninstall the notifier hooks. This will - clear the stored hooks in the driver and you will not receive any - notifications when new devices are attached. This method will also call - usb_notify_hooks::device_removed() for all the devices that you are using and - all the stack's resources that are allocated to your driver are cleared. - - \param driverName The name you passed in register_driver(). - \retval B_OK Hooks are uninstalled. - \retval B_NAME_NOT_FOUND Invalid \a driverName. -*/ - -/*! - \fn const usb_device_descriptor *(*usb_module_info::get_device_descriptor)(usb_device device) - \brief Get the device descriptor. - - \param device The id of the device you want to query. - \return The standard usb_device_descriptor, or \c NULL in case of an error. -*/ - -/*! - \fn const usb_configuration_info *(*usb_module_info::get_nth_configuration)(usb_device device, uint index) - \brief Get a configuration descriptor by index. - - \param device The id of the device you want to query. - \param index The (zero based) offset of the list of configurations. - \return The usb_configuration_info with the standard usb configuration - descriptor, or \c NULL if the \a id is invalid or the \a index is out of - bounds. -*/ - -/*! - \fn const usb_configuration_info *(*usb_module_info::get_configuration)(usb_device device) - \brief Get the current configuration. - - \param id The id of the device you want to query. - \retval The usb_configuration_info with the standard usb configuration - descriptor, or \c NULL if the \a id is invalid. -*/ - -/*! - \fn status_t (*usb_module_info::set_configuration)(usb_device device, const usb_configuration_info *configuration) - \brief Change the current configuration. - - Changing the configuration will destroy all the current endpoints. If the - \a configuration points to the current configuration, the request will be - ignored and \c B_OK will be returned. - - \param device The id of the device you want to query. - \param configuration The pointer to the new configuration you want to set. - \retval B_OK The new configuration is set succesfully. - \retval B_DEV_INVALID_PIPE The \a device parameter is invalid. - \retval B_BAD_VALUE The configuration does not exist. - - \note This method also allows you to completely unconfigure the device, which - means that all the current endpoints, pipes and transfers will be freed. - Pass \c NULL to the parameter \a configuration if you want to do that. -*/ - -/*! - \fn status_t (*usb_module_info::set_alt_interface)(usb_device device, const usb_interface_info *interface) - \brief Set an alternative interface. Not implemented. - - This method currently always returns \c B_ERROR. -*/ - -/*! - \fn status_t (*usb_module_info::set_feature)(usb_id handle, uint16 selector) - \brief Convenience function for standard control pipe set feature requests. - - Both the set_feature() and clear_feature() requests work on all the Stack's - objects: devices, interfaces and pipes. - - \param handle The object you want to query. - \param selector The value you want to pass in the feature request. - \return \c B_OK in case the request succeeded and the device responded - positively, or an error code in case it failed. -*/ - -/*! - \fn status_t (*usb_module_info::clear_feature)(usb_id handle, uint16 selector) - \brief Convenience function for standard control pipe clear feature requests. - - \see set_feature() to see how this method works. -*/ - -/*! - \fn status_t (*usb_module_info::get_status)(usb_id handle, uint16 *status) - \brief Convenience function for standard usb status requests. - - \param[in] handle The object you want to query. - \param[out] status A variable in which the device can store it's status. - \return \c B_OK in case the request succeeded and the device responded - positively, or an error code in case it failed. -*/ - -/*! - \fn status_t (*usb_module_info::get_descriptor)(usb_device device, uint8 descriptorType, uint8 index, uint16 languageID, void *data, size_t dataLength, size_t *actualLength) - \brief Convenience function to get a descriptor from a device. - - \param[in] device The device you want to query. - \param[in] descriptorType The type of descriptor you are requesting. - \param[in] index In case there are multiple descriptors of this type, you - select which one you want. - \param[in] languageID The language you want the descriptor in (if applicable, - like with string_descriptors). - \param[out] data The buffer in which the descriptor can be written. - \param[in] dataLength The size of the buffer (in bytes). - \param[out] actualLength A pointer to a variable in which the actual number - of bytes written can be stored. - \retval B_OK The request succeeded, and the descriptor is written. - \retval B_DEV_INVALID_PIPE Invalid \a device parameter. - \retval "other errors" Request failed. -*/ - -/*! - \fn status_t (*usb_module_info::send_request)(usb_device device, uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength) - \brief Send a generic, synchronous request over the default control pipe. - - See queue_request() for an asynchronous version of this method. - - Most of the standard values of a request are defined in USB_spec.h. - - \param[in] device The device you want to query. - \param[in] requestType The request type. - \param[in] request The request you want to perform. - \param[in] value The value of the request. - \param[in] index The index for the request. - \param[in] length The size of the buffer pointed by \a data - \param[out] data The buffer where to put the result in. - \param[out] actualLength The actual numbers of bytes written. - - \retval B_OK The request succeeded. - \retval B_DEV_INVALID_PIPE Invalid \a device parameter. - \retval "other errors" Request failed. -*/ - -/*! - \fn status_t (*usb_module_info::queue_interrupt)(usb_pipe pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) - \brief Asynchronously queue an interrupt transfer. - - \param pipe The id of the pipe you want to query. - \param data The data buffer you want to pass. - \param dataLength The size of the data buffer. - \param callback The callback function the stack should call after finishing. - \param callbackCookie A cookie that will be supplied to your callback - function when the transfer is finished. - - \return Whether or not the queueing of the transfer went well. The return - value won't tell you if the transfer actually succeeded. - \retval B_OK The interrupt transfer is queued. - \retval B_NO_MEMORY Error allocating objects. - \retval B_DEV_INVALID_PIPE The \a pipe is invalid. -*/ - -/*! - \fn status_t (*usb_module_info::queue_bulk)(usb_pipe pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) - \brief Asynchronously queue a bulk transfer. - - This method behaves like the queue_interrupt() method, except that it queues - a bulk transfer. -*/ - -/*! - \fn status_t (*usb_module_info::queue_bulk_v)(usb_pipe pipe, iovec *vector, size_t vectorCount, usb_callback_func callback, void *callbackCookie) - \brief Asynchronously queue a bulk vector. - - This method behaves like the queue_interrupt() method, except that it queues - bulk transfers and that it is based on an (array of) io vectors. - - \param vector One or more io vectors. IO vectors are standard POSIX entities. - \param vectorCount The number of elements in the \a vector array. -*/ - -/*! - \fn status_t (*usb_module_info::queue_isochronous)(usb_pipe pipe, void *data, size_t dataLength, usb_iso_packet_descriptor *packetDesc, uint32 packetCount, uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback, void *callbackCookie) - \brief Asynchronously queue a isochronous transfer. Not implemented. - - Not implemented in the current Haiku USB Stack. -*/ - -/*! - \fn status_t (*usb_module_info::queue_request)(usb_device device, uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, usb_callback_func callback, void *callbackCookie) - \brief Asynchronously queue a control pipe request. - - This method does roughly the same as send_request(), however, it works - asynchronously. This means that the method will return as soon as the - transfer is queued. - - \param callback The callback function for when the transfer is done. - \param callbackCookie The cookie that the stack should pass to your callback - function. - \return Whether or not the queueing of the transfer went well. The return - value won't tell you if the transfer actually succeeded. - \retval B_OK The control transfer is queued. - \retval B_NO_MEMORY Error allocating objects. - \retval B_DEV_INVALID_PIPE The \a callback is invalid. -*/ - -/*! - \fn status_t (*usb_module_info::set_pipe_policy)(usb_pipe pipe, uint8 maxNumQueuedPackets, uint16 maxBufferDurationMS, uint16 sampleSize) - \brief Set some pipe features. - - The USB standard specifies some properties that should be able to be set on - isochronous pipes. If your driver requires the properties to be changed, you - should use this method. - - \param pipe The id of the isochronous pipe you want to alter. - \param maxNumQueuedPackets The maximum number of queued packets allowed on - this pipe. - \param maxBufferDurationMS The maximum time in ms that the buffers are valid. - \param sampleSize The size of the samples through this pipe. - \retval B_OK Pipe policy changed. - \retval B_DEV_INVALID_PIPE The \a pipe argument is invalid or not an - isochronous pipe. -*/ - -/*! - \fn status_t (*usb_module_info::cancel_queued_transfers)(usb_pipe pipe) - \brief Cancel pending transfers. Not Implemented. - - Call this method to cancel pending transfers in a \a pipe. - - \warning This is currently not implemented! - - \param pipe The id of the pipe to clear. The method will always return - \c B_ERROR. -*/ - -/*! - \fn status_t (*usb_module_info::usb_ioctl)(uint32 opcode, void *buffer, size_t bufferSize) - \brief Low level commands to the USB stack. - - This method is used to give lowlevel commands to the Stack. There are - currently no uses documented. -*/ +/* + * Copyright 2007, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Documentation by: + * Niels Sascha Reedijk + * Corresponds to: + * /trunk/headers/os/drivers/USB3.h rev 19915 + */ + +/*! + \file USB3.h + \ingroup drivers + \brief Interface for the USB module. +*/ + +/*! + \typedef struct usb_module_info usb_module_info + \brief The main interface object. See the usb_module_info documentation. +*/ + +/*! + \typedef uint32 usb_id + \brief Uniquely identify various USB objects that are used in the module. +*/ + +/*! + \typedef usb_id usb_device + \brief Uniquely identify USB devices. +*/ + +/*! + \typedef usb_id usb_interface + \brief Uniquely identify USB interfaces. +*/ + +/*! + \typedef usb_id usb_pipe + \brief Uniquely identify USB pipes. +*/ + +/*! + \typedef struct usb_endpoint_info usb_endpoint_info + \brief Container for USB endpoint descriptors. + \see Documentation for usb_endpoint_info. +*/ + +/*! + \typedef struct usb_interface_info usb_interface_info + \brief Container for USB interface descriptors. + \see Documentation for usb_interface_info. +*/ + +/*! + \typedef usb_interface_list usb_interface_list + \brief Container that holds a list of USB interface descriptors. + \see Documentation for usb_interface_list. +*/ + +/*! + \typedef struct usb_configuration_info usb_configuration_info + \brief Container for USB configuration descriptors. + \see Documentation for usb_configuration_info. +*/ + +///// usb_notify_hooks ///// + +/*! + \struct usb_notify_hooks + \brief Hooks that the USB stack can callback in case of events. +*/ + +/*! + \fn status_t (*usb_notify_hooks::device_added)(usb_device device, void **cookie) + \brief Called by the stack in case a device is added. + + As soon as you have registered hooks using the + usb_module_info::install_notify() method, this hook will be called as soon as + a device is inserted that matches your provided usb_support_descriptor. + + \param device A unique id that identifies this USB device. + \param[in] cookie You can store a pointer to an object in this variable. + When the device is removed, this cookie will be provided to you. + \return You should return \c B_OK in case of success. The USB stack will then + request the kernel to republish your device names, so that the new device + will be shown in the \c /dev tree. If you return an error value, the + \a device id will become invalid and you will not be notified if this + device is removed. + \see device_removed() +*/ + +/*! + \var status_t (*usb_notify_hooks::device_removed)(void *cookie) + \brief Called by the stack in case a device you are using is removed. + + If you have accepted a device in the device_added() hook, this hook will + be called as soon as the device is removed. + + \param cookie The cookie you provided in the device_added() hook. Make sure + that you free the cookie, if necessary. + \return Currently the return value of this hook is ignored. It is recommended + to return \c B_OK though. +*/ + +///// usb_support_descriptor ///// + +/*! + \struct usb_support_descriptor + \brief Description of device descriptor that the driver can handle. + + Support descriptors can be used to match any form of class, subclass or + protocol, or a vendor and/or product. If any field has the value \c 0, it + is treated as a wildcard. + + For example, if you want to watch for all the hubs, which have a device + class of \c 0x09, you would pass this descriptor: + + \code + usb_support_descriptor hub_devs = { 9, 0, 0, 0, 0 }; + \endcode + + See usb_module_info::register_driver() for more information on how to use + this object. +*/ + +/*! + \var usb_support_descriptor::dev_class + \brief The supported device classes. +*/ + +/*! + \var usb_support_descriptor::dev_subclass + \brief The suported device subclasses. +*/ + +/*! + \var usb_support_descriptor::dev_protocol + \brief The supported device protocols. +*/ + +/*! + \var usb_support_descriptor::vendor + \brief The supported device vendor. +*/ + +/*! + \var usb_support_descriptor::product + \brief The supported device products. +*/ + +///// usb_endpoint_info ///// + +/*! + \struct usb_endpoint_info + \brief Container for endpoint descriptors and their Haiku USB stack + identifiers. +*/ + +/*! + \var usb_endpoint_descriptor *usb_endpoint_info::descr + \brief Pointer to the descriptor of the endpoint. +*/ + +/*! + \var usb_pipe usb_endpoint_info::handle + \brief Handle to use when using the stack to transfer data to and from this + endpoint. +*/ + +///// usb_interface_info ///// + +/*! + \struct usb_interface_info + \brief Container for interface descriptors and their Haiku USB stack + identifiers. +*/ + +//! @{ + +/*! + \var usb_interface_descriptor *usb_interface_info::descr + \brief Pointer to the descriptor of the interface. +*/ + +/*! + \var usb_interface usb_interface_info::handle + \brief Handle to use when using the stack to manipulate this interface. +*/ + +//! @} + +/*! + \name Endpoints +*/ + +//! @{ + +/*! + \var size_t usb_interface_info::endpoint_count + \brief The number of endpoints in this interface. +*/ + +/*! + \var usb_endpoint_info *usb_interface_info::endpoint + \brief An array of endpoints that are associated to this interface. +*/ + +//! @} + +/*! + \name Unparsed descriptors +*/ + +//! @{ + +/*! + \var size_t usb_interface_info::generic_count + \brief The number of unparsed descriptors in this interface. +*/ + +/*! + \var usb_descriptor **usb_interface_info::generic + \brief Unparsed descriptors in this interface. +*/ + +//! @} + +///// usb_interface_list ///// + +/*! + \struct usb_interface_list + \brief List of interfaces available to a configuration. +*/ + +/*! + \var size_t usb_interface_list::alt_count + \brief Number of available interfaces. +*/ + +/*! + \var usb_interface_info *usb_interface_list::alt + \brief Array of available interfaces. +*/ + +/*! + \var usb_interface_info *usb_interface_list::active + \brief Pointer to active interface. +*/ + +///// usb_configuration_info ///// + +/*! + \struct usb_configuration_info + \brief Container for a specific configuration descriptor of a device. +*/ + +/*! + \var usb_configuration_descriptor *usb_configuration_info::descr + \brief The configuration descriptor. +*/ + +/*! + \var size_t usb_configuration_info::interface_count + \brief The number of interfaces in this configuration. +*/ + +/*! + \var usb_interface_list *usb_configuration_info::interface + \brief The list of interfaces available to this configuration. +*/ + +///// usb_iso_packet_descriptor ///// + +/*! + \struct usb_iso_packet_descriptor + \brief The descriptor for data packets of isochronous transfers. +*/ + +/*! + \var int16 usb_iso_packet_descriptor::req_len + \brief Length of the request. +*/ + +/*! + \var int16 usb_iso_packet_descriptor::act_len + \brief The USB stack writes the actual transferred length in this variable. +*/ + +/*! + \var status_t usb_iso_packet_descriptor::status + \brief The status of the transfer. +*/ + +///// usb_callback_func ///// + +/*! + \typedef typedef void (*usb_callback_func)(void *cookie, status_t status, void *data, size_t actualLength) + \brief Callback function for asynchronous transfers. + + \param cookie The cookie you supplied when you queued the transfer. + \param status The status of the transfer. This is one of the following: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
B_OKTransfer succeeded.
B_CANCELEDTransfer cancelled by the user via a + usb_module_info::cancel_queued_transfers() call.
B_DEV_MULTIPLE_ERRORSMore than one of the errors + below. Unfortunately, the stack cannot give you more information.
B_DEV_STALLEDThe endpoint is stalled. You can use + usb_module_info::clear_feature() method with the associated pipe and + the USB_FEATURE_ENDPOINT_HALT arguments.
B_DEV_DATA_OVERRUNIncoming transfer: more data + flowing in than the size of the buffer.
B_DEV_DATA_UNDERRUNOutgoing transfer: more data + flowing out than the endpoint accepts.
B_DEV_CRC_ERRORThe internal data consistency + checks of the USB protocol failed. You are best to retry. If you keep + on getting this error, there might be something wrong with the + device.
B_DEV_UNEXPECTED_PIDInternal error. You should + retry your transfer.
B_DEV_FIFO_OVERRUNInternal error. You should + retry your transfer.
B_DEV_FIFO_UNDERRUNInternal error. You should + retry your transfer.
+ \param data The provided buffer. + \param actualLength The amount of bytes read or written during the transfer. +*/ + +///// usb_module_info ///// + +/*! + \struct usb_module_info + \brief Interface for drivers to interact with Haiku's USB stack. +*/ + +/*! + \var usb_module_info::binfo + \brief Instance of the bus_manager_info object. +*/ + +/*! + \fn status_t (*usb_module_info::register_driver)(const char *driverName, const usb_support_descriptor *supportDescriptors, size_t supportDescriptorCount, const char *optionalRepublishDriverName) + \brief Register your driver. + + To let the USB stack know that a driver is available to support devices, a + driver needs to register itself first. To let the stack know which devices + it needs to notify the driver of, have a look at usb_support_descriptor. + + It is possible to supply a list of support constructors. You should allocate + an array of support constructors, and give the amount of constructors in the + array using the \a supportDescriptorCount parameter. + + In case your driver supports all devices, or more likely, in case you want to + monitor all devices plugged in and removed, it is safe to pass \c NULL to the + \a supportDescriptors paramater and zero (0) to \a supportDescriptorCount. + + \param driverName A unique name that identifies your driver. Avoid names like + \c webcam or \c mouse, instead use vendor names and device types to avoid + nameclashes. The install_notify() and uninstall_notify() functions use the + driver name as an identifier. + \param supportDescriptors An array of the type usb_support_descriptor. Pass + the amount of objects in the next parameter. + \param supportDescriptorCount The number of objects in the array supplied in + the previous parameter. + \param optionalRepublishDriverName Unused parameter. You should pass \c NULL. + \retval B_OK The driver is registered. You can now call install_notify() + \retval B_BAD_VALUE You passed \c NULL as \a driverName. + \retval B_ERROR General internal error in the USB stack. You may retry the + request in this case. + \retval B_NO_MEMORY Error allocating some internal objects. The system is + out of memory. +*/ + +/*! + \fn status_t (*usb_module_info::install_notify)(const char *driverName, const usb_notify_hooks *hooks) + \brief Install notify hooks for your driver. + + After your driver is registered, you need to pass hooks to your driver that + are called whenever a device that matches your \link usb_support_descriptor + support descriptor \endlink . + + As soon as the hooks are installed you'll receive callbacks for devices that + are already attached, so make sure your driver is initialized properly when + calling this method. + + \param driverName The name you passed in register_driver(). + \param hooks The hooks the stack should call in case the status of devices + that match your support descriptor changes. + \retval B_OK Hooks are installed succesfully. + \retval B_NAME_NOT_FOUND Invalid \a driverName. + + \see usb_notify_hooks for information on how your hooks should behave. + \see uninstall_notify() +*/ + +/*! + \fn status_t (*usb_module_info::uninstall_notify)(const char *driverName) + \brief Uninstall notify hooks for your driver. + + If your driver needs to stop, you can uninstall the notifier hooks. This will + clear the stored hooks in the driver and you will not receive any + notifications when new devices are attached. This method will also call + usb_notify_hooks::device_removed() for all the devices that you are using and + all the stack's resources that are allocated to your driver are cleared. + + \param driverName The name you passed in register_driver(). + \retval B_OK Hooks are uninstalled. + \retval B_NAME_NOT_FOUND Invalid \a driverName. +*/ + +/*! + \fn const usb_device_descriptor *(*usb_module_info::get_device_descriptor)(usb_device device) + \brief Get the device descriptor. + + \param device The id of the device you want to query. + \return The standard usb_device_descriptor, or \c NULL in case of an error. +*/ + +/*! + \fn const usb_configuration_info *(*usb_module_info::get_nth_configuration)(usb_device device, uint index) + \brief Get a configuration descriptor by index. + + \param device The id of the device you want to query. + \param index The (zero based) offset of the list of configurations. + \return The usb_configuration_info with the standard usb configuration + descriptor, or \c NULL if the \a id is invalid or the \a index is out of + bounds. +*/ + +/*! + \fn const usb_configuration_info *(*usb_module_info::get_configuration)(usb_device device) + \brief Get the current configuration. + + \param id The id of the device you want to query. + \retval The usb_configuration_info with the standard usb configuration + descriptor, or \c NULL if the \a id is invalid. +*/ + +/*! + \fn status_t (*usb_module_info::set_configuration)(usb_device device, const usb_configuration_info *configuration) + \brief Change the current configuration. + + Changing the configuration will destroy all the current endpoints. If the + \a configuration points to the current configuration, the request will be + ignored and \c B_OK will be returned. + + \param device The id of the device you want to query. + \param configuration The pointer to the new configuration you want to set. + \retval B_OK The new configuration is set succesfully. + \retval B_DEV_INVALID_PIPE The \a device parameter is invalid. + \retval B_BAD_VALUE The configuration does not exist. + + \note This method also allows you to completely unconfigure the device, which + means that all the current endpoints, pipes and transfers will be freed. + Pass \c NULL to the parameter \a configuration if you want to do that. +*/ + +/*! + \fn status_t (*usb_module_info::set_alt_interface)(usb_device device, const usb_interface_info *interface) + \brief Set an alternative interface. Not implemented. + + This method currently always returns \c B_ERROR. +*/ + +/*! + \fn status_t (*usb_module_info::set_feature)(usb_id handle, uint16 selector) + \brief Convenience function for standard control pipe set feature requests. + + Both the set_feature() and clear_feature() requests work on all the Stack's + objects: devices, interfaces and pipes. + + \param handle The object you want to query. + \param selector The value you want to pass in the feature request. + \return \c B_OK in case the request succeeded and the device responded + positively, or an error code in case it failed. +*/ + +/*! + \fn status_t (*usb_module_info::clear_feature)(usb_id handle, uint16 selector) + \brief Convenience function for standard control pipe clear feature requests. + + \see set_feature() to see how this method works. +*/ + +/*! + \fn status_t (*usb_module_info::get_status)(usb_id handle, uint16 *status) + \brief Convenience function for standard usb status requests. + + \param[in] handle The object you want to query. + \param[out] status A variable in which the device can store it's status. + \return \c B_OK in case the request succeeded and the device responded + positively, or an error code in case it failed. +*/ + +/*! + \fn status_t (*usb_module_info::get_descriptor)(usb_device device, uint8 descriptorType, uint8 index, uint16 languageID, void *data, size_t dataLength, size_t *actualLength) + \brief Convenience function to get a descriptor from a device. + + \param[in] device The device you want to query. + \param[in] descriptorType The type of descriptor you are requesting. + \param[in] index In case there are multiple descriptors of this type, you + select which one you want. + \param[in] languageID The language you want the descriptor in (if applicable, + like with string_descriptors). + \param[out] data The buffer in which the descriptor can be written. + \param[in] dataLength The size of the buffer (in bytes). + \param[out] actualLength A pointer to a variable in which the actual number + of bytes written can be stored. + \retval B_OK The request succeeded, and the descriptor is written. + \retval B_DEV_INVALID_PIPE Invalid \a device parameter. + \retval "other errors" Request failed. +*/ + +/*! + \fn status_t (*usb_module_info::send_request)(usb_device device, uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength) + \brief Send a generic, synchronous request over the default control pipe. + + See queue_request() for an asynchronous version of this method. + + Most of the standard values of a request are defined in USB_spec.h. + + \param[in] device The device you want to query. + \param[in] requestType The request type. + \param[in] request The request you want to perform. + \param[in] value The value of the request. + \param[in] index The index for the request. + \param[in] length The size of the buffer pointed by \a data + \param[out] data The buffer where to put the result in. + \param[out] actualLength The actual numbers of bytes written. + + \retval B_OK The request succeeded. + \retval B_DEV_INVALID_PIPE Invalid \a device parameter. + \retval "other errors" Request failed. +*/ + +/*! + \fn status_t (*usb_module_info::queue_interrupt)(usb_pipe pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) + \brief Asynchronously queue an interrupt transfer. + + \param pipe The id of the pipe you want to query. + \param data The data buffer you want to pass. + \param dataLength The size of the data buffer. + \param callback The callback function the stack should call after finishing. + \param callbackCookie A cookie that will be supplied to your callback + function when the transfer is finished. + + \return Whether or not the queueing of the transfer went well. The return + value won't tell you if the transfer actually succeeded. + \retval B_OK The interrupt transfer is queued. + \retval B_NO_MEMORY Error allocating objects. + \retval B_DEV_INVALID_PIPE The \a pipe is not a valid interrupt pipe. +*/ + +/*! + \fn status_t (*usb_module_info::queue_bulk)(usb_pipe pipe, void *data, size_t dataLength, usb_callback_func callback, void *callbackCookie) + \brief Asynchronously queue a bulk transfer. + + This method behaves like the queue_interrupt() method, except that it queues + a bulk transfer. +*/ + +/*! + \fn status_t (*usb_module_info::queue_bulk_v)(usb_pipe pipe, iovec *vector, size_t vectorCount, usb_callback_func callback, void *callbackCookie) + \brief Asynchronously queue a bulk vector. + + This method behaves like the queue_interrupt() method, except that it queues + bulk transfers and that it is based on an (array of) io vectors. + + \param vector One or more io vectors. IO vectors are standard POSIX entities. + \param vectorCount The number of elements in the \a vector array. +*/ + +/*! + \fn status_t (*usb_module_info::queue_isochronous)(usb_pipe pipe, void *data, size_t dataLength, usb_iso_packet_descriptor *packetDesc, uint32 packetCount, uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback, void *callbackCookie) + \brief Asynchronously queue a isochronous transfer. Not implemented. + + Not implemented in the current Haiku USB Stack. +*/ + +/*! + \fn status_t (*usb_module_info::queue_request)(usb_device device, uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, usb_callback_func callback, void *callbackCookie) + \brief Asynchronously queue a control pipe request. + + This method does roughly the same as send_request(), however, it works + asynchronously. This means that the method will return as soon as the + transfer is queued. + + \param callback The callback function for when the transfer is done. + \param callbackCookie The cookie that the stack should pass to your callback + function. + \return Whether or not the queueing of the transfer went well. The return + value won't tell you if the transfer actually succeeded. + \retval B_OK The control transfer is queued. + \retval B_NO_MEMORY Error allocating objects. + \retval B_DEV_INVALID_PIPE The \a device argument is invalid. +*/ + +/*! + \fn status_t (*usb_module_info::set_pipe_policy)(usb_pipe pipe, uint8 maxNumQueuedPackets, uint16 maxBufferDurationMS, uint16 sampleSize) + \brief Set some pipe features. + + The USB standard specifies some properties that should be able to be set on + isochronous pipes. If your driver requires the properties to be changed, you + should use this method. + + \param pipe The id of the isochronous pipe you want to alter. + \param maxNumQueuedPackets The maximum number of queued packets allowed on + this pipe. + \param maxBufferDurationMS The maximum time in ms that the buffers are valid. + \param sampleSize The size of the samples through this pipe. + \retval B_OK Pipe policy changed. + \retval B_DEV_INVALID_PIPE The \a pipe argument is invalid or not an + isochronous pipe. +*/ + +/*! + \fn status_t (*usb_module_info::cancel_queued_transfers)(usb_pipe pipe) + \brief Cancel pending transfers on a pipe. + + All the pending transfers will be cancelled. The stack will perform the + callback on all of them that are cancelled. + + \attention There might be transfers that are being executed the moment you + call this method. These will be executed, and their callbacks will be + performed. Make sure you don't delete any buffers that could still be used + by these transfers. + + \param pipe The id of the pipe to clear. + + \retval B_OK All the pending transfers on this pipe are deleted. + \retval B_DEV_INVALID_PIPE The supplied usb_id is not a valid pipe. + \retval "other errors" There was an error clearing the pipe. +*/ + +/*! + \fn status_t (*usb_module_info::usb_ioctl)(uint32 opcode, void *buffer, size_t bufferSize) + \brief Low level commands to the USB stack. + + This method is used to give lowlevel commands to the Stack. There are + currently no uses documented. +*/ + +///// B_USB_MODULE_NAME ///// + +/*! + \def B_USB_MODULE_NAME + \brief The identifier string for the USB Stack interface module. +*/ diff --git a/docs/user/drivers/usb_modules.dox b/docs/user/drivers/usb_modules.dox index 4691cf4ea6..8ad4f32e76 100644 --- a/docs/user/drivers/usb_modules.dox +++ b/docs/user/drivers/usb_modules.dox @@ -1,18 +1,386 @@ -/* - * Copyright 2007, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Documentation by: - * Niels Sascha Reedijk - */ - -/*! - \page usb_modules Writing drivers for USB devices - - This page will describe how the Haiku USB stack is structured. -*/ - - - - - \ No newline at end of file +/* + * Copyright 2007, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Documentation by: + * Niels Sascha Reedijk + */ + +/*! + \page usb_modules Writing drivers for USB devices + + The introduction of USB standardized the way many devices connected to a + whole range of different computers and operating systems. It introduced a + standard that was capable of getting rid of all the legacy systems, such as + the LPT, the PS/2 and serial ports. The plug and play nature of the standard + were revolutional at the time of it's introduction, and it changed the way + in which operating systems interacted with devices. + + With the grand standard that USB has become, Haiku has an implementation + of it. It supports both the USB 1.1 and USB 2.0 specifications, and when + Haiku R1 is released, it will support the three host controller standards: + UHCI, OHCI and EHCI. The modularized design of Haiku's USB stack also paves + the way for easy implementation of any future specifications, such as + Wireless USB. + + \section usb_modules_scope The Scope of this Document + + This document is written for driver developers that need to interact with + USB devices. The USB specification standardizes the communication between + the host controller and the devices, and how devices should transfer data, + but it does not prescribe a standard environment that Operating Systems + should provide to the driver interfaces. As such, every operating system has + it's own interface for drivers, and so does Haiku. + + This document will point driver developers to relevant parts of the USB + module 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, or + on how to use modules. Have a look elsewhere in this documentation for that. + This document also asumes a basic knowledge of the USB specification, and on + how you are supposed to interact with devices. See \ref usb_modules_resources + for tutorials on the web if you are looking for a basic introduction on + communication with the USB protocol. + + \section usb_modules_structure Structure of the Stack + + This section will outline how Haiku's USB stack is structured, and how you + can interact with this stack. + + The goal of the USB stack is to provide a few basic features for drivers + interacting with USB devices. It is important that the stack maintains a + continually updated device grid, so that the driver modules are always + aware of the latest status. The stack should also facilitate communication + between drivers and the devices, by abstracting the actual transfering of + bits via the host controller hardware in the computer. The stack therefore + should implement a inituitive interface to give driver developers access to + all features and possibilities the USB specification offers, and at the same + time it should abstract many of the small requirements and peculiarities of + that specification. + + The stack internally can be divided into two parts. The first part is the + core module. This module, called \c usb_busmanager, performs all the + operations required by the USB specification. For example, it performs the + necessary lowlevel initialization when new devices are connected, or all the + requirements when it comes to performing transfers. The core module also + is the module that provides the abstractions to driver developers. The other + part of the USB stack are the individual modules that control the different + host controllers. Haiku supports the three types in existence: UHCI, OHCI + and EHCI. These modules perform the communication between the core module + and the hardware. As driver developer, you won't have to interact with these + modules: the core module provides all the abstractions you need. + + Thus, as a driver developer you are interfacing with the \c usb_busmanager + module. On Haiku, this module implements two API's. The \c v2 API, identical + to the API offered by BeOS R5, can be found in the \c USB2.h file. However, + for new drivers, or for ports, the recomended API is the \c v3 API, defined + in 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 Registration + + In order to be able to start using the USB stack to communicate with your + devices, you will need to perform some actions. This section will outline + those actions and will point you to their appropriate locations. + + \note The code examples are based on the \c usb_hid driver written by + Jerome Duval. Have a look at this driver for a complete working example. + + The following example gives an overview of the requirements to open the + USB module, and to start your driver registration in order to receive + connect and disconnect events. + + \code +// Global variables and constants +usb_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 removed +static 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 loaded +status_t +init_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; +} + \endcode + + Basically, this boils down to three steps. The first step is to acquire the + usb_module_info module. This struct contains a set of function pointers that + you use to communicate with the stack. You can retrieve it like you would + retrieve any other module. + + As soon as you have done that you can start registering your driver in the + stack. What you do is you pass a unique identifier to identify your driver, + zero or more \link usb_support_descriptor support descriptors \endlink + to provide the stack with information on which devices you support, and the + number of support descriptors you provided. The stack is very flexible with + what patterns it accepts, so even the most complex driver will be able to + pass it's credentials. Have a look at the \c usb_support_descriptor struct + and the \c usb_module_info::register_driver() call for all the details. + + The last step in initialization is to provide the stack with notification + hooks. These are functions in your driver that the stack should call as soon + as a device is attached or removed. Please perform this call after your + internal driver data structures are initialized, because as soon as you + perform this call, the usb stack will start searching for already attached + devices that match the credentials. Have a look at + \c usb_module_info::install_notify() and the structure \c usb_notify_hooks + for the details on the signatures of your hooks. + + \section usb_modules_changes Handling Device Changes + + The USB stack will notify you of device connects and disconnects when they + occur. You will receive notifications as soon as you have supplied the hooks + to the stack, using \c usb_module_info::install_notify() . This section will + explain some of the details when it comes to handling device changes. + + When a device is added, your supplied usb_notify_hooks::device_added() hook + will be called if its credentials matches one of your support descriptors. + Because the stack runs through all the registered drivers, it could be that + two or more drivers operate on the same device. The stack does not provide + a locking mechanism to prevent two conflicting drivers to get in each others + way. 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 one + other driver, because Haiku supplies the \c usb_raw driver. This driver + provides userland access to the usb devices and therefore it has a blank + support descriptor that matches everything. The \c usb_raw driver will + not conflict with your device interaction though (except when there is an + userland application that tries to meddle with your device). + + If your driver is willing to accept the supplied device, and your + device_added() hook returns B_OK, the USB stack will ask the kernel to reload + your 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 be + handled by your \c usb_notify_hooks::device_removed() hook. Because "plug and + play" also means "unplug and leave", you should make sure your driver is + capable of cleaning up in the likely event that the user removes their + device, even during transfers. In your hook function, you have the ability to + do clean up whatever there is to clean up, however, make sure that you cancel + all 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 your + device_added() hook. + + \section usb_modules_standard Standard USB Operations + + One of the many conveniences of the Haiku USB API is the fact that many of + the standard operations can be performed by simple function calls. As such, + you won't have to build many of the standard requests the USB specification + defines by hand. This section will outline all the different conveniences and + will point you to where to look if you do need something more advanced. + + \subsection usb_modules_standard_descriptors Configurations, Interfaces and Descriptors + + Many standard USB operations have to do with configurations, interfaces and + descriptors. All these operations are accessible by convenience functions. + + The device descriptor is one of the first things you will be interested in if + you want to check out a device. The device descriptor can be retrieved quite + easily using the \c usb_module_info::get_device_descriptor() call. The + retrieved descriptor complies to the one dictated by the USB standard. + + Also important are configurations. Since every device has at least one + configuration, you should be able to retrieve and manipulate configurations. + You can use \c usb_module_info::get_nth_configuration() to get them. To set + a configuration, you should use \c usb_module_info::set_configuration(). To + get the active configuration, use \c usb_module_info::get_configuration(). + + \attention By default, Haiku's stack will set the configuration at offset + zero, which is according to the standard, the default configuration. + Do not rely on that if you first get the device, that the currently active + configuration is the default configuration though. Another driver might + have manipulated this device already. + + Every configuration has associated interfaces. To make life easier, the stack + automatically gets the interface descriptors (and their associated + endpoints), and stores them in the \c usb_configuration_info structure. This + structure has a member called \link usb_configuration_info::interface + \c interface \endlink which is of the type \c usb_interface_list. That object + containts all the interfaces, including a pointer to the interface that is + currently active. Each interface is described as a \c usb_interface_info, + which is a container for the interface, its associated endpoints and any + unparsed descriptors. In order to change the active interface, you can use + the 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 actual + endpoint descriptor, and the accompanying usb_pipe handle that you can use to + actually send and receive data. + + The last point of interest are descriptors. As you have seen, Haiku caches + all the relevant descriptors itself, however, you might want to retrieve any + other type of descriptor that could be relevant for your device. The + convenience function to use in such a case is the + \c usb_module_info::get_descriptor() call. This function takes all the + parameters needed to build the actual descriptor, and performs the request + over the default control pipe. + + \subsection usb_modules_standard_features Features + + Another one of the building blocks of USB are features. Every device should + provide for a number of standard features, but the USB specification also + leaves the option to using custom device specific features. Feature requests + can be performed on devices, interfaces and pipes (which are tied to + endpoints). + + To set a feature, you can use the \c usb_module_info::set_feature() call. To + clear a feature, use the \c usb_module_info::clear_feature() call. One of the + most used feature calls is the call to clear a \c USB_FEATURE_ENDPOINT_HALT . + + \subsection usb_modules_standard_other Other Standard Calls + + To 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 the + isochronous pipe. + + \section usb_modules_transfers Data Transfers + + Transfering data is one of the basic building blocks of the USB protocol. + This section will demonstrate how to perform transfers via the four different + protocols 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 your + transfer is finished. + + The five functions share some arguments. The first argument is always the + pipe that is associated with the endpoint (except for control transfers, + these only work on the device in general). All of the functions accept a data + buffer, 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 a + transfer is finished. The functions also require a cookie that is provided to + the callback function. + + The working order is as follows: first you queue a transfer, then you handle + the result in the callback function when it's done. The callback function + will be called with a \a status argument, in which you can check whether or + not the transfer actually succeeded. See this \link #usb_callback_func + description \endlink for how your callback function should behave and what + kind of status there might have been. + + Finally, before going into the different transfer types, a note on buffer + ownership. The usb stack keeps the internal buffers tidy, but the buffer you + provide to the \c queue_* functions are yours. You are responsible for + allocating and freeing them, and you may do with them whatever you like, + \e except between queueing your transfer and the callback. During that period + you should consider the USB stack the owner of the buffer. + + \subsection usb_modules_transfers_control Control Requests + + Control requests are done over the device wide control pipe which is provided + by every device. Haiku's stack has two functions that you can use to perform + custom requests (opposed to many of the \ref usb_modules_standard + "standard operations"). Control transfers are the only transfers that you can + perform synchronously as well as asynchronously. The functions you can use + are \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 in + the USB_spec.h file which is automatically included if you include the main + USB header. Have a look of how to use these constants in the following + example: + + \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, device->total_report_size, &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. Avoid + low-level operations, because the stack needs to keep its internal + data structures consistent. If you need to perform one of the + \ref usb_modules_standard "standard operations", use the provided + convenience functions. + + \subsection usb_modules_transfers_interrupt Interrupt + + Interrupt transfers apply to endpoints that receive data, or that can be + polled in several instances of time. The intervals are determined by the + endpoint descriptor. + + To schedule a transfer, use usb_module_info::queue_interrupt(). You only have + to supply a buffer, the stack schedule the transfer in such a way that it + will be performed within a certain timeframe. To create a continuous + interrupt system, you should queue the next transfer in the callback function + of the previous. The stack will make sure that the new transfer will be + performed exactly after the required interval. + + \subsection usb_modules_transfers_bulk Bulk + + Bulk transfers are very similar to control transfers. They will be performed + as soon as possible without stalling other transfers, and they transfer data. + Bulk transfers are designed to transfer up to large amounts of data as + efficiently as possible. Performing bulk transfers isn't difficult, you + merely supply a buffer and the endpoint that should execute the request, and + you're set. + + Bulk transfers come in two flavours. The first is + usb_module_info::queue_bulk(), which takes a standard data buffer. The second + flavour is the usb_module_info::queue_bulk_v() function, which is designed to + operate on (an array of) POSIX vectors. These functions only differ in the + buffer they accept, they function in exactly the same way. + + \subsection usb_modules_transfers_isochronous Isochronous + + Isochronous 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 Up + + This section describes how to gracefully leave the stack after your driver is + requested to shut down. + + There are truely only two simple actions to perform. The first is to + uninstall your notification hooks, using + \c usb_module_info::uninstall_notify(). The second action is to 'put' the + module. + + \code +void +uninit_driver(void) +{ + usb->uninstall_notify(kDriverName); + + put_module(B_USB_MODULE_NAME); +} + \endcode + + \section usb_modules_resources More Resources + + This section should list more resources on the web. +*/