1254 lines
34 KiB
Groff
1254 lines
34 KiB
Groff
|
.\"
|
||
|
.\" Copyright (c) 2005 Ian Dowse <iedowse@FreeBSD.org>
|
||
|
.\" 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.
|
||
|
.\"
|
||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||
|
.\"
|
||
|
.\" $FreeBSD$
|
||
|
.Dd December 30, 2005
|
||
|
.Os
|
||
|
.Dt USBDI 9
|
||
|
.Sh NAME
|
||
|
.Nm usb_detach_wait ,
|
||
|
.Nm usb_detach_wakeup ,
|
||
|
.Nm usb_find_desc ,
|
||
|
.Nm usbd_abort_default_pipe ,
|
||
|
.Nm usbd_abort_pipe ,
|
||
|
.Nm usbd_alloc_buffer ,
|
||
|
.Nm usbd_alloc_xfer ,
|
||
|
.Nm usbd_bulk_transfer ,
|
||
|
.Nm usbd_clear_endpoint_stall ,
|
||
|
.Nm usbd_clear_endpoint_stall_async ,
|
||
|
.Nm usbd_clear_endpoint_toggle ,
|
||
|
.Nm usbd_close_pipe ,
|
||
|
.Nm usbd_device2interface_handle ,
|
||
|
.Nm usbd_devinfo ,
|
||
|
.Nm usbd_do_request ,
|
||
|
.Nm usbd_do_request_async ,
|
||
|
.Nm usbd_do_request_flags ,
|
||
|
.Nm usbd_do_request_flags_pipe ,
|
||
|
.Nm usbd_dopoll ,
|
||
|
.Nm usbd_endpoint_count ,
|
||
|
.Nm usbd_errstr ,
|
||
|
.Nm usbd_fill_deviceinfo ,
|
||
|
.Nm usbd_find_edesc ,
|
||
|
.Nm usbd_find_idesc ,
|
||
|
.Nm usbd_free_buffer ,
|
||
|
.Nm usbd_free_xfer ,
|
||
|
.Nm usbd_get_buffer ,
|
||
|
.Nm usbd_get_config ,
|
||
|
.Nm usbd_get_config_desc ,
|
||
|
.Nm usbd_get_config_desc_full ,
|
||
|
.Nm usbd_get_config_descriptor ,
|
||
|
.Nm usbd_get_device_descriptor ,
|
||
|
.Nm usbd_get_endpoint_descriptor ,
|
||
|
.Nm usbd_get_interface_altindex ,
|
||
|
.Nm usbd_get_interface_descriptor ,
|
||
|
.Nm usbd_get_no_alts ,
|
||
|
.Nm usbd_get_quirks ,
|
||
|
.Nm usbd_get_speed ,
|
||
|
.Nm usbd_get_string ,
|
||
|
.Nm usbd_get_string_desc ,
|
||
|
.Nm usbd_get_xfer_status ,
|
||
|
.Nm usbd_interface2device_handle ,
|
||
|
.Nm usbd_interface2endpoint_descriptor ,
|
||
|
.Nm usbd_interface_count ,
|
||
|
.Nm usbd_intr_transfer ,
|
||
|
.Nm usbd_open_pipe ,
|
||
|
.Nm usbd_open_pipe_intr ,
|
||
|
.Nm usbd_pipe2device_handle ,
|
||
|
.Nm usbd_ratecheck ,
|
||
|
.Nm usbd_set_config_index ,
|
||
|
.Nm usbd_set_config_no ,
|
||
|
.Nm usbd_set_interface ,
|
||
|
.Nm usbd_set_polling ,
|
||
|
.Nm usbd_setup_default_xfer ,
|
||
|
.Nm usbd_setup_isoc_xfer ,
|
||
|
.Nm usbd_setup_xfer ,
|
||
|
.Nm usbd_sync_transfer ,
|
||
|
.Nm usbd_transfer
|
||
|
.Nd Universal Serial Bus driver programming interface
|
||
|
.Sh SYNOPSIS
|
||
|
.In dev/usb/usb.h
|
||
|
.In dev/usb/usbdi.h
|
||
|
.In dev/usb/usbdi_util.h
|
||
|
.Pp
|
||
|
.Ft void
|
||
|
.Fn usb_detach_wait "device_ptr_t dv"
|
||
|
.Ft void
|
||
|
.Fn usb_detach_wakeup "device_ptr_t dv"
|
||
|
.Ft "const usb_descriptor_t *"
|
||
|
.Fn usb_find_desc "usbd_device_handle dev" "int type" "int subtype"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_abort_default_pipe "usbd_device_handle dev"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_abort_pipe "usbd_pipe_handle pipe"
|
||
|
.Ft "void *"
|
||
|
.Fn usbd_alloc_buffer "usbd_xfer_handle xfer" "u_int32_t size"
|
||
|
.Ft usbd_xfer_handle
|
||
|
.Fn usbd_alloc_xfer "usbd_device_handle dev"
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_bulk_transfer
|
||
|
.Fa "usbd_xfer_handle xfer"
|
||
|
.Fa "usbd_pipe_handle pipe"
|
||
|
.Fa "u_int16_t flags"
|
||
|
.Fa "u_int32_t timeout"
|
||
|
.Fa "void *buf"
|
||
|
.Fa "u_int32_t *size"
|
||
|
.Fa "char *lbl"
|
||
|
.Fc
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_clear_endpoint_stall "usbd_pipe_handle pipe"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_clear_endpoint_stall_async "usbd_pipe_handle"
|
||
|
.Ft void
|
||
|
.Fn usbd_clear_endpoint_toggle "usbd_pipe_handle pipe"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_close_pipe "usbd_pipe_handle pipe"
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_device2interface_handle
|
||
|
.Fa "usbd_device_handle dev"
|
||
|
.Fa "u_int8_t ifaceno"
|
||
|
.Fa "usbd_interface_handle *iface"
|
||
|
.Fc
|
||
|
.Ft void
|
||
|
.Fn usbd_devinfo "usbd_device_handle dev" "int showclass" "char *cp"
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_do_request
|
||
|
.Fa "usbd_device_handle dev"
|
||
|
.Fa "usb_device_request_t *req"
|
||
|
.Fa "void *data"
|
||
|
.Fc
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_do_request_async
|
||
|
.Fa "usbd_device_handle dev"
|
||
|
.Fa "usb_device_request_t *req"
|
||
|
.Fa "void *data"
|
||
|
.Fc
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_do_request_flags
|
||
|
.Fa "usbd_device_handle dev"
|
||
|
.Fa "usb_device_request_t *req"
|
||
|
.Fa "void *data"
|
||
|
.Fa "u_int16_t flags"
|
||
|
.Fa "int *actlen"
|
||
|
.Fa "u_int32_t timo"
|
||
|
.Fc
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_do_request_flags_pipe
|
||
|
.Fa "usbd_device_handle dev"
|
||
|
.Fa "usbd_pipe_handle pipe"
|
||
|
.Fa "usb_device_request_t *req"
|
||
|
.Fa "void *data"
|
||
|
.Fa "u_int16_t flags"
|
||
|
.Fa "int *actlen"
|
||
|
.Fa "u_int32_t timeout"
|
||
|
.Fc
|
||
|
.Ft void
|
||
|
.Fn usbd_dopoll "usbd_interface_handle iface"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_endpoint_count "usbd_interface_handle iface" "u_int8_t *count"
|
||
|
.Ft "const char *"
|
||
|
.Fn usbd_errstr "usbd_status err"
|
||
|
.Ft void
|
||
|
.Fo usbd_fill_deviceinfo
|
||
|
.Fa "usbd_device_handle dev"
|
||
|
.Fa "struct usb_device_info *di"
|
||
|
.Fa "int usedev"
|
||
|
.Fc
|
||
|
.Ft "usb_endpoint_descriptor_t *"
|
||
|
.Fo usbd_find_edesc
|
||
|
.Fa "usb_config_descriptor_t *cd"
|
||
|
.Fa "int ifaceidx"
|
||
|
.Fa "int altidx"
|
||
|
.Fa "int endptidx"
|
||
|
.Fc
|
||
|
.Ft "usb_interface_descriptor_t *"
|
||
|
.Fn usbd_find_idesc "usb_config_descriptor_t *cd" "int ifaceidx" "int altidx"
|
||
|
.Ft void
|
||
|
.Fn usbd_free_buffer "usbd_xfer_handle xfer"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_free_xfer "usbd_xfer_handle xfer"
|
||
|
.Ft "void *"
|
||
|
.Fn usbd_get_buffer "usbd_xfer_handle xfer"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_get_config "usbd_device_handle dev" "u_int8_t *conf"
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_get_config_desc
|
||
|
.Fa "usbd_device_handle dev"
|
||
|
.Fa "int confidx"
|
||
|
.Fa "usb_config_descriptor_t *d"
|
||
|
.Fc
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_get_config_desc_full
|
||
|
.Fa "usbd_device_handle dev"
|
||
|
.Fa "int conf"
|
||
|
.Fa "void *d"
|
||
|
.Fa "int size"
|
||
|
.Fc
|
||
|
.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 "usb_endpoint_descriptor_t *"
|
||
|
.Fo usbd_get_endpoint_descriptor
|
||
|
.Fa "usbd_interface_handle iface"
|
||
|
.Fa "u_int8_t address"
|
||
|
.Fc
|
||
|
.Ft int
|
||
|
.Fn usbd_get_interface_altindex "usbd_interface_handle iface"
|
||
|
.Ft "usb_interface_descriptor_t *"
|
||
|
.Fn usbd_get_interface_descriptor "usbd_interface_handle iface"
|
||
|
.Ft int
|
||
|
.Fn usbd_get_no_alts "usb_config_descriptor_t *cdesc" "int ifaceno"
|
||
|
.Ft "const struct usbd_quirks *"
|
||
|
.Fn usbd_get_quirks "usbd_device_handle dev"
|
||
|
.Ft int
|
||
|
.Fn usbd_get_speed "usbd_device_handle dev"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_get_string "usbd_device_handle dev" "int si" "char *buf"
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_get_string_desc
|
||
|
.Fa "usbd_device_handle dev"
|
||
|
.Fa "int sindex"
|
||
|
.Fa "int langid"
|
||
|
.Fa "usb_string_descriptor_t *sdesc"
|
||
|
.Fa "int *sizep"
|
||
|
.Fc
|
||
|
.Ft void
|
||
|
.Fo usbd_get_xfer_status
|
||
|
.Fa "usbd_xfer_handle xfer"
|
||
|
.Fa "usbd_private_handle *priv"
|
||
|
.Fa "void **buffer"
|
||
|
.Fa "u_int32_t *count"
|
||
|
.Fa "usbd_status *status"
|
||
|
.Fc
|
||
|
.Ft void
|
||
|
.Fo usbd_interface2device_handle
|
||
|
.Fa "usbd_interface_handle iface"
|
||
|
.Fa "usbd_device_handle *dev"
|
||
|
.Fc
|
||
|
.Ft "usb_endpoint_descriptor_t *"
|
||
|
.Fo usbd_interface2endpoint_descriptor
|
||
|
.Fa "usbd_interface_handle iface"
|
||
|
.Fa "u_int8_t index"
|
||
|
.Fc
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_interface_count "usbd_device_handle dev" "u_int8_t *count"
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_intr_transfer
|
||
|
.Fa "usbd_xfer_handle xfer"
|
||
|
.Fa "usbd_pipe_handle pipe"
|
||
|
.Fa "u_int16_t flags"
|
||
|
.Fa "u_int32_t timeout"
|
||
|
.Fa "void *buf"
|
||
|
.Fa "u_int32_t *size"
|
||
|
.Fa "char *lbl"
|
||
|
.Fc
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_open_pipe
|
||
|
.Fa "usbd_interface_handle iface"
|
||
|
.Fa "u_int8_t address"
|
||
|
.Fa "u_int8_t flags"
|
||
|
.Fa "usbd_pipe_handle *pipe"
|
||
|
.Fc
|
||
|
.Ft usbd_status
|
||
|
.Fo usbd_open_pipe_intr
|
||
|
.Fa "usbd_interface_handle iface"
|
||
|
.Fa "u_int8_t address"
|
||
|
.Fa "u_int8_t flags"
|
||
|
.Fa "usbd_pipe_handle *pipe"
|
||
|
.Fa "usbd_private_handle priv"
|
||
|
.Fa "void *buffer"
|
||
|
.Fa "u_int32_t len"
|
||
|
.Fa "usbd_callback cb"
|
||
|
.Fa "int ival"
|
||
|
.Fc
|
||
|
.Ft usbd_device_handle
|
||
|
.Fn usbd_pipe2device_handle "usbd_pipe_handle pipe"
|
||
|
.Ft int
|
||
|
.Fn usbd_ratecheck "struct timeval *last"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_set_config_index "usbd_device_handle dev" "int index" "int msg"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_set_config_no "usbd_device_handle dev" "int no" "int msg"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_set_interface "usbd_interface_handle iface" "int altidx"
|
||
|
.Ft void
|
||
|
.Fn usbd_set_polling "usbd_device_handle dev" "int on"
|
||
|
.Ft void
|
||
|
.Fo usbd_setup_default_xfer
|
||
|
.Fa "usbd_xfer_handle xfer"
|
||
|
.Fa "usbd_device_handle dev"
|
||
|
.Fa "usbd_private_handle priv"
|
||
|
.Fa "u_int32_t timeout"
|
||
|
.Fa "usb_device_request_t *req"
|
||
|
.Fa "void *buffer"
|
||
|
.Fa "u_int32_t length"
|
||
|
.Fa "u_int16_t flags"
|
||
|
.Fa "usbd_callback callback"
|
||
|
.Fc
|
||
|
.Ft void
|
||
|
.Fo usbd_setup_isoc_xfer
|
||
|
.Fa "usbd_xfer_handle xfer"
|
||
|
.Fa "usbd_pipe_handle pipe"
|
||
|
.Fa "usbd_private_handle priv"
|
||
|
.Fa "u_int16_t *frlengths"
|
||
|
.Fa "u_int32_t nframes"
|
||
|
.Fa "u_int16_t flags"
|
||
|
.Fa "usbd_callback callback"
|
||
|
.Fc
|
||
|
.Ft void
|
||
|
.Fo usbd_setup_xfer
|
||
|
.Fa "usbd_xfer_handle xfer"
|
||
|
.Fa "usbd_pipe_handle pipe"
|
||
|
.Fa "usbd_private_handle priv"
|
||
|
.Fa "void *buffer"
|
||
|
.Fa "u_int32_t length"
|
||
|
.Fa "u_int16_t flags"
|
||
|
.Fa "u_int32_t timeout"
|
||
|
.Fa "usbd_callback callback"
|
||
|
.Fc
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_sync_transfer "usbd_xfer_handle xfer"
|
||
|
.Ft usbd_status
|
||
|
.Fn usbd_transfer "usbd_xfer_handle xfer"
|
||
|
.Sh DESCRIPTION
|
||
|
The Universal Serial Bus (USB) driver programming interface provides
|
||
|
USB peripheral drivers with a host controller independent API for
|
||
|
controlling and communicating with USB peripherals.
|
||
|
.Pp
|
||
|
Typically, drivers will first use some combination of the functions
|
||
|
.Fn usbd_set_config_no ,
|
||
|
.Fn usbd_get_config_descriptor ,
|
||
|
.Fn usbd_set_interface ,
|
||
|
.Fn usbd_get_interface_descriptor ,
|
||
|
.Fn usbd_device2interface_handle ,
|
||
|
.Fn usbd_endpoint_count
|
||
|
and
|
||
|
.Fn usbd_interface2endpoint_descriptor
|
||
|
to query the device's properties and prepare it for use.
|
||
|
Drivers can then perform requests on the USB control pipe using
|
||
|
.Fn usbd_do_request ,
|
||
|
they can open pipes using the functions
|
||
|
.Fn usbd_open_pipe
|
||
|
and
|
||
|
.Fn usbd_open_pipe_intr ,
|
||
|
and perform transfers over these pipes using
|
||
|
.Fn usbd_alloc_xfer ,
|
||
|
.Fn usbd_setup_xfer
|
||
|
and
|
||
|
.Fn usbd_transfer .
|
||
|
Finally, the functions
|
||
|
.Fn usbd_abort_pipe ,
|
||
|
.Fn usbd_close_pipe
|
||
|
and
|
||
|
.Fn usbd_free_xfer
|
||
|
are used to cancel outstanding transfers, close open pipes and deallocate
|
||
|
transfer structures.
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_get_device_descriptor
|
||
|
function returns a pointer to the USB device descriptor for
|
||
|
.Fa dev .
|
||
|
See
|
||
|
.Sx "USB Descriptors"
|
||
|
below for information about the USB device descriptor.
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_get_config_desc
|
||
|
function retrieves the specified configuration descriptor from the device.
|
||
|
The
|
||
|
.Fa confidx
|
||
|
parameter specifies the configuration descriptor index, which must be less
|
||
|
than the
|
||
|
.Fa bNumConfigurations
|
||
|
value in the device descriptor.
|
||
|
The function
|
||
|
.Fn usbd_get_config_desc_full
|
||
|
retrieves a full configuration descriptor, which has all related interface
|
||
|
and endpoint descriptors appended to a normal configuration descriptor.
|
||
|
The parameter
|
||
|
.Fa d
|
||
|
should point to memory that is at least
|
||
|
.Fa size
|
||
|
bytes in length, and this should be at least as long as the
|
||
|
.Fa wTotalLength
|
||
|
value from the configuration descriptor.
|
||
|
See
|
||
|
.Sx "USB Descriptors"
|
||
|
below for information about the USB configuration descriptor.
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_get_config
|
||
|
function retrieves the current configuration number from the device, i.e.\&
|
||
|
the
|
||
|
.Fa bConfigurationValue
|
||
|
value from the configuration that is active.
|
||
|
If the device is unconfigured then
|
||
|
.Dv USB_UNCONFIG_NO
|
||
|
is returned.
|
||
|
The current configuration can be changed by calling either
|
||
|
.Fn usbd_set_config_index
|
||
|
or
|
||
|
.Fn usbd_set_config_no .
|
||
|
The difference between these functions is that
|
||
|
.Fn usbd_set_config_index
|
||
|
accepts a configuration index number that is less than the
|
||
|
.Fa bNumConfigurations
|
||
|
value from the device descriptor, whereas
|
||
|
.Fn usbd_set_config_no
|
||
|
requires the
|
||
|
.Fa bConfigurationValue
|
||
|
value of the desired configuration to be provided instead.
|
||
|
To unconfigure the device, supply a configuration index of
|
||
|
.Dv USB_UNCONFIG_INDEX
|
||
|
to
|
||
|
.Fn usbd_set_config_index ,
|
||
|
or else specify a configuration number of
|
||
|
.Dv USB_UNCONFIG_NO
|
||
|
to
|
||
|
.Fn usbd_set_config_no .
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_get_config_descriptor
|
||
|
function returns a pointer to an in-memory copy of the full configuration
|
||
|
descriptor of the configuration that is currently active.
|
||
|
The returned pointer remains valid until the device configuration
|
||
|
is changed using
|
||
|
.Fn usbd_set_config_index
|
||
|
or
|
||
|
.Fn usbd_set_config_no .
|
||
|
If the device is unconfigured then
|
||
|
.Dv NULL
|
||
|
is returned instead.
|
||
|
.Pp
|
||
|
The function
|
||
|
.Fn usbd_interface_count
|
||
|
returns the number of interfaces available in the current device
|
||
|
configuration.
|
||
|
The
|
||
|
.Fn usbd_get_no_alts
|
||
|
function determines the number of alternate interfaces in a full
|
||
|
configuration descriptor by counting the interface descriptors with
|
||
|
.Fa bInterfaceNumber
|
||
|
equal to
|
||
|
.Fa ifaceno
|
||
|
(the count includes alternate index zero).
|
||
|
The
|
||
|
.Fn usbd_find_idesc
|
||
|
function locates an interface descriptor within a full configuration
|
||
|
descriptor.
|
||
|
The
|
||
|
.Fa ifaceidx
|
||
|
parameter specifies the interface index number, which should be less than
|
||
|
the number of interfaces in the configuration descriptor (i.e.\& the value
|
||
|
returned by
|
||
|
.Fn usbd_interface_count
|
||
|
or the
|
||
|
.Fa bNumInterface
|
||
|
field from the configuration descriptor).
|
||
|
An alternate interface can be specified using a non-zero
|
||
|
.Fa altidx ,
|
||
|
which should be less than the value returned by
|
||
|
.Fn usbd_get_no_alts .
|
||
|
The return value is a pointer to the requested interface descriptor
|
||
|
within the full configuration descriptor, or
|
||
|
.Dv NULL
|
||
|
if the specified interface descriptor does not exist.
|
||
|
Note that the
|
||
|
.Fa altidx
|
||
|
parameter specifies the alternate setting by index number starting
|
||
|
at zero; it is not the alternate setting number defined in the
|
||
|
interface descriptor.
|
||
|
.Pp
|
||
|
The function
|
||
|
.Fn usbd_find_edesc
|
||
|
locates an endpoint descriptor within a full configuration descriptor.
|
||
|
The
|
||
|
.Fa ifaceidx
|
||
|
and
|
||
|
.Fa altidx
|
||
|
parameters are the same as described for
|
||
|
.Fn usbd_find_idesc ,
|
||
|
and the
|
||
|
.Fa endptidx
|
||
|
parameter is an endpoint index number that should be less than the
|
||
|
.Fa bNumEndpoints
|
||
|
field in the interface descriptor.
|
||
|
The return value is a pointer to the requested endpoint descriptor
|
||
|
within the full configuration descriptor, or
|
||
|
.Dv NULL
|
||
|
if the specified endpoint descriptor does not exist.
|
||
|
Note that the
|
||
|
.Fa altidx
|
||
|
and
|
||
|
.Fa endptidx
|
||
|
parameters are index numbers starting at zero; they are not the
|
||
|
alternate setting and endpoint address defined in the descriptors.
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_get_speed
|
||
|
function returns the device speed.
|
||
|
This can be
|
||
|
.Dv USB_SPEED_LOW ,
|
||
|
.Dv USB_SPEED_FULL
|
||
|
or
|
||
|
.Dv USB_SPEED_HIGH .
|
||
|
.Pp
|
||
|
USB devices optionally support string descriptors, which can be
|
||
|
retrieved using the
|
||
|
.Fn usbd_get_string
|
||
|
or
|
||
|
.Fn usbd_get_string_desc
|
||
|
functions.
|
||
|
Device, configuration and interface descriptors reference strings by
|
||
|
an index number that can be supplied to these functions.
|
||
|
The
|
||
|
.Fn usbd_get_string
|
||
|
function should be used unless a non-default language is required.
|
||
|
It requires that
|
||
|
.Fa buf
|
||
|
points to a buffer of at least
|
||
|
.Dv USB_MAX_STRING_LEN
|
||
|
bytes in size.
|
||
|
The
|
||
|
.Fa si
|
||
|
parameter specified which string to retrieve.
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usb_find_desc
|
||
|
function searches through the in-memory full configuration descriptor
|
||
|
for the active configuration and finds the first descriptor that has a
|
||
|
.Fa bDescriptorType
|
||
|
equal to
|
||
|
.Fa type ,
|
||
|
and if
|
||
|
.Fa subtype
|
||
|
is not equal to
|
||
|
.Dv USBD_SUBTYPE_ANY ,
|
||
|
the descriptor must also have a
|
||
|
.Fa bDescriptorSubtype
|
||
|
equal to
|
||
|
.Fa subtype .
|
||
|
If found, then a pointer to the descriptor is returned.
|
||
|
Otherwise,
|
||
|
.Fn usb_find_desc
|
||
|
returns
|
||
|
.Dv NULL .
|
||
|
The returned pointer is valid until the device configuration is changed using
|
||
|
.Fn usbd_set_config_index
|
||
|
or
|
||
|
.Fn usbd_set_config_no .
|
||
|
.Pp
|
||
|
The USB driver interface uses opaque interface handles to refer to
|
||
|
configuration interfaces.
|
||
|
These handles remain valid until the device configuration is changed using
|
||
|
.Fn usbd_set_config_index
|
||
|
or
|
||
|
.Fn usbd_set_config_no .
|
||
|
The
|
||
|
.Fn usbd_device2interface_handle
|
||
|
function retrieves an interface handle.
|
||
|
The
|
||
|
.Fa ifaceno
|
||
|
parameter is an interface index number starting at zero.
|
||
|
If the device is configured and the specified interface exists, then
|
||
|
.Dv USBD_NORMAL_COMPLETION
|
||
|
is returned and the interface handle is stored in
|
||
|
.Fa *iface .
|
||
|
Otherwise an error code is returned and
|
||
|
.Fa *iface
|
||
|
is not changed.
|
||
|
The
|
||
|
.Fn usbd_interface2device_handle
|
||
|
function retrieves the device handle from an interface handle.
|
||
|
This is just for convenience to save passing around the device
|
||
|
handle as well as the interface handle.
|
||
|
The
|
||
|
.Fn usbd_set_interface
|
||
|
function changes the alternate setting number for an interface to
|
||
|
the alternate setting identified by the zero-based index number
|
||
|
.Fa altidx .
|
||
|
This operation invalidates any existing endpoints on this
|
||
|
interface and their descriptors.
|
||
|
The
|
||
|
.Fn usbd_get_interface_altindex
|
||
|
function returns the current alternative setting index as was
|
||
|
specified when calling
|
||
|
.Fn usbd_set_interface .
|
||
|
The
|
||
|
.Fn usbd_endpoint_count
|
||
|
function retrieves the number of endpoints associated with the
|
||
|
specified interface.
|
||
|
The
|
||
|
.Fn usbd_interface2endpoint_descriptor
|
||
|
function returns a pointer to an in-memory endpoint descriptor for
|
||
|
the endpoint that has an index number of
|
||
|
.Fa index .
|
||
|
This pointer remains valid until the configuration or alternate setting
|
||
|
number are changed.
|
||
|
The function
|
||
|
.Fn usbd_get_endpoint_descriptor
|
||
|
is like
|
||
|
.Fn usbd_interface2endpoint_descriptor
|
||
|
but it accepts a
|
||
|
.Fa bEndpointAddress
|
||
|
address value instead of an index.
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_fill_deviceinfo
|
||
|
function fills out a
|
||
|
.Vt usb_device_info
|
||
|
structure with information about the device.
|
||
|
The vendor and product names come from the device itself, falling back to
|
||
|
a table lookup or just providing the IDs in hexadecimal.
|
||
|
If
|
||
|
.Fa usedev
|
||
|
is zero then
|
||
|
.Fn usbd_fill_deviceinfo
|
||
|
will not attempt to retrieve the vendor and product names from the
|
||
|
device.
|
||
|
The usb_device_info structure is defined in
|
||
|
.In dev/usb/usb.h
|
||
|
as follows:
|
||
|
.Bd -literal
|
||
|
struct usb_device_info {
|
||
|
u_int8_t udi_bus;
|
||
|
u_int8_t udi_addr; /* device address */
|
||
|
usb_event_cookie_t udi_cookie;
|
||
|
char udi_product[USB_MAX_STRING_LEN];
|
||
|
char udi_vendor[USB_MAX_STRING_LEN];
|
||
|
char udi_release[8];
|
||
|
u_int16_t udi_productNo;
|
||
|
u_int16_t udi_vendorNo;
|
||
|
u_int16_t udi_releaseNo;
|
||
|
u_int8_t udi_class;
|
||
|
u_int8_t udi_subclass;
|
||
|
u_int8_t udi_protocol;
|
||
|
u_int8_t udi_config;
|
||
|
u_int8_t udi_speed;
|
||
|
#define USB_SPEED_LOW 1
|
||
|
#define USB_SPEED_FULL 2
|
||
|
#define USB_SPEED_HIGH 3
|
||
|
int udi_power; /* power consumption in mA */
|
||
|
int udi_nports;
|
||
|
char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN];
|
||
|
/* hub only: addresses of devices on ports */
|
||
|
u_int8_t udi_ports[16];
|
||
|
#define USB_PORT_ENABLED 0xff
|
||
|
#define USB_PORT_SUSPENDED 0xfe
|
||
|
#define USB_PORT_POWERED 0xfd
|
||
|
}
|
||
|
.Ed
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_devinfo
|
||
|
function generates a string description of the USB device.
|
||
|
The
|
||
|
.Fa cp
|
||
|
argument should point to a 1024-byte buffer (XXX the maximum length
|
||
|
is approx 320 chars, but there is no sanity checking and everything uses
|
||
|
1024-character buffers).
|
||
|
Device class information is included if the
|
||
|
.Fa showclass
|
||
|
parameter is non-zero.
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_get_quirks
|
||
|
function returns information from a table of devices that require
|
||
|
special workarounds in order to function correctly.
|
||
|
The returned structure is defined in
|
||
|
.In dev/usb/usb_quirks.h
|
||
|
as follows:
|
||
|
.Bd -literal
|
||
|
struct usbd_quirks {
|
||
|
u_int32_t uq_flags; /* Device problems */
|
||
|
};
|
||
|
.Ed
|
||
|
.Pp
|
||
|
See
|
||
|
.In dev/usb/usb_quirks.h
|
||
|
for a list of all currently defined quirks.
|
||
|
.Pp
|
||
|
USB control requests are performed via
|
||
|
.Vt usb_device_request_t
|
||
|
structures, defined in
|
||
|
.In dev/usb/usb.h
|
||
|
as follows:
|
||
|
.Bd -literal
|
||
|
typedef struct {
|
||
|
uByte bmRequestType;
|
||
|
uByte bRequest;
|
||
|
uWord wValue;
|
||
|
uWord wIndex;
|
||
|
uWord wLength;
|
||
|
} UPACKED usb_device_request_t;
|
||
|
.Ed
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_do_request
|
||
|
function performs a single request synchronously.
|
||
|
The
|
||
|
.Fa req
|
||
|
parameter should point to a properly initialized
|
||
|
.Vt usb_device_request_t ,
|
||
|
and when the
|
||
|
.Fa wLength
|
||
|
field is non-zero,
|
||
|
.Fa data
|
||
|
should point at a buffer that is at least
|
||
|
.Fa wLength
|
||
|
bytes in length.
|
||
|
The request timeout is set to 5 seconds, so the operation will fail
|
||
|
with
|
||
|
.Er USBD_TIMEOUT
|
||
|
if the device does not respond within that time.
|
||
|
The
|
||
|
.Fn usbd_do_request_async
|
||
|
function is like
|
||
|
.Fn usbd_do_request ,
|
||
|
but it does not wait for the request to complete before returning.
|
||
|
This routine does not block so it can be used from contexts where
|
||
|
sleeping is not allowed.
|
||
|
Note that there is no notification mechanism to report when the
|
||
|
operation completed nor is there a way to determine whether the
|
||
|
request succeeded, so this function is of limited use.
|
||
|
See
|
||
|
.Fn usbd_setup_default_xfer
|
||
|
and
|
||
|
.Fn usbd_transfer
|
||
|
for a way to invoke an asynchronous callback upon completion of
|
||
|
a control request.
|
||
|
The
|
||
|
.Fn usbd_do_request_flags
|
||
|
function is like
|
||
|
.Fn usbd_do_request ,
|
||
|
but additional flags can be specified, the timeout is configurable,
|
||
|
and the actual number of bytes transferred is made available to the
|
||
|
caller.
|
||
|
The
|
||
|
.Fn usbd_do_request_flags_pipe
|
||
|
function uses a specified pipe instead of the default pipe.
|
||
|
.Pp
|
||
|
The function
|
||
|
.Fn usbd_open_pipe
|
||
|
creates a pipe connected to a specified endpoint on a specified interface.
|
||
|
The parameter
|
||
|
.Fa address
|
||
|
should be the
|
||
|
.Fa bEndpointAddress
|
||
|
value from one of this interface's endpoint descriptors.
|
||
|
If
|
||
|
.Fa flags
|
||
|
contains
|
||
|
.Dv USBD_EXCLUSIVE_USE
|
||
|
then the operation will only succeed if there are no open pipes
|
||
|
already connected to the specified endpoint.
|
||
|
The
|
||
|
.Fn usbd_open_pipe_intr
|
||
|
function creates an interrupt pipe connected to the specified endpoint.
|
||
|
The parameter
|
||
|
.Fa address
|
||
|
should be the
|
||
|
.Fa bEndpointAddress
|
||
|
value from one of this interface's endpoint descriptors.
|
||
|
The
|
||
|
.Fa flags
|
||
|
parameter is passed to
|
||
|
.Fn usbd_setup_xfer .
|
||
|
The
|
||
|
.Fa buffer
|
||
|
and
|
||
|
.Fa len
|
||
|
parameters define a buffer that is to be used for the interrupt transfers.
|
||
|
The callback to be invoked each time a transfer completes is specified by
|
||
|
.Fa cb ,
|
||
|
and
|
||
|
.Fa priv
|
||
|
is an argument to be passed to the callback function.
|
||
|
The
|
||
|
.Fa ival
|
||
|
parameter specifies the maximum acceptable interval between transfers;
|
||
|
in practice the transfers may occur more frequently.
|
||
|
The function
|
||
|
.Fn usbd_pipe2device_handle
|
||
|
returns the device associated with the specified
|
||
|
.Fa pipe .
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_abort_pipe
|
||
|
function aborts all active or waiting transfers on the specified pipe.
|
||
|
Each transfer is aborted with a
|
||
|
.Dv USBD_CANCELLED
|
||
|
status; callback routines must detect this error code to ensure that
|
||
|
they do not attempt to initiate a new transfer in response to one being
|
||
|
aborted.
|
||
|
This routine blocks while it is waiting for the hardware to complete
|
||
|
processing of aborted transfers, so it is only safe to call it in
|
||
|
contexts where sleeping is allowed.
|
||
|
The function
|
||
|
.Fn usbd_abort_default_pipe
|
||
|
aborts all active or waiting transfers on the default pipe.
|
||
|
Like
|
||
|
.Fn usbd_abort_pipe ,
|
||
|
it blocks waiting for the hardware processing to complete.
|
||
|
.Pp
|
||
|
When a pipe has no active or waiting transfers, the pipe may be closed
|
||
|
using the
|
||
|
.Fn usbd_close_pipe
|
||
|
function.
|
||
|
Once a pipe is closed, its pipe handle becomes invalid and may no longer
|
||
|
be used.
|
||
|
.Pp
|
||
|
USB transfer handles are allocated using the function
|
||
|
.Fn usbd_alloc_xfer
|
||
|
and may be freed using
|
||
|
.Fn usbd_free_xfer .
|
||
|
.Pp
|
||
|
The function
|
||
|
.Fn usbd_setup_xfer
|
||
|
initializes a transfer handle with the details of a transfer to or from
|
||
|
a USB device.
|
||
|
The
|
||
|
.Fa xfer
|
||
|
parameter specifies the transfer handle to initialize,
|
||
|
.Fa pipe
|
||
|
specifies the pipe on which the transfer is to take place, and
|
||
|
.Fa priv
|
||
|
is an argument that will be passed to callback function.
|
||
|
The arguments
|
||
|
.Fa buffer
|
||
|
and
|
||
|
.Fa length
|
||
|
define the data buffer for the transfer.
|
||
|
If
|
||
|
.Fa length
|
||
|
is zero then the
|
||
|
.Fa buffer
|
||
|
may be
|
||
|
.Dv NULL .
|
||
|
The
|
||
|
.Fa flags
|
||
|
parameter may contain the following flags:
|
||
|
.Bl -tag -width ".Dv USBD_FORCE_SHORT_XFER"
|
||
|
.It Dv USBD_NO_COPY
|
||
|
This is used in association with
|
||
|
.Fn usbd_alloc_buffer
|
||
|
and
|
||
|
.Fn usbd_free_buffer
|
||
|
to use a dedicated DMA-capable buffer for the transfer.
|
||
|
.It Dv USBD_SYNCHRONOUS
|
||
|
Wait for the transfer to compete in
|
||
|
.Fn usbd_transfer .
|
||
|
.It Dv USBD_SHORT_XFER_OK
|
||
|
Permit transfers shorter than the requested data length.
|
||
|
.It Dv USBD_FORCE_SHORT_XFER
|
||
|
Force a short transfer at the end of a write operation to let the
|
||
|
device know that the transfer has ended.
|
||
|
.El
|
||
|
.Pp
|
||
|
The
|
||
|
.Fa timeout
|
||
|
parameter specifies a timeout for the transfer in milliseconds.
|
||
|
A value of
|
||
|
.Dv USBD_NO_TIMEOUT
|
||
|
indicates that no timeout should be configured.
|
||
|
The parameter
|
||
|
.Fa callback
|
||
|
specifies the function to call when the transfer completes.
|
||
|
Note that
|
||
|
.Fn usbd_setup_xfer
|
||
|
does not actually initiate the transfer.
|
||
|
The
|
||
|
.Fn usbd_setup_default_xfer
|
||
|
initializes a control transfer for the default pipe.
|
||
|
The
|
||
|
.Fa req
|
||
|
parameter should point at a completed
|
||
|
.Vt usb_device_request_t
|
||
|
structure.
|
||
|
The function
|
||
|
.Fa usbd_setup_isoc_xfer
|
||
|
initializes a transfer for an isochronous pipe.
|
||
|
.Pp
|
||
|
The function
|
||
|
.Fn usbd_transfer
|
||
|
initiates a transfer.
|
||
|
Normally it returns
|
||
|
.Dv USBD_IN_PROGRESS
|
||
|
to indicate that the transfer has been queued.
|
||
|
If the USB stack is operating in polling mode, or if the transfer
|
||
|
is synchronous, then
|
||
|
.Dv USBD_NORMAL_COMPLETION
|
||
|
may be returned.
|
||
|
Other return values indicate that the transfer could not be
|
||
|
initiated due to an error.
|
||
|
The
|
||
|
.Fn usbd_sync_transfer
|
||
|
function executes a transfer synchronously.
|
||
|
It will sleep waiting for the transfer to complete and then return
|
||
|
the transfer status.
|
||
|
Note that if the transfer has a callback routine, this will be
|
||
|
invoked before
|
||
|
.Fn usbd_sync_transfer
|
||
|
returns.
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_intr_transfer
|
||
|
and
|
||
|
.Fn usbd_bulk_transfer
|
||
|
functions set up a transfer and wait synchronously for it to complete
|
||
|
but they allows signals to interrupt the wait.
|
||
|
They returns
|
||
|
.Dv USBD_INTERRUPTED
|
||
|
if the transfer was interrupted by a signal.
|
||
|
XXX these two functions are identical apart from their names.
|
||
|
.Pp
|
||
|
The function
|
||
|
.Fn usbd_get_xfer_status
|
||
|
retrieves various information from a completed transfer.
|
||
|
If the
|
||
|
.Fa priv
|
||
|
parameter is not NULL then the callback private argument is
|
||
|
stored in
|
||
|
.Fa *priv .
|
||
|
If
|
||
|
.Fa buffer
|
||
|
is not NULL then the transfer buffer pointer is stored in
|
||
|
.Fa *buffer .
|
||
|
The actual number of bytes transferred is stored in
|
||
|
.Fa *count
|
||
|
if
|
||
|
.Fa count is not NULL.
|
||
|
Finally, the transfer status is stored in
|
||
|
.Fa *status
|
||
|
if
|
||
|
.Fa status
|
||
|
is not NULL.
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_clear_endpoint_stall
|
||
|
function clears an endpoint stall condition synchronously, i.e.\&
|
||
|
it sleeps waiting for the stall clear request to complete.
|
||
|
The function
|
||
|
.Fn usbd_clear_endpoint_stall_async
|
||
|
performs the same function asynchronously, but it provides no
|
||
|
way to determine when the request completed, or whether it was
|
||
|
successful.
|
||
|
The
|
||
|
.Fn usbd_clear_endpoint_toggle
|
||
|
function instructs the host controller driver to reset the toggle bit
|
||
|
on a pipe.
|
||
|
This is used when manually clearing an endpoint stall using a
|
||
|
control pipe request, in order to ensure that the host controller
|
||
|
driver and the USB device restart with the same toggle value.
|
||
|
.Pp
|
||
|
Normally the USB subsystem maps and copies data to and from
|
||
|
DMA-capable memory each time a transfer is performed.
|
||
|
The function
|
||
|
.Fn usbd_alloc_buffer
|
||
|
allocates a permanent DMA-capable buffer associated with the
|
||
|
transfer to avoid this overhead.
|
||
|
The return value is the virtual address of the buffer.
|
||
|
Any time that
|
||
|
.Fn usbd_setup_xfer
|
||
|
is called on the transfer with the
|
||
|
.Dv USBD_NO_COPY
|
||
|
flag enabled, the allocated buffer will be used directly and
|
||
|
the
|
||
|
.Fa buffer
|
||
|
argument passed to
|
||
|
.Fn usbd_setup_xfer
|
||
|
will be ignored.
|
||
|
The
|
||
|
.Fn usbd_get_buffer
|
||
|
function returns a pointer to the virtual address of a buffer previously
|
||
|
allocated by
|
||
|
.Fn usbd_alloc_buffer .
|
||
|
Finally,
|
||
|
.Fn usbd_free_buffer
|
||
|
deallocates the buffer.
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_errstr
|
||
|
function converts a status code into a string for display.
|
||
|
.Pp
|
||
|
The function
|
||
|
.Fn usbd_set_polling
|
||
|
enables or disables polling mode.
|
||
|
In polling mode, all operations will busy-wait for the device to
|
||
|
respond, so its use is effectively limited to boot time and kernel
|
||
|
debuggers.
|
||
|
It is important to match up calls that enable and disable polling
|
||
|
mode, because the implementation just increments a polling reference
|
||
|
count when
|
||
|
.Fa on
|
||
|
is non-zero and decrements it when
|
||
|
.Fa on
|
||
|
is zero.
|
||
|
The
|
||
|
.Fn usbd_dopoll
|
||
|
causes the host controller driver to poll for any activity.
|
||
|
This should only be used when polling mode is enabled.
|
||
|
.Pp
|
||
|
The
|
||
|
.Fn usbd_ratecheck
|
||
|
function is used to limit the rate at which error messages are
|
||
|
printed to approximately once per second.
|
||
|
The
|
||
|
.Fa last
|
||
|
argument should point at a persistent
|
||
|
.Vt "struct timeval" .
|
||
|
A value of 1 will be returned if a message should be printed, but if
|
||
|
.Fn usbd_ratecheck
|
||
|
has already been called with the same
|
||
|
.Vt "struct timeval"
|
||
|
parameter in the last second then 0 is returned and the error message
|
||
|
should be suppressed.
|
||
|
.Pp
|
||
|
The functions
|
||
|
.Fn usb_detach_wait
|
||
|
and
|
||
|
.Fn usb_detach_wakeup
|
||
|
are used to wait for references to drain before completing the
|
||
|
detachment of a device.
|
||
|
The
|
||
|
.Fn usb_detach_wait
|
||
|
function will wait up to 60 seconds to receive a signal from
|
||
|
.Fn usb_detach_wait .
|
||
|
.Ss "USB Descriptors"
|
||
|
The USB specification defines a number of standard descriptors by
|
||
|
which USB devices report their attributes.
|
||
|
These descriptors are fixed-format structures that all USB devices
|
||
|
make available through USB control pipe requests.
|
||
|
.Pp
|
||
|
Every USB device has exactly one USB device descriptor.
|
||
|
The USB subsystem retrieves this automatically when a device is
|
||
|
attached, and a copy of the descriptor is kept in memory.
|
||
|
The
|
||
|
.Fn usbd_get_device_descriptor
|
||
|
function returns a pointer to the descriptor.
|
||
|
The device descriptor structure is defined in
|
||
|
.In dev/usb/usb.h
|
||
|
as follows:
|
||
|
.Bd -literal
|
||
|
typedef struct {
|
||
|
uByte bLength;
|
||
|
uByte bDescriptorType;
|
||
|
uWord bcdUSB;
|
||
|
#define UD_USB_2_0 0x0200
|
||
|
#define UD_IS_USB2(d) (UGETW((d)->bcdUSB) >= UD_USB_2_0)
|
||
|
uByte bDeviceClass;
|
||
|
uByte bDeviceSubClass;
|
||
|
uByte bDeviceProtocol;
|
||
|
uByte bMaxPacketSize;
|
||
|
/* The fields below are not part of the initial descriptor. */
|
||
|
uWord idVendor;
|
||
|
uWord idProduct;
|
||
|
uWord bcdDevice;
|
||
|
uByte iManufacturer;
|
||
|
uByte iProduct;
|
||
|
uByte iSerialNumber;
|
||
|
uByte bNumConfigurations;
|
||
|
} UPACKED usb_device_descriptor_t;
|
||
|
#define USB_DEVICE_DESCRIPTOR_SIZE 18
|
||
|
.Ed
|
||
|
.Pp
|
||
|
USB devices have at least one configuration descriptor.
|
||
|
The
|
||
|
.Fa bNumConfigurations
|
||
|
field of the device descriptor specifies the number of configuration
|
||
|
descriptors that a device supports.
|
||
|
The
|
||
|
.Fn usbd_get_config_desc
|
||
|
function retrieves a particular configuration descriptor from the device
|
||
|
and the
|
||
|
.Fn usbd_get_config_desc_full
|
||
|
function retrieves a full
|
||
|
.Fa wTotalLength
|
||
|
length configuration descriptor, which includes all related interface
|
||
|
and endpoint descriptors.
|
||
|
Only one configuration may be active at a time.
|
||
|
The
|
||
|
.Fn usbd_set_config_index
|
||
|
function activates a specified configuration.
|
||
|
The configuration descriptor structure is defined in
|
||
|
.In dev/usb/usb.h
|
||
|
as follows:
|
||
|
.Bd -literal
|
||
|
typedef struct {
|
||
|
uByte bLength;
|
||
|
uByte bDescriptorType;
|
||
|
uWord wTotalLength;
|
||
|
uByte bNumInterface;
|
||
|
uByte bConfigurationValue;
|
||
|
uByte iConfiguration;
|
||
|
uByte bmAttributes;
|
||
|
#define UC_BUS_POWERED 0x80
|
||
|
#define UC_SELF_POWERED 0x40
|
||
|
#define UC_REMOTE_WAKEUP 0x20
|
||
|
uByte bMaxPower; /* max current in 2 mA units */
|
||
|
#define UC_POWER_FACTOR 2
|
||
|
} UPACKED usb_config_descriptor_t;
|
||
|
#define USB_CONFIG_DESCRIPTOR_SIZE 9
|
||
|
.Ed
|
||
|
.Pp
|
||
|
Each device configuration provides one or more interfaces.
|
||
|
The
|
||
|
.Fa bNumInterface
|
||
|
field of the configuration descriptor specifies the number of
|
||
|
interfaces associated with a device configuration.
|
||
|
Interfaces are described by an interface descriptor, which is defined in
|
||
|
.In dev/usb/usb.h
|
||
|
as follows:
|
||
|
.Bd -literal
|
||
|
typedef struct {
|
||
|
uByte bLength;
|
||
|
uByte bDescriptorType;
|
||
|
uByte bInterfaceNumber;
|
||
|
uByte bAlternateSetting;
|
||
|
uByte bNumEndpoints;
|
||
|
uByte bInterfaceClass;
|
||
|
uByte bInterfaceSubClass;
|
||
|
uByte bInterfaceProtocol;
|
||
|
uByte iInterface;
|
||
|
} UPACKED usb_interface_descriptor_t;
|
||
|
#define USB_INTERFACE_DESCRIPTOR_SIZE 9
|
||
|
.Ed
|
||
|
.Pp
|
||
|
Configurations may also have alternate interfaces with the same
|
||
|
.Fa bInterfaceNumber
|
||
|
but different
|
||
|
.Fa bAlternateSetting
|
||
|
values.
|
||
|
These alternate interface settings may be selected by passing a
|
||
|
non-zero
|
||
|
.Fa altidx
|
||
|
parameter to
|
||
|
.Fn usbd_set_interface .
|
||
|
.Pp
|
||
|
Interfaces have zero or more endpoints, and each endpoint has an
|
||
|
endpoint descriptor.
|
||
|
Note that endpoint zero, which is always present, does not have an
|
||
|
endpoint descriptor, and it is never included in the
|
||
|
.Fa bNumEndpoints
|
||
|
count of endpoints.
|
||
|
The endpoint descriptor is defined in
|
||
|
.In dev/usb/usb.h
|
||
|
as follows:
|
||
|
.Bd -literal
|
||
|
typedef struct {
|
||
|
uByte bLength;
|
||
|
uByte bDescriptorType;
|
||
|
uByte bEndpointAddress;
|
||
|
#define UE_GET_DIR(a) ((a) & 0x80)
|
||
|
#define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7))
|
||
|
#define UE_DIR_IN 0x80
|
||
|
#define UE_DIR_OUT 0x00
|
||
|
#define UE_ADDR 0x0f
|
||
|
#define UE_GET_ADDR(a) ((a) & UE_ADDR)
|
||
|
uByte bmAttributes;
|
||
|
#define UE_XFERTYPE 0x03
|
||
|
#define UE_CONTROL 0x00
|
||
|
#define UE_ISOCHRONOUS 0x01
|
||
|
#define UE_BULK 0x02
|
||
|
#define UE_INTERRUPT 0x03
|
||
|
#define UE_GET_XFERTYPE(a) ((a) & UE_XFERTYPE)
|
||
|
#define UE_ISO_TYPE 0x0c
|
||
|
#define UE_ISO_ASYNC 0x04
|
||
|
#define UE_ISO_ADAPT 0x08
|
||
|
#define UE_ISO_SYNC 0x0c
|
||
|
#define UE_GET_ISO_TYPE(a) ((a) & UE_ISO_TYPE)
|
||
|
uWord wMaxPacketSize;
|
||
|
uByte bInterval;
|
||
|
} UPACKED usb_endpoint_descriptor_t;
|
||
|
#define USB_ENDPOINT_DESCRIPTOR_SIZE 7
|
||
|
.Ed
|
||
|
.Sh RETURN VALUES
|
||
|
Many functions return a
|
||
|
.Vt usbd_status
|
||
|
type to indicate the outcome of the operation.
|
||
|
If the operation completed successfully then
|
||
|
.Dv USBD_NORMAL_COMPLETION
|
||
|
is returned.
|
||
|
Operations that have been started but not yet completed will return
|
||
|
.Dv USBD_IN_PROGRESS .
|
||
|
Other errors usually indicate a problem.
|
||
|
Error codes can be converted to strings using
|
||
|
.Fn usbd_errstr .
|
||
|
.Sh ERRORS
|
||
|
.Bl -tag -width ".Er USBD_PENDING_REQUESTS"
|
||
|
.It Bq Er USBD_PENDING_REQUESTS
|
||
|
A pipe could not be closed because there are active requests.
|
||
|
.It Bq Er USBD_NOT_STARTED
|
||
|
The transfer has not yet been started.
|
||
|
.It Bq Er USBD_INVAL
|
||
|
An invalid value was supplied.
|
||
|
.It Bq Er USBD_NOMEM
|
||
|
An attempt to allocate memory failed.
|
||
|
.It Bq Er USBD_CANCELLED
|
||
|
The transfer was aborted.
|
||
|
.It Bq Er USBD_BAD_ADDRESS
|
||
|
The specified endpoint address was not found.
|
||
|
.It Bq Er USBD_IN_USE
|
||
|
The endpoint is already in use, or the configuration cannot be changed
|
||
|
because some of its endpoints are in use.
|
||
|
.It Bq Er USBD_NO_ADDR
|
||
|
No free USB devices addresses were found to assign to the device.
|
||
|
.It Bq Er USBD_SET_ADDR_FAILED
|
||
|
The device address could not be set.
|
||
|
.It Bq Er USBD_NO_POWER
|
||
|
Insufficient power was available for the device.
|
||
|
.It Bq Er USBD_TOO_DEEP
|
||
|
Too many levels of chained hubs were found.
|
||
|
.It Bq Er USBD_IOERROR
|
||
|
There was an error communicating with the device.
|
||
|
.It Bq Er USBD_NOT_CONFIGURED
|
||
|
An operation that requires an active configuration was attempted while
|
||
|
the device was in an unconfigured state.
|
||
|
.It Bq Er USBD_TIMEOUT
|
||
|
A transfer timed out.
|
||
|
.It Bq Er USBD_SHORT_XFER
|
||
|
A transfer that disallowed short data lengths completed with less than
|
||
|
the requested length transferred.
|
||
|
.It Bq Er USBD_STALLED
|
||
|
A transfer failed because the pipe is stalled.
|
||
|
.It Bq Er USBD_INTERRUPTED
|
||
|
An interruptible operation caught a signal.
|
||
|
.El
|
||
|
.Sh SEE ALSO
|
||
|
.Xr usb 4
|
||
|
.Sh HISTORY
|
||
|
The USB driver interface first appeared in
|
||
|
.Fx 3.0 .
|
||
|
.Sh AUTHORS
|
||
|
The USB driver was written by
|
||
|
.An Lennart Augustsson
|
||
|
for the
|
||
|
.Nx
|
||
|
project.
|
||
|
.Pp
|
||
|
.An -nosplit
|
||
|
This manual page was written by
|
||
|
.An Ian Dowse Aq iedowse@FreeBSD.org .
|