iPXE
uhci.h
Go to the documentation of this file.
00001 #ifndef _IPXE_UHCI_H
00002 #define _IPXE_UHCI_H
00003 
00004 /** @file
00005  *
00006  * USB Universal Host Controller Interface (UHCI) driver
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <assert.h>
00013 #include <ipxe/pci.h>
00014 #include <ipxe/usb.h>
00015 
00016 /** Minimum alignment required for data structures
00017  *
00018  * With the exception of the frame list (which is page-aligned), data
00019  * structures used by UHCI generally require 16-byte alignment.
00020  */
00021 #define UHCI_ALIGN 16
00022 
00023 /** Number of ports */
00024 #define UHCI_PORTS 2
00025 
00026 /** Maximum transfer size */
00027 #define UHCI_MTU 1280
00028 
00029 /** I/O BAR size */
00030 #define UHCI_BAR_SIZE 0x14
00031 
00032 /** USB command register */
00033 #define UHCI_USBCMD 0x00
00034 
00035 /** Max packet is 64 bytes */
00036 #define UHCI_USBCMD_MAX64 0x0080
00037 
00038 /** Host controller reset */
00039 #define UHCI_USBCMD_HCRESET 0x0002
00040 
00041 /** Run/stop */
00042 #define UHCI_USBCMD_RUN 0x0001
00043 
00044 /** USB status register */
00045 #define UHCI_USBSTS 0x02
00046 
00047 /** Host controller halted */
00048 #define UHCI_USBSTS_HCHALTED 0x0020
00049 
00050 /** USB interrupt */
00051 #define UHCI_USBSTS_USBINT 0x0001
00052 
00053 /** Frame list base address register */
00054 #define UHCI_FLBASEADD 0x08
00055 
00056 /** Port status and control register */
00057 #define UHCI_PORTSC(port) ( 0x0e + ( (port) << 1 ) )
00058 
00059 /** Port reset */
00060 #define UHCI_PORTSC_PR 0x0200
00061 
00062 /** Low-speed device attached */
00063 #define UHCI_PORTSC_LS 0x0100
00064 
00065 /** Port enabled/disabled change */
00066 #define UHCI_PORTSC_PEC 0x0008
00067 
00068 /** Port enabled */
00069 #define UHCI_PORTSC_PED 0x0004
00070 
00071 /** Connect status change */
00072 #define UHCI_PORTSC_CSC 0x0002
00073 
00074 /** Current connect status */
00075 #define UHCI_PORTSC_CCS 0x0001
00076 
00077 /** Port status change mask */
00078 #define UHCI_PORTSC_CHANGE ( UHCI_PORTSC_CSC | UHCI_PORTSC_PEC )
00079 
00080 /** Depth-first processing */
00081 #define UHCI_LINK_DEPTH_FIRST 0x00000004UL
00082 
00083 /** Queue head type */
00084 #define UHCI_LINK_TYPE_QH 0x00000002UL
00085 
00086 /** List terminator */
00087 #define UHCI_LINK_TERMINATE 0x00000001UL
00088 
00089 /** Number of frames in frame list */
00090 #define UHCI_FRAMES 1024
00091 
00092 /** A frame list */
00093 struct uhci_frame_list {
00094         /** Link pointer */
00095         uint32_t link[UHCI_FRAMES];
00096 } __attribute__ (( packed ));
00097 
00098 /** A transfer descriptor */
00099 struct uhci_transfer_descriptor {
00100         /** Link pointer */
00101         uint32_t link;
00102         /** Actual length */
00103         uint16_t actual;
00104         /** Status */
00105         uint8_t status;
00106         /** Flags */
00107         uint8_t flags;
00108         /** Control */
00109         uint32_t control;
00110         /** Buffer pointer */
00111         uint32_t data;
00112 } __attribute__ (( packed ));
00113 
00114 /** Length mask */
00115 #define UHCI_LEN_MASK 0x7ff
00116 
00117 /** Actual length */
00118 #define UHCI_ACTUAL_LEN( actual ) ( ( (actual) + 1 ) & UHCI_LEN_MASK )
00119 
00120 /** Active */
00121 #define UHCI_STATUS_ACTIVE 0x80
00122 
00123 /** Stalled */
00124 #define UHCI_STATUS_STALLED 0x40
00125 
00126 /** Data buffer error */
00127 #define UHCI_STATUS_BUFFER 0x20
00128 
00129 /** Babble detected */
00130 #define UHCI_STATUS_BABBLE 0x10
00131 
00132 /** NAK received */
00133 #define UHCI_STATUS_NAK 0x08
00134 
00135 /** CRC/timeout error */
00136 #define UHCI_STATUS_CRC_TIMEOUT 0x04
00137 
00138 /** Bitstuff error */
00139 #define UHCI_STATUS_BITSTUFF 0x02
00140 
00141 /** Short packet detect */
00142 #define UHCI_FL_SPD 0x20
00143 
00144 /** Error counter */
00145 #define UHCI_FL_CERR( count ) ( (count) << 3 )
00146 
00147 /** Error counter maximum value */
00148 #define UHCI_FL_CERR_MAX UHCI_FL_CERR ( 3 )
00149 
00150 /** Low speed device */
00151 #define UHCI_FL_LS 0x04
00152 
00153 /** Interrupt on completion */
00154 #define UHCI_FL_IOC 0x01
00155 
00156 /** Packet ID */
00157 #define UHCI_CONTROL_PID( pid ) ( (pid) << 0 )
00158 
00159 /** Packet ID mask */
00160 #define UHCI_CONTROL_PID_MASK UHCI_CONTROL_PID ( 0xff )
00161 
00162 /** Device address */
00163 #define UHCI_CONTROL_DEVICE( address ) ( (address) << 8 )
00164 
00165 /** Endpoint address */
00166 #define UHCI_CONTROL_ENDPOINT( address ) ( (address) << 15 )
00167 
00168 /** Data toggle */
00169 #define UHCI_CONTROL_TOGGLE ( 1 << 19 )
00170 
00171 /** Data length */
00172 #define UHCI_CONTROL_LEN( len ) ( ( ( (len) - 1 ) & UHCI_LEN_MASK ) << 21 )
00173 
00174 /** Check for data packet
00175  *
00176  * This check is based on the fact that only USB_PID_SETUP has bit 2
00177  * set.
00178  */
00179 #define UHCI_DATA_PACKET( control ) ( ! ( control & 0x04 ) )
00180 
00181 /** Check for short packet */
00182 #define UHCI_SHORT_PACKET( control, actual ) \
00183         ( ( ( (control) >> 21 ) ^ (actual) ) & UHCI_LEN_MASK )
00184 
00185 /** USB legacy support register (in PCI configuration space) */
00186 #define UHCI_USBLEGSUP 0xc0
00187 
00188 /** USB legacy support default value */
00189 #define UHCI_USBLEGSUP_DEFAULT 0x2000
00190 
00191 /** A queue head */
00192 struct uhci_queue_head {
00193         /** Horizontal link pointer */
00194         uint32_t link;
00195         /** Current transfer descriptor */
00196         uint32_t current;
00197 } __attribute__ (( packed ));
00198 
00199 /** A single UHCI transfer
00200  *
00201  * UHCI hardware is extremely simple, and requires software to build
00202  * the entire packet schedule (including manually handling all of the
00203  * data toggles).  The hardware requires at least 16 bytes of transfer
00204  * descriptors per 64 bytes of transmitted/received data.  We allocate
00205  * the transfer descriptors at the time that the transfer is enqueued,
00206  * to avoid the need to allocate unreasonably large blocks when the
00207  * endpoint is opened.
00208  */
00209 struct uhci_transfer {
00210         /** Producer counter */
00211         unsigned int prod;
00212         /** Consumer counter */
00213         unsigned int cons;
00214         /** Completed data length */
00215         size_t len;
00216 
00217         /** Transfer descriptors */
00218         struct uhci_transfer_descriptor *desc;
00219 
00220         /** I/O buffer */
00221         struct io_buffer *iobuf;
00222 };
00223 
00224 /** Number of transfer descriptors in a ring
00225  *
00226  * This is a policy decision.
00227  */
00228 #define UHCI_RING_COUNT 16
00229 
00230 /** A transfer ring */
00231 struct uhci_ring {
00232         /** Producer counter */
00233         unsigned int prod;
00234         /** Consumer counter */
00235         unsigned int cons;
00236 
00237         /** Maximum packet length */
00238         size_t mtu;
00239         /** Base flags
00240          *
00241          * This incorporates the CERR and LS bits
00242          */
00243         uint8_t flags;
00244         /** Base control word
00245          *
00246          * This incorporates the device address, the endpoint address,
00247          * and the data toggle for the next descriptor to be enqueued.
00248          */
00249         uint32_t control;
00250 
00251         /** Transfers */
00252         struct uhci_transfer *xfer[UHCI_RING_COUNT];
00253         /** End of transfer ring (if non-empty) */
00254         struct uhci_transfer *end;
00255 
00256         /** Queue head */
00257         struct uhci_queue_head *head;
00258 };
00259 
00260 /**
00261  * Calculate space used in transfer ring
00262  *
00263  * @v ring              Transfer ring
00264  * @ret fill            Number of entries used
00265  */
00266 static inline __attribute__ (( always_inline )) unsigned int
00267 uhci_ring_fill ( struct uhci_ring *ring ) {
00268         unsigned int fill;
00269 
00270         fill = ( ring->prod - ring->cons );
00271         assert ( fill <= UHCI_RING_COUNT );
00272         return fill;
00273 }
00274 
00275 /**
00276  * Calculate space remaining in transfer ring
00277  *
00278  * @v ring              Transfer ring
00279  * @ret remaining       Number of entries remaining
00280  */
00281 static inline __attribute__ (( always_inline )) unsigned int
00282 uhci_ring_remaining ( struct uhci_ring *ring ) {
00283         unsigned int fill = uhci_ring_fill ( ring );
00284 
00285         return ( UHCI_RING_COUNT - fill );
00286 }
00287 
00288 /** Maximum time to wait for host controller to stop
00289  *
00290  * This is a policy decision.
00291  */
00292 #define UHCI_STOP_MAX_WAIT_MS 100
00293 
00294 /** Maximum time to wait for reset to complete
00295  *
00296  * This is a policy decision.
00297  */
00298 #define UHCI_RESET_MAX_WAIT_MS 500
00299 
00300 /** Maximum time to wait for a port to be enabled
00301  *
00302  * This is a policy decision.
00303  */
00304 #define UHCI_PORT_ENABLE_MAX_WAIT_MS 500
00305 
00306 /** A UHCI device */
00307 struct uhci_device {
00308         /** Registers */
00309         unsigned long regs;
00310         /** Name */
00311         const char *name;
00312 
00313         /** EHCI companion controller bus:dev.fn address (if any) */
00314         unsigned int companion;
00315 
00316         /** Asynchronous queue head */
00317         struct uhci_queue_head *head;
00318         /** Frame list */
00319         struct uhci_frame_list *frame;
00320 
00321         /** List of all endpoints */
00322         struct list_head endpoints;
00323         /** Asynchronous schedule */
00324         struct list_head async;
00325         /** Periodic schedule
00326          *
00327          * Listed in decreasing order of endpoint interval.
00328          */
00329         struct list_head periodic;
00330 
00331         /** USB bus */
00332         struct usb_bus *bus;
00333 };
00334 
00335 /** A UHCI endpoint */
00336 struct uhci_endpoint {
00337         /** UHCI device */
00338         struct uhci_device *uhci;
00339         /** USB endpoint */
00340         struct usb_endpoint *ep;
00341         /** List of all endpoints */
00342         struct list_head list;
00343         /** Endpoint schedule */
00344         struct list_head schedule;
00345 
00346         /** Transfer ring */
00347         struct uhci_ring ring;
00348 };
00349 
00350 #endif /* _IPXE_UHCI_H */