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. |