Index: sys/compat/linuxkpi/common/include/linux/device.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/device.h +++ sys/compat/linuxkpi/common/include/linux/device.h @@ -441,9 +441,9 @@ dev->bsddev = NULL; if (bsddev != NULL && dev->bsddev_attached_here) { - mtx_lock(&Giant); + newbus_lock(); device_delete_child(device_get_parent(bsddev), bsddev); - mtx_unlock(&Giant); + newbus_unlock(); } put_device(dev); } @@ -457,9 +457,9 @@ dev->bsddev = NULL; if (bsddev != NULL && dev->bsddev_attached_here) { - mtx_lock(&Giant); + newbus_lock(); device_delete_child(device_get_parent(bsddev), bsddev); - mtx_unlock(&Giant); + newbus_unlock(); } } Index: sys/compat/linuxkpi/common/src/linux_pci.c =================================================================== --- sys/compat/linuxkpi/common/src/linux_pci.c +++ sys/compat/linuxkpi/common/src/linux_pci.c @@ -368,10 +368,10 @@ pdrv->bsddriver.methods = pci_methods; pdrv->bsddriver.size = sizeof(struct pci_dev); - mtx_lock(&Giant); + newbus_lock(); error = devclass_add_driver(dc, &pdrv->bsddriver, BUS_PASS_DEFAULT, &pdrv->bsdclass); - mtx_unlock(&Giant); + newbus_unlock(); return (-error); } @@ -440,10 +440,10 @@ spin_lock(&pci_lock); list_del(&pdrv->links); spin_unlock(&pci_lock); - mtx_lock(&Giant); + newbus_lock(); if (bus != NULL) devclass_delete_driver(bus, &pdrv->bsddriver); - mtx_unlock(&Giant); + newbus_unlock(); } void @@ -456,10 +456,10 @@ spin_lock(&pci_lock); list_del(&pdrv->links); spin_unlock(&pci_lock); - mtx_lock(&Giant); + newbus_lock(); if (bus != NULL) devclass_delete_driver(bus, &pdrv->bsddriver); - mtx_unlock(&Giant); + newbus_unlock(); } CTASSERT(sizeof(dma_addr_t) <= sizeof(uint64_t)); Index: sys/compat/linuxkpi/common/src/linux_usb.c =================================================================== --- sys/compat/linuxkpi/common/src/linux_usb.c +++ sys/compat/linuxkpi/common/src/linux_usb.c @@ -1182,7 +1182,9 @@ LIST_FOREACH(sc, &usb_linux_attached_list, sc_attached_list) { if (sc->sc_udrv == drv) { mtx_unlock(&Giant); + newbus_lock(); device_detach(sc->sc_fbsd_dev); + newbus_unlock(); goto repeat; } } Index: sys/dev/aac/aac.c =================================================================== --- sys/dev/aac/aac.c +++ sys/dev/aac/aac.c @@ -3306,10 +3306,10 @@ while (co != NULL) { if (co->co_found == 0) { mtx_unlock(&sc->aac_io_lock); - mtx_lock(&Giant); + newbus_lock(); device_delete_child(sc->aac_dev, co->co_disk); - mtx_unlock(&Giant); + newbus_unlock(); mtx_lock(&sc->aac_io_lock); co_next = TAILQ_NEXT(co, co_link); mtx_lock(&sc->aac_container_lock); @@ -3327,9 +3327,9 @@ /* Attach the newly created containers */ if (added) { mtx_unlock(&sc->aac_io_lock); - mtx_lock(&Giant); + newbus_lock(); bus_generic_attach(sc->aac_dev); - mtx_unlock(&Giant); + newbus_unlock(); mtx_lock(&sc->aac_io_lock); } Index: sys/dev/acpica/acpi.c =================================================================== --- sys/dev/acpica/acpi.c +++ sys/dev/acpica/acpi.c @@ -3029,10 +3029,9 @@ #endif /* - * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE - * drivers need this. + * Be sure to hold Giant across DEVICE_SUSPEND/RESUME */ - mtx_lock(&Giant); + newbus_lock(); slp_state = ACPI_SS_NONE; @@ -3158,7 +3157,7 @@ } sc->acpi_next_sstate = 0; - mtx_unlock(&Giant); + newbus_unlock(); #ifdef EARLY_AP_STARTUP thread_lock(curthread); Index: sys/dev/acpica/acpi_dock.c =================================================================== --- sys/dev/acpica/acpi_dock.c +++ sys/dev/acpica/acpi_dock.c @@ -191,9 +191,9 @@ if (!device_is_enabled(dev)) device_enable(dev); - mtx_lock(&Giant); + newbus_lock(); device_probe_and_attach(dev); - mtx_unlock(&Giant); + newbus_unlock(); } static ACPI_STATUS @@ -304,9 +304,9 @@ dev = acpi_get_device(handle); if (dev != NULL && device_is_attached(dev)) { - mtx_lock(&Giant); + newbus_lock(); device_detach(dev); - mtx_unlock(&Giant); + newbus_unlock(); } acpi_SetInteger(handle, "_EJ0", 0); Index: sys/dev/acpica/acpi_pci.c =================================================================== --- sys/dev/acpica/acpi_pci.c +++ sys/dev/acpica/acpi_pci.c @@ -339,9 +339,9 @@ switch (notify) { case ACPI_NOTIFY_BUS_CHECK: - mtx_lock(&Giant); + newbus_lock(); BUS_RESCAN(dev); - mtx_unlock(&Giant); + newbus_unlock(); break; default: device_printf(dev, "unknown notify %#x\n", notify); @@ -360,9 +360,9 @@ switch (notify) { case ACPI_NOTIFY_DEVICE_CHECK: - mtx_lock(&Giant); + newbus_lock(); BUS_RESCAN(dev); - mtx_unlock(&Giant); + newbus_unlock(); break; case ACPI_NOTIFY_EJECT_REQUEST: child = acpi_get_device(h); @@ -371,23 +371,23 @@ acpi_name(h)); return; } - mtx_lock(&Giant); + newbus_lock(); error = device_detach(child); if (error) { - mtx_unlock(&Giant); + newbus_unlock(); device_printf(dev, "failed to detach %s: %d\n", device_get_nameunit(child), error); return; } status = acpi_SetInteger(h, "_EJ0", 1); if (ACPI_FAILURE(status)) { - mtx_unlock(&Giant); + newbus_unlock(); device_printf(dev, "failed to eject %s: %s\n", acpi_name(h), AcpiFormatException(status)); return; } BUS_RESCAN(dev); - mtx_unlock(&Giant); + newbus_unlock(); break; default: device_printf(dev, "unknown notify %#x for %s\n", notify, Index: sys/dev/bhnd/cores/chipc/chipc.c =================================================================== --- sys/dev/bhnd/cores/chipc/chipc.c +++ sys/dev/bhnd/cores/chipc/chipc.c @@ -1170,13 +1170,13 @@ if (!CHIPC_QUIRK(sc, MUX_SPROM)) return (true); - mtx_lock(&Giant); /* for newbus */ + newbus_lock(); parent = device_get_parent(sc->dev); hostb = bhnd_bus_find_hostb_device(parent); if ((error = device_get_children(parent, &devs, &devcount))) { - mtx_unlock(&Giant); + newbus_unlock(); return (false); } @@ -1199,7 +1199,7 @@ } free(devs, M_TEMP); - mtx_unlock(&Giant); + newbus_unlock(); return (result); } Index: sys/dev/cardbus/cardbus.c =================================================================== --- sys/dev/cardbus/cardbus.c +++ sys/dev/cardbus/cardbus.c @@ -198,7 +198,7 @@ domain = pcib_get_domain(cbdev); bus = pcib_get_bus(cbdev); slot = 0; - mtx_lock(&Giant); + newbus_lock(); /* For each function, set it up and try to attach a driver to it */ for (func = 0; func <= cardbusfunchigh; func++) { struct cardbus_devinfo *dinfo; @@ -232,7 +232,7 @@ else pci_cfg_save(dinfo->pci.cfg.dev, &dinfo->pci, 1); } - mtx_unlock(&Giant); + newbus_unlock(); if (cardattached > 0) return (0); /* POWER_DISABLE_SOCKET(brdev, cbdev); */ Index: sys/dev/drm2/drm_dp_iic_helper.c =================================================================== --- sys/dev/drm2/drm_dp_iic_helper.c +++ sys/dev/drm2/drm_dp_iic_helper.c @@ -228,12 +228,12 @@ int idx, error; static int dp_bus_counter; - mtx_lock(&Giant); + newbus_lock(); idx = atomic_fetchadd_int(&dp_bus_counter, 1); ibus = device_add_child(dev, "drm_iic_dp_aux", idx); if (ibus == NULL) { - mtx_unlock(&Giant); + newbus_unlock(); DRM_ERROR("drm_iic_dp_aux bus %d creation error\n", idx); return (-ENXIO); } @@ -241,7 +241,7 @@ error = device_probe_and_attach(ibus); if (error != 0) { device_delete_child(dev, ibus); - mtx_unlock(&Giant); + newbus_unlock(); DRM_ERROR("drm_iic_dp_aux bus %d attach failed, %d\n", idx, error); return (-error); @@ -256,7 +256,7 @@ *bus = ibus; *adapter = data->port; } - mtx_unlock(&Giant); + newbus_unlock(); return (-error); } Index: sys/dev/drm2/drm_fops.c =================================================================== --- sys/dev/drm2/drm_fops.c +++ sys/dev/drm2/drm_fops.c @@ -157,9 +157,7 @@ return 0; err_undo: - mtx_lock(&Giant); /* FIXME: Giant required? */ device_unbusy(dev->dev); - mtx_unlock(&Giant); dev->open_count--; sx_xunlock(&drm_global_mutex); return -retcode; @@ -273,9 +271,7 @@ list_add(&priv->lhead, &dev->filelist); DRM_UNLOCK(dev); - mtx_lock(&Giant); /* FIXME: Giant required? */ device_busy(dev->dev); - mtx_unlock(&Giant); ret = devfs_set_cdevpriv(priv, drm_release); if (ret != 0) @@ -453,9 +449,7 @@ */ atomic_inc(&dev->counts[_DRM_STAT_CLOSES]); - mtx_lock(&Giant); device_unbusy(dev->dev); - mtx_unlock(&Giant); if (!--dev->open_count) { if (atomic_read(&dev->ioctl_count)) { DRM_ERROR("Device busy: %d\n", Index: sys/dev/fdc/fdc.c =================================================================== --- sys/dev/fdc/fdc.c +++ sys/dev/fdc/fdc.c @@ -2070,7 +2070,7 @@ fd = device_get_softc(dev); g_waitfor_event(fd_detach_geom, fd, M_WAITOK, NULL); - while (device_get_state(dev) == DS_BUSY) + while (device_is_busy(dev)) tsleep(fd, PZERO, "fdd", hz/10); callout_drain(&fd->toffhandle); Index: sys/dev/gpio/gpiopps.c =================================================================== --- sys/dev/gpio/gpiopps.c +++ sys/dev/gpio/gpiopps.c @@ -73,9 +73,7 @@ /* We can't be unloaded while open, so mark ourselves BUSY. */ mtx_lock(&sc->pps_mtx); - if (device_get_state(sc->dev) < DS_BUSY) { - device_busy(sc->dev); - } + device_busy(sc->dev); mtx_unlock(&sc->pps_mtx); return 0; @@ -86,10 +84,6 @@ { struct pps_softc *sc = dev->si_drv1; - /* - * Un-busy on last close. We rely on the vfs counting stuff to only call - * this routine on last-close, so we don't need any open-count logic. - */ mtx_lock(&sc->pps_mtx); device_unbusy(sc->dev); mtx_unlock(&sc->pps_mtx); @@ -113,6 +107,7 @@ static struct cdevsw pps_cdevsw = { .d_version = D_VERSION, + .d_flags = D_TRACKCLOSE, .d_open = gpiopps_open, .d_close = gpiopps_close, .d_ioctl = gpiopps_ioctl, Index: sys/dev/hyperv/pcib/vmbus_pcib.c =================================================================== --- sys/dev/hyperv/pcib/vmbus_pcib.c +++ sys/dev/hyperv/pcib/vmbus_pcib.c @@ -516,14 +516,14 @@ devfn = wslot_to_devfn(hpdev->desc.wslot.val); - mtx_lock(&Giant); + newbus_lock(); pci_dev = pci_find_dbsf(hbus->pci_domain, 0, PCI_SLOT(devfn), PCI_FUNC(devfn)); if (pci_dev) device_delete_child(hbus->pci_bus, pci_dev); - mtx_unlock(&Giant); + newbus_unlock(); mtx_lock(&hbus->device_list_lock); TAILQ_REMOVE(&hbus->children, hpdev, link); Index: sys/dev/ida/ida.c =================================================================== --- sys/dev/ida/ida.c +++ sys/dev/ida/ida.c @@ -334,9 +334,9 @@ config_intrhook_disestablish(&ida->ich); - mtx_lock(&Giant); + newbus_lock(); bus_generic_attach(ida->dev); - mtx_unlock(&Giant); + newbus_unlock(); } int Index: sys/dev/iicbus/icee.c =================================================================== --- sys/dev/iicbus/icee.c +++ sys/dev/iicbus/icee.c @@ -236,8 +236,7 @@ struct icee_softc *sc; sc = CDEV2SOFTC(dev); - if (device_get_state(sc->dev) < DS_BUSY) - device_busy(sc->dev); + device_busy(sc->dev); return (0); } Index: sys/dev/mfi/mfi.c =================================================================== --- sys/dev/mfi/mfi.c +++ sys/dev/mfi/mfi.c @@ -1427,9 +1427,9 @@ if (found == 0) { printf("DELETE\n"); mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + newbus_lock(); device_delete_child(sc->mfi_dev, syspd->pd_dev); - mtx_unlock(&Giant); + newbus_unlock(); mtx_lock(&sc->mfi_io_lock); } } @@ -1587,9 +1587,9 @@ KASSERT(ld != NULL, ("volume dissappeared")); */ if (ld != NULL) { - mtx_lock(&Giant); + newbus_lock(); device_delete_child(sc->mfi_dev, ld->ld_dev); - mtx_unlock(&Giant); + newbus_unlock(); } } break; @@ -1604,11 +1604,11 @@ pd_link) { if (syspd->pd_id == detail->args.pd.device_id) { - mtx_lock(&Giant); + newbus_lock(); device_delete_child( sc->mfi_dev, syspd->pd_dev); - mtx_unlock(&Giant); + newbus_unlock(); break; } } @@ -1925,11 +1925,11 @@ mfi_release_command(cm); mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + newbus_lock(); if ((child = device_add_child(sc->mfi_dev, "mfid", -1)) == NULL) { device_printf(sc->mfi_dev, "Failed to add logical disk\n"); free(ld_info, M_MFIBUF); - mtx_unlock(&Giant); + newbus_unlock(); mtx_lock(&sc->mfi_io_lock); return; } @@ -1937,7 +1937,7 @@ device_set_ivars(child, ld_info); device_set_desc(child, "MFI Logical Disk"); bus_generic_attach(sc->mfi_dev); - mtx_unlock(&Giant); + newbus_unlock(); mtx_lock(&sc->mfi_io_lock); } @@ -2013,11 +2013,11 @@ mfi_release_command(cm); mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + newbus_lock(); if ((child = device_add_child(sc->mfi_dev, "mfisyspd", -1)) == NULL) { device_printf(sc->mfi_dev, "Failed to add system pd\n"); free(pd_info, M_MFIBUF); - mtx_unlock(&Giant); + newbus_unlock(); mtx_lock(&sc->mfi_io_lock); return; } @@ -2025,7 +2025,7 @@ device_set_ivars(child, pd_info); device_set_desc(child, "MFI System PD"); bus_generic_attach(sc->mfi_dev); - mtx_unlock(&Giant); + newbus_unlock(); mtx_lock(&sc->mfi_io_lock); } @@ -2831,9 +2831,9 @@ KASSERT(ld != NULL, ("volume dissappeared")); if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) { mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + newbus_lock(); device_delete_child(sc->mfi_dev, ld->ld_dev); - mtx_unlock(&Giant); + newbus_unlock(); mtx_lock(&sc->mfi_io_lock); } else mfi_disk_enable(ld); @@ -2841,11 +2841,11 @@ case MFI_DCMD_CFG_CLEAR: if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) { mtx_unlock(&sc->mfi_io_lock); - mtx_lock(&Giant); + newbus_lock(); TAILQ_FOREACH_SAFE(ld, &sc->mfi_ld_tqh, ld_link, ldn) { device_delete_child(sc->mfi_dev, ld->ld_dev); } - mtx_unlock(&Giant); + newbus_unlock(); mtx_lock(&sc->mfi_io_lock); } else { TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) Index: sys/dev/mfi/mfi_cam.c =================================================================== --- sys/dev/mfi/mfi_cam.c +++ sys/dev/mfi/mfi_cam.c @@ -298,9 +298,9 @@ struct cam_sim *sim; device_t mfip_dev; - mtx_lock(&Giant); + newbus_lock(); mfip_dev = device_find_child(sc->mfi_dev, "mfip", -1); - mtx_unlock(&Giant); + newbus_unlock(); if (mfip_dev == NULL) { device_printf(sc->mfi_dev, "Couldn't find mfip child device!\n"); return; Index: sys/dev/mii/mii.c =================================================================== --- sys/dev/mii/mii.c +++ sys/dev/mii/mii.c @@ -415,7 +415,9 @@ ivars->ifmedia_upd = ifmedia_upd; ivars->ifmedia_sts = ifmedia_sts; ivars->mii_flags = flags; + newbus_lock(); *miibus = device_add_child(dev, "miibus", -1); + newbus_unlock(); if (*miibus == NULL) { rv = ENXIO; goto fail; @@ -443,6 +445,7 @@ device_get_unit(*miibus), "phymask", &phymask) != 0) phymask = 0xffffffff; + newbus_lock(); if (device_get_children(*miibus, &children, &nchildren) != 0) { children = NULL; nchildren = 0; @@ -513,6 +516,7 @@ skip: ivars->mii_offset++; } + newbus_unlock(); free(children, M_TEMP); if (first != 0) { @@ -528,22 +532,29 @@ rv = ENXIO; goto fail; } + newbus_lock(); rv = bus_generic_attach(dev); + newbus_unlock(); if (rv != 0) goto fail; /* Attaching of the PHY drivers is done in miibus_attach(). */ return (0); } + newbus_lock(); rv = bus_generic_attach(*miibus); + newbus_unlock(); if (rv != 0) goto fail; return (0); fail: - if (*miibus != NULL) + if (*miibus != NULL) { + newbus_lock(); device_delete_child(dev, *miibus); + newbus_unlock(); + } free(ivars, M_DEVBUF); if (first != 0) *miibus = NULL; Index: sys/dev/mlx/mlx.c =================================================================== --- sys/dev/mlx/mlx.c +++ sys/dev/mlx/mlx.c @@ -830,9 +830,9 @@ * Scan the controller to see whether new drives have appeared. */ case MLX_RESCAN_DRIVES: - mtx_lock(&Giant); + newbus_lock(); mlx_startup(sc); - mtx_unlock(&Giant); + newbus_unlock(); return(0); /* @@ -979,9 +979,9 @@ case MLX_GET_SYSDRIVE: error = ENOENT; MLX_CONFIG_LOCK(sc); - mtx_lock(&Giant); + newbus_lock(); mlxd = (struct mlxd_softc *)devclass_get_softc(mlxd_devclass, *arg); - mtx_unlock(&Giant); + newbus_unlock(); if ((mlxd != NULL) && (mlxd->mlxd_drive >= sc->mlx_sysdrive) && (mlxd->mlxd_drive < (sc->mlx_sysdrive + MLX_MAXDRIVES))) { error = 0; Index: sys/dev/mlx5/mlx5_core/mlx5_fwdump.c =================================================================== --- sys/dev/mlx5/mlx5_core/mlx5_fwdump.c +++ sys/dev/mlx5/mlx5_core/mlx5_fwdump.c @@ -311,11 +311,11 @@ error = -mlx5_set_mfrl_reg(mdev, MLX5_FRL_LEVEL3); if (error == 0) { dev = mdev->pdev->dev.bsddev; - mtx_lock(&Giant); + newbus_lock(); bus = device_get_parent(dev); error = BUS_RESET_CHILD(device_get_parent(bus), bus, DEVF_RESET_DETACH); - mtx_unlock(&Giant); + newbus_unlock(); } return (error); } Index: sys/dev/mlx5/mlx5_core/mlx5_health.c =================================================================== --- sys/dev/mlx5/mlx5_core/mlx5_health.c +++ sys/dev/mlx5/mlx5_core/mlx5_health.c @@ -374,7 +374,8 @@ priv = container_of(health, struct mlx5_priv, health); dev = container_of(priv, struct mlx5_core_dev, priv); - mtx_lock(&Giant); /* XXX newbus needs this */ + /* This might likely be wrong, cut and paste from elsewhere? */ + newbus_lock(); if (sensor_pci_no_comm(dev)) { mlx5_core_err(dev, @@ -401,7 +402,7 @@ mlx5_recover_device(dev); } - mtx_unlock(&Giant); + newbus_unlock(); } /* How much time to wait until health resetting the driver (in msecs) */ Index: sys/dev/pccard/pccard.c =================================================================== --- sys/dev/pccard/pccard.c +++ sys/dev/pccard/pccard.c @@ -238,7 +238,7 @@ DEVPRINTF((dev, "Card has %d functions. pccard_mfc is %d\n", i + 1, pccard_mfc(sc))); - mtx_lock(&Giant); + newbus_lock(); STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) { if (STAILQ_EMPTY(&pf->cfe_head)) continue; @@ -251,7 +251,7 @@ pf->dev = child; pccard_probe_and_attach_child(dev, child, pf); } - mtx_unlock(&Giant); + newbus_unlock(); return (0); } @@ -342,7 +342,7 @@ if (pf->dev == NULL) continue; state = device_get_state(pf->dev); - if (state == DS_ATTACHED || state == DS_BUSY) + if (state == DS_ATTACHED) device_detach(pf->dev); if (pf->cfe != NULL) pccard_function_disable(pf); Index: sys/dev/pci/pci_pci.c =================================================================== --- sys/dev/pci/pci_pci.c +++ sys/dev/pci/pci_pci.c @@ -1386,7 +1386,7 @@ callout_init(&sc->pcie_cc_timer, 0); callout_init(&sc->pcie_dll_timer, 0); TASK_INIT(&sc->pcie_hp_task, 0, pcib_pcie_hotplug_task, sc); - sc->pcie_hp_lock = &Giant; + sc->pcie_hp_lock = newbus_mtx(); /* Allocate IRQ. */ if (pcib_alloc_pcie_irq(sc) != 0) Index: sys/dev/pci/pci_user.c =================================================================== --- sys/dev/pci/pci_user.c +++ sys/dev/pci/pci_user.c @@ -964,8 +964,8 @@ } - /* Giant because newbus is Giant locked revisit with newbus locking */ - mtx_lock(&Giant); + /* Not entirely sure this is correct */ + newbus_lock(); switch (cmd) { case PCIOCGETCONF: @@ -1305,7 +1305,7 @@ break; } - mtx_unlock(&Giant); + newbus_unlock(); return (error); } Index: sys/dev/sdio/sdiob.c =================================================================== --- sys/dev/sdio/sdiob.c +++ sys/dev/sdio/sdiob.c @@ -955,10 +955,10 @@ return (ENXIO); } - mtx_lock(&Giant); + newbus_lock(); error = devclass_add_driver(bus_devclass, &sdiob_driver, BUS_PASS_DEFAULT, &sdiob_devclass); - mtx_unlock(&Giant); + newbus_unlock(); if (error != 0) { printf("%s: Failed to add driver to devclass: %d.\n", __func__, error); Index: sys/dev/twe/twe_freebsd.c =================================================================== --- sys/dev/twe/twe_freebsd.c +++ sys/dev/twe/twe_freebsd.c @@ -583,10 +583,10 @@ char buf[80]; int error; - mtx_lock(&Giant); + newbus_lock(); dr->td_disk = device_add_child(sc->twe_dev, NULL, -1); if (dr->td_disk == NULL) { - mtx_unlock(&Giant); + newbus_unlock(); twe_printf(sc, "Cannot add unit\n"); return (EIO); } @@ -603,7 +603,7 @@ device_set_desc_copy(dr->td_disk, buf); error = device_probe_and_attach(dr->td_disk); - mtx_unlock(&Giant); + newbus_unlock(); if (error != 0) { twe_printf(sc, "Cannot attach unit to controller. error = %d\n", error); return (EIO); @@ -622,9 +622,9 @@ int error = 0; TWE_CONFIG_ASSERT_LOCKED(sc); - mtx_lock(&Giant); + newbus_lock(); error = device_delete_child(sc->twe_dev, sc->twe_drive[unit].td_disk); - mtx_unlock(&Giant); + newbus_unlock(); if (error != 0) { twe_printf(sc, "failed to delete unit %d\n", unit); return(error); Index: sys/dev/usb/controller/usb_controller.c =================================================================== --- sys/dev/usb/controller/usb_controller.c +++ sys/dev/usb/controller/usb_controller.c @@ -438,9 +438,9 @@ USB_BUS_UNLOCK(bus); /* detach children first */ - mtx_lock(&Giant); + newbus_lock(); bus_generic_detach(dev); - mtx_unlock(&Giant); + newbus_unlock(); /* * Free USB device and all subdevices, if any. @@ -804,10 +804,10 @@ static void usb_attach_sub(device_t dev, struct usb_bus *bus) { - mtx_lock(&Giant); + newbus_lock(); if (usb_devclass_ptr == NULL) usb_devclass_ptr = devclass_find("usbus"); - mtx_unlock(&Giant); + newbus_unlock(); #if USB_HAVE_PF usbpf_attach(bus); Index: sys/dev/usb/net/if_axe.c =================================================================== --- sys/dev/usb/net/if_axe.c +++ sys/dev/usb/net/if_axe.c @@ -904,11 +904,9 @@ adv_pause = MIIF_DOPAUSE; else adv_pause = 0; - mtx_lock(&Giant); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, adv_pause); - mtx_unlock(&Giant); return (error); } Index: sys/dev/usb/net/if_axge.c =================================================================== --- sys/dev/usb/net/if_axge.c +++ sys/dev/usb/net/if_axge.c @@ -468,11 +468,9 @@ ifp->if_hwassist = AXGE_CSUM_FEATURES; ifp->if_capenable = ifp->if_capabilities; - mtx_lock(&Giant); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, AXGE_PHY_ADDR, MII_OFFSET_ANY, MIIF_DOPAUSE); - mtx_unlock(&Giant); return (error); } Index: sys/dev/usb/net/if_muge.c =================================================================== --- sys/dev/usb/net/if_muge.c +++ sys/dev/usb/net/if_muge.c @@ -1638,11 +1638,9 @@ ifp->if_capenable = ifp->if_capabilities; - mtx_lock(&Giant); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, 0); - mtx_unlock(&Giant); return (0); } Index: sys/dev/usb/net/if_smsc.c =================================================================== --- sys/dev/usb/net/if_smsc.c +++ sys/dev/usb/net/if_smsc.c @@ -1668,11 +1668,9 @@ ifp->if_capenable = ifp->if_capabilities; - mtx_lock(&Giant); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, 0); - mtx_unlock(&Giant); return (error); } Index: sys/dev/usb/net/if_ure.c =================================================================== --- sys/dev/usb/net/if_ure.c +++ sys/dev/usb/net/if_ure.c @@ -712,11 +712,9 @@ ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; IFQ_SET_READY(&ifp->if_snd); - mtx_lock(&Giant); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, 0); - mtx_unlock(&Giant); return (error); } Index: sys/dev/usb/net/usb_ethernet.c =================================================================== --- sys/dev/usb/net/usb_ethernet.c +++ sys/dev/usb/net/usb_ethernet.c @@ -249,12 +249,9 @@ if (ue->ue_methods->ue_mii_upd != NULL && ue->ue_methods->ue_mii_sts != NULL) { - /* device_xxx() depends on this */ - mtx_lock(&Giant); error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, ue_ifmedia_upd, ue->ue_methods->ue_mii_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); - mtx_unlock(&Giant); } } @@ -322,9 +319,9 @@ /* detach miibus */ if (ue->ue_miibus != NULL) { - mtx_lock(&Giant); /* device_xxx() depends on this */ + newbus_lock(); device_delete_child(ue->ue_dev, ue->ue_miibus); - mtx_unlock(&Giant); + newbus_unlock(); } /* detach ethernet */ Index: sys/dev/usb/usb_device.c =================================================================== --- sys/dev/usb/usb_device.c +++ sys/dev/usb/usb_device.c @@ -2888,7 +2888,7 @@ * are locked before locking Giant. Else the lock can be * locked multiple times. */ - mtx_lock(&Giant); + newbus_lock(); return (1); } @@ -2908,7 +2908,7 @@ sx_xunlock(&udev->enum_sx); return (255); } - mtx_lock(&Giant); + newbus_lock(); return (1); } #endif @@ -2918,7 +2918,7 @@ void usbd_enum_unlock(struct usb_device *udev) { - mtx_unlock(&Giant); + newbus_unlock(); sx_xunlock(&udev->enum_sx); sx_xunlock(&udev->sr_sx); } @@ -2934,7 +2934,7 @@ * are locked before locking Giant. Else the lock can be * locked multiple times. */ - mtx_lock(&Giant); + newbus_lock(); } /* The following function unlocks suspend and resume. */ @@ -2942,7 +2942,7 @@ void usbd_sr_unlock(struct usb_device *udev) { - mtx_unlock(&Giant); + newbus_unlock(); sx_xunlock(&udev->sr_sx); } Index: sys/dev/xen/control/control.c =================================================================== --- sys/dev/xen/control/control.c +++ sys/dev/xen/control/control.c @@ -221,12 +221,11 @@ KASSERT((PCPU_GET(cpuid) == 0), ("Not running on CPU#0")); /* - * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE - * drivers need this. + * Be sure to hold Giant across DEVICE_SUSPEND/RESUME. */ - mtx_lock(&Giant); + newbus_lock(); if (DEVICE_SUSPEND(root_bus) != 0) { - mtx_unlock(&Giant); + newbus_unlock(); printf("%s: device_suspend failed\n", __func__); return; } @@ -297,7 +296,7 @@ * similar. */ DEVICE_RESUME(root_bus); - mtx_unlock(&Giant); + newbus_unlock(); /* * Warm up timecounter again and reset system clock. Index: sys/dev/xen/pcifront/pcifront.c =================================================================== --- sys/dev/xen/pcifront/pcifront.c +++ sys/dev/xen/pcifront/pcifront.c @@ -274,9 +274,9 @@ printf("pcifront: connected to %s\n", pdev->xdev->nodename); - mtx_lock(&Giant); + newbus_lock(); device_probe_and_attach(pdev->ndev); - mtx_unlock(&Giant); + newbus_unlock(); return 0; } Index: sys/i386/bios/apm.c =================================================================== --- sys/i386/bios/apm.c +++ sys/i386/bios/apm.c @@ -452,10 +452,9 @@ EVENTHANDLER_INVOKE(power_suspend); /* - * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since - * non-MPSAFE drivers need this. + * Be sure to hold Giant across DEVICE_SUSPEND/RESUME */ - mtx_lock(&Giant); + newbus_lock(); error = DEVICE_SUSPEND(root_bus); if (error) goto backout; @@ -464,7 +463,7 @@ if (apm_suspend_system(PMST_SUSPEND) == 0) { sc->suspending = 1; apm_processevent(); - mtx_unlock(&Giant); + newbus_unlock(); return; } @@ -472,7 +471,7 @@ apm_execute_hook(hook[APM_HOOK_RESUME]); DEVICE_RESUME(root_bus); backout: - mtx_unlock(&Giant); + newbus_unlock(); EVENTHANDLER_INVOKE(power_resume); } @@ -577,9 +576,9 @@ sc->suspending = 0; apm_execute_hook(hook[APM_HOOK_RESUME]); - mtx_lock(&Giant); + newbus_lock(); DEVICE_RESUME(root_bus); - mtx_unlock(&Giant); + newbus_unlock(); EVENTHANDLER_INVOKE(power_resume); } Index: sys/kern/subr_bus.c =================================================================== --- sys/kern/subr_bus.c +++ sys/kern/subr_bus.c @@ -135,7 +135,7 @@ int unit; /**< current unit number */ char* nameunit; /**< name+unit e.g. foodev0 */ char* desc; /**< driver specific description */ - int busy; /**< count of calls to device_busy() */ + u_int busy; /**< count of calls to device_busy() */ device_state_t state; /**< current device state */ uint32_t devflags; /**< api level flags for device_get_flags() */ u_int flags; /**< internal device flags */ @@ -888,6 +888,20 @@ DEFINE_CLASS(null, null_methods, 0); +void +newbus_lock(void) +{ + + mtx_lock(&Giant); +} + +void +newbus_unlock(void) +{ + + mtx_unlock(&Giant); +} + /* * Bus pass implementation */ @@ -2639,13 +2653,13 @@ void device_busy(device_t dev) { - if (dev->state < DS_ATTACHING) - panic("device_busy: called for unattached device"); - if (dev->busy == 0 && dev->parent) + + /* + * Mark the device as busy, recursively up the tree if this busy count + * goes 0->1. + */ + if (refcount_acquire(&dev->busy) == 0 && dev->parent != NULL) device_busy(dev->parent); - dev->busy++; - if (dev->state == DS_ATTACHED) - dev->state = DS_BUSY; } /** @@ -2654,17 +2668,12 @@ void device_unbusy(device_t dev) { - if (dev->busy != 0 && dev->state != DS_BUSY && - dev->state != DS_ATTACHING) - panic("device_unbusy: called for non-busy device %s", - device_get_nameunit(dev)); - dev->busy--; - if (dev->busy == 0) { - if (dev->parent) - device_unbusy(dev->parent); - if (dev->state == DS_BUSY) - dev->state = DS_ATTACHED; - } + + /* + * Mark the device as unbsy, recursively if this is the last busy count. + */ + if (refcount_release_last(&dev->busy) && dev->parent != NULL) + device_unbusy(dev->parent); } /** @@ -2995,10 +3004,7 @@ attachentropy = (uint16_t)(get_cyclecount() - attachtime); random_harvest_direct(&attachentropy, sizeof(attachentropy), RANDOM_ATTACH); device_sysctl_update(dev); - if (dev->busy) - dev->state = DS_BUSY; - else - dev->state = DS_ATTACHED; + dev->state = DS_ATTACHED; dev->flags &= ~DF_DONENOMATCH; EVENTHANDLER_DIRECT_INVOKE(device_attach, dev); devadded(dev); @@ -3029,7 +3035,7 @@ GIANT_REQUIRED; PDEBUG(("%s", DEVICENAME(dev))); - if (dev->state == DS_BUSY) + if (dev->busy > 0) return (EBUSY); if (dev->state == DS_ATTACHING) { device_printf(dev, "device in attaching state! Deferring detach.\n"); @@ -3082,7 +3088,7 @@ { PDEBUG(("%s", DEVICENAME(dev))); - if (dev->state == DS_BUSY) + if (dev->busy > 0) return (EBUSY); if (dev->state != DS_ATTACHED) return (0); Index: sys/net/iflib_clone.c =================================================================== --- sys/net/iflib_clone.c +++ sys/net/iflib_clone.c @@ -184,9 +184,9 @@ if (__predict_false(iflib_pseudodev == NULL)) { /* SYSINIT initialization would panic !?! */ - mtx_lock(&Giant); + newbus_lock(); iflib_pseudodev = device_add_child(root_bus, "ifpseudo", 0); - mtx_unlock(&Giant); + newbus_unlock(); MPASS(iflib_pseudodev != NULL); } ip = iflib_ip_lookup(name); @@ -210,9 +210,9 @@ MPASS(devclass_get_device(ip->ip_dc, unit) == dev); rc = iflib_pseudo_register(dev, ip->ip_sctx, &ctx, &clctx); if (rc) { - mtx_lock(&Giant); + newbus_lock(); device_delete_child(iflib_pseudodev, dev); - mtx_unlock(&Giant); + newbus_unlock(); } else device_set_softc(dev, ctx); @@ -238,9 +238,9 @@ iflib_stop(ctx); sx_xunlock(ctx_lock); - mtx_lock(&Giant); + newbus_lock(); rc = device_delete_child(iflib_pseudodev, dev); - mtx_unlock(&Giant); + newbus_unlock(); if (rc == 0) iflib_pseudo_deregister(ctx); } Index: sys/sys/bus.h =================================================================== --- sys/sys/bus.h +++ sys/sys/bus.h @@ -58,7 +58,6 @@ DS_ALIVE = 20, /**< @brief probe succeeded */ DS_ATTACHING = 25, /**< @brief currently attaching */ DS_ATTACHED = 30, /**< @brief attach method called */ - DS_BUSY = 40 /**< @brief device is open */ } device_state_t; /** @@ -746,6 +745,19 @@ void bus_set_pass(int pass); +/** + * Routines to lock / unlock the newbus lock. + * Must be taken out to interact with newbus. + */ +void newbus_lock(void); +void newbus_unlock(void); +static inline struct mtx * +newbus_mtx(void) +{ + + return (&Giant); +} + /** * Shorthands for constructing method tables. */ @@ -776,7 +788,7 @@ #define EARLY_DRIVER_MODULE_ORDERED(name, busname, driver, devclass, \ evh, arg, order, pass) \ - \ + \ static struct driver_module_data name##_##busname##_driver_mod = { \ evh, arg, \ #busname, \ Index: sys/xen/xenbus/xenbusb.c =================================================================== --- sys/xen/xenbus/xenbusb.c +++ sys/xen/xenbus/xenbusb.c @@ -534,12 +534,9 @@ { device_t dev = (device_t)arg; - /* - * Hold Giant until the Giant free newbus changes are committed. - */ - mtx_lock(&Giant); + newbus_lock(); xenbusb_probe_children(dev); - mtx_unlock(&Giant); + newbus_unlock(); } /**