diff options
Diffstat (limited to 'sys/dev/usb')
-rw-r--r-- | sys/dev/usb/controller/usb_controller.c | 30 | ||||
-rw-r--r-- | sys/dev/usb/input/ukbd.c | 13 | ||||
-rw-r--r-- | sys/dev/usb/net/usb_ethernet.c | 11 | ||||
-rw-r--r-- | sys/dev/usb/usb_compat_linux.c | 27 | ||||
-rw-r--r-- | sys/dev/usb/usb_dev.c | 6 | ||||
-rw-r--r-- | sys/dev/usb/usb_handle_request.c | 12 | ||||
-rw-r--r-- | sys/dev/usb/usb_hub.c | 19 | ||||
-rw-r--r-- | sys/dev/usb/wlan/if_upgt.c | 4 |
8 files changed, 57 insertions, 65 deletions
diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c index 7a019dc..f6776f01 100644 --- a/sys/dev/usb/controller/usb_controller.c +++ b/sys/dev/usb/controller/usb_controller.c @@ -143,9 +143,7 @@ usb_attach(device_t dev) } if (usb_post_init_called) { - mtx_lock(&Giant); usb_attach_sub(dev, bus); - mtx_unlock(&Giant); usb_needs_explore(bus, 1); } return (0); /* return success */ @@ -228,20 +226,13 @@ usb_bus_explore(struct usb_proc_msg *pm) } USB_BUS_UNLOCK(bus); - mtx_lock(&Giant); - /* * First update the USB power state! */ usb_bus_powerd(bus); - /* - * Explore the Root USB HUB. This call can sleep, - * exiting Giant, which is actually Giant. - */ - (udev->hub->explore) (udev); - - mtx_unlock(&Giant); + /* Explore the Root USB HUB. */ + (udev->hub->explore) (udev); USB_BUS_LOCK(bus); } if (bus->bus_roothold != NULL) { @@ -269,7 +260,7 @@ usb_bus_detach(struct usb_proc_msg *pm) device_set_softc(dev, NULL); USB_BUS_UNLOCK(bus); - mtx_lock(&Giant); + newbus_xlock(); /* detach children first */ bus_generic_detach(dev); @@ -281,7 +272,7 @@ usb_bus_detach(struct usb_proc_msg *pm) usb_free_device(udev, USB_UNCFG_FLAG_FREE_EP0); - mtx_unlock(&Giant); + newbus_xunlock(); USB_BUS_LOCK(bus); /* clear bdev variable last */ bus->bdev = NULL; @@ -350,7 +341,7 @@ usb_bus_attach(struct usb_proc_msg *pm) } USB_BUS_UNLOCK(bus); - mtx_lock(&Giant); /* XXX not required by USB */ + newbus_xlock(); /* default power_mask value */ bus->hw_power_state = @@ -383,7 +374,7 @@ usb_bus_attach(struct usb_proc_msg *pm) err = USB_ERR_NOMEM; } - mtx_unlock(&Giant); + newbus_xunlock(); USB_BUS_LOCK(bus); if (err) { @@ -472,7 +463,7 @@ usb_post_init(void *arg) int max; int n; - mtx_lock(&Giant); + newbus_xlock(); usb_devclass_ptr = devclass_find("usbus"); @@ -483,11 +474,8 @@ usb_post_init(void *arg) dev = devclass_get_device(dc, n); if (dev && device_is_attached(dev)) { bus = device_get_ivars(dev); - if (bus) { - mtx_lock(&Giant); + if (bus) usb_attach_sub(dev, bus); - mtx_unlock(&Giant); - } } } } else { @@ -499,7 +487,7 @@ usb_post_init(void *arg) usb_needs_explore_all(); - mtx_unlock(&Giant); + newbus_xunlock(); } SYSINIT(usb_post_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, usb_post_init, NULL); diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c index 0d09ad4..2170b37 100644 --- a/sys/dev/usb/input/ukbd.c +++ b/sys/dev/usb/input/ukbd.c @@ -745,7 +745,7 @@ ukbd_attach(device_t dev) uint16_t n; uint16_t hid_len; - mtx_assert(&Giant, MA_OWNED); + mtx_lock(&Giant); kbd_init_struct(kbd, UKBD_DRIVER_NAME, KB_OTHER, unit, 0, 0, 0); @@ -854,9 +854,6 @@ ukbd_attach(device_t dev) if (bootverbose) { genkbd_diag(kbd, bootverbose); } - /* lock keyboard mutex */ - - mtx_lock(&Giant); /* start the keyboard */ @@ -879,7 +876,7 @@ ukbd_detach(device_t dev) struct ukbd_softc *sc = device_get_softc(dev); int error; - mtx_assert(&Giant, MA_OWNED); + mtx_lock(&Giant); DPRINTF("\n"); @@ -916,6 +913,8 @@ ukbd_detach(device_t dev) usb_callout_drain(&sc->sc_callout); + mtx_unlock(&Giant); + DPRINTF("%s: disconnected\n", device_get_nameunit(dev)); @@ -927,9 +926,9 @@ ukbd_resume(device_t dev) { struct ukbd_softc *sc = device_get_softc(dev); - mtx_assert(&Giant, MA_OWNED); - + mtx_lock(&Giant); ukbd_clear_state(&sc->sc_kbd); + mtx_unlock(&Giant); return (0); } diff --git a/sys/dev/usb/net/usb_ethernet.c b/sys/dev/usb/net/usb_ethernet.c index 6cf4460..427137a 100644 --- a/sys/dev/usb/net/usb_ethernet.c +++ b/sys/dev/usb/net/usb_ethernet.c @@ -221,10 +221,10 @@ ue_attach_post_task(struct usb_proc_msg *_task) if (ue->ue_methods->ue_mii_upd != NULL && ue->ue_methods->ue_mii_sts != NULL) { - mtx_lock(&Giant); /* device_xxx() depends on this */ + newbus_xlock(); error = mii_phy_probe(ue->ue_dev, &ue->ue_miibus, ue_ifmedia_upd, ue->ue_methods->ue_mii_sts); - mtx_unlock(&Giant); + newbus_xunlock(); if (error) { device_printf(ue->ue_dev, "MII without any PHY\n"); goto error; @@ -279,9 +279,12 @@ uether_ifdetach(struct usb_ether *ue) /* detach miibus */ if (ue->ue_miibus != NULL) { - mtx_lock(&Giant); /* device_xxx() depends on this */ + + /* + * It is up to the callers to provide the correct + * newbus locking. + */ device_delete_child(ue->ue_dev, ue->ue_miibus); - mtx_unlock(&Giant); } /* detach ethernet */ diff --git a/sys/dev/usb/usb_compat_linux.c b/sys/dev/usb/usb_compat_linux.c index 604ac4d..00fc86b 100644 --- a/sys/dev/usb/usb_compat_linux.c +++ b/sys/dev/usb/usb_compat_linux.c @@ -215,14 +215,12 @@ usb_linux_probe(device_t dev) if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } - mtx_lock(&Giant); LIST_FOREACH(udrv, &usb_linux_driver_list, linux_driver_list) { if (usb_linux_lookup_id(udrv->id_table, uaa)) { err = 0; break; } } - mtx_unlock(&Giant); return (err); } @@ -239,9 +237,7 @@ usb_linux_get_usb_driver(struct usb_linux_softc *sc) { struct usb_driver *udrv; - mtx_lock(&Giant); udrv = sc->sc_udrv; - mtx_unlock(&Giant); return (udrv); } @@ -260,13 +256,11 @@ usb_linux_attach(device_t dev) struct usb_driver *udrv; const struct usb_device_id *id = NULL; - mtx_lock(&Giant); LIST_FOREACH(udrv, &usb_linux_driver_list, linux_driver_list) { id = usb_linux_lookup_id(udrv->id_table, uaa); if (id) break; } - mtx_unlock(&Giant); if (id == NULL) { return (ENXIO); @@ -287,9 +281,7 @@ usb_linux_attach(device_t dev) return (ENXIO); } } - mtx_lock(&Giant); LIST_INSERT_HEAD(&usb_linux_attached_list, sc, sc_attached_list); - mtx_unlock(&Giant); /* success */ return (0); @@ -307,14 +299,12 @@ usb_linux_detach(device_t dev) struct usb_linux_softc *sc = device_get_softc(dev); struct usb_driver *udrv = NULL; - mtx_lock(&Giant); if (sc->sc_attached_list.le_prev) { LIST_REMOVE(sc, sc_attached_list); sc->sc_attached_list.le_prev = NULL; udrv = sc->sc_udrv; sc->sc_udrv = NULL; } - mtx_unlock(&Giant); if (udrv && udrv->disconnect) { (udrv->disconnect) (sc->sc_ui); @@ -474,13 +464,10 @@ usb_unlink_bsd(struct usb_xfer *xfer, if (!usbd_transfer_pending(xfer)) return; if (xfer->priv_fifo == (void *)urb) { - if (drain) { - mtx_unlock(&Giant); + if (drain) usbd_transfer_drain(xfer); - mtx_lock(&Giant); - } else { + else usbd_transfer_stop(xfer); - } usbd_transfer_start(xfer); } } @@ -1148,9 +1135,9 @@ usb_linux_register(void *arg) { struct usb_driver *drv = arg; - mtx_lock(&Giant); + newbus_xlock(); LIST_INSERT_HEAD(&usb_linux_driver_list, drv, linux_driver_list); - mtx_unlock(&Giant); + newbus_xunlock(); usb_needs_explore_all(); } @@ -1172,16 +1159,16 @@ usb_linux_deregister(void *arg) struct usb_linux_softc *sc; repeat: - mtx_lock(&Giant); + newbus_xlock(); LIST_FOREACH(sc, &usb_linux_attached_list, sc_attached_list) { if (sc->sc_udrv == drv) { - mtx_unlock(&Giant); device_detach(sc->sc_fbsd_dev); + newbus_xunlock(); goto repeat; } } LIST_REMOVE(drv, linux_driver_list); - mtx_unlock(&Giant); + newbus_xunlock(); } /*------------------------------------------------------------------------* diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c index cba8919..b7c6553 100644 --- a/sys/dev/usb/usb_dev.c +++ b/sys/dev/usb/usb_dev.c @@ -1040,9 +1040,14 @@ usb_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread* * Performance optimisation: We try to check for IOCTL's that * don't need the USB reference first. Then we grab the USB * reference if we need it! + * Note that some ioctl_post handlers would need to run with the + * newbus lock held. It cannot be acquired later because it can + * introduce a LOR, so acquire it here. */ + newbus_xlock(); err = usb_ref_device(cpd, &refs, 0 /* no uref */ ); if (err) { + newbus_xunlock(); return (ENXIO); } fflags = cpd->fflags; @@ -1076,6 +1081,7 @@ usb_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int fflag, struct thread* } done: usb_unref_device(cpd, &refs); + newbus_xunlock(); return (err); } diff --git a/sys/dev/usb/usb_handle_request.c b/sys/dev/usb/usb_handle_request.c index a720919..2bc3eef 100644 --- a/sys/dev/usb/usb_handle_request.c +++ b/sys/dev/usb/usb_handle_request.c @@ -152,7 +152,7 @@ usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no) * attach: */ USB_XFER_UNLOCK(xfer); - mtx_lock(&Giant); /* XXX */ + newbus_xlock(); sx_xlock(udev->default_sx + 1); if (conf_no == USB_UNCONFIG_NO) { @@ -176,8 +176,8 @@ usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no) goto done; } done: - mtx_unlock(&Giant); /* XXX */ sx_unlock(udev->default_sx + 1); + newbus_xunlock(); USB_XFER_LOCK(xfer); return (err); } @@ -236,7 +236,7 @@ usb_handle_iface_request(struct usb_xfer *xfer, * attach: */ USB_XFER_UNLOCK(xfer); - mtx_lock(&Giant); /* XXX */ + newbus_xlock(); sx_xlock(udev->default_sx + 1); error = ENXIO; @@ -353,20 +353,20 @@ tr_repeat: goto tr_stalled; } tr_valid: - mtx_unlock(&Giant); sx_unlock(udev->default_sx + 1); + newbus_xunlock(); USB_XFER_LOCK(xfer); return (0); tr_short: - mtx_unlock(&Giant); sx_unlock(udev->default_sx + 1); + newbus_xunlock(); USB_XFER_LOCK(xfer); return (USB_ERR_SHORT_XFER); tr_stalled: - mtx_unlock(&Giant); sx_unlock(udev->default_sx + 1); + newbus_xunlock(); USB_XFER_LOCK(xfer); return (USB_ERR_STALLED); } diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index 0defc97..a09be96 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -234,8 +234,10 @@ uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up) if (child->driver_added_refcount != refcount) { child->driver_added_refcount = refcount; + newbus_xlock(); err = usb_probe_and_attach(child, USB_IFACE_INDEX_ANY); + newbus_xunlock(); if (err) { goto done; } @@ -318,9 +320,11 @@ repeat: /* detach any existing devices */ if (child) { + newbus_xlock(); usb_free_device(child, USB_UNCFG_FLAG_FREE_SUBDEV | USB_UNCFG_FLAG_FREE_EP0); + newbus_xunlock(); child = NULL; } /* get fresh status */ @@ -428,9 +432,10 @@ repeat: mode = USB_MODE_HOST; /* need to create a new child */ - + newbus_xlock(); child = usb_alloc_device(sc->sc_dev, udev->bus, udev, udev->depth + 1, portno - 1, portno, speed, mode); + newbus_xunlock(); if (child == NULL) { DPRINTFN(0, "could not allocate new device!\n"); goto error; @@ -439,9 +444,11 @@ repeat: error: if (child) { + newbus_xlock(); usb_free_device(child, USB_UNCFG_FLAG_FREE_SUBDEV | USB_UNCFG_FLAG_FREE_EP0); + newbus_xunlock(); child = NULL; } if (err == 0) { @@ -980,7 +987,6 @@ uhub_child_location_string(device_t parent, device_t child, struct usb_hub *hub = sc->sc_udev->hub; struct hub_result res; - mtx_lock(&Giant); uhub_find_iface_index(hub, child, &res); if (!res.udev) { DPRINTF("device not on hub\n"); @@ -992,7 +998,6 @@ uhub_child_location_string(device_t parent, device_t child, snprintf(buf, buflen, "port=%u interface=%u", res.portno, res.iface_index); done: - mtx_unlock(&Giant); return (0); } @@ -1006,7 +1011,6 @@ uhub_child_pnpinfo_string(device_t parent, device_t child, struct usb_interface *iface; struct hub_result res; - mtx_lock(&Giant); uhub_find_iface_index(hub, child, &res); if (!res.udev) { DPRINTF("device not on hub\n"); @@ -1037,7 +1041,6 @@ uhub_child_pnpinfo_string(device_t parent, device_t child, goto done; } done: - mtx_unlock(&Giant); return (0); } @@ -1775,10 +1778,13 @@ usb_dev_resume_peer(struct usb_device *udev) /* always update hardware power! */ (bus->methods->set_hw_power) (bus); } + newbus_xlock(); sx_xlock(udev->default_sx + 1); + /* notify all sub-devices about resume */ err = usb_suspend_resume(udev, 0); sx_unlock(udev->default_sx + 1); + newbus_xunlock(); /* check if peer has wakeup capability */ if (usb_peer_can_wakeup(udev)) { @@ -1844,10 +1850,13 @@ repeat: } } + newbus_xlock(); sx_xlock(udev->default_sx + 1); + /* notify all sub-devices about suspend */ err = usb_suspend_resume(udev, 1); sx_unlock(udev->default_sx + 1); + newbus_xunlock(); if (usb_peer_can_wakeup(udev)) { /* allow device to do remote wakeup */ diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c index ff3220b..8714645 100644 --- a/sys/dev/usb/wlan/if_upgt.c +++ b/sys/dev/usb/wlan/if_upgt.c @@ -465,7 +465,7 @@ upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) switch (cmd) { case SIOCSIFFLAGS: - mtx_lock(&Giant); + newbus_xlock(); if (ifp->if_flags & IFF_UP) { if (ifp->if_drv_flags & IFF_DRV_RUNNING) { if ((ifp->if_flags ^ sc->sc_if_flags) & @@ -482,7 +482,7 @@ upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sc->sc_if_flags = ifp->if_flags; if (startall) ieee80211_start_all(ic); - mtx_unlock(&Giant); + newbus_xunlock(); break; case SIOCGIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); |