summaryrefslogtreecommitdiffstats
path: root/sys/scsi
diff options
context:
space:
mode:
authordufault <dufault@FreeBSD.org>1995-03-04 20:51:10 +0000
committerdufault <dufault@FreeBSD.org>1995-03-04 20:51:10 +0000
commitcaa91d7b29df7b209af9699dd4f38031136d1b0d (patch)
tree08e7e0728f4cbe050b6439ba8c037dc43bf00e8e /sys/scsi
parent504389ec944dd6925d07e290d3aa2f23ccb14153 (diff)
downloadFreeBSD-src-caa91d7b29df7b209af9699dd4f38031136d1b0d.zip
FreeBSD-src-caa91d7b29df7b209af9699dd4f38031136d1b0d.tar.gz
1. Change driver signatures to full signature for slice support.
2. Add "pt" (processor type) driver. 3. Add "worm" (Write Once) driver for Jordan.
Diffstat (limited to 'sys/scsi')
-rw-r--r--sys/scsi/cd.c34
-rw-r--r--sys/scsi/ch.c40
-rw-r--r--sys/scsi/pt.c214
-rw-r--r--sys/scsi/scsi_base.c63
-rw-r--r--sys/scsi/scsi_driver.c36
-rw-r--r--sys/scsi/scsi_driver.h17
-rw-r--r--sys/scsi/scsi_ioctl.c4
-rw-r--r--sys/scsi/scsiconf.c69
-rw-r--r--sys/scsi/scsiconf.h58
-rw-r--r--sys/scsi/sd.c32
-rw-r--r--sys/scsi/st.c23
-rw-r--r--sys/scsi/su.c64
-rw-r--r--sys/scsi/uk.c20
-rw-r--r--sys/scsi/worm.c360
14 files changed, 835 insertions, 199 deletions
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c
index d052203..76ce80e 100644
--- a/sys/scsi/cd.c
+++ b/sys/scsi/cd.c
@@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
- * $Id: cd.c,v 1.33 1995/01/08 13:38:28 dufault Exp $
+ * $Id: cd.c,v 1.34 1995/03/01 22:24:39 dufault Exp $
*/
#define SPLCD splbio
@@ -89,10 +89,12 @@ struct scsi_data {
static int cdunit(dev_t dev) { return CDUNIT(dev); }
static dev_t cdsetunit(dev_t dev, int unit) { return CDSETUNIT(dev, unit); }
-errval cd_open(dev_t dev, int flags, struct scsi_link *sc_link);
+errval cd_open(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_link *sc_link);
errval cd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
- struct scsi_link *sc_link);
-errval cd_close(dev_t dev, struct scsi_link *sc_link);
+ struct proc *p, struct scsi_link *sc_link);
+errval cd_close(dev_t dev, int flag, int fmt, struct proc *p,
+ struct scsi_link *sc_link);
void cd_strategy(struct buf *bp, struct scsi_link *sc_link);
SCSI_DEVICE_ENTRIES(cd)
@@ -108,6 +110,7 @@ struct scsi_device cd_switch =
{0, 0},
0, /* Link flags */
cdattach,
+ "CD-ROM",
cdopen,
sizeof(struct scsi_data),
T_READONLY,
@@ -138,7 +141,6 @@ static struct kern_devconf kdc_cd_template = {
&kdc_scbus0, /* parent - XXX should be host adapter*/
0, /* parentdata */
DC_UNKNOWN, /* not supported */
- "SCSI CD-ROM drive"
};
static inline void
@@ -150,6 +152,7 @@ cd_registerdev(int unit)
if(!kdc) return;
*kdc = kdc_cd_template;
kdc->kdc_unit = unit;
+ kdc->kdc_description = cd_switch.desc;
/* XXX should set parentdata */
dev_attach(kdc);
if(dk_ndrive < DK_NDRIVE) {
@@ -209,7 +212,8 @@ cdattach(struct scsi_link *sc_link)
* open the device. Make sure the partition info is a up-to-date as can be.
*/
errval
-cd_open(dev_t dev, int flags, struct scsi_link *sc_link)
+cd_open(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_link *sc_link)
{
errval errcode = 0;
u_int32 unit, part;
@@ -226,7 +230,7 @@ cd_open(dev_t dev, int flags, struct scsi_link *sc_link)
return (ENXIO);
SC_DEBUG(sc_link, SDEV_DB1,
- ("cdopen: dev=0x%x (unit %d,partition %d)\n",
+ ("cd_open: dev=0x%x (unit %d,partition %d)\n",
dev, unit, part));
/*
* If it's been invalidated, and not everybody has closed it then
@@ -240,7 +244,7 @@ cd_open(dev_t dev, int flags, struct scsi_link *sc_link)
* Check that it is still responding and ok.
* if the media has been changed this will result in a
* "unit attention" error which the error code will
- * disregard because the SDEV_MEDIA_LOADED flag is not yet set
+ * disregard because the SDEV_OPEN flag is not yet set
*/
scsi_test_unit_ready(sc_link, SCSI_SILENT);
@@ -316,7 +320,8 @@ cd_open(dev_t dev, int flags, struct scsi_link *sc_link)
* occurence of an open device
*/
errval
-cd_close(dev_t dev, struct scsi_link *sc_link)
+cd_close(dev_t dev, int flag, int fmt, struct proc *p,
+ struct scsi_link *sc_link)
{
u_int8 unit, part;
struct scsi_data *cd;
@@ -370,12 +375,6 @@ cd_strategy(struct buf *bp, struct scsi_link *sc_link)
goto bad;
}
/*
- * If it's a null transfer, return immediatly
- */
- if (bp->b_bcount == 0) {
- goto done;
- }
- /*
* Decide which unit and partition we are talking about
*/
if (PARTITION(bp->b_dev) != RAW_PART) {
@@ -539,7 +538,8 @@ cdstart(unit)
* Knows about the internals of this device
*/
errval
-cd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct scsi_link *sc_link)
+cd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p,
+struct scsi_link *sc_link)
{
errval error = 0;
u_int8 unit, part;
@@ -869,7 +869,7 @@ cd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct scsi_link *sc_link)
break;
default:
if(part == RAW_PART || SCSI_SUPER(dev))
- error = scsi_do_ioctl(dev, cmd, addr, flag, sc_link);
+ error = scsi_do_ioctl(dev, cmd, addr, flag, p, sc_link);
else
error = ENOTTY;
break;
diff --git a/sys/scsi/ch.c b/sys/scsi/ch.c
index 1c19f5e..73ebc95 100644
--- a/sys/scsi/ch.c
+++ b/sys/scsi/ch.c
@@ -2,7 +2,7 @@
* Written by grefen@?????
* Based on scsi drivers by Julian Elischer (julian@tfs.com)
*
- * $Id: ch.c,v 1.13 1995/01/19 21:02:54 ats Exp $
+ * $Id: ch.c,v 1.14 1995/03/01 22:24:40 dufault Exp $
*/
#include <sys/types.h>
@@ -46,16 +46,17 @@ struct scsi_data {
u_long op_matrix; /* possible opertaions */
u_int16 lsterr; /* details of lasterror */
u_char stor; /* posible Storage locations */
- u_int32 initialized;
};
static int chunit(dev_t dev) { return CHUNIT(dev); }
static dev_t chsetunit(dev_t dev, int unit) { return CHSETUNIT(dev, unit); }
-errval ch_open(dev_t dev, int flags, struct scsi_link *sc_link);
+errval ch_open(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_link *sc_link);
errval ch_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
- struct scsi_link *sc_link);
-errval ch_close(dev_t dev, struct scsi_link *sc_link);
+ struct proc *p, struct scsi_link *sc_link);
+errval ch_close(dev_t dev, int flag, int fmt, struct proc *p,
+ struct scsi_link *sc_link);
SCSI_DEVICE_ENTRIES(ch)
@@ -70,6 +71,7 @@ struct scsi_device ch_switch =
{0, 0},
0, /* Link flags */
chattach,
+ "Medium-Changer",
chopen,
sizeof(struct scsi_data),
T_CHANGER,
@@ -82,7 +84,6 @@ struct scsi_device ch_switch =
};
#define CH_OPEN 0x01
-#define CH_KNOWN 0x02
static int
ch_externalize(struct proc *p, struct kern_devconf *kdc, void *userp,
@@ -99,7 +100,6 @@ static struct kern_devconf kdc_ch_template = {
&kdc_scbus0, /* parent */
0, /* parentdata */
DC_UNKNOWN, /* not supported */
- "SCSI media changer"
};
static inline void
@@ -111,6 +111,7 @@ ch_registerdev(int unit)
if(!kdc) return;
*kdc = kdc_ch_template;
kdc->kdc_unit = unit;
+ kdc->kdc_description = ch_switch.desc;
dev_attach(kdc);
}
@@ -121,7 +122,7 @@ ch_registerdev(int unit)
errval
chattach(struct scsi_link *sc_link)
{
- u_int32 unit, i, stat;
+ u_int32 unit, i;
unsigned char *tbl;
struct scsi_data *ch = sc_link->sd;
@@ -134,14 +135,11 @@ chattach(struct scsi_link *sc_link)
* request must specify this.
*/
if ((ch_mode_sense(unit, SCSI_NOSLEEP | SCSI_NOMASK /*| SCSI_SILENT */ ))) {
- printf("scsi changer :- offline\n");
- stat = CH_OPEN;
+ printf("offline\n");
} else {
- printf("scsi changer, %d slot(s) %d drive(s) %d arm(s) %d i/e-slot(s)\n",
+ printf("%d slot(s) %d drive(s) %d arm(s) %d i/e-slot(s)\n",
ch->slots, ch->drives, ch->chms, ch->imexs);
- stat = CH_KNOWN;
}
- ch->initialized = 1;
ch_registerdev(unit);
return 0;
@@ -151,7 +149,8 @@ chattach(struct scsi_link *sc_link)
* open the device.
*/
errval
-ch_open(dev_t dev, int flags, struct scsi_link *sc_link)
+ch_open(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_link *sc_link)
{
errval errcode = 0;
u_int32 unit, mode;
@@ -169,12 +168,6 @@ ch_open(dev_t dev, int flags, struct scsi_link *sc_link)
return EBUSY;
}
/*
- * Make sure the device has been initialised
- */
- if (!cd->initialized)
- return (ENXIO);
-
- /*
* Catch any unit attention errors.
*/
scsi_test_unit_ready(sc_link, SCSI_SILENT);
@@ -205,7 +198,8 @@ ch_open(dev_t dev, int flags, struct scsi_link *sc_link)
* occurence of an open device
*/
errval
-ch_close(dev_t dev, struct scsi_link *sc_link)
+ch_close(dev_t dev, int flag, int fmt, struct proc *p,
+ struct scsi_link *sc_link)
{
sc_link->sd->flags = 0;
sc_link->flags &= ~SDEV_OPEN;
@@ -218,7 +212,7 @@ ch_close(dev_t dev, struct scsi_link *sc_link)
*/
errval
ch_ioctl(dev_t dev, int cmd, caddr_t arg, int mode,
-struct scsi_link *sc_link)
+struct proc *p, struct scsi_link *sc_link)
{
/* struct ch_cmd_buf *args; */
union scsi_cmd *scsi_cmd;
@@ -274,7 +268,7 @@ struct scsi_link *sc_link)
}
}
default:
- return scsi_do_ioctl(dev, cmd, arg, mode, sc_link);
+ return scsi_do_ioctl(dev, cmd, arg, mode, p, sc_link);
}
return (ret ? ESUCCESS : EIO);
}
diff --git a/sys/scsi/pt.c b/sys/scsi/pt.c
new file mode 100644
index 0000000..e606b8e
--- /dev/null
+++ b/sys/scsi/pt.c
@@ -0,0 +1,214 @@
+/*
+ * pt: Processor Type driver.
+ *
+ * Copyright (C) 1995, HD Associates, Inc.
+ * PO Box 276
+ * Pepperell, MA 01463
+ * 508 433 5266
+ * dufault@hda.com
+ *
+ * This code is contributed to the University of California at Berkeley:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id:$
+ */
+
+/*
+ * XXX dufault@hda.com: We need the "kern devconf" stuff, but I'm not
+ * going to add it until it is done in a simple way that provides
+ * base behavior in scsi_driver.c
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+
+struct scsi_data {
+ struct buf *buf_queue; /* the queue of pending IO operations */
+};
+
+void ptstart(u_int32 unit);
+void pt_strategy(struct buf *bp, struct scsi_link *sc_link);
+
+SCSI_DEVICE_ENTRIES(pt)
+
+struct scsi_device pt_switch =
+{
+ NULL,
+ ptstart, /* we have a queue, and this is how we service it */
+ NULL,
+ NULL,
+ "pt",
+ 0,
+ {0, 0},
+ SDEV_ONCE_ONLY, /* Only one open allowed */
+ 0,
+ "Processor",
+ ptopen,
+ sizeof(struct scsi_data),
+ T_PROCESSOR,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ pt_strategy,
+};
+/*
+ * ptstart looks to see if there is a buf waiting for the device
+ * and that the device is not already busy. If both are true,
+ * It dequeues the buf and creates a scsi command to perform the
+ * transfer required. The transfer request will call scsi_done
+ * on completion, which will in turn call this routine again
+ * so that the next queued transfer is performed.
+ * The bufs are queued by the strategy routine (ptstrategy)
+ *
+ * This routine is also called after other non-queued requests
+ * have been made of the scsi driver, to ensure that the queue
+ * continues to be drained.
+ * ptstart() is called at splbio
+ */
+void
+ptstart(unit)
+ u_int32 unit;
+{
+ struct scsi_link *sc_link = SCSI_LINK(&pt_switch, unit);
+ struct scsi_data *pt = sc_link->sd;
+ register struct buf *bp = 0;
+ struct
+ {
+#define PROCESSOR_SEND 0x0A
+#define PROCESSOR_RECEIVE 0x08
+ u_char op_code;
+ u_char byte2;
+ u_char len[3];
+ u_char control;
+ } cmd;
+
+ u_int32 flags;
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("ptstart "));
+ /*
+ * See if there is a buf to do and we are not already
+ * doing one
+ */
+ while (sc_link->opennings != 0) {
+
+ /* if a special awaits, let it proceed first */
+ if (sc_link->flags & SDEV_WAITING) {
+ sc_link->flags &= ~SDEV_WAITING;
+ wakeup((caddr_t)sc_link);
+ return;
+ }
+ if ((bp = pt->buf_queue) == NULL) {
+ return; /* no work to bother with */
+ }
+ pt->buf_queue = bp->b_actf;
+
+ /*
+ * Fill out the scsi command
+ */
+ bzero(&cmd, sizeof(cmd));
+ if ((bp->b_flags & B_READ) == B_WRITE) {
+ cmd.op_code = PROCESSOR_SEND;
+ flags = SCSI_DATA_OUT;
+ } else {
+ cmd.op_code = PROCESSOR_RECEIVE;
+ flags = SCSI_DATA_IN;
+ }
+
+ scsi_uto3b(bp->b_bcount, cmd.len);
+ /*
+ * go ask the adapter to do all this for us
+ */
+ if (scsi_scsi_cmd(sc_link,
+ (struct scsi_generic *) &cmd,
+ sizeof(cmd),
+ (u_char *) bp->b_un.b_addr,
+ bp->b_bcount,
+ 0, /* can't retry a read on a tape really */
+ 100000,
+ bp,
+ flags | SCSI_NOSLEEP) == SUCCESSFULLY_QUEUED) {
+ } else {
+badnews:
+ printf("pt%d: oops not queued\n", unit);
+ bp->b_flags |= B_ERROR;
+ bp->b_error = EIO;
+ biodone(bp);
+ }
+ } /* go back and see if we can cram more work in.. */
+}
+
+void
+pt_strategy(struct buf *bp, struct scsi_link *sc_link)
+{
+ struct buf **dp;
+ unsigned char unit;
+ u_int32 opri;
+ struct scsi_data *pt;
+
+ unit = STUNIT((bp->b_dev));
+ pt = sc_link->sd;
+
+ opri = splbio();
+
+ /*
+ * Use a bounce buffer if necessary
+ */
+#ifdef BOUNCE_BUFFERS
+ if (sc_link->flags & SDEV_BOUNCE)
+ vm_bounce_alloc(bp);
+#endif
+
+ /*
+ * Place it in the queue of activities for this tape
+ * at the end (a bit silly because we only have one user..
+ * (but it could fork() ))
+ */
+ dp = &(pt->buf_queue);
+ while (*dp) {
+ dp = &((*dp)->b_actf);
+ }
+ *dp = bp;
+ bp->b_actf = NULL;
+
+ /*
+ * Tell the device to get going on the transfer if it's
+ * not doing anything, otherwise just wait for completion
+ * (All a bit silly if we're only allowing 1 open but..)
+ */
+ ptstart(unit);
+
+ splx(opri);
+ return;
+}
diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c
index 31fdbe6..a055b33 100644
--- a/sys/scsi/scsi_base.c
+++ b/sys/scsi/scsi_base.c
@@ -8,7 +8,7 @@
* file.
*
* Written by Julian Elischer (julian@dialix.oz.au)
- * $Id: scsi_base.c,v 1.19 1995/01/31 11:41:44 dufault Exp $
+ * $Id: scsi_base.c,v 1.20 1995/02/15 07:44:07 davidg Exp $
*/
#define SPLSD splbio
@@ -108,12 +108,16 @@ free_xs(xs, sc_link, flags)
}
}
+/* XXX dufault: Replace "sd_size" with "scsi_read_capacity"
+ * when bde is done with sd.c
+ */
/*
* Find out from the device what its capacity is.
*/
u_int32
-scsi_size(sc_link, flags)
+scsi_read_capacity(sc_link, blk_size, flags)
struct scsi_link *sc_link;
+ u_int32 *blk_size;
u_int32 flags;
{
struct scsi_read_cap_data rdcap;
@@ -145,10 +149,9 @@ scsi_size(sc_link, flags)
printf("could not get size\n");
return (0);
} else {
- size = rdcap.addr_0 + 1;
- size += rdcap.addr_1 << 8;
- size += rdcap.addr_2 << 16;
- size += rdcap.addr_3 << 24;
+ size = scsi_4btou(&rdcap.addr_3) + 1;
+ if (blk_size)
+ *blk_size = scsi_4btou(&rdcap.length_3);
}
return (size);
}
@@ -932,9 +935,6 @@ scsi_uto3b(val, bytes)
*bytes = val & 0xff;
}
-/*
- * The reverse of scsi_uto3b
- */
u_int32
scsi_3btou(bytes)
u_char *bytes;
@@ -946,9 +946,6 @@ scsi_3btou(bytes)
return rc;
}
-/*
- * scsi_3btoi: scsi_3btou for twos complement signed integers:
- */
int32
scsi_3btoi(bytes)
u_char *bytes;
@@ -961,6 +958,48 @@ scsi_3btoi(bytes)
return (int32) rc;
}
+void
+scsi_uto2b(val, bytes)
+ u_int32 val;
+ u_char *bytes;
+{
+ *bytes++ = (val & 0xff00) >> 8;
+ *bytes = val & 0xff;
+}
+
+u_int32
+scsi_2btou(bytes)
+ u_char *bytes;
+{
+ u_int32 rc;
+ rc = (*bytes++ << 8);
+ rc += *bytes;
+ return rc;
+}
+
+void
+scsi_uto4b(val, bytes)
+ u_int32 val;
+ u_char *bytes;
+{
+ *bytes++ = (val & 0xff000000) >> 24;
+ *bytes++ = (val & 0xff0000) >> 16;
+ *bytes++ = (val & 0xff00) >> 8;
+ *bytes = val & 0xff;
+}
+
+u_int32
+scsi_4btou(bytes)
+ u_char *bytes;
+{
+ u_int32 rc;
+ rc = (*bytes++ << 24);
+ rc += (*bytes++ << 16);
+ rc += (*bytes++ << 8);
+ rc += *bytes;
+ return rc;
+}
+
/*
* Print out the scsi_link structure's address info.
*/
diff --git a/sys/scsi/scsi_driver.c b/sys/scsi/scsi_driver.c
index dab2d5b..56c1acd 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.1 1995/03/01 22:24:41 dufault Exp $
+ * $Id: scsi_driver.c,v 1.2 1995/03/03 21:38:43 dufault Exp $
*
*/
#include <sys/types.h>
@@ -68,13 +68,16 @@ int scsi_device_attach(struct scsi_link *sc_link)
SC_DEBUG(sc_link, SDEV_DB2,
("%s%dattach: ", device->name, sc_link->dev_unit));
+ sc_print_addr(sc_link);
+ printf("%s ", device->desc);
+
dev = scsi_dev_lookup(device->open);
sc_link->dev = (device->setunit ?
(*device->setunit)(dev, sc_link->dev_unit) :
makedev(major(dev), sc_link->dev_unit) );
- errcode = (*(device->attach))(sc_link);
+ errcode = (device->attach) ? (*(device->attach))(sc_link) : 0;
if (errcode == 0)
sc_link->flags |= device->link_flags;
@@ -82,8 +85,9 @@ int scsi_device_attach(struct scsi_link *sc_link)
return errcode;
}
-errval
-scsi_open(dev_t dev, int flags, struct scsi_device *device)
+int
+scsi_open(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_device *device)
{
errval errcode;
u_int32 unit;
@@ -102,7 +106,7 @@ scsi_open(dev_t dev, int flags, struct scsi_device *device)
return ENXIO;
errcode = (device->dev_open) ?
- (*device->dev_open)(dev, flags, sc_link) : 0;
+ (*device->dev_open)(dev, flags, fmt, p, sc_link) : 0;
if (sc_link->flags & SDEV_ONCE_ONLY) {
/*
@@ -125,8 +129,9 @@ scsi_open(dev_t dev, int flags, struct scsi_device *device)
* close the device.. only called if we are the LAST
* occurence of an open device
*/
-errval
-scsi_close(dev_t dev, struct scsi_device *device)
+int
+scsi_close(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_device *device)
{
errval errcode;
struct scsi_link *scsi_link = SCSI_LINK(device, GETUNIT(device, dev));
@@ -134,7 +139,7 @@ scsi_close(dev_t dev, struct scsi_device *device)
SC_DEBUG(scsi_link, SDEV_DB1, ("%sclose: Closing device\n", device->name));
errcode = (device->dev_close) ?
- (*device->dev_close)(dev, scsi_link) : 0;
+ (*device->dev_close)(dev, flags, fmt, p, scsi_link) : 0;
if (scsi_link->flags & SDEV_ONCE_ONLY)
scsi_link->flags &= ~SDEV_OPEN;
@@ -142,16 +147,16 @@ scsi_close(dev_t dev, struct scsi_device *device)
return errcode;
}
-errval
-scsi_ioctl(dev_t dev, u_int32 cmd, caddr_t arg, int mode,
+int
+scsi_ioctl(dev_t dev, u_int32 cmd, caddr_t arg, int mode, struct proc *p,
struct scsi_device *device)
{
errval errcode;
struct scsi_link *scsi_link = SCSI_LINK(device, GETUNIT(device, dev));
errcode = (device->dev_ioctl) ?
- (*device->dev_ioctl)(dev, cmd, arg, mode, scsi_link)
- : scsi_do_ioctl(dev, cmd, arg, mode, scsi_link);
+ (*device->dev_ioctl)(dev, cmd, arg, mode, p, scsi_link)
+ : scsi_do_ioctl(dev, cmd, arg, mode, p, scsi_link);
return errcode;
}
@@ -172,7 +177,12 @@ scsi_strategy(struct buf *bp, struct scsi_device *device)
SC_DEBUG(sc_link, SDEV_DB1, ("%s%ld: %d bytes @ blk%d\n",
device->name, unit, bp->b_bcount, bp->b_blkno));
- if (device->dev_strategy)
+ if (bp->b_bcount == 0)
+ {
+ bp->b_resid = 0;
+ biodone(bp);
+ }
+ else if (device->dev_strategy)
{
(*sc_link->adapter->scsi_minphys)(bp);
(*device->dev_strategy)(bp, sc_link);
diff --git a/sys/scsi/scsi_driver.h b/sys/scsi/scsi_driver.h
index dff132e..867b2f1 100644
--- a/sys/scsi/scsi_driver.h
+++ b/sys/scsi/scsi_driver.h
@@ -35,22 +35,27 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: scsi_ioctl.c,v 1.10 1995/01/19 12:41:36 dufault Exp $
+ * $Id: scsi_driver.h,v 1.1 1995/03/01 22:24:42 dufault Exp $
*
*/
#ifndef _SCSI__DRIVER_H_
#define _SCSI__DRIVER_H_
+#include <sys/conf.h>
+
struct kern_devconf;
struct scsi_link;
struct scsi_device;
struct buf;
+struct proc;
+
+int scsi_goaway __P((struct kern_devconf *, int));
+int scsi_device_attach __P((struct scsi_link *));
-int scsi_goaway __P((struct kern_devconf *, int));
-int scsi_device_attach __P((struct scsi_link *));
-errval scsi_open __P((dev_t, int, struct scsi_device *));
-errval scsi_close __P((dev_t, struct scsi_device *));
-errval scsi_ioctl __P((dev_t, u_int32, caddr_t, int, struct scsi_device *));
+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 *));
+int scsi_ioctl __P((dev_t, u_int32, caddr_t, int, struct proc *,
+ struct scsi_device *));
void scsi_strategy __P((struct buf *, struct scsi_device *));
void scsi_minphys __P((struct buf *, struct scsi_device *));
diff --git a/sys/scsi/scsi_ioctl.c b/sys/scsi/scsi_ioctl.c
index bca35ca..90dc134 100644
--- a/sys/scsi/scsi_ioctl.c
+++ b/sys/scsi/scsi_ioctl.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*End copyright
*
- * $Id: scsi_ioctl.c,v 1.10 1995/01/19 12:41:36 dufault Exp $
+ * $Id: scsi_ioctl.c,v 1.11 1995/03/01 22:24:42 dufault Exp $
*
*
*/
@@ -243,7 +243,7 @@ void scsiminphys(struct buf *bp)
* in the context of the calling process
*/
errval scsi_do_ioctl(dev_t dev, int cmd, caddr_t addr, int f,
-struct scsi_link *sc_link)
+struct proc *p, struct scsi_link *sc_link)
{
errval ret = 0;
diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c
index c65a774..9a998ba 100644
--- a/sys/scsi/scsiconf.c
+++ b/sys/scsi/scsiconf.c
@@ -16,7 +16,7 @@
*
* New configuration setup: dufault@hda.com
*
- * $Id: scsiconf.c,v 1.19 1995/02/14 06:18:06 phk Exp $
+ * $Id: scsiconf.c,v 1.20 1995/03/01 22:24:43 dufault Exp $
*/
#include <sys/types.h>
@@ -309,15 +309,15 @@ errval scsi_probe_bus(int bus, int targ, int lun);
/* XXX dufault@hda.com
* This scsi_device doesn't have the scsi_data_size.
- * This is used during probe and used to be "probe_switch".
+ * This is used during probe.
*/
-struct scsi_device inval_switch =
+struct scsi_device probe_switch =
{
NULL,
NULL,
NULL,
NULL,
- "??",
+ "probe",
0,
{0, 0},
NULL,
@@ -470,7 +470,7 @@ scsi_init(void)
/* Feel free to take this out when everyone is sure this config
* code works well:
*/
-#define CONFIGD() printf(" config'd at ")
+#define CONFIGD() printf(" is configured at ")
/* scsi_bus_conf: Figure out which bus this is. If it is wired in config
* use that. Otherwise use the next free one.
@@ -519,7 +519,6 @@ scsi_assign_unit(struct scsi_link *sc_link)
{
int i;
int found;
- printf("%s", sc_link->device->name);
found = 0;
for (i = 0; scsi_dinit[i].name; i++) {
if ((strcmp(sc_link->device->name, scsi_dinit[i].name) == 0) &&
@@ -529,9 +528,12 @@ scsi_assign_unit(struct scsi_link *sc_link)
(sc_link->lun == 0 && scsi_dinit[i].lun == SCCONF_UNSPEC)
) &&
sc_link->scsibus == scsi_dinit[i].cunit) {
- CONFIGD();
sc_link->dev_unit = scsi_dinit[i].unit;
found = 1;
+#ifdef CONFIGD
+ printf("%s is configured at %d\n",
+ sc_link->device->name, sc_link->dev_unit);
+#endif
break;
}
}
@@ -539,8 +541,6 @@ scsi_assign_unit(struct scsi_link *sc_link)
if (!found)
sc_link->dev_unit = sc_link->device->free_unit++;
- printf("%d: ", sc_link->dev_unit);
-
return sc_link->dev_unit;
}
@@ -669,6 +669,7 @@ scsi_probe_bus(int bus, int targ, int lun)
struct scsidevs *bestmatch = NULL;
struct scsi_link *sc_link = NULL;
boolean maybe_more;
+ int type;
if ((bus < 0 ) || ( bus >= scbusses->nelem)) {
return ENXIO;
@@ -717,11 +718,11 @@ scsi_probe_bus(int bus, int targ, int lun)
}
*sc_link = *sc_link_proto; /* struct copy */
sc_link->opennings = 1;
- sc_link->device = &inval_switch;
+ sc_link->device = &probe_switch;
sc_link->target = targ;
sc_link->lun = lun;
sc_link->quirks = 0;
- bestmatch = scsi_probedev(sc_link, &maybe_more);
+ bestmatch = scsi_probedev(sc_link, &maybe_more, &type);
#ifdef NEW_SCSICONF
if (bestmatch) {
sc_link->quirks = bestmatch->quirks;
@@ -732,7 +733,7 @@ scsi_probe_bus(int bus, int targ, int lun)
}
#endif
if (bestmatch) { /* FOUND */
- sc_link->device = scsi_device_lookup(bestmatch->type);
+ sc_link->device = scsi_device_lookup(type);
(void)scsi_assign_unit(sc_link);
@@ -777,9 +778,10 @@ scsi_link_get(bus, targ, lun)
* entry.
*/
struct scsidevs *
-scsi_probedev(sc_link, maybe_more)
+scsi_probedev(sc_link, maybe_more, type_p)
boolean *maybe_more;
struct scsi_link *sc_link;
+ int *type_p;
{
u_int8 unit = sc_link->adapter_unit;
u_int8 target = sc_link->target;
@@ -916,35 +918,20 @@ scsi_probedev(sc_link, maybe_more)
manu[8] = 0;
model[16] = 0;
version[4] = 0;
- printf("%s%d targ %d lun %d: type %ld(%s) %s SCSI%d\n"
- ,scsi_adapter->name
- ,unit
- ,target
- ,lu
+ sc_print_addr(sc_link);
+ printf("type %ld(%s) %s SCSI%d\n"
,type
,dtype
,remov ? "removable" : "fixed"
,inqbuf->version & SID_ANSII
);
- printf("%s%d targ %d lun %d: <%s%s%s>\n"
- ,scsi_adapter->name
- ,unit
- ,target
- ,lu
- ,manu
- ,model
- ,version
- );
+ sc_print_addr(sc_link);
+ printf("<%s%s%s>\n", manu, model, version );
if (qtype[0]) {
- printf("%s%d targ %d lun %d: qualifier %ld(%s)\n"
- ,scsi_adapter->name
- ,unit
- ,target
- ,lu
- ,qualifier
- ,qtype
- );
+ sc_print_addr(sc_link);
+ printf("qualifier %ld(%s)\n" ,qualifier ,qtype);
}
+
/*
* Try make as good a match as possible with
* available sub drivers
@@ -954,6 +941,15 @@ scsi_probedev(sc_link, maybe_more)
if ((bestmatch) && (bestmatch->flags & SC_MORE_LUS)) {
*maybe_more = 1;
}
+
+ /* If the device is unknown then we should be trying to look up a
+ * type driver based on the inquiry type.
+ */
+ if (bestmatch == &unknowndev)
+ *type_p = type;
+ else
+ *type_p = bestmatch->type;
+
return bestmatch;
}
@@ -1102,9 +1098,6 @@ scsi_selectdev(qualifier, type, remov, manu, model, rev)
}
#endif /* NEW_SCSICONF */
if (bestmatch == (struct scsidevs *) 0) {
- /* XXX At this point we should default to a base type driver.
- */
- printf("No explicit driver match. Attaching as unknown.\n");
bestmatch = &unknowndev;
}
return (bestmatch);
diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h
index 50faf12..2c18e9c 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.17 1995/02/14 06:17:23 phk Exp $
+ * $Id: scsiconf.h,v 1.18 1995/03/01 22:24:44 dufault Exp $
*/
#ifndef SCSI_SCSICONF_H
#define SCSI_SCSICONF_H 1
@@ -148,6 +148,9 @@ struct scsi_data;
struct scsi_link; /* scsi_link refers to scsi_device and vice-versa */
struct scsi_xfer;
+
+struct proc;
+
/*
* These entry points are called by the low-end drivers to get services from
* whatever high-end drivers they are attached to. Each device type has one
@@ -172,17 +175,20 @@ struct scsi_device
/* 36*/ int32 link_flags; /* Flags OR'd into sc_link at attach time */
/* 40*/ errval (*attach)(struct scsi_link *sc_link);
-/* 44*/ int (*open)(dev_t dev, int flags);
-/* 48*/ int sizeof_scsi_data;
-/* 52*/ int type; /* Type of device this supports */
-/* 56*/ int (*getunit)(dev_t dev);
-/* 60*/ dev_t (*setunit)(dev_t dev, int unit);
-
-/* 64*/ errval (*dev_open)(dev_t dev, int flags, struct scsi_link *sc_link);
-/* 68*/ errval (*dev_ioctl)(dev_t dev, int cmd, caddr_t arg, int mode,
+/* 44*/ char *desc; /* Description of device */
+/* 48*/ int (*open)(dev_t dev, int flags, int fmt, struct proc *p);
+/* 52*/ int sizeof_scsi_data;
+/* 56*/ int type; /* Type of device this supports */
+/* 60*/ int (*getunit)(dev_t dev);
+/* 64*/ dev_t (*setunit)(dev_t dev, int unit);
+
+/* 68*/ int (*dev_open)(dev_t dev, int flags, int fmt, struct proc *p,
struct scsi_link *sc_link);
-/* 72*/ errval (*dev_close)(dev_t dev, struct scsi_link *sc_link);
-/* 76*/ void (*dev_strategy)(struct buf *bp, struct scsi_link *sc_link);
+/* 72*/ int (*dev_ioctl)(dev_t dev, int cmd, caddr_t arg, int mode,
+ struct proc *p, struct scsi_link *sc_link);
+/* 76*/ int (*dev_close)(dev_t dev, int flag, int fmt, struct proc *p,
+ struct scsi_link *sc_link);
+/* 80*/ void (*dev_strategy)(struct buf *bp, struct scsi_link *sc_link);
/* Not initialized after this */
@@ -212,17 +218,17 @@ void NAME##init(void) \
{ \
scsi_device_register(&NAME##_switch); \
} \
-errval NAME##open(dev_t dev, int flags) \
+int NAME##open(dev_t dev, int flags, int fmt, struct proc *p) \
{ \
- return scsi_open(dev, flags, &NAME##_switch); \
+ return scsi_open(dev, flags, fmt, p, &NAME##_switch); \
} \
-errval NAME##ioctl(dev_t dev, int cmd, caddr_t addr, int flag) \
+int NAME##ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p) \
{ \
- return scsi_ioctl(dev, cmd, addr, flag, &NAME##_switch); \
+ return scsi_ioctl(dev, cmd, addr, flag, p, &NAME##_switch); \
} \
-errval NAME##close(dev_t dev) \
+int NAME##close(dev_t dev, int flag, int fmt, struct proc *p) \
{ \
- return scsi_close(dev, &NAME##_switch); \
+ return scsi_close(dev, flag, fmt, p, &NAME##_switch); \
} \
void NAME##minphys(struct buf *bp) \
{ \
@@ -439,7 +445,8 @@ char * scsi_type_name(int type);
void scsi_attachdevs __P((struct scsi_link *sc_link_proto));
struct scsi_xfer *get_xs( struct scsi_link *sc_link, u_int32 flags);
void free_xs(struct scsi_xfer *xs, struct scsi_link *sc_link,u_int32 flags);
-u_int32 scsi_size( struct scsi_link *sc_link,u_int32 flags);
+u_int32 scsi_read_capacity __P(( struct scsi_link *sc_link,
+ u_int32 *blk_size, u_int32 flags));
errval scsi_test_unit_ready( struct scsi_link *sc_link, u_int32 flags);
errval scsi_change_def( struct scsi_link *sc_link, u_int32 flags);
errval scsi_inquire( struct scsi_link *sc_link,
@@ -453,11 +460,12 @@ errval scsi_scsi_cmd( struct scsi_link *sc_link, struct scsi_generic *scsi_cmd,
u_int32 datalen, u_int32 retries,
u_int32 timeout, struct buf *bp,
u_int32 flags);
-errval scsi_do_ioctl __P((dev_t dev,
- int cmd, caddr_t addr, int f, struct scsi_link *sc_link));
+int scsi_do_ioctl __P((dev_t dev, int cmd, caddr_t addr, int mode,
+ struct proc *p, struct scsi_link *sc_link));
struct scsi_link *scsi_link_get __P((int bus, int targ, int lun));
-dev_t scsi_dev_lookup __P((int (*opener)(dev_t dev, int flags)));
+dev_t scsi_dev_lookup __P((int (*opener)(dev_t dev, int flags, int fmt,
+struct proc *p)));
int scsi_opened_ok __P((dev_t dev, int flag, int type, struct scsi_link *sc_link));
@@ -469,6 +477,10 @@ void show_mem(unsigned char * , u_int32);
void scsi_uto3b __P((u_int32 val, u_char *bytes));
u_int32 scsi_3btou __P((u_char *bytes));
int32 scsi_3btoi __P((u_char *bytes));
+void scsi_uto4b __P((u_int32 val, u_char *bytes));
+u_int32 scsi_4btou __P((u_char *bytes));
+void scsi_uto2b __P((u_int32 val, u_char *bytes));
+u_int32 scsi_2btou __P((u_char *bytes));
extern void sc_print_addr(struct scsi_link *);
@@ -561,10 +573,6 @@ extern struct kern_devconf kdc_scbus0; /* XXX should go away */
#define CDUNIT(DEV) SH3_UNIT(DEV)
#define CDSETUNIT(DEV, U) SH3SETUNIT((DEV), (U))
-#define SDUNITSHIFT 3
-#define SDUNIT(DEV) SH3_UNIT(DEV)
-#define SDSETUNIT(DEV, U) SH3SETUNIT((DEV), (U))
-
#define CHUNIT(DEV) SH4_UNIT(DEV)
#define CHSETUNIT(DEV, U) SH4SETUNIT((DEV), (U))
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index 0a37774..5a61b15 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
*
- * $Id: sd.c,v 1.50 1995/01/31 11:41:46 dufault Exp $
+ * $Id: sd.c,v 1.51 1995/03/01 22:24:45 dufault Exp $
*/
#define SPLSD splbio
@@ -48,6 +48,10 @@ u_int32 sdstrats, sdqueues;
#define SD_RETRIES 4
#define MAXTRANSFER 8 /* 1 page at a time */
+#define SDUNITSHIFT 3
+#define SDUNIT(DEV) SH3_UNIT(DEV)
+#define SDSETUNIT(DEV, U) SH3SETUNIT((DEV), (U))
+
#define MAKESDDEV(maj, unit, part) (makedev(maj,((unit<<SDUNITSHIFT)+part)))
#define PARTITION(z) (minor(z) & 0x07)
@@ -92,10 +96,12 @@ struct scsi_data {
static int sdunit(dev_t dev) { return SDUNIT(dev); }
static dev_t sdsetunit(dev_t dev, int unit) { return SDSETUNIT(dev, unit); }
-errval sd_open(dev_t dev, int flags, struct scsi_link *sc_link);
+errval sd_open(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_link *sc_link);
errval sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
- struct scsi_link *sc_link);
-errval sd_close(dev_t dev, struct scsi_link *sc_link);
+ struct proc *p, struct scsi_link *sc_link);
+errval sd_close(dev_t dev, int flag, int fmt, struct proc *p,
+ struct scsi_link *sc_link);
void sd_strategy(struct buf *bp, struct scsi_link *sc_link);
SCSI_DEVICE_ENTRIES(sd)
@@ -111,6 +117,7 @@ struct scsi_device sd_switch =
{0, 0},
0, /* Link flags */
sdattach,
+ "Direct-Access",
sdopen,
sizeof(struct scsi_data),
T_DIRECT,
@@ -139,7 +146,6 @@ static struct kern_devconf kdc_sd_template = {
&kdc_scbus0, /* XXX parent */
0, /* parentdata */
DC_UNKNOWN, /* not supported */
- "SCSI disk"
};
static inline void
@@ -151,6 +157,7 @@ sd_registerdev(int unit)
if(!kdc) return;
*kdc = kdc_sd_template;
kdc->kdc_unit = unit;
+ kdc->kdc_description = sd_switch.desc;
dev_attach(kdc);
if(dk_ndrive < DK_NDRIVE) {
sprintf(dk_names[dk_ndrive], "sd%d", unit);
@@ -218,7 +225,8 @@ sdattach(struct scsi_link *sc_link)
* open the device. Make sure the partition info is a up-to-date as can be.
*/
errval
-sd_open(dev_t dev, int flags, struct scsi_link *sc_link)
+sd_open(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_link *sc_link)
{
errval errcode = 0;
u_int32 unit, part;
@@ -340,7 +348,8 @@ bad:
* device. Convenient now but usually a pain.
*/
errval
-sd_close(dev_t dev, struct scsi_link *sc_link)
+sd_close(dev_t dev, int flag, int fmt, struct proc *p,
+ struct scsi_link *sc_link)
{
unsigned char unit, part;
struct scsi_data *sd;
@@ -586,7 +595,7 @@ bad:
*/
errval
sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
-struct scsi_link *sc_link)
+struct proc *p, struct scsi_link *sc_link)
{
/* struct sd_cmd_buf *args; */
errval error = 0;
@@ -693,7 +702,7 @@ struct scsi_link *sc_link)
default:
if (part == RAWPART || SCSI_SUPER(dev) )
- error = scsi_do_ioctl(dev, cmd, addr, flag, sc_link);
+ error = scsi_do_ioctl(dev, cmd, addr, flag, p, sc_link);
else
error = ENOTTY;
break;
@@ -954,10 +963,7 @@ sdsize(dev_t dev)
if ((sd->flags & SDINIT) == 0)
return -1;
if (sd == 0 || (sd->flags & SDHAVELABEL) == 0) {
- /* XXX: By rights sdopen should be called like:
- * sdopen(MAKESDDEV(major(dev), unit, RAWPART), FREAD, S_IFBLK, 0);
- */
- val = sdopen(MAKESDDEV(major(dev), unit, RAWPART), FREAD);
+ val = sdopen(MAKESDDEV(major(dev), unit, RAWPART), FREAD, S_IFBLK, 0);
if (val != 0)
return -1;
}
diff --git a/sys/scsi/st.c b/sys/scsi/st.c
index 5bb9cbc..19da5eb 100644
--- a/sys/scsi/st.c
+++ b/sys/scsi/st.c
@@ -12,7 +12,7 @@
* on the understanding that TFS is not responsible for the correct
* functioning of this software in any circumstances.
*
- * $Id: st.c,v 1.27 1995/02/25 19:11:11 jkh Exp $
+ * $Id: st.c,v 1.28 1995/03/01 22:24:46 dufault Exp $
*/
/*
@@ -218,10 +218,12 @@ struct scsi_data {
static int stunit(dev_t dev) { return STUNIT(dev); }
static dev_t stsetunit(dev_t dev, int unit) { return STSETUNIT(dev, unit); }
-errval st_open(dev_t dev, int flags, struct scsi_link *sc_link);
+errval st_open(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_link *sc_link);
errval st_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
- struct scsi_link *sc_link);
-errval st_close(dev_t dev, struct scsi_link *sc_link);
+ struct proc *p, struct scsi_link *sc_link);
+errval st_close(dev_t dev, int flag, int fmt, struct proc *p,
+ struct scsi_link *sc_link);
void st_strategy(struct buf *bp, struct scsi_link *sc_link);
SCSI_DEVICE_ENTRIES(st)
@@ -237,6 +239,7 @@ struct scsi_device st_switch =
{0, 0},
0, /* Link flags */
stattach,
+ "Sequential-Access",
stopen,
sizeof(struct scsi_data),
T_SEQUENTIAL,
@@ -287,7 +290,6 @@ static struct kern_devconf kdc_st_template = {
&kdc_scbus0, /* XXX parent */
0, /* parentdata */
DC_UNKNOWN, /* not supported */
- "SCSI tape drive"
};
static inline void
@@ -299,6 +301,7 @@ st_registerdev(int unit)
if(!kdc) return;
*kdc = kdc_st_template;
kdc->kdc_unit = unit;
+ kdc->kdc_description = st_switch.desc;
dev_attach(kdc);
}
@@ -495,7 +498,8 @@ st_loadquirks(sc_link)
* open the device.
*/
errval
-st_open(dev_t dev, int flags, struct scsi_link *sc_link)
+st_open(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_link *sc_link)
{
u_int32 unit, mode, dsty;
errval errno = 0;
@@ -580,7 +584,8 @@ st_open(dev_t dev, int flags, struct scsi_link *sc_link)
* occurence of an open device
*/
errval
-st_close(dev_t dev, struct scsi_link *sc_link)
+st_close(dev_t dev, int flag, int fmt, struct proc *p,
+ struct scsi_link *sc_link)
{
unsigned char unit, mode;
struct scsi_data *st;
@@ -1104,7 +1109,7 @@ badnews:
*/
errval
st_ioctl(dev_t dev, int cmd, caddr_t arg, int flag,
-struct scsi_link *sc_link)
+struct proc *p, struct scsi_link *sc_link)
{
errval errcode = 0;
unsigned char unit;
@@ -1227,7 +1232,7 @@ struct scsi_link *sc_link)
break;
default:
if(IS_CTLMODE(dev))
- errcode = scsi_do_ioctl(dev, cmd, arg, flag, sc_link);
+ errcode = scsi_do_ioctl(dev, cmd, arg, flag, p, sc_link);
else
errcode = ENOTTY;
break;
diff --git a/sys/scsi/su.c b/sys/scsi/su.c
index fffe45d..0211295 100644
--- a/sys/scsi/su.c
+++ b/sys/scsi/su.c
@@ -44,7 +44,7 @@
* SUCH DAMAGE.
*End copyright
*
- * $Id:$
+ * $Id: su.c,v 1.3 1995/01/08 15:56:10 dufault Exp $
*
* Tabstops 4
*/
@@ -58,39 +58,49 @@
#include <sys/buf.h>
#include <sys/systm.h>
-/* bnxio, cnxio: non existent device entries (with ugly casts to quiet gcc).
+/* XXX: These are taken from, and perhaps belong in, conf.c
+ */
+#define nxopen (d_open_t *)enxio
+#define nxclose (d_close_t *)enxio
+#define nxread (d_rdwr_t *)enxio
+#define nxwrite nxread
+#define nxstrategy (d_strategy_t *)enxio
+#define nxioctl (d_ioctl_t *)enxio
+#define nxdump (d_dump_t *)enxio
+#define nxstop (d_stop_t *)enxio
+#define nxreset (d_reset_t *)enxio
+#define nxselect (d_select_t *)enxio
+#define nxmmap (d_mmap_t *)enxio
+#define nxdevtotty (d_ttycv_t *)nullop
+#define zerosize (d_psize_t *)0
+
+/* bnxio, cnxio: non existent device entries
*/
static struct bdevsw bnxio = {
- (int (*) __P((dev_t dev, int oflags, int devtype,
- struct proc *p))) enxio,
- (int (*) __P((dev_t dev, int fflag, int devtype,
- struct proc *p))) enxio,
- (d_strategy_t *) enxio,
- (int (*) __P((dev_t dev, int cmd, caddr_t data,
- int fflag, struct proc *p))) enxio,
- (int (*) ()) enxio,
- (int (*) __P((dev_t dev))) 0,
- (int ) 0
+ nxopen,
+ nxclose,
+ nxstrategy,
+ nxioctl,
+ nxdump,
+ zerosize,
+ 0
};
static struct cdevsw cnxio = {
- (int (*) __P((dev_t dev, int oflags, int devtype,
- struct proc *p))) enxio,
- (int (*) __P((dev_t dev, int fflag, int devtype,
- struct proc *))) enxio,
- (int (*) __P((dev_t dev, struct uio *uio, int ioflag))) enxio,
- (int (*) __P((dev_t dev, struct uio *uio, int ioflag))) enxio,
- (int (*) __P((dev_t dev, int cmd, caddr_t data,
- int fflag, struct proc *p))) enxio,
- (int (*) __P((struct tty *tp, int rw))) nullop,
- (int (*) __P((int uban))) enxio,
- (struct tty *) 0,
- (int (*) __P((dev_t dev, int which, struct proc *p))) enxio,
- (int (*) __P(())) enxio,
- (d_strategy_t *) enxio
+ nxopen,
+ nxclose,
+ nxread,
+ nxwrite,
+ nxioctl,
+ nxstop,
+ nxreset,
+ nxdevtotty,
+ nxselect,
+ nxmmap,
+ nxstrategy
};
-/* getsws: Look up the base dev switch for a given new style
+/* getsws: Look up the base dev switch for a given "by minor number" style
* device.
*/
static int
diff --git a/sys/scsi/uk.c b/sys/scsi/uk.c
index 0f21110..d3c3506 100644
--- a/sys/scsi/uk.c
+++ b/sys/scsi/uk.c
@@ -2,7 +2,10 @@
* Driver for a device we can't identify.
* by Julian Elischer (julian@tfs.com)
*
- * $Id: uk.c,v 1.6 1995/01/08 13:38:38 dufault Exp $
+ * $Id: uk.c,v 1.7 1995/03/01 22:24:47 dufault Exp $
+ *
+ * If you find that you are adding any code to this file look closely
+ * at putting it in "scsi_driver.c" instead.
*/
#include <sys/param.h>
@@ -21,7 +24,8 @@ struct scsi_device uk_switch =
0,
{0, 0},
SDEV_ONCE_ONLY, /* Only one open allowed */
- ukattach,
+ 0,
+ "Unknown",
ukopen,
0,
T_UNKNOWN,
@@ -32,15 +36,3 @@ struct scsi_device uk_switch =
0,
0,
};
-
-/*
- * The routine called by the low level scsi routine when it discovers
- * a device suitable for this driver.
- */
-errval
-ukattach(struct scsi_link *sc_link)
-{
- printf("unknown device\n");
-
- return 0;
-}
diff --git a/sys/scsi/worm.c b/sys/scsi/worm.c
new file mode 100644
index 0000000..78917b4
--- /dev/null
+++ b/sys/scsi/worm.c
@@ -0,0 +1,360 @@
+/*
+ * worm: Write Once device driver
+ *
+ * Copyright (C) 1995, HD Associates, Inc.
+ * PO Box 276
+ * Pepperell, MA 01463
+ * 508 433 5266
+ * dufault@hda.com
+ *
+ * This code is contributed to the University of California at Berkeley:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id:$
+ */
+
+/* XXX This is PRELIMINARY.
+ *
+ * We need the "kern devconf" stuff, but I'm not
+ * going to add it until it is done in a simple way that provides
+ * base behavior in scsi_driver.c
+ *
+ * Until Bruce finishes the slice stuff there will be no partitions.
+ * When it is finished I hope to hoist the partition code up into
+ * "scsi_driver" and use common code for all devices.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+#include <scsi/scsi_disk.h>
+
+struct scsi_data {
+ struct buf *buf_queue; /* the queue of pending IO operations */
+
+ u_int32 n_blks; /* Number of blocks (0 for bogus) */
+ u_int32 blk_size; /* Size of each blocks */
+};
+
+void wormstart(u_int32 unit);
+
+errval worm_open(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_link *sc_link);
+errval worm_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
+ struct proc *p, struct scsi_link *sc_link);
+errval worm_close(dev_t dev, int flag, int fmt, struct proc *p,
+ struct scsi_link *sc_link);
+void worm_strategy(struct buf *bp, struct scsi_link *sc_link);
+
+SCSI_DEVICE_ENTRIES(worm)
+
+struct scsi_device worm_switch =
+{
+ NULL,
+ wormstart, /* we have a queue, and this is how we service it */
+ NULL,
+ NULL,
+ "worm",
+ 0,
+ {0, 0},
+ SDEV_ONCE_ONLY, /* Only one open allowed */
+ wormattach,
+ "Write-Once",
+ wormopen,
+ sizeof(struct scsi_data),
+ T_WORM,
+ 0,
+ 0,
+ worm_open,
+ 0,
+ worm_close,
+ worm_strategy,
+};
+
+static int worm_size(struct scsi_link *sc_link)
+{
+ int ret;
+ struct scsi_data *worm = sc_link->sd;
+
+ worm->n_blks = scsi_read_capacity(sc_link, &worm->blk_size,
+ SCSI_NOSLEEP | SCSI_NOMASK);
+
+ if (worm->n_blks)
+ {
+ sc_link->flags |= SDEV_MEDIA_LOADED;
+ ret = 1;
+ }
+ else
+ {
+ sc_link->flags &= ~SDEV_MEDIA_LOADED;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+errval
+wormattach(struct scsi_link *sc_link)
+{
+ struct scsi_data *worm = sc_link->sd;
+
+ printf("- UNTESTED ");
+
+ if (worm_size(sc_link) == 0)
+ printf("- can't get capacity.\n");
+ else
+ printf("with %ld %ld byte blocks.\n", worm->n_blks, worm->blk_size);
+
+ return 0;
+}
+
+/*
+ * wormstart looks to see if there is a buf waiting for the device
+ * and that the device is not already busy. If both are true,
+ * It dequeues the buf and creates a scsi command to perform the
+ * transfer required. The transfer request will call scsi_done
+ * on completion, which will in turn call this routine again
+ * so that the next queued transfer is performed.
+ * The bufs are queued by the strategy routine (wormstrategy)
+ *
+ * This routine is also called after other non-queued requests
+ * have been made of the scsi driver, to ensure that the queue
+ * continues to be drained.
+ * wormstart() is called at splbio
+ *
+ * XXX It looks like we need a "scsistart" to hoist common code up
+ * into. In particular, the removable media checking should be
+ * handled in one place.
+ */
+void
+wormstart(unit)
+ u_int32 unit;
+{
+ struct scsi_link *sc_link = SCSI_LINK(&worm_switch, unit);
+ struct scsi_data *worm = sc_link->sd;
+ register struct buf *bp = 0;
+ struct
+ {
+ u_char op_code;
+ u_char byte2;
+ u_char lba3; /* I don't want to worry about packing */
+ u_char lba2;
+ u_char lba1;
+ u_char lba0;
+ u_char reserved;
+ u_char tl1;
+ u_char tl0;
+ u_char ctl;
+ } cmd;
+
+ u_int32 flags;
+ u_int32 lba; /* Logical block address */
+ u_int32 tl; /* Transfer length */
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("wormstart "));
+
+ /*
+ * We should reject all queued entries if SDEV_MEDIA_LOADED is not true.
+ */
+ if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
+ goto badnews; /* no I/O.. media changed or something */
+ }
+
+ /*
+ * See if there is a buf to do and we are not already
+ * doing one
+ */
+ while (sc_link->opennings != 0) {
+
+ /* if a special awaits, let it proceed first */
+ if (sc_link->flags & SDEV_WAITING) {
+ sc_link->flags &= ~SDEV_WAITING;
+ wakeup((caddr_t)sc_link);
+ return;
+ }
+ if ((bp = worm->buf_queue) == NULL) {
+ return; /* no work to bother with */
+ }
+ worm->buf_queue = bp->b_actf;
+
+ /*
+ * Fill out the scsi command
+ */
+ bzero(&cmd, sizeof(cmd));
+ if ((bp->b_flags & B_READ) == B_WRITE) {
+ cmd.op_code = WRITE_BIG;
+ flags = SCSI_DATA_OUT;
+ } else {
+ cmd.op_code = READ_BIG;
+ flags = SCSI_DATA_IN;
+ }
+
+
+ lba = bp->b_blkno / (worm->blk_size / DEV_BSIZE);
+ tl = bp->b_bcount / worm->blk_size;
+
+ scsi_uto4b(lba, &cmd.lba3);
+ scsi_uto2b(tl, &cmd.tl1);
+
+ /*
+ * go ask the adapter to do all this for us
+ */
+ if (scsi_scsi_cmd(sc_link,
+ (struct scsi_generic *) &cmd,
+ sizeof(cmd),
+ (u_char *) bp->b_un.b_addr,
+ bp->b_bcount,
+ 0, /* can't retry a read on a tape really */
+ 100000,
+ bp,
+ flags | SCSI_NOSLEEP) == SUCCESSFULLY_QUEUED) {
+ } else {
+badnews:
+ printf("worm%d: oops not queued\n", unit);
+ bp->b_flags |= B_ERROR;
+ bp->b_error = EIO;
+ biodone(bp);
+ }
+ } /* go back and see if we can cram more work in.. */
+}
+
+void
+worm_strategy(struct buf *bp, struct scsi_link *sc_link)
+{
+ struct buf **dp;
+ unsigned char unit;
+ u_int32 opri;
+ struct scsi_data *worm;
+
+ unit = STUNIT((bp->b_dev));
+ worm = sc_link->sd;
+
+ /* XXX: Can't we move this check up to "scsi_strategy"?
+ */
+ if (!(sc_link->flags & SDEV_MEDIA_LOADED) ||
+ bp->b_blkno > worm->n_blks ||
+ bp->b_bcount & (worm->blk_size - 1)) {
+ bp->b_error = EIO;
+ bp->b_flags |= B_ERROR;
+ biodone(bp);
+ return;
+ }
+
+ opri = splbio();
+
+ /*
+ * Use a bounce buffer if necessary
+ * XXX: How can we move this up?
+ */
+#ifdef BOUNCE_BUFFERS
+ if (sc_link->flags & SDEV_BOUNCE)
+ vm_bounce_alloc(bp);
+#endif
+
+ /*
+ * Place it in the queue of activities for this device
+ * at the end.
+ */
+ dp = &(worm->buf_queue);
+ while (*dp) {
+ dp = &((*dp)->b_actf);
+ }
+ *dp = bp;
+ bp->b_actf = NULL;
+
+ wormstart(unit);
+
+ splx(opri);
+ return;
+}
+
+/*
+ * Open the device. XXX: I'm completely guessing at this sequence.
+ */
+int
+worm_open(dev_t dev, int flags, int fmt, struct proc *p,
+struct scsi_link *sc_link)
+{
+ struct scsi_data *worm = sc_link->sd;
+
+ if (sc_link->flags & SDEV_OPEN)
+ return EBUSY;
+
+ /*
+ * Check that it is still responding and ok.
+ * if the media has been changed this will result in a
+ * "unit attention" error which the error code will
+ * disregard because the SDEV_OPEN flag is not yet set
+ *
+ * XXX This should REALLY be hoisted up. As soon as Bruce
+ * finishes that slice stuff. (Add a different flag,
+ * and then do a "scsi_test_unit_ready" with the "ignore
+ * unit attention" thing set. Then all this replicated
+ * test unit ready code can be pulled up.
+ */
+ scsi_test_unit_ready(sc_link, SCSI_SILENT);
+
+ /*
+ * Next time actually take notice of error returns
+ */
+ sc_link->flags |= SDEV_OPEN; /* unit attn errors are now errors */
+
+ if (scsi_test_unit_ready(sc_link, SCSI_SILENT) != 0) {
+ SC_DEBUG(sc_link, SDEV_DB3, ("not ready\n"));
+ sc_link->flags &= ~SDEV_OPEN;
+ return ENXIO;
+ }
+
+ scsi_start_unit(sc_link, SCSI_SILENT);
+
+ scsi_prevent(sc_link, PR_PREVENT, SCSI_SILENT);
+
+ if (worm_size(sc_link) == 0) {
+ scsi_stop_unit(sc_link, 0, SCSI_SILENT);
+ scsi_prevent(sc_link, PR_ALLOW, SCSI_SILENT);
+ sc_link->flags &= ~SDEV_OPEN;
+ return ENXIO;
+ }
+
+ return 0;
+}
+
+int
+worm_close(dev_t dev, int flag, int fmt, struct proc *p,
+ struct scsi_link *sc_link)
+{
+ scsi_stop_unit(sc_link, 0, SCSI_SILENT);
+ scsi_prevent(sc_link, PR_ALLOW, SCSI_SILENT);
+ sc_link->flags &= ~SDEV_OPEN;
+
+ return 0;
+}
OpenPOWER on IntegriCloud