* (the hubs) have this as parent data. Hubs are children of controllers or
* other hubs and there is always a single root hub for each controller.
* Therefore struct usb_device can always be accessed with
- * dev_get_parentdata(dev), where dev is a USB device.
+ * dev_get_parent_priv(dev), where dev is a USB device.
*
* Pointers exist for obtaining both the device (could be any uclass) and
* controller (UCLASS_USB) from this structure. The controller does not have
int string_langid; /* language ID for strings */
int (*irq_handle)(struct usb_device *dev);
unsigned long irq_status;
- int irq_act_len; /* transfered bytes */
+ int irq_act_len; /* transferred bytes */
void *privptr;
/*
* Child devices - if this is a hub device
*/
unsigned long status;
unsigned long int_pending; /* 1 bit per ep, used by int_queue */
- int act_len; /* transfered bytes */
+ int act_len; /* transferred bytes */
int maxchild; /* Number of ports if hub */
int portnr; /* Port number, 1=first */
#ifndef CONFIG_DM_USB
* this is how the lowlevel part communicate with the outer world
*/
-#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \
- defined(CONFIG_USB_EHCI) || defined(CONFIG_USB_OHCI_NEW) || \
- defined(CONFIG_USB_SL811HS) || defined(CONFIG_USB_ISP116X_HCD) || \
- defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI) || \
- defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \
- defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \
- defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \
- defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_MUSB_SUNXI) || \
- defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2) || \
- defined(CONFIG_USB_EMUL)
-
int usb_lowlevel_init(int index, enum usb_init_type init, void **controller);
int usb_lowlevel_stop(int index);
-#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_DM_USB)
-int usb_reset_root_port(void);
+#if defined(CONFIG_USB_MUSB_HOST) || defined(CONFIG_DM_USB)
+int usb_reset_root_port(struct usb_device *dev);
#else
-#define usb_reset_root_port()
+#define usb_reset_root_port(dev)
#endif
int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int transfer_len, int interval);
-#if defined CONFIG_USB_EHCI || defined CONFIG_MUSB_HOST
+#if defined CONFIG_USB_EHCI_HCD || defined CONFIG_USB_MUSB_HOST \
+ || defined(CONFIG_DM_USB)
struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe,
int queuesize, int elementsize, void *buffer, int interval);
int destroy_int_queue(struct usb_device *dev, struct int_queue *queue);
* in boards init functions e.g. udc_disconnect() used for
* forced device disconnection from host.
*/
-#elif defined(CONFIG_USB_GADGET_PXA2XX)
-
extern void udc_disconnect(void);
-#endif
-
/*
* board-specific hardware initialization, called by
* usb drivers and u-boot commands
#ifdef CONFIG_USB_STORAGE
-#define USB_MAX_STOR_DEV 5
-block_dev_desc_t *usb_stor_get_dev(int index);
+#define USB_MAX_STOR_DEV 7
int usb_stor_scan(int mode);
int usb_stor_info(void);
/* routines */
int usb_init(void); /* initialize the USB Controller */
int usb_stop(void); /* stop the USB Controller */
+int usb_detect_change(void); /* detect if a USB device has been (un)plugged */
int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol);
void *buffer, int transfer_len, int interval);
int usb_disable_asynch(int disable);
int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
-int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer,
- int cfgno);
+int usb_get_configuration_no(struct usb_device *dev, int cfgno,
+ unsigned char *buffer, int length);
+int usb_get_configuration_len(struct usb_device *dev, int cfgno);
int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
unsigned char id, void *buf, int size);
int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
int usb_clear_halt(struct usb_device *dev, int pipe);
int usb_string(struct usb_device *dev, int index, char *buf, size_t size);
int usb_set_interface(struct usb_device *dev, int interface, int alternate);
+int usb_get_port_status(struct usb_device *dev, int port, void *data);
/* big endian -> little endian conversion */
/* some CPUs are already little endian e.g. the ARM920T */
/**
* struct usb_driver_entry - Matches a driver to its usb_device_ids
- * @compatible: Compatible string
- * @data: Data for this compatible string
+ * @driver: Driver to use
+ * @match: List of match records for this driver, terminated by {}
*/
struct usb_driver_entry {
struct driver *driver;
const struct usb_device_id *match;
};
-#define USB_DEVICE(__name, __match) \
+#define USB_DEVICE_ID_MATCH_DEVICE \
+ (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
+
+/**
+ * USB_DEVICE - macro used to describe a specific usb device
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific device.
+ */
+#define USB_DEVICE(vend, prod) \
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
+ .idVendor = (vend), \
+ .idProduct = (prod)
+
+#define U_BOOT_USB_DEVICE(__name, __match) \
ll_entry_declare(struct usb_driver_entry, __name, usb_driver_entry) = {\
.driver = llsym(struct driver, __name, driver), \
.match = __match, \
unsigned short wHubChange;
} __attribute__ ((packed));
+/*
+ * Hub Device descriptor
+ * USB Hub class device protocols
+ */
+#define USB_HUB_PR_FS 0 /* Full speed hub */
+#define USB_HUB_PR_HS_NO_TT 0 /* Hi-speed hub without TT */
+#define USB_HUB_PR_HS_SINGLE_TT 1 /* Hi-speed hub with single TT */
+#define USB_HUB_PR_HS_MULTI_TT 2 /* Hi-speed hub with multiple TT */
+#define USB_HUB_PR_SS 3 /* Super speed hub */
+
+/* Transaction Translator Think Times, in bits */
+#define HUB_TTTT_8_BITS 0x00
+#define HUB_TTTT_16_BITS 0x20
+#define HUB_TTTT_24_BITS 0x40
+#define HUB_TTTT_32_BITS 0x60
/* Hub descriptor */
struct usb_hub_descriptor {
unsigned short wHubCharacteristics;
unsigned char bPwrOn2PwrGood;
unsigned char bHubContrCurrent;
- unsigned char DeviceRemovable[(USB_MAXCHILDREN+1+7)/8];
- unsigned char PortPowerCtrlMask[(USB_MAXCHILDREN+1+7)/8];
- /* DeviceRemovable and PortPwrCtrlMask want to be variable-length
- bitmaps that hold max 255 entries. (bit0 is ignored) */
+ /* 2.0 and 3.0 hubs differ here */
+ union {
+ struct {
+ /* add 1 bit for hub status change; round to bytes */
+ __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
+ __u8 PortPowerCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
+ } __attribute__ ((packed)) hs;
+
+ struct {
+ __u8 bHubHdrDecLat;
+ __le16 wHubDelay;
+ __le16 DeviceRemovable;
+ } __attribute__ ((packed)) ss;
+ } u;
} __attribute__ ((packed));
struct usb_hub_device {
struct usb_device *pusb_dev;
struct usb_hub_descriptor desc;
+
+ ulong connect_timeout; /* Device connection timeout in ms */
+ ulong query_delay; /* Device query delay in ms */
+ int overcurrent_count[USB_MAXCHILDREN]; /* Over-current counter */
+ int hub_depth; /* USB 3.0 hub depth */
+ struct usb_tt tt; /* Transaction Translator */
};
#ifdef CONFIG_DM_USB
* This is used by sandbox to provide emulation data also.
*
* @id: ID used to match this device
- * @speed: Stores the speed associated with a USB device
* @devnum: Device address on the USB bus
- * @slot_id: USB3 slot ID, which is separate from the device address
- * @portnr: Port number of this device on its parent hub, numbered from 1
- * (0 mean this device is the root hub)
+ * @udev: usb-uclass internal use only do NOT use
* @strings: List of descriptor strings (for sandbox emulation purposes)
* @desc_list: List of descriptors (for sandbox emulation purposes)
*/
struct usb_dev_platdata {
struct usb_device_id id;
- enum usb_device_speed speed;
int devnum;
- int slot_id;
- int portnr; /* Hub port number, 1..n */
+ /*
+ * This pointer is used to pass the usb_device used in usb_scan_device,
+ * to get the usb descriptors before the driver is known, to the
+ * actual udevice once the driver is known and the udevice is created.
+ * This will be NULL except during probe, do NOT use.
+ *
+ * This should eventually go away.
+ */
+ struct usb_device *udev;
#ifdef CONFIG_SANDBOX
struct usb_string *strings;
/* NULL-terminated list of descriptor pointers */
* @desc_before_addr: true if we can read a device descriptor before it
* has been assigned an address. For XHCI this is not possible
* so this will be false.
+ * @companion: True if this is a companion controller to another USB
+ * controller
*/
struct usb_bus_priv {
int next_addr;
bool desc_before_addr;
+ bool companion;
+};
+
+/**
+ * struct usb_emul_platdata - platform data about the USB emulator
+ *
+ * Given a USB emulator (UCLASS_USB_EMUL) 'dev', this is
+ * dev_get_uclass_platdata(dev).
+ *
+ * @port1: USB emulator device port number on the parent hub
+ */
+struct usb_emul_platdata {
+ int port1; /* Port number (numbered from 1) */
};
/**
int (*interrupt)(struct udevice *bus, struct usb_device *udev,
unsigned long pipe, void *buffer, int length,
int interval);
+
+ /**
+ * create_int_queue() - Create and queue interrupt packets
+ *
+ * Create and queue @queuesize number of interrupt usb packets of
+ * @elementsize bytes each. @buffer must be atleast @queuesize *
+ * @elementsize bytes.
+ *
+ * Note some controllers only support a queuesize of 1.
+ *
+ * @interval: Interrupt interval
+ *
+ * @return A pointer to the created interrupt queue or NULL on error
+ */
+ struct int_queue * (*create_int_queue)(struct udevice *bus,
+ struct usb_device *udev, unsigned long pipe,
+ int queuesize, int elementsize, void *buffer,
+ int interval);
+
+ /**
+ * poll_int_queue() - Poll an interrupt queue for completed packets
+ *
+ * Poll an interrupt queue for completed packets. The return value
+ * points to the part of the buffer passed to create_int_queue()
+ * corresponding to the completed packet.
+ *
+ * @queue: queue to poll
+ *
+ * @return Pointer to the data of the first completed packet, or
+ * NULL if no packets are ready
+ */
+ void * (*poll_int_queue)(struct udevice *bus, struct usb_device *udev,
+ struct int_queue *queue);
+
+ /**
+ * destroy_int_queue() - Destroy an interrupt queue
+ *
+ * Destroy an interrupt queue created by create_int_queue().
+ *
+ * @queue: queue to poll
+ *
+ * @return 0 if OK, -ve on error
+ */
+ int (*destroy_int_queue)(struct udevice *bus, struct usb_device *udev,
+ struct int_queue *queue);
+
/**
* alloc_device() - Allocate a new device context (XHCI)
*
* is read). This should be NULL for EHCI, which does not need this.
*/
int (*alloc_device)(struct udevice *bus, struct usb_device *udev);
+
+ /**
+ * reset_root_port() - Reset usb root port
+ */
+ int (*reset_root_port)(struct udevice *bus, struct usb_device *udev);
+
+ /**
+ * update_hub_device() - Update HCD's internal representation of hub
+ *
+ * After a hub descriptor is fetched, notify HCD so that its internal
+ * representation of this hub can be updated (xHCI)
+ */
+ int (*update_hub_device)(struct udevice *bus, struct usb_device *udev);
+
+ /**
+ * get_max_xfer_size() - Get HCD's maximum transfer bytes
+ *
+ * The HCD may have limitation on the maximum bytes to be transferred
+ * in a USB transfer. USB class driver needs to be aware of this.
+ */
+ int (*get_max_xfer_size)(struct udevice *bus, size_t *size);
};
#define usb_get_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops)
#define usb_get_emul_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops)
-#ifdef CONFIG_MUSB_HOST
-int usb_reset_root_port(void);
-#endif
-
/**
* usb_get_dev_index() - look up a device index number
*
*/
struct usb_device *usb_get_dev_index(struct udevice *bus, int index);
-/**
- * usb_legacy_port_reset() - Legacy function to reset a hub port
- *
- * @hub: Hub device
- * @portnr: Port number (1=first)
- */
-int usb_legacy_port_reset(struct usb_device *hub, int portnr);
-
/**
* usb_setup_device() - set up a device ready for use
*
* @dev: USB device pointer. This need not be a real device - it is
* common for it to just be a local variable with its ->dev
- * member (i.e. @dev->dev) set to the parent device
+ * member (i.e. @dev->dev) set to the parent device and
+ * dev->portnr set to the port number on the hub (1=first)
* @do_read: true to read the device descriptor before an address is set
* (should be false for XHCI buses, true otherwise)
* @parent: Parent device (either UCLASS_USB or UCLASS_USB_HUB)
- * @portnr: Port number on hub (1=first) or 0 for none
* @return 0 if OK, -ve on error */
int usb_setup_device(struct usb_device *dev, bool do_read,
- struct usb_device *parent, int portnr);
+ struct usb_device *parent);
+
+/**
+ * usb_hub_is_root_hub() - Test whether a hub device is root hub or not
+ *
+ * @hub: USB hub device to test
+ * @return: true if the hub device is root hub, false otherwise.
+ */
+bool usb_hub_is_root_hub(struct udevice *hub);
/**
* usb_hub_scan() - Scan a hub and find its devices
* will be a device with uclass UCLASS_USB.
*
* @dev: Device to check
- * @busp: Returns bus, or NULL if not found
- * @return 0 if OK, -EXDEV is somehow this bus does not have a controller (this
- * indicates a critical error in the USB stack
+ * @return The bus, or NULL if not found (this indicates a critical error in
+ * the USB stack
*/
-int usb_get_bus(struct udevice *dev, struct udevice **busp);
+struct udevice *usb_get_bus(struct udevice *dev);
/**
* usb_select_config() - Set up a device ready for use
int usb_hub_probe(struct usb_device *dev, int ifnum);
void usb_hub_reset(void);
-/**
- * legacy_hub_port_reset() - reset a port given its usb_device pointer
- *
- * Reset a hub port and see if a device is present on that port, providing
- * sufficient time for it to show itself. The port status is returned.
+/*
+ * usb_find_usb2_hub_address_port() - Get hub address and port for TT setting
*
- * With driver model this moves to hub_port_reset() and is passed a struct
- * udevice.
+ * Searches for the first HS hub above the given device. If a
+ * HS hub is found, the hub address and the port the device is
+ * connected to is return, as required for SPLIT transactions
*
- * @dev: USB device to reset
- * @port: Port number to reset (note ports are numbered from 0 here)
- * @portstat: Returns port status
+ * @param: udev full speed or low speed device
*/
-int legacy_hub_port_reset(struct usb_device *dev, int port,
- unsigned short *portstat);
-
-int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat);
+void usb_find_usb2_hub_address_port(struct usb_device *udev,
+ uint8_t *hub_address, uint8_t *hub_port);
/**
* usb_alloc_new_device() - Allocate a new device
int usb_alloc_device(struct usb_device *dev);
+/**
+ * usb_update_hub_device() - Update HCD's internal representation of hub
+ *
+ * After a hub descriptor is fetched, notify HCD so that its internal
+ * representation of this hub can be updated.
+ *
+ * @dev: Hub device
+ * @return 0 if OK, -ve on error
+ */
+int usb_update_hub_device(struct usb_device *dev);
+
+/**
+ * usb_get_max_xfer_size() - Get HCD's maximum transfer bytes
+ *
+ * The HCD may have limitation on the maximum bytes to be transferred
+ * in a USB transfer. USB class driver needs to be aware of this.
+ *
+ * @dev: USB device
+ * @size: maximum transfer bytes
+ * @return 0 if OK, -ve on error
+ */
+int usb_get_max_xfer_size(struct usb_device *dev, size_t *size);
+
/**
* usb_emul_setup_device() - Set up a new USB device emulation
*
* the USB emulation uclass about the features of the emulator.
*
* @dev: Emulation device
- * @maxpacketsize: Maximum packet size (e.g. PACKET_SIZE_64)
* @strings: List of USB string descriptors, terminated by a NULL
* entry
* @desc_list: List of points or USB descriptors, terminated by NULL.
* The first entry must be struct usb_device_descriptor,
* and others follow on after that.
- * @return 0 if OK, -ve on error
+ * @return 0 if OK, -ENOSYS if not implemented, other -ve on error
*/
-int usb_emul_setup_device(struct udevice *dev, int maxpacketsize,
- struct usb_string *strings, void **desc_list);
+int usb_emul_setup_device(struct udevice *dev, struct usb_string *strings,
+ void **desc_list);
/**
* usb_emul_control() - Send a control packet to an emulator
int usb_emul_bulk(struct udevice *emul, struct usb_device *udev,
unsigned long pipe, void *buffer, int length);
+/**
+ * usb_emul_int() - Send an interrupt packet to an emulator
+ *
+ * @emul: Emulator device
+ * @udev: USB device (which the emulator is causing to appear)
+ * See struct dm_usb_ops for details on other parameters
+ * @return 0 if OK, -ve on error
+ */
+int usb_emul_int(struct udevice *emul, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length, int interval);
+
/**
* usb_emul_find() - Find an emulator for a particular device
*
- * Check @pipe to find a device number on bus @bus and return it.
+ * Check @pipe and @port1 to find a device number on bus @bus and return it.
*
* @bus: USB bus (controller)
* @pipe: Describes pipe being used, and includes the device number
+ * @port1: Describes port number on the parent hub
+ * @emulp: Returns pointer to emulator, or NULL if not found
+ * @return 0 if found, -ve on error
+ */
+int usb_emul_find(struct udevice *bus, ulong pipe, int port1,
+ struct udevice **emulp);
+
+/**
+ * usb_emul_find_for_dev() - Find an emulator for a particular device
+ *
+ * @dev: USB device to check
* @emulp: Returns pointer to emulator, or NULL if not found
* @return 0 if found, -ve on error
*/
-int usb_emul_find(struct udevice *bus, ulong pipe, struct udevice **emulp);
+int usb_emul_find_for_dev(struct udevice *dev, struct udevice **emulp);
+
+/**
+ * usb_emul_find_descriptor() - Find a USB descriptor of a particular device
+ *
+ * @ptr: a pointer to a list of USB descriptor pointers
+ * @type: type of USB descriptor to find
+ * @index: if @type is USB_DT_CONFIG, this is the configuration value
+ * @return a pointer to the USB descriptor found, NULL if not found
+ */
+struct usb_generic_descriptor **usb_emul_find_descriptor(
+ struct usb_generic_descriptor **ptr, int type, int index);
/**
- * usb_emul_reset() - Reset all emulators ready for use
+ * usb_show_tree() - show the USB device tree
*
- * Clear out any address information in the emulators and make then ready for
- * a new USB scan
+ * This shows a list of active USB devices along with basic information about
+ * each.
*/
-void usb_emul_reset(struct udevice *dev);
+void usb_show_tree(void);
#endif /*_USB_H_ */