123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413 |
- #ifndef _IPXE_USB_H
- #define _IPXE_USB_H
-
- /** @file
- *
- * Universal Serial Bus (USB)
- *
- */
-
- FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
- #include <byteswap.h>
- #include <ipxe/list.h>
- #include <ipxe/device.h>
- #include <ipxe/process.h>
- #include <ipxe/iobuf.h>
- #include <ipxe/tables.h>
-
- /** USB protocols */
- enum usb_protocol {
- /** USB 2.0 */
- USB_PROTO_2_0 = 0x0200,
- /** USB 3.0 */
- USB_PROTO_3_0 = 0x0300,
- /** USB 3.1 */
- USB_PROTO_3_1 = 0x0301,
- };
-
- /** Define a USB speed
- *
- * @v mantissa Mantissa
- * @v exponent Exponent (in engineering terms: 1=k, 2=M, 3=G)
- * @ret speed USB speed
- */
- #define USB_SPEED( mantissa, exponent ) ( (exponent << 16) | (mantissa) )
-
- /** Extract USB speed mantissa */
- #define USB_SPEED_MANTISSA(speed) ( (speed) & 0xffff )
-
- /** Extract USB speed exponent */
- #define USB_SPEED_EXPONENT(speed) ( ( (speed) >> 16 ) & 0x3 )
-
- /** USB device speeds */
- enum usb_speed {
- /** Not connected */
- USB_SPEED_NONE = 0,
- /** Low speed (1.5Mbps) */
- USB_SPEED_LOW = USB_SPEED ( 1500, 1 ),
- /** Full speed (12Mbps) */
- USB_SPEED_FULL = USB_SPEED ( 12, 2 ),
- /** High speed (480Mbps) */
- USB_SPEED_HIGH = USB_SPEED ( 480, 2 ),
- /** Super speed (5Gbps) */
- USB_SPEED_SUPER = USB_SPEED ( 5, 3 ),
- };
-
- /** USB packet IDs */
- enum usb_pid {
- /** IN PID */
- USB_PID_IN = 0x69,
- /** OUT PID */
- USB_PID_OUT = 0xe1,
- /** SETUP PID */
- USB_PID_SETUP = 0x2d,
- };
-
- /** A USB setup data packet */
- struct usb_setup_packet {
- /** Request */
- uint16_t request;
- /** Value parameter */
- uint16_t value;
- /** Index parameter */
- uint16_t index;
- /** Length of data stage */
- uint16_t len;
- } __attribute__ (( packed ));
-
- /** Data transfer is from host to device */
- #define USB_DIR_OUT ( 0 << 7 )
-
- /** Data transfer is from device to host */
- #define USB_DIR_IN ( 1 << 7 )
-
- /** Standard request type */
- #define USB_TYPE_STANDARD ( 0 << 5 )
-
- /** Class-specific request type */
- #define USB_TYPE_CLASS ( 1 << 5 )
-
- /** Vendor-specific request type */
- #define USB_TYPE_VENDOR ( 2 << 5 )
-
- /** Request recipient mask */
- #define USB_RECIP_MASK ( 0x1f << 0 )
-
- /** Request recipient is the device */
- #define USB_RECIP_DEVICE ( 0 << 0 )
-
- /** Request recipient is an interface */
- #define USB_RECIP_INTERFACE ( 1 << 0 )
-
- /** Request recipient is an endpoint */
- #define USB_RECIP_ENDPOINT ( 2 << 0 )
-
- /** Construct USB request type */
- #define USB_REQUEST_TYPE(type) ( (type) << 8 )
-
- /** Get status */
- #define USB_GET_STATUS ( USB_DIR_IN | USB_REQUEST_TYPE ( 0 ) )
-
- /** Clear feature */
- #define USB_CLEAR_FEATURE ( USB_DIR_OUT | USB_REQUEST_TYPE ( 1 ) )
-
- /** Set feature */
- #define USB_SET_FEATURE ( USB_DIR_OUT | USB_REQUEST_TYPE ( 3 ) )
-
- /** Set address */
- #define USB_SET_ADDRESS ( USB_DIR_OUT | USB_REQUEST_TYPE ( 5 ) )
-
- /** Get descriptor */
- #define USB_GET_DESCRIPTOR ( USB_DIR_IN | USB_REQUEST_TYPE ( 6 ) )
-
- /** Set descriptor */
- #define USB_SET_DESCRIPTOR ( USB_DIR_OUT | USB_REQUEST_TYPE ( 7 ) )
-
- /** Get configuration */
- #define USB_GET_CONFIGURATION ( USB_DIR_IN | USB_REQUEST_TYPE ( 8 ) )
-
- /** Set configuration */
- #define USB_SET_CONFIGURATION ( USB_DIR_OUT | USB_REQUEST_TYPE ( 9 ) )
-
- /** Get interface */
- #define USB_GET_INTERFACE \
- ( USB_DIR_IN | USB_RECIP_INTERFACE | USB_REQUEST_TYPE ( 10 ) )
-
- /** Set interface */
- #define USB_SET_INTERFACE \
- ( USB_DIR_OUT | USB_RECIP_INTERFACE | USB_REQUEST_TYPE ( 11 ) )
-
- /** Endpoint halt feature */
- #define USB_ENDPOINT_HALT 0
-
- /** A USB class code tuple */
- struct usb_class {
- /** Class code */
- uint8_t class;
- /** Subclass code */
- uint8_t subclass;
- /** Protocol code */
- uint8_t protocol;
- } __attribute__ (( packed ));
-
- /** Class code for USB hubs */
- #define USB_CLASS_HUB 9
-
- /** A USB descriptor header */
- struct usb_descriptor_header {
- /** Length of descriptor */
- uint8_t len;
- /** Descriptor type */
- uint8_t type;
- } __attribute__ (( packed ));
-
- /** A USB device descriptor */
- struct usb_device_descriptor {
- /** Descriptor header */
- struct usb_descriptor_header header;
- /** USB specification release number in BCD */
- uint16_t protocol;
- /** Device class */
- struct usb_class class;
- /** Maximum packet size for endpoint zero */
- uint8_t mtu;
- /** Vendor ID */
- uint16_t vendor;
- /** Product ID */
- uint16_t product;
- /** Device release number in BCD */
- uint16_t release;
- /** Manufacturer string */
- uint8_t manufacturer;
- /** Product string */
- uint8_t name;
- /** Serial number string */
- uint8_t serial;
- /** Number of possible configurations */
- uint8_t configurations;
- } __attribute__ (( packed ));
-
- /** A USB device descriptor */
- #define USB_DEVICE_DESCRIPTOR 1
-
- /** A USB configuration descriptor */
- struct usb_configuration_descriptor {
- /** Descriptor header */
- struct usb_descriptor_header header;
- /** Total length */
- uint16_t len;
- /** Number of interfaces */
- uint8_t interfaces;
- /** Configuration value */
- uint8_t config;
- /** Configuration string */
- uint8_t name;
- /** Attributes */
- uint8_t attributes;
- /** Maximum power consumption */
- uint8_t power;
- } __attribute__ (( packed ));
-
- /** A USB configuration descriptor */
- #define USB_CONFIGURATION_DESCRIPTOR 2
-
- /** A USB string descriptor */
- struct usb_string_descriptor {
- /** Descriptor header */
- struct usb_descriptor_header header;
- /** String */
- char string[0];
- } __attribute__ (( packed ));
-
- /** A USB string descriptor */
- #define USB_STRING_DESCRIPTOR 3
-
- /** Language ID for English */
- #define USB_LANG_ENGLISH 0x0409
-
- /** A USB interface descriptor */
- struct usb_interface_descriptor {
- /** Descriptor header */
- struct usb_descriptor_header header;
- /** Interface number */
- uint8_t interface;
- /** Alternate setting */
- uint8_t alternate;
- /** Number of endpoints */
- uint8_t endpoints;
- /** Interface class */
- struct usb_class class;
- /** Interface name */
- uint8_t name;
- } __attribute__ (( packed ));
-
- /** A USB interface descriptor */
- #define USB_INTERFACE_DESCRIPTOR 4
-
- /** A USB endpoint descriptor */
- struct usb_endpoint_descriptor {
- /** Descriptor header */
- struct usb_descriptor_header header;
- /** Endpoint address */
- uint8_t endpoint;
- /** Attributes */
- uint8_t attributes;
- /** Maximum packet size and burst size */
- uint16_t sizes;
- /** Polling interval */
- uint8_t interval;
- } __attribute__ (( packed ));
-
- /** A USB endpoint descriptor */
- #define USB_ENDPOINT_DESCRIPTOR 5
-
- /** Endpoint attribute transfer type mask */
- #define USB_ENDPOINT_ATTR_TYPE_MASK 0x03
-
- /** Endpoint periodic type */
- #define USB_ENDPOINT_ATTR_PERIODIC 0x01
-
- /** Control endpoint transfer type */
- #define USB_ENDPOINT_ATTR_CONTROL 0x00
-
- /** Bulk endpoint transfer type */
- #define USB_ENDPOINT_ATTR_BULK 0x02
-
- /** Interrupt endpoint transfer type */
- #define USB_ENDPOINT_ATTR_INTERRUPT 0x03
-
- /** Bulk OUT endpoint (internal) type */
- #define USB_BULK_OUT ( USB_ENDPOINT_ATTR_BULK | USB_DIR_OUT )
-
- /** Bulk IN endpoint (internal) type */
- #define USB_BULK_IN ( USB_ENDPOINT_ATTR_BULK | USB_DIR_IN )
-
- /** Interrupt IN endpoint (internal) type */
- #define USB_INTERRUPT_IN ( USB_ENDPOINT_ATTR_INTERRUPT | USB_DIR_IN )
-
- /** Interrupt OUT endpoint (internal) type */
- #define USB_INTERRUPT_OUT ( USB_ENDPOINT_ATTR_INTERRUPT | USB_DIR_OUT )
-
- /** USB endpoint MTU */
- #define USB_ENDPOINT_MTU(sizes) ( ( (sizes) >> 0 ) & 0x07ff )
-
- /** USB endpoint maximum burst size */
- #define USB_ENDPOINT_BURST(sizes) ( ( (sizes) >> 11 ) & 0x0003 )
-
- /** A USB endpoint companion descriptor */
- struct usb_endpoint_companion_descriptor {
- /** Descriptor header */
- struct usb_descriptor_header header;
- /** Maximum burst size */
- uint8_t burst;
- /** Extended attributes */
- uint8_t extended;
- /** Number of bytes per service interval */
- uint16_t periodic;
- } __attribute__ (( packed ));
-
- /** A USB endpoint companion descriptor */
- #define USB_ENDPOINT_COMPANION_DESCRIPTOR 48
-
- /** A USB interface association descriptor */
- struct usb_interface_association_descriptor {
- /** Descriptor header */
- struct usb_descriptor_header header;
- /** First interface number */
- uint8_t first;
- /** Interface count */
- uint8_t count;
- /** Association class */
- struct usb_class class;
- /** Association name */
- uint8_t name;
- } __attribute__ (( packed ));
-
- /** A USB interface association descriptor */
- #define USB_INTERFACE_ASSOCIATION_DESCRIPTOR 11
-
- /** A class-specific interface descriptor */
- #define USB_CS_INTERFACE_DESCRIPTOR 36
-
- /** A class-specific endpoint descriptor */
- #define USB_CS_ENDPOINT_DESCRIPTOR 37
-
- /**
- * Get next USB descriptor
- *
- * @v desc USB descriptor header
- * @ret next Next USB descriptor header
- */
- static inline __attribute__ (( always_inline )) struct usb_descriptor_header *
- usb_next_descriptor ( struct usb_descriptor_header *desc ) {
-
- return ( ( ( void * ) desc ) + desc->len );
- }
-
- /**
- * Check that descriptor lies within a configuration descriptor
- *
- * @v config Configuration descriptor
- * @v desc Descriptor header
- * @v is_within Descriptor is within the configuration descriptor
- */
- static inline __attribute__ (( always_inline )) int
- usb_is_within_config ( struct usb_configuration_descriptor *config,
- struct usb_descriptor_header *desc ) {
- struct usb_descriptor_header *end =
- ( ( ( void * ) config ) + le16_to_cpu ( config->len ) );
-
- /* Check that descriptor starts within the configuration
- * descriptor, and that the length does not exceed the
- * configuration descriptor. This relies on the fact that
- * usb_next_descriptor() needs to access only the first byte
- * of the descriptor in order to determine the length.
- */
- return ( ( desc < end ) && ( usb_next_descriptor ( desc ) <= end ) );
- }
-
- /** Iterate over all configuration descriptors */
- #define for_each_config_descriptor( desc, config ) \
- for ( desc = container_of ( &(config)->header, \
- typeof ( *desc ), header ) ; \
- usb_is_within_config ( (config), &desc->header ) ; \
- desc = container_of ( usb_next_descriptor ( &desc->header ), \
- typeof ( *desc ), header ) )
-
- /** Iterate over all configuration descriptors within an interface descriptor */
- #define for_each_interface_descriptor( desc, config, interface ) \
- for ( desc = container_of ( usb_next_descriptor ( &(interface)-> \
- header ), \
- typeof ( *desc ), header ) ; \
- ( usb_is_within_config ( (config), &desc->header ) && \
- ( desc->header.type != USB_INTERFACE_DESCRIPTOR ) ) ; \
- desc = container_of ( usb_next_descriptor ( &desc->header ), \
- typeof ( *desc ), header ) )
-
- /** A USB endpoint */
- struct usb_endpoint {
- /** USB device */
- struct usb_device *usb;
- /** Endpoint address */
- unsigned int address;
- /** Attributes */
- unsigned int attributes;
- /** Maximum transfer size */
- size_t mtu;
- /** Maximum burst size */
- unsigned int burst;
- /** Interval (in microframes) */
- unsigned int interval;
-
- /** Endpoint is open */
- int open;
- /** Buffer fill level */
- unsigned int fill;
-
- /** List of halted endpoints */
- struct list_head halted;
-
- /** Host controller operations */
- struct usb_endpoint_host_operations *host;
- /** Host controller private data */
- void *priv;
- /** Driver operations */
- struct usb_endpoint_driver_operations *driver;
-
- /** Recycled I/O buffer list */
- struct list_head recycled;
- /** Refill buffer reserved header length */
- size_t reserve;
- /** Refill buffer payload length */
- size_t len;
- /** Maximum fill level */
- unsigned int max;
- };
-
- /** USB endpoint host controller operations */
- struct usb_endpoint_host_operations {
- /** Open endpoint
- *
- * @v ep USB endpoint
- * @ret rc Return status code
- */
- int ( * open ) ( struct usb_endpoint *ep );
- /** Close endpoint
- *
- * @v ep USB endpoint
- */
- void ( * close ) ( struct usb_endpoint *ep );
- /**
- * Reset endpoint
- *
- * @v ep USB endpoint
- * @ret rc Return status code
- */
- int ( * reset ) ( struct usb_endpoint *ep );
- /** Update MTU
- *
- * @v ep USB endpoint
- * @ret rc Return status code
- */
- int ( * mtu ) ( struct usb_endpoint *ep );
- /** Enqueue message transfer
- *
- * @v ep USB endpoint
- * @v iobuf I/O buffer
- * @ret rc Return status code
- */
- int ( * message ) ( struct usb_endpoint *ep,
- struct io_buffer *iobuf );
- /** Enqueue stream transfer
- *
- * @v ep USB endpoint
- * @v iobuf I/O buffer
- * @v zlp Append a zero-length packet
- * @ret rc Return status code
- */
- int ( * stream ) ( struct usb_endpoint *ep, struct io_buffer *iobuf,
- int zlp );
- };
-
- /** USB endpoint driver operations */
- struct usb_endpoint_driver_operations {
- /** Complete transfer
- *
- * @v ep USB endpoint
- * @v iobuf I/O buffer
- * @v rc Completion status code
- */
- void ( * complete ) ( struct usb_endpoint *ep,
- struct io_buffer *iobuf, int rc );
- };
-
- /** Control endpoint address */
- #define USB_EP0_ADDRESS 0x00
-
- /** Control endpoint attributes */
- #define USB_EP0_ATTRIBUTES 0x00
-
- /** Calculate default MTU based on device speed
- *
- * @v speed Device speed
- * @ret mtu Default MTU
- */
- #define USB_EP0_DEFAULT_MTU(speed) \
- ( ( (speed) >= USB_SPEED_SUPER ) ? 512 : \
- ( ( (speed) >= USB_SPEED_FULL ) ? 64 : 8 ) )
-
- /** Control endpoint maximum burst size */
- #define USB_EP0_BURST 0
-
- /** Control endpoint interval */
- #define USB_EP0_INTERVAL 0
-
- /** Maximum endpoint number */
- #define USB_ENDPOINT_MAX 0x0f
-
- /** Endpoint direction is in */
- #define USB_ENDPOINT_IN 0x80
-
- /** Construct endpoint index from endpoint address */
- #define USB_ENDPOINT_IDX(address) \
- ( ( (address) & USB_ENDPOINT_MAX ) | \
- ( ( (address) & USB_ENDPOINT_IN ) >> 3 ) )
-
- /**
- * Initialise USB endpoint
- *
- * @v ep USB endpoint
- * @v usb USB device
- * @v driver Driver operations
- */
- static inline __attribute__ (( always_inline )) void
- usb_endpoint_init ( struct usb_endpoint *ep, struct usb_device *usb,
- struct usb_endpoint_driver_operations *driver ) {
-
- ep->usb = usb;
- ep->driver = driver;
- }
-
- /**
- * Describe USB endpoint
- *
- * @v ep USB endpoint
- * @v address Endpoint address
- * @v attributes Attributes
- * @v mtu Maximum packet size
- * @v burst Maximum burst size
- * @v interval Interval (in microframes)
- */
- static inline __attribute__ (( always_inline )) void
- usb_endpoint_describe ( struct usb_endpoint *ep, unsigned int address,
- unsigned int attributes, size_t mtu,
- unsigned int burst, unsigned int interval ) {
-
- ep->address = address;
- ep->attributes = attributes;
- ep->mtu = mtu;
- ep->burst = burst;
- ep->interval = interval;
- }
-
- /**
- * Set USB endpoint host controller private data
- *
- * @v ep USB endpoint
- * @v priv Host controller private data
- */
- static inline __attribute__ (( always_inline )) void
- usb_endpoint_set_hostdata ( struct usb_endpoint *ep, void *priv ) {
- ep->priv = priv;
- }
-
- /**
- * Get USB endpoint host controller private data
- *
- * @v ep USB endpoint
- * @ret priv Host controller private data
- */
- static inline __attribute__ (( always_inline )) void *
- usb_endpoint_get_hostdata ( struct usb_endpoint *ep ) {
- return ep->priv;
- }
-
- extern const char * usb_endpoint_name ( struct usb_endpoint *ep );
- extern int
- usb_endpoint_described ( struct usb_endpoint *ep,
- struct usb_configuration_descriptor *config,
- struct usb_interface_descriptor *interface,
- unsigned int type, unsigned int index );
- extern int usb_endpoint_open ( struct usb_endpoint *ep );
- extern void usb_endpoint_close ( struct usb_endpoint *ep );
- extern int usb_message ( struct usb_endpoint *ep, unsigned int request,
- unsigned int value, unsigned int index,
- struct io_buffer *iobuf );
- extern int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
- int terminate );
- extern void usb_complete_err ( struct usb_endpoint *ep,
- struct io_buffer *iobuf, int rc );
-
- /**
- * Initialise USB endpoint refill
- *
- * @v ep USB endpoint
- * @v reserve Refill buffer reserved header length
- * @v len Refill buffer payload length (zero for endpoint's MTU)
- * @v max Maximum fill level
- */
- static inline __attribute__ (( always_inline )) void
- usb_refill_init ( struct usb_endpoint *ep, size_t reserve, size_t len,
- unsigned int max ) {
-
- INIT_LIST_HEAD ( &ep->recycled );
- ep->reserve = reserve;
- ep->len = len;
- ep->max = max;
- }
-
- /**
- * Recycle I/O buffer
- *
- * @v ep USB endpoint
- * @v iobuf I/O buffer
- */
- static inline __attribute__ (( always_inline )) void
- usb_recycle ( struct usb_endpoint *ep, struct io_buffer *iobuf ) {
-
- list_add_tail ( &iobuf->list, &ep->recycled );
- }
-
- extern int usb_prefill ( struct usb_endpoint *ep );
- extern int usb_refill ( struct usb_endpoint *ep );
- extern void usb_flush ( struct usb_endpoint *ep );
-
- /** A USB class descriptor */
- union usb_class_descriptor {
- /** Class */
- struct usb_class class;
- /** Scalar value */
- uint32_t scalar;
- };
-
- /**
- * A USB function descriptor
- *
- * This is an internal descriptor used to represent an association of
- * interfaces within a USB device.
- */
- struct usb_function_descriptor {
- /** Vendor ID */
- uint16_t vendor;
- /** Product ID */
- uint16_t product;
- /** Class */
- union usb_class_descriptor class;
- /** Number of interfaces */
- unsigned int count;
- };
-
- /**
- * A USB function
- *
- * A USB function represents an association of interfaces within a USB
- * device.
- */
- struct usb_function {
- /** Name */
- const char *name;
- /** USB device */
- struct usb_device *usb;
- /** Function descriptor */
- struct usb_function_descriptor desc;
- /** Generic device */
- struct device dev;
- /** List of functions within this USB device */
- struct list_head list;
-
- /** Driver */
- struct usb_driver *driver;
- /** Driver private data */
- void *priv;
- /** Driver device ID */
- struct usb_device_id *id;
-
- /** List of interface numbers
- *
- * This must be the last field within the structure.
- */
- uint8_t interface[0];
- };
-
- /**
- * Set USB function driver private data
- *
- * @v func USB function
- * @v priv Driver private data
- */
- static inline __attribute__ (( always_inline )) void
- usb_func_set_drvdata ( struct usb_function *func, void *priv ) {
- func->priv = priv;
- }
-
- /**
- * Get USB function driver private data
- *
- * @v function USB function
- * @ret priv Driver private data
- */
- static inline __attribute__ (( always_inline )) void *
- usb_func_get_drvdata ( struct usb_function *func ) {
- return func->priv;
- }
-
- /** A USB device */
- struct usb_device {
- /** Name */
- char name[32];
- /** USB port */
- struct usb_port *port;
- /** Device speed */
- unsigned int speed;
- /** List of devices on this bus */
- struct list_head list;
- /** Device address, if assigned */
- unsigned int address;
- /** Device descriptor */
- struct usb_device_descriptor device;
- /** List of functions */
- struct list_head functions;
-
- /** Host controller operations */
- struct usb_device_host_operations *host;
- /** Host controller private data */
- void *priv;
-
- /** Endpoint list */
- struct usb_endpoint *ep[32];
-
- /** Control endpoint */
- struct usb_endpoint control;
- /** Completed control transfers */
- struct list_head complete;
-
- /** Default language ID (if known) */
- unsigned int language;
- };
-
- /** USB device host controller operations */
- struct usb_device_host_operations {
- /** Open device
- *
- * @v usb USB device
- * @ret rc Return status code
- */
- int ( * open ) ( struct usb_device *usb );
- /** Close device
- *
- * @v usb USB device
- */
- void ( * close ) ( struct usb_device *usb );
- /** Assign device address
- *
- * @v usb USB device
- * @ret rc Return status code
- */
- int ( * address ) ( struct usb_device *usb );
- };
-
- /**
- * Set USB device host controller private data
- *
- * @v usb USB device
- * @v priv Host controller private data
- */
- static inline __attribute__ (( always_inline )) void
- usb_set_hostdata ( struct usb_device *usb, void *priv ) {
- usb->priv = priv;
- }
-
- /**
- * Get USB device host controller private data
- *
- * @v usb USB device
- * @ret priv Host controller private data
- */
- static inline __attribute__ (( always_inline )) void *
- usb_get_hostdata ( struct usb_device *usb ) {
- return usb->priv;
- }
-
- /**
- * Get USB endpoint
- *
- * @v usb USB device
- * @v address Endpoint address
- * @ret ep USB endpoint, or NULL if not opened
- */
- static inline struct usb_endpoint * usb_endpoint ( struct usb_device *usb,
- unsigned int address ) {
-
- return usb->ep[ USB_ENDPOINT_IDX ( address ) ];
- }
-
- /** A USB port */
- struct usb_port {
- /** USB hub */
- struct usb_hub *hub;
- /** Port address */
- unsigned int address;
- /** Port protocol */
- unsigned int protocol;
- /** Port speed */
- unsigned int speed;
- /** Port disconnection has been detected
- *
- * This should be set whenever the underlying hardware reports
- * a connection status change.
- */
- int disconnected;
- /** Port has an attached device */
- int attached;
- /** Currently attached device (if in use)
- *
- * Note that this field will be NULL if the attached device
- * has been freed (e.g. because there were no drivers found).
- */
- struct usb_device *usb;
- /** List of changed ports */
- struct list_head changed;
- };
-
- /** A USB hub */
- struct usb_hub {
- /** Name */
- const char *name;
- /** USB bus */
- struct usb_bus *bus;
- /** Underlying USB device, if any */
- struct usb_device *usb;
- /** Hub protocol */
- unsigned int protocol;
- /** Number of ports */
- unsigned int ports;
-
- /** List of hubs */
- struct list_head list;
-
- /** Host controller operations */
- struct usb_hub_host_operations *host;
- /** Driver operations */
- struct usb_hub_driver_operations *driver;
- /** Driver private data */
- void *priv;
-
- /** Port list
- *
- * This must be the last field within the structure.
- */
- struct usb_port port[0];
- };
-
- /** USB hub host controller operations */
- struct usb_hub_host_operations {
- /** Open hub
- *
- * @v hub USB hub
- * @ret rc Return status code
- */
- int ( * open ) ( struct usb_hub *hub );
- /** Close hub
- *
- * @v hub USB hub
- */
- void ( * close ) ( struct usb_hub *hub );
- };
-
- /** USB hub driver operations */
- struct usb_hub_driver_operations {
- /** Open hub
- *
- * @v hub USB hub
- * @ret rc Return status code
- */
- int ( * open ) ( struct usb_hub *hub );
- /** Close hub
- *
- * @v hub USB hub
- */
- void ( * close ) ( struct usb_hub *hub );
- /** Enable port
- *
- * @v hub USB hub
- * @v port USB port
- * @ret rc Return status code
- */
- int ( * enable ) ( struct usb_hub *hub, struct usb_port *port );
- /** Disable port
- *
- * @v hub USB hub
- * @v port USB port
- * @ret rc Return status code
- */
- int ( * disable ) ( struct usb_hub *hub, struct usb_port *port );
- /** Update port speed
- *
- * @v hub USB hub
- * @v port USB port
- * @ret rc Return status code
- */
- int ( * speed ) ( struct usb_hub *hub, struct usb_port *port );
- /** Clear transaction translator buffer
- *
- * @v hub USB hub
- * @v port USB port
- * @v ep USB endpoint
- * @ret rc Return status code
- */
- int ( * clear_tt ) ( struct usb_hub *hub, struct usb_port *port,
- struct usb_endpoint *ep );
- };
-
- /**
- * Set USB hub driver private data
- *
- * @v hub USB hub
- * @v priv Driver private data
- */
- static inline __attribute__ (( always_inline )) void
- usb_hub_set_drvdata ( struct usb_hub *hub, void *priv ) {
- hub->priv = priv;
- }
-
- /**
- * Get USB hub driver private data
- *
- * @v hub USB hub
- * @ret priv Driver private data
- */
- static inline __attribute__ (( always_inline )) void *
- usb_hub_get_drvdata ( struct usb_hub *hub ) {
- return hub->priv;
- }
-
- /**
- * Get USB port
- *
- * @v hub USB hub
- * @v address Port address
- * @ret port USB port
- */
- static inline __attribute__ (( always_inline )) struct usb_port *
- usb_port ( struct usb_hub *hub, unsigned int address ) {
-
- return &hub->port[ address - 1 ];
- }
-
- /** A USB bus */
- struct usb_bus {
- /** Name */
- const char *name;
- /** Underlying hardware device */
- struct device *dev;
- /** Host controller operations set */
- struct usb_host_operations *op;
-
- /** Largest transfer allowed on the bus */
- size_t mtu;
- /** Address in-use mask
- *
- * This is used only by buses which perform manual address
- * assignment. USB allows for addresses in the range [1,127].
- * We use a simple bitmask which restricts us to the range
- * [1,64]; this is unlikely to be a problem in practice. For
- * comparison: controllers which perform autonomous address
- * assignment (such as xHCI) typically allow for only 32
- * devices per bus anyway.
- */
- unsigned long long addresses;
-
- /** Root hub */
- struct usb_hub *hub;
-
- /** List of USB buses */
- struct list_head list;
- /** List of devices */
- struct list_head devices;
- /** List of hubs */
- struct list_head hubs;
-
- /** Host controller operations */
- struct usb_bus_host_operations *host;
- /** Host controller private data */
- void *priv;
- };
-
- /** USB bus host controller operations */
- struct usb_bus_host_operations {
- /** Open bus
- *
- * @v bus USB bus
- * @ret rc Return status code
- */
- int ( * open ) ( struct usb_bus *bus );
- /** Close bus
- *
- * @v bus USB bus
- */
- void ( * close ) ( struct usb_bus *bus );
- /** Poll bus
- *
- * @v bus USB bus
- */
- void ( * poll ) ( struct usb_bus *bus );
- };
-
- /** USB host controller operations */
- struct usb_host_operations {
- /** Endpoint operations */
- struct usb_endpoint_host_operations endpoint;
- /** Device operations */
- struct usb_device_host_operations device;
- /** Bus operations */
- struct usb_bus_host_operations bus;
- /** Hub operations */
- struct usb_hub_host_operations hub;
- /** Root hub operations */
- struct usb_hub_driver_operations root;
- };
-
- /**
- * Set USB bus host controller private data
- *
- * @v bus USB bus
- * @v priv Host controller private data
- */
- static inline __attribute__ (( always_inline )) void
- usb_bus_set_hostdata ( struct usb_bus *bus, void *priv ) {
- bus->priv = priv;
- }
-
- /**
- * Get USB bus host controller private data
- *
- * @v bus USB bus
- * @ret priv Host controller private data
- */
- static inline __attribute__ (( always_inline )) void *
- usb_bus_get_hostdata ( struct usb_bus *bus ) {
- return bus->priv;
- }
-
- /**
- * Poll USB bus
- *
- * @v bus USB bus
- */
- static inline __attribute__ (( always_inline )) void
- usb_poll ( struct usb_bus *bus ) {
- bus->host->poll ( bus );
- }
-
- /** Iterate over all USB buses */
- #define for_each_usb_bus( bus ) \
- list_for_each_entry ( (bus), &usb_buses, list )
-
- /**
- * Complete transfer (without error)
- *
- * @v ep USB endpoint
- * @v iobuf I/O buffer
- */
- static inline __attribute__ (( always_inline )) void
- usb_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf ) {
- usb_complete_err ( ep, iobuf, 0 );
- }
-
- extern int usb_control ( struct usb_device *usb, unsigned int request,
- unsigned int value, unsigned int index, void *data,
- size_t len );
- extern int usb_get_string_descriptor ( struct usb_device *usb,
- unsigned int index,
- unsigned int language,
- char *buf, size_t len );
-
- /**
- * Get status
- *
- * @v usb USB device
- * @v type Request type
- * @v index Target index
- * @v data Status to fill in
- * @v len Length of status descriptor
- * @ret rc Return status code
- */
- static inline __attribute__ (( always_inline )) int
- usb_get_status ( struct usb_device *usb, unsigned int type, unsigned int index,
- void *data, size_t len ) {
-
- return usb_control ( usb, ( USB_GET_STATUS | type ), 0, index,
- data, len );
- }
-
- /**
- * Clear feature
- *
- * @v usb USB device
- * @v type Request type
- * @v feature Feature selector
- * @v index Target index
- * @ret rc Return status code
- */
- static inline __attribute__ (( always_inline )) int
- usb_clear_feature ( struct usb_device *usb, unsigned int type,
- unsigned int feature, unsigned int index ) {
-
- return usb_control ( usb, ( USB_CLEAR_FEATURE | type ),
- feature, index, NULL, 0 );
- }
-
- /**
- * Set feature
- *
- * @v usb USB device
- * @v type Request type
- * @v feature Feature selector
- * @v index Target index
- * @ret rc Return status code
- */
- static inline __attribute__ (( always_inline )) int
- usb_set_feature ( struct usb_device *usb, unsigned int type,
- unsigned int feature, unsigned int index ) {
-
- return usb_control ( usb, ( USB_SET_FEATURE | type ),
- feature, index, NULL, 0 );
- }
-
- /**
- * Set address
- *
- * @v usb USB device
- * @v address Device address
- * @ret rc Return status code
- */
- static inline __attribute__ (( always_inline )) int
- usb_set_address ( struct usb_device *usb, unsigned int address ) {
-
- return usb_control ( usb, USB_SET_ADDRESS, address, 0, NULL, 0 );
- }
-
- /**
- * Get USB descriptor
- *
- * @v usb USB device
- * @v type Request type
- * @v desc Descriptor type
- * @v index Descriptor index
- * @v language Language ID (for string descriptors)
- * @v data Descriptor to fill in
- * @v len Maximum length of descriptor
- * @ret rc Return status code
- */
- static inline __attribute__ (( always_inline )) int
- usb_get_descriptor ( struct usb_device *usb, unsigned int type,
- unsigned int desc, unsigned int index,
- unsigned int language, struct usb_descriptor_header *data,
- size_t len ) {
-
- return usb_control ( usb, ( USB_GET_DESCRIPTOR | type ),
- ( ( desc << 8 ) | index ), language, data, len );
- }
-
- /**
- * Get first part of USB device descriptor (up to and including MTU)
- *
- * @v usb USB device
- * @v data Device descriptor to (partially) fill in
- * @ret rc Return status code
- */
- static inline __attribute__ (( always_inline )) int
- usb_get_mtu ( struct usb_device *usb, struct usb_device_descriptor *data ) {
-
- return usb_get_descriptor ( usb, 0, USB_DEVICE_DESCRIPTOR, 0, 0,
- &data->header,
- ( offsetof ( typeof ( *data ), mtu ) +
- sizeof ( data->mtu ) ) );
- }
-
- /**
- * Get USB device descriptor
- *
- * @v usb USB device
- * @v data Device descriptor to fill in
- * @ret rc Return status code
- */
- static inline __attribute__ (( always_inline )) int
- usb_get_device_descriptor ( struct usb_device *usb,
- struct usb_device_descriptor *data ) {
-
- return usb_get_descriptor ( usb, 0, USB_DEVICE_DESCRIPTOR, 0, 0,
- &data->header, sizeof ( *data ) );
- }
-
- /**
- * Get USB configuration descriptor
- *
- * @v usb USB device
- * @v index Configuration index
- * @v data Configuration descriptor to fill in
- * @ret rc Return status code
- */
- static inline __attribute__ (( always_inline )) int
- usb_get_config_descriptor ( struct usb_device *usb, unsigned int index,
- struct usb_configuration_descriptor *data,
- size_t len ) {
-
- return usb_get_descriptor ( usb, 0, USB_CONFIGURATION_DESCRIPTOR, index,
- 0, &data->header, len );
- }
-
- /**
- * Set USB configuration
- *
- * @v usb USB device
- * @v index Configuration index
- * @ret rc Return status code
- */
- static inline __attribute__ (( always_inline )) int
- usb_set_configuration ( struct usb_device *usb, unsigned int index ) {
-
- return usb_control ( usb, USB_SET_CONFIGURATION, index, 0, NULL, 0 );
- }
-
- /**
- * Set USB interface alternate setting
- *
- * @v usb USB device
- * @v interface Interface number
- * @v alternate Alternate setting
- * @ret rc Return status code
- */
- static inline __attribute__ (( always_inline )) int
- usb_set_interface ( struct usb_device *usb, unsigned int interface,
- unsigned int alternate ) {
-
- return usb_control ( usb, USB_SET_INTERFACE, alternate, interface,
- NULL, 0 );
- }
-
- extern struct list_head usb_buses;
-
- extern struct usb_interface_descriptor *
- usb_interface_descriptor ( struct usb_configuration_descriptor *config,
- unsigned int interface, unsigned int alternate );
- extern struct usb_endpoint_descriptor *
- usb_endpoint_descriptor ( struct usb_configuration_descriptor *config,
- struct usb_interface_descriptor *interface,
- unsigned int type, unsigned int index );
- extern struct usb_endpoint_companion_descriptor *
- usb_endpoint_companion_descriptor ( struct usb_configuration_descriptor *config,
- struct usb_endpoint_descriptor *desc );
-
- extern struct usb_hub * alloc_usb_hub ( struct usb_bus *bus,
- struct usb_device *usb,
- unsigned int ports,
- struct usb_hub_driver_operations *op );
- extern int register_usb_hub ( struct usb_hub *hub );
- extern void unregister_usb_hub ( struct usb_hub *hub );
- extern void free_usb_hub ( struct usb_hub *hub );
-
- extern void usb_port_changed ( struct usb_port *port );
-
- extern struct usb_bus * alloc_usb_bus ( struct device *dev,
- unsigned int ports, size_t mtu,
- struct usb_host_operations *op );
- extern int register_usb_bus ( struct usb_bus *bus );
- extern void unregister_usb_bus ( struct usb_bus *bus );
- extern void free_usb_bus ( struct usb_bus *bus );
- extern struct usb_bus * find_usb_bus_by_location ( unsigned int bus_type,
- unsigned int location );
-
- extern int usb_alloc_address ( struct usb_bus *bus );
- extern void usb_free_address ( struct usb_bus *bus, unsigned int address );
- extern unsigned int usb_route_string ( struct usb_device *usb );
- extern unsigned int usb_depth ( struct usb_device *usb );
- extern struct usb_port * usb_root_hub_port ( struct usb_device *usb );
- extern struct usb_port * usb_transaction_translator ( struct usb_device *usb );
-
- /** Minimum reset time
- *
- * Section 7.1.7.5 of the USB2 specification states that root hub
- * ports should assert reset signalling for at least 50ms.
- */
- #define USB_RESET_DELAY_MS 50
-
- /** Reset recovery time
- *
- * Section 9.2.6.2 of the USB2 specification states that the
- * "recovery" interval after a port reset is 10ms.
- */
- #define USB_RESET_RECOVER_DELAY_MS 10
-
- /** Maximum time to wait for a control transaction to complete
- *
- * Section 9.2.6.1 of the USB2 specification states that the upper
- * limit for commands to be processed is 5 seconds.
- */
- #define USB_CONTROL_MAX_WAIT_MS 5000
-
- /** Set address recovery time
- *
- * Section 9.2.6.3 of the USB2 specification states that devices are
- * allowed a 2ms recovery interval after receiving a new address.
- */
- #define USB_SET_ADDRESS_RECOVER_DELAY_MS 2
-
- /** Time to wait for ports to stabilise
- *
- * Section 7.1.7.3 of the USB specification states that we must allow
- * 100ms for devices to signal attachment, and an additional 100ms for
- * connection debouncing. (This delay is parallelised across all
- * ports on a hub; we do not delay separately for each port.)
- */
- #define USB_PORT_DELAY_MS 200
-
- /** A USB device ID */
- struct usb_device_id {
- /** Name */
- const char *name;
- /** Vendor ID */
- uint16_t vendor;
- /** Product ID */
- uint16_t product;
- /** Arbitrary driver data */
- unsigned long driver_data;
- };
-
- /** Match-anything ID */
- #define USB_ANY_ID 0xffff
-
- /** A USB class ID */
- struct usb_class_id {
- /** Class */
- union usb_class_descriptor class;
- /** Class mask */
- union usb_class_descriptor mask;
- };
-
- /** Construct USB class ID
- *
- * @v base Base class code (or USB_ANY_ID)
- * @v subclass Subclass code (or USB_ANY_ID)
- * @v protocol Protocol code (or USB_ANY_ID)
- */
- #define USB_CLASS_ID( base, subclass, protocol ) { \
- .class = { \
- .class = { \
- ( (base) & 0xff ), \
- ( (subclass) & 0xff ), \
- ( (protocol) & 0xff ), \
- }, \
- }, \
- .mask = { \
- .class = { \
- ( ( (base) == USB_ANY_ID ) ? 0x00 : 0xff ), \
- ( ( (subclass) == USB_ANY_ID ) ? 0x00 : 0xff ), \
- ( ( (protocol) == USB_ANY_ID ) ? 0x00 : 0xff ), \
- }, \
- }, \
- }
-
- /** A USB driver */
- struct usb_driver {
- /** USB ID table */
- struct usb_device_id *ids;
- /** Number of entries in ID table */
- unsigned int id_count;
- /** Class ID */
- struct usb_class_id class;
- /** Driver score
- *
- * This is used to determine the preferred configuration for a
- * USB device.
- */
- unsigned int score;
- /**
- * Probe device
- *
- * @v func USB function
- * @v config Configuration descriptor
- * @ret rc Return status code
- */
- int ( * probe ) ( struct usb_function *func,
- struct usb_configuration_descriptor *config );
- /**
- * Remove device
- *
- * @v func USB function
- */
- void ( * remove ) ( struct usb_function *func );
- };
-
- /** USB driver table */
- #define USB_DRIVERS __table ( struct usb_driver, "usb_drivers" )
-
- /** Declare a USB driver */
- #define __usb_driver __table_entry ( USB_DRIVERS, 01 )
-
- /** USB driver scores */
- enum usb_driver_score {
- /** Fallback driver (has no effect on overall score) */
- USB_SCORE_FALLBACK = 0,
- /** Deprecated driver */
- USB_SCORE_DEPRECATED = 1,
- /** Normal driver */
- USB_SCORE_NORMAL = 2,
- };
-
- extern struct usb_driver *
- usb_find_driver ( struct usb_function_descriptor *desc,
- struct usb_device_id **id );
-
- #endif /* _IPXE_USB_H */
|