Module Name: src Committed By: martin Date: Tue Mar 12 12:36:17 UTC 2024
Modified Files: src/sys/dev/usb [netbsd-8]: usbdi.c Log Message: Pull up following revision(s) (requested by riastradh in ticket #1940): sys/dev/usb/usbdi.c: revision 1.248 usbdi(9): Avoid calling ubm_softint with lock held and polling on. PR kern/57783 To generate a diff of this commit: cvs rdiff -u -r1.173.2.5 -r1.173.2.6 src/sys/dev/usb/usbdi.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/usbdi.c diff -u src/sys/dev/usb/usbdi.c:1.173.2.5 src/sys/dev/usb/usbdi.c:1.173.2.6 --- src/sys/dev/usb/usbdi.c:1.173.2.5 Fri Jan 11 15:52:24 2019 +++ src/sys/dev/usb/usbdi.c Tue Mar 12 12:36:17 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi.c,v 1.173.2.5 2019/01/11 15:52:24 martin Exp $ */ +/* $NetBSD: usbdi.c,v 1.173.2.6 2024/03/12 12:36:17 martin Exp $ */ /* * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.173.2.5 2019/01/11 15:52:24 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.173.2.6 2024/03/12 12:36:17 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -1169,14 +1169,34 @@ usbd_dopoll(struct usbd_interface *iface void usbd_set_polling(struct usbd_device *dev, int on) { - if (on) - dev->ud_bus->ub_usepolling++; - else - dev->ud_bus->ub_usepolling--; - /* Kick the host controller when switching modes */ mutex_enter(dev->ud_bus->ub_lock); - dev->ud_bus->ub_methods->ubm_softint(dev->ud_bus); + if (on) { + /* + * Enabling polling. If we're enabling for the first + * time, call the softint routine on transition while + * we hold the lock and polling is still disabled, and + * then enable polling -- once polling is enabled, we + * must not hold the lock when we call the softint + * routine. + */ + KASSERT(dev->ud_bus->ub_usepolling < __type_max(char)); + if (dev->ud_bus->ub_usepolling == 0) + dev->ud_bus->ub_methods->ubm_softint(dev->ud_bus); + dev->ud_bus->ub_usepolling++; + } else { + /* + * Disabling polling. If we're disabling polling for + * the last time, disable polling first and then call + * the softint routine while we hold the lock -- until + * polling is disabled, we must not hold the lock when + * we call the softint routine. + */ + KASSERT(dev->ud_bus->ub_usepolling > 0); + dev->ud_bus->ub_usepolling--; + if (dev->ud_bus->ub_usepolling == 0) + dev->ud_bus->ub_methods->ubm_softint(dev->ud_bus); + } mutex_exit(dev->ud_bus->ub_lock); }