|  | @@ -0,0 +1,516 @@
 | 
		
	
		
			
			|  | 1 | +#ifndef _IPXE_EHCI_H
 | 
		
	
		
			
			|  | 2 | +#define _IPXE_EHCI_H
 | 
		
	
		
			
			|  | 3 | +
 | 
		
	
		
			
			|  | 4 | +/** @file
 | 
		
	
		
			
			|  | 5 | + *
 | 
		
	
		
			
			|  | 6 | + * USB Enhanced Host Controller Interface (EHCI) driver
 | 
		
	
		
			
			|  | 7 | + *
 | 
		
	
		
			
			|  | 8 | + */
 | 
		
	
		
			
			|  | 9 | +
 | 
		
	
		
			
			|  | 10 | +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
		
	
		
			
			|  | 11 | +
 | 
		
	
		
			
			|  | 12 | +#include <ipxe/pci.h>
 | 
		
	
		
			
			|  | 13 | +#include <ipxe/usb.h>
 | 
		
	
		
			
			|  | 14 | +
 | 
		
	
		
			
			|  | 15 | +/** Minimum alignment required for data structures
 | 
		
	
		
			
			|  | 16 | + *
 | 
		
	
		
			
			|  | 17 | + * With the exception of the periodic frame list (which is
 | 
		
	
		
			
			|  | 18 | + * page-aligned), data structures used by EHCI generally require
 | 
		
	
		
			
			|  | 19 | + * 32-byte alignment and must not cross a 4kB page boundary.  We
 | 
		
	
		
			
			|  | 20 | + * simplify this requirement by aligning each structure on its own
 | 
		
	
		
			
			|  | 21 | + * size, with a minimum of a 32 byte alignment.
 | 
		
	
		
			
			|  | 22 | + */
 | 
		
	
		
			
			|  | 23 | +#define EHCI_MIN_ALIGN 32
 | 
		
	
		
			
			|  | 24 | +
 | 
		
	
		
			
			|  | 25 | +/** Maximum transfer size
 | 
		
	
		
			
			|  | 26 | + *
 | 
		
	
		
			
			|  | 27 | + * EHCI allows for transfers of up to 20kB with page-alignment, or
 | 
		
	
		
			
			|  | 28 | + * 16kB with arbitrary alignment.
 | 
		
	
		
			
			|  | 29 | + */
 | 
		
	
		
			
			|  | 30 | +#define EHCI_MTU 16384
 | 
		
	
		
			
			|  | 31 | +
 | 
		
	
		
			
			|  | 32 | +/** Page-alignment required for some data structures */
 | 
		
	
		
			
			|  | 33 | +#define EHCI_PAGE_ALIGN 4096
 | 
		
	
		
			
			|  | 34 | +
 | 
		
	
		
			
			|  | 35 | +/** EHCI PCI BAR */
 | 
		
	
		
			
			|  | 36 | +#define EHCI_BAR PCI_BASE_ADDRESS_0
 | 
		
	
		
			
			|  | 37 | +
 | 
		
	
		
			
			|  | 38 | +/** Capability register length */
 | 
		
	
		
			
			|  | 39 | +#define EHCI_CAP_CAPLENGTH 0x00
 | 
		
	
		
			
			|  | 40 | +
 | 
		
	
		
			
			|  | 41 | +/** Host controller interface version number */
 | 
		
	
		
			
			|  | 42 | +#define EHCI_CAP_HCIVERSION 0x02
 | 
		
	
		
			
			|  | 43 | +
 | 
		
	
		
			
			|  | 44 | +/** Structural parameters */
 | 
		
	
		
			
			|  | 45 | +#define EHCI_CAP_HCSPARAMS 0x04
 | 
		
	
		
			
			|  | 46 | +
 | 
		
	
		
			
			|  | 47 | +/** Number of ports */
 | 
		
	
		
			
			|  | 48 | +#define EHCI_HCSPARAMS_PORTS(params) ( ( (params) >> 0 ) & 0x0f )
 | 
		
	
		
			
			|  | 49 | +
 | 
		
	
		
			
			|  | 50 | +/** Capability parameters */
 | 
		
	
		
			
			|  | 51 | +#define EHCI_CAP_HCCPARAMS 0x08
 | 
		
	
		
			
			|  | 52 | +
 | 
		
	
		
			
			|  | 53 | +/** 64-bit addressing capability */
 | 
		
	
		
			
			|  | 54 | +#define EHCI_HCCPARAMS_ADDR64(params) ( ( (params) >> 0 ) & 0x1 )
 | 
		
	
		
			
			|  | 55 | +
 | 
		
	
		
			
			|  | 56 | +/** Programmable frame list flag */
 | 
		
	
		
			
			|  | 57 | +#define EHCI_HCCPARAMS_FLSIZE(params) ( ( (params) >> 1 ) & 0x1 )
 | 
		
	
		
			
			|  | 58 | +
 | 
		
	
		
			
			|  | 59 | +/** EHCI extended capabilities pointer */
 | 
		
	
		
			
			|  | 60 | +#define EHCI_HCCPARAMS_EECP(params) ( ( ( (params) >> 8 ) & 0xff ) )
 | 
		
	
		
			
			|  | 61 | +
 | 
		
	
		
			
			|  | 62 | +/** EHCI extended capability ID */
 | 
		
	
		
			
			|  | 63 | +#define EHCI_EECP_ID(eecp) ( ( (eecp) >> 0 ) & 0xff )
 | 
		
	
		
			
			|  | 64 | +
 | 
		
	
		
			
			|  | 65 | +/** Next EHCI extended capability pointer */
 | 
		
	
		
			
			|  | 66 | +#define EHCI_EECP_NEXT(eecp) ( ( ( (eecp) >> 8 ) & 0xff ) )
 | 
		
	
		
			
			|  | 67 | +
 | 
		
	
		
			
			|  | 68 | +/** USB legacy support extended capability */
 | 
		
	
		
			
			|  | 69 | +#define EHCI_EECP_ID_LEGACY 1
 | 
		
	
		
			
			|  | 70 | +
 | 
		
	
		
			
			|  | 71 | +/** USB legacy support BIOS owned semaphore */
 | 
		
	
		
			
			|  | 72 | +#define EHCI_USBLEGSUP_BIOS 0x02
 | 
		
	
		
			
			|  | 73 | +
 | 
		
	
		
			
			|  | 74 | +/** USB legacy support BIOS ownership flag */
 | 
		
	
		
			
			|  | 75 | +#define EHCI_USBLEGSUP_BIOS_OWNED 0x01
 | 
		
	
		
			
			|  | 76 | +
 | 
		
	
		
			
			|  | 77 | +/** USB legacy support OS owned semaphore */
 | 
		
	
		
			
			|  | 78 | +#define EHCI_USBLEGSUP_OS 0x03
 | 
		
	
		
			
			|  | 79 | +
 | 
		
	
		
			
			|  | 80 | +/** USB legacy support OS ownership flag */
 | 
		
	
		
			
			|  | 81 | +#define EHCI_USBLEGSUP_OS_OWNED 0x01
 | 
		
	
		
			
			|  | 82 | +
 | 
		
	
		
			
			|  | 83 | +/** USB legacy support control/status */
 | 
		
	
		
			
			|  | 84 | +#define EHCI_USBLEGSUP_CTLSTS 0x04
 | 
		
	
		
			
			|  | 85 | +
 | 
		
	
		
			
			|  | 86 | +/** USB command register */
 | 
		
	
		
			
			|  | 87 | +#define EHCI_OP_USBCMD 0x00
 | 
		
	
		
			
			|  | 88 | +
 | 
		
	
		
			
			|  | 89 | +/** Run/stop */
 | 
		
	
		
			
			|  | 90 | +#define EHCI_USBCMD_RUN 0x00000001UL
 | 
		
	
		
			
			|  | 91 | +
 | 
		
	
		
			
			|  | 92 | +/** Host controller reset */
 | 
		
	
		
			
			|  | 93 | +#define EHCI_USBCMD_HCRST 0x00000002UL
 | 
		
	
		
			
			|  | 94 | +
 | 
		
	
		
			
			|  | 95 | +/** Frame list size */
 | 
		
	
		
			
			|  | 96 | +#define EHCI_USBCMD_FLSIZE(flsize) ( (flsize) << 2 )
 | 
		
	
		
			
			|  | 97 | +
 | 
		
	
		
			
			|  | 98 | +/** Frame list size mask */
 | 
		
	
		
			
			|  | 99 | +#define EHCI_USBCMD_FLSIZE_MASK EHCI_USBCMD_FLSIZE ( 3 )
 | 
		
	
		
			
			|  | 100 | +
 | 
		
	
		
			
			|  | 101 | +/** Default frame list size */
 | 
		
	
		
			
			|  | 102 | +#define EHCI_FLSIZE_DEFAULT 0
 | 
		
	
		
			
			|  | 103 | +
 | 
		
	
		
			
			|  | 104 | +/** Smallest allowed frame list size */
 | 
		
	
		
			
			|  | 105 | +#define EHCI_FLSIZE_SMALL 2
 | 
		
	
		
			
			|  | 106 | +
 | 
		
	
		
			
			|  | 107 | +/** Number of elements in frame list */
 | 
		
	
		
			
			|  | 108 | +#define EHCI_PERIODIC_FRAMES(flsize) ( 1024 >> (flsize) )
 | 
		
	
		
			
			|  | 109 | +
 | 
		
	
		
			
			|  | 110 | +/** Periodic schedule enable */
 | 
		
	
		
			
			|  | 111 | +#define EHCI_USBCMD_PERIODIC 0x00000010UL
 | 
		
	
		
			
			|  | 112 | +
 | 
		
	
		
			
			|  | 113 | +/** Asynchronous schedule enable */
 | 
		
	
		
			
			|  | 114 | +#define EHCI_USBCMD_ASYNC 0x00000020UL
 | 
		
	
		
			
			|  | 115 | +
 | 
		
	
		
			
			|  | 116 | +/** Asyncchronous schedule advance doorbell */
 | 
		
	
		
			
			|  | 117 | +#define EHCI_USBCMD_ASYNC_ADVANCE 0x000040UL
 | 
		
	
		
			
			|  | 118 | +
 | 
		
	
		
			
			|  | 119 | +/** USB status register */
 | 
		
	
		
			
			|  | 120 | +#define EHCI_OP_USBSTS 0x04
 | 
		
	
		
			
			|  | 121 | +
 | 
		
	
		
			
			|  | 122 | +/** USB interrupt */
 | 
		
	
		
			
			|  | 123 | +#define EHCI_USBSTS_USBINT 0x00000001UL
 | 
		
	
		
			
			|  | 124 | +
 | 
		
	
		
			
			|  | 125 | +/** USB error interrupt */
 | 
		
	
		
			
			|  | 126 | +#define EHCI_USBSTS_USBERRINT 0x00000002UL
 | 
		
	
		
			
			|  | 127 | +
 | 
		
	
		
			
			|  | 128 | +/** Port change detect */
 | 
		
	
		
			
			|  | 129 | +#define EHCI_USBSTS_PORT 0x00000004UL
 | 
		
	
		
			
			|  | 130 | +
 | 
		
	
		
			
			|  | 131 | +/** Frame list rollover */
 | 
		
	
		
			
			|  | 132 | +#define EHCI_USBSTS_ROLLOVER 0x00000008UL
 | 
		
	
		
			
			|  | 133 | +
 | 
		
	
		
			
			|  | 134 | +/** Host system error */
 | 
		
	
		
			
			|  | 135 | +#define EHCI_USBSTS_SYSERR 0x00000010UL
 | 
		
	
		
			
			|  | 136 | +
 | 
		
	
		
			
			|  | 137 | +/** Asynchronous schedule advanced */
 | 
		
	
		
			
			|  | 138 | +#define EHCI_USBSTS_ASYNC_ADVANCE 0x00000020UL
 | 
		
	
		
			
			|  | 139 | +
 | 
		
	
		
			
			|  | 140 | +/** Periodic schedule enabled */
 | 
		
	
		
			
			|  | 141 | +#define EHCI_USBSTS_PERIODIC 0x00004000UL
 | 
		
	
		
			
			|  | 142 | +
 | 
		
	
		
			
			|  | 143 | +/** Asynchronous schedule enabled */
 | 
		
	
		
			
			|  | 144 | +#define EHCI_USBSTS_ASYNC 0x00008000UL
 | 
		
	
		
			
			|  | 145 | +
 | 
		
	
		
			
			|  | 146 | +/** Host controller halted */
 | 
		
	
		
			
			|  | 147 | +#define EHCI_USBSTS_HCH 0x00001000UL
 | 
		
	
		
			
			|  | 148 | +
 | 
		
	
		
			
			|  | 149 | +/** USB status change mask */
 | 
		
	
		
			
			|  | 150 | +#define EHCI_USBSTS_CHANGE						\
 | 
		
	
		
			
			|  | 151 | +	( EHCI_USBSTS_USBINT | EHCI_USBSTS_USBERRINT |			\
 | 
		
	
		
			
			|  | 152 | +	  EHCI_USBSTS_PORT | EHCI_USBSTS_ROLLOVER |			\
 | 
		
	
		
			
			|  | 153 | +	  EHCI_USBSTS_SYSERR | EHCI_USBSTS_ASYNC_ADVANCE )
 | 
		
	
		
			
			|  | 154 | +
 | 
		
	
		
			
			|  | 155 | +/** USB interrupt enable register */
 | 
		
	
		
			
			|  | 156 | +#define EHCI_OP_USBINTR 0x08
 | 
		
	
		
			
			|  | 157 | +
 | 
		
	
		
			
			|  | 158 | +/** Frame index register */
 | 
		
	
		
			
			|  | 159 | +#define EHCI_OP_FRINDEX 0x0c
 | 
		
	
		
			
			|  | 160 | +
 | 
		
	
		
			
			|  | 161 | +/** Control data structure segment register */
 | 
		
	
		
			
			|  | 162 | +#define EHCI_OP_CTRLDSSEGMENT 0x10
 | 
		
	
		
			
			|  | 163 | +
 | 
		
	
		
			
			|  | 164 | +/** Periodic frame list base address register */
 | 
		
	
		
			
			|  | 165 | +#define EHCI_OP_PERIODICLISTBASE 0x14
 | 
		
	
		
			
			|  | 166 | +
 | 
		
	
		
			
			|  | 167 | +/** Current asynchronous list address register */
 | 
		
	
		
			
			|  | 168 | +#define EHCI_OP_ASYNCLISTADDR 0x18
 | 
		
	
		
			
			|  | 169 | +
 | 
		
	
		
			
			|  | 170 | +/** Configure flag register */
 | 
		
	
		
			
			|  | 171 | +#define EHCI_OP_CONFIGFLAG 0x40
 | 
		
	
		
			
			|  | 172 | +
 | 
		
	
		
			
			|  | 173 | +/** Configure flag */
 | 
		
	
		
			
			|  | 174 | +#define EHCI_CONFIGFLAG_CF 0x00000001UL
 | 
		
	
		
			
			|  | 175 | +
 | 
		
	
		
			
			|  | 176 | +/** Port status and control register */
 | 
		
	
		
			
			|  | 177 | +#define EHCI_OP_PORTSC(port) ( 0x40 + ( (port) << 2 ) )
 | 
		
	
		
			
			|  | 178 | +
 | 
		
	
		
			
			|  | 179 | +/** Current connect status */
 | 
		
	
		
			
			|  | 180 | +#define EHCI_PORTSC_CCS 0x00000001UL
 | 
		
	
		
			
			|  | 181 | +
 | 
		
	
		
			
			|  | 182 | +/** Connect status change */
 | 
		
	
		
			
			|  | 183 | +#define EHCI_PORTSC_CSC 0x00000002UL
 | 
		
	
		
			
			|  | 184 | +
 | 
		
	
		
			
			|  | 185 | +/** Port enabled */
 | 
		
	
		
			
			|  | 186 | +#define EHCI_PORTSC_PED 0x00000004UL
 | 
		
	
		
			
			|  | 187 | +
 | 
		
	
		
			
			|  | 188 | +/** Port enabled/disabled change */
 | 
		
	
		
			
			|  | 189 | +#define EHCI_PORTSC_PEC 0x00000008UL
 | 
		
	
		
			
			|  | 190 | +
 | 
		
	
		
			
			|  | 191 | +/** Over-current change */
 | 
		
	
		
			
			|  | 192 | +#define EHCI_PORTSC_OCC 0x00000020UL
 | 
		
	
		
			
			|  | 193 | +
 | 
		
	
		
			
			|  | 194 | +/** Port reset */
 | 
		
	
		
			
			|  | 195 | +#define EHCI_PORTSC_PR 0x00000100UL
 | 
		
	
		
			
			|  | 196 | +
 | 
		
	
		
			
			|  | 197 | +/** Line status */
 | 
		
	
		
			
			|  | 198 | +#define EHCI_PORTSC_LINE_STATUS(portsc) ( ( (portsc) >> 10 ) & 0x3 )
 | 
		
	
		
			
			|  | 199 | +
 | 
		
	
		
			
			|  | 200 | +/** Line status: low-speed device */
 | 
		
	
		
			
			|  | 201 | +#define EHCI_PORTSC_LINE_STATUS_LOW 0x1
 | 
		
	
		
			
			|  | 202 | +
 | 
		
	
		
			
			|  | 203 | +/** Port power */
 | 
		
	
		
			
			|  | 204 | +#define EHCI_PORTSC_PP 0x00001000UL
 | 
		
	
		
			
			|  | 205 | +
 | 
		
	
		
			
			|  | 206 | +/** Port owner */
 | 
		
	
		
			
			|  | 207 | +#define EHCI_PORTSC_OWNER 0x00002000UL
 | 
		
	
		
			
			|  | 208 | +
 | 
		
	
		
			
			|  | 209 | +/** Port status change mask */
 | 
		
	
		
			
			|  | 210 | +#define EHCI_PORTSC_CHANGE \
 | 
		
	
		
			
			|  | 211 | +	( EHCI_PORTSC_CSC | EHCI_PORTSC_PEC | EHCI_PORTSC_OCC )
 | 
		
	
		
			
			|  | 212 | +
 | 
		
	
		
			
			|  | 213 | +/** List terminator */
 | 
		
	
		
			
			|  | 214 | +#define EHCI_LINK_TERMINATE 0x00000001UL
 | 
		
	
		
			
			|  | 215 | +
 | 
		
	
		
			
			|  | 216 | +/** Frame list type */
 | 
		
	
		
			
			|  | 217 | +#define EHCI_LINK_TYPE(type) ( (type) << 1 )
 | 
		
	
		
			
			|  | 218 | +
 | 
		
	
		
			
			|  | 219 | +/** Queue head type */
 | 
		
	
		
			
			|  | 220 | +#define EHCI_LINK_TYPE_QH EHCI_LINK_TYPE ( 1 )
 | 
		
	
		
			
			|  | 221 | +
 | 
		
	
		
			
			|  | 222 | +/** A periodic frame list entry */
 | 
		
	
		
			
			|  | 223 | +struct ehci_periodic_frame {
 | 
		
	
		
			
			|  | 224 | +	/** First queue head */
 | 
		
	
		
			
			|  | 225 | +	uint32_t link;
 | 
		
	
		
			
			|  | 226 | +} __attribute__ (( packed ));
 | 
		
	
		
			
			|  | 227 | +
 | 
		
	
		
			
			|  | 228 | +/** A transfer descriptor */
 | 
		
	
		
			
			|  | 229 | +struct ehci_transfer_descriptor {
 | 
		
	
		
			
			|  | 230 | +	/** Next transfer descriptor */
 | 
		
	
		
			
			|  | 231 | +	uint32_t next;
 | 
		
	
		
			
			|  | 232 | +	/** Alternate next transfer descriptor */
 | 
		
	
		
			
			|  | 233 | +	uint32_t alt;
 | 
		
	
		
			
			|  | 234 | +	/** Status */
 | 
		
	
		
			
			|  | 235 | +	uint8_t status;
 | 
		
	
		
			
			|  | 236 | +	/** Flags */
 | 
		
	
		
			
			|  | 237 | +	uint8_t flags;
 | 
		
	
		
			
			|  | 238 | +	/** Transfer length */
 | 
		
	
		
			
			|  | 239 | +	uint16_t len;
 | 
		
	
		
			
			|  | 240 | +	/** Buffer pointers (low 32 bits) */
 | 
		
	
		
			
			|  | 241 | +	uint32_t low[5];
 | 
		
	
		
			
			|  | 242 | +	/** Extended buffer pointers (high 32 bits) */
 | 
		
	
		
			
			|  | 243 | +	uint32_t high[5];
 | 
		
	
		
			
			|  | 244 | +
 | 
		
	
		
			
			|  | 245 | +	/** Immediate data buffer
 | 
		
	
		
			
			|  | 246 | +	 *
 | 
		
	
		
			
			|  | 247 | +	 * This is not part of the hardware data structure.  Transfer
 | 
		
	
		
			
			|  | 248 | +	 * descriptors must be aligned to a 32-byte boundary.  Create
 | 
		
	
		
			
			|  | 249 | +	 * an array of descriptors therefore requires 12 bytes of
 | 
		
	
		
			
			|  | 250 | +	 * padding at the end of each descriptor.
 | 
		
	
		
			
			|  | 251 | +	 *
 | 
		
	
		
			
			|  | 252 | +	 * We can use this padding as an immediate data buffer (for
 | 
		
	
		
			
			|  | 253 | +	 * setup packets).  This avoids the need for separate
 | 
		
	
		
			
			|  | 254 | +	 * allocations.  As a bonus, there is no need to check this
 | 
		
	
		
			
			|  | 255 | +	 * buffer for reachability, since it is contained within a
 | 
		
	
		
			
			|  | 256 | +	 * transfer descriptor which must already be reachable.
 | 
		
	
		
			
			|  | 257 | +	 */
 | 
		
	
		
			
			|  | 258 | +	uint8_t immediate[12];
 | 
		
	
		
			
			|  | 259 | +} __attribute__ (( packed ));
 | 
		
	
		
			
			|  | 260 | +
 | 
		
	
		
			
			|  | 261 | +/** Transaction error */
 | 
		
	
		
			
			|  | 262 | +#define EHCI_STATUS_XACT_ERR 0x08
 | 
		
	
		
			
			|  | 263 | +
 | 
		
	
		
			
			|  | 264 | +/** Babble detected */
 | 
		
	
		
			
			|  | 265 | +#define EHCI_STATUS_BABBLE 0x10
 | 
		
	
		
			
			|  | 266 | +
 | 
		
	
		
			
			|  | 267 | +/** Data buffer error */
 | 
		
	
		
			
			|  | 268 | +#define EHCI_STATUS_BUFFER 0x20
 | 
		
	
		
			
			|  | 269 | +
 | 
		
	
		
			
			|  | 270 | +/** Halted */
 | 
		
	
		
			
			|  | 271 | +#define EHCI_STATUS_HALTED 0x40
 | 
		
	
		
			
			|  | 272 | +
 | 
		
	
		
			
			|  | 273 | +/** Active */
 | 
		
	
		
			
			|  | 274 | +#define EHCI_STATUS_ACTIVE 0x80
 | 
		
	
		
			
			|  | 275 | +
 | 
		
	
		
			
			|  | 276 | +/** PID code */
 | 
		
	
		
			
			|  | 277 | +#define EHCI_FL_PID(code) ( (code) << 0 )
 | 
		
	
		
			
			|  | 278 | +
 | 
		
	
		
			
			|  | 279 | +/** OUT token */
 | 
		
	
		
			
			|  | 280 | +#define EHCI_FL_PID_OUT EHCI_FL_PID ( 0 )
 | 
		
	
		
			
			|  | 281 | +
 | 
		
	
		
			
			|  | 282 | +/** IN token */
 | 
		
	
		
			
			|  | 283 | +#define EHCI_FL_PID_IN EHCI_FL_PID ( 1 )
 | 
		
	
		
			
			|  | 284 | +
 | 
		
	
		
			
			|  | 285 | +/** SETUP token */
 | 
		
	
		
			
			|  | 286 | +#define EHCI_FL_PID_SETUP EHCI_FL_PID ( 2 )
 | 
		
	
		
			
			|  | 287 | +
 | 
		
	
		
			
			|  | 288 | +/** Interrupt on completion */
 | 
		
	
		
			
			|  | 289 | +#define EHCI_FL_IOC 0x80
 | 
		
	
		
			
			|  | 290 | +
 | 
		
	
		
			
			|  | 291 | +/** Length mask */
 | 
		
	
		
			
			|  | 292 | +#define EHCI_LEN_MASK 0x7fff
 | 
		
	
		
			
			|  | 293 | +
 | 
		
	
		
			
			|  | 294 | +/** Data toggle */
 | 
		
	
		
			
			|  | 295 | +#define EHCI_LEN_TOGGLE 0x8000
 | 
		
	
		
			
			|  | 296 | +
 | 
		
	
		
			
			|  | 297 | +/** A queue head */
 | 
		
	
		
			
			|  | 298 | +struct ehci_queue_head {
 | 
		
	
		
			
			|  | 299 | +	/** Horizontal link pointer */
 | 
		
	
		
			
			|  | 300 | +	uint32_t link;
 | 
		
	
		
			
			|  | 301 | +	/** Endpoint characteristics */
 | 
		
	
		
			
			|  | 302 | +	uint32_t chr;
 | 
		
	
		
			
			|  | 303 | +	/** Endpoint capabilities */
 | 
		
	
		
			
			|  | 304 | +	uint32_t cap;
 | 
		
	
		
			
			|  | 305 | +	/** Current transfer descriptor */
 | 
		
	
		
			
			|  | 306 | +	uint32_t current;
 | 
		
	
		
			
			|  | 307 | +	/** Transfer descriptor cache */
 | 
		
	
		
			
			|  | 308 | +	struct ehci_transfer_descriptor cache;
 | 
		
	
		
			
			|  | 309 | +} __attribute__ (( packed ));
 | 
		
	
		
			
			|  | 310 | +
 | 
		
	
		
			
			|  | 311 | +/** Device address */
 | 
		
	
		
			
			|  | 312 | +#define EHCI_CHR_ADDRESS( address ) ( (address) << 0 )
 | 
		
	
		
			
			|  | 313 | +
 | 
		
	
		
			
			|  | 314 | +/** Endpoint number */
 | 
		
	
		
			
			|  | 315 | +#define EHCI_CHR_ENDPOINT( address ) ( ( (address) & 0xf ) << 8 )
 | 
		
	
		
			
			|  | 316 | +
 | 
		
	
		
			
			|  | 317 | +/** Endpoint speed */
 | 
		
	
		
			
			|  | 318 | +#define EHCI_CHR_EPS( eps ) ( (eps) << 12 )
 | 
		
	
		
			
			|  | 319 | +
 | 
		
	
		
			
			|  | 320 | +/** Full-speed endpoint */
 | 
		
	
		
			
			|  | 321 | +#define EHCI_CHR_EPS_FULL EHCI_CHR_EPS ( 0 )
 | 
		
	
		
			
			|  | 322 | +
 | 
		
	
		
			
			|  | 323 | +/** Low-speed endpoint */
 | 
		
	
		
			
			|  | 324 | +#define EHCI_CHR_EPS_LOW EHCI_CHR_EPS ( 1 )
 | 
		
	
		
			
			|  | 325 | +
 | 
		
	
		
			
			|  | 326 | +/** High-speed endpoint */
 | 
		
	
		
			
			|  | 327 | +#define EHCI_CHR_EPS_HIGH EHCI_CHR_EPS ( 2 )
 | 
		
	
		
			
			|  | 328 | +
 | 
		
	
		
			
			|  | 329 | +/** Explicit data toggles */
 | 
		
	
		
			
			|  | 330 | +#define EHCI_CHR_TOGGLE 0x00004000UL
 | 
		
	
		
			
			|  | 331 | +
 | 
		
	
		
			
			|  | 332 | +/** Head of reclamation list flag */
 | 
		
	
		
			
			|  | 333 | +#define EHCI_CHR_HEAD 0x00008000UL
 | 
		
	
		
			
			|  | 334 | +
 | 
		
	
		
			
			|  | 335 | +/** Maximum packet length */
 | 
		
	
		
			
			|  | 336 | +#define EHCI_CHR_MAX_LEN( len ) ( (len) << 16 )
 | 
		
	
		
			
			|  | 337 | +
 | 
		
	
		
			
			|  | 338 | +/** Control endpoint flag */
 | 
		
	
		
			
			|  | 339 | +#define EHCI_CHR_CONTROL 0x08000000UL
 | 
		
	
		
			
			|  | 340 | +
 | 
		
	
		
			
			|  | 341 | +/** Interrupt schedule mask */
 | 
		
	
		
			
			|  | 342 | +#define EHCI_CAP_INTR_SCHED( uframe ) ( 1 << ( (uframe) + 0 ) )
 | 
		
	
		
			
			|  | 343 | +
 | 
		
	
		
			
			|  | 344 | +/** High-bandwidth pipe multiplier */
 | 
		
	
		
			
			|  | 345 | +#define EHCI_CAP_MULT( mult ) ( (mult) << 30 )
 | 
		
	
		
			
			|  | 346 | +
 | 
		
	
		
			
			|  | 347 | +/** A transfer descriptor ring */
 | 
		
	
		
			
			|  | 348 | +struct ehci_ring {
 | 
		
	
		
			
			|  | 349 | +	/** Producer counter */
 | 
		
	
		
			
			|  | 350 | +	unsigned int prod;
 | 
		
	
		
			
			|  | 351 | +	/** Consumer counter */
 | 
		
	
		
			
			|  | 352 | +	unsigned int cons;
 | 
		
	
		
			
			|  | 353 | +
 | 
		
	
		
			
			|  | 354 | +	/** Residual untransferred data */
 | 
		
	
		
			
			|  | 355 | +	size_t residual;
 | 
		
	
		
			
			|  | 356 | +
 | 
		
	
		
			
			|  | 357 | +	/** I/O buffers */
 | 
		
	
		
			
			|  | 358 | +	struct io_buffer **iobuf;
 | 
		
	
		
			
			|  | 359 | +
 | 
		
	
		
			
			|  | 360 | +	/** Queue head */
 | 
		
	
		
			
			|  | 361 | +	struct ehci_queue_head *head;
 | 
		
	
		
			
			|  | 362 | +	/** Transfer descriptors */
 | 
		
	
		
			
			|  | 363 | +	struct ehci_transfer_descriptor *desc;
 | 
		
	
		
			
			|  | 364 | +};
 | 
		
	
		
			
			|  | 365 | +
 | 
		
	
		
			
			|  | 366 | +/** Number of transfer descriptors in a ring
 | 
		
	
		
			
			|  | 367 | + *
 | 
		
	
		
			
			|  | 368 | + * This is a policy decision.
 | 
		
	
		
			
			|  | 369 | + */
 | 
		
	
		
			
			|  | 370 | +#define EHCI_RING_COUNT 64
 | 
		
	
		
			
			|  | 371 | +
 | 
		
	
		
			
			|  | 372 | +/**
 | 
		
	
		
			
			|  | 373 | + * Calculate space used in transfer descriptor ring
 | 
		
	
		
			
			|  | 374 | + *
 | 
		
	
		
			
			|  | 375 | + * @v ring		Transfer descriptor ring
 | 
		
	
		
			
			|  | 376 | + * @ret fill		Number of entries used
 | 
		
	
		
			
			|  | 377 | + */
 | 
		
	
		
			
			|  | 378 | +static inline __attribute__ (( always_inline )) unsigned int
 | 
		
	
		
			
			|  | 379 | +ehci_ring_fill ( struct ehci_ring *ring ) {
 | 
		
	
		
			
			|  | 380 | +	unsigned int fill;
 | 
		
	
		
			
			|  | 381 | +
 | 
		
	
		
			
			|  | 382 | +	fill = ( ring->prod - ring->cons );
 | 
		
	
		
			
			|  | 383 | +	assert ( fill <= EHCI_RING_COUNT );
 | 
		
	
		
			
			|  | 384 | +	return fill;
 | 
		
	
		
			
			|  | 385 | +}
 | 
		
	
		
			
			|  | 386 | +
 | 
		
	
		
			
			|  | 387 | +/**
 | 
		
	
		
			
			|  | 388 | + * Calculate space remaining in transfer descriptor ring
 | 
		
	
		
			
			|  | 389 | + *
 | 
		
	
		
			
			|  | 390 | + * @v ring		Transfer descriptor ring
 | 
		
	
		
			
			|  | 391 | + * @ret remaining	Number of entries remaining
 | 
		
	
		
			
			|  | 392 | + */
 | 
		
	
		
			
			|  | 393 | +static inline __attribute__ (( always_inline )) unsigned int
 | 
		
	
		
			
			|  | 394 | +ehci_ring_remaining ( struct ehci_ring *ring ) {
 | 
		
	
		
			
			|  | 395 | +	unsigned int fill = ehci_ring_fill ( ring );
 | 
		
	
		
			
			|  | 396 | +
 | 
		
	
		
			
			|  | 397 | +	return ( EHCI_RING_COUNT - fill );
 | 
		
	
		
			
			|  | 398 | +}
 | 
		
	
		
			
			|  | 399 | +
 | 
		
	
		
			
			|  | 400 | +/** Time to delay after enabling power to a port
 | 
		
	
		
			
			|  | 401 | + *
 | 
		
	
		
			
			|  | 402 | + * This is not mandated by EHCI; we use the value given for xHCI.
 | 
		
	
		
			
			|  | 403 | + */
 | 
		
	
		
			
			|  | 404 | +#define EHCI_PORT_POWER_DELAY_MS 20
 | 
		
	
		
			
			|  | 405 | +
 | 
		
	
		
			
			|  | 406 | +/** Maximum time to wait for BIOS to release ownership
 | 
		
	
		
			
			|  | 407 | + *
 | 
		
	
		
			
			|  | 408 | + * This is a policy decision.
 | 
		
	
		
			
			|  | 409 | + */
 | 
		
	
		
			
			|  | 410 | +#define EHCI_USBLEGSUP_MAX_WAIT_MS 100
 | 
		
	
		
			
			|  | 411 | +
 | 
		
	
		
			
			|  | 412 | +/** Maximum time to wait for asynchronous schedule to advance
 | 
		
	
		
			
			|  | 413 | + *
 | 
		
	
		
			
			|  | 414 | + * This is a policy decision.
 | 
		
	
		
			
			|  | 415 | + */
 | 
		
	
		
			
			|  | 416 | +#define EHCI_ASYNC_ADVANCE_MAX_WAIT_MS 100
 | 
		
	
		
			
			|  | 417 | +
 | 
		
	
		
			
			|  | 418 | +/** Maximum time to wait for host controller to stop
 | 
		
	
		
			
			|  | 419 | + *
 | 
		
	
		
			
			|  | 420 | + * This is a policy decision.
 | 
		
	
		
			
			|  | 421 | + */
 | 
		
	
		
			
			|  | 422 | +#define EHCI_STOP_MAX_WAIT_MS 100
 | 
		
	
		
			
			|  | 423 | +
 | 
		
	
		
			
			|  | 424 | +/** Maximum time to wait for reset to complete
 | 
		
	
		
			
			|  | 425 | + *
 | 
		
	
		
			
			|  | 426 | + * This is a policy decision.
 | 
		
	
		
			
			|  | 427 | + */
 | 
		
	
		
			
			|  | 428 | +#define EHCI_RESET_MAX_WAIT_MS 500
 | 
		
	
		
			
			|  | 429 | +
 | 
		
	
		
			
			|  | 430 | +/** Maximum time to wait for a port reset to complete
 | 
		
	
		
			
			|  | 431 | + *
 | 
		
	
		
			
			|  | 432 | + * This is a policy decision.
 | 
		
	
		
			
			|  | 433 | + */
 | 
		
	
		
			
			|  | 434 | +#define EHCI_PORT_RESET_MAX_WAIT_MS 500
 | 
		
	
		
			
			|  | 435 | +
 | 
		
	
		
			
			|  | 436 | +/** An EHCI transfer */
 | 
		
	
		
			
			|  | 437 | +struct ehci_transfer {
 | 
		
	
		
			
			|  | 438 | +	/** Data buffer */
 | 
		
	
		
			
			|  | 439 | +	void *data;
 | 
		
	
		
			
			|  | 440 | +	/** Length */
 | 
		
	
		
			
			|  | 441 | +	size_t len;
 | 
		
	
		
			
			|  | 442 | +	/** Flags
 | 
		
	
		
			
			|  | 443 | +	 *
 | 
		
	
		
			
			|  | 444 | +	 * This is the bitwise OR of zero or more EHCI_FL_XXX values.
 | 
		
	
		
			
			|  | 445 | +	 * The low 8 bits are copied to the flags byte within the
 | 
		
	
		
			
			|  | 446 | +	 * transfer descriptor; the remaining bits hold flags
 | 
		
	
		
			
			|  | 447 | +	 * meaningful only to our driver code.
 | 
		
	
		
			
			|  | 448 | +	 */
 | 
		
	
		
			
			|  | 449 | +	unsigned int flags;
 | 
		
	
		
			
			|  | 450 | +};
 | 
		
	
		
			
			|  | 451 | +
 | 
		
	
		
			
			|  | 452 | +/** Copy data to immediate data buffer */
 | 
		
	
		
			
			|  | 453 | +#define EHCI_FL_IMMEDIATE 0x0100
 | 
		
	
		
			
			|  | 454 | +
 | 
		
	
		
			
			|  | 455 | +/** Set initial data toggle */
 | 
		
	
		
			
			|  | 456 | +#define EHCI_FL_TOGGLE 0x8000
 | 
		
	
		
			
			|  | 457 | +
 | 
		
	
		
			
			|  | 458 | +/** An EHCI device */
 | 
		
	
		
			
			|  | 459 | +struct ehci_device {
 | 
		
	
		
			
			|  | 460 | +	/** Registers */
 | 
		
	
		
			
			|  | 461 | +	void *regs;
 | 
		
	
		
			
			|  | 462 | +
 | 
		
	
		
			
			|  | 463 | +	/** Capability registers */
 | 
		
	
		
			
			|  | 464 | +	void *cap;
 | 
		
	
		
			
			|  | 465 | +	/** Operational registers */
 | 
		
	
		
			
			|  | 466 | +	void *op;
 | 
		
	
		
			
			|  | 467 | +
 | 
		
	
		
			
			|  | 468 | +	/** Number of ports */
 | 
		
	
		
			
			|  | 469 | +	unsigned int ports;
 | 
		
	
		
			
			|  | 470 | +	/** 64-bit addressing capability */
 | 
		
	
		
			
			|  | 471 | +	int addr64;
 | 
		
	
		
			
			|  | 472 | +	/** Frame list size */
 | 
		
	
		
			
			|  | 473 | +	unsigned int flsize;
 | 
		
	
		
			
			|  | 474 | +	/** EHCI extended capabilities offset */
 | 
		
	
		
			
			|  | 475 | +	unsigned int eecp;
 | 
		
	
		
			
			|  | 476 | +
 | 
		
	
		
			
			|  | 477 | +	/** USB legacy support capability (if present and enabled) */
 | 
		
	
		
			
			|  | 478 | +	unsigned int legacy;
 | 
		
	
		
			
			|  | 479 | +
 | 
		
	
		
			
			|  | 480 | +	/** Control data structure segment */
 | 
		
	
		
			
			|  | 481 | +	uint32_t ctrldssegment;
 | 
		
	
		
			
			|  | 482 | +	/** Asynchronous queue head */
 | 
		
	
		
			
			|  | 483 | +	struct ehci_queue_head *head;
 | 
		
	
		
			
			|  | 484 | +	/** Periodic frame list */
 | 
		
	
		
			
			|  | 485 | +	struct ehci_periodic_frame *frame;
 | 
		
	
		
			
			|  | 486 | +
 | 
		
	
		
			
			|  | 487 | +	/** List of all endpoints */
 | 
		
	
		
			
			|  | 488 | +	struct list_head endpoints;
 | 
		
	
		
			
			|  | 489 | +	/** Asynchronous schedule */
 | 
		
	
		
			
			|  | 490 | +	struct list_head async;
 | 
		
	
		
			
			|  | 491 | +	/** Periodic schedule
 | 
		
	
		
			
			|  | 492 | +	 *
 | 
		
	
		
			
			|  | 493 | +	 * Listed in decreasing order of endpoint interval.
 | 
		
	
		
			
			|  | 494 | +	 */
 | 
		
	
		
			
			|  | 495 | +	struct list_head periodic;
 | 
		
	
		
			
			|  | 496 | +
 | 
		
	
		
			
			|  | 497 | +	/** USB bus */
 | 
		
	
		
			
			|  | 498 | +	struct usb_bus *bus;
 | 
		
	
		
			
			|  | 499 | +};
 | 
		
	
		
			
			|  | 500 | +
 | 
		
	
		
			
			|  | 501 | +/** An EHCI endpoint */
 | 
		
	
		
			
			|  | 502 | +struct ehci_endpoint {
 | 
		
	
		
			
			|  | 503 | +	/** EHCI device */
 | 
		
	
		
			
			|  | 504 | +	struct ehci_device *ehci;
 | 
		
	
		
			
			|  | 505 | +	/** USB endpoint */
 | 
		
	
		
			
			|  | 506 | +	struct usb_endpoint *ep;
 | 
		
	
		
			
			|  | 507 | +	/** List of all endpoints */
 | 
		
	
		
			
			|  | 508 | +	struct list_head list;
 | 
		
	
		
			
			|  | 509 | +	/** Endpoint schedule */
 | 
		
	
		
			
			|  | 510 | +	struct list_head schedule;
 | 
		
	
		
			
			|  | 511 | +
 | 
		
	
		
			
			|  | 512 | +	/** Transfer descriptor ring */
 | 
		
	
		
			
			|  | 513 | +	struct ehci_ring ring;
 | 
		
	
		
			
			|  | 514 | +};
 | 
		
	
		
			
			|  | 515 | +
 | 
		
	
		
			
			|  | 516 | +#endif /* _IPXE_EHCI_H */
 |