1 |
1275 |
phoenix |
Specification and Internals for the New UHCI Driver (Whitepaper...)
|
2 |
|
|
|
3 |
|
|
brought to you by
|
4 |
|
|
|
5 |
|
|
Georg Acher, acher@in.tum.de (executive slave) (base guitar)
|
6 |
|
|
Deti Fliegl, deti@fliegl.de (executive slave) (lead voice)
|
7 |
|
|
Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader)
|
8 |
|
|
|
9 |
|
|
$Id: uhci.txt,v 1.1.1.1 2004-04-15 02:32:08 phoenix Exp $
|
10 |
|
|
|
11 |
|
|
This document and the new uhci sources can be found on
|
12 |
|
|
http://hotswap.in.tum.de/usb
|
13 |
|
|
|
14 |
|
|
1. General issues
|
15 |
|
|
|
16 |
|
|
1.1 Why a new UHCI driver, we already have one?!?
|
17 |
|
|
|
18 |
|
|
Correct, but its internal structure got more and more mixed up by the (still
|
19 |
|
|
ongoing) efforts to get isochronous transfers (ISO) to work.
|
20 |
|
|
Since there is an increasing need for reliable ISO-transfers (especially
|
21 |
|
|
for USB-audio needed by TS and for a DAB-USB-Receiver build by GA and DF),
|
22 |
|
|
this state was a bit unsatisfying in our opinion, so we've decided (based
|
23 |
|
|
on knowledge and experiences with the old UHCI driver) to start
|
24 |
|
|
from scratch with a new approach, much simpler but at the same time more
|
25 |
|
|
powerful.
|
26 |
|
|
It is inspired by the way Win98/Win2000 handles USB requests via URBs,
|
27 |
|
|
but it's definitely 100% free of MS-code and doesn't crash while
|
28 |
|
|
unplugging an used ISO-device like Win98 ;-)
|
29 |
|
|
Some code for HW setup and root hub management was taken from the
|
30 |
|
|
original UHCI driver, but heavily modified to fit into the new code.
|
31 |
|
|
The invention of the basic concept, and major coding were completed in two
|
32 |
|
|
days (and nights) on the 16th and 17th of October 1999, now known as the
|
33 |
|
|
great USB-October-Revolution started by GA, DF, and TS ;-)
|
34 |
|
|
|
35 |
|
|
Since the concept is in no way UHCI dependent, we hope that it will also be
|
36 |
|
|
transferred to the OHCI-driver, so both drivers share a common API.
|
37 |
|
|
|
38 |
|
|
1.2. Advantages and disadvantages
|
39 |
|
|
|
40 |
|
|
+ All USB transfer types work now!
|
41 |
|
|
+ Asynchronous operation
|
42 |
|
|
+ Simple, but powerful interface (only two calls for start and cancel)
|
43 |
|
|
+ Easy migration to the new API, simplified by a compatibility API
|
44 |
|
|
+ Simple usage of ISO transfers
|
45 |
|
|
+ Automatic linking of requests
|
46 |
|
|
+ ISO transfers allow variable length for each frame and striping
|
47 |
|
|
+ No CPU dependent and non-portable atomic memory access, no asm()-inlines
|
48 |
|
|
+ Tested on x86 and Alpha
|
49 |
|
|
|
50 |
|
|
- Rewriting for ISO transfers needed
|
51 |
|
|
|
52 |
|
|
1.3. Is there some compatibility to the old API?
|
53 |
|
|
|
54 |
|
|
Yes, but only for control, bulk and interrupt transfers. We've implemented
|
55 |
|
|
some wrapper calls for these transfer types. The usbcore works fine with
|
56 |
|
|
these wrappers. For ISO there's no compatibility, because the old ISO-API
|
57 |
|
|
and its semantics were unnecessary complicated in our opinion.
|
58 |
|
|
|
59 |
|
|
1.4. What's really working?
|
60 |
|
|
|
61 |
|
|
As said above, CTRL and BULK already work fine even with the wrappers,
|
62 |
|
|
so legacy code wouldn't notice the change.
|
63 |
|
|
Regarding to Thomas, ISO transfers now run stable with USB audio.
|
64 |
|
|
INT transfers (e.g. mouse driver) work fine, too.
|
65 |
|
|
|
66 |
|
|
1.5. Are there any bugs?
|
67 |
|
|
|
68 |
|
|
No ;-)
|
69 |
|
|
Hm...
|
70 |
|
|
Well, of course this implementation needs extensive testing on all available
|
71 |
|
|
hardware, but we believe that any fixes shouldn't harm the overall concept.
|
72 |
|
|
|
73 |
|
|
1.6. What should be done next?
|
74 |
|
|
|
75 |
|
|
A large part of the request handling seems to be identical for UHCI and
|
76 |
|
|
OHCI, so it would be a good idea to extract the common parts and have only
|
77 |
|
|
the HW specific stuff in uhci.c. Furthermore, all other USB device drivers
|
78 |
|
|
should need URBification, if they use isochronous or interrupt transfers.
|
79 |
|
|
One thing missing in the current implementation (and the old UHCI driver)
|
80 |
|
|
is fair queueing for BULK transfers. Since this would need (in principle)
|
81 |
|
|
the alteration of already constructed TD chains (to switch from depth to
|
82 |
|
|
breadth execution), another way has to be found. Maybe some simple
|
83 |
|
|
heuristics work with the same effect.
|
84 |
|
|
|
85 |
|
|
---------------------------------------------------------------------------
|
86 |
|
|
|
87 |
|
|
2. Internal structure and mechanisms
|
88 |
|
|
|
89 |
|
|
To get quickly familiar with the internal structures, here's a short
|
90 |
|
|
description how the new UHCI driver works. However, the ultimate source of
|
91 |
|
|
truth is only uhci.c!
|
92 |
|
|
|
93 |
|
|
2.1. Descriptor structure (QHs and TDs)
|
94 |
|
|
|
95 |
|
|
During initialization, the following skeleton is allocated in init_skel:
|
96 |
|
|
|
97 |
|
|
framespecific | common chain
|
98 |
|
|
|
99 |
|
|
framelist[]
|
100 |
|
|
[ 0 ]-----> TD --> TD -------\
|
101 |
|
|
[ 1 ]-----> TD --> TD --------> TD ----> QH -------> QH -------> QH ---> NULL
|
102 |
|
|
... TD --> TD -------/
|
103 |
|
|
[1023]-----> TD --> TD ------/
|
104 |
|
|
|
105 |
|
|
^^ ^^ ^^ ^^ ^^ ^^
|
106 |
|
|
1024 TDs for 7 TDs for 1 TD for Start of Start of End Chain
|
107 |
|
|
ISO INT (2-128ms) 1ms-INT CTRL Chain BULK Chain
|
108 |
|
|
|
109 |
|
|
For each CTRL or BULK transfer a new QH is allocated and the containing data
|
110 |
|
|
transfers are appended as (vertical) TDs. After building the whole QH with its
|
111 |
|
|
dangling TDs, the QH is inserted before the BULK Chain QH (for CTRL) or
|
112 |
|
|
before the End Chain QH (for BULK). Since only the QH->next pointers are
|
113 |
|
|
affected, no atomic memory operation is required. The three QHs in the
|
114 |
|
|
common chain are never equipped with TDs!
|
115 |
|
|
|
116 |
|
|
For ISO or INT, the TD for each frame is simply inserted into the appropriate
|
117 |
|
|
ISO/INT-TD-chain for the desired frame. The 7 skeleton INT-TDs are scattered
|
118 |
|
|
among the 1024 frames similar to the old UHCI driver.
|
119 |
|
|
|
120 |
|
|
For CTRL/BULK/ISO, the last TD in the transfer has the IOC-bit set. For INT,
|
121 |
|
|
every TD (there is only one...) has the IOC-bit set.
|
122 |
|
|
|
123 |
|
|
Besides the data for the UHCI controller (2 or 4 32bit words), the descriptors
|
124 |
|
|
are double-linked through the .vertical and .horizontal elements in the
|
125 |
|
|
SW data of the descriptor (using the double-linked list structures and
|
126 |
|
|
operations), but SW-linking occurs only in closed domains, i.e. for each of
|
127 |
|
|
the 1024 ISO-chains and the 8 INT-chains there is a closed cycle. This
|
128 |
|
|
simplifies all insertions and unlinking operations and avoids costly
|
129 |
|
|
bus_to_virt()-calls.
|
130 |
|
|
|
131 |
|
|
2.2. URB structure and linking to QH/TDs
|
132 |
|
|
|
133 |
|
|
During assembly of the QH and TDs of the requested action, these descriptors
|
134 |
|
|
are stored in urb->urb_list, so the allocated QH/TD descriptors are bound to
|
135 |
|
|
this URB.
|
136 |
|
|
If the assembly was successful and the descriptors were added to the HW chain,
|
137 |
|
|
the corresponding URB is inserted into a global URB list for this controller.
|
138 |
|
|
This list stores all pending URBs.
|
139 |
|
|
|
140 |
|
|
2.3. Interrupt processing
|
141 |
|
|
|
142 |
|
|
Since UHCI provides no means to directly detect completed transactions, the
|
143 |
|
|
following is done in each UHCI interrupt (uhci_interrupt()):
|
144 |
|
|
|
145 |
|
|
For each URB in the pending queue (process_urb()), the ACTIVE-flag of the
|
146 |
|
|
associated TDs are processed (depending on the transfer type
|
147 |
|
|
process_{transfer|interrupt|iso}()). If the TDs are not active anymore,
|
148 |
|
|
they indicate the completion of the transaction and the status is calculated.
|
149 |
|
|
Inactive QH/TDs are removed from the HW chain (since the host controller
|
150 |
|
|
already removed the TDs from the QH, no atomic access is needed) and
|
151 |
|
|
eventually the URB is marked as completed (OK or errors) and removed from the
|
152 |
|
|
pending queue. Then the next linked URB is submitted. After (or immediately
|
153 |
|
|
before) that, the completion handler is called.
|
154 |
|
|
|
155 |
|
|
2.4. Unlinking URBs
|
156 |
|
|
|
157 |
|
|
First, all QH/TDs stored in the URB are unlinked from the HW chain.
|
158 |
|
|
To ensure that the host controller really left a vertical TD chain, we
|
159 |
|
|
wait for one frame. After that, the TDs are physically destroyed.
|
160 |
|
|
|
161 |
|
|
2.5. URB linking and the consequences
|
162 |
|
|
|
163 |
|
|
Since URBs can be linked and the corresponding submit_urb is called in
|
164 |
|
|
the UHCI-interrupt, all work associated with URB/QH/TD assembly has to be
|
165 |
|
|
interrupt save. This forces kmalloc to use GFP_ATOMIC in the interrupt.
|