Use control requests to initiate message transfers down a control pipe. You can set up transfers manually, as described below. You can also set up and send synchronous transfers using the usb_pipe_ctrl_xfer_wait(9F) wrapper function.
The client driver must initialize the ctrl_bmRequestType, ctrl_bRequest, ctrl_wValue, ctrl_wIndex, and ctrl_wLength fields as described in the USB 2.0 specification.
The ctrl_data field of the request must be initialized to point to a data buffer. The usb_alloc_ctrl_req(9F) function initializes this field when you pass a positive value as the buffer len. The buffer must, of course, be initialized for any outbound transfers. In all cases, the client driver must free the request when the transfer is complete.
Multiple control requests can be queued. Queued requests can be a combination of synchronous and asynchronous requests.
The ctrl_timeout field defines the maximum wait time for the request to be processed, excluding wait time on the queue. This field applies to both synchronous and asynchronous requests. The ctrl_timeout field is specified in seconds.
The ctrl_exc_cb field accepts the address of a function to call if an exception occurs. The arguments of this exception handler are specified in the usb_ctrl_request(9S) man page. The second argument of the exception handler is the usb_ctrl_req_t structure. Passing the request structure as an argument allows the exception handler to check the ctrl_completion_reason and ctrl_cb_flags fields of the request to determine the best recovery action.
The USB_ATTRS_ONE_XFER and USB_ATTRS_ISOC_* flags are invalid attributes for all control requests. The USB_ATTRS_SHORT_XFER_OK flag is valid only for host-bound requests.