Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

175
Documentation/usb/CREDITS Normal file
View file

@ -0,0 +1,175 @@
Credits for the Simple Linux USB Driver:
The following people have contributed to this code (in alphabetical
order by last name). I'm sure this list should be longer, its
difficult to maintain, add yourself with a patch if desired.
Georg Acher <acher@informatik.tu-muenchen.de>
David Brownell <dbrownell@users.sourceforge.net>
Alan Cox <alan@lxorguk.ukuu.org.uk>
Randy Dunlap <randy.dunlap@intel.com>
Johannes Erdfelt <johannes@erdfelt.com>
Deti Fliegl <deti@fliegl.de>
ham <ham@unsuave.com>
Bradley M Keryan <keryan@andrew.cmu.edu>
Greg Kroah-Hartman <greg@kroah.com>
Pavel Machek <pavel@suse.cz>
Paul Mackerras <paulus@cs.anu.edu.au>
Petko Manlolov <petkan@dce.bg>
David E. Nelson <dnelson@jump.net>
Vojtech Pavlik <vojtech@suse.cz>
Bill Ryder <bryder@sgi.com>
Thomas Sailer <sailer@ife.ee.ethz.ch>
Gregory P. Smith <greg@electricrain.com>
Linus Torvalds <torvalds@linux-foundation.org>
Roman Weissgaerber <weissg@vienna.at>
<Kazuki.Yasumatsu@fujixerox.co.jp>
Special thanks to:
Inaky Perez Gonzalez <inaky@peloncho.fis.ucm.es> for starting the
Linux USB driver effort and writing much of the larger uusbd driver.
Much has been learned from that effort.
The NetBSD & FreeBSD USB developers. For being on the Linux USB list
and offering suggestions and sharing implementation experiences.
Additional thanks to the following companies and people for donations
of hardware, support, time and development (this is from the original
THANKS file in Inaky's driver):
The following corporations have helped us in the development
of Linux USB / UUSBD:
- 3Com GmbH for donating a ISDN Pro TA and supporting me
in technical questions and with test equipment. I'd never
expect such a great help.
- USAR Systems provided us with one of their excellent USB
Evaluation Kits. It allows us to test the Linux-USB driver
for compliance with the latest USB specification. USAR
Systems recognized the importance of an up-to-date open
Operating System and supports this project with
Hardware. Thanks!.
- Thanks to Intel Corporation for their precious help.
- We teamed up with Cherry to make Linux the first OS with
built-in USB support. Cherry is one of the biggest keyboard
makers in the world.
- CMD Technology, Inc. sponsored us kindly donating a CSA-6700
PCI-to-USB Controller Board to test the OHCI implementation.
- Due to their support to us, Keytronic can be sure that they
will sell keyboards to some of the 3 million (at least)
Linux users.
- Many thanks to ing büro h doran [http://www.ibhdoran.com]!
It was almost impossible to get a PC backplate USB connector
for the motherboard here at Europe (mine, home-made, was
quite lousy :). Now I know where to acquire nice USB stuff!
- Genius Germany donated a USB mouse to test the mouse boot
protocol. They've also donated a F-23 digital joystick and a
NetMouse Pro. Thanks!
- AVM GmbH Berlin is supporting the development of the Linux
USB driver for the AVM ISDN Controller B1 USB. AVM is a
leading manufacturer for active and passive ISDN Controllers
and CAPI 2.0-based software. The active design of the AVM B1
is open for all OS platforms, including Linux.
- Thanks to Y-E Data, Inc. for donating their FlashBuster-U
USB Floppy Disk Drive, so we could test the bulk transfer
code.
- Many thanks to Logitech for contributing a three axis USB
mouse.
Logitech designs, manufactures and markets
Human Interface Devices, having a long history and
experience in making devices such as keyboards, mice,
trackballs, cameras, loudspeakers and control devices for
gaming and professional use.
Being a recognized vendor and seller for all these devices,
they have donated USB mice, a joystick and a scanner, as a
way to acknowledge the importance of Linux and to allow
Logitech customers to enjoy support in their favorite
operating systems and all Linux users to use Logitech and
other USB hardware.
Logitech is official sponsor of the Linux Conference on
Feb. 11th 1999 in Vienna, where we'll will present the
current state of the Linux USB effort.
- CATC has provided means to uncover dark corners of the UHCI
inner workings with a USB Inspector.
- Thanks to Entrega for providing PCI to USB cards, hubs and
converter products for development.
- Thanks to ConnectTech for providing a WhiteHEAT usb to
serial converter, and the documentation for the device to
allow a driver to be written.
- Thanks to ADMtek for providing Pegasus and Pegasus II
evaluation boards, specs and valuable advices during
the driver development.
And thanks go to (hey! in no particular order :)
- Oren Tirosh <orenti@hishome.net>, for standing so patiently
all my doubts'bout USB and giving lots of cool ideas.
- Jochen Karrer <karrer@wpfd25.physik.uni-wuerzburg.de>, for
pointing out mortal bugs and giving advice.
- Edmund Humemberger <ed@atnet.at>, for it's great work on
public relationships and general management stuff for the
Linux-USB effort.
- Alberto Menegazzi <flash@flash.iol.it> is starting the
documentation for the UUSBD. Go for it!
- Ric Klaren <ia_ric@cs.utwente.nl> for doing nice
introductory documents (competing with Alberto's :).
- Christian Groessler <cpg@aladdin.de>, for it's help on those
itchy bits ... :)
- Paul MacKerras for polishing OHCI and pushing me harder for
the iMac support, giving improvements and enhancements.
- Fernando Herrera <fherrera@eurielec.etsit.upm.es> has taken
charge of composing, maintaining and feeding the
long-awaited, unique and marvelous UUSBD FAQ! Tadaaaa!!!
- Rasca Gmelch <thron@gmx.de> has revived the raw driver and
pointed bugs, as well as started the uusbd-utils package.
- Peter Dettori <dettori@ozy.dec.com> is uncovering bugs like
crazy, as well as making cool suggestions, great :)
- All the Free Software and Linux community, the FSF & the GNU
project, the MIT X consortium, the TeX people ... everyone!
You know who you are!
- Big thanks to Richard Stallman for creating Emacs!
- The people at the linux-usb mailing list, for reading so
many messages :) Ok, no more kidding; for all your advises!
- All the people at the USB Implementors Forum for their
help and assistance.
- Nathan Myers <ncm@cantrip.org>, for his advice! (hope you
liked Cibeles' party).
- Linus Torvalds, for starting, developing and managing Linux.
- Mike Smith, Craig Keithley, Thierry Giron and Janet Schank
for convincing me USB Standard hubs are not that standard
and that's good to allow for vendor specific quirks on the
standard hub driver.

261
Documentation/usb/URB.txt Normal file
View file

@ -0,0 +1,261 @@
Revised: 2000-Dec-05.
Again: 2002-Jul-06
Again: 2005-Sep-19
NOTE:
The USB subsystem now has a substantial section in "The Linux Kernel API"
guide (in Documentation/DocBook), generated from the current source
code. This particular documentation file isn't particularly current or
complete; don't rely on it except for a quick overview.
1.1. Basic concept or 'What is an URB?'
The basic idea of the new driver is message passing, the message itself is
called USB Request Block, or URB for short.
- An URB consists of all relevant information to execute any USB transaction
and deliver the data and status back.
- Execution of an URB is inherently an asynchronous operation, i.e. the
usb_submit_urb(urb) call returns immediately after it has successfully
queued the requested action.
- Transfers for one URB can be canceled with usb_unlink_urb(urb) at any time.
- Each URB has a completion handler, which is called after the action
has been successfully completed or canceled. The URB also contains a
context-pointer for passing information to the completion handler.
- Each endpoint for a device logically supports a queue of requests.
You can fill that queue, so that the USB hardware can still transfer
data to an endpoint while your driver handles completion of another.
This maximizes use of USB bandwidth, and supports seamless streaming
of data to (or from) devices when using periodic transfer modes.
1.2. The URB structure
Some of the fields in an URB are:
struct urb
{
// (IN) device and pipe specify the endpoint queue
struct usb_device *dev; // pointer to associated USB device
unsigned int pipe; // endpoint information
unsigned int transfer_flags; // ISO_ASAP, SHORT_NOT_OK, etc.
// (IN) all urbs need completion routines
void *context; // context for completion routine
void (*complete)(struct urb *); // pointer to completion routine
// (OUT) status after each completion
int status; // returned status
// (IN) buffer used for data transfers
void *transfer_buffer; // associated data buffer
int transfer_buffer_length; // data buffer length
int number_of_packets; // size of iso_frame_desc
// (OUT) sometimes only part of CTRL/BULK/INTR transfer_buffer is used
int actual_length; // actual data buffer length
// (IN) setup stage for CTRL (pass a struct usb_ctrlrequest)
unsigned char* setup_packet; // setup packet (control only)
// Only for PERIODIC transfers (ISO, INTERRUPT)
// (IN/OUT) start_frame is set unless ISO_ASAP isn't set
int start_frame; // start frame
int interval; // polling interval
// ISO only: packets are only "best effort"; each can have errors
int error_count; // number of errors
struct usb_iso_packet_descriptor iso_frame_desc[0];
};
Your driver must create the "pipe" value using values from the appropriate
endpoint descriptor in an interface that it's claimed.
1.3. How to get an URB?
URBs are allocated with the following call
struct urb *usb_alloc_urb(int isoframes, int mem_flags)
Return value is a pointer to the allocated URB, 0 if allocation failed.
The parameter isoframes specifies the number of isochronous transfer frames
you want to schedule. For CTRL/BULK/INT, use 0. The mem_flags parameter
holds standard memory allocation flags, letting you control (among other
things) whether the underlying code may block or not.
To free an URB, use
void usb_free_urb(struct urb *urb)
You may free an urb that you've submitted, but which hasn't yet been
returned to you in a completion callback. It will automatically be
deallocated when it is no longer in use.
1.4. What has to be filled in?
Depending on the type of transaction, there are some inline functions
defined in <linux/usb.h> to simplify the initialization, such as
fill_control_urb() and fill_bulk_urb(). In general, they need the usb
device pointer, the pipe (usual format from usb.h), the transfer buffer,
the desired transfer length, the completion handler, and its context.
Take a look at the some existing drivers to see how they're used.
Flags:
For ISO there are two startup behaviors: Specified start_frame or ASAP.
For ASAP set URB_ISO_ASAP in transfer_flags.
If short packets should NOT be tolerated, set URB_SHORT_NOT_OK in
transfer_flags.
1.5. How to submit an URB?
Just call
int usb_submit_urb(struct urb *urb, int mem_flags)
The mem_flags parameter, such as SLAB_ATOMIC, controls memory allocation,
such as whether the lower levels may block when memory is tight.
It immediately returns, either with status 0 (request queued) or some
error code, usually caused by the following:
- Out of memory (-ENOMEM)
- Unplugged device (-ENODEV)
- Stalled endpoint (-EPIPE)
- Too many queued ISO transfers (-EAGAIN)
- Too many requested ISO frames (-EFBIG)
- Invalid INT interval (-EINVAL)
- More than one packet for INT (-EINVAL)
After submission, urb->status is -EINPROGRESS; however, you should never
look at that value except in your completion callback.
For isochronous endpoints, your completion handlers should (re)submit
URBs to the same endpoint with the ISO_ASAP flag, using multi-buffering,
to get seamless ISO streaming.
1.6. How to cancel an already running URB?
There are two ways to cancel an URB you've submitted but which hasn't
been returned to your driver yet. For an asynchronous cancel, call
int usb_unlink_urb(struct urb *urb)
It removes the urb from the internal list and frees all allocated
HW descriptors. The status is changed to reflect unlinking. Note
that the URB will not normally have finished when usb_unlink_urb()
returns; you must still wait for the completion handler to be called.
To cancel an URB synchronously, call
void usb_kill_urb(struct urb *urb)
It does everything usb_unlink_urb does, and in addition it waits
until after the URB has been returned and the completion handler
has finished. It also marks the URB as temporarily unusable, so
that if the completion handler or anyone else tries to resubmit it
they will get a -EPERM error. Thus you can be sure that when
usb_kill_urb() returns, the URB is totally idle.
There is a lifetime issue to consider. An URB may complete at any
time, and the completion handler may free the URB. If this happens
while usb_unlink_urb or usb_kill_urb is running, it will cause a
memory-access violation. The driver is responsible for avoiding this,
which often means some sort of lock will be needed to prevent the URB
from being deallocated while it is still in use.
On the other hand, since usb_unlink_urb may end up calling the
completion handler, the handler must not take any lock that is held
when usb_unlink_urb is invoked. The general solution to this problem
is to increment the URB's reference count while holding the lock, then
drop the lock and call usb_unlink_urb or usb_kill_urb, and then
decrement the URB's reference count. You increment the reference
count by calling
struct urb *usb_get_urb(struct urb *urb)
(ignore the return value; it is the same as the argument) and
decrement the reference count by calling usb_free_urb. Of course,
none of this is necessary if there's no danger of the URB being freed
by the completion handler.
1.7. What about the completion handler?
The handler is of the following type:
typedef void (*usb_complete_t)(struct urb *)
I.e., it gets the URB that caused the completion call. In the completion
handler, you should have a look at urb->status to detect any USB errors.
Since the context parameter is included in the URB, you can pass
information to the completion handler.
Note that even when an error (or unlink) is reported, data may have been
transferred. That's because USB transfers are packetized; it might take
sixteen packets to transfer your 1KByte buffer, and ten of them might
have transferred successfully before the completion was called.
NOTE: ***** WARNING *****
NEVER SLEEP IN A COMPLETION HANDLER. These are often called in atomic
context.
In the current kernel, completion handlers run with local interrupts
disabled, but in the future this will be changed, so don't assume that
local IRQs are always disabled inside completion handlers.
1.8. How to do isochronous (ISO) transfers?
For ISO transfers you have to fill a usb_iso_packet_descriptor structure,
allocated at the end of the URB by usb_alloc_urb(n,mem_flags), for each
packet you want to schedule. You also have to set urb->interval to say
how often to make transfers; it's often one per frame (which is once
every microframe for highspeed devices). The actual interval used will
be a power of two that's no bigger than what you specify.
The usb_submit_urb() call modifies urb->interval to the implemented interval
value that is less than or equal to the requested interval value. If
ISO_ASAP scheduling is used, urb->start_frame is also updated.
For each entry you have to specify the data offset for this frame (base is
transfer_buffer), and the length you want to write/expect to read.
After completion, actual_length contains the actual transferred length and
status contains the resulting status for the ISO transfer for this frame.
It is allowed to specify a varying length from frame to frame (e.g. for
audio synchronisation/adaptive transfer rates). You can also use the length
0 to omit one or more frames (striping).
For scheduling you can choose your own start frame or ISO_ASAP. As explained
earlier, if you always keep at least one URB queued and your completion
keeps (re)submitting a later URB, you'll get smooth ISO streaming (if usb
bandwidth utilization allows).
If you specify your own start frame, make sure it's several frames in advance
of the current frame. You might want this model if you're synchronizing
ISO data with some other event stream.
1.9. How to start interrupt (INT) transfers?
Interrupt transfers, like isochronous transfers, are periodic, and happen
in intervals that are powers of two (1, 2, 4 etc) units. Units are frames
for full and low speed devices, and microframes for high speed ones.
The usb_submit_urb() call modifies urb->interval to the implemented interval
value that is less than or equal to the requested interval value.
In Linux 2.6, unlike earlier versions, interrupt URBs are not automagically
restarted when they complete. They end when the completion handler is
called, just like other URBs. If you want an interrupt URB to be restarted,
your completion handler must resubmit it.

View file

@ -0,0 +1,439 @@
Linux UWB + Wireless USB + WiNET
(C) 2005-2006 Intel Corporation
Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version
2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
Please visit http://bughost.org/thewiki/Design-overview.txt-1.8 for
updated content.
* Design-overview.txt-1.8
This code implements a Ultra Wide Band stack for Linux, as well as
drivers for the USB based UWB radio controllers defined in the
Wireless USB 1.0 specification (including Wireless USB host controller
and an Intel WiNET controller).
1. Introduction
1. HWA: Host Wire adapters, your Wireless USB dongle
2. DWA: Device Wired Adaptor, a Wireless USB hub for wired
devices
3. WHCI: Wireless Host Controller Interface, the PCI WUSB host
adapter
2. The UWB stack
1. Devices and hosts: the basic structure
2. Host Controller life cycle
3. On the air: beacons and enumerating the radio neighborhood
4. Device lists
5. Bandwidth allocation
3. Wireless USB Host Controller drivers
4. Glossary
Introduction
UWB is a wide-band communication protocol that is to serve also as the
low-level protocol for others (much like TCP sits on IP). Currently
these others are Wireless USB and TCP/IP, but seems Bluetooth and
Firewire/1394 are coming along.
UWB uses a band from roughly 3 to 10 GHz, transmitting at a max of
~-41dB (or 0.074 uW/MHz--geography specific data is still being
negotiated w/ regulators, so watch for changes). That band is divided in
a bunch of ~1.5 GHz wide channels (or band groups) composed of three
subbands/subchannels (528 MHz each). Each channel is independent of each
other, so you could consider them different "busses". Initially this
driver considers them all a single one.
Radio time is divided in 65536 us long /superframes/, each one divided
in 256 256us long /MASs/ (Media Allocation Slots), which are the basic
time/media allocation units for transferring data. At the beginning of
each superframe there is a Beacon Period (BP), where every device
transmit its beacon on a single MAS. The length of the BP depends on how
many devices are present and the length of their beacons.
Devices have a MAC (fixed, 48 bit address) and a device (changeable, 16
bit address) and send periodic beacons to advertise themselves and pass
info on what they are and do. They advertise their capabilities and a
bunch of other stuff.
The different logical parts of this driver are:
*
*UWB*: the Ultra-Wide-Band stack -- manages the radio and
associated spectrum to allow for devices sharing it. Allows to
control bandwidth assignment, beaconing, scanning, etc
*
*WUSB*: the layer that sits on top of UWB to provide Wireless USB.
The Wireless USB spec defines means to control a UWB radio and to
do the actual WUSB.
HWA: Host Wire adapters, your Wireless USB dongle
WUSB also defines a device called a Host Wire Adaptor (HWA), which in
mere terms is a USB dongle that enables your PC to have UWB and Wireless
USB. The Wireless USB Host Controller in a HWA looks to the host like a
[Wireless] USB controller connected via USB (!)
The HWA itself is broken in two or three main interfaces:
*
*RC*: Radio control -- this implements an interface to the
Ultra-Wide-Band radio controller. The driver for this implements a
USB-based UWB Radio Controller to the UWB stack.
*
*HC*: the wireless USB host controller. It looks like a USB host
whose root port is the radio and the WUSB devices connect to it.
To the system it looks like a separate USB host. The driver (will)
implement a USB host controller (similar to UHCI, OHCI or EHCI)
for which the root hub is the radio...To reiterate: it is a USB
controller that is connected via USB instead of PCI.
*
*WINET*: some HW provide a WiNET interface (IP over UWB). This
package provides a driver for it (it looks like a network
interface, winetX). The driver detects when there is a link up for
their type and kick into gear.
DWA: Device Wired Adaptor, a Wireless USB hub for wired devices
These are the complement to HWAs. They are a USB host for connecting
wired devices, but it is connected to your PC connected via Wireless
USB. To the system it looks like yet another USB host. To the untrained
eye, it looks like a hub that connects upstream wirelessly.
We still offer no support for this; however, it should share a lot of
code with the HWA-RC driver; there is a bunch of factorization work that
has been done to support that in upcoming releases.
WHCI: Wireless Host Controller Interface, the PCI WUSB host adapter
This is your usual PCI device that implements WHCI. Similar in concept
to EHCI, it allows your wireless USB devices (including DWAs) to connect
to your host via a PCI interface. As in the case of the HWA, it has a
Radio Control interface and the WUSB Host Controller interface per se.
There is still no driver support for this, but will be in upcoming
releases.
The UWB stack
The main mission of the UWB stack is to keep a tally of which devices
are in radio proximity to allow drivers to connect to them. As well, it
provides an API for controlling the local radio controllers (RCs from
now on), such as to start/stop beaconing, scan, allocate bandwidth, etc.
Devices and hosts: the basic structure
The main building block here is the UWB device (struct uwb_dev). For
each device that pops up in radio presence (ie: the UWB host receives a
beacon from it) you get a struct uwb_dev that will show up in
/sys/bus/uwb/devices.
For each RC that is detected, a new struct uwb_rc and struct uwb_dev are
created. An entry is also created in /sys/class/uwb_rc for each RC.
Each RC driver is implemented by a separate driver that plugs into the
interface that the UWB stack provides through a struct uwb_rc_ops. The
spec creators have been nice enough to make the message format the same
for HWA and WHCI RCs, so the driver is really a very thin transport that
moves the requests from the UWB API to the device [/uwb_rc_ops->cmd()/]
and sends the replies and notifications back to the API
[/uwb_rc_neh_grok()/]. Notifications are handled to the UWB daemon, that
is chartered, among other things, to keep the tab of how the UWB radio
neighborhood looks, creating and destroying devices as they show up or
disappear.
Command execution is very simple: a command block is sent and a event
block or reply is expected back. For sending/receiving command/events, a
handle called /neh/ (Notification/Event Handle) is opened with
/uwb_rc_neh_open()/.
The HWA-RC (USB dongle) driver (drivers/uwb/hwa-rc.c) does this job for
the USB connected HWA. Eventually, drivers/whci-rc.c will do the same
for the PCI connected WHCI controller.
Host Controller life cycle
So let's say we connect a dongle to the system: it is detected and
firmware uploaded if needed [for Intel's i1480
/drivers/uwb/ptc/usb.c:ptc_usb_probe()/] and then it is reenumerated.
Now we have a real HWA device connected and
/drivers/uwb/hwa-rc.c:hwarc_probe()/ picks it up, that will set up the
Wire-Adaptor environment and then suck it into the UWB stack's vision of
the world [/drivers/uwb/lc-rc.c:uwb_rc_add()/].
*
[*] The stack should put a new RC to scan for devices
[/uwb_rc_scan()/] so it finds what's available around and tries to
connect to them, but this is policy stuff and should be driven
from user space. As of now, the operator is expected to do it
manually; see the release notes for documentation on the procedure.
When a dongle is disconnected, /drivers/uwb/hwa-rc.c:hwarc_disconnect()/
takes time of tearing everything down safely (or not...).
On the air: beacons and enumerating the radio neighborhood
So assuming we have devices and we have agreed for a channel to connect
on (let's say 9), we put the new RC to beacon:
*
$ echo 9 0 > /sys/class/uwb_rc/uwb0/beacon
Now it is visible. If there were other devices in the same radio channel
and beacon group (that's what the zero is for), the dongle's radio
control interface will send beacon notifications on its
notification/event endpoint (NEEP). The beacon notifications are part of
the event stream that is funneled into the API with
/drivers/uwb/neh.c:uwb_rc_neh_grok()/ and delivered to the UWBD, the UWB
daemon through a notification list.
UWBD wakes up and scans the event list; finds a beacon and adds it to
the BEACON CACHE (/uwb_beca/). If he receives a number of beacons from
the same device, he considers it to be 'onair' and creates a new device
[/drivers/uwb/lc-dev.c:uwbd_dev_onair()/]. Similarly, when no beacons
are received in some time, the device is considered gone and wiped out
[uwbd calls periodically /uwb/beacon.c:uwb_beca_purge()/ that will purge
the beacon cache of dead devices].
Device lists
All UWB devices are kept in the list of the struct bus_type uwb_bus_type.
Bandwidth allocation
The UWB stack maintains a local copy of DRP availability through
processing of incoming *DRP Availability Change* notifications. This
local copy is currently used to present the current bandwidth
availability to the user through the sysfs file
/sys/class/uwb_rc/uwbx/bw_avail. In the future the bandwidth
availability information will be used by the bandwidth reservation
routines.
The bandwidth reservation routines are in progress and are thus not
present in the current release. When completed they will enable a user
to initiate DRP reservation requests through interaction with sysfs. DRP
reservation requests from remote UWB devices will also be handled. The
bandwidth management done by the UWB stack will include callbacks to the
higher layers will enable the higher layers to use the reservations upon
completion. [Note: The bandwidth reservation work is in progress and
subject to change.]
Wireless USB Host Controller drivers
*WARNING* This section needs a lot of work!
As explained above, there are three different types of HCs in the WUSB
world: HWA-HC, DWA-HC and WHCI-HC.
HWA-HC and DWA-HC share that they are Wire-Adapters (USB or WUSB
connected controllers), and their transfer management system is almost
identical. So is their notification delivery system.
HWA-HC and WHCI-HC share that they are both WUSB host controllers, so
they have to deal with WUSB device life cycle and maintenance, wireless
root-hub
HWA exposes a Host Controller interface (HWA-HC 0xe0/02/02). This has
three endpoints (Notifications, Data Transfer In and Data Transfer
Out--known as NEP, DTI and DTO in the code).
We reserve UWB bandwidth for our Wireless USB Cluster, create a Cluster
ID and tell the HC to use all that. Then we start it. This means the HC
starts sending MMCs.
*
The MMCs are blocks of data defined somewhere in the WUSB1.0 spec
that define a stream in the UWB channel time allocated for sending
WUSB IEs (host to device commands/notifications) and Device
Notifications (device initiated to host). Each host defines a
unique Wireless USB cluster through MMCs. Devices can connect to a
single cluster at the time. The IEs are Information Elements, and
among them are the bandwidth allocations that tell each device
when can they transmit or receive.
Now it all depends on external stimuli.
*New device connection*
A new device pops up, it scans the radio looking for MMCs that give out
the existence of Wireless USB channels. Once one (or more) are found,
selects which one to connect to. Sends a /DN_Connect/ (device
notification connect) during the DNTS (Device Notification Time
Slot--announced in the MMCs
HC picks the /DN_Connect/ out (nep module sends to notif.c for delivery
into /devconnect/). This process starts the authentication process for
the device. First we allocate a /fake port/ and assign an
unauthenticated address (128 to 255--what we really do is
0x80 | fake_port_idx). We fiddle with the fake port status and /hub_wq/
sees a new connection, so he moves on to enable the fake port with a reset.
So now we are in the reset path -- we know we have a non-yet enumerated
device with an unauthorized address; we ask user space to authenticate
(FIXME: not yet done, similar to bluetooth pairing), then we do the key
exchange (FIXME: not yet done) and issue a /set address 0/ to bring the
device to the default state. Device is authenticated.
From here, the USB stack takes control through the usb_hcd ops. hub_wq
has seen the port status changes, as we have been toggling them. It will
start enumerating and doing transfers through usb_hcd->urb_enqueue() to
read descriptors and move our data.
*Device life cycle and keep alives*
Every time there is a successful transfer to/from a device, we update a
per-device activity timestamp. If not, every now and then we check and
if the activity timestamp gets old, we ping the device by sending it a
Keep Alive IE; it responds with a /DN_Alive/ pong during the DNTS (this
arrives to us as a notification through
devconnect.c:wusb_handle_dn_alive(). If a device times out, we
disconnect it from the system (cleaning up internal information and
toggling the bits in the fake hub port, which kicks hub_wq into removing
the rest of the stuff).
This is done through devconnect:__wusb_check_devs(), which will scan the
device list looking for whom needs refreshing.
If the device wants to disconnect, it will either die (ugly) or send a
/DN_Disconnect/ that will prompt a disconnection from the system.
*Sending and receiving data*
Data is sent and received through /Remote Pipes/ (rpipes). An rpipe is
/aimed/ at an endpoint in a WUSB device. This is the same for HWAs and
DWAs.
Each HC has a number of rpipes and buffers that can be assigned to them;
when doing a data transfer (xfer), first the rpipe has to be aimed and
prepared (buffers assigned), then we can start queueing requests for
data in or out.
Data buffers have to be segmented out before sending--so we send first a
header (segment request) and then if there is any data, a data buffer
immediately after to the DTI interface (yep, even the request). If our
buffer is bigger than the max segment size, then we just do multiple
requests.
[This sucks, because doing USB scatter gatter in Linux is resource
intensive, if any...not that the current approach is not. It just has to
be cleaned up a lot :)].
If reading, we don't send data buffers, just the segment headers saying
we want to read segments.
When the xfer is executed, we receive a notification that says data is
ready in the DTI endpoint (handled through
xfer.c:wa_handle_notif_xfer()). In there we read from the DTI endpoint a
descriptor that gives us the status of the transfer, its identification
(given when we issued it) and the segment number. If it was a data read,
we issue another URB to read into the destination buffer the chunk of
data coming out of the remote endpoint. Done, wait for the next guy. The
callbacks for the URBs issued from here are the ones that will declare
the xfer complete at some point and call its callback.
Seems simple, but the implementation is not trivial.
*
*WARNING* Old!!
The main xfer descriptor, wa_xfer (equivalent to a URB) contains an
array of segments, tallys on segments and buffers and callback
information. Buried in there is a lot of URBs for executing the segments
and buffer transfers.
For OUT xfers, there is an array of segments, one URB for each, another
one of buffer URB. When submitting, we submit URBs for segment request
1, buffer 1, segment 2, buffer 2...etc. Then we wait on the DTI for xfer
result data; when all the segments are complete, we call the callback to
finalize the transfer.
For IN xfers, we only issue URBs for the segments we want to read and
then wait for the xfer result data.
*URB mapping into xfers*
This is done by hwahc_op_urb_[en|de]queue(). In enqueue() we aim an
rpipe to the endpoint where we have to transmit, create a transfer
context (wa_xfer) and submit it. When the xfer is done, our callback is
called and we assign the status bits and release the xfer resources.
In dequeue() we are basically cancelling/aborting the transfer. We issue
a xfer abort request to the HC, cancel all the URBs we had submitted
and not yet done and when all that is done, the xfer callback will be
called--this will call the URB callback.
Glossary
*DWA* -- Device Wire Adapter
USB host, wired for downstream devices, upstream connects wirelessly
with Wireless USB.
*EVENT* -- Response to a command on the NEEP
*HWA* -- Host Wire Adapter / USB dongle for UWB and Wireless USB
*NEH* -- Notification/Event Handle
Handle/file descriptor for receiving notifications or events. The WA
code requires you to get one of this to listen for notifications or
events on the NEEP.
*NEEP* -- Notification/Event EndPoint
Stuff related to the management of the first endpoint of a HWA USB
dongle that is used to deliver an stream of events and notifications to
the host.
*NOTIFICATION* -- Message coming in the NEEP as response to something.
*RC* -- Radio Control
Design-overview.txt-1.8 (last edited 2006-11-04 12:22:24 by
InakyPerezGonzalez)

128
Documentation/usb/acm.txt Normal file
View file

@ -0,0 +1,128 @@
Linux ACM driver v0.16
(c) 1999 Vojtech Pavlik <vojtech@suse.cz>
Sponsored by SuSE
----------------------------------------------------------------------------
0. Disclaimer
~~~~~~~~~~~~~
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA
Should you need to contact me, the author, you can do so either by e-mail
- mail your message to <vojtech@suse.cz>, or by paper mail: Vojtech Pavlik,
Ucitelska 1576, Prague 8, 182 00 Czech Republic
For your convenience, the GNU General Public License version 2 is included
in the package: See the file COPYING.
1. Usage
~~~~~~~~
The drivers/usb/class/cdc-acm.c drivers works with USB modems and USB ISDN terminal
adapters that conform to the Universal Serial Bus Communication Device Class
Abstract Control Model (USB CDC ACM) specification.
Many modems do, here is a list of those I know of:
3Com OfficeConnect 56k
3Com Voice FaxModem Pro
3Com Sportster
MultiTech MultiModem 56k
Zoom 2986L FaxModem
Compaq 56k FaxModem
ELSA Microlink 56k
I know of one ISDN TA that does work with the acm driver:
3Com USR ISDN Pro TA
Some cell phones also connect via USB. I know the following phones work:
SonyEricsson K800i
Unfortunately many modems and most ISDN TAs use proprietary interfaces and
thus won't work with this drivers. Check for ACM compliance before buying.
To use the modems you need these modules loaded:
usbcore.ko
uhci-hcd.ko ohci-hcd.ko or ehci-hcd.ko
cdc-acm.ko
After that, the modem[s] should be accessible. You should be able to use
minicom, ppp and mgetty with them.
2. Verifying that it works
~~~~~~~~~~~~~~~~~~~~~~~~~~
The first step would be to check /proc/bus/usb/devices, it should look
like this:
T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0
D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 0.00
S: Product=USB UHCI Root Hub
S: SerialNumber=6800
C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=255ms
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
D: Ver= 1.00 Cls=02(comm.) Sub=00 Prot=00 MxPS= 8 #Cfgs= 2
P: Vendor=04c1 ProdID=008f Rev= 2.07
S: Manufacturer=3Com Inc.
S: Product=3Com U.S. Robotics Pro ISDN TA
S: SerialNumber=UFT53A49BVT7
C: #Ifs= 1 Cfg#= 1 Atr=60 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=acm
E: Ad=85(I) Atr=02(Bulk) MxPS= 64 Ivl= 0ms
E: Ad=04(O) Atr=02(Bulk) MxPS= 64 Ivl= 0ms
E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=128ms
C:* #Ifs= 2 Cfg#= 2 Atr=60 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=acm
E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=128ms
I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=acm
E: Ad=85(I) Atr=02(Bulk) MxPS= 64 Ivl= 0ms
E: Ad=04(O) Atr=02(Bulk) MxPS= 64 Ivl= 0ms
The presence of these three lines (and the Cls= 'comm' and 'data' classes)
is important, it means it's an ACM device. The Driver=acm means the acm
driver is used for the device. If you see only Cls=ff(vend.) then you're out
of luck, you have a device with vendor specific-interface.
D: Ver= 1.00 Cls=02(comm.) Sub=00 Prot=00 MxPS= 8 #Cfgs= 2
I: If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=acm
I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=acm
In the system log you should see:
usb.c: USB new device connect, assigned device number 2
usb.c: kmalloc IF c7691fa0, numif 1
usb.c: kmalloc IF c7b5f3e0, numif 2
usb.c: skipped 4 class/vendor specific interface descriptors
usb.c: new device strings: Mfr=1, Product=2, SerialNumber=3
usb.c: USB device number 2 default language ID 0x409
Manufacturer: 3Com Inc.
Product: 3Com U.S. Robotics Pro ISDN TA
SerialNumber: UFT53A49BVT7
acm.c: probing config 1
acm.c: probing config 2
ttyACM0: USB ACM device
acm.c: acm_control_msg: rq: 0x22 val: 0x0 len: 0x0 result: 0
acm.c: acm_control_msg: rq: 0x20 val: 0x0 len: 0x7 result: 7
usb.c: acm driver claimed interface c7b5f3e0
usb.c: acm driver claimed interface c7b5f3f8
usb.c: acm driver claimed interface c7691fa0
If all this seems to be OK, fire up minicom and set it to talk to the ttyACM
device and try typing 'at'. If it responds with 'OK', then everything is
working.

View file

@ -0,0 +1,79 @@
What is anchor?
===============
A USB driver needs to support some callbacks requiring
a driver to cease all IO to an interface. To do so, a
driver has to keep track of the URBs it has submitted
to know they've all completed or to call usb_kill_urb
for them. The anchor is a data structure takes care of
keeping track of URBs and provides methods to deal with
multiple URBs.
Allocation and Initialisation
=============================
There's no API to allocate an anchor. It is simply declared
as struct usb_anchor. init_usb_anchor() must be called to
initialise the data structure.
Deallocation
============
Once it has no more URBs associated with it, the anchor can be
freed with normal memory management operations.
Association and disassociation of URBs with anchors
===================================================
An association of URBs to an anchor is made by an explicit
call to usb_anchor_urb(). The association is maintained until
an URB is finished by (successful) completion. Thus disassociation
is automatic. A function is provided to forcibly finish (kill)
all URBs associated with an anchor.
Furthermore, disassociation can be made with usb_unanchor_urb()
Operations on multitudes of URBs
================================
usb_kill_anchored_urbs()
------------------------
This function kills all URBs associated with an anchor. The URBs
are called in the reverse temporal order they were submitted.
This way no data can be reordered.
usb_unlink_anchored_urbs()
--------------------------
This function unlinks all URBs associated with an anchor. The URBs
are processed in the reverse temporal order they were submitted.
This is similar to usb_kill_anchored_urbs(), but it will not sleep.
Therefore no guarantee is made that the URBs have been unlinked when
the call returns. They may be unlinked later but will be unlinked in
finite time.
usb_scuttle_anchored_urbs()
---------------------------
All URBs of an anchor are unanchored en masse.
usb_wait_anchor_empty_timeout()
-------------------------------
This function waits for all URBs associated with an anchor to finish
or a timeout, whichever comes first. Its return value will tell you
whether the timeout was reached.
usb_anchor_empty()
------------------
Returns true if no URBs are associated with an anchor. Locking
is the caller's responsibility.
usb_get_from_anchor()
---------------------
Returns the oldest anchored URB of an anchor. The URB is unanchored
and returned with a reference. As you may mix URBs to several
destinations in one anchor you have no guarantee the chronologically
first submitted URB is returned.

View file

@ -0,0 +1,92 @@
Authorizing (or not) your USB devices to connect to the system
(C) 2007 Inaky Perez-Gonzalez <inaky@linux.intel.com> Intel Corporation
This feature allows you to control if a USB device can be used (or
not) in a system. This feature will allow you to implement a lock-down
of USB devices, fully controlled by user space.
As of now, when a USB device is connected it is configured and
its interfaces are immediately made available to the users. With this
modification, only if root authorizes the device to be configured will
then it be possible to use it.
Usage:
Authorize a device to connect:
$ echo 1 > /sys/bus/usb/devices/DEVICE/authorized
Deauthorize a device:
$ echo 0 > /sys/bus/usb/devices/DEVICE/authorized
Set new devices connected to hostX to be deauthorized by default (ie:
lock down):
$ echo 0 > /sys/bus/usb/devices/usbX/authorized_default
Remove the lock down:
$ echo 1 > /sys/bus/usb/devices/usbX/authorized_default
By default, Wired USB devices are authorized by default to
connect. Wireless USB hosts deauthorize by default all new connected
devices (this is so because we need to do an authentication phase
before authorizing).
Example system lockdown (lame)
-----------------------
Imagine you want to implement a lockdown so only devices of type XYZ
can be connected (for example, it is a kiosk machine with a visible
USB port):
boot up
rc.local ->
for host in /sys/bus/usb/devices/usb*
do
echo 0 > $host/authorized_default
done
Hookup an script to udev, for new USB devices
if device_is_my_type $DEV
then
echo 1 > $device_path/authorized
done
Now, device_is_my_type() is where the juice for a lockdown is. Just
checking if the class, type and protocol match something is the worse
security verification you can make (or the best, for someone willing
to break it). If you need something secure, use crypto and Certificate
Authentication or stuff like that. Something simple for an storage key
could be:
function device_is_my_type()
{
echo 1 > authorized # temporarily authorize it
# FIXME: make sure none can mount it
mount DEVICENODE /mntpoint
sum=$(md5sum /mntpoint/.signature)
if [ $sum = $(cat /etc/lockdown/keysum) ]
then
echo "We are good, connected"
umount /mntpoint
# Other stuff so others can use it
else
echo 0 > authorized
fi
}
Of course, this is lame, you'd want to do a real certificate
verification stuff with PKI, so you don't depend on a shared secret,
etc, but you get the idea. Anybody with access to a device gadget kit
can fake descriptors and device info. Don't trust that. You are
welcome.

View file

@ -0,0 +1,78 @@
Background
==========
Bulk endpoint streams were added in the USB 3.0 specification. Streams allow a
device driver to overload a bulk endpoint so that multiple transfers can be
queued at once.
Streams are defined in sections 4.4.6.4 and 8.12.1.4 of the Universal Serial Bus
3.0 specification at http://www.usb.org/developers/docs/ The USB Attached SCSI
Protocol, which uses streams to queue multiple SCSI commands, can be found on
the T10 website (http://t10.org/).
Device-side implications
========================
Once a buffer has been queued to a stream ring, the device is notified (through
an out-of-band mechanism on another endpoint) that data is ready for that stream
ID. The device then tells the host which "stream" it wants to start. The host
can also initiate a transfer on a stream without the device asking, but the
device can refuse that transfer. Devices can switch between streams at any
time.
Driver implications
===================
int usb_alloc_streams(struct usb_interface *interface,
struct usb_host_endpoint **eps, unsigned int num_eps,
unsigned int num_streams, gfp_t mem_flags);
Device drivers will call this API to request that the host controller driver
allocate memory so the driver can use up to num_streams stream IDs. They must
pass an array of usb_host_endpoints that need to be setup with similar stream
IDs. This is to ensure that a UASP driver will be able to use the same stream
ID for the bulk IN and OUT endpoints used in a Bi-directional command sequence.
The return value is an error condition (if one of the endpoints doesn't support
streams, or the xHCI driver ran out of memory), or the number of streams the
host controller allocated for this endpoint. The xHCI host controller hardware
declares how many stream IDs it can support, and each bulk endpoint on a
SuperSpeed device will say how many stream IDs it can handle. Therefore,
drivers should be able to deal with being allocated less stream IDs than they
requested.
Do NOT call this function if you have URBs enqueued for any of the endpoints
passed in as arguments. Do not call this function to request less than two
streams.
Drivers will only be allowed to call this API once for the same endpoint
without calling usb_free_streams(). This is a simplification for the xHCI host
controller driver, and may change in the future.
Picking new Stream IDs to use
============================
Stream ID 0 is reserved, and should not be used to communicate with devices. If
usb_alloc_streams() returns with a value of N, you may use streams 1 though N.
To queue an URB for a specific stream, set the urb->stream_id value. If the
endpoint does not support streams, an error will be returned.
Note that new API to choose the next stream ID will have to be added if the xHCI
driver supports secondary stream IDs.
Clean up
========
If a driver wishes to stop using streams to communicate with the device, it
should call
void usb_free_streams(struct usb_interface *interface,
struct usb_host_endpoint **eps, unsigned int num_eps,
gfp_t mem_flags);
All stream IDs will be deallocated when the driver releases the interface, to
ensure that drivers that don't support streams will be able to use the endpoint.

View file

@ -0,0 +1,134 @@
What callbacks will usbcore do?
===============================
Usbcore will call into a driver through callbacks defined in the driver
structure and through the completion handler of URBs a driver submits.
Only the former are in the scope of this document. These two kinds of
callbacks are completely independent of each other. Information on the
completion callback can be found in Documentation/usb/URB.txt.
The callbacks defined in the driver structure are:
1. Hotplugging callbacks:
* @probe: Called to see if the driver is willing to manage a particular
* interface on a device.
* @disconnect: Called when the interface is no longer accessible, usually
* because its device has been (or is being) disconnected or the
* driver module is being unloaded.
2. Odd backdoor through usbfs:
* @ioctl: Used for drivers that want to talk to userspace through
* the "usbfs" filesystem. This lets devices provide ways to
* expose information to user space regardless of where they
* do (or don't) show up otherwise in the filesystem.
3. Power management (PM) callbacks:
* @suspend: Called when the device is going to be suspended.
* @resume: Called when the device is being resumed.
* @reset_resume: Called when the suspended device has been reset instead
* of being resumed.
4. Device level operations:
* @pre_reset: Called when the device is about to be reset.
* @post_reset: Called after the device has been reset
The ioctl interface (2) should be used only if you have a very good
reason. Sysfs is preferred these days. The PM callbacks are covered
separately in Documentation/usb/power-management.txt.
Calling conventions
===================
All callbacks are mutually exclusive. There's no need for locking
against other USB callbacks. All callbacks are called from a task
context. You may sleep. However, it is important that all sleeps have a
small fixed upper limit in time. In particular you must not call out to
user space and await results.
Hotplugging callbacks
=====================
These callbacks are intended to associate and disassociate a driver with
an interface. A driver's bond to an interface is exclusive.
The probe() callback
--------------------
int (*probe) (struct usb_interface *intf,
const struct usb_device_id *id);
Accept or decline an interface. If you accept the device return 0,
otherwise -ENODEV or -ENXIO. Other error codes should be used only if a
genuine error occurred during initialisation which prevented a driver
from accepting a device that would else have been accepted.
You are strongly encouraged to use usbcore's facility,
usb_set_intfdata(), to associate a data structure with an interface, so
that you know which internal state and identity you associate with a
particular interface. The device will not be suspended and you may do IO
to the interface you are called for and endpoint 0 of the device. Device
initialisation that doesn't take too long is a good idea here.
The disconnect() callback
-------------------------
void (*disconnect) (struct usb_interface *intf);
This callback is a signal to break any connection with an interface.
You are not allowed any IO to a device after returning from this
callback. You also may not do any other operation that may interfere
with another driver bound the interface, eg. a power management
operation.
If you are called due to a physical disconnection, all your URBs will be
killed by usbcore. Note that in this case disconnect will be called some
time after the physical disconnection. Thus your driver must be prepared
to deal with failing IO even prior to the callback.
Device level callbacks
======================
pre_reset
---------
int (*pre_reset)(struct usb_interface *intf);
A driver or user space is triggering a reset on the device which
contains the interface passed as an argument. Cease IO, wait for all
outstanding URBs to complete, and save any device state you need to
restore. No more URBs may be submitted until the post_reset method
is called.
If you need to allocate memory here, use GFP_NOIO or GFP_ATOMIC, if you
are in atomic context.
post_reset
----------
int (*post_reset)(struct usb_interface *intf);
The reset has completed. Restore any saved device state and begin
using the device again.
If you need to allocate memory here, use GFP_NOIO or GFP_ATOMIC, if you
are in atomic context.
Call sequences
==============
No callbacks other than probe will be invoked for an interface
that isn't bound to your driver.
Probe will never be called for an interface bound to a driver.
Hence following a successful probe, disconnect will be called
before there is another probe for the same interface.
Once your driver is bound to an interface, disconnect can be
called at any time except in between pre_reset and post_reset.
pre_reset is always followed by post_reset, even if the reset
failed or the device has been unplugged.
suspend is always followed by one of: resume, reset_resume, or
disconnect.

View file

@ -0,0 +1,71 @@
1. How to test OTG FSM(HNP and SRP)
-----------------------------------
To show how to demo OTG HNP and SRP functions via sys input files
with 2 Freescale i.MX6Q sabre SD boards.
1.1 How to enable OTG FSM in menuconfig
---------------------------------------
Select CONFIG_USB_OTG_FSM, rebuild kernel Image and modules.
If you want to check some internal variables for otg fsm,
select CONFIG_USB_CHIPIDEA_DEBUG, there are 2 files which
can show otg fsm variables and some controller registers value:
cat /sys/kernel/debug/ci_hdrc.0/otg
cat /sys/kernel/debug/ci_hdrc.0/registers
1.2 Test operations
-------------------
1) Power up 2 Freescale i.MX6Q sabre SD boards with gadget class driver loaded
(e.g. g_mass_storage).
2) Connect 2 boards with usb cable with one end is micro A plug, the other end
is micro B plug.
The A-device(with micro A plug inserted) should enumrate B-device.
3) Role switch
On B-device:
echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req
if HNP polling is not supported, also need:
On A-device:
echo 0 > /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_req
B-device should take host role and enumrate A-device.
4) A-device switch back to host.
On B-device:
echo 0 > /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req
A-device should switch back to host and enumrate B-device.
5) Remove B-device(unplug micro B plug) and insert again in 10 seconds,
A-device should enumrate B-device again.
6) Remove B-device(unplug micro B plug) and insert again after 10 seconds,
A-device should NOT enumrate B-device.
if A-device wants to use bus:
On A-device:
echo 0 > /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_drop
echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_req
if B-device wants to use bus:
On B-device:
echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req
7) A-device power down the bus.
On A-device:
echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_drop
A-device should disconnect with B-device and power down the bus.
8) B-device does data pulse for SRP.
On B-device:
echo 1 > /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req
A-device should resume usb bus and enumrate B-device.
1.3 Reference document
----------------------
"On-The-Go and Embedded Host Supplement to the USB Revision 2.0 Specification
July 27, 2012 Revision 2.0 version 1.1a"

133
Documentation/usb/dma.txt Normal file
View file

@ -0,0 +1,133 @@
In Linux 2.5 kernels (and later), USB device drivers have additional control
over how DMA may be used to perform I/O operations. The APIs are detailed
in the kernel usb programming guide (kerneldoc, from the source code).
API OVERVIEW
The big picture is that USB drivers can continue to ignore most DMA issues,
though they still must provide DMA-ready buffers (see
Documentation/DMA-API-HOWTO.txt). That's how they've worked through
the 2.4 (and earlier) kernels.
OR: they can now be DMA-aware.
- New calls enable DMA-aware drivers, letting them allocate dma buffers and
manage dma mappings for existing dma-ready buffers (see below).
- URBs have an additional "transfer_dma" field, as well as a transfer_flags
bit saying if it's valid. (Control requests also have "setup_dma", but
drivers must not use it.)
- "usbcore" will map this DMA address, if a DMA-aware driver didn't do
it first and set URB_NO_TRANSFER_DMA_MAP. HCDs
don't manage dma mappings for URBs.
- There's a new "generic DMA API", parts of which are usable by USB device
drivers. Never use dma_set_mask() on any USB interface or device; that
would potentially break all devices sharing that bus.
ELIMINATING COPIES
It's good to avoid making CPUs copy data needlessly. The costs can add up,
and effects like cache-trashing can impose subtle penalties.
- If you're doing lots of small data transfers from the same buffer all
the time, that can really burn up resources on systems which use an
IOMMU to manage the DMA mappings. It can cost MUCH more to set up and
tear down the IOMMU mappings with each request than perform the I/O!
For those specific cases, USB has primitives to allocate less expensive
memory. They work like kmalloc and kfree versions that give you the right
kind of addresses to store in urb->transfer_buffer and urb->transfer_dma.
You'd also set URB_NO_TRANSFER_DMA_MAP in urb->transfer_flags:
void *usb_alloc_coherent (struct usb_device *dev, size_t size,
int mem_flags, dma_addr_t *dma);
void usb_free_coherent (struct usb_device *dev, size_t size,
void *addr, dma_addr_t dma);
Most drivers should *NOT* be using these primitives; they don't need
to use this type of memory ("dma-coherent"), and memory returned from
kmalloc() will work just fine.
The memory buffer returned is "dma-coherent"; sometimes you might need to
force a consistent memory access ordering by using memory barriers. It's
not using a streaming DMA mapping, so it's good for small transfers on
systems where the I/O would otherwise thrash an IOMMU mapping. (See
Documentation/DMA-API-HOWTO.txt for definitions of "coherent" and
"streaming" DMA mappings.)
Asking for 1/Nth of a page (as well as asking for N pages) is reasonably
space-efficient.
On most systems the memory returned will be uncached, because the
semantics of dma-coherent memory require either bypassing CPU caches
or using cache hardware with bus-snooping support. While x86 hardware
has such bus-snooping, many other systems use software to flush cache
lines to prevent DMA conflicts.
- Devices on some EHCI controllers could handle DMA to/from high memory.
Unfortunately, the current Linux DMA infrastructure doesn't have a sane
way to expose these capabilities ... and in any case, HIGHMEM is mostly a
design wart specific to x86_32. So your best bet is to ensure you never
pass a highmem buffer into a USB driver. That's easy; it's the default
behavior. Just don't override it; e.g. with NETIF_F_HIGHDMA.
This may force your callers to do some bounce buffering, copying from
high memory to "normal" DMA memory. If you can come up with a good way
to fix this issue (for x86_32 machines with over 1 GByte of memory),
feel free to submit patches.
WORKING WITH EXISTING BUFFERS
Existing buffers aren't usable for DMA without first being mapped into the
DMA address space of the device. However, most buffers passed to your
driver can safely be used with such DMA mapping. (See the first section
of Documentation/DMA-API-HOWTO.txt, titled "What memory is DMA-able?")
- When you're using scatterlists, you can map everything at once. On some
systems, this kicks in an IOMMU and turns the scatterlists into single
DMA transactions:
int usb_buffer_map_sg (struct usb_device *dev, unsigned pipe,
struct scatterlist *sg, int nents);
void usb_buffer_dmasync_sg (struct usb_device *dev, unsigned pipe,
struct scatterlist *sg, int n_hw_ents);
void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
struct scatterlist *sg, int n_hw_ents);
It's probably easier to use the new usb_sg_*() calls, which do the DMA
mapping and apply other tweaks to make scatterlist i/o be fast.
- Some drivers may prefer to work with the model that they're mapping large
buffers, synchronizing their safe re-use. (If there's no re-use, then let
usbcore do the map/unmap.) Large periodic transfers make good examples
here, since it's cheaper to just synchronize the buffer than to unmap it
each time an urb completes and then re-map it on during resubmission.
These calls all work with initialized urbs: urb->dev, urb->pipe,
urb->transfer_buffer, and urb->transfer_buffer_length must all be
valid when these calls are used (urb->setup_packet must be valid too
if urb is a control request):
struct urb *usb_buffer_map (struct urb *urb);
void usb_buffer_dmasync (struct urb *urb);
void usb_buffer_unmap (struct urb *urb);
The calls manage urb->transfer_dma for you, and set URB_NO_TRANSFER_DMA_MAP
so that usbcore won't map or unmap the buffer. They cannot be used for
setup_packet buffers in control requests.
Note that several of those interfaces are currently commented out, since
they don't have current users. See the source code. Other than the dmasync
calls (where the underlying DMA primitives have changed), most of them can
easily be commented back in if you want to use them.

View file

@ -0,0 +1,45 @@
TODO
~~~~~~
Please pick something while reading :)
- Convert interrupt handler to per-ep-thread-irq
As it turns out some DWC3-commands ~1ms to complete. Currently we spin
until the command completes which is bad.
Implementation idea:
- dwc core implements a demultiplexing irq chip for interrupts per
endpoint. The interrupt numbers are allocated during probe and belong
to the device. If MSI provides per-endpoint interrupt this dummy
interrupt chip can be replaced with "real" interrupts.
- interrupts are requested / allocated on usb_ep_enable() and removed on
usb_ep_disable(). Worst case are 32 interrupts, the lower limit is two
for ep0/1.
- dwc3_send_gadget_ep_cmd() will sleep in wait_for_completion_timeout()
until the command completes.
- the interrupt handler is split into the following pieces:
- primary handler of the device
goes through every event and calls generic_handle_irq() for event
it. On return from generic_handle_irq() in acknowledges the event
counter so interrupt goes away (eventually).
- threaded handler of the device
none
- primary handler of the EP-interrupt
reads the event and tries to process it. Everything that requires
sleeping is handed over to the Thread. The event is saved in an
per-endpoint data-structure.
We probably have to pay attention not to process events once we
handed something to thread so we don't process event X prio Y
where X > Y.
- threaded handler of the EP-interrupt
handles the remaining EP work which might sleep such as waiting
for command completion.
Latency:
There should be no increase in latency since the interrupt-thread has a
high priority and will be run before an average task in user land
(except the user changed priorities).

214
Documentation/usb/ehci.txt Normal file
View file

@ -0,0 +1,214 @@
27-Dec-2002
The EHCI driver is used to talk to high speed USB 2.0 devices using
USB 2.0-capable host controller hardware. The USB 2.0 standard is
compatible with the USB 1.1 standard. It defines three transfer speeds:
- "High Speed" 480 Mbit/sec (60 MByte/sec)
- "Full Speed" 12 Mbit/sec (1.5 MByte/sec)
- "Low Speed" 1.5 Mbit/sec
USB 1.1 only addressed full speed and low speed. High speed devices
can be used on USB 1.1 systems, but they slow down to USB 1.1 speeds.
USB 1.1 devices may also be used on USB 2.0 systems. When plugged
into an EHCI controller, they are given to a USB 1.1 "companion"
controller, which is a OHCI or UHCI controller as normally used with
such devices. When USB 1.1 devices plug into USB 2.0 hubs, they
interact with the EHCI controller through a "Transaction Translator"
(TT) in the hub, which turns low or full speed transactions into
high speed "split transactions" that don't waste transfer bandwidth.
At this writing, this driver has been seen to work with implementations
of EHCI from (in alphabetical order): Intel, NEC, Philips, and VIA.
Other EHCI implementations are becoming available from other vendors;
you should expect this driver to work with them too.
While usb-storage devices have been available since mid-2001 (working
quite speedily on the 2.4 version of this driver), hubs have only
been available since late 2001, and other kinds of high speed devices
appear to be on hold until more systems come with USB 2.0 built-in.
Such new systems have been available since early 2002, and became much
more typical in the second half of 2002.
Note that USB 2.0 support involves more than just EHCI. It requires
other changes to the Linux-USB core APIs, including the hub driver,
but those changes haven't needed to really change the basic "usbcore"
APIs exposed to USB device drivers.
- David Brownell
<dbrownell@users.sourceforge.net>
FUNCTIONALITY
This driver is regularly tested on x86 hardware, and has also been
used on PPC hardware so big/little endianness issues should be gone.
It's believed to do all the right PCI magic so that I/O works even on
systems with interesting DMA mapping issues.
Transfer Types
At this writing the driver should comfortably handle all control, bulk,
and interrupt transfers, including requests to USB 1.1 devices through
transaction translators (TTs) in USB 2.0 hubs. But you may find bugs.
High Speed Isochronous (ISO) transfer support is also functional, but
at this writing no Linux drivers have been using that support.
Full Speed Isochronous transfer support, through transaction translators,
is not yet available. Note that split transaction support for ISO
transfers can't share much code with the code for high speed ISO transfers,
since EHCI represents these with a different data structure. So for now,
most USB audio and video devices can't be connected to high speed buses.
Driver Behavior
Transfers of all types can be queued. This means that control transfers
from a driver on one interface (or through usbfs) won't interfere with
ones from another driver, and that interrupt transfers can use periods
of one frame without risking data loss due to interrupt processing costs.
The EHCI root hub code hands off USB 1.1 devices to its companion
controller. This driver doesn't need to know anything about those
drivers; a OHCI or UHCI driver that works already doesn't need to change
just because the EHCI driver is also present.
There are some issues with power management; suspend/resume doesn't
behave quite right at the moment.
Also, some shortcuts have been taken with the scheduling periodic
transactions (interrupt and isochronous transfers). These place some
limits on the number of periodic transactions that can be scheduled,
and prevent use of polling intervals of less than one frame.
USE BY
Assuming you have an EHCI controller (on a PCI card or motherboard)
and have compiled this driver as a module, load this like:
# modprobe ehci-hcd
and remove it by:
# rmmod ehci-hcd
You should also have a driver for a "companion controller", such as
"ohci-hcd" or "uhci-hcd". In case of any trouble with the EHCI driver,
remove its module and then the driver for that companion controller will
take over (at lower speed) all the devices that were previously handled
by the EHCI driver.
Module parameters (pass to "modprobe") include:
log2_irq_thresh (default 0):
Log2 of default interrupt delay, in microframes. The default
value is 0, indicating 1 microframe (125 usec). Maximum value
is 6, indicating 2^6 = 64 microframes. This controls how often
the EHCI controller can issue interrupts.
If you're using this driver on a 2.5 kernel, and you've enabled USB
debugging support, you'll see three files in the "sysfs" directory for
any EHCI controller:
"async" dumps the asynchronous schedule, used for control
and bulk transfers. Shows each active qh and the qtds
pending, usually one qtd per urb. (Look at it with
usb-storage doing disk I/O; watch the request queues!)
"periodic" dumps the periodic schedule, used for interrupt
and isochronous transfers. Doesn't show qtds.
"registers" show controller register state, and
The contents of those files can help identify driver problems.
Device drivers shouldn't care whether they're running over EHCI or not,
but they may want to check for "usb_device->speed == USB_SPEED_HIGH".
High speed devices can do things that full speed (or low speed) ones
can't, such as "high bandwidth" periodic (interrupt or ISO) transfers.
Also, some values in device descriptors (such as polling intervals for
periodic transfers) use different encodings when operating at high speed.
However, do make a point of testing device drivers through USB 2.0 hubs.
Those hubs report some failures, such as disconnections, differently when
transaction translators are in use; some drivers have been seen to behave
badly when they see different faults than OHCI or UHCI report.
PERFORMANCE
USB 2.0 throughput is gated by two main factors: how fast the host
controller can process requests, and how fast devices can respond to
them. The 480 Mbit/sec "raw transfer rate" is obeyed by all devices,
but aggregate throughput is also affected by issues like delays between
individual high speed packets, driver intelligence, and of course the
overall system load. Latency is also a performance concern.
Bulk transfers are most often used where throughput is an issue. It's
good to keep in mind that bulk transfers are always in 512 byte packets,
and at most 13 of those fit into one USB 2.0 microframe. Eight USB 2.0
microframes fit in a USB 1.1 frame; a microframe is 1 msec/8 = 125 usec.
So more than 50 MByte/sec is available for bulk transfers, when both
hardware and device driver software allow it. Periodic transfer modes
(isochronous and interrupt) allow the larger packet sizes which let you
approach the quoted 480 MBit/sec transfer rate.
Hardware Performance
At this writing, individual USB 2.0 devices tend to max out at around
20 MByte/sec transfer rates. This is of course subject to change;
and some devices now go faster, while others go slower.
The first NEC implementation of EHCI seems to have a hardware bottleneck
at around 28 MByte/sec aggregate transfer rate. While this is clearly
enough for a single device at 20 MByte/sec, putting three such devices
onto one bus does not get you 60 MByte/sec. The issue appears to be
that the controller hardware won't do concurrent USB and PCI access,
so that it's only trying six (or maybe seven) USB transactions each
microframe rather than thirteen. (Seems like a reasonable trade off
for a product that beat all the others to market by over a year!)
It's expected that newer implementations will better this, throwing
more silicon real estate at the problem so that new motherboard chip
sets will get closer to that 60 MByte/sec target. That includes an
updated implementation from NEC, as well as other vendors' silicon.
There's a minimum latency of one microframe (125 usec) for the host
to receive interrupts from the EHCI controller indicating completion
of requests. That latency is tunable; there's a module option. By
default ehci-hcd driver uses the minimum latency, which means that if
you issue a control or bulk request you can often expect to learn that
it completed in less than 250 usec (depending on transfer size).
Software Performance
To get even 20 MByte/sec transfer rates, Linux-USB device drivers will
need to keep the EHCI queue full. That means issuing large requests,
or using bulk queuing if a series of small requests needs to be issued.
When drivers don't do that, their performance results will show it.
In typical situations, a usb_bulk_msg() loop writing out 4 KB chunks is
going to waste more than half the USB 2.0 bandwidth. Delays between the
I/O completion and the driver issuing the next request will take longer
than the I/O. If that same loop used 16 KB chunks, it'd be better; a
sequence of 128 KB chunks would waste a lot less.
But rather than depending on such large I/O buffers to make synchronous
I/O be efficient, it's better to just queue up several (bulk) requests
to the HC, and wait for them all to complete (or be canceled on error).
Such URB queuing should work with all the USB 1.1 HC drivers too.
In the Linux 2.5 kernels, new usb_sg_*() api calls have been defined; they
queue all the buffers from a scatterlist. They also use scatterlist DMA
mapping (which might apply an IOMMU) and IRQ reduction, all of which will
help make high speed transfers run as fast as they can.
TBD: Interrupt and ISO transfer performance issues. Those periodic
transfers are fully scheduled, so the main issue is likely to be how
to trigger "high bandwidth" modes.
TBD: More than standard 80% periodic bandwidth allocation is possible
through sysfs uframe_periodic_max parameter. Describe that.

View file

@ -0,0 +1,175 @@
Revised: 2004-Oct-21
This is the documentation of (hopefully) all possible error codes (and
their interpretation) that can be returned from usbcore.
Some of them are returned by the Host Controller Drivers (HCDs), which
device drivers only see through usbcore. As a rule, all the HCDs should
behave the same except for transfer speed dependent behaviors and the
way certain faults are reported.
**************************************************************************
* Error codes returned by usb_submit_urb *
**************************************************************************
Non-USB-specific:
0 URB submission went fine
-ENOMEM no memory for allocation of internal structures
USB-specific:
-EBUSY The URB is already active.
-ENODEV specified USB-device or bus doesn't exist
-ENOENT specified interface or endpoint does not exist or
is not enabled
-ENXIO host controller driver does not support queuing of this type
of urb. (treat as a host controller bug.)
-EINVAL a) Invalid transfer type specified (or not supported)
b) Invalid or unsupported periodic transfer interval
c) ISO: attempted to change transfer interval
d) ISO: number_of_packets is < 0
e) various other cases
-EXDEV ISO: URB_ISO_ASAP wasn't specified and all the frames
the URB would be scheduled in have already expired.
-EFBIG Host controller driver can't schedule that many ISO frames.
-EPIPE The pipe type specified in the URB doesn't match the
endpoint's actual type.
-EMSGSIZE (a) endpoint maxpacket size is zero; it is not usable
in the current interface altsetting.
(b) ISO packet is larger than the endpoint maxpacket.
(c) requested data transfer length is invalid: negative
or too large for the host controller.
-ENOSPC This request would overcommit the usb bandwidth reserved
for periodic transfers (interrupt, isochronous).
-ESHUTDOWN The device or host controller has been disabled due to some
problem that could not be worked around.
-EPERM Submission failed because urb->reject was set.
-EHOSTUNREACH URB was rejected because the device is suspended.
-ENOEXEC A control URB doesn't contain a Setup packet.
**************************************************************************
* Error codes returned by in urb->status *
* or in iso_frame_desc[n].status (for ISO) *
**************************************************************************
USB device drivers may only test urb status values in completion handlers.
This is because otherwise there would be a race between HCDs updating
these values on one CPU, and device drivers testing them on another CPU.
A transfer's actual_length may be positive even when an error has been
reported. That's because transfers often involve several packets, so that
one or more packets could finish before an error stops further endpoint I/O.
For isochronous URBs, the urb status value is non-zero only if the URB is
unlinked, the device is removed, the host controller is disabled, or the total
transferred length is less than the requested length and the URB_SHORT_NOT_OK
flag is set. Completion handlers for isochronous URBs should only see
urb->status set to zero, -ENOENT, -ECONNRESET, -ESHUTDOWN, or -EREMOTEIO.
Individual frame descriptor status fields may report more status codes.
0 Transfer completed successfully
-ENOENT URB was synchronously unlinked by usb_unlink_urb
-EINPROGRESS URB still pending, no results yet
(That is, if drivers see this it's a bug.)
-EPROTO (*, **) a) bitstuff error
b) no response packet received within the
prescribed bus turn-around time
c) unknown USB error
-EILSEQ (*, **) a) CRC mismatch
b) no response packet received within the
prescribed bus turn-around time
c) unknown USB error
Note that often the controller hardware does not
distinguish among cases a), b), and c), so a
driver cannot tell whether there was a protocol
error, a failure to respond (often caused by
device disconnect), or some other fault.
-ETIME (**) No response packet received within the prescribed
bus turn-around time. This error may instead be
reported as -EPROTO or -EILSEQ.
-ETIMEDOUT Synchronous USB message functions use this code
to indicate timeout expired before the transfer
completed, and no other error was reported by HC.
-EPIPE (**) Endpoint stalled. For non-control endpoints,
reset this status with usb_clear_halt().
-ECOMM During an IN transfer, the host controller
received data from an endpoint faster than it
could be written to system memory
-ENOSR During an OUT transfer, the host controller
could not retrieve data from system memory fast
enough to keep up with the USB data rate
-EOVERFLOW (*) The amount of data returned by the endpoint was
greater than either the max packet size of the
endpoint or the remaining buffer size. "Babble".
-EREMOTEIO The data read from the endpoint did not fill the
specified buffer, and URB_SHORT_NOT_OK was set in
urb->transfer_flags.
-ENODEV Device was removed. Often preceded by a burst of
other errors, since the hub driver doesn't detect
device removal events immediately.
-EXDEV ISO transfer only partially completed
(only set in iso_frame_desc[n].status, not urb->status)
-EINVAL ISO madness, if this happens: Log off and go home
-ECONNRESET URB was asynchronously unlinked by usb_unlink_urb
-ESHUTDOWN The device or host controller has been disabled due
to some problem that could not be worked around,
such as a physical disconnect.
(*) Error codes like -EPROTO, -EILSEQ and -EOVERFLOW normally indicate
hardware problems such as bad devices (including firmware) or cables.
(**) This is also one of several codes that different kinds of host
controller use to indicate a transfer has failed because of device
disconnect. In the interval before the hub driver starts disconnect
processing, devices may receive such fault reports for every request.
**************************************************************************
* Error codes returned by usbcore-functions *
* (expect also other submit and transfer status codes) *
**************************************************************************
usb_register():
-EINVAL error during registering new driver
usb_get_*/usb_set_*():
usb_control_msg():
usb_bulk_msg():
-ETIMEDOUT Timeout expired before the transfer completed.

View file

@ -0,0 +1,67 @@
*How FunctionFS works*
From kernel point of view it is just a composite function with some
unique behaviour. It may be added to an USB configuration only after
the user space driver has registered by writing descriptors and
strings (the user space program has to provide the same information
that kernel level composite functions provide when they are added to
the configuration).
This in particular means that the composite initialisation functions
may not be in init section (ie. may not use the __init tag).
From user space point of view it is a file system which when
mounted provides an "ep0" file. User space driver need to
write descriptors and strings to that file. It does not need
to worry about endpoints, interfaces or strings numbers but
simply provide descriptors such as if the function was the
only one (endpoints and strings numbers starting from one and
interface numbers starting from zero). The FunctionFS changes
them as needed also handling situation when numbers differ in
different configurations.
When descriptors and strings are written "ep#" files appear
(one for each declared endpoint) which handle communication on
a single endpoint. Again, FunctionFS takes care of the real
numbers and changing of the configuration (which means that
"ep1" file may be really mapped to (say) endpoint 3 (and when
configuration changes to (say) endpoint 2)). "ep0" is used
for receiving events and handling setup requests.
When all files are closed the function disables itself.
What I also want to mention is that the FunctionFS is designed in such
a way that it is possible to mount it several times so in the end
a gadget could use several FunctionFS functions. The idea is that
each FunctionFS instance is identified by the device name used
when mounting.
One can imagine a gadget that has an Ethernet, MTP and HID interfaces
where the last two are implemented via FunctionFS. On user space
level it would look like this:
$ insmod g_ffs.ko idVendor=<ID> iSerialNumber=<string> functions=mtp,hid
$ mkdir /dev/ffs-mtp && mount -t functionfs mtp /dev/ffs-mtp
$ ( cd /dev/ffs-mtp && mtp-daemon ) &
$ mkdir /dev/ffs-hid && mount -t functionfs hid /dev/ffs-hid
$ ( cd /dev/ffs-hid && hid-daemon ) &
On kernel level the gadget checks ffs_data->dev_name to identify
whether it's FunctionFS designed for MTP ("mtp") or HID ("hid").
If no "functions" module parameters is supplied, the driver accepts
just one function with any name.
When "functions" module parameter is supplied, only functions
with listed names are accepted. In particular, if the "functions"
parameter's value is just a one-element list, then the behaviour
is similar to when there is no "functions" at all; however,
only a function with the specified name is accepted.
The gadget is registered only after all the declared function
filesystems have been mounted and USB descriptors of all functions
have been written to their ep0's.
Conversely, the gadget is unregistered after the first USB function
closes its endpoints.

View file

@ -0,0 +1,384 @@
Linux USB gadget configured through configfs
25th April 2013
Overview
========
A USB Linux Gadget is a device which has a UDC (USB Device Controller) and can
be connected to a USB Host to extend it with additional functions like a serial
port or a mass storage capability.
A gadget is seen by its host as a set of configurations, each of which contains
a number of interfaces which, from the gadget's perspective, are known as
functions, each function representing e.g. a serial connection or a SCSI disk.
Linux provides a number of functions for gadgets to use.
Creating a gadget means deciding what configurations there will be
and which functions each configuration will provide.
Configfs (please see Documentation/filesystems/configfs/*) lends itself nicely
for the purpose of telling the kernel about the above mentioned decision.
This document is about how to do it.
It also describes how configfs integration into gadget is designed.
Requirements
============
In order for this to work configfs must be available, so CONFIGFS_FS must be
'y' or 'm' in .config. As of this writing USB_LIBCOMPOSITE selects CONFIGFS_FS.
Usage
=====
(The original post describing the first function
made available through configfs can be seen here:
http://www.spinics.net/lists/linux-usb/msg76388.html)
$ modprobe libcomposite
$ mount none $CONFIGFS_HOME -t configfs
where CONFIGFS_HOME is the mount point for configfs
1. Creating the gadgets
-----------------------
For each gadget to be created its corresponding directory must be created:
$ mkdir $CONFIGFS_HOME/usb_gadget/<gadget name>
e.g.:
$ mkdir $CONFIGFS_HOME/usb_gadget/g1
...
...
...
$ cd $CONFIGFS_HOME/usb_gadget/g1
Each gadget needs to have its vendor id <VID> and product id <PID> specified:
$ echo <VID> > idVendor
$ echo <PID> > idProduct
A gadget also needs its serial number, manufacturer and product strings.
In order to have a place to store them, a strings subdirectory must be created
for each language, e.g.:
$ mkdir strings/0x409
Then the strings can be specified:
$ echo <serial number> > strings/0x409/serialnumber
$ echo <manufacturer> > strings/0x409/manufacturer
$ echo <product> > strings/0x409/product
2. Creating the configurations
------------------------------
Each gadget will consist of a number of configurations, their corresponding
directories must be created:
$ mkdir configs/<name>.<number>
where <name> can be any string which is legal in a filesystem and the
<number> is the configuration's number, e.g.:
$ mkdir configs/c.1
...
...
...
Each configuration also needs its strings, so a subdirectory must be created
for each language, e.g.:
$ mkdir configs/c.1/strings/0x409
Then the configuration string can be specified:
$ echo <configuration> > configs/c.1/strings/0x409/configuration
Some attributes can also be set for a configuration, e.g.:
$ echo 120 > configs/c.1/MaxPower
3. Creating the functions
-------------------------
The gadget will provide some functions, for each function its corresponding
directory must be created:
$ mkdir functions/<name>.<instance name>
where <name> corresponds to one of allowed function names and instance name
is an arbitrary string allowed in a filesystem, e.g.:
$ mkdir functions/ncm.usb0 # usb_f_ncm.ko gets loaded with request_module()
...
...
...
Each function provides its specific set of attributes, with either read-only
or read-write access. Where applicable they need to be written to as
appropriate.
Please refer to Documentation/ABI/*/configfs-usb-gadget* for more information.
4. Associating the functions with their configurations
------------------------------------------------------
At this moment a number of gadgets is created, each of which has a number of
configurations specified and a number of functions available. What remains
is specifying which function is available in which configuration (the same
function can be used in multiple configurations). This is achieved with
creating symbolic links:
$ ln -s functions/<name>.<instance name> configs/<name>.<number>
e.g.:
$ ln -s functions/ncm.usb0 configs/c.1
...
...
...
5. Enabling the gadget
----------------------
All the above steps serve the purpose of composing the gadget of
configurations and functions.
An example directory structure might look like this:
.
./strings
./strings/0x409
./strings/0x409/serialnumber
./strings/0x409/product
./strings/0x409/manufacturer
./configs
./configs/c.1
./configs/c.1/ncm.usb0 -> ../../../../usb_gadget/g1/functions/ncm.usb0
./configs/c.1/strings
./configs/c.1/strings/0x409
./configs/c.1/strings/0x409/configuration
./configs/c.1/bmAttributes
./configs/c.1/MaxPower
./functions
./functions/ncm.usb0
./functions/ncm.usb0/ifname
./functions/ncm.usb0/qmult
./functions/ncm.usb0/host_addr
./functions/ncm.usb0/dev_addr
./UDC
./bcdUSB
./bcdDevice
./idProduct
./idVendor
./bMaxPacketSize0
./bDeviceProtocol
./bDeviceSubClass
./bDeviceClass
Such a gadget must be finally enabled so that the USB host can enumerate it.
In order to enable the gadget it must be bound to a UDC (USB Device Controller).
$ echo <udc name> > UDC
where <udc name> is one of those found in /sys/class/udc/*
e.g.:
$ echo s3c-hsotg > UDC
6. Disabling the gadget
-----------------------
$ echo "" > UDC
7. Cleaning up
--------------
Remove functions from configurations:
$ rm configs/<config name>.<number>/<function>
where <config name>.<number> specify the configuration and <function> is
a symlink to a function being removed from the configuration, e.g.:
$ rm configfs/c.1/ncm.usb0
...
...
...
Remove strings directories in configurations
$ rmdir configs/<config name>.<number>/strings/<lang>
e.g.:
$ rmdir configs/c.1/strings/0x409
...
...
...
and remove the configurations
$ rmdir configs/<config name>.<number>
e.g.:
rmdir configs/c.1
...
...
...
Remove functions (function modules are not unloaded, though)
$ rmdir functions/<name>.<instance name>
e.g.:
$ rmdir functions/ncm.usb0
...
...
...
Remove strings directories in the gadget
$ rmdir strings/<lang>
e.g.:
$ rmdir strings/0x409
and finally remove the gadget:
$ cd ..
$ rmdir <gadget name>
e.g.:
$ rmdir g1
Implementation design
=====================
Below the idea of how configfs works is presented.
In configfs there are items and groups, both represented as directories.
The difference between an item and a group is that a group can contain
other groups. In the picture below only an item is shown.
Both items and groups can have attributes, which are represented as files.
The user can create and remove directories, but cannot remove files,
which can be read-only or read-write, depending on what they represent.
The filesystem part of configfs operates on config_items/groups and
configfs_attributes which are generic and of the same type for all
configured elements. However, they are embedded in usage-specific
larger structures. In the picture below there is a "cs" which contains
a config_item and an "sa" which contains a configfs_attribute.
The filesystem view would be like this:
./
./cs (directory)
|
+--sa (file)
|
.
.
.
Whenever a user reads/writes the "sa" file, a function is called
which accepts a struct config_item and a struct configfs_attribute.
In the said function the "cs" and "sa" are retrieved using the well
known container_of technique and an appropriate sa's function (show or
store) is called and passed the "cs" and a character buffer. The "show"
is for displaying the file's contents (copy data from the cs to the
buffer), while the "store" is for modifying the file's contents (copy data
from the buffer to the cs), but it is up to the implementer of the
two functions to decide what they actually do.
typedef struct configured_structure cs;
typedef struct specific_attribute sa;
sa
+----------------------------------+
cs | (*show)(cs *, buffer); |
+-----------------+ | (*store)(cs *, buffer, length); |
| | | |
| +-------------+ | | +------------------+ |
| | struct |-|----|------>|struct | |
| | config_item | | | |configfs_attribute| |
| +-------------+ | | +------------------+ |
| | +----------------------------------+
| data to be set | .
| | .
+-----------------+ .
The file names are decided by the config item/group designer, while
the directories in general can be named at will. A group can have
a number of its default sub-groups created automatically.
For more information on configfs please see
Documentation/filesystems/configfs/*.
The concepts described above translate to USB gadgets like this:
1. A gadget has its config group, which has some attributes (idVendor,
idProduct etc) and default sub-groups (configs, functions, strings).
Writing to the attributes causes the information to be stored in
appropriate locations. In the configs, functions and strings sub-groups
a user can create their sub-groups to represent configurations, functions,
and groups of strings in a given language.
2. The user creates configurations and functions, in the configurations
creates symbolic links to functions. This information is used when the
gadget's UDC attribute is written to, which means binding the gadget
to the UDC. The code in drivers/usb/gadget/configfs.c iterates over
all configurations, and in each configuration it iterates over all
functions and binds them. This way the whole gadget is bound.
3. The file drivers/usb/gadget/configfs.c contains code for
- gadget's config_group
- gadget's default groups (configs, functions, strings)
- associating functions with configurations (symlinks)
4. Each USB function naturally has its own view of what it wants
configured, so config_groups for particular functions are defined
in the functions implementation files drivers/usb/gadget/f_*.c.
5. Funciton's code is written in such a way that it uses
usb_get_function_instance(), which, in turn, calls request_module.
So, provided that modprobe works, modules for particular functions
are loaded automatically. Please note that the converse is not true:
after a gadget is disabled and torn down, the modules remain loaded.

View file

@ -0,0 +1,445 @@
Linux USB HID gadget driver
Introduction
The HID Gadget driver provides emulation of USB Human Interface
Devices (HID). The basic HID handling is done in the kernel,
and HID reports can be sent/received through I/O on the
/dev/hidgX character devices.
For more details about HID, see the developer page on
http://www.usb.org/developers/hidpage/
Configuration
g_hid is a platform driver, so to use it you need to add
struct platform_device(s) to your platform code defining the
HID function descriptors you want to use - E.G. something
like:
#include <linux/platform_device.h>
#include <linux/usb/g_hid.h>
/* hid descriptor for a keyboard */
static struct hidg_func_descriptor my_hid_data = {
.subclass = 0, /* No subclass */
.protocol = 1, /* Keyboard */
.report_length = 8,
.report_desc_length = 63,
.report_desc = {
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x06, /* USAGE (Keyboard) */
0xa1, 0x01, /* COLLECTION (Application) */
0x05, 0x07, /* USAGE_PAGE (Keyboard) */
0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */
0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x95, 0x08, /* REPORT_COUNT (8) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
0x95, 0x01, /* REPORT_COUNT (1) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x81, 0x03, /* INPUT (Cnst,Var,Abs) */
0x95, 0x05, /* REPORT_COUNT (5) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x05, 0x08, /* USAGE_PAGE (LEDs) */
0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */
0x29, 0x05, /* USAGE_MAXIMUM (Kana) */
0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
0x95, 0x01, /* REPORT_COUNT (1) */
0x75, 0x03, /* REPORT_SIZE (3) */
0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */
0x95, 0x06, /* REPORT_COUNT (6) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x65, /* LOGICAL_MAXIMUM (101) */
0x05, 0x07, /* USAGE_PAGE (Keyboard) */
0x19, 0x00, /* USAGE_MINIMUM (Reserved) */
0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */
0x81, 0x00, /* INPUT (Data,Ary,Abs) */
0xc0 /* END_COLLECTION */
}
};
static struct platform_device my_hid = {
.name = "hidg",
.id = 0,
.num_resources = 0,
.resource = 0,
.dev.platform_data = &my_hid_data,
};
You can add as many HID functions as you want, only limited by
the amount of interrupt endpoints your gadget driver supports.
Send and receive HID reports
HID reports can be sent/received using read/write on the
/dev/hidgX character devices. See below for an example program
to do this.
hid_gadget_test is a small interactive program to test the HID
gadget driver. To use, point it at a hidg device and set the
device type (keyboard / mouse / joystick) - E.G.:
# hid_gadget_test /dev/hidg0 keyboard
You are now in the prompt of hid_gadget_test. You can type any
combination of options and values. Available options and
values are listed at program start. In keyboard mode you can
send up to six values.
For example type: g i s t r --left-shift
Hit return and the corresponding report will be sent by the
HID gadget.
Another interesting example is the caps lock test. Type
--caps-lock and hit return. A report is then sent by the
gadget and you should receive the host answer, corresponding
to the caps lock LED status.
--caps-lock
recv report:2
With this command:
# hid_gadget_test /dev/hidg1 mouse
You can test the mouse emulation. Values are two signed numbers.
Sample code
/* hid_gadget_test */
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUF_LEN 512
struct options {
const char *opt;
unsigned char val;
};
static struct options kmod[] = {
{.opt = "--left-ctrl", .val = 0x01},
{.opt = "--right-ctrl", .val = 0x10},
{.opt = "--left-shift", .val = 0x02},
{.opt = "--right-shift", .val = 0x20},
{.opt = "--left-alt", .val = 0x04},
{.opt = "--right-alt", .val = 0x40},
{.opt = "--left-meta", .val = 0x08},
{.opt = "--right-meta", .val = 0x80},
{.opt = NULL}
};
static struct options kval[] = {
{.opt = "--return", .val = 0x28},
{.opt = "--esc", .val = 0x29},
{.opt = "--bckspc", .val = 0x2a},
{.opt = "--tab", .val = 0x2b},
{.opt = "--spacebar", .val = 0x2c},
{.opt = "--caps-lock", .val = 0x39},
{.opt = "--f1", .val = 0x3a},
{.opt = "--f2", .val = 0x3b},
{.opt = "--f3", .val = 0x3c},
{.opt = "--f4", .val = 0x3d},
{.opt = "--f5", .val = 0x3e},
{.opt = "--f6", .val = 0x3f},
{.opt = "--f7", .val = 0x40},
{.opt = "--f8", .val = 0x41},
{.opt = "--f9", .val = 0x42},
{.opt = "--f10", .val = 0x43},
{.opt = "--f11", .val = 0x44},
{.opt = "--f12", .val = 0x45},
{.opt = "--insert", .val = 0x49},
{.opt = "--home", .val = 0x4a},
{.opt = "--pageup", .val = 0x4b},
{.opt = "--del", .val = 0x4c},
{.opt = "--end", .val = 0x4d},
{.opt = "--pagedown", .val = 0x4e},
{.opt = "--right", .val = 0x4f},
{.opt = "--left", .val = 0x50},
{.opt = "--down", .val = 0x51},
{.opt = "--kp-enter", .val = 0x58},
{.opt = "--up", .val = 0x52},
{.opt = "--num-lock", .val = 0x53},
{.opt = NULL}
};
int keyboard_fill_report(char report[8], char buf[BUF_LEN], int *hold)
{
char *tok = strtok(buf, " ");
int key = 0;
int i = 0;
for (; tok != NULL; tok = strtok(NULL, " ")) {
if (strcmp(tok, "--quit") == 0)
return -1;
if (strcmp(tok, "--hold") == 0) {
*hold = 1;
continue;
}
if (key < 6) {
for (i = 0; kval[i].opt != NULL; i++)
if (strcmp(tok, kval[i].opt) == 0) {
report[2 + key++] = kval[i].val;
break;
}
if (kval[i].opt != NULL)
continue;
}
if (key < 6)
if (islower(tok[0])) {
report[2 + key++] = (tok[0] - ('a' - 0x04));
continue;
}
for (i = 0; kmod[i].opt != NULL; i++)
if (strcmp(tok, kmod[i].opt) == 0) {
report[0] = report[0] | kmod[i].val;
break;
}
if (kmod[i].opt != NULL)
continue;
if (key < 6)
fprintf(stderr, "unknown option: %s\n", tok);
}
return 8;
}
static struct options mmod[] = {
{.opt = "--b1", .val = 0x01},
{.opt = "--b2", .val = 0x02},
{.opt = "--b3", .val = 0x04},
{.opt = NULL}
};
int mouse_fill_report(char report[8], char buf[BUF_LEN], int *hold)
{
char *tok = strtok(buf, " ");
int mvt = 0;
int i = 0;
for (; tok != NULL; tok = strtok(NULL, " ")) {
if (strcmp(tok, "--quit") == 0)
return -1;
if (strcmp(tok, "--hold") == 0) {
*hold = 1;
continue;
}
for (i = 0; mmod[i].opt != NULL; i++)
if (strcmp(tok, mmod[i].opt) == 0) {
report[0] = report[0] | mmod[i].val;
break;
}
if (mmod[i].opt != NULL)
continue;
if (!(tok[0] == '-' && tok[1] == '-') && mvt < 2) {
errno = 0;
report[1 + mvt++] = (char)strtol(tok, NULL, 0);
if (errno != 0) {
fprintf(stderr, "Bad value:'%s'\n", tok);
report[1 + mvt--] = 0;
}
continue;
}
fprintf(stderr, "unknown option: %s\n", tok);
}
return 3;
}
static struct options jmod[] = {
{.opt = "--b1", .val = 0x10},
{.opt = "--b2", .val = 0x20},
{.opt = "--b3", .val = 0x40},
{.opt = "--b4", .val = 0x80},
{.opt = "--hat1", .val = 0x00},
{.opt = "--hat2", .val = 0x01},
{.opt = "--hat3", .val = 0x02},
{.opt = "--hat4", .val = 0x03},
{.opt = "--hatneutral", .val = 0x04},
{.opt = NULL}
};
int joystick_fill_report(char report[8], char buf[BUF_LEN], int *hold)
{
char *tok = strtok(buf, " ");
int mvt = 0;
int i = 0;
*hold = 1;
/* set default hat position: neutral */
report[3] = 0x04;
for (; tok != NULL; tok = strtok(NULL, " ")) {
if (strcmp(tok, "--quit") == 0)
return -1;
for (i = 0; jmod[i].opt != NULL; i++)
if (strcmp(tok, jmod[i].opt) == 0) {
report[3] = (report[3] & 0xF0) | jmod[i].val;
break;
}
if (jmod[i].opt != NULL)
continue;
if (!(tok[0] == '-' && tok[1] == '-') && mvt < 3) {
errno = 0;
report[mvt++] = (char)strtol(tok, NULL, 0);
if (errno != 0) {
fprintf(stderr, "Bad value:'%s'\n", tok);
report[mvt--] = 0;
}
continue;
}
fprintf(stderr, "unknown option: %s\n", tok);
}
return 4;
}
void print_options(char c)
{
int i = 0;
if (c == 'k') {
printf(" keyboard options:\n"
" --hold\n");
for (i = 0; kmod[i].opt != NULL; i++)
printf("\t\t%s\n", kmod[i].opt);
printf("\n keyboard values:\n"
" [a-z] or\n");
for (i = 0; kval[i].opt != NULL; i++)
printf("\t\t%-8s%s", kval[i].opt, i % 2 ? "\n" : "");
printf("\n");
} else if (c == 'm') {
printf(" mouse options:\n"
" --hold\n");
for (i = 0; mmod[i].opt != NULL; i++)
printf("\t\t%s\n", mmod[i].opt);
printf("\n mouse values:\n"
" Two signed numbers\n"
"--quit to close\n");
} else {
printf(" joystick options:\n");
for (i = 0; jmod[i].opt != NULL; i++)
printf("\t\t%s\n", jmod[i].opt);
printf("\n joystick values:\n"
" three signed numbers\n"
"--quit to close\n");
}
}
int main(int argc, const char *argv[])
{
const char *filename = NULL;
int fd = 0;
char buf[BUF_LEN];
int cmd_len;
char report[8];
int to_send = 8;
int hold = 0;
fd_set rfds;
int retval, i;
if (argc < 3) {
fprintf(stderr, "Usage: %s devname mouse|keyboard|joystick\n",
argv[0]);
return 1;
}
if (argv[2][0] != 'k' && argv[2][0] != 'm' && argv[2][0] != 'j')
return 2;
filename = argv[1];
if ((fd = open(filename, O_RDWR, 0666)) == -1) {
perror(filename);
return 3;
}
print_options(argv[2][0]);
while (42) {
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
FD_SET(fd, &rfds);
retval = select(fd + 1, &rfds, NULL, NULL, NULL);
if (retval == -1 && errno == EINTR)
continue;
if (retval < 0) {
perror("select()");
return 4;
}
if (FD_ISSET(fd, &rfds)) {
cmd_len = read(fd, buf, BUF_LEN - 1);
printf("recv report:");
for (i = 0; i < cmd_len; i++)
printf(" %02x", buf[i]);
printf("\n");
}
if (FD_ISSET(STDIN_FILENO, &rfds)) {
memset(report, 0x0, sizeof(report));
cmd_len = read(STDIN_FILENO, buf, BUF_LEN - 1);
if (cmd_len == 0)
break;
buf[cmd_len - 1] = '\0';
hold = 0;
memset(report, 0x0, sizeof(report));
if (argv[2][0] == 'k')
to_send = keyboard_fill_report(report, buf, &hold);
else if (argv[2][0] == 'm')
to_send = mouse_fill_report(report, buf, &hold);
else
to_send = joystick_fill_report(report, buf, &hold);
if (to_send == -1)
break;
if (write(fd, report, to_send) != to_send) {
perror(filename);
return 5;
}
if (!hold) {
memset(report, 0x0, sizeof(report));
if (write(fd, report, to_send) != to_send) {
perror(filename);
return 6;
}
}
}
}
close(fd);
return 0;
}

View file

@ -0,0 +1,150 @@
-*- org -*-
* Overview
The Multifunction Composite Gadget (or g_multi) is a composite gadget
that makes extensive use of the composite framework to provide
a... multifunction gadget.
In it's standard configuration it provides a single USB configuration
with RNDIS[1] (that is Ethernet), USB CDC[2] ACM (that is serial) and
USB Mass Storage functions.
A CDC ECM (Ethernet) function may be turned on via a Kconfig option
and RNDIS can be turned off. If they are both enabled the gadget will
have two configurations -- one with RNDIS and another with CDC ECM[3].
Please note that if you use non-standard configuration (that is enable
CDC ECM) you may need to change vendor and/or product ID.
* Host drivers
To make use of the gadget one needs to make it work on host side --
without that there's no hope of achieving anything with the gadget.
As one might expect, things one need to do very from system to system.
** Linux host drivers
Since the gadget uses standard composite framework and appears as such
to Linux host it does not need any additional drivers on Linux host
side. All the functions are handled by respective drivers developed
for them.
This is also true for two configuration set-up with RNDIS
configuration being the first one. Linux host will use the second
configuration with CDC ECM which should work better under Linux.
** Windows host drivers
For the gadget two work under Windows two conditions have to be met:
*** Detecting as composite gadget
First of all, Windows need to detect the gadget as an USB composite
gadget which on its own have some conditions[4]. If they are met,
Windows lets USB Generic Parent Driver[5] handle the device which then
tries to much drivers for each individual interface (sort of, don't
get into too many details).
The good news is: you do not have to worry about most of the
conditions!
The only thing to worry is that the gadget has to have a single
configuration so a dual RNDIS and CDC ECM gadget won't work unless you
create a proper INF -- and of course, if you do submit it!
*** Installing drivers for each function
The other, trickier thing is making Windows install drivers for each
individual function.
For mass storage it is trivial since Windows detect it's an interface
implementing USB Mass Storage class and selects appropriate driver.
Things are harder with RDNIS and CDC ACM.
**** RNDIS
To make Windows select RNDIS drivers for the first function in the
gadget, one needs to use the [[file:linux.inf]] file provided with this
document. It "attaches" Window's RNDIS driver to the first interface
of the gadget.
Please note, that while testing we encountered some issues[6] when
RNDIS was not the first interface. You do not need to worry abut it
unless you are trying to develop your own gadget in which case watch
out for this bug.
**** CDC ACM
Similarly, [[file:linux-cdc-acm.inf]] is provided for CDC ACM.
**** Customising the gadget
If you intend to hack the g_multi gadget be advised that rearranging
functions will obviously change interface numbers for each of the
functionality. As an effect provided INFs won't work since they have
interface numbers hard-coded in them (it's not hard to change those
though[7]).
This also means, that after experimenting with g_multi and changing
provided functions one should change gadget's vendor and/or product ID
so there will be no collision with other customised gadgets or the
original gadget.
Failing to comply may cause brain damage after wondering for hours why
things don't work as intended before realising Windows have cached
some drivers information (changing USB port may sometimes help plus
you might try using USBDeview[8] to remove the phantom device).
**** INF testing
Provided INF files have been tested on Windows XP SP3, Windows Vista
and Windows 7, all 32-bit versions. It should work on 64-bit versions
as well. It most likely won't work on Windows prior to Windows XP
SP2.
** Other systems
At this moment, drivers for any other systems have not been tested.
Knowing how MacOS is based on BSD and BSD is an Open Source it is
believed that it should (read: "I have no idea whether it will") work
out-of-the-box.
For more exotic systems I have even less to say...
Any testing and drivers *are* *welcome*!
* Authors
This document has been written by Michal Nazarewicz
([[mailto:mina86@mina86.com]]). INF files have been hacked with
support of Marek Szyprowski ([[mailto:m.szyprowski@samsung.com]]) and
Xiaofan Chen ([[mailto:xiaofanc@gmail.com]]) basing on the MS RNDIS
template[9], Microchip's CDC ACM INF file and David Brownell's
([[mailto:dbrownell@users.sourceforge.net]]) original INF files.
* Footnotes
[1] Remote Network Driver Interface Specification,
[[http://msdn.microsoft.com/en-us/library/ee484414.aspx]].
[2] Communications Device Class Abstract Control Model, spec for this
and other USB classes can be found at
[[http://www.usb.org/developers/devclass_docs/]].
[3] CDC Ethernet Control Model.
[4] [[http://msdn.microsoft.com/en-us/library/ff537109(v=VS.85).aspx]]
[5] [[http://msdn.microsoft.com/en-us/library/ff539234(v=VS.85).aspx]]
[6] To put it in some other nice words, Windows failed to respond to
any user input.
[7] You may find [[http://www.cygnal.org/ubb/Forum9/HTML/001050.html]]
useful.
[8] http://www.nirsoft.net/utils/usb_devices_view.html
[9] [[http://msdn.microsoft.com/en-us/library/ff570620.aspx]]

View file

@ -0,0 +1,510 @@
Linux USB Printer Gadget Driver
06/04/2007
Copyright (C) 2007 Craig W. Nadler <craig@nadler.us>
GENERAL
=======
This driver may be used if you are writing printer firmware using Linux as
the embedded OS. This driver has nothing to do with using a printer with
your Linux host system.
You will need a USB device controller and a Linux driver for it that accepts
a gadget / "device class" driver using the Linux USB Gadget API. After the
USB device controller driver is loaded then load the printer gadget driver.
This will present a printer interface to the USB Host that your USB Device
port is connected to.
This driver is structured for printer firmware that runs in user mode. The
user mode printer firmware will read and write data from the kernel mode
printer gadget driver using a device file. The printer returns a printer status
byte when the USB HOST sends a device request to get the printer status. The
user space firmware can read or write this status byte using a device file
/dev/g_printer . Both blocking and non-blocking read/write calls are supported.
HOWTO USE THIS DRIVER
=====================
To load the USB device controller driver and the printer gadget driver. The
following example uses the Netchip 2280 USB device controller driver:
modprobe net2280
modprobe g_printer
The follow command line parameter can be used when loading the printer gadget
(ex: modprobe g_printer idVendor=0x0525 idProduct=0xa4a8 ):
idVendor - This is the Vendor ID used in the device descriptor. The default is
the Netchip vendor id 0x0525. YOU MUST CHANGE TO YOUR OWN VENDOR ID
BEFORE RELEASING A PRODUCT. If you plan to release a product and don't
already have a Vendor ID please see www.usb.org for details on how to
get one.
idProduct - This is the Product ID used in the device descriptor. The default
is 0xa4a8, you should change this to an ID that's not used by any of
your other USB products if you have any. It would be a good idea to
start numbering your products starting with say 0x0001.
bcdDevice - This is the version number of your product. It would be a good idea
to put your firmware version here.
iManufacturer - A string containing the name of the Vendor.
iProduct - A string containing the Product Name.
iSerialNum - A string containing the Serial Number. This should be changed for
each unit of your product.
iPNPstring - The PNP ID string used for this printer. You will want to set
either on the command line or hard code the PNP ID string used for
your printer product.
qlen - The number of 8k buffers to use per endpoint. The default is 10, you
should tune this for your product. You may also want to tune the
size of each buffer for your product.
USING THE EXAMPLE CODE
======================
This example code talks to stdout, instead of a print engine.
To compile the test code below:
1) save it to a file called prn_example.c
2) compile the code with the follow command:
gcc prn_example.c -o prn_example
To read printer data from the host to stdout:
# prn_example -read_data
To write printer data from a file (data_file) to the host:
# cat data_file | prn_example -write_data
To get the current printer status for the gadget driver:
# prn_example -get_status
Printer status is:
Printer is NOT Selected
Paper is Out
Printer OK
To set printer to Selected/On-line:
# prn_example -selected
To set printer to Not Selected/Off-line:
# prn_example -not_selected
To set paper status to paper out:
# prn_example -paper_out
To set paper status to paper loaded:
# prn_example -paper_loaded
To set error status to printer OK:
# prn_example -no_error
To set error status to ERROR:
# prn_example -error
EXAMPLE CODE
============
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/poll.h>
#include <sys/ioctl.h>
#include <linux/usb/g_printer.h>
#define PRINTER_FILE "/dev/g_printer"
#define BUF_SIZE 512
/*
* 'usage()' - Show program usage.
*/
static void
usage(const char *option) /* I - Option string or NULL */
{
if (option) {
fprintf(stderr,"prn_example: Unknown option \"%s\"!\n",
option);
}
fputs("\n", stderr);
fputs("Usage: prn_example -[options]\n", stderr);
fputs("Options:\n", stderr);
fputs("\n", stderr);
fputs("-get_status Get the current printer status.\n", stderr);
fputs("-selected Set the selected status to selected.\n", stderr);
fputs("-not_selected Set the selected status to NOT selected.\n",
stderr);
fputs("-error Set the error status to error.\n", stderr);
fputs("-no_error Set the error status to NO error.\n", stderr);
fputs("-paper_out Set the paper status to paper out.\n", stderr);
fputs("-paper_loaded Set the paper status to paper loaded.\n",
stderr);
fputs("-read_data Read printer data from driver.\n", stderr);
fputs("-write_data Write printer sata to driver.\n", stderr);
fputs("-NB_read_data (Non-Blocking) Read printer data from driver.\n",
stderr);
fputs("\n\n", stderr);
exit(1);
}
static int
read_printer_data()
{
struct pollfd fd[1];
/* Open device file for printer gadget. */
fd[0].fd = open(PRINTER_FILE, O_RDWR);
if (fd[0].fd < 0) {
printf("Error %d opening %s\n", fd[0].fd, PRINTER_FILE);
close(fd[0].fd);
return(-1);
}
fd[0].events = POLLIN | POLLRDNORM;
while (1) {
static char buf[BUF_SIZE];
int bytes_read;
int retval;
/* Wait for up to 1 second for data. */
retval = poll(fd, 1, 1000);
if (retval && (fd[0].revents & POLLRDNORM)) {
/* Read data from printer gadget driver. */
bytes_read = read(fd[0].fd, buf, BUF_SIZE);
if (bytes_read < 0) {
printf("Error %d reading from %s\n",
fd[0].fd, PRINTER_FILE);
close(fd[0].fd);
return(-1);
} else if (bytes_read > 0) {
/* Write data to standard OUTPUT (stdout). */
fwrite(buf, 1, bytes_read, stdout);
fflush(stdout);
}
}
}
/* Close the device file. */
close(fd[0].fd);
return 0;
}
static int
write_printer_data()
{
struct pollfd fd[1];
/* Open device file for printer gadget. */
fd[0].fd = open (PRINTER_FILE, O_RDWR);
if (fd[0].fd < 0) {
printf("Error %d opening %s\n", fd[0].fd, PRINTER_FILE);
close(fd[0].fd);
return(-1);
}
fd[0].events = POLLOUT | POLLWRNORM;
while (1) {
int retval;
static char buf[BUF_SIZE];
/* Read data from standard INPUT (stdin). */
int bytes_read = fread(buf, 1, BUF_SIZE, stdin);
if (!bytes_read) {
break;
}
while (bytes_read) {
/* Wait for up to 1 second to sent data. */
retval = poll(fd, 1, 1000);
/* Write data to printer gadget driver. */
if (retval && (fd[0].revents & POLLWRNORM)) {
retval = write(fd[0].fd, buf, bytes_read);
if (retval < 0) {
printf("Error %d writing to %s\n",
fd[0].fd,
PRINTER_FILE);
close(fd[0].fd);
return(-1);
} else {
bytes_read -= retval;
}
}
}
}
/* Wait until the data has been sent. */
fsync(fd[0].fd);
/* Close the device file. */
close(fd[0].fd);
return 0;
}
static int
read_NB_printer_data()
{
int fd;
static char buf[BUF_SIZE];
int bytes_read;
/* Open device file for printer gadget. */
fd = open(PRINTER_FILE, O_RDWR|O_NONBLOCK);
if (fd < 0) {
printf("Error %d opening %s\n", fd, PRINTER_FILE);
close(fd);
return(-1);
}
while (1) {
/* Read data from printer gadget driver. */
bytes_read = read(fd, buf, BUF_SIZE);
if (bytes_read <= 0) {
break;
}
/* Write data to standard OUTPUT (stdout). */
fwrite(buf, 1, bytes_read, stdout);
fflush(stdout);
}
/* Close the device file. */
close(fd);
return 0;
}
static int
get_printer_status()
{
int retval;
int fd;
/* Open device file for printer gadget. */
fd = open(PRINTER_FILE, O_RDWR);
if (fd < 0) {
printf("Error %d opening %s\n", fd, PRINTER_FILE);
close(fd);
return(-1);
}
/* Make the IOCTL call. */
retval = ioctl(fd, GADGET_GET_PRINTER_STATUS);
if (retval < 0) {
fprintf(stderr, "ERROR: Failed to set printer status\n");
return(-1);
}
/* Close the device file. */
close(fd);
return(retval);
}
static int
set_printer_status(unsigned char buf, int clear_printer_status_bit)
{
int retval;
int fd;
retval = get_printer_status();
if (retval < 0) {
fprintf(stderr, "ERROR: Failed to get printer status\n");
return(-1);
}
/* Open device file for printer gadget. */
fd = open(PRINTER_FILE, O_RDWR);
if (fd < 0) {
printf("Error %d opening %s\n", fd, PRINTER_FILE);
close(fd);
return(-1);
}
if (clear_printer_status_bit) {
retval &= ~buf;
} else {
retval |= buf;
}
/* Make the IOCTL call. */
if (ioctl(fd, GADGET_SET_PRINTER_STATUS, (unsigned char)retval)) {
fprintf(stderr, "ERROR: Failed to set printer status\n");
return(-1);
}
/* Close the device file. */
close(fd);
return 0;
}
static int
display_printer_status()
{
char printer_status;
printer_status = get_printer_status();
if (printer_status < 0) {
fprintf(stderr, "ERROR: Failed to get printer status\n");
return(-1);
}
printf("Printer status is:\n");
if (printer_status & PRINTER_SELECTED) {
printf(" Printer is Selected\n");
} else {
printf(" Printer is NOT Selected\n");
}
if (printer_status & PRINTER_PAPER_EMPTY) {
printf(" Paper is Out\n");
} else {
printf(" Paper is Loaded\n");
}
if (printer_status & PRINTER_NOT_ERROR) {
printf(" Printer OK\n");
} else {
printf(" Printer ERROR\n");
}
return(0);
}
int
main(int argc, char *argv[])
{
int i; /* Looping var */
int retval = 0;
/* No Args */
if (argc == 1) {
usage(0);
exit(0);
}
for (i = 1; i < argc && !retval; i ++) {
if (argv[i][0] != '-') {
continue;
}
if (!strcmp(argv[i], "-get_status")) {
if (display_printer_status()) {
retval = 1;
}
} else if (!strcmp(argv[i], "-paper_loaded")) {
if (set_printer_status(PRINTER_PAPER_EMPTY, 1)) {
retval = 1;
}
} else if (!strcmp(argv[i], "-paper_out")) {
if (set_printer_status(PRINTER_PAPER_EMPTY, 0)) {
retval = 1;
}
} else if (!strcmp(argv[i], "-selected")) {
if (set_printer_status(PRINTER_SELECTED, 0)) {
retval = 1;
}
} else if (!strcmp(argv[i], "-not_selected")) {
if (set_printer_status(PRINTER_SELECTED, 1)) {
retval = 1;
}
} else if (!strcmp(argv[i], "-error")) {
if (set_printer_status(PRINTER_NOT_ERROR, 1)) {
retval = 1;
}
} else if (!strcmp(argv[i], "-no_error")) {
if (set_printer_status(PRINTER_NOT_ERROR, 0)) {
retval = 1;
}
} else if (!strcmp(argv[i], "-read_data")) {
if (read_printer_data()) {
retval = 1;
}
} else if (!strcmp(argv[i], "-write_data")) {
if (write_printer_data()) {
retval = 1;
}
} else if (!strcmp(argv[i], "-NB_read_data")) {
if (read_NB_printer_data()) {
retval = 1;
}
} else {
usage(argv[i]);
retval = 1;
}
}
exit(retval);
}

View file

@ -0,0 +1,282 @@
Linux Gadget Serial Driver v2.0
11/20/2004
(updated 8-May-2008 for v2.3)
License and Disclaimer
----------------------
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA.
This document and the gadget serial driver itself are
Copyright (C) 2004 by Al Borchers (alborchers@steinerpoint.com).
If you have questions, problems, or suggestions for this driver
please contact Al Borchers at alborchers@steinerpoint.com.
Prerequisites
-------------
Versions of the gadget serial driver are available for the
2.4 Linux kernels, but this document assumes you are using
version 2.3 or later of the gadget serial driver in a 2.6
Linux kernel.
This document assumes that you are familiar with Linux and
Windows and know how to configure and build Linux kernels, run
standard utilities, use minicom and HyperTerminal, and work with
USB and serial devices. It also assumes you configure the Linux
gadget and usb drivers as modules.
With version 2.3 of the driver, major and minor device nodes are
no longer statically defined. Your Linux based system should mount
sysfs in /sys, and use "mdev" (in Busybox) or "udev" to make the
/dev nodes matching the sysfs /sys/class/tty files.
Overview
--------
The gadget serial driver is a Linux USB gadget driver, a USB device
side driver. It runs on a Linux system that has USB device side
hardware; for example, a PDA, an embedded Linux system, or a PC
with a USB development card.
The gadget serial driver talks over USB to either a CDC ACM driver
or a generic USB serial driver running on a host PC.
Host
--------------------------------------
| Host-Side CDC ACM USB Host |
| Operating | or | Controller | USB
| System | Generic USB | Driver |--------
| (Linux or | Serial | and | |
| Windows) Driver USB Stack | |
-------------------------------------- |
|
|
|
Gadget |
-------------------------------------- |
| Gadget USB Periph. | |
| Device-Side | Gadget | Controller | |
| Linux | Serial | Driver |--------
| Operating | Driver | and |
| System USB Stack |
--------------------------------------
On the device-side Linux system, the gadget serial driver looks
like a serial device.
On the host-side system, the gadget serial device looks like a
CDC ACM compliant class device or a simple vendor specific device
with bulk in and bulk out endpoints, and it is treated similarly
to other serial devices.
The host side driver can potentially be any ACM compliant driver
or any driver that can talk to a device with a simple bulk in/out
interface. Gadget serial has been tested with the Linux ACM driver,
the Windows usbser.sys ACM driver, and the Linux USB generic serial
driver.
With the gadget serial driver and the host side ACM or generic
serial driver running, you should be able to communicate between
the host and the gadget side systems as if they were connected by a
serial cable.
The gadget serial driver only provides simple unreliable data
communication. It does not yet handle flow control or many other
features of normal serial devices.
Installing the Gadget Serial Driver
-----------------------------------
To use the gadget serial driver you must configure the Linux gadget
side kernel for "Support for USB Gadgets", for a "USB Peripheral
Controller" (for example, net2280), and for the "Serial Gadget"
driver. All this are listed under "USB Gadget Support" when
configuring the kernel. Then rebuild and install the kernel or
modules.
Then you must load the gadget serial driver. To load it as an
ACM device (recommended for interoperability), do this:
modprobe g_serial
To load it as a vendor specific bulk in/out device, do this:
modprobe g_serial use_acm=0
This will also automatically load the underlying gadget peripheral
controller driver. This must be done each time you reboot the gadget
side Linux system. You can add this to the start up scripts, if
desired.
Your system should use mdev (from busybox) or udev to make the
device nodes. After this gadget driver has been set up you should
then see a /dev/ttyGS0 node:
# ls -l /dev/ttyGS0 | cat
crw-rw---- 1 root root 253, 0 May 8 14:10 /dev/ttyGS0
#
Note that the major number (253, above) is system-specific. If
you need to create /dev nodes by hand, the right numbers to use
will be in the /sys/class/tty/ttyGS0/dev file.
When you link this gadget driver early, perhaps even statically,
you may want to set up an /etc/inittab entry to run "getty" on it.
The /dev/ttyGS0 line should work like most any other serial port.
If gadget serial is loaded as an ACM device you will want to use
either the Windows or Linux ACM driver on the host side. If gadget
serial is loaded as a bulk in/out device, you will want to use the
Linux generic serial driver on the host side. Follow the appropriate
instructions below to install the host side driver.
Installing the Windows Host ACM Driver
--------------------------------------
To use the Windows ACM driver you must have the "linux-cdc-acm.inf"
file (provided along this document) which supports all recent versions
of Windows.
When the gadget serial driver is loaded and the USB device connected
to the Windows host with a USB cable, Windows should recognize the
gadget serial device and ask for a driver. Tell Windows to find the
driver in the folder that contains the "linux-cdc-acm.inf" file.
For example, on Windows XP, when the gadget serial device is first
plugged in, the "Found New Hardware Wizard" starts up. Select
"Install from a list or specific location (Advanced)", then on the
next screen select "Include this location in the search" and enter the
path or browse to the folder containing the "linux-cdc-acm.inf" file.
Windows will complain that the Gadget Serial driver has not passed
Windows Logo testing, but select "Continue anyway" and finish the
driver installation.
On Windows XP, in the "Device Manager" (under "Control Panel",
"System", "Hardware") expand the "Ports (COM & LPT)" entry and you
should see "Gadget Serial" listed as the driver for one of the COM
ports.
To uninstall the Windows XP driver for "Gadget Serial", right click
on the "Gadget Serial" entry in the "Device Manager" and select
"Uninstall".
Installing the Linux Host ACM Driver
------------------------------------
To use the Linux ACM driver you must configure the Linux host side
kernel for "Support for Host-side USB" and for "USB Modem (CDC ACM)
support".
Once the gadget serial driver is loaded and the USB device connected
to the Linux host with a USB cable, the host system should recognize
the gadget serial device. For example, the command
cat /proc/bus/usb/devices
should show something like this:
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 5 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=02(comm.) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=0525 ProdID=a4a7 Rev= 2.01
S: Manufacturer=Linux 2.6.8.1 with net2280
S: Product=Gadget Serial
S: SerialNumber=0
C:* #Ifs= 2 Cfg#= 2 Atr=c0 MxPwr= 2mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=acm
E: Ad=83(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=acm
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
If the host side Linux system is configured properly, the ACM driver
should be loaded automatically. The command "lsmod" should show the
"acm" module is loaded.
Installing the Linux Host Generic USB Serial Driver
---------------------------------------------------
To use the Linux generic USB serial driver you must configure the
Linux host side kernel for "Support for Host-side USB", for "USB
Serial Converter support", and for the "USB Generic Serial Driver".
Once the gadget serial driver is loaded and the USB device connected
to the Linux host with a USB cable, the host system should recognize
the gadget serial device. For example, the command
cat /proc/bus/usb/devices
should show something like this:
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 6 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=ff(vend.) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=0525 ProdID=a4a6 Rev= 2.01
S: Manufacturer=Linux 2.6.8.1 with net2280
S: Product=Gadget Serial
S: SerialNumber=0
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 2mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=serial
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
You must explicitly load the usbserial driver with parameters to
configure it to recognize the gadget serial device, like this:
modprobe usbserial vendor=0x0525 product=0xA4A6
If everything is working, usbserial will print a message in the
system log saying something like "Gadget Serial converter now
attached to ttyUSB0".
Testing with Minicom or HyperTerminal
-------------------------------------
Once the gadget serial driver and the host driver are both installed,
and a USB cable connects the gadget device to the host, you should
be able to communicate over USB between the gadget and host systems.
You can use minicom or HyperTerminal to try this out.
On the gadget side run "minicom -s" to configure a new minicom
session. Under "Serial port setup" set "/dev/ttygserial" as the
"Serial Device". Set baud rate, data bits, parity, and stop bits,
to 9600, 8, none, and 1--these settings mostly do not matter.
Under "Modem and dialing" erase all the modem and dialing strings.
On a Linux host running the ACM driver, configure minicom similarly
but use "/dev/ttyACM0" as the "Serial Device". (If you have other
ACM devices connected, change the device name appropriately.)
On a Linux host running the USB generic serial driver, configure
minicom similarly, but use "/dev/ttyUSB0" as the "Serial Device".
(If you have other USB serial devices connected, change the device
name appropriately.)
On a Windows host configure a new HyperTerminal session to use the
COM port assigned to Gadget Serial. The "Port Settings" will be
set automatically when HyperTerminal connects to the gadget serial
device, so you can leave them set to the default values--these
settings mostly do not matter.
With minicom configured and running on the gadget side and with
minicom or HyperTerminal configured and running on the host side,
you should be able to send data back and forth between the gadget
side and host side systems. Anything you type on the terminal
window on the gadget side should appear in the terminal window on
the host side and vice versa.

View file

@ -0,0 +1,148 @@
LINUX HOTPLUGGING
In hotpluggable busses like USB (and Cardbus PCI), end-users plug devices
into the bus with power on. In most cases, users expect the devices to become
immediately usable. That means the system must do many things, including:
- Find a driver that can handle the device. That may involve
loading a kernel module; newer drivers can use module-init-tools
to publish their device (and class) support to user utilities.
- Bind a driver to that device. Bus frameworks do that using a
device driver's probe() routine.
- Tell other subsystems to configure the new device. Print
queues may need to be enabled, networks brought up, disk
partitions mounted, and so on. In some cases these will
be driver-specific actions.
This involves a mix of kernel mode and user mode actions. Making devices
be immediately usable means that any user mode actions can't wait for an
administrator to do them: the kernel must trigger them, either passively
(triggering some monitoring daemon to invoke a helper program) or
actively (calling such a user mode helper program directly).
Those triggered actions must support a system's administrative policies;
such programs are called "policy agents" here. Typically they involve
shell scripts that dispatch to more familiar administration tools.
Because some of those actions rely on information about drivers (metadata)
that is currently available only when the drivers are dynamically linked,
you get the best hotplugging when you configure a highly modular system.
KERNEL HOTPLUG HELPER (/sbin/hotplug)
There is a kernel parameter: /proc/sys/kernel/hotplug, which normally
holds the pathname "/sbin/hotplug". That parameter names a program
which the kernel may invoke at various times.
The /sbin/hotplug program can be invoked by any subsystem as part of its
reaction to a configuration change, from a thread in that subsystem.
Only one parameter is required: the name of a subsystem being notified of
some kernel event. That name is used as the first key for further event
dispatch; any other argument and environment parameters are specified by
the subsystem making that invocation.
Hotplug software and other resources is available at:
http://linux-hotplug.sourceforge.net
Mailing list information is also available at that site.
--------------------------------------------------------------------------
USB POLICY AGENT
The USB subsystem currently invokes /sbin/hotplug when USB devices
are added or removed from system. The invocation is done by the kernel
hub workqueue [hub_wq], or else as part of root hub initialization
(done by init, modprobe, kapmd, etc). Its single command line parameter
is the string "usb", and it passes these environment variables:
ACTION ... "add", "remove"
PRODUCT ... USB vendor, product, and version codes (hex)
TYPE ... device class codes (decimal)
INTERFACE ... interface 0 class codes (decimal)
If "usbdevfs" is configured, DEVICE and DEVFS are also passed. DEVICE is
the pathname of the device, and is useful for devices with multiple and/or
alternate interfaces that complicate driver selection. By design, USB
hotplugging is independent of "usbdevfs": you can do most essential parts
of USB device setup without using that filesystem, and without running a
user mode daemon to detect changes in system configuration.
Currently available policy agent implementations can load drivers for
modules, and can invoke driver-specific setup scripts. The newest ones
leverage USB module-init-tools support. Later agents might unload drivers.
USB MODUTILS SUPPORT
Current versions of module-init-tools will create a "modules.usbmap" file
which contains the entries from each driver's MODULE_DEVICE_TABLE. Such
files can be used by various user mode policy agents to make sure all the
right driver modules get loaded, either at boot time or later.
See <linux/usb.h> for full information about such table entries; or look
at existing drivers. Each table entry describes one or more criteria to
be used when matching a driver to a device or class of devices. The
specific criteria are identified by bits set in "match_flags", paired
with field values. You can construct the criteria directly, or with
macros such as these, and use driver_info to store more information.
USB_DEVICE (vendorId, productId)
... matching devices with specified vendor and product ids
USB_DEVICE_VER (vendorId, productId, lo, hi)
... like USB_DEVICE with lo <= productversion <= hi
USB_INTERFACE_INFO (class, subclass, protocol)
... matching specified interface class info
USB_DEVICE_INFO (class, subclass, protocol)
... matching specified device class info
A short example, for a driver that supports several specific USB devices
and their quirks, might have a MODULE_DEVICE_TABLE like this:
static const struct usb_device_id mydriver_id_table[] = {
{ USB_DEVICE (0x9999, 0xaaaa), driver_info: QUIRK_X },
{ USB_DEVICE (0xbbbb, 0x8888), driver_info: QUIRK_Y|QUIRK_Z },
...
{ } /* end with an all-zeroes entry */
};
MODULE_DEVICE_TABLE(usb, mydriver_id_table);
Most USB device drivers should pass these tables to the USB subsystem as
well as to the module management subsystem. Not all, though: some driver
frameworks connect using interfaces layered over USB, and so they won't
need such a "struct usb_driver".
Drivers that connect directly to the USB subsystem should be declared
something like this:
static struct usb_driver mydriver = {
.name = "mydriver",
.id_table = mydriver_id_table,
.probe = my_probe,
.disconnect = my_disconnect,
/*
if using the usb chardev framework:
.minor = MY_USB_MINOR_START,
.fops = my_file_ops,
if exposing any operations through usbdevfs:
.ioctl = my_ioctl,
*/
};
When the USB subsystem knows about a driver's device ID table, it's used when
choosing drivers to probe(). The thread doing new device processing checks
drivers' device ID entries from the MODULE_DEVICE_TABLE against interface and
device descriptors for the device. It will only call probe() if there is a
match, and the third argument to probe() will be the entry that matched.
If you don't provide an id_table for your driver, then your driver may get
probed for each new device; the third parameter to probe() will be null.

View file

@ -0,0 +1,84 @@
Infinity Usb Unlimited Readme
-----------------------------
Hi all,
This module provide a serial interface to use your
IUU unit in phoenix mode. Loading this module will
bring a ttyUSB[0-x] interface. This driver must be
used by your favorite application to pilot the IUU
This driver is still in beta stage, so bugs can
occur and your system may freeze. As far I now,
I never had any problem with it, but I'm not a real
guru, so don't blame me if your system is unstable
You can plug more than one IUU. Every unit will
have his own device file(/dev/ttyUSB0,/dev/ttyUSB1,...)
How to tune the reader speed ?
A few parameters can be used at load time
To use parameters, just unload the module if it is
already loaded and use modprobe iuu_phoenix param=value.
In case of prebuilt module, use the command
insmod iuu_phoenix param=value.
Example:
modprobe iuu_phoenix clockmode=3
The parameters are:
parm: clockmode:1=3Mhz579,2=3Mhz680,3=6Mhz (int)
parm: boost:overclock boost percent 100 to 500 (int)
parm: cdmode:Card detect mode 0=none, 1=CD, 2=!CD, 3=DSR, 4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING (int)
parm: xmas:xmas color enabled or not (bool)
parm: debug:Debug enabled or not (bool)
- clockmode will provide 3 different base settings commonly adopted by
different software:
1. 3Mhz579
2. 3Mhz680
3. 6Mhz
- boost provide a way to overclock the reader ( my favorite :-) )
For example to have best performance than a simple clockmode=3, try this:
modprobe boost=195
This will put the reader in a base of 3Mhz579 but boosted a 195 % !
the real clock will be now : 6979050 Hz ( 6Mhz979 ) and will increase
the speed to a score 10 to 20% better than the simple clockmode=3 !!!
- cdmode permit to setup the signal used to inform the userland ( ioctl answer )
if the card is present or not. Eight signals are possible.
- xmas is completely useless except for your eyes. This is one of my friend who was
so sad to have a nice device like the iuu without seeing all color range available.
So I have added this option to permit him to see a lot of color ( each activity change the color
and the frequency randomly )
- debug will produce a lot of debugging messages...
Last notes:
Don't worry about the serial settings, the serial emulation
is an abstraction, so use any speed or parity setting will
work. ( This will not change anything ).Later I will perhaps
use this settings to deduce de boost but is that feature
really necessary ?
The autodetect feature used is the serial CD. If that doesn't
work for your software, disable detection mechanism in it.
Have fun !
Alain Degreffe
eczema(at)ecze.com

View file

@ -0,0 +1,107 @@
; Windows USB CDC ACM Setup File
; Based on INF template which was:
; Copyright (c) 2000 Microsoft Corporation
; Copyright (c) 2007 Microchip Technology Inc.
; likely to be covered by the MLPL as found at:
; <http://msdn.microsoft.com/en-us/cc300389.aspx#MLPL>.
; For use only on Windows operating systems.
[Version]
Signature="$Windows NT$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%Linux%
DriverVer=11/15/2007,5.1.2600.0
[Manufacturer]
%Linux%=DeviceList, NTamd64
[DestinationDirs]
DefaultDestDir=12
;------------------------------------------------------------------------------
; Windows 2000/XP/Vista-32bit Sections
;------------------------------------------------------------------------------
[DriverInstall.nt]
include=mdmcpq.inf
CopyFiles=DriverCopyFiles.nt
AddReg=DriverInstall.nt.AddReg
[DriverCopyFiles.nt]
usbser.sys,,,0x20
[DriverInstall.nt.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,USBSER.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.nt.Services]
AddService=usbser, 0x00000002, DriverService.nt
[DriverService.nt]
DisplayName=%SERVICE%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\USBSER.sys
;------------------------------------------------------------------------------
; Vista-64bit Sections
;------------------------------------------------------------------------------
[DriverInstall.NTamd64]
include=mdmcpq.inf
CopyFiles=DriverCopyFiles.NTamd64
AddReg=DriverInstall.NTamd64.AddReg
[DriverCopyFiles.NTamd64]
USBSER.sys,,,0x20
[DriverInstall.NTamd64.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,USBSER.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.NTamd64.Services]
AddService=usbser, 0x00000002, DriverService.NTamd64
[DriverService.NTamd64]
DisplayName=%SERVICE%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\USBSER.sys
;------------------------------------------------------------------------------
; Vendor and Product ID Definitions
;------------------------------------------------------------------------------
; When developing your USB device, the VID and PID used in the PC side
; application program and the firmware on the microcontroller must match.
; Modify the below line to use your VID and PID. Use the format as shown
; below.
; Note: One INF file can be used for multiple devices with different
; VID and PIDs. For each supported device, append
; ",USB\VID_xxxx&PID_yyyy" to the end of the line.
;------------------------------------------------------------------------------
[SourceDisksFiles]
[SourceDisksNames]
[DeviceList]
%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02, USB\VID_1D6B&PID_0106&MI_00
[DeviceList.NTamd64]
%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02, USB\VID_1D6B&PID_0106&MI_00
;------------------------------------------------------------------------------
; String Definitions
;------------------------------------------------------------------------------
;Modify these strings to customize your device
;------------------------------------------------------------------------------
[Strings]
Linux = "Linux Developer Community"
DESCRIPTION = "Gadget Serial"
SERVICE = "USB RS-232 Emulation Driver"

View file

@ -0,0 +1,66 @@
; Based on template INF file found at
; <http://msdn.microsoft.com/en-us/library/ff570620.aspx>
; which was:
; Copyright (c) Microsoft Corporation
; and released under the MLPL as found at:
; <http://msdn.microsoft.com/en-us/cc300389.aspx#MLPL>.
; For use only on Windows operating systems.
[Version]
Signature = "$Windows NT$"
Class = Net
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
Provider = %Linux%
DriverVer = 06/21/2006,6.0.6000.16384
[Manufacturer]
%Linux% = LinuxDevices,NTx86,NTamd64,NTia64
; Decoration for x86 architecture
[LinuxDevices.NTx86]
%LinuxDevice% = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_1d6b&PID_0104&MI_00
; Decoration for x64 architecture
[LinuxDevices.NTamd64]
%LinuxDevice% = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_1d6b&PID_0104&MI_00
; Decoration for ia64 architecture
[LinuxDevices.NTia64]
%LinuxDevice% = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_1d6b&PID_0104&MI_00
;@@@ This is the common setting for setup
[ControlFlags]
ExcludeFromSelect=*
; DDInstall section
; References the in-build Netrndis.inf
[RNDIS.NT.5.1]
Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI
BusType = 15
; NEVER REMOVE THE FOLLOWING REFERENCE FOR NETRNDIS.INF
include = netrndis.inf
needs = Usb_Rndis.ndi
AddReg = Rndis_AddReg_Vista
; DDInstal.Services section
[RNDIS.NT.5.1.Services]
include = netrndis.inf
needs = Usb_Rndis.ndi.Services
; Optional registry settings. You can modify as needed.
[RNDIS_AddReg_Vista]
HKR, NDI\params\VistaProperty, ParamDesc, 0, %Vista_Property%
HKR, NDI\params\VistaProperty, type, 0, "edit"
HKR, NDI\params\VistaProperty, LimitText, 0, "12"
HKR, NDI\params\VistaProperty, UpperCase, 0, "1"
HKR, NDI\params\VistaProperty, default, 0, " "
HKR, NDI\params\VistaProperty, optional, 0, "1"
; No sys copyfiles - the sys files are already in-build
; (part of the operating system).
; We do not support XP SP1-, 2003 SP1-, ME, 9x.
[Strings]
Linux = "Linux Developer Community"
LinuxDevice = "Linux USB Ethernet/RNDIS Gadget"
Vista_Property = "Optional Vista Property"

View file

@ -0,0 +1,225 @@
* Overview
Mass Storage Gadget (or MSG) acts as a USB Mass Storage device,
appearing to the host as a disk or a CD-ROM drive. It supports
multiple logical units (LUNs). Backing storage for each LUN is
provided by a regular file or a block device, access can be limited
to read-only, and gadget can indicate that it is removable and/or
CD-ROM (the latter implies read-only access).
Its requirements are modest; only a bulk-in and a bulk-out endpoint
are needed. The memory requirement amounts to two 16K buffers.
Support is included for full-speed, high-speed and SuperSpeed
operation.
Note that the driver is slightly non-portable in that it assumes
a single memory/DMA buffer will be usable for bulk-in and bulk-out
endpoints. With most device controllers this is not an issue, but
there may be some with hardware restrictions that prevent a buffer
from being used by more than one endpoint.
This document describes how to use the gadget from user space, its
relation to mass storage function (or MSF) and different gadgets
using it, and how it differs from File Storage Gadget (or FSG)
(which is no longer included in Linux). It will talk only briefly
about how to use MSF within composite gadgets.
* Module parameters
The mass storage gadget accepts the following mass storage specific
module parameters:
- file=filename[,filename...]
This parameter lists paths to files or block devices used for
backing storage for each logical unit. There may be at most
FSG_MAX_LUNS (8) LUNs set. If more files are specified, they will
be silently ignored. See also “luns” parameter.
*BEWARE* that if a file is used as a backing storage, it may not
be modified by any other process. This is because the host
assumes the data does not change without its knowledge. It may be
read, but (if the logical unit is writable) due to buffering on
the host side, the contents are not well defined.
The size of the logical unit will be rounded down to a full
logical block. The logical block size is 2048 bytes for LUNs
simulating CD-ROM, block size of the device if the backing file is
a block device, or 512 bytes otherwise.
- removable=b[,b...]
This parameter specifies whether each logical unit should be
removable. “b” here is either “y”, “Y” or “1” for true or “n”,
“N” or “0” for false.
If this option is set for a logical unit, gadget will accept an
“eject” SCSI request (Start/Stop Unit). When it is sent, the
backing file will be closed to simulate ejection and the logical
unit will not be mountable by the host until a new backing file is
specified by userspace on the device (see “sysfs entries”
section).
If a logical unit is not removable (the default), a backing file
must be specified for it with the “file” parameter as the module
is loaded. The same applies if the module is built in, no
exceptions.
The default value of the flag is false, *HOWEVER* it used to be
true. This has been changed to better match File Storage Gadget
and because it seems like a saner default after all. Thus to
maintain compatibility with older kernels, it's best to specify
the default values. Also, if one relied on old default, explicit
“n” needs to be specified now.
Note that “removable” means the logical unit's media can be
ejected or removed (as is true for a CD-ROM drive or a card
reader). It does *not* mean that the entire gadget can be
unplugged from the host; the proper term for that is
“hot-unpluggable”.
- cdrom=b[,b...]
This parameter specifies whether each logical unit should simulate
CD-ROM. The default is false.
- ro=b[,b...]
This parameter specifies whether each logical unit should be
reported as read only. This will prevent host from modifying the
backing files.
Note that if this flag for given logical unit is false but the
backing file could not be opened in read/write mode, the gadget
will fall back to read only mode anyway.
The default value for non-CD-ROM logical units is false; for
logical units simulating CD-ROM it is forced to true.
- nofua=b[,b...]
This parameter specifies whether FUA flag should be ignored in SCSI
Write10 and Write12 commands sent to given logical units.
MS Windows mounts removable storage in “Removal optimised mode” by
default. All the writes to the media are synchronous, which is
achieved by setting the FUA (Force Unit Access) bit in SCSI
Write(10,12) commands. This forces each write to wait until the
data has actually been written out and prevents I/O requests
aggregation in block layer dramatically decreasing performance.
Note that this may mean that if the device is powered from USB and
the user unplugs the device without unmounting it first (which at
least some Windows users do), the data may be lost.
The default value is false.
- luns=N
This parameter specifies number of logical units the gadget will
have. It is limited by FSG_MAX_LUNS (8) and higher value will be
capped.
If this parameter is provided, and the number of files specified
in “file” argument is greater then the value of “luns”, all excess
files will be ignored.
If this parameter is not present, the number of logical units will
be deduced from the number of files specified in the “file”
parameter. If the file parameter is missing as well, one is
assumed.
- stall=b
Specifies whether the gadget is allowed to halt bulk endpoints.
The default is determined according to the type of USB device
controller, but usually true.
In addition to the above, the gadget also accepts the following
parameters defined by the composite framework (they are common to
all composite gadgets so just a quick listing):
- idVendor -- USB Vendor ID (16 bit integer)
- idProduct -- USB Product ID (16 bit integer)
- bcdDevice -- USB Device version (BCD) (16 bit integer)
- iManufacturer -- USB Manufacturer string (string)
- iProduct -- USB Product string (string)
- iSerialNumber -- SerialNumber string (sting)
* sysfs entries
For each logical unit, the gadget creates a directory in the sysfs
hierarchy. Inside of it the following three files are created:
- file
When read it returns the path to the backing file for the given
logical unit. If there is no backing file (possible only if the
logical unit is removable), the content is empty.
When written into, it changes the backing file for given logical
unit. This change can be performed even if given logical unit is
not specified as removable (but that may look strange to the
host). It may fail, however, if host disallowed medium removal
with the Prevent-Allow Medium Removal SCSI command.
- ro
Reflects the state of ro flag for the given logical unit. It can
be read any time, and written to when there is no backing file
open for given logical unit.
- nofua
Reflects the state of nofua flag for given logical unit. It can
be read and written.
Other then those, as usual, the values of module parameters can be
read from /sys/module/g_mass_storage/parameters/* files.
* Other gadgets using mass storage function
The Mass Storage Gadget uses the Mass Storage Function to handle
mass storage protocol. As a composite function, MSF may be used by
other gadgets as well (eg. g_multi and acm_ms).
All of the information in previous sections are valid for other
gadgets using MSF, except that support for mass storage related
module parameters may be missing, or the parameters may have
a prefix. To figure out whether any of this is true one needs to
consult the gadget's documentation or its source code.
For examples of how to include mass storage function in gadgets, one
may take a look at mass_storage.c, acm_ms.c and multi.c (sorted by
complexity).
* Relation to file storage gadget
The Mass Storage Function and thus the Mass Storage Gadget has been
based on the File Storage Gadget. The difference between the two is
that MSG is a composite gadget (ie. uses the composite framework)
while file storage gadget was a traditional gadget. From userspace
point of view this distinction does not really matter, but from
kernel hacker's point of view, this means that (i) MSG does not
duplicate code needed for handling basic USB protocol commands and
(ii) MSF can be used in any other composite gadget.
Because of that, File Storage Gadget has been removed in Linux 3.8.
All users need to transition to the Mass Storage Gadget. The two
gadgets behave mostly the same from the outside except:
1. In FSG the “removable” and “cdrom” module parameters set the flag
for all logical units whereas in MSG they accept a list of y/n
values for each logical unit. If one uses only a single logical
unit this does not matter, but if there are more, the y/n value
needs to be repeated for each logical unit.
2. FSG's “serial”, “vendor”, “product” and “release” module
parameters are handled in MSG by the composite layer's parameters
named respectively: “iSerialnumber”, “idVendor”, “idProduct” and
“bcdDevice”.
3. MSG does not support FSG's test mode, thus “transport”,
“protocol” and “buflen” FSG's module parameters are not
supported. MSG always uses SCSI protocol with bulk only
transport mode and 16 KiB buffers.

View file

@ -0,0 +1,46 @@
USB 7-Segment Numeric Display
Manufactured by Delcom Engineering
Device Information
------------------
USB VENDOR_ID 0x0fc5
USB PRODUCT_ID 0x1227
Both the 6 character and 8 character displays have PRODUCT_ID,
and according to Delcom Engineering no queryable information
can be obtained from the device to tell them apart.
Device Modes
------------
By default, the driver assumes the display is only 6 characters
The mode for 6 characters is:
MSB 0x06; LSB 0x3f
For the 8 character display:
MSB 0x08; LSB 0xff
The device can accept "text" either in raw, hex, or ascii textmode.
raw controls each segment manually,
hex expects a value between 0-15 per character,
ascii expects a value between '0'-'9' and 'A'-'F'.
The default is ascii.
Device Operation
----------------
1. Turn on the device:
echo 1 > /sys/bus/usb/.../powered
2. Set the device's mode:
echo $mode_msb > /sys/bus/usb/.../mode_msb
echo $mode_lsb > /sys/bus/usb/.../mode_lsb
3. Set the textmode:
echo $textmode > /sys/bus/usb/.../textmode
4. set the text (for example):
echo "123ABC" > /sys/bus/usb/.../text (ascii)
echo "A1B2" > /sys/bus/usb/.../text (ascii)
echo -ne "\x01\x02\x03" > /sys/bus/usb/.../text (hex)
5. Set the decimal places.
The device has either 6 or 8 decimal points.
to set the nth decimal place calculate 10 ** n
and echo it in to /sys/bus/usb/.../decimals
To set multiple decimals points sum up each power.
For example, to set the 0th and 3rd decimal place
echo 1001 > /sys/bus/usb/.../decimals

View file

@ -0,0 +1,72 @@
CHANGES
- 0.3 - Created based off of scanner & INSTALL from the original touchscreen
driver on freecode (http://freecode.com/projects/3mtouchscreendriver)
- Amended for linux-2.4.18, then 2.4.19
- 0.5 - Complete rewrite using Linux Input in 2.6.3
Unfortunately no calibration support at this time
- 1.4 - Multiple changes to support the EXII 5000UC and house cleaning
Changed reset from standard USB dev reset to vendor reset
Changed data sent to host from compensated to raw coordinates
Eliminated vendor/product module params
Performed multiple successful tests with an EXII-5010UC
SUPPORTED HARDWARE:
All controllers have the Vendor: 0x0596 & Product: 0x0001
Controller Description Part Number
------------------------------------------------------
USB Capacitive - Pearl Case 14-205 (Discontinued)
USB Capacitive - Black Case 14-124 (Discontinued)
USB Capacitive - No Case 14-206 (Discontinued)
USB Capacitive - Pearl Case EXII-5010UC
USB Capacitive - Black Case EXII-5030UC
USB Capacitive - No Case EXII-5050UC
DRIVER NOTES:
Installation is simple, you only need to add Linux Input, Linux USB, and the
driver to the kernel. The driver can also be optionally built as a module.
This driver appears to be one of possible 2 Linux USB Input Touchscreen
drivers. Although 3M produces a binary only driver available for
download, I persist in updating this driver since I would like to use the
touchscreen for embedded apps using QTEmbedded, DirectFB, etc. So I feel the
logical choice is to use Linux Input.
Currently there is no way to calibrate the device via this driver. Even if
the device could be calibrated, the driver pulls to raw coordinate data from
the controller. This means calibration must be performed within the
userspace.
The controller screen resolution is now 0 to 16384 for both X and Y reporting
the raw touch data. This is the same for the old and new capacitive USB
controllers.
Perhaps at some point an abstract function will be placed into evdev so
generic functions like calibrations, resets, and vendor information can be
requested from the userspace (And the drivers would handle the vendor specific
tasks).
TODO:
Implement a control urb again to handle requests to and from the device
such as calibration, etc once/if it becomes available.
DISCLAIMER:
I am not a MicroTouch/3M employee, nor have I ever been. 3M does not support
this driver! If you want touch drivers only supported within X, please go to:
http://www.3m.com/3MTouchSystems/
THANKS:
A huge thank you to 3M Touch Systems for the EXII-5010UC controllers for
testing!

View file

@ -0,0 +1,32 @@
23-Aug-2002
The "ohci-hcd" driver is a USB Host Controller Driver (HCD) that is derived
from the "usb-ohci" driver from the 2.4 kernel series. The "usb-ohci" code
was written primarily by Roman Weissgaerber <weissg@vienna.at> but with
contributions from many others (read its copyright/licencing header).
It supports the "Open Host Controller Interface" (OHCI), which standardizes
hardware register protocols used to talk to USB 1.1 host controllers. As
compared to the earlier "Universal Host Controller Interface" (UHCI) from
Intel, it pushes more intelligence into the hardware. USB 1.1 controllers
from vendors other than Intel and VIA generally use OHCI.
Changes since the 2.4 kernel include
- improved robustness; bugfixes; and less overhead
- supports the updated and simplified usbcore APIs
- interrupt transfers can be larger, and can be queued
- less code, by using the upper level "hcd" framework
- supports some non-PCI implementations of OHCI
- ... more
The "ohci-hcd" driver handles all USB 1.1 transfer types. Transfers of all
types can be queued. That was also true in "usb-ohci", except for interrupt
transfers. Previously, using periods of one frame would risk data loss due
to overhead in IRQ processing. When interrupt transfers are queued, those
risks can be minimized by making sure the hardware always has transfers to
work on while the OS is getting around to the relevant IRQ processing.
- David Brownell
<dbrownell@users.sourceforge.net>

View file

@ -0,0 +1,165 @@
USB device persistence during system suspend
Alan Stern <stern@rowland.harvard.edu>
September 2, 2006 (Updated February 25, 2008)
What is the problem?
According to the USB specification, when a USB bus is suspended the
bus must continue to supply suspend current (around 1-5 mA). This
is so that devices can maintain their internal state and hubs can
detect connect-change events (devices being plugged in or unplugged).
The technical term is "power session".
If a USB device's power session is interrupted then the system is
required to behave as though the device has been unplugged. It's a
conservative approach; in the absence of suspend current the computer
has no way to know what has actually happened. Perhaps the same
device is still attached or perhaps it was removed and a different
device plugged into the port. The system must assume the worst.
By default, Linux behaves according to the spec. If a USB host
controller loses power during a system suspend, then when the system
wakes up all the devices attached to that controller are treated as
though they had disconnected. This is always safe and it is the
"officially correct" thing to do.
For many sorts of devices this behavior doesn't matter in the least.
If the kernel wants to believe that your USB keyboard was unplugged
while the system was asleep and a new keyboard was plugged in when the
system woke up, who cares? It'll still work the same when you type on
it.
Unfortunately problems _can_ arise, particularly with mass-storage
devices. The effect is exactly the same as if the device really had
been unplugged while the system was suspended. If you had a mounted
filesystem on the device, you're out of luck -- everything in that
filesystem is now inaccessible. This is especially annoying if your
root filesystem was located on the device, since your system will
instantly crash.
Loss of power isn't the only mechanism to worry about. Anything that
interrupts a power session will have the same effect. For example,
even though suspend current may have been maintained while the system
was asleep, on many systems during the initial stages of wakeup the
firmware (i.e., the BIOS) resets the motherboard's USB host
controllers. Result: all the power sessions are destroyed and again
it's as though you had unplugged all the USB devices. Yes, it's
entirely the BIOS's fault, but that doesn't do _you_ any good unless
you can convince the BIOS supplier to fix the problem (lots of luck!).
On many systems the USB host controllers will get reset after a
suspend-to-RAM. On almost all systems, no suspend current is
available during hibernation (also known as swsusp or suspend-to-disk).
You can check the kernel log after resuming to see if either of these
has happened; look for lines saying "root hub lost power or was reset".
In practice, people are forced to unmount any filesystems on a USB
device before suspending. If the root filesystem is on a USB device,
the system can't be suspended at all. (All right, it _can_ be
suspended -- but it will crash as soon as it wakes up, which isn't
much better.)
What is the solution?
The kernel includes a feature called USB-persist. It tries to work
around these issues by allowing the core USB device data structures to
persist across a power-session disruption.
It works like this. If the kernel sees that a USB host controller is
not in the expected state during resume (i.e., if the controller was
reset or otherwise had lost power) then it applies a persistence check
to each of the USB devices below that controller for which the
"persist" attribute is set. It doesn't try to resume the device; that
can't work once the power session is gone. Instead it issues a USB
port reset and then re-enumerates the device. (This is exactly the
same thing that happens whenever a USB device is reset.) If the
re-enumeration shows that the device now attached to that port has the
same descriptors as before, including the Vendor and Product IDs, then
the kernel continues to use the same device structure. In effect, the
kernel treats the device as though it had merely been reset instead of
unplugged.
The same thing happens if the host controller is in the expected state
but a USB device was unplugged and then replugged, or if a USB device
fails to carry out a normal resume.
If no device is now attached to the port, or if the descriptors are
different from what the kernel remembers, then the treatment is what
you would expect. The kernel destroys the old device structure and
behaves as though the old device had been unplugged and a new device
plugged in.
The end result is that the USB device remains available and usable.
Filesystem mounts and memory mappings are unaffected, and the world is
now a good and happy place.
Note that the "USB-persist" feature will be applied only to those
devices for which it is enabled. You can enable the feature by doing
(as root):
echo 1 >/sys/bus/usb/devices/.../power/persist
where the "..." should be filled in the with the device's ID. Disable
the feature by writing 0 instead of 1. For hubs the feature is
automatically and permanently enabled and the power/persist file
doesn't even exist, so you only have to worry about setting it for
devices where it really matters.
Is this the best solution?
Perhaps not. Arguably, keeping track of mounted filesystems and
memory mappings across device disconnects should be handled by a
centralized Logical Volume Manager. Such a solution would allow you
to plug in a USB flash device, create a persistent volume associated
with it, unplug the flash device, plug it back in later, and still
have the same persistent volume associated with the device. As such
it would be more far-reaching than USB-persist.
On the other hand, writing a persistent volume manager would be a big
job and using it would require significant input from the user. This
solution is much quicker and easier -- and it exists now, a giant
point in its favor!
Furthermore, the USB-persist feature applies to _all_ USB devices, not
just mass-storage devices. It might turn out to be equally useful for
other device types, such as network interfaces.
WARNING: USB-persist can be dangerous!!
When recovering an interrupted power session the kernel does its best
to make sure the USB device hasn't been changed; that is, the same
device is still plugged into the port as before. But the checks
aren't guaranteed to be 100% accurate.
If you replace one USB device with another of the same type (same
manufacturer, same IDs, and so on) there's an excellent chance the
kernel won't detect the change. The serial number string and other
descriptors are compared with the kernel's stored values, but this
might not help since manufacturers frequently omit serial numbers
entirely in their devices.
Furthermore it's quite possible to leave a USB device exactly the same
while changing its media. If you replace the flash memory card in a
USB card reader while the system is asleep, the kernel will have no
way to know you did it. The kernel will assume that nothing has
happened and will continue to use the partition tables, inodes, and
memory mappings for the old card.
If the kernel gets fooled in this way, it's almost certain to cause
data corruption and to crash your system. You'll have no one to blame
but yourself.
For those devices with avoid_reset_quirk attribute being set, persist
maybe fail because they may morph after reset.
YOU HAVE BEEN WARNED! USE AT YOUR OWN RISK!
That having been said, most of the time there shouldn't be any trouble
at all. The USB-persist feature can be extremely useful. Make the
most of it.

View file

@ -0,0 +1,759 @@
Power Management for USB
Alan Stern <stern@rowland.harvard.edu>
Last-updated: February 2014
Contents:
---------
* What is Power Management?
* What is Remote Wakeup?
* When is a USB device idle?
* Forms of dynamic PM
* The user interface for dynamic PM
* Changing the default idle-delay time
* Warnings
* The driver interface for Power Management
* The driver interface for autosuspend and autoresume
* Other parts of the driver interface
* Mutual exclusion
* Interaction between dynamic PM and system PM
* xHCI hardware link PM
* USB Port Power Control
* User Interface for Port Power Control
* Suggested Userspace Port Power Policy
What is Power Management?
-------------------------
Power Management (PM) is the practice of saving energy by suspending
parts of a computer system when they aren't being used. While a
component is "suspended" it is in a nonfunctional low-power state; it
might even be turned off completely. A suspended component can be
"resumed" (returned to a functional full-power state) when the kernel
needs to use it. (There also are forms of PM in which components are
placed in a less functional but still usable state instead of being
suspended; an example would be reducing the CPU's clock rate. This
document will not discuss those other forms.)
When the parts being suspended include the CPU and most of the rest of
the system, we speak of it as a "system suspend". When a particular
device is turned off while the system as a whole remains running, we
call it a "dynamic suspend" (also known as a "runtime suspend" or
"selective suspend"). This document concentrates mostly on how
dynamic PM is implemented in the USB subsystem, although system PM is
covered to some extent (see Documentation/power/*.txt for more
information about system PM).
Note: Dynamic PM support for USB is present only if the kernel was
built with CONFIG_USB_SUSPEND enabled (which depends on
CONFIG_PM_RUNTIME). System PM support is present only if the kernel
was built with CONFIG_SUSPEND or CONFIG_HIBERNATION enabled.
(Starting with the 3.10 kernel release, dynamic PM support for USB is
present whenever the kernel was built with CONFIG_PM_RUNTIME enabled.
The CONFIG_USB_SUSPEND option has been eliminated.)
What is Remote Wakeup?
----------------------
When a device has been suspended, it generally doesn't resume until
the computer tells it to. Likewise, if the entire computer has been
suspended, it generally doesn't resume until the user tells it to, say
by pressing a power button or opening the cover.
However some devices have the capability of resuming by themselves, or
asking the kernel to resume them, or even telling the entire computer
to resume. This capability goes by several names such as "Wake On
LAN"; we will refer to it generically as "remote wakeup". When a
device is enabled for remote wakeup and it is suspended, it may resume
itself (or send a request to be resumed) in response to some external
event. Examples include a suspended keyboard resuming when a key is
pressed, or a suspended USB hub resuming when a device is plugged in.
When is a USB device idle?
--------------------------
A device is idle whenever the kernel thinks it's not busy doing
anything important and thus is a candidate for being suspended. The
exact definition depends on the device's driver; drivers are allowed
to declare that a device isn't idle even when there's no actual
communication taking place. (For example, a hub isn't considered idle
unless all the devices plugged into that hub are already suspended.)
In addition, a device isn't considered idle so long as a program keeps
its usbfs file open, whether or not any I/O is going on.
If a USB device has no driver, its usbfs file isn't open, and it isn't
being accessed through sysfs, then it definitely is idle.
Forms of dynamic PM
-------------------
Dynamic suspends occur when the kernel decides to suspend an idle
device. This is called "autosuspend" for short. In general, a device
won't be autosuspended unless it has been idle for some minimum period
of time, the so-called idle-delay time.
Of course, nothing the kernel does on its own initiative should
prevent the computer or its devices from working properly. If a
device has been autosuspended and a program tries to use it, the
kernel will automatically resume the device (autoresume). For the
same reason, an autosuspended device will usually have remote wakeup
enabled, if the device supports remote wakeup.
It is worth mentioning that many USB drivers don't support
autosuspend. In fact, at the time of this writing (Linux 2.6.23) the
only drivers which do support it are the hub driver, kaweth, asix,
usblp, usblcd, and usb-skeleton (which doesn't count). If a
non-supporting driver is bound to a device, the device won't be
autosuspended. In effect, the kernel pretends the device is never
idle.
We can categorize power management events in two broad classes:
external and internal. External events are those triggered by some
agent outside the USB stack: system suspend/resume (triggered by
userspace), manual dynamic resume (also triggered by userspace), and
remote wakeup (triggered by the device). Internal events are those
triggered within the USB stack: autosuspend and autoresume. Note that
all dynamic suspend events are internal; external agents are not
allowed to issue dynamic suspends.
The user interface for dynamic PM
---------------------------------
The user interface for controlling dynamic PM is located in the power/
subdirectory of each USB device's sysfs directory, that is, in
/sys/bus/usb/devices/.../power/ where "..." is the device's ID. The
relevant attribute files are: wakeup, control, and
autosuspend_delay_ms. (There may also be a file named "level"; this
file was deprecated as of the 2.6.35 kernel and replaced by the
"control" file. In 2.6.38 the "autosuspend" file will be deprecated
and replaced by the "autosuspend_delay_ms" file. The only difference
is that the newer file expresses the delay in milliseconds whereas the
older file uses seconds. Confusingly, both files are present in 2.6.37
but only "autosuspend" works.)
power/wakeup
This file is empty if the device does not support
remote wakeup. Otherwise the file contains either the
word "enabled" or the word "disabled", and you can
write those words to the file. The setting determines
whether or not remote wakeup will be enabled when the
device is next suspended. (If the setting is changed
while the device is suspended, the change won't take
effect until the following suspend.)
power/control
This file contains one of two words: "on" or "auto".
You can write those words to the file to change the
device's setting.
"on" means that the device should be resumed and
autosuspend is not allowed. (Of course, system
suspends are still allowed.)
"auto" is the normal state in which the kernel is
allowed to autosuspend and autoresume the device.
(In kernels up to 2.6.32, you could also specify
"suspend", meaning that the device should remain
suspended and autoresume was not allowed. This
setting is no longer supported.)
power/autosuspend_delay_ms
This file contains an integer value, which is the
number of milliseconds the device should remain idle
before the kernel will autosuspend it (the idle-delay
time). The default is 2000. 0 means to autosuspend
as soon as the device becomes idle, and negative
values mean never to autosuspend. You can write a
number to the file to change the autosuspend
idle-delay time.
Writing "-1" to power/autosuspend_delay_ms and writing "on" to
power/control do essentially the same thing -- they both prevent the
device from being autosuspended. Yes, this is a redundancy in the
API.
(In 2.6.21 writing "0" to power/autosuspend would prevent the device
from being autosuspended; the behavior was changed in 2.6.22. The
power/autosuspend attribute did not exist prior to 2.6.21, and the
power/level attribute did not exist prior to 2.6.22. power/control
was added in 2.6.34, and power/autosuspend_delay_ms was added in
2.6.37 but did not become functional until 2.6.38.)
Changing the default idle-delay time
------------------------------------
The default autosuspend idle-delay time (in seconds) is controlled by
a module parameter in usbcore. You can specify the value when usbcore
is loaded. For example, to set it to 5 seconds instead of 2 you would
do:
modprobe usbcore autosuspend=5
Equivalently, you could add to a configuration file in /etc/modprobe.d
a line saying:
options usbcore autosuspend=5
Some distributions load the usbcore module very early during the boot
process, by means of a program or script running from an initramfs
image. To alter the parameter value you would have to rebuild that
image.
If usbcore is compiled into the kernel rather than built as a loadable
module, you can add
usbcore.autosuspend=5
to the kernel's boot command line.
Finally, the parameter value can be changed while the system is
running. If you do:
echo 5 >/sys/module/usbcore/parameters/autosuspend
then each new USB device will have its autosuspend idle-delay
initialized to 5. (The idle-delay values for already existing devices
will not be affected.)
Setting the initial default idle-delay to -1 will prevent any
autosuspend of any USB device. This has the benefit of allowing you
then to enable autosuspend for selected devices.
Warnings
--------
The USB specification states that all USB devices must support power
management. Nevertheless, the sad fact is that many devices do not
support it very well. You can suspend them all right, but when you
try to resume them they disconnect themselves from the USB bus or
they stop working entirely. This seems to be especially prevalent
among printers and scanners, but plenty of other types of device have
the same deficiency.
For this reason, by default the kernel disables autosuspend (the
power/control attribute is initialized to "on") for all devices other
than hubs. Hubs, at least, appear to be reasonably well-behaved in
this regard.
(In 2.6.21 and 2.6.22 this wasn't the case. Autosuspend was enabled
by default for almost all USB devices. A number of people experienced
problems as a result.)
This means that non-hub devices won't be autosuspended unless the user
or a program explicitly enables it. As of this writing there aren't
any widespread programs which will do this; we hope that in the near
future device managers such as HAL will take on this added
responsibility. In the meantime you can always carry out the
necessary operations by hand or add them to a udev script. You can
also change the idle-delay time; 2 seconds is not the best choice for
every device.
If a driver knows that its device has proper suspend/resume support,
it can enable autosuspend all by itself. For example, the video
driver for a laptop's webcam might do this (in recent kernels they
do), since these devices are rarely used and so should normally be
autosuspended.
Sometimes it turns out that even when a device does work okay with
autosuspend there are still problems. For example, the usbhid driver,
which manages keyboards and mice, has autosuspend support. Tests with
a number of keyboards show that typing on a suspended keyboard, while
causing the keyboard to do a remote wakeup all right, will nonetheless
frequently result in lost keystrokes. Tests with mice show that some
of them will issue a remote-wakeup request in response to button
presses but not to motion, and some in response to neither.
The kernel will not prevent you from enabling autosuspend on devices
that can't handle it. It is even possible in theory to damage a
device by suspending it at the wrong time. (Highly unlikely, but
possible.) Take care.
The driver interface for Power Management
-----------------------------------------
The requirements for a USB driver to support external power management
are pretty modest; the driver need only define
.suspend
.resume
.reset_resume
methods in its usb_driver structure, and the reset_resume method is
optional. The methods' jobs are quite simple:
The suspend method is called to warn the driver that the
device is going to be suspended. If the driver returns a
negative error code, the suspend will be aborted. Normally
the driver will return 0, in which case it must cancel all
outstanding URBs (usb_kill_urb()) and not submit any more.
The resume method is called to tell the driver that the
device has been resumed and the driver can return to normal
operation. URBs may once more be submitted.
The reset_resume method is called to tell the driver that
the device has been resumed and it also has been reset.
The driver should redo any necessary device initialization,
since the device has probably lost most or all of its state
(although the interfaces will be in the same altsettings as
before the suspend).
If the device is disconnected or powered down while it is suspended,
the disconnect method will be called instead of the resume or
reset_resume method. This is also quite likely to happen when
waking up from hibernation, as many systems do not maintain suspend
current to the USB host controllers during hibernation. (It's
possible to work around the hibernation-forces-disconnect problem by
using the USB Persist facility.)
The reset_resume method is used by the USB Persist facility (see
Documentation/usb/persist.txt) and it can also be used under certain
circumstances when CONFIG_USB_PERSIST is not enabled. Currently, if a
device is reset during a resume and the driver does not have a
reset_resume method, the driver won't receive any notification about
the resume. Later kernels will call the driver's disconnect method;
2.6.23 doesn't do this.
USB drivers are bound to interfaces, so their suspend and resume
methods get called when the interfaces are suspended or resumed. In
principle one might want to suspend some interfaces on a device (i.e.,
force the drivers for those interface to stop all activity) without
suspending the other interfaces. The USB core doesn't allow this; all
interfaces are suspended when the device itself is suspended and all
interfaces are resumed when the device is resumed. It isn't possible
to suspend or resume some but not all of a device's interfaces. The
closest you can come is to unbind the interfaces' drivers.
The driver interface for autosuspend and autoresume
---------------------------------------------------
To support autosuspend and autoresume, a driver should implement all
three of the methods listed above. In addition, a driver indicates
that it supports autosuspend by setting the .supports_autosuspend flag
in its usb_driver structure. It is then responsible for informing the
USB core whenever one of its interfaces becomes busy or idle. The
driver does so by calling these six functions:
int usb_autopm_get_interface(struct usb_interface *intf);
void usb_autopm_put_interface(struct usb_interface *intf);
int usb_autopm_get_interface_async(struct usb_interface *intf);
void usb_autopm_put_interface_async(struct usb_interface *intf);
void usb_autopm_get_interface_no_resume(struct usb_interface *intf);
void usb_autopm_put_interface_no_suspend(struct usb_interface *intf);
The functions work by maintaining a usage counter in the
usb_interface's embedded device structure. When the counter is > 0
then the interface is deemed to be busy, and the kernel will not
autosuspend the interface's device. When the usage counter is = 0
then the interface is considered to be idle, and the kernel may
autosuspend the device.
Drivers need not be concerned about balancing changes to the usage
counter; the USB core will undo any remaining "get"s when a driver
is unbound from its interface. As a corollary, drivers must not call
any of the usb_autopm_* functions after their disconnect() routine has
returned.
Drivers using the async routines are responsible for their own
synchronization and mutual exclusion.
usb_autopm_get_interface() increments the usage counter and
does an autoresume if the device is suspended. If the
autoresume fails, the counter is decremented back.
usb_autopm_put_interface() decrements the usage counter and
attempts an autosuspend if the new value is = 0.
usb_autopm_get_interface_async() and
usb_autopm_put_interface_async() do almost the same things as
their non-async counterparts. The big difference is that they
use a workqueue to do the resume or suspend part of their
jobs. As a result they can be called in an atomic context,
such as an URB's completion handler, but when they return the
device will generally not yet be in the desired state.
usb_autopm_get_interface_no_resume() and
usb_autopm_put_interface_no_suspend() merely increment or
decrement the usage counter; they do not attempt to carry out
an autoresume or an autosuspend. Hence they can be called in
an atomic context.
The simplest usage pattern is that a driver calls
usb_autopm_get_interface() in its open routine and
usb_autopm_put_interface() in its close or release routine. But other
patterns are possible.
The autosuspend attempts mentioned above will often fail for one
reason or another. For example, the power/control attribute might be
set to "on", or another interface in the same device might not be
idle. This is perfectly normal. If the reason for failure was that
the device hasn't been idle for long enough, a timer is scheduled to
carry out the operation automatically when the autosuspend idle-delay
has expired.
Autoresume attempts also can fail, although failure would mean that
the device is no longer present or operating properly. Unlike
autosuspend, there's no idle-delay for an autoresume.
Other parts of the driver interface
-----------------------------------
Drivers can enable autosuspend for their devices by calling
usb_enable_autosuspend(struct usb_device *udev);
in their probe() routine, if they know that the device is capable of
suspending and resuming correctly. This is exactly equivalent to
writing "auto" to the device's power/control attribute. Likewise,
drivers can disable autosuspend by calling
usb_disable_autosuspend(struct usb_device *udev);
This is exactly the same as writing "on" to the power/control attribute.
Sometimes a driver needs to make sure that remote wakeup is enabled
during autosuspend. For example, there's not much point
autosuspending a keyboard if the user can't cause the keyboard to do a
remote wakeup by typing on it. If the driver sets
intf->needs_remote_wakeup to 1, the kernel won't autosuspend the
device if remote wakeup isn't available. (If the device is already
autosuspended, though, setting this flag won't cause the kernel to
autoresume it. Normally a driver would set this flag in its probe
method, at which time the device is guaranteed not to be
autosuspended.)
If a driver does its I/O asynchronously in interrupt context, it
should call usb_autopm_get_interface_async() before starting output and
usb_autopm_put_interface_async() when the output queue drains. When
it receives an input event, it should call
usb_mark_last_busy(struct usb_device *udev);
in the event handler. This tells the PM core that the device was just
busy and therefore the next autosuspend idle-delay expiration should
be pushed back. Many of the usb_autopm_* routines also make this call,
so drivers need to worry only when interrupt-driven input arrives.
Asynchronous operation is always subject to races. For example, a
driver may call the usb_autopm_get_interface_async() routine at a time
when the core has just finished deciding the device has been idle for
long enough but not yet gotten around to calling the driver's suspend
method. The suspend method must be responsible for synchronizing with
the I/O request routine and the URB completion handler; it should
cause autosuspends to fail with -EBUSY if the driver needs to use the
device.
External suspend calls should never be allowed to fail in this way,
only autosuspend calls. The driver can tell them apart by applying
the PMSG_IS_AUTO() macro to the message argument to the suspend
method; it will return True for internal PM events (autosuspend) and
False for external PM events.
Mutual exclusion
----------------
For external events -- but not necessarily for autosuspend or
autoresume -- the device semaphore (udev->dev.sem) will be held when a
suspend or resume method is called. This implies that external
suspend/resume events are mutually exclusive with calls to probe,
disconnect, pre_reset, and post_reset; the USB core guarantees that
this is true of autosuspend/autoresume events as well.
If a driver wants to block all suspend/resume calls during some
critical section, the best way is to lock the device and call
usb_autopm_get_interface() (and do the reverse at the end of the
critical section). Holding the device semaphore will block all
external PM calls, and the usb_autopm_get_interface() will prevent any
internal PM calls, even if it fails. (Exercise: Why?)
Interaction between dynamic PM and system PM
--------------------------------------------
Dynamic power management and system power management can interact in
a couple of ways.
Firstly, a device may already be autosuspended when a system suspend
occurs. Since system suspends are supposed to be as transparent as
possible, the device should remain suspended following the system
resume. But this theory may not work out well in practice; over time
the kernel's behavior in this regard has changed. As of 2.6.37 the
policy is to resume all devices during a system resume and let them
handle their own runtime suspends afterward.
Secondly, a dynamic power-management event may occur as a system
suspend is underway. The window for this is short, since system
suspends don't take long (a few seconds usually), but it can happen.
For example, a suspended device may send a remote-wakeup signal while
the system is suspending. The remote wakeup may succeed, which would
cause the system suspend to abort. If the remote wakeup doesn't
succeed, it may still remain active and thus cause the system to
resume as soon as the system suspend is complete. Or the remote
wakeup may fail and get lost. Which outcome occurs depends on timing
and on the hardware and firmware design.
xHCI hardware link PM
---------------------
xHCI host controller provides hardware link power management to usb2.0
(xHCI 1.0 feature) and usb3.0 devices which support link PM. By
enabling hardware LPM, the host can automatically put the device into
lower power state(L1 for usb2.0 devices, or U1/U2 for usb3.0 devices),
which state device can enter and resume very quickly.
The user interface for controlling USB2 hardware LPM is located in the
power/ subdirectory of each USB device's sysfs directory, that is, in
/sys/bus/usb/devices/.../power/ where "..." is the device's ID. The
relevant attribute files is usb2_hardware_lpm.
power/usb2_hardware_lpm
When a USB2 device which support LPM is plugged to a
xHCI host root hub which support software LPM, the
host will run a software LPM test for it; if the device
enters L1 state and resume successfully and the host
supports USB2 hardware LPM, this file will show up and
driver will enable hardware LPM for the device. You
can write y/Y/1 or n/N/0 to the file to enable/disable
USB2 hardware LPM manually. This is for test purpose mainly.
USB Port Power Control
----------------------
In addition to suspending endpoint devices and enabling hardware
controlled link power management, the USB subsystem also has the
capability to disable power to ports under some conditions. Power is
controlled through Set/ClearPortFeature(PORT_POWER) requests to a hub.
In the case of a root or platform-internal hub the host controller
driver translates PORT_POWER requests into platform firmware (ACPI)
method calls to set the port power state. For more background see the
Linux Plumbers Conference 2012 slides [1] and video [2]:
Upon receiving a ClearPortFeature(PORT_POWER) request a USB port is
logically off, and may trigger the actual loss of VBUS to the port [3].
VBUS may be maintained in the case where a hub gangs multiple ports into
a shared power well causing power to remain until all ports in the gang
are turned off. VBUS may also be maintained by hub ports configured for
a charging application. In any event a logically off port will lose
connection with its device, not respond to hotplug events, and not
respond to remote wakeup events*.
WARNING: turning off a port may result in the inability to hot add a device.
Please see "User Interface for Port Power Control" for details.
As far as the effect on the device itself it is similar to what a device
goes through during system suspend, i.e. the power session is lost. Any
USB device or driver that misbehaves with system suspend will be
similarly affected by a port power cycle event. For this reason the
implementation shares the same device recovery path (and honors the same
quirks) as the system resume path for the hub.
[1]: http://dl.dropbox.com/u/96820575/sarah-sharp-lpt-port-power-off2-mini.pdf
[2]: http://linuxplumbers.ubicast.tv/videos/usb-port-power-off-kerneluserspace-api/
[3]: USB 3.1 Section 10.12
* wakeup note: if a device is configured to send wakeup events the port
power control implementation will block poweroff attempts on that
port.
User Interface for Port Power Control
-------------------------------------
The port power control mechanism uses the PM runtime system. Poweroff is
requested by clearing the power/pm_qos_no_power_off flag of the port device
(defaults to 1). If the port is disconnected it will immediately receive a
ClearPortFeature(PORT_POWER) request. Otherwise, it will honor the pm runtime
rules and require the attached child device and all descendants to be suspended.
This mechanism is dependent on the hub advertising port power switching in its
hub descriptor (wHubCharacteristics logical power switching mode field).
Note, some interface devices/drivers do not support autosuspend. Userspace may
need to unbind the interface drivers before the usb_device will suspend. An
unbound interface device is suspended by default. When unbinding, be careful
to unbind interface drivers, not the driver of the parent usb device. Also,
leave hub interface drivers bound. If the driver for the usb device (not
interface) is unbound the kernel is no longer able to resume the device. If a
hub interface driver is unbound, control of its child ports is lost and all
attached child-devices will disconnect. A good rule of thumb is that if the
'driver/module' link for a device points to /sys/module/usbcore then unbinding
it will interfere with port power control.
Example of the relevant files for port power control. Note, in this example
these files are relative to a usb hub device (prefix).
prefix=/sys/devices/pci0000:00/0000:00:14.0/usb3/3-1
attached child device +
hub port device + |
hub interface device + | |
v v v
$prefix/3-1:1.0/3-1-port1/device
$prefix/3-1:1.0/3-1-port1/power/pm_qos_no_power_off
$prefix/3-1:1.0/3-1-port1/device/power/control
$prefix/3-1:1.0/3-1-port1/device/3-1.1:<intf0>/driver/unbind
$prefix/3-1:1.0/3-1-port1/device/3-1.1:<intf1>/driver/unbind
...
$prefix/3-1:1.0/3-1-port1/device/3-1.1:<intfN>/driver/unbind
In addition to these files some ports may have a 'peer' link to a port on
another hub. The expectation is that all superspeed ports have a
hi-speed peer.
$prefix/3-1:1.0/3-1-port1/peer -> ../../../../usb2/2-1/2-1:1.0/2-1-port1
../../../../usb2/2-1/2-1:1.0/2-1-port1/peer -> ../../../../usb3/3-1/3-1:1.0/3-1-port1
Distinct from 'companion ports', or 'ehci/xhci shared switchover ports'
peer ports are simply the hi-speed and superspeed interface pins that
are combined into a single usb3 connector. Peer ports share the same
ancestor XHCI device.
While a superspeed port is powered off a device may downgrade its
connection and attempt to connect to the hi-speed pins. The
implementation takes steps to prevent this:
1/ Port suspend is sequenced to guarantee that hi-speed ports are powered-off
before their superspeed peer is permitted to power-off. The implication is
that the setting pm_qos_no_power_off to zero on a superspeed port may not cause
the port to power-off until its highspeed peer has gone to its runtime suspend
state. Userspace must take care to order the suspensions if it wants to
guarantee that a superspeed port will power-off.
2/ Port resume is sequenced to force a superspeed port to power-on prior to its
highspeed peer.
3/ Port resume always triggers an attached child device to resume. After a
power session is lost the device may have been removed, or need reset.
Resuming the child device when the parent port regains power resolves those
states and clamps the maximum port power cycle frequency at the rate the child
device can suspend (autosuspend-delay) and resume (reset-resume latency).
Sysfs files relevant for port power control:
<hubdev-portX>/power/pm_qos_no_power_off:
This writable flag controls the state of an idle port.
Once all children and descendants have suspended the
port may suspend/poweroff provided that
pm_qos_no_power_off is '0'. If pm_qos_no_power_off is
'1' the port will remain active/powered regardless of
the stats of descendants. Defaults to 1.
<hubdev-portX>/power/runtime_status:
This file reflects whether the port is 'active' (power is on)
or 'suspended' (logically off). There is no indication to
userspace whether VBUS is still supplied.
<hubdev-portX>/connect_type:
An advisory read-only flag to userspace indicating the
location and connection type of the port. It returns
one of four values 'hotplug', 'hardwired', 'not used',
and 'unknown'. All values, besides unknown, are set by
platform firmware.
"hotplug" indicates an externally connectable/visible
port on the platform. Typically userspace would choose
to keep such a port powered to handle new device
connection events.
"hardwired" refers to a port that is not visible but
connectable. Examples are internal ports for USB
bluetooth that can be disconnected via an external
switch or a port with a hardwired USB camera. It is
expected to be safe to allow these ports to suspend
provided pm_qos_no_power_off is coordinated with any
switch that gates connections. Userspace must arrange
for the device to be connected prior to the port
powering off, or to activate the port prior to enabling
connection via a switch.
"not used" refers to an internal port that is expected
to never have a device connected to it. These may be
empty internal ports, or ports that are not physically
exposed on a platform. Considered safe to be
powered-off at all times.
"unknown" means platform firmware does not provide
information for this port. Most commonly refers to
external hub ports which should be considered 'hotplug'
for policy decisions.
NOTE1: since we are relying on the BIOS to get this ACPI
information correct, the USB port descriptions may be
missing or wrong.
NOTE2: Take care in clearing pm_qos_no_power_off. Once
power is off this port will
not respond to new connect events.
Once a child device is attached additional constraints are
applied before the port is allowed to poweroff.
<child>/power/control:
Must be 'auto', and the port will not
power down until <child>/power/runtime_status
reflects the 'suspended' state. Default
value is controlled by child device driver.
<child>/power/persist:
This defaults to '1' for most devices and indicates if
kernel can persist the device's configuration across a
power session loss (suspend / port-power event). When
this value is '0' (quirky devices), port poweroff is
disabled.
<child>/driver/unbind:
Wakeup capable devices will block port poweroff. At
this time the only mechanism to clear the usb-internal
wakeup-capability for an interface device is to unbind
its driver.
Summary of poweroff pre-requisite settings relative to a port device:
echo 0 > power/pm_qos_no_power_off
echo 0 > peer/power/pm_qos_no_power_off # if it exists
echo auto > power/control # this is the default value
echo auto > <child>/power/control
echo 1 > <child>/power/persist # this is the default value
Suggested Userspace Port Power Policy
-------------------------------------
As noted above userspace needs to be careful and deliberate about what
ports are enabled for poweroff.
The default configuration is that all ports start with
power/pm_qos_no_power_off set to '1' causing ports to always remain
active.
Given confidence in the platform firmware's description of the ports
(ACPI _PLD record for a port populates 'connect_type') userspace can
clear pm_qos_no_power_off for all 'not used' ports. The same can be
done for 'hardwired' ports provided poweroff is coordinated with any
connection switch for the port.
A more aggressive userspace policy is to enable USB port power off for
all ports (set <hubdev-portX>/power/pm_qos_no_power_off to '0') when
some external factor indicates the user has stopped interacting with the
system. For example, a distro may want to enable power off all USB
ports when the screen blanks, and re-power them when the screen becomes
active. Smart phones and tablets may want to power off USB ports when
the user pushes the power button.

View file

@ -0,0 +1,390 @@
/proc/bus/usb filesystem output
===============================
(version 2010.09.13)
The usbfs filesystem for USB devices is traditionally mounted at
/proc/bus/usb. It provides the /proc/bus/usb/devices file, as well as
the /proc/bus/usb/BBB/DDD files.
In many modern systems the usbfs filesystem isn't used at all. Instead
USB device nodes are created under /dev/usb/ or someplace similar. The
"devices" file is available in debugfs, typically as
/sys/kernel/debug/usb/devices.
**NOTE**: If /proc/bus/usb appears empty, and a host controller
driver has been linked, then you need to mount the
filesystem. Issue the command (as root):
mount -t usbfs none /proc/bus/usb
An alternative and more permanent method would be to add
none /proc/bus/usb usbfs defaults 0 0
to /etc/fstab. This will mount usbfs at each reboot.
You can then issue `cat /proc/bus/usb/devices` to extract
USB device information, and user mode drivers can use usbfs
to interact with USB devices.
There are a number of mount options supported by usbfs.
Consult the source code (linux/drivers/usb/core/inode.c) for
information about those options.
**NOTE**: The filesystem has been renamed from "usbdevfs" to
"usbfs", to reduce confusion with "devfs". You may
still see references to the older "usbdevfs" name.
For more information on mounting the usbfs file system, see the
"USB Device Filesystem" section of the USB Guide. The latest copy
of the USB Guide can be found at http://www.linux-usb.org/
THE /proc/bus/usb/BBB/DDD FILES:
--------------------------------
Each connected USB device has one file. The BBB indicates the bus
number. The DDD indicates the device address on that bus. Both
of these numbers are assigned sequentially, and can be reused, so
you can't rely on them for stable access to devices. For example,
it's relatively common for devices to re-enumerate while they are
still connected (perhaps someone jostled their power supply, hub,
or USB cable), so a device might be 002/027 when you first connect
it and 002/048 sometime later.
These files can be read as binary data. The binary data consists
of first the device descriptor, then the descriptors for each
configuration of the device. Multi-byte fields in the device descriptor
are converted to host endianness by the kernel. The configuration
descriptors are in bus endian format! The configuration descriptor
are wTotalLength bytes apart. If a device returns less configuration
descriptor data than indicated by wTotalLength there will be a hole in
the file for the missing bytes. This information is also shown
in text form by the /proc/bus/usb/devices file, described later.
These files may also be used to write user-level drivers for the USB
devices. You would open the /proc/bus/usb/BBB/DDD file read/write,
read its descriptors to make sure it's the device you expect, and then
bind to an interface (or perhaps several) using an ioctl call. You
would issue more ioctls to the device to communicate to it using
control, bulk, or other kinds of USB transfers. The IOCTLs are
listed in the <linux/usbdevice_fs.h> file, and at this writing the
source code (linux/drivers/usb/core/devio.c) is the primary reference
for how to access devices through those files.
Note that since by default these BBB/DDD files are writable only by
root, only root can write such user mode drivers. You can selectively
grant read/write permissions to other users by using "chmod". Also,
usbfs mount options such as "devmode=0666" may be helpful.
THE /proc/bus/usb/devices FILE:
-------------------------------
In /proc/bus/usb/devices, each device's output has multiple
lines of ASCII output.
I made it ASCII instead of binary on purpose, so that someone
can obtain some useful data from it without the use of an
auxiliary program. However, with an auxiliary program, the numbers
in the first 4 columns of each "T:" line (topology info:
Lev, Prnt, Port, Cnt) can be used to build a USB topology diagram.
Each line is tagged with a one-character ID for that line:
T = Topology (etc.)
B = Bandwidth (applies only to USB host controllers, which are
virtualized as root hubs)
D = Device descriptor info.
P = Product ID info. (from Device descriptor, but they won't fit
together on one line)
S = String descriptors.
C = Configuration descriptor info. (* = active configuration)
I = Interface descriptor info.
E = Endpoint descriptor info.
=======================================================================
/proc/bus/usb/devices output format:
Legend:
d = decimal number (may have leading spaces or 0's)
x = hexadecimal number (may have leading spaces or 0's)
s = string
Topology info:
T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd
| | | | | | | | |__MaxChildren
| | | | | | | |__Device Speed in Mbps
| | | | | | |__DeviceNumber
| | | | | |__Count of devices at this level
| | | | |__Connector/Port on Parent for this device
| | | |__Parent DeviceNumber
| | |__Level in topology for this bus
| |__Bus number
|__Topology info tag
Speed may be:
1.5 Mbit/s for low speed USB
12 Mbit/s for full speed USB
480 Mbit/s for high speed USB (added for USB 2.0);
also used for Wireless USB, which has no fixed speed
5000 Mbit/s for SuperSpeed USB (added for USB 3.0)
For reasons lost in the mists of time, the Port number is always
too low by 1. For example, a device plugged into port 4 will
show up with "Port=03".
Bandwidth info:
B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd
| | | |__Number of isochronous requests
| | |__Number of interrupt requests
| |__Total Bandwidth allocated to this bus
|__Bandwidth info tag
Bandwidth allocation is an approximation of how much of one frame
(millisecond) is in use. It reflects only periodic transfers, which
are the only transfers that reserve bandwidth. Control and bulk
transfers use all other bandwidth, including reserved bandwidth that
is not used for transfers (such as for short packets).
The percentage is how much of the "reserved" bandwidth is scheduled by
those transfers. For a low or full speed bus (loosely, "USB 1.1"),
90% of the bus bandwidth is reserved. For a high speed bus (loosely,
"USB 2.0") 80% is reserved.
Device descriptor info & Product ID info:
D: Ver=x.xx Cls=xx(s) Sub=xx Prot=xx MxPS=dd #Cfgs=dd
P: Vendor=xxxx ProdID=xxxx Rev=xx.xx
where
D: Ver=x.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd
| | | | | | |__NumberConfigurations
| | | | | |__MaxPacketSize of Default Endpoint
| | | | |__DeviceProtocol
| | | |__DeviceSubClass
| | |__DeviceClass
| |__Device USB version
|__Device info tag #1
where
P: Vendor=xxxx ProdID=xxxx Rev=xx.xx
| | | |__Product revision number
| | |__Product ID code
| |__Vendor ID code
|__Device info tag #2
String descriptor info:
S: Manufacturer=ssss
| |__Manufacturer of this device as read from the device.
| For USB host controller drivers (virtual root hubs) this may
| be omitted, or (for newer drivers) will identify the kernel
| version and the driver which provides this hub emulation.
|__String info tag
S: Product=ssss
| |__Product description of this device as read from the device.
| For older USB host controller drivers (virtual root hubs) this
| indicates the driver; for newer ones, it's a product (and vendor)
| description that often comes from the kernel's PCI ID database.
|__String info tag
S: SerialNumber=ssss
| |__Serial Number of this device as read from the device.
| For USB host controller drivers (virtual root hubs) this is
| some unique ID, normally a bus ID (address or slot name) that
| can't be shared with any other device.
|__String info tag
Configuration descriptor info:
C:* #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA
| | | | | |__MaxPower in mA
| | | | |__Attributes
| | | |__ConfiguratioNumber
| | |__NumberOfInterfaces
| |__ "*" indicates the active configuration (others are " ")
|__Config info tag
USB devices may have multiple configurations, each of which act
rather differently. For example, a bus-powered configuration
might be much less capable than one that is self-powered. Only
one device configuration can be active at a time; most devices
have only one configuration.
Each configuration consists of one or more interfaces. Each
interface serves a distinct "function", which is typically bound
to a different USB device driver. One common example is a USB
speaker with an audio interface for playback, and a HID interface
for use with software volume control.
Interface descriptor info (can be multiple per Config):
I:* If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss
| | | | | | | | |__Driver name
| | | | | | | | or "(none)"
| | | | | | | |__InterfaceProtocol
| | | | | | |__InterfaceSubClass
| | | | | |__InterfaceClass
| | | | |__NumberOfEndpoints
| | | |__AlternateSettingNumber
| | |__InterfaceNumber
| |__ "*" indicates the active altsetting (others are " ")
|__Interface info tag
A given interface may have one or more "alternate" settings.
For example, default settings may not use more than a small
amount of periodic bandwidth. To use significant fractions
of bus bandwidth, drivers must select a non-default altsetting.
Only one setting for an interface may be active at a time, and
only one driver may bind to an interface at a time. Most devices
have only one alternate setting per interface.
Endpoint descriptor info (can be multiple per Interface):
E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddss
| | | | |__Interval (max) between transfers
| | | |__EndpointMaxPacketSize
| | |__Attributes(EndpointType)
| |__EndpointAddress(I=In,O=Out)
|__Endpoint info tag
The interval is nonzero for all periodic (interrupt or isochronous)
endpoints. For high speed endpoints the transfer interval may be
measured in microseconds rather than milliseconds.
For high speed periodic endpoints, the "MaxPacketSize" reflects
the per-microframe data transfer size. For "high bandwidth"
endpoints, that can reflect two or three packets (for up to
3KBytes every 125 usec) per endpoint.
With the Linux-USB stack, periodic bandwidth reservations use the
transfer intervals and sizes provided by URBs, which can be less
than those found in endpoint descriptor.
=======================================================================
If a user or script is interested only in Topology info, for
example, use something like "grep ^T: /proc/bus/usb/devices"
for only the Topology lines. A command like
"grep -i ^[tdp]: /proc/bus/usb/devices" can be used to list
only the lines that begin with the characters in square brackets,
where the valid characters are TDPCIE. With a slightly more able
script, it can display any selected lines (for example, only T, D,
and P lines) and change their output format. (The "procusb"
Perl script is the beginning of this idea. It will list only
selected lines [selected from TBDPSCIE] or "All" lines from
/proc/bus/usb/devices.)
The Topology lines can be used to generate a graphic/pictorial
of the USB devices on a system's root hub. (See more below
on how to do this.)
The Interface lines can be used to determine what driver is
being used for each device, and which altsetting it activated.
The Configuration lines could be used to list maximum power
(in milliamps) that a system's USB devices are using.
For example, "grep ^C: /proc/bus/usb/devices".
Here's an example, from a system which has a UHCI root hub,
an external hub connected to the root hub, and a mouse and
a serial converter connected to the external hub.
T: Bus=00 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
B: Alloc= 28/900 us ( 3%), #Int= 2, #Iso= 0
D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0000 ProdID=0000 Rev= 0.00
S: Product=USB UHCI Root Hub
S: SerialNumber=dce0
C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=255ms
T: Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 4
D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0451 ProdID=1446 Rev= 1.00
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=255ms
T: Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=1.5 MxCh= 0
D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=04b4 ProdID=0001 Rev= 0.00
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=mouse
E: Ad=81(I) Atr=03(Int.) MxPS= 3 Ivl= 10ms
T: Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#= 4 Spd=12 MxCh= 0
D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0565 ProdID=0001 Rev= 1.08
S: Manufacturer=Peracom Networks, Inc.
S: Product=Peracom USB to Serial Converter
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=00(>ifc ) Sub=00 Prot=00 Driver=serial
E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl= 16ms
E: Ad=01(O) Atr=02(Bulk) MxPS= 16 Ivl= 16ms
E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl= 8ms
Selecting only the "T:" and "I:" lines from this (for example, by using
"procusb ti"), we have:
T: Bus=00 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
T: Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 4
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
T: Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=1.5 MxCh= 0
I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=mouse
T: Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#= 4 Spd=12 MxCh= 0
I: If#= 0 Alt= 0 #EPs= 3 Cls=00(>ifc ) Sub=00 Prot=00 Driver=serial
Physically this looks like (or could be converted to):
+------------------+
| PC/root_hub (12)| Dev# = 1
+------------------+ (nn) is Mbps.
Level 0 | CN.0 | CN.1 | [CN = connector/port #]
+------------------+
/
/
+-----------------------+
Level 1 | Dev#2: 4-port hub (12)|
+-----------------------+
|CN.0 |CN.1 |CN.2 |CN.3 |
+-----------------------+
\ \____________________
\_____ \
\ \
+--------------------+ +--------------------+
Level 2 | Dev# 3: mouse (1.5)| | Dev# 4: serial (12)|
+--------------------+ +--------------------+
Or, in a more tree-like structure (ports [Connectors] without
connections could be omitted):
PC: Dev# 1, root hub, 2 ports, 12 Mbps
|_ CN.0: Dev# 2, hub, 4 ports, 12 Mbps
|_ CN.0: Dev #3, mouse, 1.5 Mbps
|_ CN.1:
|_ CN.2: Dev #4, serial, 12 Mbps
|_ CN.3:
|_ CN.1:
### END ###

138
Documentation/usb/rio.txt Normal file
View file

@ -0,0 +1,138 @@
Copyright (C) 1999, 2000 Bruce Tenison
Portions Copyright (C) 1999, 2000 David Nelson
Thanks to David Nelson for guidance and the usage of the scanner.txt
and scanner.c files to model our driver and this informative file.
Mar. 2, 2000
CHANGES
- Initial Revision
OVERVIEW
This README will address issues regarding how to configure the kernel
to access a RIO 500 mp3 player.
Before I explain how to use this to access the Rio500 please be warned:
W A R N I N G:
--------------
Please note that this software is still under development. The authors
are in no way responsible for any damage that may occur, no matter how
inconsequential.
It seems that the Rio has a problem when sending .mp3 with low batteries.
I suggest when the batteries are low and you want to transfer stuff that you
replace it with a fresh one. In my case, what happened is I lost two 16kb
blocks (they are no longer usable to store information to it). But I don't
know if that's normal or not; it could simply be a problem with the flash
memory.
In an extreme case, I left my Rio playing overnight and the batteries wore
down to nothing and appear to have corrupted the flash memory. My RIO
needed to be replaced as a result. Diamond tech support is aware of the
problem. Do NOT allow your batteries to wear down to nothing before
changing them. It appears RIO 500 firmware does not handle low battery
power well at all.
On systems with OHCI controllers, the kernel OHCI code appears to have
power on problems with some chipsets. If you are having problems
connecting to your RIO 500, try turning it on first and then plugging it
into the USB cable.
Contact information:
--------------------
The main page for the project is hosted at sourceforge.net in the following
URL: <http://rio500.sourceforge.net>. You can also go to the project's
sourceforge home page at: <http://sourceforge.net/projects/rio500/>.
There is also a mailing list: rio500-users@lists.sourceforge.net
Authors:
-------
Most of the code was written by Cesar Miquel <miquel@df.uba.ar>. Keith
Clayton <kclayton@jps.net> is incharge of the PPC port and making sure
things work there. Bruce Tenison <btenison@dibbs.net> is adding support
for .fon files and also does testing. The program will mostly sure be
re-written and Pete Ikusz along with the rest will re-design it. I would
also like to thank Tri Nguyen <tmn_3022000@hotmail.com> who provided use
with some important information regarding the communication with the Rio.
ADDITIONAL INFORMATION and Userspace tools
http://rio500.sourceforge.net/
REQUIREMENTS
A host with a USB port. Ideally, either a UHCI (Intel) or OHCI
(Compaq and others) hardware port should work.
A Linux development kernel (2.3.x) with USB support enabled or a
backported version to linux-2.2.x. See http://www.linux-usb.org for
more information on accomplishing this.
A Linux kernel with RIO 500 support enabled.
'lspci' which is only needed to determine the type of USB hardware
available in your machine.
CONFIGURATION
Using `lspci -v`, determine the type of USB hardware available.
If you see something like:
USB Controller: ......
Flags: .....
I/O ports at ....
Then you have a UHCI based controller.
If you see something like:
USB Controller: .....
Flags: ....
Memory at .....
Then you have a OHCI based controller.
Using `make menuconfig` or your preferred method for configuring the
kernel, select 'Support for USB', 'OHCI/UHCI' depending on your
hardware (determined from the steps above), 'USB Diamond Rio500 support', and
'Preliminary USB device filesystem'. Compile and install the modules
(you may need to execute `depmod -a` to update the module
dependencies).
Add a device for the USB rio500:
`mknod /dev/usb/rio500 c 180 64`
Set appropriate permissions for /dev/usb/rio500 (don't forget about
group and world permissions). Both read and write permissions are
required for proper operation.
Load the appropriate modules (if compiled as modules):
OHCI:
modprobe usbcore
modprobe usb-ohci
modprobe rio500
UHCI:
modprobe usbcore
modprobe usb-uhci (or uhci)
modprobe rio500
That's it. The Rio500 Utils at: http://rio500.sourceforge.net should
be able to access the rio500.
BUGS
If you encounter any problems feel free to drop me an email.
Bruce Tenison
btenison@dibbs.net

View file

@ -0,0 +1,16 @@
usb-help.txt
2008-Mar-7
For USB help other than the readme files that are located in
Documentation/usb/*, see the following:
Linux-USB project: http://www.linux-usb.org
mirrors at http://usb.in.tum.de/linux-usb/
and http://it.linux-usb.org
Linux USB Guide: http://linux-usb.sourceforge.net
Linux-USB device overview (working devices and drivers):
http://www.qbik.ch/usb/devices/
The Linux-USB mailing list is at linux-usb@vger.kernel.org
###

View file

@ -0,0 +1,493 @@
INTRODUCTION
The USB serial driver currently supports a number of different USB to
serial converter products, as well as some devices that use a serial
interface from userspace to talk to the device.
See the individual product section below for specific information about
the different devices.
CONFIGURATION
Currently the driver can handle up to 256 different serial interfaces at
one time.
The major number that the driver uses is 188 so to use the driver,
create the following nodes:
mknod /dev/ttyUSB0 c 188 0
mknod /dev/ttyUSB1 c 188 1
mknod /dev/ttyUSB2 c 188 2
mknod /dev/ttyUSB3 c 188 3
.
.
.
mknod /dev/ttyUSB254 c 188 254
mknod /dev/ttyUSB255 c 188 255
When the device is connected and recognized by the driver, the driver
will print to the system log, which node(s) the device has been bound
to.
SPECIFIC DEVICES SUPPORTED
ConnectTech WhiteHEAT 4 port converter
ConnectTech has been very forthcoming with information about their
device, including providing a unit to test with.
The driver is officially supported by Connect Tech Inc.
http://www.connecttech.com
For any questions or problems with this driver, please contact
Connect Tech's Support Department at support@connecttech.com
HandSpring Visor, Palm USB, and Clié USB driver
This driver works with all HandSpring USB, Palm USB, and Sony Clié USB
devices.
Only when the device tries to connect to the host, will the device show
up to the host as a valid USB device. When this happens, the device is
properly enumerated, assigned a port, and then communication _should_ be
possible. The driver cleans up properly when the device is removed, or
the connection is canceled on the device.
NOTE:
This means that in order to talk to the device, the sync button must be
pressed BEFORE trying to get any program to communicate to the device.
This goes against the current documentation for pilot-xfer and other
packages, but is the only way that it will work due to the hardware
in the device.
When the device is connected, try talking to it on the second port
(this is usually /dev/ttyUSB1 if you do not have any other usb-serial
devices in the system.) The system log should tell you which port is
the port to use for the HotSync transfer. The "Generic" port can be used
for other device communication, such as a PPP link.
For some Sony Clié devices, /dev/ttyUSB0 must be used to talk to the
device. This is true for all OS version 3.5 devices, and most devices
that have had a flash upgrade to a newer version of the OS. See the
kernel system log for information on which is the correct port to use.
If after pressing the sync button, nothing shows up in the system log,
try resetting the device, first a hot reset, and then a cold reset if
necessary. Some devices need this before they can talk to the USB port
properly.
Devices that are not compiled into the kernel can be specified with module
parameters. e.g. modprobe visor vendor=0x54c product=0x66
There is a webpage and mailing lists for this portion of the driver at:
http://sourceforge.net/projects/usbvisor/
For any questions or problems with this driver, please contact Greg
Kroah-Hartman at greg@kroah.com
PocketPC PDA Driver
This driver can be used to connect to Compaq iPAQ, HP Jornada, Casio EM500
and other PDAs running Windows CE 3.0 or PocketPC 2002 using a USB
cable/cradle.
Most devices supported by ActiveSync are supported out of the box.
For others, please use module parameters to specify the product and vendor
id. e.g. modprobe ipaq vendor=0x3f0 product=0x1125
The driver presents a serial interface (usually on /dev/ttyUSB0) over
which one may run ppp and establish a TCP/IP link to the PDA. Once this
is done, you can transfer files, backup, download email etc. The most
significant advantage of using USB is speed - I can get 73 to 113
kbytes/sec for download/upload to my iPAQ.
This driver is only one of a set of components required to utilize
the USB connection. Please visit http://synce.sourceforge.net which
contains the necessary packages and a simple step-by-step howto.
Once connected, you can use Win CE programs like ftpView, Pocket Outlook
from the PDA and xcerdisp, synce utilities from the Linux side.
To use Pocket IE, follow the instructions given at
http://www.tekguru.co.uk/EM500/usbtonet.htm to achieve the same thing
on Win98. Omit the proxy server part; Linux is quite capable of forwarding
packets unlike Win98. Another modification is required at least for the
iPAQ - disable autosync by going to the Start/Settings/Connections menu
and unchecking the "Automatically synchronize ..." box. Go to
Start/Programs/Connections, connect the cable and select "usbdial" (or
whatever you named your new USB connection). You should finally wind
up with a "Connected to usbdial" window with status shown as connected.
Now start up PIE and browse away.
If it doesn't work for some reason, load both the usbserial and ipaq module
with the module parameter "debug" set to 1 and examine the system log.
You can also try soft-resetting your PDA before attempting a connection.
Other functionality may be possible depending on your PDA. According to
Wes Cilldhaire <billybobjoehenrybob@hotmail.com>, with the Toshiba E570,
...if you boot into the bootloader (hold down the power when hitting the
reset button, continuing to hold onto the power until the bootloader screen
is displayed), then put it in the cradle with the ipaq driver loaded, open
a terminal on /dev/ttyUSB0, it gives you a "USB Reflash" terminal, which can
be used to flash the ROM, as well as the microP code.. so much for needing
Toshiba's $350 serial cable for flashing!! :D
NOTE: This has NOT been tested. Use at your own risk.
For any questions or problems with the driver, please contact Ganesh
Varadarajan <ganesh@veritas.com>
Keyspan PDA Serial Adapter
Single port DB-9 serial adapter, pushed as a PDA adapter for iMacs (mostly
sold in Macintosh catalogs, comes in a translucent white/green dongle).
Fairly simple device. Firmware is homebrew.
This driver also works for the Xircom/Entrgra single port serial adapter.
Current status:
Things that work:
basic input/output (tested with 'cu')
blocking write when serial line can't keep up
changing baud rates (up to 115200)
getting/setting modem control pins (TIOCM{GET,SET,BIS,BIC})
sending break (although duration looks suspect)
Things that don't:
device strings (as logged by kernel) have trailing binary garbage
device ID isn't right, might collide with other Keyspan products
changing baud rates ought to flush tx/rx to avoid mangled half characters
Big Things on the todo list:
parity, 7 vs 8 bits per char, 1 or 2 stop bits
HW flow control
not all of the standard USB descriptors are handled: Get_Status, Set_Feature
O_NONBLOCK, select()
For any questions or problems with this driver, please contact Brian
Warner at warner@lothar.com
Keyspan USA-series Serial Adapters
Single, Dual and Quad port adapters - driver uses Keyspan supplied
firmware and is being developed with their support.
Current status:
The USA-18X, USA-28X, USA-19, USA-19W and USA-49W are supported and
have been pretty thoroughly tested at various baud rates with 8-N-1
character settings. Other character lengths and parity setups are
presently untested.
The USA-28 isn't yet supported though doing so should be pretty
straightforward. Contact the maintainer if you require this
functionality.
More information is available at:
http://www.carnationsoftware.com/carnation/Keyspan.html
For any questions or problems with this driver, please contact Hugh
Blemings at hugh@misc.nu
FTDI Single Port Serial Driver
This is a single port DB-25 serial adapter.
Devices supported include:
-TripNav TN-200 USB GPS
-Navis Engineering Bureau CH-4711 USB GPS
For any questions or problems with this driver, please contact Bill Ryder.
ZyXEL omni.net lcd plus ISDN TA
This is an ISDN TA. Please report both successes and troubles to
azummo@towertech.it
Cypress M8 CY4601 Family Serial Driver
This driver was in most part developed by Neil "koyama" Whelchel. It
has been improved since that previous form to support dynamic serial
line settings and improved line handling. The driver is for the most
part stable and has been tested on an smp machine. (dual p2)
Chipsets supported under CY4601 family:
CY7C63723, CY7C63742, CY7C63743, CY7C64013
Devices supported:
-DeLorme's USB Earthmate GPS (SiRF Star II lp arch)
-Cypress HID->COM RS232 adapter
Note: Cypress Semiconductor claims no affiliation with the
hid->com device.
Most devices using chipsets under the CY4601 family should
work with the driver. As long as they stay true to the CY4601
usbserial specification.
Technical notes:
The Earthmate starts out at 4800 8N1 by default... the driver will
upon start init to this setting. usbserial core provides the rest
of the termios settings, along with some custom termios so that the
output is in proper format and parsable.
The device can be put into sirf mode by issuing NMEA command:
$PSRF100,<protocol>,<baud>,<databits>,<stopbits>,<parity>*CHECKSUM
$PSRF100,0,9600,8,1,0*0C
It should then be sufficient to change the port termios to match this
to begin communicating.
As far as I can tell it supports pretty much every sirf command as
documented online available with firmware 2.31, with some unknown
message ids.
The hid->com adapter can run at a maximum baud of 115200bps. Please note
that the device has trouble or is incapable of raising line voltage properly.
It will be fine with null modem links, as long as you do not try to link two
together without hacking the adapter to set the line high.
The driver is smp safe. Performance with the driver is rather low when using
it for transferring files. This is being worked on, but I would be willing to
accept patches. An urb queue or packet buffer would likely fit the bill here.
If you have any questions, problems, patches, feature requests, etc. you can
contact me here via email:
dignome@gmail.com
(your problems/patches can alternately be submitted to usb-devel)
Digi AccelePort Driver
This driver supports the Digi AccelePort USB 2 and 4 devices, 2 port
(plus a parallel port) and 4 port USB serial converters. The driver
does NOT yet support the Digi AccelePort USB 8.
This driver works under SMP with the usb-uhci driver. It does not
work under SMP with the uhci driver.
The driver is generally working, though we still have a few more ioctls
to implement and final testing and debugging to do. The parallel port
on the USB 2 is supported as a serial to parallel converter; in other
words, it appears as another USB serial port on Linux, even though
physically it is really a parallel port. The Digi Acceleport USB 8
is not yet supported.
Please contact Peter Berger (pberger@brimson.com) or Al Borchers
(alborchers@steinerpoint.com) for questions or problems with this
driver.
Belkin USB Serial Adapter F5U103
Single port DB-9/PS-2 serial adapter from Belkin with firmware by eTEK Labs.
The Peracom single port serial adapter also works with this driver, as
well as the GoHubs adapter.
Current status:
The following have been tested and work:
Baud rate 300-230400
Data bits 5-8
Stop bits 1-2
Parity N,E,O,M,S
Handshake None, Software (XON/XOFF), Hardware (CTSRTS,CTSDTR)*
Break Set and clear
Line control Input/Output query and control **
* Hardware input flow control is only enabled for firmware
levels above 2.06. Read source code comments describing Belkin
firmware errata. Hardware output flow control is working for all
firmware versions.
** Queries of inputs (CTS,DSR,CD,RI) show the last
reported state. Queries of outputs (DTR,RTS) show the last
requested state and may not reflect current state as set by
automatic hardware flow control.
TO DO List:
-- Add true modem control line query capability. Currently tracks the
states reported by the interrupt and the states requested.
-- Add error reporting back to application for UART error conditions.
-- Add support for flush ioctls.
-- Add everything else that is missing :)
For any questions or problems with this driver, please contact William
Greathouse at wgreathouse@smva.com
Empeg empeg-car Mark I/II Driver
This is an experimental driver to provide connectivity support for the
client synchronization tools for an Empeg empeg-car mp3 player.
Tips:
* Don't forget to create the device nodes for ttyUSB{0,1,2,...}
* modprobe empeg (modprobe is your friend)
* emptool --usb /dev/ttyUSB0 (or whatever you named your device node)
For any questions or problems with this driver, please contact Gary
Brubaker at xavyer@ix.netcom.com
MCT USB Single Port Serial Adapter U232
This driver is for the MCT USB-RS232 Converter (25 pin, Model No.
U232-P25) from Magic Control Technology Corp. (there is also a 9 pin
Model No. U232-P9). More information about this device can be found at
the manufacturer's web-site: http://www.mct.com.tw.
The driver is generally working, though it still needs some more testing.
It is derived from the Belkin USB Serial Adapter F5U103 driver and its
TODO list is valid for this driver as well.
This driver has also been found to work for other products, which have
the same Vendor ID but different Product IDs. Sitecom's U232-P25 serial
converter uses Product ID 0x230 and Vendor ID 0x711 and works with this
driver. Also, D-Link's DU-H3SP USB BAY also works with this driver.
For any questions or problems with this driver, please contact Wolfgang
Grandegger at wolfgang@ces.ch
Inside Out Networks Edgeport Driver
This driver supports all devices made by Inside Out Networks, specifically
the following models:
Edgeport/4
Rapidport/4
Edgeport/4t
Edgeport/2
Edgeport/4i
Edgeport/2i
Edgeport/421
Edgeport/21
Edgeport/8
Edgeport/8 Dual
Edgeport/2D8
Edgeport/4D8
Edgeport/8i
Edgeport/2 DIN
Edgeport/4 DIN
Edgeport/16 Dual
For any questions or problems with this driver, please contact Greg
Kroah-Hartman at greg@kroah.com
REINER SCT cyberJack pinpad/e-com USB chipcard reader
Interface to ISO 7816 compatible contactbased chipcards, e.g. GSM SIMs.
Current status:
This is the kernel part of the driver for this USB card reader.
There is also a user part for a CT-API driver available. A site
for downloading is TBA. For now, you can request it from the
maintainer (linux-usb@sii.li).
For any questions or problems with this driver, please contact
linux-usb@sii.li
Prolific PL2303 Driver
This driver supports any device that has the PL2303 chip from Prolific
in it. This includes a number of single port USB to serial converters,
more than 70% of USB GPS devices (in 2010), and some USB UPSes. Devices
from Aten (the UC-232) and IO-Data work with this driver, as does
the DCU-11 mobile-phone cable.
For any questions or problems with this driver, please contact Greg
Kroah-Hartman at greg@kroah.com
KL5KUSB105 chipset / PalmConnect USB single-port adapter
Current status:
The driver was put together by looking at the usb bus transactions
done by Palm's driver under Windows, so a lot of functionality is
still missing. Notably, serial ioctls are sometimes faked or not yet
implemented. Support for finding out about DSR and CTS line status is
however implemented (though not nicely), so your favorite autopilot(1)
and pilot-manager -daemon calls will work. Baud rates up to 115200
are supported, but handshaking (software or hardware) is not, which is
why it is wise to cut down on the rate used is wise for large
transfers until this is settled.
Options supported:
If this driver is compiled as a module you can pass the following
options to it:
debug - extra verbose debugging info
(default: 0; nonzero enables)
use_lowlatency - use low_latency flag to speed up tty layer
when reading from the device.
(default: 0; nonzero enables)
See http://www.uuhaus.de/linux/palmconnect.html for up-to-date
information on this driver.
Winchiphead CH341 Driver
This driver is for the Winchiphead CH341 USB-RS232 Converter. This chip
also implements an IEEE 1284 parallel port, I2C and SPI, but that is not
supported by the driver. The protocol was analyzed from the behaviour
of the Windows driver, no datasheet is available at present.
The manufacturer's website: http://www.winchiphead.com/.
For any questions or problems with this driver, please contact
frank@kingswood-consulting.co.uk.
Moschip MCS7720, MCS7715 driver
These chips are present in devices sold by various manufacturers, such as Syba
and Cables Unlimited. There may be others. The 7720 provides two serial
ports, and the 7715 provides one serial and one standard PC parallel port.
Support for the 7715's parallel port is enabled by a separate option, which
will not appear unless parallel port support is first enabled at the top-level
of the Device Drivers config menu. Currently only compatibility mode is
supported on the parallel port (no ECP/EPP).
TODO:
- Implement ECP/EPP modes for the parallel port.
- Baud rates higher than 115200 are currently broken.
- Devices with a single serial port based on the Moschip MCS7703 may work
with this driver with a simple addition to the usb_device_id table. I
don't have one of these devices, so I can't say for sure.
Generic Serial driver
If your device is not one of the above listed devices, compatible with
the above models, you can try out the "generic" interface. This
interface does not provide any type of control messages sent to the
device, and does not support any kind of device flow control. All that
is required of your device is that it has at least one bulk in endpoint,
or one bulk out endpoint.
To enable the generic driver to recognize your device, build the driver
as a module and load it by the following invocation:
insmod usbserial vendor=0x#### product=0x####
where the #### is replaced with the hex representation of your device's
vendor id and product id.
This driver has been successfully used to connect to the NetChip USB
development board, providing a way to develop USB firmware without
having to write a custom driver.
For any questions or problems with this driver, please contact Greg
Kroah-Hartman at greg@kroah.com
CONTACT:
If anyone has any problems using these drivers, with any of the above
specified products, please contact the specific driver's author listed
above, or join the Linux-USB mailing list (information on joining the
mailing list, as well as a link to its searchable archive is at
http://www.linux-usb.org/ )
Greg Kroah-Hartman
greg@kroah.com

View file

@ -0,0 +1,355 @@
* Introduction
The name "usbmon" in lowercase refers to a facility in kernel which is
used to collect traces of I/O on the USB bus. This function is analogous
to a packet socket used by network monitoring tools such as tcpdump(1)
or Ethereal. Similarly, it is expected that a tool such as usbdump or
USBMon (with uppercase letters) is used to examine raw traces produced
by usbmon.
The usbmon reports requests made by peripheral-specific drivers to Host
Controller Drivers (HCD). So, if HCD is buggy, the traces reported by
usbmon may not correspond to bus transactions precisely. This is the same
situation as with tcpdump.
Two APIs are currently implemented: "text" and "binary". The binary API
is available through a character device in /dev namespace and is an ABI.
The text API is deprecated since 2.6.35, but available for convenience.
* How to use usbmon to collect raw text traces
Unlike the packet socket, usbmon has an interface which provides traces
in a text format. This is used for two purposes. First, it serves as a
common trace exchange format for tools while more sophisticated formats
are finalized. Second, humans can read it in case tools are not available.
To collect a raw text trace, execute following steps.
1. Prepare
Mount debugfs (it has to be enabled in your kernel configuration), and
load the usbmon module (if built as module). The second step is skipped
if usbmon is built into the kernel.
# mount -t debugfs none_debugs /sys/kernel/debug
# modprobe usbmon
#
Verify that bus sockets are present.
# ls /sys/kernel/debug/usb/usbmon
0s 0u 1s 1t 1u 2s 2t 2u 3s 3t 3u 4s 4t 4u
#
Now you can choose to either use the socket '0u' (to capture packets on all
buses), and skip to step #3, or find the bus used by your device with step #2.
This allows to filter away annoying devices that talk continuously.
2. Find which bus connects to the desired device
Run "cat /sys/kernel/debug/usb/devices", and find the T-line which corresponds
to the device. Usually you do it by looking for the vendor string. If you have
many similar devices, unplug one and compare the two
/sys/kernel/debug/usb/devices outputs. The T-line will have a bus number.
Example:
T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0557 ProdID=2004 Rev= 1.00
S: Manufacturer=ATEN
S: Product=UC100KM V2.00
"Bus=03" means it's bus 3. Alternatively, you can look at the output from
"lsusb" and get the bus number from the appropriate line. Example:
Bus 003 Device 002: ID 0557:2004 ATEN UC100KM V2.00
3. Start 'cat'
# cat /sys/kernel/debug/usb/usbmon/3u > /tmp/1.mon.out
to listen on a single bus, otherwise, to listen on all buses, type:
# cat /sys/kernel/debug/usb/usbmon/0u > /tmp/1.mon.out
This process will be reading until killed. Naturally, the output can be
redirected to a desirable location. This is preferred, because it is going
to be quite long.
4. Perform the desired operation on the USB bus
This is where you do something that creates the traffic: plug in a flash key,
copy files, control a webcam, etc.
5. Kill cat
Usually it's done with a keyboard interrupt (Control-C).
At this point the output file (/tmp/1.mon.out in this example) can be saved,
sent by e-mail, or inspected with a text editor. In the last case make sure
that the file size is not excessive for your favourite editor.
* Raw text data format
Two formats are supported currently: the original, or '1t' format, and
the '1u' format. The '1t' format is deprecated in kernel 2.6.21. The '1u'
format adds a few fields, such as ISO frame descriptors, interval, etc.
It produces slightly longer lines, but otherwise is a perfect superset
of '1t' format.
If it is desired to recognize one from the other in a program, look at the
"address" word (see below), where '1u' format adds a bus number. If 2 colons
are present, it's the '1t' format, otherwise '1u'.
Any text format data consists of a stream of events, such as URB submission,
URB callback, submission error. Every event is a text line, which consists
of whitespace separated words. The number or position of words may depend
on the event type, but there is a set of words, common for all types.
Here is the list of words, from left to right:
- URB Tag. This is used to identify URBs, and is normally an in-kernel address
of the URB structure in hexadecimal, but can be a sequence number or any
other unique string, within reason.
- Timestamp in microseconds, a decimal number. The timestamp's resolution
depends on available clock, and so it can be much worse than a microsecond
(if the implementation uses jiffies, for example).
- Event Type. This type refers to the format of the event, not URB type.
Available types are: S - submission, C - callback, E - submission error.
- "Address" word (formerly a "pipe"). It consists of four fields, separated by
colons: URB type and direction, Bus number, Device address, Endpoint number.
Type and direction are encoded with two bytes in the following manner:
Ci Co Control input and output
Zi Zo Isochronous input and output
Ii Io Interrupt input and output
Bi Bo Bulk input and output
Bus number, Device address, and Endpoint are decimal numbers, but they may
have leading zeros, for the sake of human readers.
- URB Status word. This is either a letter, or several numbers separated
by colons: URB status, interval, start frame, and error count. Unlike the
"address" word, all fields save the status are optional. Interval is printed
only for interrupt and isochronous URBs. Start frame is printed only for
isochronous URBs. Error count is printed only for isochronous callback
events.
The status field is a decimal number, sometimes negative, which represents
a "status" field of the URB. This field makes no sense for submissions, but
is present anyway to help scripts with parsing. When an error occurs, the
field contains the error code.
In case of a submission of a Control packet, this field contains a Setup Tag
instead of an group of numbers. It is easy to tell whether the Setup Tag is
present because it is never a number. Thus if scripts find a set of numbers
in this word, they proceed to read Data Length (except for isochronous URBs).
If they find something else, like a letter, they read the setup packet before
reading the Data Length or isochronous descriptors.
- Setup packet, if present, consists of 5 words: one of each for bmRequestType,
bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0.
These words are safe to decode if Setup Tag was 's'. Otherwise, the setup
packet was present, but not captured, and the fields contain filler.
- Number of isochronous frame descriptors and descriptors themselves.
If an Isochronous transfer event has a set of descriptors, a total number
of them in an URB is printed first, then a word per descriptor, up to a
total of 5. The word consists of 3 colon-separated decimal numbers for
status, offset, and length respectively. For submissions, initial length
is reported. For callbacks, actual length is reported.
- Data Length. For submissions, this is the requested length. For callbacks,
this is the actual length.
- Data tag. The usbmon may not always capture data, even if length is nonzero.
The data words are present only if this tag is '='.
- Data words follow, in big endian hexadecimal format. Notice that they are
not machine words, but really just a byte stream split into words to make
it easier to read. Thus, the last word may contain from one to four bytes.
The length of collected data is limited and can be less than the data length
reported in the Data Length word. In the case of an Isochronous input (Zi)
completion where the received data is sparse in the buffer, the length of
the collected data can be greater than the Data Length value (because Data
Length counts only the bytes that were received whereas the Data words
contain the entire transfer buffer).
Examples:
An input control transfer to get a port status.
d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 <
d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000
An output bulk transfer to send a SCSI command 0x28 (READ_10) in a 31-byte
Bulk wrapper to a storage device at address 5:
dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 ad000000 00800000 80010a28 20000000 20000040 00000000 000000
dd65f0e8 4128379808 C Bo:1:005:2 0 31 >
* Raw binary format and API
The overall architecture of the API is about the same as the one above,
only the events are delivered in binary format. Each event is sent in
the following structure (its name is made up, so that we can refer to it):
struct usbmon_packet {
u64 id; /* 0: URB ID - from submission to callback */
unsigned char type; /* 8: Same as text; extensible. */
unsigned char xfer_type; /* ISO (0), Intr, Control, Bulk (3) */
unsigned char epnum; /* Endpoint number and transfer direction */
unsigned char devnum; /* Device address */
u16 busnum; /* 12: Bus number */
char flag_setup; /* 14: Same as text */
char flag_data; /* 15: Same as text; Binary zero is OK. */
s64 ts_sec; /* 16: gettimeofday */
s32 ts_usec; /* 24: gettimeofday */
int status; /* 28: */
unsigned int length; /* 32: Length of data (submitted or actual) */
unsigned int len_cap; /* 36: Delivered length */
union { /* 40: */
unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
struct iso_rec { /* Only for ISO */
int error_count;
int numdesc;
} iso;
} s;
int interval; /* 48: Only for Interrupt and ISO */
int start_frame; /* 52: For ISO */
unsigned int xfer_flags; /* 56: copy of URB's transfer_flags */
unsigned int ndesc; /* 60: Actual number of ISO descriptors */
}; /* 64 total length */
These events can be received from a character device by reading with read(2),
with an ioctl(2), or by accessing the buffer with mmap. However, read(2)
only returns first 48 bytes for compatibility reasons.
The character device is usually called /dev/usbmonN, where N is the USB bus
number. Number zero (/dev/usbmon0) is special and means "all buses".
Note that specific naming policy is set by your Linux distribution.
If you create /dev/usbmon0 by hand, make sure that it is owned by root
and has mode 0600. Otherwise, unpriviledged users will be able to snoop
keyboard traffic.
The following ioctl calls are available, with MON_IOC_MAGIC 0x92:
MON_IOCQ_URB_LEN, defined as _IO(MON_IOC_MAGIC, 1)
This call returns the length of data in the next event. Note that majority of
events contain no data, so if this call returns zero, it does not mean that
no events are available.
MON_IOCG_STATS, defined as _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats)
The argument is a pointer to the following structure:
struct mon_bin_stats {
u32 queued;
u32 dropped;
};
The member "queued" refers to the number of events currently queued in the
buffer (and not to the number of events processed since the last reset).
The member "dropped" is the number of events lost since the last call
to MON_IOCG_STATS.
MON_IOCT_RING_SIZE, defined as _IO(MON_IOC_MAGIC, 4)
This call sets the buffer size. The argument is the size in bytes.
The size may be rounded down to the next chunk (or page). If the requested
size is out of [unspecified] bounds for this kernel, the call fails with
-EINVAL.
MON_IOCQ_RING_SIZE, defined as _IO(MON_IOC_MAGIC, 5)
This call returns the current size of the buffer in bytes.
MON_IOCX_GET, defined as _IOW(MON_IOC_MAGIC, 6, struct mon_get_arg)
MON_IOCX_GETX, defined as _IOW(MON_IOC_MAGIC, 10, struct mon_get_arg)
These calls wait for events to arrive if none were in the kernel buffer,
then return the first event. The argument is a pointer to the following
structure:
struct mon_get_arg {
struct usbmon_packet *hdr;
void *data;
size_t alloc; /* Length of data (can be zero) */
};
Before the call, hdr, data, and alloc should be filled. Upon return, the area
pointed by hdr contains the next event structure, and the data buffer contains
the data, if any. The event is removed from the kernel buffer.
The MON_IOCX_GET copies 48 bytes to hdr area, MON_IOCX_GETX copies 64 bytes.
MON_IOCX_MFETCH, defined as _IOWR(MON_IOC_MAGIC, 7, struct mon_mfetch_arg)
This ioctl is primarily used when the application accesses the buffer
with mmap(2). Its argument is a pointer to the following structure:
struct mon_mfetch_arg {
uint32_t *offvec; /* Vector of events fetched */
uint32_t nfetch; /* Number of events to fetch (out: fetched) */
uint32_t nflush; /* Number of events to flush */
};
The ioctl operates in 3 stages.
First, it removes and discards up to nflush events from the kernel buffer.
The actual number of events discarded is returned in nflush.
Second, it waits for an event to be present in the buffer, unless the pseudo-
device is open with O_NONBLOCK.
Third, it extracts up to nfetch offsets into the mmap buffer, and stores
them into the offvec. The actual number of event offsets is stored into
the nfetch.
MON_IOCH_MFLUSH, defined as _IO(MON_IOC_MAGIC, 8)
This call removes a number of events from the kernel buffer. Its argument
is the number of events to remove. If the buffer contains fewer events
than requested, all events present are removed, and no error is reported.
This works when no events are available too.
FIONBIO
The ioctl FIONBIO may be implemented in the future, if there's a need.
In addition to ioctl(2) and read(2), the special file of binary API can
be polled with select(2) and poll(2). But lseek(2) does not work.
* Memory-mapped access of the kernel buffer for the binary API
The basic idea is simple:
To prepare, map the buffer by getting the current size, then using mmap(2).
Then, execute a loop similar to the one written in pseudo-code below:
struct mon_mfetch_arg fetch;
struct usbmon_packet *hdr;
int nflush = 0;
for (;;) {
fetch.offvec = vec; // Has N 32-bit words
fetch.nfetch = N; // Or less than N
fetch.nflush = nflush;
ioctl(fd, MON_IOCX_MFETCH, &fetch); // Process errors, too
nflush = fetch.nfetch; // This many packets to flush when done
for (i = 0; i < nflush; i++) {
hdr = (struct ubsmon_packet *) &mmap_area[vec[i]];
if (hdr->type == '@') // Filler packet
continue;
caddr_t data = &mmap_area[vec[i]] + 64;
process_packet(hdr, data);
}
}
Thus, the main idea is to execute only one ioctl per N events.
Although the buffer is circular, the returned headers and data do not cross
the end of the buffer, so the above pseudo-code does not need any gathering.

130
Documentation/usb/wusb-cbaf Normal file
View file

@ -0,0 +1,130 @@
#! /bin/bash
#
set -e
progname=$(basename $0)
function help
{
cat <<EOF
Usage: $progname COMMAND DEVICEs [ARGS]
Command for manipulating the pairing/authentication credentials of a
Wireless USB device that supports wired-mode Cable-Based-Association.
Works in conjunction with the wusb-cba.ko driver from http://linuxuwb.org.
DEVICE
sysfs path to the device to authenticate; for example, both this
guys are the same:
/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4.4/1-4.4:1.1
/sys/bus/usb/drivers/wusb-cbaf/1-4.4:1.1
COMMAND/ARGS are
start
Start a WUSB host controller (by setting up a CHID)
set-chid DEVICE HOST-CHID HOST-BANDGROUP HOST-NAME
Sets host information in the device; after this you can call the
get-cdid to see how does this device report itself to us.
get-cdid DEVICE
Get the device ID associated to the HOST-CHID we sent with
'set-chid'. We might not know about it.
set-cc DEVICE
If we allow the device to connect, set a random new CDID and CK
(connection key). Device saves them for the next time it wants to
connect wireless. We save them for that next time also so we can
authenticate the device (when we see the CDID he uses to id
itself) and the CK to crypto talk to it.
CHID is always 16 hex bytes in 'XX YY ZZ...' form
BANDGROUP is almost always 0001
Examples:
You can default most arguments to '' to get a sane value:
$ $progname set-chid '' '' '' "My host name"
A full sequence:
$ $progname set-chid '' '' '' "My host name"
$ $progname get-cdid ''
$ $progname set-cc ''
EOF
}
# Defaults
# FIXME: CHID should come from a database :), band group from the host
host_CHID="00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff"
host_band_group="0001"
host_name=$(hostname)
devs="$(echo /sys/bus/usb/drivers/wusb-cbaf/[0-9]*)"
hdevs="$(for h in /sys/class/uwb_rc/*/wusbhc; do readlink -f $h; done)"
result=0
case $1 in
start)
for dev in ${2:-$hdevs}
do
echo $host_CHID > $dev/wusb_chid
echo I: started host $(basename $dev) >&2
done
;;
stop)
for dev in ${2:-$hdevs}
do
echo 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > $dev/wusb_chid
echo I: stopped host $(basename $dev) >&2
done
;;
set-chid)
shift
for dev in ${2:-$devs}; do
echo "${4:-$host_name}" > $dev/wusb_host_name
echo "${3:-$host_band_group}" > $dev/wusb_host_band_groups
echo ${2:-$host_CHID} > $dev/wusb_chid
done
;;
get-cdid)
for dev in ${2:-$devs}
do
cat $dev/wusb_cdid
done
;;
set-cc)
for dev in ${2:-$devs}; do
shift
CDID="$(head --bytes=16 /dev/urandom | od -tx1 -An)"
CK="$(head --bytes=16 /dev/urandom | od -tx1 -An)"
echo "$CDID" > $dev/wusb_cdid
echo "$CK" > $dev/wusb_ck
echo I: CC set >&2
echo "CHID: $(cat $dev/wusb_chid)"
echo "CDID:$CDID"
echo "CK: $CK"
done
;;
help|h|--help|-h)
help
;;
*)
echo "E: Unknown usage" 1>&2
help 1>&2
result=1
esac
exit $result