8225e7146f
Bump date.
988 lines
30 KiB
Groff
988 lines
30 KiB
Groff
.\" $NetBSD: usbdi.9,v 1.29 2013/09/26 16:18:52 skrll Exp $
|
|
.\"
|
|
.\" Copyright (c) 2012 Matthew R. Green
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\" 3. The name of the author may not be used to endorse or promote products
|
|
.\" derived from this software without specific prior written permission.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
.\" SUCH DAMAGE.
|
|
.\"
|
|
.\"
|
|
.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" This code is derived from software contributed to The NetBSD Foundation
|
|
.\" by Lennart Augustsson.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
.\" POSSIBILITY OF SUCH DAMAGE.
|
|
.\"
|
|
.Dd September 26, 2013
|
|
.Dt USBDI 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm usbdi
|
|
.Nd USB device drivers interface
|
|
.Sh SYNOPSIS
|
|
.In dev/usb/usb.h
|
|
.In dev/usb/usbdi.h
|
|
.In dev/usb/usbdi_util.h
|
|
.Ss Functions offered by usbdi.h
|
|
.Ft usbd_status
|
|
.Fn usbd_open_pipe "usbd_interface_handle iface" "uint8_t address" \
|
|
"uint8_t flags" "usbd_pipe_handle *pipe"
|
|
.Ft usbd_status
|
|
.Fn usbd_close_pipe "usbd_pipe_handle pipe"
|
|
.Ft usbd_status
|
|
.Fn usbd_transfer "usbd_xfer_handle xfer"
|
|
.Ft usbd_xfer_handle
|
|
.Fn usbd_alloc_xfer "usbd_device_handle dev"
|
|
.Ft usbd_status
|
|
.Fn usbd_free_xfer "usbd_xfer_handle xfer"
|
|
.Ft void
|
|
.Fn usbd_setup_xfer "usbd_xfer_handle xfer" "usbd_pipe_handle pipe" \
|
|
"usbd_private_handle priv" "void *buffer" "uint32_t length" \
|
|
"uint16_t flags" "uint32_t timeout" "usbd_callback"
|
|
.Ft void
|
|
.Fn usbd_setup_default_xfer "usbd_xfer_handle xfer" \
|
|
"usbd_device_handle dev" "usbd_private_handle priv" \
|
|
"uint32_t timeout" "usb_device_request_t *req" " void *buffer" \
|
|
"uint32_t length" "uint16_t flags" "usbd_callback"
|
|
.Ft void
|
|
.Fn usbd_setup_isoc_xfer "usbd_xfer_handle xfer" "usbd_pipe_handle pipe" \
|
|
"usbd_private_handle priv" "uint16_t *frlengths" \
|
|
"uint32_t nframes" "uint16_t flags" "usbd_callback"
|
|
.Ft void
|
|
.Fn usbd_get_xfer_status "usbd_xfer_handle xfer" "usbd_private_handle *priv" \
|
|
"void **buffer" "uint32_t *count" "usbd_status *status"
|
|
.Ft usb_endpoint_descriptor_t *
|
|
.Fn usbd_interface2endpoint_descriptor "usbd_interface_handle iface" \
|
|
"uint8_t address"
|
|
.Ft usbd_status
|
|
.Fn usbd_abort_pipe "usbd_pipe_handle pipe"
|
|
.Ft usbd_status
|
|
.Fn usbd_abort_default_pipe "usbd_device_handle dev"
|
|
.Ft usbd_status
|
|
.Fn usbd_clear_endpoint_stall "usbd_pipe_handle pipe"
|
|
.Ft usbd_status
|
|
.Fn usbd_clear_endpoint_stall_async "usbd_pipe_handle pipe"
|
|
.Ft void
|
|
.Fn usbd_clear_endpoint_toggle "usbd_pipe_handle pipe"
|
|
.Ft usbd_status
|
|
.Fn usbd_endpoint_count "usbd_interface_handle dev" "uint8_t *count"
|
|
.Ft usbd_status
|
|
.Fn usbd_interface_count "usbd_device_handle dev" "uint8_t *count"
|
|
.Ft usbd_status
|
|
.Fn usbd_interface2device_handle "usbd_interface_handle iface" "usbd_device_handle *dev"
|
|
.Ft usbd_status
|
|
.Fn usbd_device2interface_handle "usbd_device_handle dev" "uint8_t ifaceno" "usbd_interface_handle *iface"
|
|
.Pp
|
|
.Ft usbd_device_handle
|
|
.Fn usbd_pipe2device_handle "usbd_pipe_handle pipe"
|
|
.Ft void *
|
|
.Fn usbd_alloc_buffer "usbd_xfer_handle req" "uint32_t size"
|
|
.Ft void
|
|
.Fn usbd_free_buffer "usbd_xfer_handle req"
|
|
.Ft void *
|
|
.Fn usbd_get_buffer "usbd_xfer_handle xfer"
|
|
.Ft usbd_status
|
|
.Fn usbd_sync_transfer "usbd_xfer_handle req"
|
|
.Ft usbd_status
|
|
.Fn usbd_sync_transfer_sig "usbd_xfer_handle req"
|
|
.Ft usbd_status
|
|
.Fn usbd_open_pipe_intr "usbd_interface_handle iface" "uint8_t address" \
|
|
"uint8_t flags" "usbd_pipe_handle *pipe" \
|
|
"usbd_private_handle priv" "void *buffer" \
|
|
"uint32_t length" "usbd_callback callback" "int interval"
|
|
.Ft usbd_status
|
|
.Fn usbd_do_request "usbd_device_handle dev" "usb_device_request_t *req" \
|
|
"void *data"
|
|
.Ft usbd_status
|
|
.Fn usbd_do_request_flags "usbd_device_handle dev" \
|
|
"usb_device_request_t *req" "void *data" "uint16_t flags" "int *actlen" \
|
|
"u_int32_t timo"
|
|
.\" usbd_do_request_async() not used outside of usbdi*
|
|
.Ft usb_interface_descriptor_t *
|
|
.Fn usbd_get_interface_descriptor "usbd_interface_handle iface"
|
|
.Ft usb_config_descriptor_t *
|
|
.Fn usbd_get_config_descriptor "usbd_device_handle dev"
|
|
.Ft usb_device_descriptor_t *
|
|
.Fn usbd_get_device_descriptor "usbd_device_handle dev"
|
|
.Ft usbd_status
|
|
.Fn usbd_set_interface "usbd_interface_handle iface" "int altidx"
|
|
.Ft int
|
|
.Fn usbd_get_no_alts "usb_config_descriptor_t *iface" "int ifaceno"
|
|
.Ft usbd_status
|
|
.\" unused, delete?
|
|
.\" .Fn usbd_get_interface "usbd_interface_handle iface" "uint8_t *aiface"
|
|
.\" .Ft void
|
|
.Fn usbd_fill_deviceinfo "usbd_device_handle dev" "struct usb_device_info *di"
|
|
.Ft int
|
|
.Fn usbd_get_interface_altindex "usbd_interface_handle iface"
|
|
.Ft usb_endpoint_descriptor_t *
|
|
.Fn usbd_get_endpoint_descriptor "usbd_interface_handle dev" \
|
|
"u_int8_t address"
|
|
.Ft usb_interface_descriptor_t *
|
|
.Fn usbd_find_idesc "usb_config_descriptor_t *cd" "int iindex" "int ano"
|
|
.Ft usb_endpoint_descriptor_t *
|
|
.Fn usbd_find_edesc "usb_config_descriptor_t *cd" "int ifaceidx" "int altidx" \
|
|
"int endptidx"
|
|
.Ft void
|
|
.Fn usbd_dopoll "usbd_interface_handle iface"
|
|
.Ft void
|
|
.Fn usbd_set_polling "usbd_device_handle iface" "int val"
|
|
.Ft const char *
|
|
.Fn usbd_errstr "usbd_status err"
|
|
.Ft void
|
|
.Fn usbd_add_dev_event "int type" "usbd_device_handle iface"
|
|
.Ft void
|
|
.Fn usbd_add_drv_event "int type" "usbd_device_handle iface" "device_t dv"
|
|
.Ft char *
|
|
.Fn usbd_devinfo_alloc "usbd_device_handle iface" "int showclass"
|
|
.Ft void
|
|
.Fn usbd_devinfo_free "char *str"
|
|
.Ft const struct usbd_quirks *
|
|
.Fn usbd_get_quirks "usbd_device_handle iface"
|
|
.Ft usbd_status
|
|
.Fn usbd_reload_device_desc "usbd_device_handle iface"
|
|
.Ft int
|
|
.Fn usbd_ratecheck "struct timeval *tv"
|
|
.Ft usbd_status
|
|
.Fn usbd_get_string "usbd_device_handle iface" "int si" "char *buf"
|
|
.Ft usbd_status
|
|
.Fn usbd_get_string0 "usbd_device_handle iface" "int" si "char *buf" \
|
|
"int unicode"
|
|
.Ft void
|
|
.Fn usb_desc_iter_init "usbd_device_handle iface" "usbd_desc_iter_t *iter"
|
|
.Ft const usb_descriptor_t *
|
|
.Fn usb_desc_iter_next "usbd_desc_iter_t *iter"
|
|
.Ft void
|
|
.Fn usb_add_task "usbd_device_handle iface" "struct usb_task *task" \
|
|
"int queue"
|
|
.Ft void
|
|
.Fn usb_rem_task "usbd_device_handle iface" "struct usb_task *task"
|
|
.Ft void
|
|
.Fn usb_init_task "struct usb_task *task" "void (*func)(void *)" \
|
|
"void *arg" uint8_t flags
|
|
.Ft const struct usb_devno *
|
|
.Fn usb_lookup "const struct usb_devno *tbl" \
|
|
"u_int16_t vendor" "u_int16_t product"
|
|
.Ss Utilities from usbdi_util.h
|
|
Based on the routines in
|
|
.Dv usbdi.h
|
|
a number of utility functions have been defined that are accessible
|
|
through
|
|
.Dv usbdi_util.h .
|
|
.Ft usbd_status
|
|
.Fn usbd_get_desc "usbd_device_handle dev" "int type" "int index" \
|
|
"int len" "void *desc"
|
|
.Ft usbd_status
|
|
.Fn usbd_get_config_desc "usbd_device_handle dev" "int confidx" \
|
|
"usb_config_descriptor_t *d"
|
|
.Ft usbd_status
|
|
.Fn usbd_get_config_desc_full "usbd_device_handle" "int dev" "void *d" "int size"
|
|
.Ft usbd_status
|
|
.Fn usbd_get_device_desc "usbd_device_handle dev" \
|
|
"usb_device_descriptor_t *d"
|
|
.Ft usbd_status
|
|
.Fn usbd_set_address "usbd_device_handle dev" "int addr"
|
|
.Ft usbd_status
|
|
.Fn usbd_get_port_status "usbd_device_handle dev" "intp ort" "usb_port_status_t *ps"
|
|
.Ft usbd_status
|
|
.Fn usbd_set_hub_feature "usbd_device_handle dev" "int sel"
|
|
.Ft usbd_status
|
|
.Fn usbd_clear_hub_feature "usbd_device_handle dev" "int sel"
|
|
.Ft usbd_status
|
|
.Fn usbd_set_port_feature "usbd_device_handle dev" "int port" "int sel"
|
|
.Ft usbd_status
|
|
.Fn usbd_clear_port_feature "usbd_device_handle dev" "int port" "int sel"
|
|
.Ft usbd_status
|
|
.Fn usbd_get_device_status "usbd_device_handle dev" "usb_status_t *st"
|
|
.Ft usbd_status
|
|
.Fn usbd_get_hub_status "usbd_device_handle dev" "usb_hub_status_t *st"
|
|
.Ft usbd_status
|
|
.Fn usbd_set_protocol "usbd_interface_handle dev" "int report"
|
|
.Ft usbd_status
|
|
.Fn usbd_get_report_descriptor "usbd_device_handle dev" "int ifcno" "int repid" "int size" "void *d"
|
|
.Ft struct usb_hid_descriptor *
|
|
.Fn usbd_get_hid_descriptor "usbd_interface_handle ifc"
|
|
.Ft usbd_status
|
|
.Fn usbd_set_report "usbd_interface_handle iface" "nt type" "int id" "void *data" "int len"
|
|
.Ft usbd_status
|
|
.Fn usbd_set_report_async "usbd_interface_handle iface" "int type" "int id" "void *data" "int len"
|
|
.Ft usbd_status
|
|
.Fn usbd_get_report "usbd_interface_handle iface" "int type" "int id" "void *data" "int len"
|
|
.Ft usbd_status
|
|
.Fn usbd_set_idle "usbd_interface_handle iface" "int duration" "int id"
|
|
.Ft usbd_status
|
|
.Fn usbd_alloc_report_desc "usbd_interface_handle ifc" "void **descp" \
|
|
"int *sizep" "int mem"
|
|
.\" private API between ugen(4) and usbdi(9)
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_get_config "usbd_device_handle dev" "uint8_t *conf"
|
|
.Ft usbd_status
|
|
.Fn usbd_get_string_desc "usbd_device_handle dev" "int sindex" "int langid" \
|
|
"usb_string_descriptor_t *sdesc"
|
|
.Ft void
|
|
.Fn usbd_delay_ms "usbd_device_handle dev" "u_int ms"
|
|
.Ft usbd_status
|
|
.Fn usbd_set_config_no "usbd_device_handle dev" "int no" "int msg"
|
|
.Ft usbd_status
|
|
.Fn usbd_set_config_index "usbd_device_handle dev" "int index" "int msg"
|
|
.Ft usbd_status
|
|
.Fn usbd_bulk_transfer "usbd_xfer_handle xfer" "usbd_pipe_handle pipe" \
|
|
"uint16_t flags" "uint32_t timeout" "void *buf" "uint32_t *size" "char *lbl"
|
|
.Ft usbd_status
|
|
.Fn usbd_intr_transfer "usbd_xfer_handle xfer" "usbd_pipe_handle pipe" \
|
|
"uint16_t flags" "uint32_t timeout" "void *buf" "uint32_t *size" "char *lbl"
|
|
.Ft void
|
|
.Fn usb_detach_waitold "device_t dv"
|
|
.Ft void
|
|
.Fn usb_detach_wakeupold "device_t dv"
|
|
.Ft void
|
|
.Fn usb_detach_wait "device_t dv" "kcondvar_t *cv" "kmutex_t *lk"
|
|
.Ft void
|
|
.Fn usb_detach_broadcast "device_t dv" "kcondvar_t *cv"
|
|
.Sh DESCRIPTION
|
|
Device driver access to the USB bus centers around transfers.
|
|
A transfer describes a communication with a USB device.
|
|
A transfer is an abstract concept that can result in several
|
|
physical packets being transferred to or from a device.
|
|
A transfer is described by the
|
|
.Va usbd_xfer_handle
|
|
cookie.
|
|
A pipe is a logical connection to a USB device.
|
|
It is described by the
|
|
.Va usbd_pipe_handle
|
|
cookie.
|
|
See the
|
|
.Sx TRANSFERS
|
|
and
|
|
.Sx PIPES
|
|
sections for more details.
|
|
.Pp
|
|
There are a number of functions to obtain a handle, descriptor
|
|
of resource count:
|
|
.Bl -tag -width 10n
|
|
.It Fn usbd_device2interface_handle dev ifaceno iface
|
|
Fills in
|
|
.Fa iface
|
|
with the
|
|
.Ft usbd_interface_handle
|
|
for the USB device
|
|
.Fa dev
|
|
on interface number
|
|
.Fa ifaceno .
|
|
.It Fn usbd_interface2device_handle iface dev
|
|
Fills in
|
|
.Fa dev
|
|
with the
|
|
.Ft usbd_device_handle
|
|
pointer for interface
|
|
.Fa iface .
|
|
.\" usbd_pipe2device_handle is unused; remove from usbdi?
|
|
.It Fn usbd_pipe2device_handle pipe
|
|
Returns the
|
|
.Ft usbd_device_handle
|
|
associated with
|
|
.Fa pipe .
|
|
.It Fn usbd_interface2endpoint_descriptor iface address
|
|
Returns the
|
|
.Ft usb_endpoint_descriptor_t *
|
|
for the particular interface
|
|
.Fa iface
|
|
at address
|
|
.Fa address .
|
|
.\" XXX describe what a .Ft usb_endpoint_descriptor_t is.
|
|
.It Fn usbd_endpoint_count dev count
|
|
.It Fn usbd_interface_count dev count
|
|
Fills in
|
|
.Fa count
|
|
with the number of endpoint or interfaces the USB device
|
|
.Fa dev
|
|
has.
|
|
.El
|
|
.Pp
|
|
Error handling and other return values are described in
|
|
.Xr usbd_status 9 .
|
|
.Pp
|
|
Additional comments on particular functions:
|
|
.Bl -tag -width 10n
|
|
.It Fn usbd_errstr err
|
|
Returns the string associated with
|
|
.Fa err .
|
|
.It Fn usbd_add_dev_event type iface
|
|
The
|
|
.Ar type
|
|
must be one of
|
|
.Dv USB_EVENT_CTRLR_ATTACH ,
|
|
.Dv USB_EVENT_CTRLR_DETACH ,
|
|
.Dv USB_EVENT_DEVICE_ATTACH
|
|
and
|
|
.Dv USB_EVENT_DEVICE_DETACH .
|
|
.It Fn usbd_add_drv_event type iface dv
|
|
The
|
|
.Fa type
|
|
must be one of
|
|
.Dv USB_EVENT_DRIVER_ATTACH
|
|
and
|
|
.Dv USB_EVENT_DRIVER_DETACH .
|
|
The
|
|
.Fa dv
|
|
corresponds with the
|
|
.Ft device_t
|
|
associated with the device attached or detached.
|
|
.It Fn usb_lookup tbl vendor product
|
|
Lookup a USB device.
|
|
The returned
|
|
.Va struct usb_devno
|
|
pointer has these members:
|
|
.Bl -item -offset offset -compact
|
|
.It
|
|
.Vt u_int16_t ud_vendor ;
|
|
.It
|
|
.Vt u_int16_t ud_product ;
|
|
.El
|
|
The
|
|
.Dv USB_PRODUCT_ANY
|
|
macro can be used to match any USB product by a particular vendor.
|
|
.El
|
|
.\"
|
|
.\" XXX functions missing descriptions in usbdi.h XXX
|
|
.\"
|
|
.\" .Fn usbd_get_interface_descriptor "usbd_interface_handle iface"
|
|
.\" .Fn usbd_get_config_descriptor "usbd_device_handle dev"
|
|
.\" .Fn usbd_get_device_descriptor "usbd_device_handle dev"
|
|
.\" .Fn usbd_get_no_alts "usb_config_descriptor_t *iface" "int ifaceno"
|
|
.\" unused, delete?
|
|
.\" .Fn usbd_get_interface "usbd_interface_handle iface" "uint8_t *aiface"
|
|
.\" .Fn usbd_fill_deviceinfo "usbd_device_handle dev" "struct usb_device_info *di"
|
|
.\" .Fn usbd_get_interface_altindex "usbd_interface_handle iface"
|
|
.\" .Fn usbd_get_endpoint_descriptor "usbd_interface_handle dev" \
|
|
.\" "u_int8_t address"
|
|
.\" .Fn usbd_find_idesc "usb_config_descriptor_t *cd" "int iindex" "int ano"
|
|
.\" .Fn usbd_find_edesc "usb_config_descriptor_t *cd" "int ifaceidx" "int altidx" \
|
|
.\" "int endptidx"
|
|
.\" .Fn usbd_dopoll "usbd_interface_handle iface"
|
|
.\" .Fn usbd_set_polling" usbd_device_handle iface" "int val"
|
|
.\"
|
|
.\" .Fn usbd_add_dev_event "int type" "usbd_device_handle iface"
|
|
.\" .Fn usbd_add_drv_event "int type" "usbd_device_handle iface" "device_t dv"
|
|
.\"
|
|
.\" .Fn usbd_devinfo_alloc "usbd_device_handle iface" "int showclass"
|
|
.\" .Fn usbd_devinfo_free "char *str"
|
|
.\"
|
|
.\" .Fn usbd_get_quirks "usbd_device_handle iface"
|
|
.\" .Fn usbd_reload_device_desc "usbd_device_handle iface"
|
|
.\" .Fn usbd_ratecheck "struct timeval *tv"
|
|
.\" .Fn usbd_get_string "usbd_device_handle iface" "int si" "char *buf"
|
|
.\" .Fn usbd_get_string0 "usbd_device_handle iface" "int" si "char *buf" \
|
|
.\" "int unicode"
|
|
.\"
|
|
.\" .Fn usb_desc_iter_init "usbd_device_handle iface" "usbd_desc_iter_t *iter"
|
|
.\" .Fn usb_desc_iter_next "usbd_desc_iter_t *iter"
|
|
.\"
|
|
.\" XXX functions missing descriptions in usbdi.h XXX
|
|
.\"
|
|
.\" .Dv usbdi_util.h .
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_get_desc "usbd_device_handle dev" "int type" "int index" \
|
|
.\" "int len" "void *desc"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_get_config_desc "usbd_device_handle dev" "int confidx" \
|
|
.\" "usb_config_descriptor_t *d"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_get_config_desc_full "usbd_device_handle" "int dev" "void *d" "int size"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_get_device_desc "usbd_device_handle dev" \
|
|
.\" "usb_device_descriptor_t *d"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_set_address "usbd_device_handle dev" "int addr"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_get_port_status "usbd_device_handle dev" "intp ort" "usb_port_status_t *ps"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_set_hub_feature "usbd_device_handle dev" "int sel"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_clear_hub_feature "usbd_device_handle dev" "int sel"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_set_port_feature "usbd_device_handle dev" "int port" "int sel"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_clear_port_feature "usbd_device_handle dev" "int port" "int sel"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_get_device_status "usbd_device_handle dev" "usb_status_t *st"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_get_hub_status "usbd_device_handle dev" "usb_hub_status_t *st"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_set_protocol "usbd_interface_handle dev" "int report"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_get_report_descriptor "usbd_device_handle dev" "int ifcno" "int repid" "int size" "void *d"
|
|
.\" .Ft struct usb_hid_descriptor *
|
|
.\" .Fn usbd_get_hid_descriptor "usbd_interface_handle ifc"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_set_report "usbd_interface_handle iface" "nt type" "int id" "void *data" "int len"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_set_report_async "usbd_interface_handle iface" "int type" "int id" "void *data" "int len"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_get_report "usbd_interface_handle iface" "int type" "int id" "void *data" "int len"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_set_idle "usbd_interface_handle iface" "int duration" "int id"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_alloc_report_desc "usbd_interface_handle ifc" "void **descp" \
|
|
.\" "int *sizep" "int mem"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_get_string_desc "usbd_device_handle dev" "int sindex" "int langid" \
|
|
.\" "usb_string_descriptor_t *sdesc"
|
|
.\" .Ft void
|
|
.\" .Fn usbd_delay_ms "usbd_device_handle dev" "u_int ms"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_set_config_no "usbd_device_handle dev" "int no" "int msg"
|
|
.\" .Ft usbd_status
|
|
.\" .Fn usbd_set_config_index "usbd_device_handle dev" "int index" "int msg"
|
|
.\" .Ft usbd_status
|
|
.\"
|
|
.Sh PIPES
|
|
Pipes are created and destroyed by using the
|
|
.Fn usbd_open_pipe ,
|
|
.Fn usbd_open_pipe_intr
|
|
and
|
|
.Fn usbd_close_pipe
|
|
functions.
|
|
The open functions take the interface handle
|
|
.Fa iface ,
|
|
the
|
|
.Fa address
|
|
of this pipe and
|
|
.Fa flags
|
|
for this pipe which currently may be 0, or a combination of
|
|
.Dv USBD_EXCLUSIVE_USE ,
|
|
to enable exclusive access to this interface and address, and
|
|
.Dv USBD_MPSAFE ,
|
|
to allow running transfer callbacks on this pipe without first acquiring
|
|
.Dv kernel_lock .
|
|
The
|
|
.Fn usbd_open_pipe_intr
|
|
takes additional arguments
|
|
.Fa priv
|
|
to set the default private handle.
|
|
.Fa buffer
|
|
and
|
|
.Fa len
|
|
to describe the buffer to be used,
|
|
.Fa callback
|
|
for the function to call at interrupt time, and finally the
|
|
.Fa interval
|
|
for interrupts to be delivered in milliseconds.
|
|
The
|
|
.Fa interval
|
|
may be set to
|
|
.Dv USBD_DEFAULT_INTERVAL
|
|
use the default interval, specified by the ep. description.
|
|
It is common to have more than one pipe per device.
|
|
.Sh TRANSFERS
|
|
Transfers are allocated and deallocated with
|
|
.Fn usbd_alloc_xfer
|
|
and
|
|
.Fn usbd_free_xfer ,
|
|
respectively, and are associated with a pipe at their creation time.
|
|
.Pp
|
|
The data describing the transfer is filled by either
|
|
.Fn usbd_setup_default_xfer
|
|
for control pipe transfers, by
|
|
.Fn usbd_setup_xfer
|
|
for bulk and interrupt transfers, and by
|
|
.Fn usbd_setup_isoc_xfer
|
|
for isochronous transfers.
|
|
Private data may be passed between setup and completion or status
|
|
calls using the
|
|
.Ft usbd_private_handle priv
|
|
argument, which must be an integral type.
|
|
.Pp
|
|
Arguments to the setup functions include the newly allocated
|
|
.Fa xfer ,
|
|
the
|
|
.Fa pipe
|
|
to associate this transfer with,
|
|
the private data
|
|
.Fa priv ,
|
|
the
|
|
.Fa timeout
|
|
in milliseconds,
|
|
for control, bulk and interrupt transfers
|
|
.Fa buffer
|
|
the data to transfer and its
|
|
.Fa length
|
|
and for isochronous transfers the frame length
|
|
.Fa frlengths
|
|
and number of frames
|
|
.Fa nframes ,
|
|
and for default transfers a USB request structure
|
|
.Fa req
|
|
must be presented.
|
|
See the
|
|
.Sx INITIALISING USB REQUESTS
|
|
section for more details on USB requests.
|
|
.Pp
|
|
The transfer specific
|
|
.Fa flags
|
|
that can be set are:
|
|
.Bl -tag -width 10n
|
|
.It Dv USBD_NO_COPY
|
|
Do not copy data to DMA buffer
|
|
.It Dv USBD_SYNCHRONOUS
|
|
Wait for completion
|
|
.It Dv USBD_SYNCHRONOUS_SIG
|
|
When waiting for completion, allow signals to trigger wake up.
|
|
.It Dv USBD_SHORT_XFER_OK
|
|
Short reads are not an error
|
|
.It Dv USBD_FORCE_SHORT_XFER
|
|
Force last short packet on write
|
|
.El
|
|
.Pp
|
|
To allocate buffers suitable for USB tranfers (i.e., DMA capable), the
|
|
.Fn usbd_alloc_buffer
|
|
function should be used on the specified
|
|
.Fa xfer
|
|
for
|
|
.Fa size
|
|
bytes of space.
|
|
The
|
|
.Fn usbd_free_buffer
|
|
function can be used to free the buffer after use.
|
|
The
|
|
.Fn usbd_get_buffer
|
|
function returns the current kernel address for the DMA-capable buffer
|
|
in
|
|
.Fa xfer .
|
|
.Pp
|
|
Upon completion the
|
|
.Fa callback
|
|
function is called, which takes the completed
|
|
.Fa xfer ,
|
|
the private data
|
|
.Fa priv
|
|
originally assocated with this transfer, and
|
|
.Fa status
|
|
the status of this transfer.
|
|
.Pp
|
|
Transfers are initiated by calling
|
|
.Fn usbd_transfer ,
|
|
and their results made be later obtained by calling
|
|
.Fa usbd_get_xfer_status ,
|
|
which fills in the private data
|
|
.Fa priv ,
|
|
original buffer location
|
|
.Fa buffer ,
|
|
the length
|
|
.Fa length ,
|
|
and the
|
|
.Fa status
|
|
of this request.
|
|
.Pp
|
|
The
|
|
.Fn usbd_bulk_transfer
|
|
and
|
|
.Fn usbd_intr_transfer
|
|
functions are used to transfer data in either an interrupt or
|
|
bulk fashion, and are front-ends to the
|
|
.Fn usbd_setup_xfer ,
|
|
.Fn usbd_transfer
|
|
and
|
|
.Fn usbd_get_xfer_status ,
|
|
as well as associated error handling.
|
|
The
|
|
.Fa lbl
|
|
option is deprecated and will be removed.
|
|
The
|
|
.Fn usbd_sync_transfer
|
|
is identical to
|
|
.Fn usbd_transfer
|
|
with the
|
|
.Dv USBD_SYNCHRONOUS
|
|
flag set.
|
|
The
|
|
.Fn usbd_sync_transfer_sig
|
|
is identical to
|
|
.Fn usbd_transfer
|
|
with the
|
|
.Dv USBD_SYNCHRONOUS
|
|
and
|
|
.Dv USBD_SYNCHRONOUS_SIG
|
|
flags set.
|
|
.Pp
|
|
Transfers are aborted via this pipe with
|
|
.Fn usbd_abort_pipe
|
|
and
|
|
.Fn usbd_abort_default_pipe .
|
|
.Pp
|
|
The
|
|
.Fn usbd_clear_endpoint_stall
|
|
and
|
|
.Fn 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
|
|
.Fn usbd_clear_endpoint_toggle
|
|
function should be used.
|
|
.Pp
|
|
A request is described by a
|
|
.Va usb_device_request_t
|
|
which must be initialised as necessary before calling either
|
|
.Fn usbd_do_request
|
|
or
|
|
.Fn usbd_do_request_flags
|
|
to submit the request.
|
|
For both these functions
|
|
.Fa dev
|
|
is the handle of the USB device the request is for,
|
|
.Fa req
|
|
is the USB request, as described in the
|
|
.Sx INITIALISING USB REQUESTS
|
|
section, and then
|
|
.Fa data
|
|
is a buffer containing the data
|
|
.\" (if any)????
|
|
for the request.
|
|
For the
|
|
.Fn usbd_do_request_flags
|
|
function there are additional
|
|
.Fa flags
|
|
passed to the
|
|
.Fa usbd_setup
|
|
function,
|
|
.Fa actlen
|
|
a pointer to fill in with the actual length of this request, and
|
|
.Fa timo ,
|
|
the number of milliseconds to wait before timing out this request.
|
|
.Sh INITIALISING USB REQUESTS
|
|
There are 5 members of a
|
|
.Va usb_device_request_t
|
|
that must be initialised:
|
|
.Pp
|
|
.Bl -item -offset offset -compact
|
|
.It
|
|
.Vt uByte bmRequestType ;
|
|
.It
|
|
.Vt uByte bRequest ;
|
|
.It
|
|
.Vt uWord wValue ;
|
|
.It
|
|
.Vt uWord wIndex ;
|
|
.It
|
|
.Vt uWord wLength ;
|
|
.El
|
|
.Pp
|
|
The first two are normal byte values that may be simply assigned,
|
|
but the last three must be initialised with the
|
|
.Fn USETW
|
|
macro.
|
|
.Pp
|
|
The
|
|
.Fa bmRequestType
|
|
holds the request type of this USB request, which describes the
|
|
indended recipient of the request.
|
|
.Pp
|
|
This may be one of:
|
|
.Bl -tag -width UT_WRITEXX -offset offset -compact
|
|
.It Dv UT_WRITE
|
|
.It Dv UT_READ
|
|
.El
|
|
.Pp
|
|
with one of:
|
|
.Bl -tag -width UT_STANDARDXX -offset offset -compact
|
|
.It Dv UT_STANDARD
|
|
.It Dv UT_CLASS
|
|
.It Dv UT_VENDOR
|
|
.El
|
|
.Pp
|
|
and with one of:
|
|
.Bl -tag -width UT_INTERFACEXX -offset offset -compact
|
|
.It Dv UT_DEVICE
|
|
.It Dv UT_INTERFACE
|
|
.It Dv UT_ENDPOINT
|
|
.It Dv UT_OTHER
|
|
.El
|
|
.Pp
|
|
These are also in combinations as:
|
|
.Bl -tag -width UT_WRITE_VENDOR_INTERFACEXX -offset offset -compact
|
|
.It Dv UT_READ_DEVICE
|
|
.It Dv UT_READ_INTERFACE
|
|
.It Dv UT_READ_ENDPOINT
|
|
.It Dv UT_WRITE_DEVICE
|
|
.It Dv UT_WRITE_INTERFACE
|
|
.It Dv UT_WRITE_ENDPOINT
|
|
.It Dv UT_READ_CLASS_DEVICE
|
|
.It Dv UT_READ_CLASS_INTERFACE
|
|
.It Dv UT_READ_CLASS_OTHER
|
|
.It Dv UT_READ_CLASS_ENDPOINT
|
|
.It Dv UT_WRITE_CLASS_DEVICE
|
|
.It Dv UT_WRITE_CLASS_INTERFACE
|
|
.It Dv UT_WRITE_CLASS_OTHER
|
|
.It Dv UT_WRITE_CLASS_ENDPOINT
|
|
.It Dv UT_READ_VENDOR_DEVICE
|
|
.It Dv UT_READ_VENDOR_INTERFACE
|
|
.It Dv UT_READ_VENDOR_OTHER
|
|
.It Dv UT_READ_VENDOR_ENDPOINT
|
|
.It Dv UT_WRITE_VENDOR_DEVICE
|
|
.It Dv UT_WRITE_VENDOR_INTERFACE
|
|
.It Dv UT_WRITE_VENDOR_OTHER
|
|
.It Dv UT_WRITE_VENDOR_ENDPOINT
|
|
.El
|
|
.Pp
|
|
The
|
|
.Fa bRequest
|
|
describes which request is being made.
|
|
The available values are:
|
|
.Bl -tag -width UR_GET_DESCRIPTORXX -offset offset -compact
|
|
.It Dv UR_GET_STATUS
|
|
.It Dv UR_CLEAR_FEATURE
|
|
.It Dv UR_SET_FEATURE
|
|
.It Dv UR_SET_ADDRESS
|
|
.It Dv UR_GET_DESCRIPTOR
|
|
.It Dv UR_SET_DESCRIPTOR
|
|
.\" these have API front ends
|
|
.\" .It Dv UR_GET_CONFIG
|
|
.\" api usbd_get_config() (ugen private)
|
|
.\" .It Dv UR_SET_CONFIG
|
|
.\" static api usbd_set_config() (usb_subr private)
|
|
.\" .It Dv UR_GET_INTERFACE
|
|
.\" .It Dv UR_SET_INTERFACE
|
|
.\" this isn't supported
|
|
.\" .It Dv UR_SYNCH_FRAME
|
|
.El
|
|
.Pp
|
|
The
|
|
.Fa wValue ,
|
|
.Fa wIndex
|
|
and
|
|
.Fa wLength
|
|
are device-specific values and must be initialised with the
|
|
.Fn USETW
|
|
macro.
|
|
.Sh USB REQUEST TYPES AND STRUCTURES
|
|
The
|
|
.Dv UR_GET_STATUS
|
|
request operates on a
|
|
.Va usb_status_t
|
|
structure, which has this member:
|
|
.Bl -item -offset offset -compact
|
|
.It
|
|
.Vt uWord wStatus ;
|
|
.El
|
|
.Pp
|
|
For device status requests the
|
|
.Fa wStatus
|
|
member may have either of these bit flags set:
|
|
.Bl -tag -width UDS_REMOTE_WAKEUPXX -offset offset -compact
|
|
.It Dv UDS_SELF_POWERED
|
|
.It Dv UDS_REMOTE_WAKEUP
|
|
.El
|
|
.Pp
|
|
For endpoint status requests the
|
|
.Fa wStatus
|
|
member may have this bit flag set:
|
|
.Bl -tag -width UES_HALTXX -offset offset -compact
|
|
.It Dv UES_HALT
|
|
.El
|
|
.Pp
|
|
The
|
|
.Dv UR_CLEAR_FEATURE
|
|
and
|
|
.Dv UR_SET_FEATURE
|
|
requests clear or set special features on USB devices.
|
|
The values for
|
|
.Va wValue ,
|
|
.Va wIndex
|
|
and
|
|
.Va wLength
|
|
depend upon the device and device type.
|
|
.Pp
|
|
The
|
|
.Dv UR_SET_ADDRESS
|
|
request sets the virtual USB address of a port using the
|
|
.Va wValue .
|
|
.Pp
|
|
The
|
|
.Dv UR_GET_DESCRIPTOR
|
|
and
|
|
.Dv UR_SET_DESCRIPTOR
|
|
requests operate on a
|
|
.Va usb_descriptor_t
|
|
structure, which has these members:
|
|
.Bl -item -offset offset -compact
|
|
.It
|
|
.Vt uByte bLength ;
|
|
.It
|
|
.Vt uByte bDescriptorType ;
|
|
.El
|
|
.Pp
|
|
The
|
|
.Fa bDescriptorType
|
|
member may be one of the following values:
|
|
.Bl -tag -width UDESC_OTHER_SPEED_CONFIGURATIONXX -offset offset -compact
|
|
.It Dv UDESC_DEVICE
|
|
.It Dv UDESC_CONFIG
|
|
.It Dv UDESC_STRING
|
|
.It Dv UDESC_INTERFACE
|
|
.It Dv UDESC_ENDPOINT
|
|
.It Dv UDESC_DEVICE_QUALIFIER
|
|
.It Dv UDESC_OTHER_SPEED_CONFIGURATION
|
|
.It Dv UDESC_INTERFACE_POWER
|
|
.It Dv UDESC_OTG
|
|
.It Dv UDESC_DEBUG
|
|
.It Dv UDESC_INTERFACE_ASSOC
|
|
.It Dv UDESC_CS_DEVICE
|
|
.It Dv UDESC_CS_CONFIG
|
|
.It Dv UDESC_CS_STRING
|
|
.It Dv UDESC_CS_INTERFACE
|
|
.It Dv UDESC_CS_ENDPOINT
|
|
.It Dv UDESC_HUB
|
|
.El
|
|
.Pp
|
|
The
|
|
.\" XXXMRG is the below even remotely valid?
|
|
.Fn usbd_set_interface
|
|
function can be used to change the index used for transfers on this
|
|
interface as obtained via
|
|
.Fn usbd_device2interface_handle .
|
|
.Sh USB DEVICE DETACHMENT
|
|
There are two functions available to ease the detach of active devices.
|
|
Typically a reference count is maintained on syscall activity.
|
|
When a USB device is to be detached, the reference count should be
|
|
decremented and if it is greater or equal to zero,
|
|
.Fn usb_detach_wait
|
|
should be called on the
|
|
.Ft dv
|
|
associated with this USB device and, typically, a device-specific
|
|
condition variable
|
|
.Fa cv .
|
|
and mutex
|
|
.Fa lk
|
|
protecting this reference count state.
|
|
At the end of each syscall function, if the reference count is decremented
|
|
to less than zero, then
|
|
.Fn usb_detach_broadcast
|
|
must be called on the
|
|
.Ft dv
|
|
and
|
|
.Fa cv
|
|
that is being waited on with
|
|
.Fn usb_detach_wait .
|
|
.Pp
|
|
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
|
|
.Fn usb_detach_waitold
|
|
function works like
|
|
.Fn usb_detach_wait ,
|
|
and the
|
|
.Fn usb_detach_wakeupold
|
|
function works like
|
|
.Fn usb_detach_broadcast .
|
|
.\" XXX add an actual code example.
|
|
.Sh USB TASK MANAGEMENT
|
|
The USB stack provides a task management framework to execute tasks
|
|
in a thread context at the soonest opportunity.
|
|
Typically this is used by network drivers to handle periodic updates
|
|
or status change requests, or other operations that need to run in
|
|
a normal context.
|
|
.Pp
|
|
The
|
|
.Fn usb_init_task
|
|
function takes a pointer to a
|
|
.Ft struct usb_task
|
|
that will be initalised, a function to call for this task
|
|
.Fa func ,
|
|
the argument to pass to
|
|
.Fa func ,
|
|
.Fa arg ,
|
|
and the task flags
|
|
.Fa flags .
|
|
If the
|
|
.Fa flags
|
|
argument is
|
|
.Dv USB_TASKQ_MPSAFE ,
|
|
the
|
|
.Fa func
|
|
function will be called without first acquiring
|
|
.Dv kernel_lock .
|
|
.Pp
|
|
To invoke the task callback the
|
|
.Fn usb_add_task
|
|
function should be called with the
|
|
.Fa iface
|
|
associated with this device, the task structure
|
|
.Fa task ,
|
|
and the
|
|
.Fa queue
|
|
to run against, either
|
|
.Dv USB_TASKQ_HC
|
|
for operations initiated by host controllers or
|
|
.Dv USB_TASKQ_DRIVER
|
|
for operations initiated by USB drivers.
|
|
.Pp
|
|
To deschedule a potentially running task the
|
|
.Fn usb_rem_task
|
|
function should be called.
|
|
.Pp
|
|
The driver using these facilities is expected to provide the
|
|
necessary serialisation between
|
|
.Fn usb_init_task ,
|
|
.Fn usb_add_task
|
|
and
|
|
.Fn usb_rem_task
|
|
for each specific
|
|
.Ft struct usb_task .
|
|
.Sh SEE ALSO
|
|
.Xr usb 4 ,
|
|
.Xr usbd_status 9
|
|
.Sh HISTORY
|
|
This
|
|
.Nm
|
|
interface first appeared in
|
|
.Nx 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.
|
|
.Sh BUGS
|
|
This manual is under development, so its biggest shortcoming is
|
|
incompleteness.
|