Make the newbus subsystem Giant free by adding the new newbus sxlock.
The newbus lock is responsible for protecting newbus internIal structures, device states and devclass flags. It is necessary to hold it when all such datas are accessed. For the other operations, softc locking should ensure enough protection to avoid races. Newbus lock is automatically held when virtual operations on the device and bus are invoked when loading the driver or when the suspend/resume take place. For other 'spourious' operations trying to access/modify the newbus topology, newbus lock needs to be automatically acquired and dropped. For the moment Giant is also acquired in some key point (modules subsystem) in order to avoid problems before the 8.0 release as module handlers could make assumptions about it. This Giant locking should go just after the release happens. Please keep in mind that the public interface can be expanded in order to provide more support, if there are really necessities at some point and also some bugs could arise as long as the patch needs a bit of further testing. Bump __FreeBSD_version in order to reflect the newbus lock introduction. Reviewed by: ed, hps, jhb, imp, mav, scottl No answer by: ariff, thompsa, yongari Tested by: pho, G. Trematerra <giovanni dot trematerra at gmail dot com>, Brandon Gooch <jamesbrandongooch at gmail dot com> Sponsored by: Yahoo! Incorporated Approved by: re (ksmith)
This commit is contained in:
parent
d40b91cb13
commit
444b91868b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=196037
@ -3270,10 +3270,10 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
|
||||
while (co != NULL) {
|
||||
if (co->co_found == 0) {
|
||||
mtx_unlock(&sc->aac_io_lock);
|
||||
mtx_lock(&Giant);
|
||||
newbus_xlock();
|
||||
device_delete_child(sc->aac_dev,
|
||||
co->co_disk);
|
||||
mtx_unlock(&Giant);
|
||||
newbus_xunlock();
|
||||
mtx_lock(&sc->aac_io_lock);
|
||||
co_next = TAILQ_NEXT(co, co_link);
|
||||
mtx_lock(&sc->aac_container_lock);
|
||||
@ -3291,9 +3291,9 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
|
||||
/* Attach the newly created containers */
|
||||
if (added) {
|
||||
mtx_unlock(&sc->aac_io_lock);
|
||||
mtx_lock(&Giant);
|
||||
newbus_xlock();
|
||||
bus_generic_attach(sc->aac_dev);
|
||||
mtx_unlock(&Giant);
|
||||
newbus_xunlock();
|
||||
mtx_lock(&sc->aac_io_lock);
|
||||
}
|
||||
|
||||
|
@ -675,8 +675,6 @@ acpi_suspend(device_t dev)
|
||||
device_t child, *devlist;
|
||||
int error, i, numdevs, pstate;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
/* First give child devices a chance to suspend. */
|
||||
error = bus_generic_suspend(dev);
|
||||
if (error)
|
||||
@ -719,8 +717,6 @@ acpi_resume(device_t dev)
|
||||
int i, numdevs, error;
|
||||
device_t child, *devlist;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
/*
|
||||
* Put all devices in D0 before resuming them. Call _S0D on each one
|
||||
* since some systems expect this.
|
||||
@ -745,8 +741,6 @@ static int
|
||||
acpi_shutdown(device_t dev)
|
||||
{
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
/* Allow children to shutdown first. */
|
||||
bus_generic_shutdown(dev);
|
||||
|
||||
@ -2534,11 +2528,7 @@ acpi_EnterSleepState(struct acpi_softc *sc, int state)
|
||||
thread_unlock(curthread);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE
|
||||
* drivers need this.
|
||||
*/
|
||||
mtx_lock(&Giant);
|
||||
newbus_xlock();
|
||||
|
||||
slp_state = ACPI_SS_NONE;
|
||||
|
||||
@ -2611,7 +2601,7 @@ acpi_EnterSleepState(struct acpi_softc *sc, int state)
|
||||
if (slp_state >= ACPI_SS_SLEPT)
|
||||
acpi_enable_fixed_events(sc);
|
||||
|
||||
mtx_unlock(&Giant);
|
||||
newbus_xunlock();
|
||||
|
||||
#ifdef SMP
|
||||
thread_lock(curthread);
|
||||
|
@ -329,6 +329,7 @@ acpi_battery_find_dev(u_int logical_unit)
|
||||
|
||||
dev = NULL;
|
||||
found_unit = 0;
|
||||
newbus_slock();
|
||||
batt_dc = devclass_find("battery");
|
||||
maxunit = devclass_get_maxunit(batt_dc);
|
||||
for (i = 0; i < maxunit; i++) {
|
||||
@ -340,6 +341,7 @@ acpi_battery_find_dev(u_int logical_unit)
|
||||
found_unit++;
|
||||
dev = NULL;
|
||||
}
|
||||
newbus_sunlock();
|
||||
|
||||
return (dev);
|
||||
}
|
||||
@ -369,13 +371,17 @@ acpi_battery_ioctl(u_long cmd, caddr_t addr, void *arg)
|
||||
*/
|
||||
switch (cmd) {
|
||||
case ACPIIO_BATT_GET_UNITS:
|
||||
newbus_slock();
|
||||
*(int *)addr = acpi_battery_get_units();
|
||||
newbus_sunlock();
|
||||
error = 0;
|
||||
break;
|
||||
case ACPIIO_BATT_GET_BATTINFO:
|
||||
if (dev != NULL || unit == ACPI_BATTERY_ALL_UNITS) {
|
||||
bzero(&ioctl_arg->battinfo, sizeof(ioctl_arg->battinfo));
|
||||
newbus_slock();
|
||||
error = acpi_battery_get_battinfo(dev, &ioctl_arg->battinfo);
|
||||
newbus_sunlock();
|
||||
}
|
||||
break;
|
||||
case ACPIIO_BATT_GET_BIF:
|
||||
@ -416,6 +422,11 @@ acpi_battery_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int val, error;
|
||||
|
||||
/*
|
||||
* Tolerate a race here because newbus lock can't be acquired before
|
||||
* acpi_battery_get_battinfo() as it can create a LOR with the sysctl
|
||||
* lock.
|
||||
*/
|
||||
acpi_battery_get_battinfo(NULL, &acpi_battery_battinfo);
|
||||
val = *(u_int *)oidp->oid_arg1;
|
||||
error = sysctl_handle_int(oidp, &val, 0, req);
|
||||
@ -427,6 +438,10 @@ acpi_battery_units_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int count, error;
|
||||
|
||||
/*
|
||||
* Tolerate a race here in order to avoid a LOR between sysctl lock
|
||||
* and newbus lock.
|
||||
*/
|
||||
count = acpi_battery_get_units();
|
||||
error = sysctl_handle_int(oidp, &count, 0, req);
|
||||
return (error);
|
||||
|
@ -732,7 +732,9 @@ acpi_cpu_startup(void *arg)
|
||||
int i;
|
||||
|
||||
/* Get set of CPU devices */
|
||||
newbus_slock();
|
||||
devclass_get_devices(acpi_cpu_devclass, &cpu_devices, &cpu_ndevices);
|
||||
newbus_sunlock();
|
||||
|
||||
/*
|
||||
* Setup any quirks that might necessary now that we have probed
|
||||
|
@ -188,12 +188,12 @@ acpi_dock_attach_later(void *context)
|
||||
|
||||
dev = (device_t)context;
|
||||
|
||||
newbus_xlock();
|
||||
if (!device_is_enabled(dev))
|
||||
device_enable(dev);
|
||||
|
||||
mtx_lock(&Giant);
|
||||
device_probe_and_attach(dev);
|
||||
mtx_unlock(&Giant);
|
||||
newbus_xunlock();
|
||||
}
|
||||
|
||||
static ACPI_STATUS
|
||||
@ -299,11 +299,11 @@ acpi_dock_eject_child(ACPI_HANDLE handle, UINT32 level, void *context,
|
||||
"ejecting device for %s\n", acpi_name(handle));
|
||||
|
||||
dev = acpi_get_device(handle);
|
||||
newbus_xlock();
|
||||
if (dev != NULL && device_is_attached(dev)) {
|
||||
mtx_lock(&Giant);
|
||||
device_detach(dev);
|
||||
mtx_unlock(&Giant);
|
||||
}
|
||||
newbus_xunlock();
|
||||
|
||||
acpi_SetInteger(handle, "_EJ0", 0);
|
||||
out:
|
||||
|
@ -936,6 +936,8 @@ acpi_tz_thread(void *arg)
|
||||
sc = NULL;
|
||||
|
||||
for (;;) {
|
||||
newbus_slock();
|
||||
|
||||
/* If the number of devices has changed, re-evaluate. */
|
||||
if (devclass_get_count(acpi_tz_devclass) != devcount) {
|
||||
if (devs != NULL) {
|
||||
@ -948,6 +950,7 @@ acpi_tz_thread(void *arg)
|
||||
for (i = 0; i < devcount; i++)
|
||||
sc[i] = device_get_softc(devs[i]);
|
||||
}
|
||||
newbus_sunlock();
|
||||
|
||||
/* Check for temperature events and act on them. */
|
||||
for (i = 0; i < devcount; i++) {
|
||||
|
@ -113,6 +113,7 @@ adb_bus_enumerate(void *xdev)
|
||||
uint8_t i, next_free;
|
||||
uint16_t r3;
|
||||
|
||||
newbus_xlock();
|
||||
sc->sc_dev = dev;
|
||||
sc->parent = device_get_parent(dev);
|
||||
|
||||
@ -187,6 +188,7 @@ adb_bus_enumerate(void *xdev)
|
||||
}
|
||||
|
||||
bus_generic_attach(dev);
|
||||
newbus_xunlock();
|
||||
|
||||
config_intrhook_disestablish(&sc->enum_hook);
|
||||
}
|
||||
|
@ -269,6 +269,7 @@ amdtemp_intrhook(void *arg)
|
||||
/*
|
||||
* dev.cpu.N.temperature.
|
||||
*/
|
||||
newbus_xlock();
|
||||
nexus = device_find_child(root_bus, "nexus", 0);
|
||||
acpi = device_find_child(nexus, "acpi", 0);
|
||||
|
||||
@ -285,6 +286,7 @@ amdtemp_intrhook(void *arg)
|
||||
"Max of sensor 0 / 1");
|
||||
}
|
||||
}
|
||||
newbus_xunlock();
|
||||
config_intrhook_disestablish(&sc->sc_ich);
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,10 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
SYSCTL_NODE(_hw, OID_AUTO, amr, CTLFLAG_RD, 0, "AMR driver parameters");
|
||||
|
||||
/*
|
||||
* In order to get rid of Giant, amr_state should be protected by
|
||||
* a proper softc lock for the cdev operations.
|
||||
*/
|
||||
static d_open_t amr_open;
|
||||
static d_close_t amr_close;
|
||||
static d_ioctl_t amr_ioctl;
|
||||
@ -312,9 +316,11 @@ amr_startup(void *arg)
|
||||
config_intrhook_disestablish(&sc->amr_ich);
|
||||
sc->amr_ich.ich_func = NULL;
|
||||
|
||||
newbus_xlock();
|
||||
/* get up-to-date drive information */
|
||||
if (amr_query_controller(sc)) {
|
||||
device_printf(sc->amr_dev, "can't scan controller for drives\n");
|
||||
newbus_xunlock();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -347,6 +353,7 @@ amr_startup(void *arg)
|
||||
|
||||
/* interrupts will be enabled before we do anything more */
|
||||
sc->amr_state |= AMR_STATE_INTEN;
|
||||
newbus_xunlock();
|
||||
|
||||
/*
|
||||
* Start the timeout routine.
|
||||
@ -434,7 +441,11 @@ static int
|
||||
amr_open(struct cdev *dev, int flags, int fmt, struct thread *td)
|
||||
{
|
||||
int unit = dev2unit(dev);
|
||||
struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit);
|
||||
struct amr_softc *sc;
|
||||
|
||||
newbus_slock();
|
||||
sc = devclass_get_softc(devclass_find("amr"), unit);
|
||||
newbus_sunlock();
|
||||
|
||||
debug_called(1);
|
||||
|
||||
@ -490,7 +501,11 @@ static int
|
||||
amr_close(struct cdev *dev, int flags, int fmt, struct thread *td)
|
||||
{
|
||||
int unit = dev2unit(dev);
|
||||
struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit);
|
||||
struct amr_softc *sc;
|
||||
|
||||
newbus_slock();
|
||||
sc = devclass_get_softc(devclass_find("amr"), unit);
|
||||
newbus_sunlock();
|
||||
|
||||
debug_called(1);
|
||||
|
||||
@ -507,6 +522,7 @@ amr_rescan_drives(struct cdev *dev)
|
||||
struct amr_softc *sc = (struct amr_softc *)dev->si_drv1;
|
||||
int i, error = 0;
|
||||
|
||||
newbus_xlock();
|
||||
sc->amr_state |= AMR_STATE_REMAP_LD;
|
||||
while (sc->amr_busyslots) {
|
||||
device_printf(sc->amr_dev, "idle controller\n");
|
||||
@ -530,6 +546,7 @@ amr_rescan_drives(struct cdev *dev)
|
||||
sc->amr_drive[i].al_disk = 0;
|
||||
}
|
||||
}
|
||||
newbus_xunlock();
|
||||
|
||||
shutdown_out:
|
||||
amr_startup(sc);
|
||||
@ -805,7 +822,9 @@ amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct threa
|
||||
struct amr_linux_ioctl ali;
|
||||
int adapter, error;
|
||||
|
||||
newbus_slock();
|
||||
devclass = devclass_find("amr");
|
||||
newbus_sunlock();
|
||||
if (devclass == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
|
@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
|
||||
static d_ioctl_t ata_ioctl;
|
||||
static struct cdevsw ata_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_flags = D_NEEDGIANT, /* we need this as newbus isn't mpsafe */
|
||||
.d_ioctl = ata_ioctl,
|
||||
.d_name = "ata",
|
||||
};
|
||||
@ -204,7 +203,9 @@ ata_conn_event(void *context, int dummy)
|
||||
{
|
||||
device_t dev = (device_t)context;
|
||||
|
||||
newbus_xlock();
|
||||
ata_reinit(dev);
|
||||
newbus_xunlock();
|
||||
}
|
||||
|
||||
int
|
||||
@ -246,7 +247,6 @@ ata_reinit(device_t dev)
|
||||
|
||||
/* reinit the children and delete any that fails */
|
||||
if (!device_get_children(dev, &children, &nchildren)) {
|
||||
mtx_lock(&Giant); /* newbus suckage it needs Giant */
|
||||
for (i = 0; i < nchildren; i++) {
|
||||
/* did any children go missing ? */
|
||||
if (children[i] && device_is_attached(children[i]) &&
|
||||
@ -269,7 +269,6 @@ ata_reinit(device_t dev)
|
||||
}
|
||||
}
|
||||
free(children, M_TEMP);
|
||||
mtx_unlock(&Giant); /* newbus suckage dealt with, release Giant */
|
||||
}
|
||||
|
||||
/* if we still have a good request put it on the queue again */
|
||||
@ -395,6 +394,7 @@ ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
|
||||
int *value = (int *)data;
|
||||
int i, nchildren, error = ENOTTY;
|
||||
|
||||
newbus_xlock();
|
||||
switch (cmd) {
|
||||
case IOCATAGMAXCHANNEL:
|
||||
/* In case we have channel 0..n this will return n+1. */
|
||||
@ -405,32 +405,40 @@ ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
|
||||
case IOCATAREINIT:
|
||||
if (*value >= devclass_get_maxunit(ata_devclass) ||
|
||||
!(device = devclass_get_device(ata_devclass, *value)) ||
|
||||
!device_is_attached(device))
|
||||
!device_is_attached(device)) {
|
||||
newbus_xunlock();
|
||||
return ENXIO;
|
||||
}
|
||||
error = ata_reinit(device);
|
||||
break;
|
||||
|
||||
case IOCATAATTACH:
|
||||
if (*value >= devclass_get_maxunit(ata_devclass) ||
|
||||
!(device = devclass_get_device(ata_devclass, *value)) ||
|
||||
!device_is_attached(device))
|
||||
!device_is_attached(device)) {
|
||||
newbus_xunlock();
|
||||
return ENXIO;
|
||||
}
|
||||
error = DEVICE_ATTACH(device);
|
||||
break;
|
||||
|
||||
case IOCATADETACH:
|
||||
if (*value >= devclass_get_maxunit(ata_devclass) ||
|
||||
!(device = devclass_get_device(ata_devclass, *value)) ||
|
||||
!device_is_attached(device))
|
||||
!device_is_attached(device)) {
|
||||
newbus_xunlock();
|
||||
return ENXIO;
|
||||
}
|
||||
error = DEVICE_DETACH(device);
|
||||
break;
|
||||
|
||||
case IOCATADEVICES:
|
||||
if (devices->channel >= devclass_get_maxunit(ata_devclass) ||
|
||||
!(device = devclass_get_device(ata_devclass, devices->channel)) ||
|
||||
!device_is_attached(device))
|
||||
!device_is_attached(device)) {
|
||||
newbus_xunlock();
|
||||
return ENXIO;
|
||||
}
|
||||
bzero(devices->name[0], 32);
|
||||
bzero(&devices->params[0], sizeof(struct ata_params));
|
||||
bzero(devices->name[1], 32);
|
||||
@ -465,6 +473,7 @@ ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
|
||||
if (ata_raid_ioctl_func)
|
||||
error = ata_raid_ioctl_func(cmd, data);
|
||||
}
|
||||
newbus_xunlock();
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -572,7 +581,7 @@ ata_boot_attach(void)
|
||||
struct ata_channel *ch;
|
||||
int ctlr;
|
||||
|
||||
mtx_lock(&Giant); /* newbus suckage it needs Giant */
|
||||
newbus_xlock();
|
||||
|
||||
/* kick of probe and attach on all channels */
|
||||
for (ctlr = 0; ctlr < devclass_get_maxunit(ata_devclass); ctlr++) {
|
||||
@ -587,8 +596,7 @@ ata_boot_attach(void)
|
||||
free(ata_delayed_attach, M_TEMP);
|
||||
ata_delayed_attach = NULL;
|
||||
}
|
||||
|
||||
mtx_unlock(&Giant); /* newbus suckage dealt with, release Giant */
|
||||
newbus_xunlock();
|
||||
}
|
||||
|
||||
|
||||
@ -717,7 +725,6 @@ ata_identify(device_t dev)
|
||||
if (bootverbose)
|
||||
device_printf(dev, "Identifying devices: %08x\n", ch->devices);
|
||||
|
||||
mtx_lock(&Giant);
|
||||
/* Skip existing devices. */
|
||||
if (!device_get_children(dev, &children, &nchildren)) {
|
||||
for (i = 0; i < nchildren; i++) {
|
||||
@ -729,10 +736,8 @@ ata_identify(device_t dev)
|
||||
/* Create new devices. */
|
||||
if (bootverbose)
|
||||
device_printf(dev, "New devices: %08x\n", n);
|
||||
if (n == 0) {
|
||||
mtx_unlock(&Giant);
|
||||
if (n == 0)
|
||||
return (0);
|
||||
}
|
||||
for (i = 0; i < ATA_PM; ++i) {
|
||||
if (n & (((ATA_ATA_MASTER | ATA_ATAPI_MASTER) << i))) {
|
||||
int unit = -1;
|
||||
@ -775,7 +780,6 @@ ata_identify(device_t dev)
|
||||
}
|
||||
bus_generic_probe(dev);
|
||||
bus_generic_attach(dev);
|
||||
mtx_unlock(&Giant);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1488,7 +1488,9 @@ psmopen(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||
if (sc->state & PSM_OPEN)
|
||||
return (EBUSY);
|
||||
|
||||
newbus_xlock();
|
||||
device_busy(devclass_get_device(psm_devclass, unit));
|
||||
newbus_xunlock();
|
||||
|
||||
/* Initialize state */
|
||||
sc->mode.level = sc->dflt_mode.level;
|
||||
@ -1643,7 +1645,9 @@ psmclose(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||
/* close is almost always successful */
|
||||
sc->state &= ~PSM_OPEN;
|
||||
kbdc_lock(sc->kbdc, FALSE);
|
||||
newbus_xlock();
|
||||
device_unbusy(devclass_get_device(psm_devclass, unit));
|
||||
newbus_xunlock();
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -597,7 +597,9 @@ bktr_open( struct cdev *dev, int flags, int fmt, struct thread *td )
|
||||
return( ENXIO );
|
||||
|
||||
/* Record that the device is now busy */
|
||||
newbus_xlock();
|
||||
device_busy(devclass_get_device(bktr_devclass, unit));
|
||||
newbus_xunlock();
|
||||
|
||||
|
||||
if (bt848_card != -1) {
|
||||
@ -668,8 +670,11 @@ bktr_open( struct cdev *dev, int flags, int fmt, struct thread *td )
|
||||
}
|
||||
|
||||
/* If there was an error opening the device, undo the busy status */
|
||||
if (result != 0)
|
||||
if (result != 0) {
|
||||
newbus_xlock();
|
||||
device_unbusy(devclass_get_device(bktr_devclass, unit));
|
||||
newbus_xunlock();
|
||||
}
|
||||
return( result );
|
||||
}
|
||||
|
||||
@ -689,6 +694,7 @@ bktr_close( struct cdev *dev, int flags, int fmt, struct thread *td )
|
||||
/* Get the device data */
|
||||
bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
|
||||
if (bktr == NULL) {
|
||||
|
||||
/* the device is no longer valid/functioning */
|
||||
return (ENXIO);
|
||||
}
|
||||
@ -705,10 +711,11 @@ bktr_close( struct cdev *dev, int flags, int fmt, struct thread *td )
|
||||
break;
|
||||
default:
|
||||
return (ENXIO);
|
||||
break;
|
||||
}
|
||||
|
||||
newbus_xlock();
|
||||
device_unbusy(devclass_get_device(bktr_devclass, unit));
|
||||
newbus_xunlock();
|
||||
return( result );
|
||||
}
|
||||
|
||||
|
@ -614,11 +614,13 @@ int drm_open(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
||||
|
||||
if (!retcode) {
|
||||
atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
|
||||
newbus_xlock();
|
||||
DRM_LOCK();
|
||||
device_busy(dev->device);
|
||||
if (!dev->open_count++)
|
||||
retcode = drm_firstopen(dev);
|
||||
DRM_UNLOCK();
|
||||
newbus_xunlock();
|
||||
}
|
||||
|
||||
return retcode;
|
||||
@ -632,6 +634,11 @@ void drm_close(void *data)
|
||||
|
||||
DRM_DEBUG("open_count = %d\n", dev->open_count);
|
||||
|
||||
/*
|
||||
* We require to lock newbus here for handling device_unbusy() and
|
||||
* avoid a LOR with DRM_LOCK.
|
||||
*/
|
||||
newbus_xlock();
|
||||
DRM_LOCK();
|
||||
|
||||
if (dev->driver->preclose != NULL)
|
||||
@ -708,6 +715,7 @@ void drm_close(void *data)
|
||||
}
|
||||
|
||||
DRM_UNLOCK();
|
||||
newbus_xunlock();
|
||||
}
|
||||
|
||||
/* drm_ioctl is called whenever a process performs an ioctl on /dev/drm.
|
||||
|
@ -173,10 +173,12 @@ ips_intrhook(void *arg)
|
||||
struct ips_softc *sc = (struct ips_softc *)arg;
|
||||
|
||||
config_intrhook_disestablish(&sc->ips_ich);
|
||||
newbus_xlock();
|
||||
if (ips_adapter_init(sc))
|
||||
ips_pci_free(sc);
|
||||
else
|
||||
sc->configured = 1;
|
||||
newbus_xunlock();
|
||||
}
|
||||
|
||||
static int ips_pci_free(ips_softc_t *sc)
|
||||
|
@ -1327,11 +1327,11 @@ mfi_add_ld_complete(struct mfi_command *cm)
|
||||
mfi_release_command(cm);
|
||||
|
||||
mtx_unlock(&sc->mfi_io_lock);
|
||||
mtx_lock(&Giant);
|
||||
newbus_xlock();
|
||||
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_xunlock();
|
||||
mtx_lock(&sc->mfi_io_lock);
|
||||
return;
|
||||
}
|
||||
@ -1339,7 +1339,7 @@ mfi_add_ld_complete(struct mfi_command *cm)
|
||||
device_set_ivars(child, ld_info);
|
||||
device_set_desc(child, "MFI Logical Disk");
|
||||
bus_generic_attach(sc->mfi_dev);
|
||||
mtx_unlock(&Giant);
|
||||
newbus_xunlock();
|
||||
mtx_lock(&sc->mfi_io_lock);
|
||||
}
|
||||
|
||||
@ -1805,9 +1805,9 @@ mfi_check_command_post(struct mfi_softc *sc, struct mfi_command *cm)
|
||||
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_xlock();
|
||||
device_delete_child(sc->mfi_dev, ld->ld_dev);
|
||||
mtx_unlock(&Giant);
|
||||
newbus_xunlock();
|
||||
mtx_lock(&sc->mfi_io_lock);
|
||||
} else
|
||||
mfi_disk_enable(ld);
|
||||
@ -1815,11 +1815,11 @@ mfi_check_command_post(struct mfi_softc *sc, struct mfi_command *cm)
|
||||
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_xlock();
|
||||
TAILQ_FOREACH_SAFE(ld, &sc->mfi_ld_tqh, ld_link, ldn) {
|
||||
device_delete_child(sc->mfi_dev, ld->ld_dev);
|
||||
}
|
||||
mtx_unlock(&Giant);
|
||||
newbus_xunlock();
|
||||
mtx_lock(&sc->mfi_io_lock);
|
||||
} else {
|
||||
TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link)
|
||||
@ -1985,7 +1985,9 @@ mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td
|
||||
|
||||
adapter = ioc->mfi_adapter_no;
|
||||
if (device_get_unit(sc->mfi_dev) == 0 && adapter != 0) {
|
||||
newbus_slock();
|
||||
devclass = devclass_find("mfi");
|
||||
newbus_sunlock();
|
||||
sc = devclass_get_softc(devclass, adapter);
|
||||
}
|
||||
mtx_lock(&sc->mfi_io_lock);
|
||||
@ -2173,7 +2175,9 @@ mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td
|
||||
struct mfi_linux_ioc_packet l_ioc;
|
||||
int adapter;
|
||||
|
||||
newbus_slock();
|
||||
devclass = devclass_find("mfi");
|
||||
newbus_sunlock();
|
||||
if (devclass == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
@ -2194,7 +2198,9 @@ mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td
|
||||
struct mfi_linux_ioc_aen l_aen;
|
||||
int adapter;
|
||||
|
||||
newbus_slock();
|
||||
devclass = devclass_find("mfi");
|
||||
newbus_sunlock();
|
||||
if (devclass == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
|
@ -772,7 +772,9 @@ mlx_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct threa
|
||||
* Scan the controller to see whether new drives have appeared.
|
||||
*/
|
||||
case MLX_RESCAN_DRIVES:
|
||||
newbus_xlock();
|
||||
mlx_startup(sc);
|
||||
newbus_xunlock();
|
||||
return(0);
|
||||
|
||||
/*
|
||||
|
@ -1496,7 +1496,9 @@ mmc_delayed_attach(void *xsc)
|
||||
{
|
||||
struct mmc_softc *sc = xsc;
|
||||
|
||||
newbus_xlock();
|
||||
mmc_scan(sc);
|
||||
newbus_xunlock();
|
||||
config_intrhook_disestablish(&sc->config_intrhook);
|
||||
}
|
||||
|
||||
|
@ -464,14 +464,7 @@ cbb_event_thread(void *arg)
|
||||
sc->flags |= CBB_KTHREAD_RUNNING;
|
||||
while ((sc->flags & CBB_KTHREAD_DONE) == 0) {
|
||||
mtx_unlock(&sc->mtx);
|
||||
/*
|
||||
* We take out Giant here because we need it deep,
|
||||
* down in the bowels of the vm system for mapping the
|
||||
* memory we need to read the CIS. In addition, since
|
||||
* we are adding/deleting devices from the dev tree,
|
||||
* and that code isn't MP safe, we have to hold Giant.
|
||||
*/
|
||||
mtx_lock(&Giant);
|
||||
newbus_xlock();
|
||||
status = cbb_get(sc, CBB_SOCKET_STATE);
|
||||
DPRINTF(("Status is 0x%x\n", status));
|
||||
if (!CBB_CARD_PRESENT(status)) {
|
||||
@ -497,7 +490,7 @@ cbb_event_thread(void *arg)
|
||||
not_a_card = 0; /* We know card type */
|
||||
cbb_insert(sc);
|
||||
}
|
||||
mtx_unlock(&Giant);
|
||||
newbus_xunlock();
|
||||
|
||||
/*
|
||||
* First time through we need to tell mountroot that we're
|
||||
|
@ -152,7 +152,9 @@ iop_attach(void *arg)
|
||||
break;
|
||||
|
||||
case I2O_CLASS_RANDOM_BLOCK_STORAGE:
|
||||
newbus_xlock();
|
||||
pst_add_raid(sc, &sc->lct[i]);
|
||||
newbus_xunlock();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -903,7 +903,9 @@ rpopen(struct tty *tp)
|
||||
rp_callout_handle = timeout(rp_do_poll,
|
||||
(void *)NULL, POLL_INTERVAL);
|
||||
|
||||
newbus_xlock();
|
||||
device_busy(rp->rp_ctlp->dev);
|
||||
newbus_xunlock();
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -914,7 +916,9 @@ rpclose(struct tty *tp)
|
||||
|
||||
rp = tty_softc(tp);
|
||||
rphardclose(tp);
|
||||
newbus_xlock();
|
||||
device_unbusy(rp->rp_ctlp->dev);
|
||||
newbus_xunlock();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -7435,6 +7435,7 @@ hdac_attach2(void *arg)
|
||||
quirks_on, quirks_off);
|
||||
);
|
||||
|
||||
newbus_xlock();
|
||||
hdac_lock(sc);
|
||||
|
||||
/* Remove ourselves from the config hooks */
|
||||
@ -7674,6 +7675,7 @@ hdac_attach2(void *arg)
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO,
|
||||
"pindump", CTLTYPE_INT | CTLFLAG_RW, sc->dev, sizeof(sc->dev),
|
||||
sysctl_hdac_pindump, "I", "Dump pin states/data");
|
||||
newbus_xunlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -294,8 +294,10 @@ twe_init(struct twe_softc *sc)
|
||||
/*
|
||||
* Scan for drives
|
||||
*/
|
||||
newbus_xlock();
|
||||
for (i = 0; i < TWE_MAX_UNITS; i++)
|
||||
twe_add_unit(sc, i);
|
||||
newbus_xunlock();
|
||||
|
||||
/*
|
||||
* Initialise connection with controller.
|
||||
@ -621,11 +623,15 @@ twe_ioctl(struct twe_softc *sc, int ioctlcmd, void *addr)
|
||||
break;
|
||||
|
||||
case TWEIO_ADD_UNIT:
|
||||
newbus_xlock();
|
||||
error = twe_add_unit(sc, td->td_unit);
|
||||
newbus_xunlock();
|
||||
break;
|
||||
|
||||
case TWEIO_DEL_UNIT:
|
||||
newbus_xlock();
|
||||
error = twe_del_unit(sc, td->td_unit);
|
||||
newbus_xunlock();
|
||||
break;
|
||||
|
||||
/* XXX implement ATA PASSTHROUGH */
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
/* Explore the Root USB HUB. */
|
||||
(udev->hub->explore) (udev);
|
||||
|
||||
mtx_unlock(&Giant);
|
||||
|
||||
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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 @@ usb_handle_iface_request(struct usb_xfer *xfer,
|
||||
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);
|
||||
}
|
||||
|
@ -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 @@ uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
|
||||
/* 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 @@ uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
|
||||
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 @@ uhub_reattach_port(struct uhub_softc *sc, uint8_t portno)
|
||||
|
||||
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 @@ usb_dev_suspend_peer(struct usb_device *udev)
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
|
@ -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);
|
||||
|
@ -1156,7 +1156,7 @@ vbd_add_dev(struct xenbus_device *xdev)
|
||||
devclass_t dc;
|
||||
int err = 0;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
newbus_xlock();
|
||||
|
||||
/* We will add a vbd device as a child of nexus0 (for now) */
|
||||
if (!(dc = devclass_find("nexus")) ||
|
||||
@ -1183,7 +1183,7 @@ vbd_add_dev(struct xenbus_device *xdev)
|
||||
|
||||
done:
|
||||
|
||||
mtx_unlock(&Giant);
|
||||
newbus_xunlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1388,7 +1388,7 @@ vif_add_dev(struct xenbus_device *xdev)
|
||||
devclass_t dc;
|
||||
int err = 0;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
newbus_xlock();
|
||||
|
||||
/* We will add a vif device as a child of nexus0 (for now) */
|
||||
if (!(dc = devclass_find("nexus")) ||
|
||||
@ -1415,7 +1415,7 @@ vif_add_dev(struct xenbus_device *xdev)
|
||||
|
||||
done:
|
||||
|
||||
mtx_unlock(&Giant);
|
||||
newbus_xunlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -164,6 +164,7 @@ acpi_capm_get_info(apm_info_t aip)
|
||||
else
|
||||
aip->ai_acline = acline; /* on/off */
|
||||
|
||||
newbus_slock();
|
||||
if (acpi_battery_get_battinfo(NULL, &batt) != 0) {
|
||||
aip->ai_batt_stat = APM_UNKNOWN;
|
||||
aip->ai_batt_life = APM_UNKNOWN;
|
||||
@ -175,6 +176,7 @@ acpi_capm_get_info(apm_info_t aip)
|
||||
aip->ai_batt_time = (batt.min == -1) ? -1 : batt.min * 60;
|
||||
aip->ai_batteries = acpi_battery_get_units();
|
||||
}
|
||||
newbus_sunlock();
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -190,6 +192,7 @@ acpi_capm_get_pwstatus(apm_pwstatus_t app)
|
||||
(app->ap_device < PMDV_BATT0 || app->ap_device > PMDV_BATT_ALL))
|
||||
return (1);
|
||||
|
||||
newbus_slock();
|
||||
if (app->ap_device == PMDV_ALLDEV)
|
||||
error = acpi_battery_get_battinfo(NULL, &batt);
|
||||
else {
|
||||
@ -200,6 +203,7 @@ acpi_capm_get_pwstatus(apm_pwstatus_t app)
|
||||
else
|
||||
error = ENXIO;
|
||||
}
|
||||
newbus_sunlock();
|
||||
if (error)
|
||||
return (1);
|
||||
|
||||
@ -283,7 +287,9 @@ apmopen(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||
struct acpi_softc *acpi_sc;
|
||||
struct apm_clone_data *clone;
|
||||
|
||||
newbus_slock();
|
||||
acpi_sc = devclass_get_softc(devclass_find("acpi"), 0);
|
||||
newbus_sunlock();
|
||||
clone = apm_create_clone(dev, acpi_sc);
|
||||
dev->si_drv1 = clone;
|
||||
|
||||
|
@ -288,10 +288,12 @@ smapi_modevent (module_t mod, int what, void *arg)
|
||||
case MOD_LOAD:
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
newbus_xlock();
|
||||
devclass_get_devices(smapi_devclass, &devs, &count);
|
||||
for (i = 0; i < count; i++) {
|
||||
device_delete_child(device_get_parent(devs[i]), devs[i]);
|
||||
}
|
||||
newbus_xunlock();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -230,10 +230,12 @@ smbios_modevent (mod, what, arg)
|
||||
case MOD_LOAD:
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
newbus_xlock();
|
||||
devclass_get_devices(smbios_devclass, &devs, &count);
|
||||
for (i = 0; i < count; i++) {
|
||||
device_delete_child(device_get_parent(devs[i]), devs[i]);
|
||||
}
|
||||
newbus_xunlock();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -248,10 +248,12 @@ vpd_modevent (mod, what, arg)
|
||||
case MOD_LOAD:
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
newbus_xlock();
|
||||
devclass_get_devices(vpd_devclass, &devs, &count);
|
||||
for (i = 0; i < count; i++) {
|
||||
device_delete_child(device_get_parent(devs[i]), devs[i]);
|
||||
}
|
||||
newbus_xunlock();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/rman.h>
|
||||
#include <sys/selinfo.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/uio.h>
|
||||
@ -191,6 +192,54 @@ void print_devclass_list(void);
|
||||
#define print_devclass_list() /* nop */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Newbus locking facilities.
|
||||
*/
|
||||
static struct sx newbus_lock;
|
||||
|
||||
#define NBL_LOCK_INIT() sx_init(&newbus_lock, "newbus")
|
||||
#define NBL_LOCK_DESTROY() sx_destroy(&newbus_lock)
|
||||
#define NBL_XLOCK() sx_xlock(&newbus_lock)
|
||||
#define NBL_SLOCK() sx_slock(&newbus_lock)
|
||||
#define NBL_XUNLOCK() sx_xunlock(&newbus_lock)
|
||||
#define NBL_SUNLOCK() sx_sunlock(&newbus_lock)
|
||||
#ifdef INVARIANTS
|
||||
#define NBL_ASSERT(what) do { \
|
||||
if (cold == 0) \
|
||||
sx_assert(&newbus_lock, (what)); \
|
||||
} while (0)
|
||||
#else
|
||||
#define NBL_ASSERT(what)
|
||||
#endif
|
||||
|
||||
void
|
||||
newbus_xlock()
|
||||
{
|
||||
|
||||
NBL_XLOCK();
|
||||
}
|
||||
|
||||
void
|
||||
newbus_slock()
|
||||
{
|
||||
|
||||
NBL_SLOCK();
|
||||
}
|
||||
|
||||
void
|
||||
newbus_xunlock()
|
||||
{
|
||||
|
||||
NBL_XUNLOCK();
|
||||
}
|
||||
|
||||
void
|
||||
newbus_sunlock()
|
||||
{
|
||||
|
||||
NBL_SUNLOCK();
|
||||
}
|
||||
|
||||
/*
|
||||
* dev sysctl tree
|
||||
*/
|
||||
@ -364,7 +413,6 @@ static d_poll_t devpoll;
|
||||
|
||||
static struct cdevsw dev_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_flags = D_NEEDGIANT,
|
||||
.d_open = devopen,
|
||||
.d_close = devclose,
|
||||
.d_read = devread,
|
||||
@ -1061,6 +1109,7 @@ devclass_delete_driver(devclass_t busclass, driver_t *driver)
|
||||
int i;
|
||||
int error;
|
||||
|
||||
NBL_ASSERT(SA_XLOCKED);
|
||||
PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
|
||||
|
||||
if (!dc)
|
||||
@ -1759,6 +1808,7 @@ device_delete_child(device_t dev, device_t child)
|
||||
int error;
|
||||
device_t grandchild;
|
||||
|
||||
NBL_ASSERT(SA_XLOCKED);
|
||||
PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev)));
|
||||
|
||||
/* remove children first */
|
||||
@ -1857,7 +1907,7 @@ device_probe_child(device_t dev, device_t child)
|
||||
int result, pri = 0;
|
||||
int hasclass = (child->devclass != NULL);
|
||||
|
||||
GIANT_REQUIRED;
|
||||
NBL_ASSERT(SA_XLOCKED);
|
||||
|
||||
dc = dev->devclass;
|
||||
if (!dc)
|
||||
@ -2508,7 +2558,7 @@ device_probe(device_t dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
NBL_ASSERT(SA_XLOCKED);
|
||||
|
||||
if (dev->state >= DS_ALIVE && (dev->flags & DF_REBID) == 0)
|
||||
return (-1);
|
||||
@ -2542,7 +2592,7 @@ device_probe_and_attach(device_t dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
NBL_ASSERT(SA_XLOCKED);
|
||||
|
||||
error = device_probe(dev);
|
||||
if (error == -1)
|
||||
@ -2576,6 +2626,8 @@ device_attach(device_t dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
NBL_ASSERT(SA_XLOCKED);
|
||||
|
||||
device_sysctl_init(dev);
|
||||
if (!device_is_quiet(dev))
|
||||
device_print_child(dev->parent, dev);
|
||||
@ -2617,7 +2669,7 @@ device_detach(device_t dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
NBL_ASSERT(SA_XLOCKED);
|
||||
|
||||
PDEBUG(("%s", DEVICENAME(dev)));
|
||||
if (dev->state == DS_BUSY)
|
||||
@ -2661,6 +2713,8 @@ int
|
||||
device_quiesce(device_t dev)
|
||||
{
|
||||
|
||||
NBL_ASSERT(SA_XLOCKED);
|
||||
|
||||
PDEBUG(("%s", DEVICENAME(dev)));
|
||||
if (dev->state == DS_BUSY)
|
||||
return (EBUSY);
|
||||
@ -2681,6 +2735,7 @@ device_quiesce(device_t dev)
|
||||
int
|
||||
device_shutdown(device_t dev)
|
||||
{
|
||||
|
||||
if (dev->state < DS_ATTACHED)
|
||||
return (0);
|
||||
return (DEVICE_SHUTDOWN(dev));
|
||||
@ -3096,6 +3151,8 @@ bus_generic_attach(device_t dev)
|
||||
{
|
||||
device_t child;
|
||||
|
||||
NBL_ASSERT(SA_XLOCKED);
|
||||
|
||||
TAILQ_FOREACH(child, &dev->children, link) {
|
||||
device_probe_and_attach(child);
|
||||
}
|
||||
@ -3116,6 +3173,8 @@ bus_generic_detach(device_t dev)
|
||||
device_t child;
|
||||
int error;
|
||||
|
||||
NBL_ASSERT(SA_XLOCKED);
|
||||
|
||||
if (dev->state != DS_ATTACHED)
|
||||
return (EBUSY);
|
||||
|
||||
@ -3996,6 +4055,7 @@ root_bus_module_handler(module_t mod, int what, void* arg)
|
||||
switch (what) {
|
||||
case MOD_LOAD:
|
||||
TAILQ_INIT(&bus_data_devices);
|
||||
NBL_LOCK_INIT();
|
||||
kobj_class_compile((kobj_class_t) &root_driver);
|
||||
root_bus = make_device(NULL, "root", 0);
|
||||
root_bus->desc = "System root bus";
|
||||
@ -4055,14 +4115,28 @@ driver_module_handler(module_t mod, int what, void *arg)
|
||||
kobj_class_t driver;
|
||||
int error, pass;
|
||||
|
||||
dmd = (struct driver_module_data *)arg;
|
||||
bus_devclass = devclass_find_internal(dmd->dmd_busname, NULL, TRUE);
|
||||
error = 0;
|
||||
dmd = (struct driver_module_data *)arg;
|
||||
|
||||
switch (what) {
|
||||
/*
|
||||
* If MOD_SHUTDOWN is passed, return immediately in order to
|
||||
* avoid unnecessary locking and a LOR with the modules sx lock.
|
||||
*/
|
||||
if (what == MOD_SHUTDOWN)
|
||||
return (EOPNOTSUPP);
|
||||
NBL_XLOCK();
|
||||
bus_devclass = devclass_find_internal(dmd->dmd_busname, NULL, TRUE);
|
||||
if (bus_devclass == NULL) {
|
||||
NBL_XUNLOCK();
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
switch (what) {
|
||||
case MOD_LOAD:
|
||||
if (dmd->dmd_chainevh)
|
||||
error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
|
||||
if (error != 0)
|
||||
break;
|
||||
|
||||
pass = dmd->dmd_pass;
|
||||
driver = dmd->dmd_driver;
|
||||
@ -4115,6 +4189,7 @@ driver_module_handler(module_t mod, int what, void *arg)
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
NBL_XUNLOCK();
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -1499,7 +1499,9 @@ fdstrategy(struct bio *bp)
|
||||
bioq_disksort(&fdc->head, bp);
|
||||
untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */
|
||||
devstat_start_transaction_bio(fd->device_stats, bp);
|
||||
newbus_xlock();
|
||||
device_busy(fd->dev);
|
||||
newbus_xunlock();
|
||||
fdstart(fdc);
|
||||
splx(s);
|
||||
return;
|
||||
@ -2178,7 +2180,9 @@ fdstate(fdc_p fdc)
|
||||
fd->skip = 0;
|
||||
bp->bio_resid = 0;
|
||||
fdc->bp = NULL;
|
||||
newbus_xlock();
|
||||
device_unbusy(fd->dev);
|
||||
newbus_xunlock();
|
||||
biofinish(bp, fd->device_stats, 0);
|
||||
fdc->fd = (fd_p) 0;
|
||||
fdc->fdu = -1;
|
||||
@ -2339,7 +2343,9 @@ retrier(struct fdc_data *fdc)
|
||||
bp->bio_resid = 0;
|
||||
fdc->bp = NULL;
|
||||
fdc->fd->skip = 0;
|
||||
newbus_xlock();
|
||||
device_unbusy(fd->dev);
|
||||
newbus_xunlock();
|
||||
biofinish(bp, fdc->fd->device_stats, 0);
|
||||
fdc->state = FINDWORK;
|
||||
fdc->flags |= FDC_NEEDS_RESET;
|
||||
|
@ -478,6 +478,14 @@ int resource_set_string(const char *name, int unit, const char *resname,
|
||||
int bus_data_generation_check(int generation);
|
||||
void bus_data_generation_update(void);
|
||||
|
||||
/*
|
||||
* Exported locking facilities.
|
||||
*/
|
||||
void newbus_xlock(void);
|
||||
void newbus_slock(void);
|
||||
void newbus_xunlock(void);
|
||||
void newbus_sunlock(void);
|
||||
|
||||
/**
|
||||
* Some convenience defines for probe routines to return. These are just
|
||||
* suggested values, and there's nothing magical about them.
|
||||
|
@ -58,7 +58,7 @@
|
||||
* in the range 5 to 9.
|
||||
*/
|
||||
#undef __FreeBSD_version
|
||||
#define __FreeBSD_version 800106 /* Master, propagated to newvers */
|
||||
#define __FreeBSD_version 800107 /* Master, propagated to newvers */
|
||||
|
||||
#ifndef LOCORE
|
||||
#include <sys/types.h>
|
||||
|
@ -348,7 +348,9 @@ xenbus_devices_changed(struct xenbus_watch *watch,
|
||||
if (p)
|
||||
*p = 0;
|
||||
|
||||
newbus_xlock();
|
||||
xenbus_add_device(dev, bus, type, id);
|
||||
newbus_xunlock();
|
||||
taskqueue_enqueue(taskqueue_thread, &sc->xs_probechildren);
|
||||
out:
|
||||
free(node, M_DEVBUF);
|
||||
@ -361,7 +363,9 @@ xenbus_attach_deferred(void *arg)
|
||||
struct xenbus_softc *sc = device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
newbus_xlock();
|
||||
error = xenbus_enumerate_bus(dev, "device");
|
||||
newbus_xunlock();
|
||||
if (error)
|
||||
return;
|
||||
xenbus_probe_children(dev);
|
||||
|
Loading…
Reference in New Issue
Block a user