/usr/share/doc/libusb-1.0-doc/html/caveats.html is in libusb-1.0-doc 2:1.0.20-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | <!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/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.9.1"/>
<title>Caveats</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectbrief">A cross-platform user library to access USB devices</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.9.1 -->
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main Page</span></a></li>
<li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="annotated.html"><span>Data Structures</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
</ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">Caveats </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="devresets"></a>
Device resets</h1>
<p>The <a class="el" href="group__dev.html#ga7321bd8dc28e9a20b411bf18e6d0e9aa" title="Perform a USB port reset to reinitialize a device. ">libusb_reset_device()</a> function allows you to reset a device. If your program has to call such a function, it should obviously be aware that the reset will cause device state to change (e.g. register values may be reset).</p>
<p>The problem is that any other program could reset the device your program is working with, at any time. libusb does not offer a mechanism to inform you when this has happened, so if someone else resets your device it will not be clear to your own program why the device state has changed.</p>
<p>Ultimately, this is a limitation of writing drivers in userspace. Separation from the USB stack in the underlying kernel makes it difficult for the operating system to deliver such notifications to your program. The Linux kernel USB stack allows such reset notifications to be delivered to in-kernel USB drivers, but it is not clear how such notifications could be delivered to second-class drivers that live in userspace.</p>
<h1><a class="anchor" id="blockonly"></a>
Blocking-only functionality</h1>
<p>The functionality listed below is only available through synchronous, blocking functions. There are no asynchronous/non-blocking alternatives, and no clear ways of implementing these.</p>
<ul>
<li>Configuration activation (<a class="el" href="group__dev.html#ga186593ecae576dad6cd9679f45a2aa43" title="Set the active configuration for a device. ">libusb_set_configuration()</a>)</li>
<li>Interface/alternate setting activation (<a class="el" href="group__dev.html#ga3047fea29830a56524388fd423068b53" title="Activate an alternate setting for an interface. ">libusb_set_interface_alt_setting()</a>)</li>
<li>Releasing of interfaces (<a class="el" href="group__dev.html#gaf0d053dd23420c4daec89c06da04abe4" title="Release an interface previously claimed with libusb_claim_interface(). ">libusb_release_interface()</a>)</li>
<li>Clearing of halt/stall condition (<a class="el" href="group__dev.html#ga5b321176ce7f18cfec369dd3ab7d431e" title="Clear the halt/stall condition for an endpoint. ">libusb_clear_halt()</a>)</li>
<li>Device resets (<a class="el" href="group__dev.html#ga7321bd8dc28e9a20b411bf18e6d0e9aa" title="Perform a USB port reset to reinitialize a device. ">libusb_reset_device()</a>)</li>
</ul>
<h1><a class="anchor" id="configsel"></a>
Configuration selection and handling</h1>
<p>When libusb presents a device handle to an application, there is a chance that the corresponding device may be in unconfigured state. For devices with multiple configurations, there is also a chance that the configuration currently selected is not the one that the application wants to use.</p>
<p>The obvious solution is to add a call to <a class="el" href="group__dev.html#ga186593ecae576dad6cd9679f45a2aa43" title="Set the active configuration for a device. ">libusb_set_configuration()</a> early on during your device initialization routines, but there are caveats to be aware of:</p><ol type="1">
<li>If the device is already in the desired configuration, calling <a class="el" href="group__dev.html#ga186593ecae576dad6cd9679f45a2aa43" title="Set the active configuration for a device. ">libusb_set_configuration()</a> using the same configuration value will cause a lightweight device reset. This may not be desirable behaviour.</li>
<li>In the case where the desired configuration is already active, libusb may not even be able to perform a lightweight device reset. For example, take my USB keyboard with fingerprint reader: I'm interested in driving the fingerprint reader interface through libusb, but the kernel's USB-HID driver will almost always have claimed the keyboard interface. Because the kernel has claimed an interface, it is not even possible to perform the lightweight device reset, so <a class="el" href="group__dev.html#ga186593ecae576dad6cd9679f45a2aa43" title="Set the active configuration for a device. ">libusb_set_configuration()</a> will fail. (Luckily the device in question only has a single configuration.)</li>
<li>libusb will be unable to set a configuration if other programs or drivers have claimed interfaces. In particular, this means that kernel drivers must be detached from all the interfaces before <a class="el" href="group__dev.html#ga186593ecae576dad6cd9679f45a2aa43" title="Set the active configuration for a device. ">libusb_set_configuration()</a> may succeed.</li>
</ol>
<p>One solution to some of the above problems is to consider the currently active configuration. If the configuration we want is already active, then we don't have to select any configuration: </p><div class="fragment"><div class="line">cfg = -1;</div>
<div class="line"><a class="code" href="group__dev.html#ga6fdf904b6d53279da278b3556e51273c">libusb_get_configuration</a>(dev, &cfg);</div>
<div class="line"><span class="keywordflow">if</span> (cfg != desired)</div>
<div class="line"> <a class="code" href="group__dev.html#ga186593ecae576dad6cd9679f45a2aa43">libusb_set_configuration</a>(dev, desired);</div>
</div><!-- fragment --><p>This is probably suitable for most scenarios, but is inherently racy: another application or driver may change the selected configuration <em>after</em> the <a class="el" href="group__dev.html#ga6fdf904b6d53279da278b3556e51273c" title="Determine the bConfigurationValue of the currently active configuration. ">libusb_get_configuration()</a> call.</p>
<p>Even in cases where <a class="el" href="group__dev.html#ga186593ecae576dad6cd9679f45a2aa43" title="Set the active configuration for a device. ">libusb_set_configuration()</a> succeeds, consider that other applications or drivers may change configuration after your application calls <a class="el" href="group__dev.html#ga186593ecae576dad6cd9679f45a2aa43" title="Set the active configuration for a device. ">libusb_set_configuration()</a>.</p>
<p>One possible way to lock your device into a specific configuration is as follows:</p><ol type="1">
<li>Set the desired configuration (or use the logic above to realise that it is already in the desired configuration)</li>
<li>Claim the interface that you wish to use</li>
<li>Check that the currently active configuration is the one that you want to use.</li>
</ol>
<p>The above method works because once an interface is claimed, no application or driver is able to select another configuration.</p>
<h1><a class="anchor" id="earlycomp"></a>
Early transfer completion</h1>
<p>NOTE: This section is currently Linux-centric. I am not sure if any of these considerations apply to Darwin or other platforms.</p>
<p>When a transfer completes early (i.e. when less data is received/sent in any one packet than the transfer buffer allows for) then libusb is designed to terminate the transfer immediately, not transferring or receiving any more data unless other transfers have been queued by the user.</p>
<p>On legacy platforms, libusb is unable to do this in all situations. After the incomplete packet occurs, "surplus" data may be transferred. For recent versions of libusb, this information is kept (the data length of the transfer is updated) and, for device-to-host transfers, any surplus data was added to the buffer. Still, this is not a nice solution because it loses the information about the end of the short packet, and the user probably wanted that surplus data to arrive in the next logical transfer.</p>
<h1><a class="anchor" id="zlp"></a>
Zero length packets</h1>
<ul>
<li>libusb is able to send a packet of zero length to an endpoint simply by submitting a transfer of zero length.</li>
<li>The <a class="el" href="group__asyncio.html#gga1fb47dd0f7c209b60a3609ff0c03d56da26b66334b6ec0537c49841ca623d901f">LIBUSB_TRANSFER_ADD_ZERO_PACKET</a> flag is currently only supported on Linux. </li>
</ul>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Oct 23 2015 21:25:30 by  <a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
</body>
</html>
|