From 31232de07ef2bd97ff67625976eecd97eeb1bd3d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 6 Apr 2020 14:29:44 +0200 Subject: usb: Keep async schedule running only across mass storage xfers Rather than keeping the asynchronous schedule running always, keep it running only across USB mass storage transfers for now, as it seems that keeping it running all the time interferes with certain control transfers during device enumeration. Note that running the async schedule all the time should not be an issue, especially on EHCI HCD, as that one implements most of the transfers using async schedule. Note that we have usb_disable_asynch(), which however is utterly broken. The usb_disable_asynch() blocks the USB core from doing async transfers by setting a global flag. The async schedule should however be disabled per USB controller. Moreover, setting a global flag does not prevent the controller from using the async schedule, which e.g. the EHCI HCD does. This patch implements additional callback to the controller, which permits it to lock the async schedule and keep it running across multiple transfers. Once the schedule is unlocked, it must also be disabled. This thus prevents the async schedule from running outside of the USB mass storage transfers. Signed-off-by: Marek Vasut Cc: Lukasz Majewski Cc: Tom Rini Tested-by: Tom Rini [omap3_beagle, previously failing] --- drivers/usb/host/usb-uclass.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/usb/host/usb-uclass.c') diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index 8521651588..5e423012df 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -22,6 +22,17 @@ struct usb_uclass_priv { int companion_device_count; }; +int usb_lock_async(struct usb_device *udev, int lock) +{ + struct udevice *bus = udev->controller_dev; + struct dm_usb_ops *ops = usb_get_ops(bus); + + if (!ops->lock_async) + return -ENOSYS; + + return ops->lock_async(bus, lock); +} + int usb_disable_asynch(int disable) { int old_value = asynch_allowed; -- cgit v1.2.1