USBDI(9) | Kernel Developer's Manual | USBDI(9) |
usbdi
—
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
usbd_open_pipe
(struct
usbd_interface *iface,
uint8_t address,
uint8_t flags,
struct usbd_pipe **pipe);
usbd_status
usbd_close_pipe
(struct
usbd_pipe *pipe);
usbd_status
usbd_transfer
(struct
usbd_xfer *xfer);
struct usbd_xfer *
usbd_setup_xfer
(struct
usbd_xfer *xfer, void
*priv, void
*buffer, uint32_t
length, uint16_t
flags, uint32_t
timeout,
usbd_callback);
void
usbd_setup_default_xfer
(struct
usbd_xfer *xfer, struct
usbd_device *dev, void
*priv, uint32_t
timeout,
usb_device_request_t
*req, void
*buffer, uint32_t
length, uint16_t
flags,
usbd_callback);
void
usbd_setup_isoc_xfer
(struct
usbd_xfer *xfer, void
*priv, uint16_t
*frlengths, uint32_t
nframes, uint16_t
flags,
usbd_callback);
void
usbd_get_xfer_status
(struct
usbd_xfer *xfer, void
**priv, void
**buffer, uint32_t
*count, usbd_status
*status);
usb_endpoint_descriptor_t *
usbd_interface2endpoint_descriptor
(struct
usbd_interface *iface,
uint8_t address);
usbd_status
usbd_abort_pipe
(struct
usbd_pipe *pipe);
usbd_status
usbd_abort_default_pipe
(struct
usbd_device *dev);
usbd_status
usbd_clear_endpoint_stall
(struct
usbd_pipe *pipe);
usbd_status
usbd_clear_endpoint_stall_async
(struct
usbd_pipe *pipe);
void
usbd_clear_endpoint_toggle
(struct
usbd_pipe *pipe);
usbd_status
usbd_endpoint_count
(struct
usbd_interface *dev,
uint8_t *count);
usbd_status
usbd_interface_count
(struct
usbd_device *dev, uint8_t
*count);
usbd_status
usbd_interface2device_handle
(struct
usbd_interface *iface,
struct usbd_device
**dev);
usbd_status
usbd_device2interface_handle
(struct
usbd_device *dev, uint8_t
ifaceno, struct
usbd_interface **iface);
struct usbd_device *
usbd_pipe2device_handle
(struct
usbd_pipe *pipe);
int
usbd_create_xfer
(struct
usbd_pipe *pipe, size_t
len, unsigned int
flags, unsigned int
nframes, struct usbd_xfer
**xp);
void
usbd_destroy_xfer
(struct
usbd_xfer *xfer);
void *
usbd_get_buffer
(struct
usbd_xfer *xfer);
usbd_status
usbd_sync_transfer
(struct
usbd_xfer *req);
usbd_status
usbd_sync_transfer_sig
(struct
usbd_xfer *req);
usbd_status
usbd_open_pipe_intr
(struct
usbd_interface *iface,
uint8_t address,
uint8_t flags,
struct usbd_pipe **pipe,
void *priv,
void *buffer,
uint32_t length,
usbd_callback callback,
int interval);
usbd_status
usbd_do_request
(struct
usbd_device *dev,
usb_device_request_t
*req, void
*data);
usbd_status
usbd_do_request_flags
(struct
usbd_device *dev,
usb_device_request_t
*req, void *data,
uint16_t flags,
int *actlen,
uint32_t timo);
usb_interface_descriptor_t *
usbd_get_interface_descriptor
(struct
usbd_interface *iface);
usb_config_descriptor_t *
usbd_get_config_descriptor
(struct
usbd_device *dev);
usb_device_descriptor_t *
usbd_get_device_descriptor
(struct
usbd_device *dev);
usbd_status
usbd_set_interface
(struct
usbd_interface *iface,
int altidx);
int
usbd_get_no_alts
(usb_config_descriptor_t
*iface, int
ifaceno);
usbd_status
usbd_fill_deviceinfo
(struct
usbd_device *dev, struct
usb_device_info *di);
int
usbd_get_interface_altindex
(struct
usbd_interface *iface);
usb_endpoint_descriptor_t *
usbd_get_endpoint_descriptor
(struct
usbd_interface *dev,
uint8_t address);
usb_interface_descriptor_t *
usbd_find_idesc
(usb_config_descriptor_t
*cd, int iindex,
int ano);
usb_endpoint_descriptor_t *
usbd_find_edesc
(usb_config_descriptor_t
*cd, int ifaceidx,
int altidx,
int endptidx);
void
usbd_dopoll
(struct
usbd_interface *iface);
void
usbd_set_polling
(struct
usbd_device *iface, int
val);
const char *
usbd_errstr
(usbd_status
err);
void
usbd_add_dev_event
(int
type, struct usbd_device
*iface);
void
usbd_add_drv_event
(int
type, struct usbd_device
*iface, device_t
dv);
char *
usbd_devinfo_alloc
(struct
usbd_device *iface, int
showclass);
void
usbd_devinfo_free
(char
*str);
const struct usbd_quirks *
usbd_get_quirks
(struct
usbd_device *iface);
usbd_status
usbd_reload_device_desc
(struct
usbd_device *iface);
int
usbd_ratecheck
(struct
timeval *tv);
usbd_status
usbd_get_string
(struct
usbd_device *iface, int
si, char *buf);
usbd_status
usbd_get_string0
(struct
usbd_device *iface, int
si, char *buf,
int unicode);
void
usb_desc_iter_init
(struct
usbd_device *iface,
usbd_desc_iter_t
*iter);
const usb_descriptor_t *
usb_desc_iter_next
(usbd_desc_iter_t
*iter);
void
usb_add_task
(struct
usbd_device *iface,
struct usb_task *task,
int queue);
void
usb_rem_task
(struct
usbd_device *iface,
struct usb_task
*task);
void
usb_init_task
(struct
usb_task *task, void
(*func)(void *), void
*arg, uint8_t,
flags);
const struct usb_devno *
usb_lookup
(const
struct usb_devno *tbl,
uint16_t vendor,
uint16_t product);
usbdi.h
.
usbd_alloc_buffer
(struct
usbd_xfer *xfer, uint32_t
size);
void
usbd_free_buffer
(struct
usbd_xfer *xfer);
usbdi.h
a number of utility
functions have been defined that are accessible through
usbdi_util.h
.
usbd_get_desc
(struct
usbd_device *dev, int
type, int index,
int len,
void *desc);
usbd_status
usbd_get_config_desc
(struct
usbd_device *dev, int
confidx,
usb_config_descriptor_t
*d);
usbd_status
usbd_get_config_desc_full
(struct
usbd_device *, int
dev, void *d,
int size);
usbd_status
usbd_get_device_desc
(struct
usbd_device *dev,
usb_device_descriptor_t
*d);
usbd_status
usbd_set_address
(struct
usbd_device *dev, int
addr);
usbd_status
usbd_get_port_status
(struct
usbd_device *dev, int
port, usb_port_status_t
*ps);
usbd_status
usbd_set_hub_feature
(struct
usbd_device *dev, int
sel);
usbd_status
usbd_clear_hub_feature
(struct
usbd_device *dev, int
sel);
usbd_status
usbd_set_port_feature
(struct
usbd_device *dev, int
port, int sel);
usbd_status
usbd_clear_port_feature
(struct
usbd_device *dev, int
port, int sel);
usbd_status
usbd_get_device_status
(struct
usbd_device *dev,
usb_status_t *st);
usbd_status
usbd_get_hub_status
(struct
usbd_device *dev,
usb_hub_status_t
*st);
usbd_status
usbd_set_protocol
(struct
usbd_interface *dev, int
report);
usbd_status
usbd_get_report_descriptor
(struct
usbd_device *dev, int
ifcno, int repid,
int size,
void *d);
struct usb_hid_descriptor *
usbd_get_hid_descriptor
(struct
usbd_interface *ifc);
usbd_status
usbd_set_report
(struct
usbd_interface *iface,
int type,
int id,
void *data,
int len);
usbd_status
usbd_set_report_async
(struct
usbd_interface *iface,
int type,
int id,
void *data,
int len);
usbd_status
usbd_get_report
(struct
usbd_interface *iface,
int type,
int id,
void *data,
int len);
usbd_status
usbd_set_idle
(struct
usbd_interface *iface,
int duration,
int id);
usbd_status
usbd_alloc_report_desc
(struct
usbd_interface *ifc, void
**descp, int
*sizep, int
mem);
usbd_status
usbd_get_string_desc
(struct
usbd_device *dev, int
sindex, int langid,
usb_string_descriptor_t
*sdesc);
void
usbd_delay_ms
(struct
usbd_device *dev, u_int
ms);
usbd_status
usbd_set_config_no
(struct
usbd_device *dev, int
no, int msg);
usbd_status
usbd_set_config_index
(struct
usbd_device *dev, int
index, int
msg);
usbd_status
usbd_bulk_transfer
(struct
usbd_xfer *xfer, struct
usbd_pipe *pipe, uint16_t
flags, uint32_t
timeout, void *buf,
uint32_t *size);
usbd_status
usbd_intr_transfer
(struct
usbd_xfer *xfer, struct
usbd_pipe *pipe, uint16_t
flags, uint32_t
timeout, void *buf,
uint32_t *size);
void
usb_detach_waitold
(device_t
dv);
void
usb_detach_wakeupold
(device_t
dv);
void
usb_detach_wait
(device_t
dv, kcondvar_t *cv,
kmutex_t *lk);
void
usb_detach_broadcast
(device_t
dv, kcondvar_t
*cv);
There are a number of functions to obtain a handle, descriptor or resource count:
usbd_device2interface_handle
(dev,
ifaceno, iface)usbd_interface2device_handle
(iface,
dev)usbd_pipe2device_handle
(pipe)usbd_interface2endpoint_descriptor
(iface,
address)usbd_endpoint_count
(dev,
count)usbd_interface_count
(dev,
count)Error handling and other return values are described in usbd_status(9).
Additional comments on particular functions:
usbd_errstr
(err)usbd_add_dev_event
(type,
iface)USB_EVENT_CTRLR_ATTACH
,
USB_EVENT_CTRLR_DETACH
,
USB_EVENT_DEVICE_ATTACH
and
USB_EVENT_DEVICE_DETACH
.usbd_add_drv_event
(type,
iface, dv)USB_EVENT_DRIVER_ATTACH
and
USB_EVENT_DRIVER_DETACH
. The
dv corresponds with the
device_t associated with the device attached or
detached.usb_lookup
(tbl,
vendor, product)USB_PRODUCT_ANY
macro can be used to match any
USB product by a particular vendor.usbd_open_pipe
(),
usbd_open_pipe_intr
() and
usbd_close_pipe
() functions. The open functions take
the interface handle iface, the
address of this pipe and flags for
this pipe which currently may be 0, or a combination of
USBD_EXCLUSIVE_USE
, to enable exclusive access to this
interface and address, and USBD_MPSAFE
, to allow
running transfer callbacks on this pipe without first acquiring
kernel_lock
. The
usbd_open_pipe_intr
() takes additional arguments
priv to set the default private handle.
buffer and len to describe the
buffer to be used, callback for the function to call at
interrupt time, and finally the interval for interrupts
to be delivered in milliseconds. The interval may be set
to USBD_DEFAULT_INTERVAL
use the default interval,
specified by the ep. description. It is common to have more than one pipe per
device.
usbd_create_xfer
() and
usbd_destroy_xfer
(), respectively, and are associated
with a pipe at their creation time. The create function takes the pipe handle
pipe, the length of the largest transfer possible
len, possible transfer flags
flags, the number of isochronous frames (or 0) in
nframes.
The data describing the transfer is filled by either
usbd_setup_default_xfer
() for control pipe
transfers, by usbd_setup_xfer
() for bulk and
interrupt transfers, and by usbd_setup_isoc_xfer
()
for isochronous transfers. Private data may be passed between setup and
completion or status calls using the void *priv
argument.
Arguments to the setup functions include the newly allocated xfer, the private data priv, the timeout in milliseconds, for control, bulk and interrupt transfers buffer the data to transfer and its length and for isochronous transfers the frame length frlengths and number of frames nframes, and for default transfers a USB request structure req must be presented. See the INITIALISING USB REQUESTS section for more details on USB requests.
The transfer specific flags that can be set are:
USBD_SYNCHRONOUS
USBD_SYNCHRONOUS_SIG
USBD_SHORT_XFER_OK
USBD_FORCE_SHORT_XFER
The usbd_get_buffer
() function returns the
current kernel address for the buffer suitable for transfer in
xfer.
The usbd_open_pipe
(),
usbd_open_pipe_intr
(),
usbd_close_pipe
(),
usbd_alloc_xfer
(), and
usbd_free_xfer
() can all sleep and should not be
called from interrupt context as a result.
Upon completion the callback function is called, which takes the completed xfer, the private data priv originally assocated with this transfer, and status the status of this transfer.
Transfers are initiated by calling
usbd_transfer
(), and their results made be later
obtained by calling usbd_get_xfer_status, which fills
in the private data priv, original buffer location
buffer, the length length, and
the status of this request.
The usbd_bulk_transfer
() and
usbd_intr_transfer
() functions are used to transfer
data in either an interrupt or bulk fashion, and are front-ends to the
usbd_setup_xfer
(),
usbd_transfer
() and
usbd_get_xfer_status
(), as well as associated error
handling. The usbd_sync_transfer
() is identical to
usbd_transfer
() with the
USBD_SYNCHRONOUS
flag set. The
usbd_sync_transfer_sig
() is identical to
usbd_transfer
() with the
USBD_SYNCHRONOUS
and
USBD_SYNCHRONOUS_SIG
flags set.
Transfers are aborted via this pipe with
usbd_abort_pipe
() and
usbd_abort_default_pipe
().
The usbd_clear_endpoint_stall
() and
usbd_clear_endpoint_stall_async
() functions are used
to clear endpoint halt in either a synchronous or asynchronous fashion. To
clear the toggle state of an endpoint the
usbd_clear_endpoint_toggle
() function should be
used.
A request is described by a
usb_device_request_t which must be initialised as
necessary before calling either usbd_do_request
() or
usbd_do_request_flags
() to submit the request. For
both these functions dev is the handle of the USB
device the request is for, req is the USB request, as
described in the
INITIALISING USB
REQUESTS section, and then data is a buffer
containing the data for the request. For the
usbd_do_request_flags
() function there are
additional flags passed to the
usbd_setup function, actlen a
pointer to fill in with the actual length of this request, and
timo, the number of milliseconds to wait before timing
out this request.
The first two are normal byte values that may be simply assigned,
but the last three must be initialised with the
USETW
() macro.
The bmRequestType holds the request type of this USB request, which describes the intended recipient of the request.
This may be one of:
with one of:
and with one of:
These are also in combinations as:
UT_READ_DEVICE
UT_READ_INTERFACE
UT_READ_ENDPOINT
UT_WRITE_DEVICE
UT_WRITE_INTERFACE
UT_WRITE_ENDPOINT
UT_READ_CLASS_DEVICE
UT_READ_CLASS_INTERFACE
UT_READ_CLASS_OTHER
UT_READ_CLASS_ENDPOINT
UT_WRITE_CLASS_DEVICE
UT_WRITE_CLASS_INTERFACE
UT_WRITE_CLASS_OTHER
UT_WRITE_CLASS_ENDPOINT
UT_READ_VENDOR_DEVICE
UT_READ_VENDOR_INTERFACE
UT_READ_VENDOR_OTHER
UT_READ_VENDOR_ENDPOINT
UT_WRITE_VENDOR_DEVICE
UT_WRITE_VENDOR_INTERFACE
UT_WRITE_VENDOR_OTHER
UT_WRITE_VENDOR_ENDPOINT
The bRequest describes which request is being made. The available values are:
The wValue, wIndex and
wLength are device-specific values and must be
initialised with the USETW
() macro.
UR_GET_STATUS
request operates on a
usb_status_t structure, which has this member:
For device status requests the wStatus member may have either of these bit flags set:
For endpoint status requests the wStatus member may have this bit flag set:
The UR_CLEAR_FEATURE
and
UR_SET_FEATURE
requests clear or set special
features on USB devices. The values for wValue,
wIndex and wLength depend upon
the device and device type.
The UR_SET_ADDRESS
request sets the
virtual USB address of a port using the wValue.
The UR_GET_DESCRIPTOR
and
UR_SET_DESCRIPTOR
requests operate on a
usb_descriptor_t structure, which has these
members:
The bDescriptorType member may be one of the following values:
The usbd_set_interface
() function can be
used to change the index used for transfers on this interface as obtained
via usbd_device2interface_handle
().
usb_detach_wait
() should
be called on the dv associated with this USB device and,
typically, a device-specific condition variable cv. and
mutex lk protecting this reference count state. At the
end of each syscall function, if the reference count is decremented to less
than zero, then usb_detach_broadcast
() must be called
on the dv and cv that is being
waited on with usb_detach_wait
().
The are another pair of functions with similar functionality that
do not use a condition variable or mutex and should be avoided in new code.
The usb_detach_waitold
() function works like
usb_detach_wait
(), and the
usb_detach_wakeupold
() function works like
usb_detach_broadcast
().
The usb_init_task
() function takes a
pointer to a struct usb_task that will be initalised,
a function to call for this task func, the argument to
pass to func, arg, and the task
flags flags. If the flags
argument is USB_TASKQ_MPSAFE
, the
func function will be called without first acquiring
kernel_lock
.
To invoke the task callback the
usb_add_task
() function should be called with the
iface associated with this device, the task structure
task, and the queue to run
against, either USB_TASKQ_HC
for operations
initiated by host controllers or USB_TASKQ_DRIVER
for operations initiated by USB drivers.
To deschedule a potentially running task the
usb_rem_task
() function should be called.
The driver using these facilities is expected to provide the
necessary serialisation between usb_init_task
(),
usb_add_task
() and
usb_rem_task
() for each specific
struct usb_task.
usbdi
interface first appeared in
NetBSD 1.4. The interface is based on an early
definition from the OpenUSBDI group within the USB organisation. Right after
this definition the OpenUSBDI development got closed for open source
developers, so this interface has not followed the further changes. The
OpenUSBDI specification is now available again, but looks different.
April 24, 2016 | NetBSD 9.0 |