diff options
| author | svn2git <svn2git@FreeBSD.org> | 1994-05-01 08:00:00 +0000 | 
|---|---|---|
| committer | svn2git <svn2git@FreeBSD.org> | 1994-05-01 08:00:00 +0000 | 
| commit | a16f65c7d117419bd266c28a1901ef129a337569 (patch) | |
| tree | 2626602f66dc3551e7a7c7bc9ad763c3bc7ab40a /sys/scsi/scsiconf.c | |
| parent | 8503f4f13f77abf7adc8f7e329c6f9c1d52b6a20 (diff) | |
Diffstat (limited to 'sys/scsi/scsiconf.c')
| -rw-r--r-- | sys/scsi/scsiconf.c | 1110 | 
1 files changed, 514 insertions, 596 deletions
| diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c index 31c8fa6fea06..8d9a2fe13efd 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.6 1993/09/05 17:41:07 rgrimes Exp $ + *      $Id: scsiconf.c,v 1.8 1993/12/19 00:54:54 wollman Exp $   */  #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 ((int)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 ((int)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); -} - | 
