From 482af6d15ca8eed28b51edc11692815419326d65 Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Fri, 24 May 2013 15:48:56 +0200 Subject: libpayload: Redirect USB slave init through controller driver xHCI requires special treatment of set_address since it determines the device number itself (instead of the driver, as with the other controllers). The controller also wants to validate a chosen device configuration and we need to setup additional structures for the device and the endpoints. Therefore, we add three functions to the hci_t structure, namely: set_address() finish_device_config() destroy_device() Current implementation for the Set Address request moved into generic_set_address() which is set_address() for the UHCI, OCHI and EHCI drivers. The latter two are only provided as hooks for the xHCI driver. The Set Configuration request is moved after endpoint enumeration. For all other controller drivers nothing changes, as there is no other device communication between the lines where the set_configuration() call moved. Change-Id: I6127627b9367ef573aa1a1525782bc1304ea350d Signed-off-by: Nico Huber Signed-off-by: Patrick Georgi Reviewed-on: http://review.coreboot.org/3447 Tested-by: build bot (Jenkins) Reviewed-by: Anton Kochkov Reviewed-by: Paul Menzel Reviewed-by: Stefan Reinauer --- payloads/libpayload/include/usb/usb.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'payloads/libpayload/include/usb/usb.h') diff --git a/payloads/libpayload/include/usb/usb.h b/payloads/libpayload/include/usb/usb.h index fc3ce5a50f..3aac2aee6c 100644 --- a/payloads/libpayload/include/usb/usb.h +++ b/payloads/libpayload/include/usb/usb.h @@ -115,7 +115,7 @@ struct usbdev { typedef enum { OHCI = 0, UHCI = 1, EHCI = 2, XHCI = 3} hc_type; struct usbdev_hc { - struct usbdev_hc *next; + hci_t *next; pcidev_t bus_address; u32 reg_base; hc_type type; @@ -143,6 +143,20 @@ struct usbdev_hc { void (*destroy_intr_queue) (endpoint_t *ep, void *queue); u8* (*poll_intr_queue) (void *queue); void *instance; + + /* set_address(): Tell the usb device its address and + return it. xHCI controllers want to + do this by themself. Also, the usbdev + structure has to be allocated and + initialized. */ + int (*set_address) (hci_t *controller, int speed, int hubport, int hubaddr); + /* finish_device_config(): Another hook for xHCI, + returns 0 on success. */ + int (*finish_device_config) (usbdev_t *dev); + /* destroy_device(): Finally, destroy all structures that + were allocated during set_address() + and finish_device_config(). */ + void (*destroy_device) (hci_t *controller, int devaddr); }; typedef struct { @@ -250,6 +264,9 @@ gen_bmRequestType (dev_req_dir dir, dev_req_type type, dev_req_recp recp) return (dir << 7) | (type << 5) | recp; } +/* default "set address" handler */ +int generic_set_address (hci_t *controller, int speed, int hubport, int hubaddr); + void usb_detach_device(hci_t *controller, int devno); int usb_attach_device(hci_t *controller, int hubaddress, int port, int speed); -- cgit v1.2.3