summaryrefslogtreecommitdiffstats
path: root/sys/scsi/scsiconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/scsi/scsiconf.c')
-rw-r--r--sys/scsi/scsiconf.c1110
1 files changed, 514 insertions, 596 deletions
diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c
index 70765b0..708cc7c 100644
--- a/sys/scsi/scsiconf.c
+++ b/sys/scsi/scsiconf.c
@@ -14,768 +14,686 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
- * $Id: scsiconf.c,v 1.5 1993/08/28 03:08:53 rgrimes Exp $
+ * $Id: scsiconf.c,v 2.6 93/10/24 12:43:51 julian Exp Locker: julian $
*/
#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sys/malloc.h>
#include "st.h"
#include "sd.h"
#include "ch.h"
#include "cd.h"
-#include "sg.h"
+#include "uk.h"
+#include "su.h"
+#ifndef NSCBUS
+#define NSCBUS 8
+#endif /* NSCBUS */
-#ifdef MACH
-#include <i386/machparam.h>
-#endif MACH
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
-#if !defined(OSF) && !defined(__386BSD__)
+#ifdef TFS
#include "bll.h"
#include "cals.h"
#include "kil.h"
-#else
+#include "scan.h"
+#else /* TFS */
#define NBLL 0
#define NCALS 0
#define NKIL 0
-#endif /* !defined(OSF) && !defined(__386BSD__) */
+#define NSCAN 0
+#endif /* TFS */
#if NSD > 0
-extern sdattach();
-#endif NSD
+extern sdattach();
+#endif /* NSD */
#if NST > 0
-extern stattach();
-#endif NST
+extern stattach();
+#endif /* NST */
#if NCH > 0
-extern chattach();
-#endif NCH
+extern chattach();
+#endif /* NCH */
#if NCD > 0
-extern cdattach();
-#endif NCD
+extern cdattach();
+#endif /* NCD */
#if NBLL > 0
-extern bllattach();
-#endif NBLL
+extern bllattach();
+#endif /* NBLL */
#if NCALS > 0
-extern calsattach();
-#endif NCALS
+extern calsattach();
+#endif /* NCALS */
#if NKIL > 0
-extern kil_attach();
-#endif NKIL
-
-/***************************************************************\
-* The structure of pre-configured devices that might be turned *
-* off and therefore may not show up *
-\***************************************************************/
-struct predefined
-{
- u_char scsibus;
- u_char dev;
- u_char lu;
- int (*attach_rtn)();
- char *devname;
- char flags;
-}
-pd[] =
+extern kil_attach();
+#endif /* NKIL */
+#if NUK > 0
+extern ukattach();
+#endif /* NUK */
+
+/*
+ * One of these is allocated and filled in for each scsi bus.
+ * it holds pointers to allow the scsi bus to get to the driver
+ * That is running each LUN on the bus
+ * it also has a template entry which is the prototype struct
+ * supplied by the adapter driver, this is used to initialise
+ * the others, before they have the rest of the fields filled in
+ */
+struct scsibus_data *scbus_data[NSCBUS];
+
+/*
+ * The structure of pre-configured devices that might be turned
+ * off and therefore may not show up
+ */
+struct predefined {
+ u_char scsibus;
+ u_char dev;
+ u_char lu;
+ errval(*attach_rtn) ();
+ char *devname;
+ char flags;
+} pd[] =
+
{
#ifdef EXAMPLE_PREDEFINE
#if NSD > 0
- {0,0,0,sdattach,"sd",0},/* define a disk at scsibus=0 dev=0 lu=0 */
-#endif NSD
-#endif EXAMPLE_PREDEFINE
- {0,9,9} /*illegal dummy end entry */
+ {
+ 0, 0, 0, sdattach, "sd", 0
+ }, /* define a disk at scsibus=0 dev=0 lu=0 */
+#endif /* NSD */
+#endif /* EXAMPLE_PREDEFINE */
+ {
+ 0, 9, 9
+ } /*illegal dummy end entry */
};
+/*
+ * The structure of known drivers for autoconfiguration
+ */
+struct scsidevs {
+ u_int32 type;
+ boolean removable;
+ char *manufacturer;
+ char *model;
+ char *version;
+ errval(*attach_rtn) ();
+ char *devname;
+ char flags; /* 1 show my comparisons during boot(debug) */
+};
-/***************************************************************\
-* The structure of known drivers for autoconfiguration *
-\***************************************************************/
-static struct scsidevs
-{
- int type;
- int removable;
- char *manufacturer;
- char *model;
- char *version;
- int (*attach_rtn)();
- char *devname;
- char flags; /* 1 show my comparisons during boot(debug) */
-}
#define SC_SHOWME 0x01
#define SC_ONE_LU 0x00
#define SC_MORE_LUS 0x02
-knowndevs[] = {
+#if NUK > 0
+
+static struct scsidevs unknowndev = {
+ -1, 0, "standard", "any"
+ ,"any", ukattach, "uk", SC_MORE_LUS
+};
+#endif /*NUK*/
+static struct scsidevs knowndevs[] =
+{
#if NSD > 0
- { T_DIRECT,T_FIXED,"standard","any"
- ,"any",sdattach,"sd",SC_ONE_LU },
- { T_DIRECT,T_FIXED,"MAXTOR ","XT-4170S "
- ,"B5A ",sdattach,"mx1",SC_ONE_LU },
-#endif NSD
+ {
+ T_DIRECT, T_FIXED, "standard", "any"
+ ,"any", sdattach, "sd", SC_ONE_LU
+ },
+ {
+ T_DIRECT, T_FIXED, "MAXTOR ", "XT-4170S "
+ ,"B5A ", sdattach, "mx1", SC_ONE_LU
+ },
+#endif /* NSD */
#if NST > 0
- { T_SEQUENTIAL,T_REMOV,"standard","any"
- ,"any",stattach,"st",SC_ONE_LU },
-#endif NST
+ {
+ T_SEQUENTIAL, T_REMOV, "standard", "any"
+ ,"any", stattach, "st", SC_ONE_LU
+ },
+#endif /* NST */
#if NCALS > 0
- { T_PROCESSOR,T_FIXED,"standard","any"
- ,"any",calsattach,"cals",SC_MORE_LUS },
-#endif NCALS
+ {
+ T_PROCESSOR, T_FIXED, "standard", "any"
+ ,"any", calsattach, "cals", SC_MORE_LUS
+ },
+#endif /* NCALS */
#if NCH > 0
- { T_CHANGER,T_REMOV,"standard","any"
- ,"any",chattach,"ch",SC_ONE_LU },
-#endif NCH
+ {
+ T_CHANGER, T_REMOV, "standard", "any"
+ ,"any", chattach, "ch", SC_ONE_LU
+ },
+#endif /* NCH */
#if NCD > 0
- { T_READONLY,T_REMOV,"SONY ","CD-ROM CDU-8012 "
- ,"3.1a",cdattach,"cd",SC_ONE_LU },
- { T_READONLY,T_REMOV,"PIONEER ","CD-ROM DRM-600 "
- ,"any",cdattach,"cd",SC_MORE_LUS },
-#endif NCD
+#ifndef UKTEST /* make cdroms unrecognised to test the uk driver */
+ {
+ T_READONLY, T_REMOV, "SONY ", "CD-ROM CDU-8012 "
+ ,"3.1a", cdattach, "cd", SC_ONE_LU
+ },
+ {
+ T_READONLY, T_REMOV, "PIONEER ", "CD-ROM DRM-600 "
+ ,"any", cdattach, "cd", SC_MORE_LUS
+ },
+#endif
+#endif /* NCD */
#if NBLL > 0
- { T_PROCESSOR,T_FIXED,"AEG ","READER "
- ,"V1.0",bllattach,"bll",SC_MORE_LUS },
-#endif NBLL
+ {
+ T_PROCESSOR, T_FIXED, "AEG ", "READER "
+ ,"V1.0", bllattach, "bll", SC_MORE_LUS
+ },
+#endif /* NBLL */
#if NKIL > 0
- { T_SCANNER,T_FIXED,"KODAK ","IL Scanner 900 "
- ,"any",kil_attach,"kil",SC_ONE_LU },
-#endif NKIL
+ {
+ T_SCANNER, T_FIXED, "KODAK ", "IL Scanner 900 "
+ ,"any", kil_attach, "kil", SC_ONE_LU
+ },
+#endif /* NKIL */
-{0}
+ {
+ 0
+ }
};
-/***************************************************************\
-* Declarations *
-\***************************************************************/
-struct predefined *scsi_get_predef();
-struct scsidevs *scsi_probedev();
-struct scsidevs *selectdev();
-
-/* controls debug level within the scsi subsystem */
-/* see scsiconf.h for values */
-int scsi_debug = 0x0;
-int scsibus = 0x0; /* This is the Nth scsibus */
-
-/***************************************************************\
-* The routine called by the adapter boards to get all their *
-* devices configured in. *
-\***************************************************************/
-scsi_attachdevs( unit, scsi_addr, scsi_switch)
-int unit,scsi_addr;
-struct scsi_switch *scsi_switch;
+
+/*
+ * Declarations
+ */
+struct predefined *scsi_get_predef();
+struct scsidevs *scsi_probedev();
+struct scsidevs *selectdev();
+errval scsi_probe_bus __P((int bus, int targ, int lun));
+
+struct scsi_device probe_switch =
{
- int targ,lun;
- struct scsidevs *bestmatch = (struct scsidevs *)0;
- struct predefined *predef;
- int maybe_more;
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "probe",
+ 0,
+ { 0, 0 }
+};
-#ifdef SCSI_DELAY
-#if SCSI_DELAY > 2
+/*
+ * controls debug level within the scsi subsystem -
+ * see scsiconf.h for values
+ */
+int32 scsibus = 0x0; /* This is the Nth scsibus we've seen */
+
+/*
+ * The routine called by the adapter boards to get all their
+ * devices configured in.
+ */
+void
+scsi_attachdevs(sc_link_proto)
+ struct scsi_link *sc_link_proto;
+{
+
+ if(scsibus >= NSCBUS) {
+ printf("too many scsi busses, reconfigure the kernel\n");
+ return;
+ }
+ sc_link_proto->scsibus = scsibus;
+ scbus_data[scsibus] = malloc(sizeof(struct scsibus_data), M_TEMP, M_NOWAIT);
+ if(!scbus_data[scsibus]) {
+ panic("scsi_attachdevs: malloc\n");
+ }
+ bzero(scbus_data[scsibus], sizeof(struct scsibus_data));
+ scbus_data[scsibus]->adapter_link = sc_link_proto;
+#if defined(SCSI_DELAY) && SCSI_DELAY > 2
printf("%s%d waiting for scsi devices to settle\n",
- scsi_switch->name, unit);
-#else SCSI_DELAY > 2
-#define SCSI_DELAY 2
-#endif SCSI_DELAY > 2
-#else
+ sc_link_proto->adapter->name, sc_link_proto->adapter_unit);
+#else /* SCSI_DELAY > 2 */
+#undef SCSI_DELAY
#define SCSI_DELAY 2
-#endif SCSI_DELAY
- spinwait(1000 * SCSI_DELAY);
- targ = 0;
- while(targ < 8)
- {
- maybe_more = 0; /* by default only check 1 lun */
- if (targ == scsi_addr)
- {
- targ++;
+#endif /* SCSI_DELAY */
+ DELAY(1000000 * SCSI_DELAY);
+ scsibus++;
+ scsi_probe_bus(scsibus - 1,-1,-1);
+}
+
+/*
+ * Probe the requested scsi bus. It must be already set up.
+ * -1 requests all set up scsi busses.
+ * targ and lun optionally narrow the search if not -1
+ */
+errval
+scsi_probe_busses(int bus, int targ, int lun)
+{
+ if (bus == -1) {
+ for(bus = 0; bus < scsibus; bus++) {
+ scsi_probe_bus(bus, targ, lun);
+ }
+ return 0;
+ } else {
+ return scsi_probe_bus(bus, targ, lun);
+ }
+}
+
+/*
+ * Probe the requested scsi bus. It must be already set up.
+ * targ and lun optionally narrow the search if not -1
+ */
+errval
+scsi_probe_bus(int bus, int targ, int lun)
+{
+ struct scsibus_data *scsi ;
+ int maxtarg,mintarg,maxlun,minlun;
+ struct scsi_link *sc_link_proto;
+ u_int8 scsi_addr ;
+ struct scsidevs *bestmatch = NULL;
+ struct predefined *predef = NULL;
+ struct scsi_link *sc_link = NULL;
+ boolean maybe_more;
+
+ if ((bus < 0 ) || ( bus >= scsibus)) {
+ return ENXIO;
+ }
+ scsi = scbus_data[bus];
+ if(!scsi) return ENXIO;
+ sc_link_proto = scsi->adapter_link;
+ scsi_addr = sc_link_proto->adapter_targ;
+ if(targ == -1){
+ maxtarg = 7;
+ mintarg = 0;
+ } else {
+ if((targ < 0 ) || (targ > 7)) return EINVAL;
+ maxtarg = mintarg = targ;
+ }
+
+ if(lun == -1){
+ maxlun = 7;
+ minlun = 0;
+ } else {
+ if((lun < 0 ) || (lun > 7)) return EINVAL;
+ maxlun = minlun = lun;
+ }
+
+
+ for ( targ = mintarg;targ <= maxtarg; targ++) {
+ maybe_more = 0; /* by default only check 1 lun */
+ if (targ == scsi_addr) {
continue;
}
- lun = 0;
- while(lun < 8)
- {
- predef = scsi_get_predef(scsibus
- ,targ
- ,lun
- ,scsi_switch
- ,&maybe_more);
- bestmatch = scsi_probedev(unit
- ,targ
- ,lun
- ,scsi_switch
- ,&maybe_more);
- if((bestmatch) && (predef)) /* both exist */
- {
- if(bestmatch->attach_rtn
- != predef->attach_rtn)
- {
- printf("Clash in found/expected devices\n");
- printf("will link in FOUND\n");
+ for ( lun = minlun; lun <= maxlun ;lun++) {
+ /*
+ * The spot appears to already have something
+ * linked in, skip past it. Must be doing a 'reprobe'
+ */
+ if(scsi->sc_link[targ][lun])
+ {/* don't do this one, but check other luns */
+ maybe_more = 1;
+ continue;
+ }
+ /*
+ * If we presently don't have a link block
+ * then allocate one to use while probing
+ */
+ if (!sc_link) {
+ sc_link = malloc(sizeof(*sc_link), M_TEMP, M_NOWAIT);
+ *sc_link = *sc_link_proto; /* struct copy */
+ sc_link->opennings = 1;
+ sc_link->device = &probe_switch;
+ }
+ sc_link->target = targ;
+ sc_link->lun = lun;
+ predef = scsi_get_predef(sc_link, &maybe_more);
+ bestmatch = scsi_probedev(sc_link, &maybe_more);
+ if ((bestmatch) && (predef)) { /* both exist */
+ if (bestmatch->attach_rtn
+ != predef->attach_rtn) {
+ printf("Clash in found/expected devices\n");
+#if NUK > 0
+ if(bestmatch == &unknowndev) {
+ printf("will link in PREDEFINED\n");
+ (*(predef->attach_rtn)) (sc_link);
+ } else
+#endif /*NUK*/
+ {
+ printf("will link in FOUND\n");
+ (*(bestmatch->attach_rtn)) (sc_link);
+ }
+ } else {
+ (*(bestmatch->attach_rtn)) (sc_link);
}
- (*(bestmatch->attach_rtn))(unit,
- targ,
- lun,
- scsi_switch);
}
- if((bestmatch) && (!predef)) /* just FOUND */
- {
- (*(bestmatch->attach_rtn))(unit,
- targ,
- lun,
- scsi_switch);
+ if ((bestmatch) && (!predef)) { /* just FOUND */
+ (*(bestmatch->attach_rtn)) (sc_link);
}
- if((!bestmatch) && (predef)) /* just predef */
- {
- (*(predef->attach_rtn))(unit,
- targ,
- lun,
- scsi_switch);
+ if ((!bestmatch) && (predef)) { /* just predef */
+ (*(predef->attach_rtn)) (sc_link);
}
- if(!(maybe_more)) /* nothing suggests we'll find more */
- {
+ if ((bestmatch) || (predef)) { /* one exists */
+ scsi->sc_link[targ][lun] = sc_link;
+ sc_link = NULL; /* it's been used */
+ }
+ if (!(maybe_more)) { /* nothing suggests we'll find more */
break; /* nothing here, skip to next targ */
}
- /* otherwise something says we should look further*/
- lun++;
+ /* otherwise something says we should look further */
}
- targ++;
}
-#if NSG > 0
- /***************************************************************\
- * If available hook up the generic scsi driver, letting it *
- * know which target is US. (i.e. illegal or at least special) *
- \***************************************************************/
- sg_attach(unit,scsi_addr,scsi_switch);
-#endif
- scsibus++; /* next time we are on the NEXT scsi bus */
+ if (sc_link) {
+ free(sc_link, M_TEMP);
+ }
+ return 0;
}
-/***********************************************\
-* given a target and lu, check if there is a *
-* predefined device for that address *
-\***********************************************/
-struct predefined *scsi_get_predef(unit,target,lu,scsi_switch,maybe_more)
-int unit,target,lu,*maybe_more;
-struct scsi_switch *scsi_switch;
+/*
+ * given a target and lu, check if there is a predefined device for
+ * that address
+ */
+struct predefined *
+scsi_get_predef(sc_link, maybe_more)
+ struct scsi_link *sc_link;
+ boolean *maybe_more;
{
- int upto,numents;
+ u_int8 unit = sc_link->scsibus;
+ u_int8 target = sc_link->target;
+ u_int8 lu = sc_link->lun;
+ struct scsi_adapter *scsi_adapter = sc_link->adapter;
+ u_int32 upto, numents;
- numents = (sizeof(pd)/sizeof(struct predefined)) - 1;
-
- for(upto = 0;upto < numents;upto++)
- {
- if(pd[upto].scsibus != unit)
+ numents = (sizeof(pd) / sizeof(struct predefined)) - 1;
+
+ for (upto = 0; upto < numents; upto++) {
+ if (pd[upto].scsibus != unit)
continue;
- if(pd[upto].dev != target)
+ if (pd[upto].dev != target)
continue;
- if(pd[upto].lu != lu)
+ if (pd[upto].lu != lu)
continue;
-
+
printf("%s%d targ %d lun %d: <%s> - PRECONFIGURED -\n"
- ,scsi_switch->name
- ,unit
- ,target
- ,lu
- ,pd[upto].devname);
+ ,scsi_adapter->name
+ ,unit
+ ,target
+ ,lu
+ ,pd[upto].devname);
*maybe_more = pd[upto].flags & SC_MORE_LUS;
- return(&(pd[upto]));
+ return (&(pd[upto]));
}
- return((struct predefined *)0);
+ return ((struct predefined *) 0);
}
-/***********************************************\
-* given a target and lu, ask the device what *
-* it is, and find the correct driver table *
-* entry. *
-\***********************************************/
-struct scsidevs *scsi_probedev(unit,target,lu,scsi_switch, maybe_more)
-
-struct scsi_switch *scsi_switch;
-int unit,target,lu;
-int *maybe_more;
+/*
+ * given a target and lu, ask the device what
+ * it is, and find the correct driver table
+ * entry.
+ */
+struct scsidevs *
+scsi_probedev(sc_link, maybe_more)
+ boolean *maybe_more;
+ struct scsi_link *sc_link;
{
- struct scsidevs *bestmatch = (struct scsidevs *)0;
- char *dtype=(char *)0,*desc;
- char *qtype;
- static struct scsi_inquiry_data inqbuf;
- int len,qualifier,type,remov;
- char manu[32];
- char model[32];
- char version[32];
-
-
- bzero(&inqbuf,sizeof(inqbuf));
- /***********************************************\
- * Ask the device what it is *
- \***********************************************/
-#ifdef DEBUG
- if((target == 0) && (lu == 0))
- scsi_debug = 0xfff;
+ u_int8 unit = sc_link->adapter_unit;
+ u_int8 target = sc_link->target;
+ u_int8 lu = sc_link->lun;
+ struct scsi_adapter *scsi_adapter = sc_link->adapter;
+ struct scsidevs *bestmatch = (struct scsidevs *) 0;
+ char *dtype = (char *) 0, *desc;
+ char *qtype;
+ static struct scsi_inquiry_data inqbuf;
+ u_int32 len, qualifier, type;
+ boolean remov;
+ char manu[32];
+ char model[32];
+ char version[32];
+
+ bzero(&inqbuf, sizeof(inqbuf));
+ /*
+ * Ask the device what it is
+ */
+#ifdef SCSIDEBUG
+ if ((target == DEBUGTARG) && (lu == DEBUGLUN))
+ sc_link->flags |= (DEBUGLEVEL);
else
- scsi_debug = 0;
-#endif DEBUG
- if(scsi_ready( unit,
- target,
- lu,
- scsi_switch,
- SCSI_NOSLEEP | SCSI_NOMASK) != COMPLETE)
- {
- return(struct scsidevs *)0;
- }
- if(scsi_inquire(unit,
- target,
- lu,
- scsi_switch,
- &inqbuf,
- SCSI_NOSLEEP | SCSI_NOMASK) != COMPLETE)
- {
- return(struct scsidevs *)0;
- }
+ sc_link->flags &= ~(SDEV_DB1 | SDEV_DB2 | SDEV_DB3 | SDEV_DB4);
+#endif /* SCSIDEBUG */
+ /* catch unit attn */
+ scsi_test_unit_ready(sc_link, SCSI_NOSLEEP | SCSI_NOMASK | SCSI_SILENT);
+#ifdef DOUBTFULL
+ switch (scsi_test_unit_ready(sc_link, SCSI_NOSLEEP | SCSI_NOMASK | SCSI_SILENT)) {
+ case 0: /* said it WAS ready */
+ case EBUSY: /* replied 'NOT READY' but WAS present, continue */
+ case ENXIO:
+ break;
+ case EIO: /* device timed out */
+ case EINVAL: /* Lun not supported */
+ default:
+ return (struct scsidevs *) 0;
- /***********************************************\
- * note what BASIC type of device it is *
- \***********************************************/
- if(scsi_debug & SHOWINQUIRY)
- {
- desc=(char *)&inqbuf;
- printf("inq: %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
- desc[0], desc[1], desc[2], desc[3],
- desc[4], desc[5], desc[6], desc[7],
- desc[8], desc[9], desc[10], desc[11],
- desc[12]);
+ }
+#endif /*DOUBTFULL*/
+#ifdef SCSI_2_DEF
+ /* some devices need to be told to go to SCSI2 */
+ /* However some just explode if you tell them this.. leave it out */
+ scsi_change_def(sc_link, SCSI_NOSLEEP | SCSI_NOMASK | SCSI_SILENT);
+#endif /*SCSI_2_DEF */
+
+ /* Now go ask the device all about itself */
+ if (scsi_inquire(sc_link, &inqbuf, SCSI_NOSLEEP | SCSI_NOMASK) != 0) {
+ return (struct scsidevs *) 0;
}
+ /*
+ * note what BASIC type of device it is
+ */
type = inqbuf.device & SID_TYPE;
qualifier = inqbuf.device & SID_QUAL;
remov = inqbuf.dev_qual2 & SID_REMOVABLE;
-
- /* Any device qualifier that has
- * the top bit set (qualifier&4 != 0) is vendor specific and
- * won't match in this switch.
+ /*
+ * Any device qualifier that has the top bit set (qualifier&4 != 0)
+ * is vendor specific and won't match in this switch.
*/
- switch(qualifier)
- {
+ switch (qualifier) {
case SID_QUAL_LU_OK:
- qtype="";
+ qtype = "";
break;
case SID_QUAL_LU_OFFLINE:
- qtype=", Unit not Connected!";
+ qtype = ", Unit not Connected!";
break;
case SID_QUAL_RSVD:
- qtype=", Reserved Peripheral Qualifier!";
+ qtype = ", Reserved Peripheral Qualifier!";
*maybe_more = 1;
- return (struct scsidevs *)0;
+ return (struct scsidevs *) 0;
break;
case SID_QUAL_BAD_LU:
/*
* Check for a non-existent unit. If the device is returning
- * this much, then we must set the flag that has
- * the searcher keep looking on other luns.
- */
- qtype=", The Target can't support this Unit!";
+ * this much, then we must set the flag that has
+ * the searchers keep looking on other luns.
+ */
+ qtype = ", The Target can't support this Unit!";
*maybe_more = 1;
- return (struct scsidevs *)0;
+ return (struct scsidevs *) 0;
default:
- dtype="vendor specific";
- qtype="";
+ dtype = "vendor specific";
+ qtype = "";
*maybe_more = 1;
break;
}
-
- if (dtype == 0)
- {
- switch(type)
- {
+ if (dtype == 0) {
+ switch (type) {
case T_DIRECT:
- dtype="direct";
+ dtype = "direct";
break;
case T_SEQUENTIAL:
- dtype="sequential";
+ dtype = "sequential";
break;
case T_PRINTER:
- dtype="printer";
+ dtype = "printer";
break;
case T_PROCESSOR:
- dtype="processor";
+ dtype = "processor";
break;
case T_READONLY:
- dtype="readonly";
+ dtype = "readonly";
break;
case T_WORM:
- dtype="worm";
+ dtype = "worm";
break;
case T_SCANNER:
- dtype="scanner";
+ dtype = "scanner";
break;
case T_OPTICAL:
- dtype="optical";
+ dtype = "optical";
break;
case T_CHANGER:
- dtype="changer";
+ dtype = "changer";
break;
case T_COMM:
- dtype="communication";
+ dtype = "communication";
break;
case T_NODEVICE:
*maybe_more = 1;
- return (struct scsidevs *)0;
+ return (struct scsidevs *) 0;
default:
- dtype="unknown";
+ dtype = "unknown";
break;
}
-
- }
- /***********************************************\
- * Then if it's advanced enough, more detailed *
- * information *
- \***********************************************/
- if((inqbuf.version & SID_ANSII) > 0)
- {
- if ((len = inqbuf.additional_length
- + ( (char *)inqbuf.unused
- - (char *)&inqbuf))
- > (sizeof(struct scsi_inquiry_data) - 1))
- len = sizeof(struct scsi_inquiry_data) - 1;
- desc=inqbuf.vendor;
- desc[len-(desc - (char *)&inqbuf)] = 0;
- strncpy(manu,inqbuf.vendor,8);manu[8]=0;
- strncpy(model,inqbuf.product,16);model[16]=0;
- strncpy(version,inqbuf.revision,4);version[4]=0;
}
- else
- /***********************************************\
- * If not advanced enough, use default values *
- \***********************************************/
+ /*
+ * Then if it's advanced enough, more detailed
+ * information
+ */
+ if ((inqbuf.version & SID_ANSII) > 0) {
+ if ((len = inqbuf.additional_length
+ + ((char *) inqbuf.unused
+ - (char *) &inqbuf))
+ > (sizeof(struct scsi_inquiry_data) - 1))
+ len = sizeof(struct scsi_inquiry_data) - 1;
+ desc = inqbuf.vendor;
+ desc[len - (desc - (char *) &inqbuf)] = 0;
+ strncpy(manu, inqbuf.vendor, 8);
+ manu[8] = 0;
+ strncpy(model, inqbuf.product, 16);
+ model[16] = 0;
+ strncpy(version, inqbuf.revision, 4);
+ version[4] = 0;
+ } else
+ /*
+ * If not advanced enough, use default values
+ */
{
- desc="early protocol device";
- strncpy(manu,"unknown",8);
- strncpy(model,"unknown",16);
- strncpy(version,"????",4);
+ desc = "early protocol device";
+ strncpy(manu, "unknown", 8);
+ strncpy(model, "unknown", 16);
+ strncpy(version, "????", 4);
}
printf("%s%d targ %d lun %d: type %d(%s) %s SCSI%d\n"
- ,scsi_switch->name
- ,unit
- ,target
- ,lu
- ,type
- ,dtype
- ,remov?"removable":"fixed"
- ,inqbuf.version & SID_ANSII
- );
+ ,scsi_adapter->name
+ ,unit
+ ,target
+ ,lu
+ ,type
+ ,dtype
+ ,remov ? "removable" : "fixed"
+ ,inqbuf.version & SID_ANSII
+ );
printf("%s%d targ %d lun %d: <%s%s%s>\n"
- ,scsi_switch->name
- ,unit
- ,target
- ,lu
- ,manu
- ,model
- ,version
- );
- if(qtype[0])
- {
+ ,scsi_adapter->name
+ ,unit
+ ,target
+ ,lu
+ ,manu
+ ,model
+ ,version
+ );
+ if (qtype[0]) {
printf("%s%d targ %d lun %d: qualifier %d(%s)\n"
- ,scsi_switch->name
- ,unit
- ,target
- ,lu
- ,qualifier
- ,qtype
- );
+ ,scsi_adapter->name
+ ,unit
+ ,target
+ ,lu
+ ,qualifier
+ ,qtype
+ );
}
- /***********************************************\
- * Try make as good a match as possible with *
- * available sub drivers *
- \***********************************************/
- bestmatch = (selectdev(unit,target,lu,&scsi_switch,
- qualifier,type,remov?T_REMOV:T_FIXED,manu,model,version));
- if((bestmatch) && (bestmatch->flags & SC_MORE_LUS))
- {
+ /*
+ * Try make as good a match as possible with
+ * available sub drivers
+ */
+ bestmatch = (selectdev(
+ qualifier, type, remov ? T_REMOV : T_FIXED, manu, model, version));
+ if ((bestmatch) && (bestmatch->flags & SC_MORE_LUS)) {
*maybe_more = 1;
}
- return(bestmatch);
+ return (bestmatch);
}
-
-/***********************************************\
-* Try make as good a match as possible with *
-* available sub drivers *
-\***********************************************/
-struct scsidevs
-*selectdev(unit,target,lu,dvr_switch,qualifier,type,remov,manu,model,rev)
-int unit,target,lu;
-struct scsi_switch *dvr_switch;
-int qualifier,type,remov;
-char *manu,*model,*rev;
+/*
+ * Try make as good a match as possible with
+ * available sub drivers
+ */
+struct scsidevs *
+selectdev(qualifier, type, remov, manu, model, rev)
+ u_int32 qualifier, type;
+ boolean remov;
+ char *manu, *model, *rev;
{
- int numents = (sizeof(knowndevs)/sizeof(struct scsidevs)) - 1;
- int count = 0;
- int bestmatches = 0;
- struct scsidevs *bestmatch = (struct scsidevs *)0;
- struct scsidevs *thisentry = knowndevs;
+ u_int32 numents = (sizeof(knowndevs) / sizeof(struct scsidevs)) - 1;
+ u_int32 count = 0;
+ u_int32 bestmatches = 0;
+ struct scsidevs *bestmatch = (struct scsidevs *) 0;
+ struct scsidevs *thisentry = knowndevs;
type |= qualifier; /* why? */
thisentry--;
- while( count++ < numents)
- {
+ while (count++ < numents) {
thisentry++;
- if(type != thisentry->type)
- {
+ if (type != thisentry->type) {
continue;
}
- if(bestmatches < 1)
- {
+ if (bestmatches < 1) {
bestmatches = 1;
bestmatch = thisentry;
}
- if(remov != thisentry->removable)
- {
+ if (remov != thisentry->removable) {
continue;
}
- if(bestmatches < 2)
- {
+ if (bestmatches < 2) {
bestmatches = 2;
bestmatch = thisentry;
}
- if(thisentry->flags & SC_SHOWME)
- printf("\n%s-\n%s-",thisentry->manufacturer, manu);
- if(strcmp(thisentry->manufacturer, manu))
- {
+ if (thisentry->flags & SC_SHOWME)
+ printf("\n%s-\n%s-", thisentry->manufacturer, manu);
+ if (strcmp(thisentry->manufacturer, manu)) {
continue;
}
- if(bestmatches < 3)
- {
+ if (bestmatches < 3) {
bestmatches = 3;
bestmatch = thisentry;
}
- if(thisentry->flags & SC_SHOWME)
- printf("\n%s-\n%s-",thisentry->model, model);
- if(strcmp(thisentry->model, model))
- {
+ if (thisentry->flags & SC_SHOWME)
+ printf("\n%s-\n%s-", thisentry->model, model);
+ if (strcmp(thisentry->model, model)) {
continue;
}
- if(bestmatches < 4)
- {
+ if (bestmatches < 4) {
bestmatches = 4;
bestmatch = thisentry;
}
- if(thisentry->flags & SC_SHOWME)
- printf("\n%s-\n%s-",thisentry->version, rev);
- if(strcmp(thisentry->version, rev))
- {
+ if (thisentry->flags & SC_SHOWME)
+ printf("\n%s-\n%s-", thisentry->version, rev);
+ if (strcmp(thisentry->version, rev)) {
continue;
}
- if(bestmatches < 5)
- {
+ if (bestmatches < 5) {
bestmatches = 5;
bestmatch = thisentry;
break;
}
}
-
- if (bestmatch == (struct scsidevs *)0)
- printf(" No explicit device driver match for \"%s %s\".\n",
- manu, model);
-
- return(bestmatch);
-}
-
-static int recurse = 0;
-/***********************************************\
-* Do a scsi operation asking a device if it is *
-* ready. Use the scsi_cmd routine in the switch *
-* table. *
-\***********************************************/
-scsi_ready(unit,target,lu,scsi_switch, flags)
-struct scsi_switch *scsi_switch;
-{
- struct scsi_test_unit_ready scsi_cmd;
- struct scsi_xfer scsi_xfer;
- volatile int rval;
- int key;
-
- bzero(&scsi_cmd, sizeof(scsi_cmd));
- bzero(&scsi_xfer, sizeof(scsi_xfer));
- scsi_cmd.op_code = TEST_UNIT_READY;
-
- scsi_xfer.flags=flags | INUSE;
- scsi_xfer.adapter=unit;
- scsi_xfer.targ=target;
- scsi_xfer.lu=lu;
- scsi_xfer.cmd=(struct scsi_generic *)&scsi_cmd;
- scsi_xfer.retries=8;
- scsi_xfer.timeout=10000;
- scsi_xfer.cmdlen=sizeof(scsi_cmd);
- scsi_xfer.data=0;
- scsi_xfer.datalen=0;
- scsi_xfer.resid=0;
- scsi_xfer.when_done=0;
- scsi_xfer.done_arg=0;
-retry: scsi_xfer.error=0;
- /*******************************************************\
- * do not use interrupts *
- \*******************************************************/
- rval = (*(scsi_switch->scsi_cmd))(&scsi_xfer);
- if (rval != COMPLETE)
- {
- if(scsi_debug)
- {
- printf("scsi error, rval = 0x%x\n",rval);
- printf("code from driver: 0x%x\n",scsi_xfer.error);
- }
- switch(scsi_xfer.error)
- {
- case XS_SENSE:
- /*******************************************************\
- * Any sense value is illegal except UNIT ATTENTION *
- * In which case we need to check again to get the *
- * correct response. *
- *( especially exabytes) *
- \*******************************************************/
- if(((scsi_xfer.sense.error_code & SSD_ERRCODE) == 0x70 )
- ||((scsi_xfer.sense.error_code & SSD_ERRCODE) == 0x71 ))
- {
- key = scsi_xfer.sense.ext.extended.flags & SSD_KEY ;
- switch(key)
- {
- case 2: /* not ready BUT PRESENT! */
- return(COMPLETE);
- case 6:
- spinwait(1000);
- if(scsi_xfer.retries--)
- {
- scsi_xfer.flags &= ~ITSDONE;
- goto retry;
- }
- return(COMPLETE);
- default:
- if(scsi_debug)
- printf("%d:%d,key=%x.",
- target,lu,key);
- }
- }
- return(HAD_ERROR);
- case XS_BUSY:
- spinwait(1000);
- if(scsi_xfer.retries--)
- {
- scsi_xfer.flags &= ~ITSDONE;
- goto retry;
- }
- return(COMPLETE); /* it's busy so it's there */
- case XS_TIMEOUT:
- default:
- return(HAD_ERROR);
- }
- }
- return(COMPLETE);
-}
-/***********************************************\
-* Do a scsi operation asking a device what it is*
-* Use the scsi_cmd routine in the switch table. *
-\***********************************************/
-scsi_inquire(unit,target,lu,scsi_switch,inqbuf, flags)
-struct scsi_switch *scsi_switch;
-u_char *inqbuf;
-{
- struct scsi_inquiry scsi_cmd;
- struct scsi_xfer scsi_xfer;
- volatile int rval;
-
- bzero(&scsi_cmd, sizeof(scsi_cmd));
- bzero(&scsi_xfer, sizeof(scsi_xfer));
- scsi_cmd.op_code = INQUIRY;
- scsi_cmd.length = sizeof(struct scsi_inquiry_data);
-
- scsi_xfer.flags=flags | SCSI_DATA_IN | INUSE;
- scsi_xfer.adapter=unit;
- scsi_xfer.targ=target;
- scsi_xfer.lu=lu;
- scsi_xfer.retries=8;
- scsi_xfer.timeout=10000;
- scsi_xfer.cmd=(struct scsi_generic *)&scsi_cmd;
- scsi_xfer.cmdlen= sizeof(struct scsi_inquiry);
- scsi_xfer.data=inqbuf;
- scsi_xfer.datalen=sizeof(struct scsi_inquiry_data);
- scsi_xfer.resid=sizeof(struct scsi_inquiry_data);
- scsi_xfer.when_done=0;
- scsi_xfer.done_arg=0;
-retry: scsi_xfer.error=0;
- /*******************************************************\
- * do not use interrupts *
- \*******************************************************/
- if ((*(scsi_switch->scsi_cmd))(&scsi_xfer) != COMPLETE)
- {
- if(scsi_debug) printf("inquiry had error(0x%x) ",scsi_xfer.error);
- switch(scsi_xfer.error)
- {
- case XS_NOERROR:
- break;
- case XS_SENSE:
- /*******************************************************\
- * Any sense value is illegal except UNIT ATTENTION *
- * In which case we need to check again to get the *
- * correct response. *
- *( especially exabytes) *
- \*******************************************************/
- if(((scsi_xfer.sense.error_code & SSD_ERRCODE) == 0x70 )
- && ((scsi_xfer.sense.ext.extended.flags & SSD_KEY) == 6))
- { /* it's changed so it's there */
- spinwait(1000);
- {
- if(scsi_xfer.retries--)
- {
- scsi_xfer.flags &= ~ITSDONE;
- goto retry;
- }
- }
- return( COMPLETE);
- }
- return(HAD_ERROR);
- case XS_BUSY:
- spinwait(1000);
- if(scsi_xfer.retries--)
- {
- scsi_xfer.flags &= ~ITSDONE;
- goto retry;
- }
- case XS_TIMEOUT:
- default:
- return(HAD_ERROR);
- }
+ if (bestmatch == (struct scsidevs *) 0) {
+#if NUK > 0
+ bestmatch = &unknowndev;
+#else
+ printf("No explicit device driver match.\n");
+#endif
}
- return(COMPLETE);
-}
-
-
-
-
-/***********************************************\
-* Utility routines often used in SCSI stuff *
-\***********************************************/
-
-/***********************************************\
-* convert a physical address to 3 bytes, *
-* MSB at the lowest address, *
-* LSB at the highest. *
-\***********************************************/
-
-lto3b(val, bytes)
-u_char *bytes;
-{
- *bytes++ = (val&0xff0000)>>16;
- *bytes++ = (val&0xff00)>>8;
- *bytes = val&0xff;
+ return (bestmatch);
}
-
-/***********************************************\
-* The reverse of lto3b *
-\***********************************************/
-_3btol(bytes)
-u_char *bytes;
-{
- int rc;
- rc = (*bytes++ << 16);
- rc += (*bytes++ << 8);
- rc += *bytes;
- return(rc);
-}
-
OpenPOWER on IntegriCloud