summaryrefslogtreecommitdiffstats
path: root/sys/scsi/sd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/scsi/sd.c')
-rw-r--r--sys/scsi/sd.c213
1 files changed, 207 insertions, 6 deletions
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index bbc83ae..a5d6236 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -1,4 +1,3 @@
-
/*
* Written by Julian Elischer (julian@dialix.oz.au)
* for TRW Financial Systems for use under the MACH(2.5) operating system.
@@ -15,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
*
- * $Id: sd.c,v 1.122 1998/04/15 17:47:21 bde Exp $
+ * $Id: sd.c,v 1.123 1998/04/17 22:37:10 des Exp $
*/
#include "opt_bounce.h"
@@ -35,7 +34,11 @@
#include <sys/conf.h>
#ifdef DEVFS
#include <sys/devfsext.h>
-#endif /*DEVFS*/
+#ifdef SLICE
+#include <sys/device.h>
+#include <dev/slice/slice.h>
+#endif /* SLICE */
+#endif /* DEVFS */
#include <scsi/scsi_disk.h>
#include <scsi/scsiconf.h>
@@ -93,8 +96,17 @@ struct scsi_data {
struct buf_queue_head buf_queue;
int dkunit; /* disk stats unit number */
#ifdef DEVFS
+#ifdef SLICE
+ struct slice *slice;
+ int mynor;
+ struct slicelimits limit;
+ struct scsi_link *sc_link;
+ int unit;
+ struct intr_config_hook ich;
+#else /* SLICE */
void *b_devfs_token;
void *c_devfs_token;
+#endif /* SLICE */
void *ctl_devfs_token;
#endif
};
@@ -119,10 +131,35 @@ static d_strategy_t sdstrategy;
#define CDEV_MAJOR 13
#define BDEV_MAJOR 4
+#ifndef SLICE
static struct cdevsw sd_cdevsw;
static struct bdevsw sd_bdevsw =
{ sdopen, sdclose, sdstrategy, sdioctl, /*4*/
sddump, sdsize, D_DISK, "sd", &sd_cdevsw, -1 };
+#else /* ! SLICE */
+
+static sl_h_IO_req_t sdsIOreq; /* IO req downward (to device) */
+static sl_h_ioctl_t sdsioctl; /* ioctl req downward (to device) */
+static sl_h_open_t sdsopen; /* downwards travelling open */
+static sl_h_close_t sdsclose; /* downwards travelling close */
+static void sds_init (void *arg);
+
+static struct slice_handler slicetype = {
+ "scsidisk",
+ 0,
+ NULL,
+ 0,
+ NULL, /* constructor */
+ &sdsIOreq,
+ &sdsioctl,
+ &sdsopen,
+ &sdsclose,
+ NULL, /* revoke */
+ NULL, /* claim */
+ NULL, /* verify */
+ NULL /* upconfig */
+};
+#endif
@@ -148,7 +185,11 @@ static struct scsi_device sd_switch =
sd_open,
sd_ioctl,
sd_close,
+#ifndef SLICE
sd_strategy,
+#else
+ NULL,
+#endif
};
static struct scsi_xfer sx;
@@ -227,6 +268,31 @@ sdattach(struct scsi_link *sc_link)
sd_registerdev(unit);
#ifdef DEVFS
+#ifdef SLICE
+ {
+ char namebuf[64];
+ sd->unit = unit;
+ sd->sc_link = sc_link;
+ sprintf(namebuf,"sd%d",sd->unit);
+ sd->mynor = dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART);
+ sd->limit.blksize = sd->params.secsiz;
+ /* need to cast to avoid overflow! */
+ sd->limit.slicesize =
+ (u_int64_t)sd->params.secsiz * sd->params.disksize;
+ sl_make_slice(&slicetype,
+ sd,
+ &sd->limit,
+ &sd->slice,
+ NULL,
+ namebuf);
+ /* Allow full probing */
+ sd->slice->probeinfo.typespecific = NULL;
+ sd->slice->probeinfo.type = NULL;
+ }
+ sd->ich.ich_func = sds_init;
+ sd->ich.ich_arg = sd;
+ config_intrhook_establish(&sd->ich);
+#else /* SLICE */
mynor = dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART);
sd->b_devfs_token = devfs_add_devswf(&sd_bdevsw, mynor, DV_BLK,
UID_ROOT, GID_OPERATOR, 0640,
@@ -240,11 +306,26 @@ sdattach(struct scsi_link *sc_link)
DV_CHR,
UID_ROOT, GID_WHEEL, 0600,
"rsd%d.ctl", unit);
+#endif /* SLICE */
#endif
-
return 0;
}
+#ifdef SLICE
+/* run a LOT later */
+static void
+sds_init(void *arg)
+{
+ struct scsi_data *sd = arg;
+ sh_p tp;
+
+ if ((tp = slice_probeall(sd->slice)) != NULL) {
+ (*tp->constructor)(sd->slice);
+ }
+ config_intrhook_disestablish(&sd->ich);
+}
+#endif /* SLICE */
+
/*
* open the device. Make sure the partition info is a up-to-date as can be.
*/
@@ -295,6 +376,7 @@ sd_open(dev, mode, fmt, p, sc_link)
*/
sc_link->flags |= SDEV_OPEN; /* unit attn becomes an err now */
if (!(sc_link->flags & SDEV_MEDIA_LOADED) && sd->dk_slices != NULL) {
+#ifndef SLICE
/*
* If somebody still has it open, then forbid re-entry.
*/
@@ -304,6 +386,7 @@ sd_open(dev, mode, fmt, p, sc_link)
}
dsgone(&sd->dk_slices);
+#endif /* !SLICE */
}
/*
@@ -339,11 +422,13 @@ sd_open(dev, mode, fmt, p, sc_link)
/* XXX as long as it's not 0 - readdisklabel divides by it (?) */
label.d_secperunit = sd->params.disksize;
+#ifndef SLICE
/* Initialize slice tables. */
errcode = dsopen("sd", dev, fmt, &sd->dk_slices, &label, sdstrategy1,
(ds_setgeom_t *)NULL, &sd_bdevsw, &sd_cdevsw);
if (errcode != 0)
goto bad;
+#endif /* !SLICE */
SC_DEBUG(sc_link, SDEV_DB3, ("Slice tables initialized "));
SC_DEBUG(sc_link, SDEV_DB3, ("open %ld %ld\n", sdstrats, sdqueues));
@@ -379,15 +464,18 @@ sd_close(dev, fflag, fmt, p, sc_link)
errcode = scsi_device_lock(sc_link);
if (errcode)
return errcode;
+#ifndef SLICE
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;
}
+#endif /* ! SLICE */
scsi_device_unlock(sc_link);
return (0);
}
+#ifndef SLICE
/*
* Actually translate the requested transfer into one the physical driver
* can understand. The transfer is described by a buf and will include
@@ -518,6 +606,7 @@ sdstrategy1(struct buf *bp)
sdstrategy(bp);
}
+#endif /* ! SLICE */
/*
* sdstart looks to see if there is a buf waiting for the device
* and that the device is not already busy. If both are true,
@@ -650,7 +739,7 @@ sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p,
#if 0
/* Wait until we have exclusive access to the device. */
/* XXX this is how wd does it. How did we work without this? */
- wdsleep(du->dk_ctrlr, "wdioct");
+ sdsleep(du->dk_ctrlr, "wdioct");
#endif
/*
@@ -662,10 +751,10 @@ sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p,
if (cmd == DIOCSBAD)
return (EINVAL); /* XXX */
+#ifndef SLICE
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);
@@ -673,6 +762,7 @@ sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p,
return (error);
if (PARTITION(dev) != RAW_PART)
return (ENOTTY);
+#endif /* ! SLICE */ /* really only take this from the ctl device XXX */
return (scsi_do_ioctl(dev, cmd, addr, flag, p, sc_link));
}
@@ -888,6 +978,7 @@ sd_get_parms(int unit, int flags)
return (error);
}
+#ifndef SLICE
static int
sdsize(dev_t dev)
{
@@ -899,6 +990,7 @@ sdsize(dev_t dev)
return (dssize(dev, &sd->dk_slices, sdopen, sdclose));
}
+#endif /* ! SLICE */
/*
* sense handler: Called to determine what to do when the
* device returns a CHECK CONDITION.
@@ -952,6 +1044,7 @@ sd_sense_handler(struct scsi_xfer *xs)
return SCSIRET_DO_RETRY;
}
+#ifndef SLICE
/*
* dump all of physical memory into the partition specified, starting
* at offset 'dumplo' into the partition.
@@ -1092,7 +1185,9 @@ sddump(dev_t dev)
}
return (0);
}
+#endif /* !SLICE */
+#ifndef SLICE
static sd_devsw_installed = 0;
static void sd_drvinit(void *unused)
@@ -1106,3 +1201,109 @@ static void sd_drvinit(void *unused)
SYSINIT(sddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,sd_drvinit,NULL)
+#endif /* !SLICE */
+#ifdef SLICE
+
+/*
+ * Read/write routine for a buffer. Finds the proper unit, range checks
+ * arguments, and schedules the transfer. Does not wait for the transfer
+ * to complete. Multi-page transfers are supported. All I/O requests must
+ * be a multiple of a sector in length.
+scsi_strategy(bp, &sd_switch);
+ */
+static void
+sdsIOreq(void *private ,struct buf *bp)
+{
+ struct scsi_data *sd = private;
+ u_int32_t opri;
+ u_int32_t unit = sd->unit;
+ struct scsi_link *sc_link = sd->sc_link;
+
+ SC_DEBUG(sc_link, SDEV_DB2, ("sdIOreq\n"));
+ SC_DEBUG(sc_link, SDEV_DB1, ("%ld bytes @ blk%ld\n",
+ bp->b_bcount, bp->b_pblkno));
+
+ bp->b_resid = 0;
+ bp->b_error = 0;
+
+ (*sc_link->adapter->scsi_minphys)(bp);
+
+ sdstrats++;
+ /*
+ * If the device has been made invalid, error out
+ */
+ if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
+ bp->b_error = EIO;
+ goto bad;
+ }
+
+ /*
+ * check it's not too big a transfer for our adapter
+ */
+ /*scsi_minphys(bp,&sd_switch);*/
+
+ opri = SPLSD();
+ /*
+ * 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 disk activities for this disk
+ */
+#ifdef SDDISKSORT
+ bufq_disksort(&sd->buf_queue, bp);
+#else
+ bufq_insert_tail(&sd->buf_queue, bp);
+#endif
+
+ /*
+ * Tell the device to get going on the transfer if it's
+ * not doing anything, otherwise just wait for completion
+ */
+ sdstart(unit, 0);
+
+ splx(opri);
+ return;
+bad:
+ bp->b_flags |= B_ERROR;
+ bp->b_resid = bp->b_bcount;
+ biodone(bp);
+ return;
+}
+
+
+static int
+sdsopen(void *private, int flags, int mode, struct proc *p)
+{
+ struct scsi_data *sd;
+
+ sd = private;
+
+ return(sdopen(makedev(0,sd->mynor), 0 , 0, p));
+}
+
+static void
+sdsclose(void *private, int flags, int mode, struct proc *p)
+{
+ struct scsi_data *sd;
+
+ sd = private;
+
+ sdclose(makedev(0,sd->mynor), 0 , 0, p);
+ return;
+}
+static int
+sdsioctl( void *private, int cmd, caddr_t addr, int flag, struct proc *p)
+{
+ struct scsi_data *sd;
+
+ sd = private;
+
+ return(sdioctl(makedev(0,sd->mynor), cmd, addr, flag, p));
+}
+
+#endif
OpenPOWER on IntegriCloud