summaryrefslogtreecommitdiffstats
path: root/sys/scsi/ssc.c
diff options
context:
space:
mode:
authordufault <dufault@FreeBSD.org>1995-01-08 13:38:38 +0000
committerdufault <dufault@FreeBSD.org>1995-01-08 13:38:38 +0000
commit3cf1ff13e332d0b753ba08fe1e3ad5b994f1ac6c (patch)
tree273bcb9e1be1a1dad1080681ddc7edafb2c2060a /sys/scsi/ssc.c
parentc280bae2f039222946dd53421445e050d5f7d844 (diff)
downloadFreeBSD-src-3cf1ff13e332d0b753ba08fe1e3ad5b994f1ac6c.zip
FreeBSD-src-3cf1ff13e332d0b753ba08fe1e3ad5b994f1ac6c.tar.gz
Reviewed by: gibbs@estienne.CS.Berkeley.EDU
Reenabled "SCIOCOMAND" ioctl. Restructured so low level drivers can easily request retries. Added preliminary fixed SCSI devices (should be revisited before 2.1) Added "ssc" device that can have its' (HBA, ID, LUN) set via ioctl.
Diffstat (limited to 'sys/scsi/ssc.c')
-rw-r--r--sys/scsi/ssc.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/sys/scsi/ssc.c b/sys/scsi/ssc.c
new file mode 100644
index 0000000..5dc2630
--- /dev/null
+++ b/sys/scsi/ssc.c
@@ -0,0 +1,82 @@
+/* "superscsi" pseudo device. This requires options SCSISUPER.
+ * "superscsi" supports general SCSI utilities that can iterate
+ * over all SCSI targets, including those without device entry
+ * points.
+ *
+ * "superscsi" supports the SCIOCADDR ioctl to change the BUS, ID, LUN
+ * of the target so that you can get to all devices. The only thing
+ * you can do to "superscsi" is open it, set the target, perform ioctl
+ * calls, and close it.
+ *
+ * Keep "superscsi" protected: you can drive a truck through the
+ * security hole if you don't.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <scsi/scsiconf.h>
+#include <sys/scsiio.h>
+
+#include <sys/errno.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/systm.h>
+
+static dev_t sscdev = NODEV;
+
+int sscopen(dev_t dev, int flag, int type, struct proc *p)
+{
+ if (sscdev != NODEV)
+ return suopen(sscdev, flag, type, p);
+ return 0;
+}
+
+int sscclose(dev_t dev, int fflag, int type, struct proc *p)
+{
+
+ if (sscdev != NODEV)
+ return suclose(sscdev, fflag, type, p);
+ return 0;
+}
+
+int sscioctl(dev_t dev, int cmd, caddr_t data, int fflag, struct proc *p)
+{
+ if (cmd == SCIOCADDR)
+ {
+ struct scsi_addr *sca = (struct scsi_addr *) data;
+ dev_t newdev =
+ SCSI_MKSUPER(SCSI_MKDEV(sca->scbus,sca->lun,sca->target));
+ int ret;
+
+ if (sscdev != NODEV)
+ {
+ suclose(sscdev, fflag, S_IFCHR, p);
+ sscdev = NODEV;
+ }
+
+ if ( (ret = suopen(newdev, fflag, S_IFCHR, p)) )
+ return ret;
+
+ sscdev = newdev;
+
+ return 0;
+ }
+
+ if (sscdev != NODEV)
+ return suioctl(sscdev, cmd, data, fflag, p);
+
+ return ENXIO;
+}
+
+/* I've elected not to support any of these other entries. There
+ * really is no good reason other than I'm not sure how you would use
+ * them.
+ */
+int sscstrategy(struct buf *bp) { return ENXIO; }
+int sscdump(dev_t dev) { return ENXIO; }
+int sscpsize(dev_t dev) { return ENXIO; }
+int sscread(dev_t dev, struct uio *uio, int ioflag) { return ENXIO; }
+int sscwrite(dev_t dev, struct uio *uio, int ioflag) { return ENXIO; }
+int sscselect(dev_t dev, int which, struct proc *p) { return ENXIO; }
OpenPOWER on IntegriCloud