USB_CALLBACK_FLAGS(9S) | Data Structures for Drivers | USB_CALLBACK_FLAGS(9S) |
usb_callback_flags - USB callback flag definitions
#include <sys/usb/usba.h>
illumos DDI specific (illumos DDI)
If the USB framework detects an error during a request execution, it calls the client driver's exception callback handler to report what happened. Callback flags (which are set prior to calling the exception callback handler) detail errors discovered during the exception recovery process, and summarize recovery actions taken by the USBA framework.
Information from the callback flags supplements information from the original transport error. For transfers, the original transport error status is returned to the callback handler through the original request (whose completion reason field contains any transport error indication). For command completion callbacks, the callback's rval argument contains the transport error status. A completion reason of USB_CR_OK means the transfer completed with no errors detected.
The usb_cb_flags_t enumerated type contains the following definitions:
USB_CB_NO_INFO
USB_CB_FUNCTIONAL_STALL
USB_CB_STALL_CLEARED
USB_CB_PROTOCOL_STALL
USB_CB_RESET_PIPE
USB_CB_ASYNC_REQ_FAILED
USB_CB_SUBMIT_FAILED
USB_CB_NO_RESOURCES
USB_CB_INTR_CONTEXT
The usb_cb_flags_t enumerated type defines a bitmask. Multiple bits can be set, reporting back multiple statuses to the exception callback handler.
The USBA framework supports callback handling as a way of asynchronous client driver notification. There are three kinds of callbacks: Normal completion transfer callback, exception (error) completion transfer callback, and command completion callback, each described below.
Callback handlers are called whenever they are specified in a request or command, regardless of whether or not that request or command specifies the USB_FLAGS_SLEEP flag. (USB_FLAGS_SLEEP tells the request or command to block until completed.) Callback handlers must be specified whenever an asynchronous transfer is requested.
Each pipe is associated with a pool of threads that are used to run callbacks associated with requests on that pipe. All transfer completion callbacks for a particular pipe are run serially by a single thread.
Pipes taking requests with callbacks which can block must have their pipe policy properly initialized. If a callback blocks on a condition that is only met by another thread associated with the same pipe, there must be sufficient threads available. Otherwise that callback thread will block forever. Similarly, problems will ensue when callbacks overlap and there are not enough threads to handle the number of overlapping callbacks.
The pp_max_async_reqs field of the pipe_policy provides a hint of how many threads to allocate for asynchronous processing of request callbacks on a pipe. Set this value high enough per pipe to accommodate all of the pipe's possible asynchronous conditions. The pipe_policy is passed to usb_pipe_open(9F).
Transfer completion callbacks (normal completion and exception):
Most transfer completion callbacks are allowed to block, but only under certain conditions:
A transfer request can specify a non-null normal-completion callback. Such requests conclude by calling the normal-completion callback when the transfer completes normally. Similarly, a transfer request can specify a non-null exception callback. Such requests conclude by calling the exception callback when the transfer completes abnormally. Note that the same callback can be used for both normal completion and exception callback handling. A completion reason of USB_CR_OK defines normal completion.
All request-callbacks take as arguments a usb_pipe_handle_t and a pointer to the request:
xxxx_cb(usb_pipe_handle_t ph, struct usb_ctrl_req *req);
Such callbacks can retrieve saved state or other information from the private area of the pipe handle. (See usb_pipe_set_private(9F).) Handlers also have access to the completion reason (usb_cr_t) and callback flags (usb_cb_flags_t) through the request argument they are passed.
Request information follows. In the data below, xxxx below represents the type of request (ctrl, intr, isoc or bulk.)
Request structure name is usb_xxxx_req_t.
Normal completion callback handler field is xxxx_cb.
Exception callback handler field is xxxx_exc_cb.
Completion reason field is xxxx_completion_reason.
Callback flags field is xxxx_cb_flags.
Calls to some non-transfer functions can be set up for callback notification. These include usb_pipe_close(9F), usb_pipe_reset(9F), usb_pipe_drain_reqs(9F), usb_set_cfg(9F), usb_set_alt_if(9F) and usb_clr_feature(9F).
The signature of a command completion callback is as follows:
command_cb(
usb_pipe_handle_t cb_pipe_handle,
usb_opaque_t arg,
int rval,
usb_cb_flags_t flags);
As with transfer completion callbacks, command completion callbacks take a usb_pipe_handle_t to retrieve saved state or other information from the pipe's private area. Also, command completion callbacks are provided with an additional user-definable argument (usb_opaque_t arg), the return status of the executed command (int rval), and the callback flags (usb_cb_flags_t flags).
The rval argument is roughly equivalent to the completion reason of a transfer callback, indicating the overall status. See the return values of the relevant function for possible rval values which can be passed to the callback.
The callback flags can be checked when rval indicates failure status. Just as for transfer completion callbacks, callback flags return additional information on execution events.
See attributes(7) for descriptions of the following attributes:
ATTRIBUTE TYPE | ATTRIBUTE VALUE |
Architecture | PCI-based systems |
Interface stability | Committed |
usb_alloc_request(9F), usb_pipe_bulk_xfer(9F), usb_pipe_ctrl_xfer(9F), usb_pipe_intr_xfer(9F), usb_pipe_isoc_xfer(9F), usb_bulk_request(9S), usb_ctrl_request(9S), usb_intr_request(9S), usb_isoc_request(9S)
January 5, 2004 | OmniOS |