USBA_HCDI_PIPE_CTRL_XFER(9E) | Driver Entry Points | USBA_HCDI_PIPE_CTRL_XFER(9E) |
usba_hcdi_pipe_ctrl_xfer
—
perform a USB control transfer
#include
<sys/usb/usba/hcdi.h>
int
prefix_hcdi_pipe_ctrl_xfer
(usba_pipe_handle_data_t
*ph, usb_ctrl_req_t *ucrp,
usb_flags_t usb_flags);
Volatile - illumos USB HCD private function
This is a private function that is not part of the stable DDI. It may be removed or changed at any time.
Note, the request may still fail even if USB_FLAGS_SLEEP is specified.
The
usba_hcdi_pipe_ctrl_xfer
()
entry point is used to initiate an
asynchronous
USB Control transfer on the pipe ph. The specific USB
control transfer is provided in ucrp. For more
background on transfer types, see
usba_hcdi(9E).
The host controller driver should first check the USB address of the pipe handle. It may correspond to the root hub. If it does, rather than initiating an I/O transfer, the driver may need to emulate it using available information.
Control endpoints are always bi-directional. A given endpoint may perform transfer data from the OS to the device, or from the device to the OS. The driver will need to look at the control transfer request and transform that into the appropriate format for the controller.
Control transfers are made up of three parts. A setup stage, an optional data stage, and a status stage. Depending on the controller, the driver may need to transform the transfer request into a format that matches this. Refer to the device's controller specification for more information on whether this is required or not.
The device driver should a request based on the information present in the control request ucrp. If there is a non-zero length for the transfer, indicated by the ctrl_wLength member of ucrp being greater than zero, then the controller needs to allocate a separate memory buffer for the request. The corresponding data will be found in an mblk(9S) structure as the ctrl_data member of ucrp.
If this transfer needs to be sent to a device through the controller and is not being handled directly by the driver, then the driver should allocate a separate region of memory (generally memory suitable for a DMA transfer) for the transfer. If sending data to the device, the data in the message block should be copied prior to the transfer. Otherwise, once the transfer completes, data should be transferred into the message block and the write pointer incremented.
If the driver needs to allocate memory for this transfer, it should honor the values set in usb_flags to indicate whether or not it should block for memory, whether DMA memory or normal kernel memory.
If the driver successfully schedules the I/O or it can handle the I/O itself because it's a synthetic root hub request, then it should return USB_SUCCESS. If the driver returns successfully, it must call usba_hcdi_cb(9F) with ucrp either before or after it returns. The only times that a driver would call the callback before the function returns are for requests to the root hub that it handles inline and does not need to send off asynchronous activity to the controller.
For asynchronous requests, the controller is also responsible for timing out the request if it does not complete. If the timeout in the request as indicated in the ctrl_timeout member is set to zero, then the driver should use the USBA default timeout of HCDI_DEFAULT_TIMEOUT. All timeout values are in seconds.
When the control transfer completes the driver should consider the following items to determine what actions it should take on the callback:
Upon successful completion, the
usba_hcdi_pipe_ctrl_xfer
() function should return
USB_SUCCESS. Otherwise, it should return the appropriate
USB error. If uncertain, use
USB_FAILURE.
usba_hcdi(9E), usba_hcdi_cb(9F), mblk(9S), usb_ctrl_req(9S), usba_pipe_handle_data(9S)
December 22, 2016 | OmniOS |