]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | Specification and Internals for the New UHCI Driver (Whitepaper...) |
2 | ||
3 | brought to you by | |
4 | ||
5 | Georg Acher, [email protected] (executive slave) (base guitar) | |
6 | Deti Fliegl, [email protected] (executive slave) (lead voice) | |
7 | Thomas Sailer, [email protected] (chief consultant) (cheer leader) | |
8 | ||
9 | $Id: README.uhci,v 1.1 1999/12/14 14:03:02 fliegl 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. |