dm-usb fixes + dm conversion for sunxi-ehci
Subsystems (3)
cover dm-usb fixes + dm conversion for sunxi-ehci
Hi All,
Here are a couple of dm-usb fixes and the dm conversion for sunxi-ehci, note that this series is currently still RFC only as I'm still having some issues with USB-1 devices not working which I need to investigate further.
I guess that some of the dm-usb fixed can be applied regardless as they are an improvement over the current status quo.
Regards,
Hans
RFC 1/4 dm: usb: Copy over usb_device values from usb_scan_device() to final usb_device
Currently we copy over a number of usb_device values stored in the on stack struct usb_device probed in usb_scan_device() to the final driver-model managed struct usb_device in usb_child_pre_probe() through usb_device_platdata, and then call usb_select_config() to fill in the rest.
There are 2 problems with this approach:
1) It does not fill in enough fields before calling usb_select_config(), specifically it does not fill in ep0's maxpacketsize causing a div by zero exception in the ehci driver.
2) It unnecessarily redoes a number of usb requests making usb probing slower, and potentially upsetting some devices.
This commit fixes both issues by removing the usb_select_config() call from usb_child_pre_probe(), and instead of copying over things field by field through usb_device_platdata, store a pointer to the in stack usb_device (which is still valid when usb_child_pre_probe() gets called) and copy over the entire struct.
---
Changes in v2:
-Remove code setting controller_dev from usb_child_pre_probe as that is
already done in usb_scan_device() and copied over with the rest
--- drivers/usb/host/usb-uclass.c | 27 ++++++--------------------- include/usb.h | 5 +---- 2 files changed, 7 insertions(+), 25 deletions(-)
drivers/usb/host/usb-uclass.c +6 -21
@@ -535,12 +535,7 @@ int usb_scan_device(struct udevice *parent, int port, } plat =dev_get_parent_platdata (dev);debug ("%s: Probing '%s', plat=%p\n" , __func__, dev->name, plat); - plat->devnum = udev->devnum; - plat->speed = udev->speed; - plat->slot_id = udev->slot_id; - plat->portnr = port; -debug ("** device '%s': stashing slot_id=%d\n" , dev->name, - plat->slot_id); + plat->udev = udev; priv->next_addr++; ret =device_probe (dev);if (ret) {
@@ -599,25 +594,15 @@ int usb_get_bus(struct udevice *dev, struct udevice **busp)int usb_child_pre_probe (struct udevice *dev) { -struct udevice *bus;struct usb_device *udev =dev_get_parentdata (dev);struct usb_dev_platdata *plat =dev_get_parent_platdata (dev); -int ret; - ret =usb_get_bus (dev, &bus); -if (ret) -return ret; - udev->controller_dev = bus; +/* +* Copy over all the values set in the on stack struct usb_device in +* usb_scan_device() to our final struct usb_device for this dev. +*/ + *udev = *(plat->udev); udev->dev = dev; - udev->devnum = plat->devnum; - udev->slot_id = plat->slot_id; - udev->portnr = plat->portnr; - udev->speed = plat->speed; -debug ("** device '%s': getting slot_id=%d\n" , dev->name, plat->slot_id); - - ret =usb_select_config (udev); -if (ret) -return ret;return 0 ; }
include/usb.h +1 -4
@@ -581,10 +581,7 @@ struct usb_platdata {*/ 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 */ +struct usb_device *udev;#ifdef CONFIG_SANDBOX struct usb_string *strings;/* NULL-terminated list of descriptor pointers */
Signature · 1 line
2.3.6
RFC 2/4 dm: usb: Use controller_dev in dm ehci code
In reply to Hans de GoedeUse the controller_dev pointer in the ehci hcd code rather then going up the tree till we find the first UCLASS_USB device.
--- drivers/usb/host/ehci-hcd.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
drivers/usb/host/ehci-hcd.c +1 -8
@@ -125,14 +125,7 @@ static struct descriptor {static struct ehci_ctrl *ehci_get_ctrl (struct usb_device *udev) {#ifdef CONFIG_DM_USB -struct udevice *dev; - -/* Find the USB controller */ -for (dev = udev->dev; -device_get_uclass_id (dev) !=UCLASS_USB ; - dev = dev->parent) - ; -return dev_get_priv (dev); +return dev_get_priv (udev->controller_dev);#else return udev->controller;#endif
Signature · 1 line
2.3.6
RFC 3/4 dm: usb: Store usb_device parent pointer in usb_device
In reply to Hans de GoedeWhen calling into the hcd code in usb_scan_device() we do not yet have the actual udevice for the device we are scanning, so we temporarily set usb_device.dev to the parent.
This means that we cannot use usb_device.dev to accurately determine our place in the usb topology when reading descriptors, and this is necessary to correctly program the usb-2 hub tt settings when a usb-1 device is connected to a usb-2 hub.
This commit (re)adds a direct parent usb_device pointer to struct usb_device so that the usb hcd code can get to the usb_device parent without needing to go through the dm.
This fixes usb-1 devices plugged into usb-2 hubs not working with the driver model.
--- drivers/usb/host/ehci-hcd.c | 24 +----------------------- drivers/usb/host/usb-uclass.c | 5 ++--- include/usb.h | 2 +- 3 files changed, 4 insertions(+), 27 deletions(-)
drivers/usb/host/ehci-hcd.c +1 -23
@@ -292,7 +292,6 @@ static void ehci_update_endpt2_dev_n_port(struct usb_device *udev, struct QH *qh) {struct usb_device *ttdev; -int parent_devnum;if (udev->speed !=USB_SPEED_LOW && udev->speed !=USB_SPEED_FULL )return ;
@@ -302,35 +301,14 @@ static void ehci_update_endpt2_dev_n_port(struct usb_device *udev,* the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs * in the tree before that one! */ -#ifdef CONFIG_DM_USB -struct udevice *parent; - -for (ttdev = udev; ; ) { -struct udevice *dev = ttdev->dev; - -if (dev->parent && -device_get_uclass_id (dev->parent) ==UCLASS_USB_HUB ) - parent = dev->parent; -else - parent =NULL ; -if (!parent) -return ; - ttdev =dev_get_parentdata (parent); -if (!ttdev->speed !=USB_SPEED_HIGH ) -break ; - } - parent_devnum = ttdev->devnum; -#else ttdev = udev;while (ttdev->parent && ttdev->parent->speed !=USB_SPEED_HIGH ) ttdev = ttdev->parent;if (!ttdev->parent)return ; - parent_devnum = ttdev->parent->devnum; -#endif qh->qh_endpt2 |=cpu_to_hc32 (QH_ENDPT2_PORTNUM (ttdev->portnr) | -QH_ENDPT2_HUBADDR (parent_devnum)); +QH_ENDPT2_HUBADDR (ttdev->parent->devnum)); } static int
drivers/usb/host/usb-uclass.c +2 -3
@@ -470,7 +470,6 @@ int usb_scan_device(struct udevice *parent, int port,bool created = false;struct usb_dev_platdata *plat;struct usb_bus_priv *priv; -struct usb_device *parent_udev;int ret; ALLOC_CACHE_ALIGN_BUFFER(struct usb_device, udev, 1);struct usb_interface_descriptor *iface = &udev->config.if_desc[0 ].desc;
@@ -515,9 +514,9 @@ int usb_scan_device(struct udevice *parent, int port, udev->devnum = priv->next_addr +1 ; udev->portnr = port;debug ("Calling usb_setup_device(), portnr=%d\n" , udev->portnr); - parent_udev =device_get_uclass_id (parent) ==UCLASS_USB_HUB ? + udev->parent =device_get_uclass_id (parent) ==UCLASS_USB_HUB ?dev_get_parentdata (parent) :NULL ; - ret =usb_setup_device (udev, priv->desc_before_addr, parent_udev, port); + ret =usb_setup_device (udev, priv->desc_before_addr, udev->parent, port);debug ("read_descriptor for '%s': ret=%d\n" , parent->name, ret);if (ret)return ret;
include/usb.h +1 -1
@@ -141,9 +141,9 @@ struct usb_device {int act_len;/* transfered bytes */ int maxchild;/* Number of ports if hub */ int portnr;/* Port number, 1=first */ -#ifndef CONFIG_DM_USB /* parent hub, or NULL if this is the root hub */ struct usb_device *parent; +#ifndef CONFIG_DM_USB struct usb_device *children[USB_MAXCHILDREN ];void *controller;/* hardware controller private data */ #endif
Signature · 1 line
2.3.6
RFC 4/4 sunxi: ehci: Convert to the driver-model
In reply to Hans de GoedeConvert sunxi-boards which use the sunxi-ehci code to the driver-model.
--- board/sunxi/Kconfig | 3 ++ drivers/usb/host/ehci-sunxi.c | 95 ++++++++++++++++++++++++++++++------------- 2 files changed, 69 insertions(+), 29 deletions(-)
board/sunxi/Kconfig +3 -0
@@ -559,4 +559,7 @@ config DM_ETH config DM_SERIAL default y +config DM_USB + default y if !USB_MUSB_SUNXI + endif
drivers/usb/host/ehci-sunxi.c +66 -29
119 lines not on this page · raw message
Signature · 1 line
2.3.6
cover dm-usb fixes + dm conversion for sunxi-ehci
In reply to Hans de GoedeHi,
Quoted 6 lines · Hans de Goede
Hi All,
Here are a couple of dm-usb fixes and the dm conversion for sunxi-ehci, note that this series is currently still RFC only as I'm still having some issues with USB-1 devices not working which I need to investigate further.
Quoted 6 lines
I guess that some of the dm-usb fixed can be applied regardless as they are an improvement over the current status quo.
Regards,
Hans
p.s.
This series also fixes the dm usb reset issue I was seeing, that was an issue in the dm conversion of ehci-sunxi.c and thus entirely my fault.
Regards,
Hans