aboutsummaryrefslogtreecommitdiff
path: root/sys/ia64
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2012-08-16 17:17:08 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2012-08-16 17:17:08 +0000
commit9ea9af5281f6b37b62bdd7ae73e722f0c65ac5ad (patch)
treeea71bba17b7d635b91fcb0fec57e515f0fb3cae6 /sys/ia64
parent344aebe2c2cb04ca1976157fd8661e9ab214d258 (diff)
downloadsrc-9ea9af5281f6b37b62bdd7ae73e722f0c65ac5ad.tar.gz
src-9ea9af5281f6b37b62bdd7ae73e722f0c65ac5ad.zip
Add locking for sscdisk(4) and mark it MPSAFE. Since this driver just
makes calls out to the emulator, the locking is fairly simple. A global mutex protects the list of ssc disks, and each ssc disk has a mutex to protect it's bioq. Approved by: marcel
Notes
Notes: svn path=/head/; revision=239331
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/sscdisk.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/sys/ia64/ia64/sscdisk.c b/sys/ia64/ia64/sscdisk.c
index b38a73a3be9c..146be7f733c4 100644
--- a/sys/ia64/ia64/sscdisk.c
+++ b/sys/ia64/ia64/sscdisk.c
@@ -77,13 +77,15 @@ static MALLOC_DEFINE(M_SSC, "ssc_disk", "Simulator Disk");
static d_strategy_t sscstrategy;
static LIST_HEAD(, ssc_s) ssc_softc_list = LIST_HEAD_INITIALIZER(ssc_softc_list);
+static struct mtx ssc_list_lock;
+MTX_SYSINIT(ssc_list, &ssc_list_lock, "ssc list", MTX_DEF);
struct ssc_s {
int unit;
LIST_ENTRY(ssc_s) list;
struct bio_queue_head bio_queue;
struct disk *disk;
- struct cdev *dev;
+ struct mtx lock;
int busy;
int fd;
};
@@ -94,30 +96,27 @@ static void
sscstrategy(struct bio *bp)
{
struct ssc_s *sc;
- int s;
struct disk_req req;
struct disk_stat stat;
u_long len, va, off;
sc = bp->bio_disk->d_drv1;
- s = splbio();
-
+ mtx_lock(&sc->lock);
bioq_disksort(&sc->bio_queue, bp);
if (sc->busy) {
- splx(s);
+ mtx_unlock(&sc->lock);
return;
}
-
sc->busy++;
-
- while (1) {
+
+ for (;;) {
bp = bioq_takefirst(&sc->bio_queue);
- splx(s);
if (!bp)
break;
+ mtx_unlock(&sc->lock);
va = (u_long) bp->bio_data;
len = bp->bio_bcount;
off = bp->bio_pblkno << DEV_BSHIFT;
@@ -140,10 +139,11 @@ sscstrategy(struct bio *bp)
}
bp->bio_resid = 0;
biodone(bp);
- s = splbio();
+ mtx_lock(&sc->lock);
}
sc->busy = 0;
+ mtx_unlock(&sc->lock);
return;
}
@@ -158,17 +158,24 @@ ssccreate(int unit)
if (fd == -1)
return (NULL);
+ sc = malloc(sizeof(*sc), M_SSC, M_WAITOK | M_ZERO);
+
+ mtx_lock(&ssc_list_lock);
if (unit == -1)
unit = sscunits++;
/* Make sure this unit isn't already in action */
LIST_FOREACH(sc, &ssc_softc_list, list) {
- if (sc->unit == unit)
+ if (sc->unit == unit) {
+ mtx_unlock(&ssc_list_lock);
+ free(sc, M_SSC);
return (NULL);
+ }
}
- sc = malloc(sizeof(*sc), M_SSC, M_WAITOK | M_ZERO);
LIST_INSERT_HEAD(&ssc_softc_list, sc, list);
sc->unit = unit;
+ mtx_unlock(&ssc_list_lock);
bioq_init(&sc->bio_queue);
+ mtx_init(&sc->lock, "ssc", NULL, MTX_DEF);
sc->disk = disk_alloc();
sc->disk->d_drv1 = sc;
@@ -180,7 +187,6 @@ ssccreate(int unit)
sc->disk->d_sectorsize = DEV_BSIZE;
sc->disk->d_strategy = sscstrategy;
sc->disk->d_unit = sc->unit;
- sc->disk->d_flags = DISKFLAG_NEEDSGIANT;
disk_create(sc->disk, DISK_VERSION);
sc->fd = fd;
if (sc->unit == 0)