Sophie

Sophie

distrib > CentOS > 6 > i386 > by-pkgid > cf93d8a8acdcc6fe2225039da0502495 > files > 3789

kernel-doc-2.6.32-131.17.1.el6.centos.plus.noarch.rpm

<?xml version="1.0" encoding="ANSI_X3.4-1968" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968" /><title>The ioctl() Requests</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /><link rel="home" href="index.html" title="The Linux-USB Host Side API" /><link rel="up" href="ch07.html" title="Chapter&#160;7.&#160;The USB Filesystem (usbfs)" /><link rel="prev" href="ch07s05.html" title="Life Cycle of User Mode Drivers" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">The ioctl() Requests</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch07s05.html">Prev</a>&#160;</td><th width="60%" align="center">Chapter&#160;7.&#160;The USB Filesystem (usbfs)</th><td width="20%" align="right">&#160;</td></tr></table><hr /></div><div class="sect1" title="The ioctl() Requests"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="usbfs-ioctl"></a>The ioctl() Requests</h2></div></div></div><div class="toc"><dl><dt><span class="sect2"><a href="ch07s06.html#usbfs-mgmt">Management/Status Requests</a></span></dt><dt><span class="sect2"><a href="ch07s06.html#usbfs-sync">Synchronous I/O Support</a></span></dt><dt><span class="sect2"><a href="ch07s06.html#usbfs-async">Asynchronous I/O Support</a></span></dt></dl></div><p>To use these ioctls, you need to include the following
	    headers in your userspace program:
</p><pre class="programlisting">#include &lt;linux/usb.h&gt;
#include &lt;linux/usbdevice_fs.h&gt;
#include &lt;asm/byteorder.h&gt;</pre><p>
	    The standard USB device model requests, from "Chapter 9" of
	    the USB 2.0 specification, are automatically included from
	    the <code class="filename">&lt;linux/usb/ch9.h&gt;</code> header.
	    </p><p>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
	    <code class="filename">Documentation/usb/error-codes.txt</code>
	    in your kernel sources.)
	    </p><p>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 khubd (in the kernel) setting a device-wide
	    <span class="emphasis"><em>configuration</em></span> that affects things
	    like power consumption and basic functionality.
	    The endpoints are part of USB <span class="emphasis"><em>interfaces</em></span>,
	    which may have <span class="emphasis"><em>altsettings</em></span>
	    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.
	    </p><div class="sect2" title="Management/Status Requests"><div class="titlepage"><div><div><h3 class="title"><a id="usbfs-mgmt"></a>Management/Status Requests</h3></div></div></div><p>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.
		</p><div class="variablelist"><dl><dt><span class="term">USBDEVFS_CLAIMINTERFACE</span></dt><dd><p>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).
		    </p><p>
		    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.
		    </p><p>
		    This claim will be released by a RELEASEINTERFACE ioctl,
		    or by closing the file descriptor.
		    File modification time is not updated by this request.
		    </p></dd><dt><span class="term">USBDEVFS_CONNECTINFO</span></dt><dd><p>Says whether the device is lowspeed.
		    The ioctl parameter points to a structure like this:
</p><pre class="programlisting">struct usbdevfs_connectinfo {
        unsigned int   devnum;
        unsigned char  slow;
}; </pre><p>
		    File modification time is not updated by this request.
		    </p><p>
		    <span class="emphasis"><em>You can't tell whether a "not slow"
		    device is connected at high speed (480 MBit/sec)
		    or just full speed (12 MBit/sec).</em></span>
		    You should know the devnum value already,
		    it's the DDD value of the device file name.
		    </p></dd><dt><span class="term">USBDEVFS_GETDRIVER</span></dt><dd><p>Returns the name of the kernel driver
		    bound to a given interface (a string).  Parameter
		    is a pointer to this structure, which is modified:
</p><pre class="programlisting">struct usbdevfs_getdriver {
        unsigned int  interface;
        char          driver[USBDEVFS_MAXDRIVERNAME + 1];
};</pre><p>
		    File modification time is not updated by this request.
		    </p></dd><dt><span class="term">USBDEVFS_IOCTL</span></dt><dd><p>Passes a request from userspace through
		    to a kernel driver that has an ioctl entry in the
		    <span class="emphasis"><em>struct usb_driver</em></span> it registered.
</p><pre class="programlisting">struct usbdevfs_ioctl {
        int     ifno;
        int     ioctl_code;
        void    *data;
};

/* user mode call looks like this.
 * 'request' becomes the driver-&gt;ioctl() 'code' parameter.
 * the size of 'param' is encoded in 'request', and that data
 * is copied to or from the driver-&gt;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, &amp;wrapper);
} </pre><p>
		    File modification time is not updated by this request.
		    </p><p>
		    This request lets kernel drivers talk to user mode code
		    through filesystem operations even when they don't create
		    a charactor 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.
		    </p></dd><dt><span class="term">USBDEVFS_RELEASEINTERFACE</span></dt><dd><p>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.
		    </p><div class="warning" title="Warning" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Warning</h3><p>
		    <span class="emphasis"><em>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.  </em></span>
		    </p></div></dd><dt><span class="term">USBDEVFS_RESETEP</span></dt><dd><p>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.
		    </p><div class="warning" title="Warning" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Warning</h3><p>
		    <span class="emphasis"><em>Avoid using this request.
		    It should probably be removed.</em></span>
		    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.
		    </p></div></dd></dl></div></div><div class="sect2" title="Synchronous I/O Support"><div class="titlepage"><div><div><h3 class="title"><a id="usbfs-sync"></a>Synchronous I/O Support</h3></div></div></div><p>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.
		</p><div class="variablelist"><dl><dt><span class="term">USBDEVFS_BULK</span></dt><dd><p>Issues a bulk read or write request to the
		    device.
		    The ioctl parameter is a pointer to this structure:
</p><pre class="programlisting">struct usbdevfs_bulktransfer {
        unsigned int  ep;
        unsigned int  len;
        unsigned int  timeout; /* in milliseconds */
        void          *data;
};</pre><p>
		    </p><p>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.
		    <span class="emphasis"><em>FIXME say how read length is returned,
		    and how short reads are handled.</em></span>.
		    </p></dd><dt><span class="term">USBDEVFS_CLEAR_HALT</span></dt><dd><p>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.
		    </p><p>
		    Use this on bulk or interrupt endpoints which have
		    stalled, returning <span class="emphasis"><em>-EPIPE</em></span> 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.
		    </p></dd><dt><span class="term">USBDEVFS_CONTROL</span></dt><dd><p>Issues a control request to the device.
		    The ioctl parameter points to a structure like this:
</p><pre class="programlisting">struct usbdevfs_ctrltransfer {
        __u8   bRequestType;
        __u8   bRequest;
        __u16  wValue;
        __u16  wIndex;
        __u16  wLength;
        __u32  timeout;  /* in milliseconds */
        void   *data;
};</pre><p>
		    </p><p>
		    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
		    <span class="emphasis"><em>&lt;linux/usb.h&gt;</em></span>).
		    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).
		    </p><p>
		    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.)
		    <span class="emphasis"><em>Also</em></span> there's no way to say it's
		    not OK to get a short read back from the device.
		    </p></dd><dt><span class="term">USBDEVFS_RESET</span></dt><dd><p>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.
		    </p><div class="warning" title="Warning" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Warning</h3><p>
		    <span class="emphasis"><em>Avoid using this call</em></span>
		    until some usbcore bugs get fixed,
		    since it does not fully synchronize device, interface,
		    and driver (not just usbfs) state.
		    </p></div></dd><dt><span class="term">USBDEVFS_SETINTERFACE</span></dt><dd><p>Sets the alternate setting for an
		    interface.  The ioctl parameter is a pointer to a
		    structure like this:
</p><pre class="programlisting">struct usbdevfs_setinterface {
        unsigned int  interface;
        unsigned int  altsetting;
}; </pre><p>
		    File modification time is not updated by this request.
		    </p><p>
		    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.)
		    </p></dd><dt><span class="term">USBDEVFS_SETCONFIGURATION</span></dt><dd><p>Issues the
		    <code class="function">usb_set_configuration</code> 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.
		    </p><div class="warning" title="Warning" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Warning</h3><p>
		    <span class="emphasis"><em>Avoid using this call</em></span>
		    until some usbcore bugs get fixed,
		    since it does not fully synchronize device, interface,
		    and driver (not just usbfs) state.
		    </p></div></dd></dl></div></div><div class="sect2" title="Asynchronous I/O Support"><div class="titlepage"><div><div><h3 class="title"><a id="usbfs-async"></a>Asynchronous I/O Support</h3></div></div></div><p>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.
		</p><p>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).
		</p><p>Each request can specify a realtime signal number
		(between SIGRTMIN and SIGRTMAX, inclusive) to request a
		signal be sent when the request completes.
		</p><p>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.
		</p><pre class="programlisting">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[];
};</pre><p> 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.
		</p><div class="variablelist"><dl><dt><span class="term">USBDEVFS_DISCARDURB</span></dt><dd><p>
		    <span class="emphasis"><em>TBS</em></span>
		    File modification time is not updated by this request.
		    </p><p>
		    </p></dd><dt><span class="term">USBDEVFS_DISCSIGNAL</span></dt><dd><p>
		    <span class="emphasis"><em>TBS</em></span>
		    File modification time is not updated by this request.
		    </p><p>
		    </p></dd><dt><span class="term">USBDEVFS_REAPURB</span></dt><dd><p>
		    <span class="emphasis"><em>TBS</em></span>
		    File modification time is not updated by this request.
		    </p><p>
		    </p></dd><dt><span class="term">USBDEVFS_REAPURBNDELAY</span></dt><dd><p>
		    <span class="emphasis"><em>TBS</em></span>
		    File modification time is not updated by this request.
		    </p><p>
		    </p></dd><dt><span class="term">USBDEVFS_SUBMITURB</span></dt><dd><p>
		    <span class="emphasis"><em>TBS</em></span>
		    </p><p>
		    </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch07s05.html">Prev</a>&#160;</td><td width="20%" align="center"><a accesskey="u" href="ch07.html">Up</a></td><td width="40%" align="right">&#160;</td></tr><tr><td width="40%" align="left" valign="top">Life Cycle of User Mode Drivers&#160;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&#160;</td></tr></table></div></body></html>