USB_PIPE_XOPEN(9F) | Kernel Functions for Drivers | USB_PIPE_XOPEN(9F) |
usb_pipe_open
,
usb_pipe_xopen
— Open a USB
pipe to a device
#include
<sys/usb/usba.h>
int
usb_pipe_open
(dev_info_t *dip,
usb_ep_descr_t *endpoint,
usb_pipe_policy_t *pipe_policy,
usb_flags_t flags, usb_pipe_handle_t
*pipe_handle);
int
usb_pipe_xopen
(dev_info_t *dip,
usb_ep_xdescr_t *extended_endpoint,
usb_pipe_policy_t *pipe_policy,
usb_flags_t flags, usb_pipe_handle_t
*pipe_handle);
illumos DDI specific (illumos DDI)
A pipe is a logical connection to an endpoint on a USB device. The
usb_pipe_xopen
()
function creates such a logical connection and returns an initialized handle
which refers to that connection.
The USB 3.0 specification defines four endpoint types, each with a corresponding type of pipe. Each of the four types of pipes uses its physical connection resource differently. They are:
The type of endpoint to which a pipe connects (and therefore the pipe type) is defined by the bmAttributes field of that pipe's endpoint descriptor. (See usb_ep_descr(9S)).
Prior to the USB 3.0
specification, only the
usb_ep_descr(9S) was required
to identify all of the attributes of a given pipe. Starting with
USB 3.0 there are additional endpoint companion
descriptors required to open a pipe. To support SuperSpeed devices, the new
usb_pipe_xopen
()
function must be used rather than the older
usb_pipe_open
()
function. The
usb_ep_xdescr(9S) structure
can be automatically filled out and obtained by calling the
usb_ep_xdescr_fill(9F)
function.
Opens to interrupt and isochronous pipes can fail if the required bandwidth cannot be guaranteed.
The polling interval for periodic (interrupt or isochronous) pipes, carried by the endpoint argument's bInterval field, must be within range. Valid ranges are:
Full speed: range of 1-255 maps to 1-255 ms.
Low speed: range of 10-255 maps to 10-255 ms.
High speed: range of 1-16 maps to (2**(bInterval-1)) * 125us.
Super speed: range of 1-16 maps to (2**(bInterval-1)) * 125us.
Adequate bandwidth during transfers is guaranteed for all periodic pipes which are opened successfully. Interrupt and isochronous pipes have guaranteed latency times, so bandwidth for them is allocated when they are opened. (Please refer to Sections 4.4.7 and 4.4.8 of the USB 3.1 specification which address isochronous and interrupt transfers.) Opens of interrupt and isochronous pipes fail if inadequate bandwidth is available to support their guaranteed latency time. Because periodic pipe bandwidth is allocated on pipe open, open periodic pipes only when needed.
The bandwidth required by a device varies based on polling interval, the maximum packet size (wMaxPacketSize) and the device speed. Unallocated bandwidth remaining for new devices depends on the bandwidth already allocated for previously opened periodic pipes.
The pipe_policy parameter provides a hint as to pipe usage and must be specified. It is a usb_pipe_policy_t which contains the following fields:
uchar_t pp_max_async_reqs:
The pp_max_async_reqs member is a hint indicating how many asynchronous operations requiring their own kernel thread will be concurrently in progress, the highest number of threads ever needed at one time. Allow at least one for synchronous callback handling and as many as are needed to accommodate the anticipated parallelism of asynchronous* calls to the following functions: usb_pipe_close(9F), usb_set_cfg(9F), usb_set_alt_if(9F), usb_clr_feature(9F), usb_pipe_reset(9F), usb_pipe_drain_reqs(9F), usb_pipe_stop_intr_polling(9F), and usb_pipe_stop_isoc_polling(9F).
Setting to too small a value can deadlock the pipe. Asynchronous calls are calls made without the USB_FLAGS_SLEEP flag being passed. Note that a large number of callbacks becomes an issue mainly when blocking functions are called from callback handlers.
The control pipe to the default endpoints (endpoints for both directions with addr 0, sometimes called the default control pipe or default pipe) comes pre-opened by the hub. A client driver receives the default control pipe handle through usb_get_dev_data(9F). A client driver cannot open the default control pipe manually. Note that the same control pipe may be shared among several drivers when a device has multiple interfaces and each interface is operated by its own driver.
All explicit pipe opens are exclusive; attempts to open an opened pipe fail.
On success, the pipe_handle argument points to an opaque handle of the opened pipe. On failure, it is set to NULL.
May be called from user or kernel context regardless of arguments. May also be called from interrupt context if the USB_FLAGS_SLEEP option is not set.
The device referred to by dip is at
least a SuperSpeed device and the older
usb_pipe_open
() function was used.
usb_ep_data_t *ep_data; usb_ep_xdescr_t ep_xdescr; usb_pipe_policy_t policy; usb_pipe_handle_t pipe; usb_client_dev_data_t *reg_data; uint8_t interface = 1; uint8_t alternate = 1; uint8_t first_ep_number = 0; /* Initialize pipe policy. */ bzero(policy, sizeof(usb_pipe_policy_t)); policy.pp_max_async_requests = 2; /* Get tree of descriptors for device. */ if (usb_get_dev_data(dip, USBDRV_VERSION, ®_data, USB_FLAGS_ALL_DESCR, 0) != USB_SUCCESS) { ... } /* Get first interrupt-IN endpoint. */ ep_data = usb_lookup_ep_data(dip, reg_data, interface, alternate, first_ep_number, USB_EP_ATTR_INTR, USB_EP_DIR_IN); if (ep_data == NULL) { ... } /* Translate the ep_data into the filled in usb_ep_xdescr_t */ if (usb_ep_xdescr_fill(USB_EP_XDESCR_CURRENT_VERSION, dip, ep_data, &ep_xdescr) != USB_SUCCESS) { ... } /* Open the pipe. Get handle to pipe back in 5th argument. */ if (usb_pipe_open(dip, &ep_data.ep_descr &policy, USB_FLAGS_SLEEP, &pipe) != USB_SUCCESS) { ... }
usb_get_alt_if(9F), usb_get_cfg(9F), usb_get_dev_data(9F), usb_get_status(9F), usb_pipe_bulk_xfer(9F), usb_pipe_close(9F), usb_pipe_ctrl_xfer(9F), usb_pipe_get_state(9F), usb_pipe_intr_xfer(9F), usb_pipe_isoc_xfer(9F), usb_pipe_reset(9F), usb_pipe_set_private(9F), usb_callback_flags(9S), usb_ep_descr(9S)
Universal Serial Bus 3.1 Specification, http://www.usb.org.
September 16, 2016 | OmniOS |