summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/scsi/scsi_driver.c24
-rw-r--r--sys/scsi/scsi_driver.h4
-rw-r--r--sys/scsi/scsiconf.h4
-rw-r--r--sys/scsi/sd.c19
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)
OpenPOWER on IntegriCloud