| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | 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: 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. |