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
This commit is contained in:
parent
344aebe2c2
commit
9ea9af5281
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user