From 04145a03db9d78469e0817ab3a767c76c0fb0947 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 20 May 2021 16:21:52 -0400 Subject: [PATCH] USB: UDC: Implement udc_async_callbacks in dummy-hcd This patch adds a udc_async_callbacks handler to the dummy-hcd UDC driver, which will prevent a theoretical race during gadget unbinding. The implementation is simple, since dummy-hcd already has a flag to keep track of whether emulated IRQs are enabled. All the handler has to do is store the enable value in the flag, and avoid setting the flag prematurely. Acked-by: Felipe Balbi Signed-off-by: Alan Stern Link: https://lore.kernel.org/r/20210520202152.GD1216852@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/dummy_hcd.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 7db773c87379..a2d956af42a2 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -934,6 +934,15 @@ static void dummy_udc_set_speed(struct usb_gadget *_gadget, dummy_udc_update_ep0(dum); } +static void dummy_udc_async_callbacks(struct usb_gadget *_gadget, bool enable) +{ + struct dummy *dum = gadget_dev_to_dummy(&_gadget->dev); + + spin_lock_irq(&dum->lock); + dum->ints_enabled = enable; + spin_unlock_irq(&dum->lock); +} + static int dummy_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver); static int dummy_udc_stop(struct usb_gadget *g); @@ -946,6 +955,7 @@ static const struct usb_gadget_ops dummy_ops = { .udc_start = dummy_udc_start, .udc_stop = dummy_udc_stop, .udc_set_speed = dummy_udc_set_speed, + .udc_async_callbacks = dummy_udc_async_callbacks, }; /*-------------------------------------------------------------------------*/ @@ -1005,7 +1015,6 @@ static int dummy_udc_start(struct usb_gadget *g, spin_lock_irq(&dum->lock); dum->devstatus = 0; dum->driver = driver; - dum->ints_enabled = 1; spin_unlock_irq(&dum->lock); return 0;