| 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_SYNCHRONOUSUSBD_SYNCHRONOUS_SIGUSBD_SHORT_XFER_OKUSBD_FORCE_SHORT_XFERThe 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 associated 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_DEVICEUT_READ_INTERFACEUT_READ_ENDPOINTUT_WRITE_DEVICEUT_WRITE_INTERFACEUT_WRITE_ENDPOINTUT_READ_CLASS_DEVICEUT_READ_CLASS_INTERFACEUT_READ_CLASS_OTHERUT_READ_CLASS_ENDPOINTUT_WRITE_CLASS_DEVICEUT_WRITE_CLASS_INTERFACEUT_WRITE_CLASS_OTHERUT_WRITE_CLASS_ENDPOINTUT_READ_VENDOR_DEVICEUT_READ_VENDOR_INTERFACEUT_READ_VENDOR_OTHERUT_READ_VENDOR_ENDPOINTUT_WRITE_VENDOR_DEVICEUT_WRITE_VENDOR_INTERFACEUT_WRITE_VENDOR_OTHERUT_WRITE_VENDOR_ENDPOINTThe 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 initialised,
    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 10.0 |