aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/amr
diff options
context:
space:
mode:
authorAttilio Rao <attilio@FreeBSD.org>2009-08-02 14:28:40 +0000
committerAttilio Rao <attilio@FreeBSD.org>2009-08-02 14:28:40 +0000
commit444b91868b5294e3a2151fffa3b063763a562448 (patch)
treec00d808d1df8000c2086c86613be9ec8536a5e28 /sys/dev/amr
parentd40b91cb1354e9bae491567cc88c215eda16d649 (diff)
downloadsrc-444b91868b5294e3a2151fffa3b063763a562448.tar.gz
src-444b91868b5294e3a2151fffa3b063763a562448.zip
Notes
Diffstat (limited to 'sys/dev/amr')
-rw-r--r--sys/dev/amr/amr.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c
index 2061fcc801f9..688b2df63ad7 100644
--- a/sys/dev/amr/amr.c
+++ b/sys/dev/amr/amr.c
@@ -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);