Skip to content

Commit

Permalink
drv: wait for any drivers to be added before trying to match iface
Browse files Browse the repository at this point in the history
drvBind races with drvAdd. This change ensures that devices won't be
orphaned if added by hcd before adding the corresponding driver in the
single-driver scenario. This does not fix the race in case of
multi-driver scenario, though, hence the "orphaned" todo is left
untouched

JIRA: RTOS-937
  • Loading branch information
adamgreloch committed Jan 3, 2025
1 parent 5c03045 commit 11073b9
Showing 1 changed file with 18 additions and 5 deletions.
23 changes: 18 additions & 5 deletions usb/drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
struct {
handle_t lock;
usb_drv_t *drvs;
handle_t drvAddedCond;
} usbdrv_common;


Expand Down Expand Up @@ -251,11 +252,10 @@ static usb_drv_t *usb_drvMatchIface(usb_dev_t *dev, usb_iface_t *iface)
int i, match, bestmatch = 0;

mutexLock(usbdrv_common.lock);
drv = usbdrv_common.drvs;
if (drv == NULL) {
mutexUnlock(usbdrv_common.lock);
return NULL;
while (usbdrv_common.drvs == NULL) {
condWait(usbdrv_common.drvAddedCond, usbdrv_common.lock, 0);
}
drv = usbdrv_common.drvs;

do {
for (i = 0; i < drv->nfilters; i++) {
Expand Down Expand Up @@ -363,6 +363,9 @@ int usb_drvBind(usb_dev_t *dev)
umsg->insertion.descriptor = dev->desc;
umsg->insertion.locationID = dev->locationID;

/* FIXME: drvAdd races with drvMatchIface in multi-driver scenario.
* Devices may become orphaned forever if they get added by hcd before the driver
* is connected */
for (i = 0; i < dev->nifs; i++) {
if ((drv = usb_drvMatchIface(dev, &dev->ifs[i])) != NULL) {
dev->ifs[i].driver = drv;
Expand Down Expand Up @@ -417,6 +420,7 @@ void usb_drvAdd(usb_drv_t *drv)
idtree_init(&drv->pipes);
idtree_init(&drv->urbs);
LIST_ADD(&usbdrv_common.drvs, drv);
condSignal(usbdrv_common.drvAddedCond);
mutexUnlock(usbdrv_common.lock);
}

Expand Down Expand Up @@ -617,10 +621,19 @@ void usb_drvPipeFree(usb_drv_t *drv, usb_pipe_t *pipe)

int usb_drvInit(void)
{
if (mutexCreate(&usbdrv_common.lock) != 0) {
int ret;

ret = mutexCreate(&usbdrv_common.lock);
if (ret != 0) {
USB_LOG("usbdrv: Can't create mutex!\n");
return -ENOMEM;
}

ret = condCreate(&usbdrv_common.drvAddedCond);
if (ret != 0) {
USB_LOG("usbdrv: Can't create cond!\n");
return -ENOMEM;
}

return 0;
}

0 comments on commit 11073b9

Please sign in to comment.