diff options
-rw-r--r-- | sys/scsi/scsi_driver.c | 24 | ||||
-rw-r--r-- | sys/scsi/scsi_driver.h | 4 | ||||
-rw-r--r-- | sys/scsi/scsiconf.h | 4 | ||||
-rw-r--r-- | sys/scsi/sd.c | 19 |
4 files changed, 47 insertions, 4 deletions
diff --git a/sys/scsi/scsi_driver.c b/sys/scsi/scsi_driver.c index 06c1ebf..32d9c7b 100644 --- a/sys/scsi/scsi_driver.c +++ b/sys/scsi/scsi_driver.c @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_driver.c,v 1.22 1997/02/22 09:44:31 peter Exp $ + * $Id: scsi_driver.c,v 1.23 1997/03/23 06:33:47 bde Exp $ * */ @@ -232,3 +232,25 @@ scsi_strategy(struct buf *bp, struct scsi_device *device) } } } + +int scsi_device_lock(struct scsi_link *sc_link) +{ + int error; + while (sc_link->flags & SDEV_XLOCK) { + sc_link->flags |= SDEV_WANT; + error = tsleep(&sc_link->flags, PRIBIO | PCATCH, "sdevlk",0); + if (error) + return error; + } + sc_link->flags |= SDEV_XLOCK; + return 0; +} + +void scsi_device_unlock(struct scsi_link *sc_link) +{ + sc_link->flags &= ~SDEV_XLOCK; + if (sc_link->flags & SDEV_WANT) { + sc_link->flags &= ~SDEV_WANT; + wakeup(&sc_link->flags); + } +} diff --git a/sys/scsi/scsi_driver.h b/sys/scsi/scsi_driver.h index f6875da..bbbe318 100644 --- a/sys/scsi/scsi_driver.h +++ b/sys/scsi/scsi_driver.h @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_driver.h,v 1.10 1997/02/22 09:44:31 peter Exp $ + * $Id: scsi_driver.h,v 1.11 1997/03/23 04:39:07 bde Exp $ * */ #ifndef _SCSI__DRIVER_H_ @@ -50,6 +50,8 @@ struct proc; int scsi_goaway __P((int)); int scsi_device_attach __P((struct scsi_link *)); +int scsi_device_lock __P((struct scsi_link *)); +void scsi_device_unlock __P((struct scsi_link *)); int scsi_open __P((dev_t, int, int, struct proc *, struct scsi_device *)); int scsi_close __P((dev_t, int, int, struct proc *, struct scsi_device *)); diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h index 563645f..6c14350 100644 --- a/sys/scsi/scsiconf.h +++ b/sys/scsi/scsiconf.h @@ -14,7 +14,7 @@ * * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 * - * $Id: scsiconf.h,v 1.53 1997/04/03 10:09:29 kato Exp $ + * $Id: scsiconf.h,v 1.54 1997/05/19 17:32:10 jmz Exp $ */ #ifndef SCSI_SCSICONF_H #define SCSI_SCSICONF_H 1 @@ -337,6 +337,8 @@ struct scsi_link #define SDEV_TARGET_OPS 0x0800 /* XXX-HA: Supports target ops */ #define SDEV_IS_OPEN 0x1000 /* at least 1 open session */ #define SDEV_UK 0x2000 /* this is the "uk" device */ +#define SDEV_XLOCK 0x4000 /* Device is locked */ +#define SDEV_WANT 0x8000 /* A process is waiting for lock */ /* * One of these is allocated and filled in for each scsi bus. diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index cef96bd..8386c42 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -15,7 +15,7 @@ * * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992 * - * $Id: sd.c,v 1.104 1997/03/24 11:25:02 bde Exp $ + * $Id: sd.c,v 1.105 1997/05/01 19:15:38 sos Exp $ */ #include "opt_bounce.h" @@ -279,6 +279,10 @@ sd_open(dev, mode, fmt, p, sc_link) */ scsi_test_unit_ready(sc_link, 0); + errcode = scsi_device_lock(sc_link); + if (errcode) + return errcode; + /* * If it's been invalidated, then forget the label */ @@ -354,6 +358,7 @@ sd_open(dev, mode, fmt, p, sc_link) SC_DEBUG(sc_link, SDEV_DB3, ("open %ld %ld\n", sdstrats, sdqueues)); + scsi_device_unlock(sc_link); return 0; bad: @@ -361,6 +366,7 @@ bad: scsi_prevent(sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT); sc_link->flags &= ~SDEV_OPEN; } + scsi_device_unlock(sc_link); return errcode; } @@ -377,13 +383,18 @@ sd_close(dev, fflag, fmt, p, sc_link) struct scsi_link *sc_link; { struct scsi_data *sd; + errval errcode; sd = sc_link->sd; + errcode = scsi_device_lock(sc_link); + if (errcode) + return errcode; dsclose(dev, fmt, sd->dk_slices); if (!dsisopen(sd->dk_slices)) { scsi_prevent(sc_link, PR_ALLOW, SCSI_SILENT | SCSI_ERR_OK); sc_link->flags &= ~SDEV_OPEN; } + scsi_device_unlock(sc_link); return (0); } @@ -661,8 +672,14 @@ sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p, if (cmd == DIOCSBAD) return (EINVAL); /* XXX */ + + error = scsi_device_lock(sc_link); + if (error) + return error; + error = dsioctl("sd", dev, cmd, addr, flag, &sd->dk_slices, sdstrategy1, (ds_setgeom_t *)NULL); + scsi_device_unlock(sc_link); if (error != -1) return (error); if (PARTITION(dev) != RAW_PART) |