USBA_HCDI_PIPE_CTRL_XFER(9E) Driver Entry Points
NAME
usba_hcdi_pipe_ctrl_xfer - perform a USB control transfer
SYNOPSIS
#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);
INTERFACE LEVEL
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.
PARAMETERS
ph A pointer to a USB pipe handle as defined in
usba_pipe_handle_data(9S).
ucrp A pointer to a USB control transfer request. The
structure's members are documented in
usb_ctrl_req(9S).
usb_flags Flags which describe how allocations should be performed.
Valid flags are:
USB_FLAGS_NOSLEEP Do not block waiting for memory. If memory is
not available the allocation will fail.
USB_FLAGS_SLEEP Perform a blocking allocation. If memory is not
available, the function will wait until memory is
made available.
Note, the request may still fail even if
USB_FLAGS_SLEEP is specified.
DESCRIPTION
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.
Callback Handling
When the control transfer completes the driver should consider the
following items to determine what actions it should take on the
callback:
+o If the transfer timed out, it should remove the transfer from the
outstanding list, queue the next transfer, and return the transfer
back to the OS with the error code
USB_CR_TIMEOUT with
usba_hcdi_cb(9F).
+o If the transfer failed, it should find the appropriate error and
call
usba_hcdi_cb(9F) with that error.
+o If the transfer succeeded, but less data was transferred than
expected, consult the
ctrl_attributes member of the
ucrp. If the
USB_ATTRS_SHORT_XFER_OK flag is not present, then the driver should
call
usba_hcdi_cb(9F) with the error
USB_CR_DATA_UNDERRUN.
+o If the transfer was going to the host, then the driver should copy
the data into the transfer's message block and update the
b_wptr member of the
mblk(9S).
+o If everything was successful, call
usba_hcdi_cb(9F) with the code
USB_CR_OK.
RETURN VALUES
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.
SEE ALSO
usba_hcdi(9E),
usba_hcdi_cb(9F),
mblk(9S),
usb_ctrl_req(9S),
usba_pipe_handle_data(9S)illumos December 22, 2016 illumos