To use these ioctls, you need to include the following headers in your userspace program:
#include <linux/usb.h> #include <linux/usbdevice_fs.h> #include <asm/byteorder.h>
The standard USB device model requests, from "Chapter 9" of
the USB 2.0 specification, are automatically included from
the <linux/usb/ch9.h>
header.
Unless noted otherwise, the ioctl requests
described here will
update the modification time on the usbfs file to which
they are applied (unless they fail).
A return of zero indicates success; otherwise, a
standard USB error code is returned. (These are
documented in
Documentation/usb/error-codes.txt
in your kernel sources.)
Each of these files multiplexes access to several I/O streams, one per endpoint. Each device has one control endpoint (endpoint zero) which supports a limited RPC style RPC access. Devices are configured by hub_wq (in the kernel) setting a device-wide configuration that affects things like power consumption and basic functionality. The endpoints are part of USB interfaces, which may have altsettings affecting things like which endpoints are available. Many devices only have a single configuration and interface, so drivers for them will ignore configurations and altsettings.
A number of usbfs requests don't deal very directly with device I/O. They mostly relate to device management and status. These are all synchronous requests.
This is used to force usbfs to claim a specific interface, which has not previously been claimed by usbfs or any other kernel driver. The ioctl parameter is an integer holding the number of the interface (bInterfaceNumber from descriptor).
Note that if your driver doesn't claim an interface before trying to use one of its endpoints, and no other driver has bound to it, then the interface is automatically claimed by usbfs.
This claim will be released by a RELEASEINTERFACE ioctl, or by closing the file descriptor. File modification time is not updated by this request.
Says whether the device is lowspeed. The ioctl parameter points to a structure like this:
struct usbdevfs_connectinfo { unsigned int devnum; unsigned char slow; };
File modification time is not updated by this request.
You can't tell whether a "not slow" device is connected at high speed (480 MBit/sec) or just full speed (12 MBit/sec). You should know the devnum value already, it's the DDD value of the device file name.
Returns the name of the kernel driver bound to a given interface (a string). Parameter is a pointer to this structure, which is modified:
struct usbdevfs_getdriver { unsigned int interface; char driver[USBDEVFS_MAXDRIVERNAME + 1]; };
File modification time is not updated by this request.
Passes a request from userspace through to a kernel driver that has an ioctl entry in the struct usb_driver it registered.
struct usbdevfs_ioctl { int ifno; int ioctl_code; void *data; }; /* user mode call looks like this. * 'request' becomes the driver->ioctl() 'code' parameter. * the size of 'param' is encoded in 'request', and that data * is copied to or from the driver->ioctl() 'buf' parameter. */ static int usbdev_ioctl (int fd, int ifno, unsigned request, void *param) { struct usbdevfs_ioctl wrapper; wrapper.ifno = ifno; wrapper.ioctl_code = request; wrapper.data = param; return ioctl (fd, USBDEVFS_IOCTL, &wrapper); }
File modification time is not updated by this request.
This request lets kernel drivers talk to user mode code through filesystem operations even when they don't create a character or block special device. It's also been used to do things like ask devices what device special file should be used. Two pre-defined ioctls are used to disconnect and reconnect kernel drivers, so that user mode code can completely manage binding and configuration of devices.
This is used to release the claim usbfs made on interface, either implicitly or because of a USBDEVFS_CLAIMINTERFACE call, before the file descriptor is closed. The ioctl parameter is an integer holding the number of the interface (bInterfaceNumber from descriptor); File modification time is not updated by this request.
No security check is made to ensure that the task which made the claim is the one which is releasing it. This means that user mode driver may interfere other ones.
Resets the data toggle value for an endpoint (bulk or interrupt) to DATA0. The ioctl parameter is an integer endpoint number (1 to 15, as identified in the endpoint descriptor), with USB_DIR_IN added if the device's endpoint sends data to the host.
Avoid using this request. It should probably be removed. Using it typically means the device and driver will lose toggle synchronization. If you really lost synchronization, you likely need to completely handshake with the device, using a request like CLEAR_HALT or SET_INTERFACE.
Synchronous requests involve the kernel blocking until the user mode request completes, either by finishing successfully or by reporting an error. In most cases this is the simplest way to use usbfs, although as noted above it does prevent performing I/O to more than one endpoint at a time.
Issues a bulk read or write request to the device. The ioctl parameter is a pointer to this structure:
struct usbdevfs_bulktransfer { unsigned int ep; unsigned int len; unsigned int timeout; /* in milliseconds */ void *data; };
The "ep" value identifies a bulk endpoint number (1 to 15, as identified in an endpoint descriptor), masked with USB_DIR_IN when referring to an endpoint which sends data to the host from the device. The length of the data buffer is identified by "len"; Recent kernels support requests up to about 128KBytes. FIXME say how read length is returned, and how short reads are handled..
Clears endpoint halt (stall) and resets the endpoint toggle. This is only meaningful for bulk or interrupt endpoints. The ioctl parameter is an integer endpoint number (1 to 15, as identified in an endpoint descriptor), masked with USB_DIR_IN when referring to an endpoint which sends data to the host from the device.
Use this on bulk or interrupt endpoints which have stalled, returning -EPIPE status to a data transfer request. Do not issue the control request directly, since that could invalidate the host's record of the data toggle.
Issues a control request to the device. The ioctl parameter points to a structure like this:
struct usbdevfs_ctrltransfer { __u8 bRequestType; __u8 bRequest; __u16 wValue; __u16 wIndex; __u16 wLength; __u32 timeout; /* in milliseconds */ void *data; };
The first eight bytes of this structure are the contents of the SETUP packet to be sent to the device; see the USB 2.0 specification for details. The bRequestType value is composed by combining a USB_TYPE_* value, a USB_DIR_* value, and a USB_RECIP_* value (from <linux/usb.h>). If wLength is nonzero, it describes the length of the data buffer, which is either written to the device (USB_DIR_OUT) or read from the device (USB_DIR_IN).
At this writing, you can't transfer more than 4 KBytes of data to or from a device; usbfs has a limit, and some host controller drivers have a limit. (That's not usually a problem.) Also there's no way to say it's not OK to get a short read back from the device.
Does a USB level device reset. The ioctl parameter is ignored. After the reset, this rebinds all device interfaces. File modification time is not updated by this request.
Avoid using this call until some usbcore bugs get fixed, since it does not fully synchronize device, interface, and driver (not just usbfs) state.
Sets the alternate setting for an interface. The ioctl parameter is a pointer to a structure like this:
struct usbdevfs_setinterface { unsigned int interface; unsigned int altsetting; };
File modification time is not updated by this request.
Those struct members are from some interface descriptor applying to the current configuration. The interface number is the bInterfaceNumber value, and the altsetting number is the bAlternateSetting value. (This resets each endpoint in the interface.)
Issues the
usb_set_configuration
call
for the device.
The parameter is an integer holding the number of
a configuration (bConfigurationValue from descriptor).
File modification time is not updated by this request.
Avoid using this call until some usbcore bugs get fixed, since it does not fully synchronize device, interface, and driver (not just usbfs) state.
As mentioned above, there are situations where it may be important to initiate concurrent operations from user mode code. This is particularly important for periodic transfers (interrupt and isochronous), but it can be used for other kinds of USB requests too. In such cases, the asynchronous requests described here are essential. Rather than submitting one request and having the kernel block until it completes, the blocking is separate.
These requests are packaged into a structure that resembles the URB used by kernel device drivers. (No POSIX Async I/O support here, sorry.) It identifies the endpoint type (USBDEVFS_URB_TYPE_*), endpoint (number, masked with USB_DIR_IN as appropriate), buffer and length, and a user "context" value serving to uniquely identify each request. (It's usually a pointer to per-request data.) Flags can modify requests (not as many as supported for kernel drivers).
Each request can specify a realtime signal number (between SIGRTMIN and SIGRTMAX, inclusive) to request a signal be sent when the request completes.
When usbfs returns these urbs, the status value is updated, and the buffer may have been modified. Except for isochronous transfers, the actual_length is updated to say how many bytes were transferred; if the USBDEVFS_URB_DISABLE_SPD flag is set ("short packets are not OK"), if fewer bytes were read than were requested then you get an error report.
struct usbdevfs_iso_packet_desc { unsigned int length; unsigned int actual_length; unsigned int status; }; struct usbdevfs_urb { unsigned char type; unsigned char endpoint; int status; unsigned int flags; void *buffer; int buffer_length; int actual_length; int start_frame; int number_of_packets; int error_count; unsigned int signr; void *usercontext; struct usbdevfs_iso_packet_desc iso_frame_desc[]; };
For these asynchronous requests, the file modification time reflects when the request was initiated. This contrasts with their use with the synchronous requests, where it reflects when requests complete.
TBS File modification time is not updated by this request.
TBS File modification time is not updated by this request.
TBS File modification time is not updated by this request.
TBS File modification time is not updated by this request.
TBS