*BSD News Article 5512


Return to BSD News archive

Newsgroups: comp.unix.bsd
Path: sserve!manuel!munnari.oz.au!spool.mu.edu!uwm.edu!linac!pacific.mps.ohio-state.edu!zaphod.mps.ohio-state.edu!magnus.acs.ohio-state.edu!usenet.ins.cwru.edu!agate!tfs.com!tfs.com!julian
From: julian@tfs.com (Julian Elischer)
Subject: new new scsi release beta2 part 1 of 5 (fixed)
Message-ID: <1992Sep23.221352.16254@tfs.com>
Organization: TRW Financial Systems
Date: Wed, 23 Sep 1992 22:13:52 GMT
Lines: 1720

This release of the new scsi system has been considerably neatenned up
as far as the definitions of scsi arguments go.
also supports cdrom.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	ddb/db_command.c.patch
#	kern/kern_subr.c.patch
#	i386/isa/isa.h.patch
#	i386/isa/clock.c.patch
#	i386/i386/conf.c.patch
#	i386/conf/SCSITEST
#	i386/conf/devices.i386.patch
#	i386/conf/files.i386.patch
#	i386/conf/Makefile.i386.patch
#	scsi
#	scsi/README
#	scsi/scsiconf.h
#	scsi/scsiconf.c
#	scsi/scsi_all.h
#
echo x - ddb/db_command.c.patch
sed 's/^X//' >ddb/db_command.c.patch << 'END-of-ddb/db_command.c.patch'
X*** /usr/src/syschanges/sys.originals/ddb/db_command.c	Thu Apr 16 00:00:20 1992
X--- /usr/src/sys.386bsd/ddb/db_command.c	Sun Aug 23 16:10:49 1992
X***************
X*** 515,531 ****
X  			 args[5], args[6], args[7], args[8], args[9] );
X  	db_printf("%#n\n", retval);
X  }
X- 
X- int
X- strcmp(s1, s2)
X- 	register const char *s1, *s2;
X- {
X- 	while (*s1 == *s2++)
X- 		if (*s1++ == 0)
X- 			return (0);
X- 	return (*(unsigned char *)s1 - *(unsigned char *)--s2);
X- }
X- 
X- 		
X- 
X- 	
X--- 515,517 ----
END-of-ddb/db_command.c.patch
echo x - kern/kern_subr.c.patch
sed 's/^X//' >kern/kern_subr.c.patch << 'END-of-kern/kern_subr.c.patch'
X*** /usr/src/syschanges/sys.originals/kern/kern_subr.c	Mon Jul 13 07:24:35 1992
X--- /usr/src/sys.386bsd/kern/kern_subr.c	Sun Aug 23 16:11:29 1992
X***************
X*** 199,204 ****
X--- 199,220 ----
X  	*to = '\0';
X  }
X  
X+ 
X+ int
X+ strcmp(s1, s2)
X+ 	register const char *s1, *s2;
X+ {
X+ 	while (*s1 == *s2++)
X+ 		if (*s1++ == 0)
X+ 			return (0);
X+ 	return (*(unsigned char *)s1 - *(unsigned char *)--s2);
X+ }
X+ 
X+ 		
X+ 
X+ 	
X+ 
X+ 
X  #ifndef lint	/* unused except by ct.c, other oddities XXX */
X  /*
X   * Get next character written in by user from uio.
END-of-kern/kern_subr.c.patch
echo x - i386/isa/isa.h.patch
sed 's/^X//' >i386/isa/isa.h.patch << 'END-of-i386/isa/isa.h.patch'
X*** /usr/src/syschanges/sys.originals/i386/isa/isa.h	Tue May 12 21:51:02 1992
X--- /usr/src/sys.386bsd/i386/isa/isa.h	Sat Aug 22 00:23:26 1992
X***************
X*** 86,93 ****
X  					/* 0x280 - 0x2F7 Open */
X  
X  #define IO_COM2		0x2f8		/* COM2 i/o address */
X  
X! 					/* 0x300 - 0x36F Open */
X  
X  #define IO_FD2		0x370		/* secondary base i/o address */
X  #define IO_LPT1		0x378		/* Parallel Port #1 */
X--- 86,96 ----
X  					/* 0x280 - 0x2F7 Open */
X  
X  #define IO_COM2		0x2f8		/* COM2 i/o address */
X+ 					/* 0x300 - 0x32F Open */
X  
X! #define	IO_AHA0		0x330		/* adaptec 1542 default addr. */
X! #define	IO_AHA1		0x334		/* adaptec 1542 default addr. */
X! 					/* 0x338 - 0x36F Open */
X  
X  #define IO_FD2		0x370		/* secondary base i/o address */
X  #define IO_LPT1		0x378		/* Parallel Port #1 */
END-of-i386/isa/isa.h.patch
echo x - i386/isa/clock.c.patch
sed 's/^X//' >i386/isa/clock.c.patch << 'END-of-i386/isa/clock.c.patch'
X*** /usr/src/syschanges/sys.originals/i386/isa/clock.c	Tue Dec 24 14:23:38 1991
X--- /usr/src/sys.386bsd/i386/isa/clock.c	Sun Aug 23 20:27:24 1992
X***************
X*** 49,62 ****
X  
X  #define DAYST 119
X  #define DAYEN 303
X  
X  startrtclock() {
X  	int s;
X  
X  	/* initialize 8253 clock */
X  	outb (IO_TIMER1+3, 0x36);
X! 	outb (IO_TIMER1, 1193182/hz);
X! 	outb (IO_TIMER1, (1193182/hz)/256);
X  
X  	/* initialize brain-dead battery powered clock */
X  	outb (IO_RTC, RTC_STATUSA);
X--- 49,65 ----
X  
X  #define DAYST 119
X  #define DAYEN 303
X+ #define XTALSPEED 1193182
X  
X  startrtclock() {
X  	int s;
X  
X+ 	findcpuspeed();		/* use the clock (while it's free)
X+ 					to find the cpu speed */
X  	/* initialize 8253 clock */
X  	outb (IO_TIMER1+3, 0x36);
X! 	outb (IO_TIMER1, XTALSPEED/hz);
X! 	outb (IO_TIMER1, (XTALSPEED/hz)/256);
X  
X  	/* initialize brain-dead battery powered clock */
X  	outb (IO_RTC, RTC_STATUSA);
X***************
X*** 71,76 ****
X--- 74,105 ----
X  	outb (IO_RTC+1, 0);
X  }
X  
X+ unsigned int delaycount;	/* calibrated loop variable (1 millisecond) */
X+ 
X+ #define FIRST_GUESS	0x2000
X+ findcpuspeed()
X+ {
X+ 	unsigned char low;
X+ 	unsigned int remainder;
X+ 
X+ 	/* Put counter in count down mode */
X+ 	outb(IO_TIMER1+3, 0x34);
X+ 	outb(IO_TIMER1, 0xff);
X+ 	outb(IO_TIMER1, 0xff);
X+ 	delaycount = FIRST_GUESS;
X+ 	spinwait(1);
X+ 	/* Read the value left in the counter */
X+ 	low 	= inb(IO_TIMER1);	/* least siginifcant */
X+ 	remainder = inb(IO_TIMER1);	/* most significant */
X+ 	remainder = (remainder<<8) + low ;
X+ 	/* Formula for delaycount is :
X+ 	 *  (loopcount * timer clock speed)/ (counter ticks * 1000)
X+ 	 */
X+ 	delaycount = (FIRST_GUESS * (XTALSPEED/1000)) / (0xffff-remainder);
X+ }
X+ 
X+ 
X+ 
X  /* convert 2 digit BCD number */
X  bcd(i)
X  int i;
X***************
X*** 204,206 ****
X--- 233,249 ----
X  	setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL);
X  	splnone();
X  }
X+ 
X+ 
X+ 
X+ 
X+ spinwait(millisecs)
X+ int millisecs;		/* number of milliseconds to delay */
X+ {
X+ 	int i, j;
X+ 
X+ 	for (i=0;i<millisecs;i++)
X+ 		for (j=0;j<delaycount;j++)
X+ 			;
X+ }
X+ 
END-of-i386/isa/clock.c.patch
echo x - i386/i386/conf.c.patch
sed 's/^X//' >i386/i386/conf.c.patch << 'END-of-i386/i386/conf.c.patch'
X*** /usr/src/syschanges/sys.originals/i386/i386/conf.c	Sat May 30 16:48:08 1992
X--- /usr/src/sys.386bsd/i386/i386/conf.c	Wed Sep 23 01:41:37 1992
X***************
X*** 74,79 ****
X--- 74,122 ----
X  #define	assize		NULL
X  #endif
X  
X+ #include "sd.h"
X+ #if NSD > 0
X+ int	sdopen(),sdclose(),sdstrategy(),sdioctl();
X+ int	/*sddump(),*/sdsize();
X+ #define	sddump		enxio
X+ #else
X+ #define	sdopen		enxio
X+ #define	sdclose		enxio
X+ #define	sdstrategy	enxio
X+ #define	sdioctl		enxio
X+ #define	sddump		enxio
X+ #define	sdsize		NULL
X+ #endif
X+ 
X+ #include "st.h"
X+ #if NST > 0
X+ int	stopen(),stclose(),ststrategy(),stioctl();
X+ /*int	stdump(),stsize();*/
X+ #define	stdump		enxio
X+ #define	stsize		NULL
X+ #else
X+ #define	stopen		enxio
X+ #define	stclose		enxio
X+ #define	ststrategy	enxio
X+ #define	stioctl		enxio
X+ #define	stdump		enxio
X+ #define	stsize		NULL
X+ #endif
X+ 
X+ #include "cd.h"
X+ #if NCD > 0
X+ int	cdopen(),cdclose(),cdstrategy(),cdioctl();
X+ int	/*cddump(),*/cdsize();
X+ #define	cddump		enxio
X+ #else
X+ #define	cdopen		enxio
X+ #define	cdclose		enxio
X+ #define	cdstrategy	enxio
X+ #define	cdioctl		enxio
X+ #define	cddump		enxio
X+ #define	cdsize		NULL
X+ #endif
X+ 
X  #include "wt.h"
X  #if NWT > 0
X  int	wtopen(),wtclose(),wtstrategy(),wtioctl();
X***************
X*** 114,121 ****
X--- 157,173 ----
X  	  fddump,	fdsize,		NULL },
X  	{ wtopen,	wtclose,	wtstrategy,	wtioctl,	/*3*/
X  	  wtdump,	wtsize,		B_TAPE },
X+ #if NSD > 0
X+ 	{ sdopen,	sdclose,	sdstrategy,	sdioctl,	/*4*/
X+ 	  sddump,	sdsize,		NULL },
X+ #else NSD > 0
X  	{ asopen,	asclose,	asstrategy,	asioctl,	/*4*/
X  	  asdump,	assize,		NULL },
X+ #endif NSD > 0
X+ 	{ stopen,	stclose,	ststrategy,	stioctl,	/*5*/
X+ 	  stdump,	stsize,		NULL },
X+ 	{ cdopen,	cdclose,	cdstrategy,	cdioctl,	/*6*/
X+ 	  cddump,	cdsize,		NULL },
X  };
X  int	nblkdev = sizeof (bdevsw) / sizeof (bdevsw[0]);
X  
X***************
X*** 211,219 ****
X--- 263,283 ----
X  	{ pcopen,	pcclose,	pcread,		pcwrite,	/*C*/
X  	  pcioctl,	nullop,		nullop,		&pccons,
X  	  ttselect,	pcmmap,		NULL },
X+ #if	NSD > 0
X+ 	{ sdopen,	sdclose,	rawread,	rawwrite,	/*D*/
X+ 	  sdioctl,	enodev,		nullop,		NULL,
X+ 	  seltrue,	enodev,		sdstrategy },
X+ #else	NSD > 0
X  	{ asopen,	asclose,	rawread,	rawwrite,	/*D*/
X  	  asioctl,	enodev,		nullop,		NULL,
X  	  seltrue,	enodev,		asstrategy },
X+ #endif	NSD > 0
X+ 	{ stopen,	stclose,	rawread,	rawwrite,	/*E*/
X+ 	  stioctl,	enodev,		nullop,		NULL,
X+ 	  seltrue,	enodev,		ststrategy },
X+ 	{ cdopen,	cdclose,	rawread,	enodev,		/*F*/
X+ 	  cdioctl,	enodev,		nullop,		NULL,
X+ 	  seltrue,	enodev,		cdstrategy },
X  };
X  int	nchrdev = sizeof (cdevsw) / sizeof (cdevsw[0]);
X  
END-of-i386/i386/conf.c.patch
echo x - i386/conf/SCSITEST
sed 's/^X//' >i386/conf/SCSITEST << 'END-of-i386/conf/SCSITEST'
X#
X# SCSITEST -- Generic ISA machine -- scsi test kernel
X#
Xmachine		"i386"
Xcpu		"i386"
Xident		SCSITEST
Xtimezone	8 dst
Xmaxusers	10
Xoptions		INET,ISOFS,NFS
Xoptions		"COMPAT_43"
Xoptions		"TCP_COMPAT_42"
X
Xconfig		"386bsd"	root on wd0 swap on wd0 and sd0
X
Xcontroller	isa0
Xcontroller	wd0	at isa? port "IO_WD1" bio irq 14 vector wdintr
Xdisk		wd0	at wd0 drive 0
Xdisk		wd0	at wd0 drive 1
X
Xcontroller	fd0	at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
Xdisk		fd0	at fd0 drive 0
Xdisk		fd1	at fd0 drive 1
X
Xdevice		pc0	at isa? port "IO_KBD" tty irq 1 vector pcrint
Xdevice		npx0	at isa? port "IO_NPX" irq 13 vector npxintr
Xdevice		com1	at isa? port "IO_COM1" tty irq 4 vector comintr
Xdevice		com2	at isa? port "IO_COM2" tty irq 3 vector comintr
X
Xcontroller	aha0	at isa? port "IO_AHA0" bio irq 11 drq 5 vector ahaintr
Xcontroller	aha1	at isa? port "IO_AHA1" bio irq 12 drq 7 vector ahaintr
X#controller	bt0	at isa? port "IO_BT0" bio irq 12  vector btintr
Xcontroller	scbus0
X
Xdevice		sd0
Xdevice		sd1
Xdevice		sd2
Xdevice		sd3
X
Xdevice		st0
Xdevice		st1
Xdevice		st2
Xdevice		st3
X
Xdevice		cd0
Xdevice		cd1
X
Xdevice		we0 at isa? port 0x280 net irq 2 iomem 0xd0000 iosiz 8192 vector weintr
X
X
Xpseudo-device	loop
Xpseudo-device	ether
Xpseudo-device	sl	2
Xpseudo-device	log
Xpseudo-device	ddb
Xpseudo-device	pty	4
X
Xpseudo-device	swappager
Xpseudo-device	vnodepager
Xpseudo-device	devpager
END-of-i386/conf/SCSITEST
echo x - i386/conf/devices.i386.patch
sed 's/^X//' >i386/conf/devices.i386.patch << 'END-of-i386/conf/devices.i386.patch'
X*** /usr/src/syschanges/sys.originals/i386/conf/devices.i386	Thu Jun 11 14:09:16 1992
X--- /usr/src/sys.386bsd/i386/conf/devices.i386	Wed Sep 16 21:59:36 1992
X***************
X*** 2,5 ****
X--- 2,6 ----
X  dk	1
X  fd	2
X  wt	3
X+ sd	4
X  as	4
END-of-i386/conf/devices.i386.patch
echo x - i386/conf/files.i386.patch
sed 's/^X//' >i386/conf/files.i386.patch << 'END-of-i386/conf/files.i386.patch'
X*** /usr/src/syschanges/sys.originals/i386/conf/files.i386	Mon May 25 12:25:04 1992
X--- /usr/src/sys.386bsd/i386/conf/files.i386	Sat Sep 19 14:40:51 1992
X***************
X*** 25,27 ****
X--- 25,34 ----
X  i386/i386/db_disasm.c	optional ddb
X  i386/i386/db_interface.c	optional ddb
X  i386/i386/db_trace.c	optional ddb
X+ i386/isa/aha1542.c	optional aha
X+ i386/eisa/bt742a.c	optional bt
X+ scsi/st.c		optional st
X+ scsi/sd.c		optional sd
X+ scsi/cd.c		optional cd
X+ scsi/ch.c		optional ch
X+ scsi/scsiconf.c		optional scbus
END-of-i386/conf/files.i386.patch
echo x - i386/conf/Makefile.i386.patch
sed 's/^X//' >i386/conf/Makefile.i386.patch << 'END-of-i386/conf/Makefile.i386.patch'
X*** /usr/src/syschanges/sys.originals/i386/conf/Makefile.i386	Mon Feb 24 14:52:46 1992
X--- /usr/src/sys.386bsd/i386/conf/Makefile.i386	Mon Aug 24 13:02:30 1992
X***************
X*** 38,44 ****
X  SYSTEM_OBJS=locore.o ${OBJS} param.o ioconf.o conf.o
X  SYSTEM_DEP=Makefile symbols.sort ${SYSTEM_OBJS}
X  SYSTEM_LD_HEAD= 	@echo loading $@; rm -f $@
X! SYSTEM_LD= @${LD} -z -T FE000000 -o $@ -X ${SYSTEM_OBJS}
X  SYSTEM_LD_TAIL= @echo rearranging symbols; symorder symbols.sort $@; size $@; chmod 755 $@
X  
X  %OBJS
X--- 38,44 ----
X  SYSTEM_OBJS=locore.o ${OBJS} param.o ioconf.o conf.o
X  SYSTEM_DEP=Makefile symbols.sort ${SYSTEM_OBJS}
X  SYSTEM_LD_HEAD= 	@echo loading $@; rm -f $@
X! SYSTEM_LD= @${LD} -z -T FE000000 -o $@ -X vers.o ${SYSTEM_OBJS}
X  SYSTEM_LD_TAIL= @echo rearranging symbols; symorder symbols.sort $@; size $@; chmod 755 $@
X  
X  %OBJS
X***************
X*** 63,71 ****
X  
X  locore.o: assym.s ${I386}/i386/locore.s machine/trap.h machine/psl.h \
X  	machine/pte.h vector.s ${I386}/isa/icu.s ${I386}/isa/isa.h \
X! 	${I386}/isa/icu.h
X  	${CPP} -I. -DLOCORE ${COPTS} ${I386}/i386/locore.s | \
X  		${AS} ${ASFLAGS} -o locore.o
X  
X  # the following is necessary because autoconf.o depends on #if GENERIC
X  autoconf.o: Makefile
X--- 63,74 ----
X  
X  locore.o: assym.s ${I386}/i386/locore.s machine/trap.h machine/psl.h \
X  	machine/pte.h vector.s ${I386}/isa/icu.s ${I386}/isa/isa.h \
X! 	${I386}/isa/icu.h vers.o
X  	${CPP} -I. -DLOCORE ${COPTS} ${I386}/i386/locore.s | \
X  		${AS} ${ASFLAGS} -o locore.o
X+ 
X+ vers.c:	Makefile
X+ 	sh ../../conf/newvers.sh
X  
X  # the following is necessary because autoconf.o depends on #if GENERIC
X  autoconf.o: Makefile
END-of-i386/conf/Makefile.i386.patch
echo c - scsi
mkdir scsi > /dev/null 2>&1
echo x - scsi/README
sed 's/^X//' >scsi/README << 'END-of-scsi/README'
XThis release consists of the following files 
X(relative to the base of the kernel tree)
X
Xddb/db_command.c.patch
Xkern/kern_subr.c.patch
Xi386/isa/isa.h.patch
Xi386/isa/clock.c.patch
Xi386/i386/conf.c.patch
Xi386/conf/SCSITEST
Xi386/conf/devices.i386.patch
Xi386/conf/files.i386.patch
Xi386/conf/Makefile.i386.patch
Xscsi
Xscsi/README
Xscsi/scsiconf.h
Xscsi/scsiconf.c
Xscsi/scsi_all.h
Xscsi/scsi_disk.h
Xscsi/scsi_tape.h
Xscsi/scsi_cd.h
Xscsi/st.c
Xscsi/sd.c
Xscsi/cd.c
Xi386/isa/aha1542.c
X/dev/MAKEDEV
X
XThe patch files do the following things:
X
X	ddb/db_command.c.patch
X	kern/kern_subr.c.patch
XThese move the strcmp function out of ddb to a more generic place
Xso I can use it even if ddb is not configured in.
X
X	i386/isa/isa.h.patch
Xdefine ports needed for the adaptec board.
X
X	i386/isa/clock.c.patch
Xadd a calibrated spinwait that can be used before the clock interrupts 
Xcan be used. (i.e. in boot up)
X
X	i386/i386/conf.c.patch
Xadd cdevsw and bdevsw table entries for the scsi disk and tape devices.
X
X	i386/conf/devices.i386.patch
Xdefine an sd device so I can config it for swap
X
X	i386/conf/files.i386.patch
Xdefine the files we need to compile in for this scsi system.
X
X	i386/conf/Makefile.i386.patch
XThis Makefile knows how to make the vers.c program. This should
Xbecome un-needed when the patch kit fixes this bug. 
X
X	/dev/MAKEDEV
XA replacement MAKEDEV that knows about these devices.
X
X
X----------------------------------------------------------------
XThis scsi system is designed to allow the re-use of top end drivers
Xsuch as disk and tape drivers, with different scsi adapters.
X
XAs of writing this document, There are top end drivers working for:
X----------------------------------------------------------------
Xgeneric scsi disk
Xgeneric scsi tape
Xcd-rom (tested for SUN cd-rom only)
XAEG Character recognition devices *
XCalera Character recognition devices *
XKodak IL900 scanner *
XExabyte tape changer device.**
X----------------------------------------------------------------
X
X
XThere are also working bottom end drivers for:
X----------------------------------------------------------------
Xadaptec 1542 (and 1742 in 1542 mode)
Xbustec 742a **
X----------------------------------------------------------------
X
X
XWork is proceeding on the following bottom end drivers:
X----------------------------------------------------------------
XFuture Domain (8 and 16 bit)****	hosler@tfs.com & rpr@oce.nl
XWD7000****				terry@icarus.weber.edu
Xseagate st01/st02****			overby@aspen.cray.com ?
Xadaptec 174x ***			me
XUltrastore ***				overby@aspen.cray.com & friend?
X----------------------------------------------------------------
X* drivers not made public (proprietary.. proof that the concept works though)
X** driver not yet released but working.
X*** just a dream so far.
X**** some amount more than just a dream so far.
X
X
X################## Using the scsi system ##################
X------------minor numbers---------------
XThis scsi system does not allocate minor numbers to devices depending
Xon their SCSI IDs is any way. A devices minor number is dependant
Xon the order in which it was found.
Xe.g. the first tape found will become st0 (minor number 0)
X	the second found will become st1 (minor number 16)
X	the third will become st2 (minor 32) 
X	etc.
X
XThese devices could be on the same scsi bus or different scsi busses.
XThat would not change their minor numbers.
X
XIt is possible to run two different TYPES of scsi adapters at the 
Xsame time and have st0 on one and st1 on another. (for example)
X
XThere is a scheme supported in which scsi devices can be 'wired in' even
Xif they are not present or powered on at probe time. (see scsiconf.c)
X
X--------------getting started------------
XIt should be possible to use the /dev entries for as0 as if they were 
X/dev entries for sd0 and the old as bootblocks should
Xcontinue to work if you are using an adaptec 1542b.
X
X--------------making devices------------
XA changed version of /dev/MAKEDEV is supplied that
Xcan be used to make devices sd[01234] and st[01234]
X
Xe.g. 
Xcd /dev
Xsh MAKEDEV sd0 sd1 sd2 st0 st1 cd0
X
X
XThe tape devices are as follows:
Xrst0	basic raw device, will rewind on close
Xnrst0	will not rewind on close
Xerst0	will rewind and EJECTon close
Xnerst0  will not rewind and WILL eject (some devices may rewind anyhow)
X
X------------future enhancements--------------
XSome people have indicated that they would like to have the SCSI ID
Xencoded into the minor number in some way, and
Xthis may be supported at some timein the future, using
Xminor numbers greater than 128. (or maybe a different major number)
X
XI will also be writing (probably) a generic scsi-error
Xhandling routine that will be table driven, so that the routine can
Xbe removed from each individual driver. With enough care,
Xtwo similar devices with different error codes (quite common) could run
Xthe same driver but use different error tables.
X
X--------------file layout-------------------
XOriginally I had all scsi definitions in one file: scsi.h
XI have since moved definitions of commands so that all
Xdefinitions needed for a particular type of device are
Xfound together in the include file of that name.
XThis approximatly follows the layout of their definition 
Xin the SCSI-2 spec. 
XAs such they are:
X
Xscsi_all.h   general commands for all devices --- CHAPTER 7
Xscsi-disk.h  commands relevant to disk        --- CHAPTER 8
Xscsi-tape.h  commands for scsi tapes          --- CHAPTER 9
Xscsi-cd.h    commands for cd-roms (and audio) --- CHAPTER 13
X
X-----------cd-rom-----------------
XI have only recntly added the cd-rom driver
XI have mounted disk using the iso9660 file system
Xbut have not managed to get the AUDIO commands to work (yet)
XI have only tested this code on a SUN cd-rom which uses
Xa 512 byte logical blocksize, however it has code to addapt
Xto other logical blocksizes (multiples of 512 please!)
X
END-of-scsi/README
echo x - scsi/scsiconf.h
sed 's/^X//' >scsi/scsiconf.h << 'END-of-scsi/scsiconf.h'
X/*
X * Written by Julian Elischer (julian@tfs.com)
X * for TRW Financial Systems for use under the MACH(2.5) operating system.
X *
X * TRW Financial Systems, in accordance with their agreement with Carnegie
X * Mellon University, makes this software available to CMU to distribute
X * or use in any manner that they see fit as long as this message is kept with
X * the software. For this reason TFS also grants any other persons or
X * organisations permission to use or modify this software.
X *
X * TFS supplies this software to be publicly redistributed
X * on the understanding that TFS is not responsible for the correct
X * functioning of this software in any circumstances.
X *
X */
X
X/*
X * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
X */
X
Xstruct scsi_switch
X{
X	int	(*scsi_cmd)();
X	void	(*scsi_minphys)();
X	int	(*open_target_lu)();
X	int	(*close_target_lu)();
X	int	(*adapter_info)();
X
X};
X
X/***********************************************\
X* The scsi debug control bits			*
X\***********************************************/
Xextern	int	scsi_debug;
X#define PRINTROUTINES	0x01
X#define	TRACEOPENS	0x02
X#define	TRACEINTERRUPTS	0x04
X#define	SHOWREQUESTS	0x08
X#define	SHOWSCATGATH	0x10
X#define	SHOWINQUIRY	0x20
X#define	SHOWCOMMANDS	0x40
X
X
X/********************************/
X/* return values for scsi_cmd() */
X/********************************/
X#define SUCCESSFULLY_QUEUED	0
X#define TRY_AGAIN_LATER		1
X#define	COMPLETE		2
X#define	HAD_ERROR		3
X
Xstruct scsi_xfer
X{
X	struct	scsi_xfer *next;	/* when free */
X	int	flags;
X	u_char	adapter;
X	u_char	targ;
X	u_char	lu;
X	u_char	retries;	/* the number of times to retry */
X	long	int	timeout;	/* in miliseconds */
X	struct	scsi_generic *cmd;
X	int	cmdlen;
X	u_char	*data;		/* either the dma address OR a uio address */
X	int	datalen;	/* data len (blank if uio)    */
X	int	resid;
X	int	(*when_done)();
X	int	done_arg;
X	int	done_arg2;
X	int	error;
X	struct	buf *bp;
X	struct	scsi_sense_data	sense;
X};
X/********************************/
X/* Flag values			*/
X/********************************/
X#define	SCSI_NOSLEEP	0x01	/* Not a user... don't sleep		*/
X#define	SCSI_NOMASK	0x02	/* dont allow interrupts.. booting	*/
X#define	SCSI_NOSTART	0x04	/* left over from ancient history	*/
X#define	ITSDONE		0x10	/* the transfer is as done as it gets	*/
X#define	INUSE		0x20	/* The scsi_xfer block is in use	*/
X#define	SCSI_SILENT	0x40	/* Don't report errors to console	*/
X#define SCSI_ERR_OK	0x80	/* An error on this operation is OK.	*/
X#define	SCSI_RESET	0x100	/* Reset the device in question		*/
X#define	SCSI_DATA_UIO	0x200	/* The data address refers to a UIO	*/
X#define	SCSI_DATA_IN	0x400	/* expect data to come INTO memory	*/
X#define	SCSI_DATA_OUT	0x800	/* expect data to flow OUT of memory	*/
X/********************************/
X/* Error values			*/
X/********************************/
X#define XS_NOERROR	0x0	/* there is no error, (sense is invalid)  */
X#define XS_SENSE	0x1	/* Check the returned sense for the error */
X#define	XS_DRIVER_STUFFUP 0x2	/* Driver failed to perform operation	  */
X#define XS_TIMEOUT	0x03	/* The device timed out.. turned off?	  */
X#define XS_SWTIMEOUT	0x04	/* The Timeout reported was caught by SW  */
X#define XS_BUSY		0x08	/* The device busy, try again later?	  */
X
END-of-scsi/scsiconf.h
echo x - scsi/scsiconf.c
sed 's/^X//' >scsi/scsiconf.c << 'END-of-scsi/scsiconf.c'
X/*
X * Written by Julian Elischer (julian@tfs.com)
X * for TRW Financial Systems for use under the MACH(2.5) operating system.
X *
X * TRW Financial Systems, in accordance with their agreement with Carnegie
X * Mellon University, makes this software available to CMU to distribute
X * or use in any manner that they see fit as long as this message is kept with
X * the software. For this reason TFS also grants any other persons or
X * organisations permission to use or modify this software.
X *
X * TFS supplies this software to be publicly redistributed
X * on the understanding that TFS is not responsible for the correct
X * functioning of this software in any circumstances.
X *
X */
X
X/*
X * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
X */
X
X/*
X$Log:
X*
X*/
X#include <sys/types.h>
X#include "st.h"
X#include "sd.h"
X#include "ch.h"
X#include "cd.h"
X
X#ifdef	MACH
X#include <i386/machparam.h>
X#include <i386at/scsi_all.h>
X#include <i386at/scsiconf.h>
X#else	MACH
X#ifdef	__386BSD__
X#include <scsi/scsi_all.h>
X#include <scsi/scsiconf.h>
X#endif	__386BSD__
X#endif	MACH
X
X#if !defined(OSF) && !defined(__386BSD__)
X#include "bll.h"
X#include "cals.h"
X#endif /* !defined(OSF) && !defined(__386BSD__) */
X
X#if NSD > 0
Xextern	sdattach();
X#endif NSD
X#if NST > 0
Xextern	stattach();
X#endif NST
X#if NCH > 0
Xextern	chattach();
X#endif NCH
X#if NCD > 0
Xextern	cdattach();
X#endif NCD
X#if NBLL > 0
Xextern	bllattach();
X#endif NBLL
X#if NCALS > 0
Xextern	calsattach();
X#endif NCALS
X
X/***************************************************************\
X* The structure of pre-configured devices that might be turned	*
X* off and therefore may not show up				*
X\***************************************************************/
Xstruct	predefined
X{
X	u_char	scsibus;
X	u_char	dev;
X	u_char	lu;
X	int	(*attach_rtn)();
X	char	*devname;
X}
Xpd[] = 
X{
X#ifdef EXAMPLE_PREDEFINE
X#if NSD > 0
X	{0,0,0,sdattach,"sd"},	/* define a disk at scsibus=0 dev=0 lu=0 */
X#endif NSD
X#endif EXAMPLE_PREDEFINE
X	{0,9,9}			/*illegal dummy end entry */
X};
X
X
X/***************************************************************\
X* The structure of known drivers for autoconfiguration		*
X\***************************************************************/
Xstatic struct scsidevs 
X{
X	int type;
X	int removable;
X	char	*manufacturer;
X	char	*model;
X	char	*version;
X	int	(*attach_rtn)();
X	char	*devname;
X	char	showme;		/* 1 show my comparisons during boot(debug) */
X}
Xknowndevs[] = {
X#if NSD > 0
X	{ T_DIRECT,T_FIXED,"standard","any","any",sdattach,"sd" },
X	{ T_DIRECT,T_FIXED,"MAXTOR  ","XT-4170S        ","B5A ",sdattach,"mx1",0 },
X#endif NSD
X#if NST > 0
X	{ T_SEQUENTIAL,T_REMOV,"standard","any","any",stattach,"st" },
X#endif NST
X#if NCALS > 0
X	{ T_PROCESSOR,T_FIXED,"standard","any","any",calsattach,"cals" },
X#endif NCALS
X#if NCH > 0
X	{ T_CHANGER,T_REMOV,"standard","any","any",chattach,"ch" },
X#endif NCH
X#if NCD > 0
X	{ T_READONLY,T_REMOV,"SONY    ","CD-ROM CDU-8012 ","3.1a",cdattach,"cd" },
X#endif NCD
X#if NBLL > 0
X	{ T_PROCESSOR,T_FIXED,"AEG     ","READER          ","V1.0",bllattach,"bll" },
X#endif NBLL
X{0}
X};
X/***************************************************************\
X* Declarations							*
X\***************************************************************/
Xstruct	predefined	*scsi_get_predef();
Xstruct	scsidevs	*scsi_probedev();
Xstruct	scsidevs	*selectdev();
X
X/* controls debug level within the scsi subsystem */
X/* see scsiconf.h for values			  */
Xint	scsi_debug	=	0x0;
Xint	scsibus		=	0x0; /* This is the Nth scsibus */
X
X/***************************************************************\
X* The routine called by the adapter boards to get all their	*
X* devices configured in.					*
X\***************************************************************/
Xscsi_attachdevs( unit, scsi_addr, scsi_switch)
Xint	unit,scsi_addr;
Xstruct	scsi_switch	*scsi_switch;
X{
X	int	targ,lun;
X	struct	scsidevs	*bestmatch = (struct scsidevs *)0;
X	struct	predefined *predef;
X
X#ifdef	KODAK_SCANNER
X	printf("waiting for scsi devices to settle\n");
X	spinwait(1000 * 30);
X#endif	KODAK_SCANNER
X	targ = 0;
X	while(targ < 8)
X	{
X		if (targ == scsi_addr) 
X		{
X			targ++;
X			continue;
X		}
X		lun = 0;
X		while(lun < 8)
X		{
X			predef = scsi_get_predef(scsibus,targ,lun);
X			bestmatch = scsi_probedev(unit,targ,lun,scsi_switch);
X			if((bestmatch) && (predef)) /* both exist */
X			{
X				if(bestmatch->attach_rtn 
X				    != predef->attach_rtn)
X				{
X				    printf("Clash in found/expected devices\n");
X				    printf("will link in FOUND\n");
X				}
X				(*(bestmatch->attach_rtn))(unit,
X						targ,
X						lun,
X						scsi_switch);
X			}
X			if((bestmatch) && (!predef)) /* just FOUND */
X			{
X				(*(bestmatch->attach_rtn))(unit,
X						targ,
X						lun,
X						scsi_switch);
X			}
X			if((!bestmatch) && (predef)) /* just predef */
X			{
X				(*(predef->attach_rtn))(unit,
X						targ,
X						lun,
X						scsi_switch);
X			}
X			lun++;
X		}
X		targ++;
X	}
X	scsibus++;	/* next time we are on the NEXT scsi bus */
X}
X
X/***********************************************\
X* given a target and lu, check if there is a	*
X* predefined device for that address		*
X\***********************************************/
Xstruct	predefined	*scsi_get_predef(unit,target,lu)
Xint	unit,target,lu;
X{
X	int upto,numents;
X
X	numents = (sizeof(pd)/sizeof(struct predefined)) - 1;
X	
X	for(upto = 0;upto < numents;upto++)
X	{
X		if(pd[upto].scsibus != unit)
X			continue;
X		if(pd[upto].dev != target)
X			continue;
X		if(pd[upto].lu != lu)
X			continue;
X		
X		printf("  dev%d,lu%d: %s - PRECONFIGURED -\n"
X			,target
X			,lu
X			,pd[upto].devname);
X		return(&(pd[upto]));
X	}
X	return((struct predefined *)0);
X}
X
X/***********************************************\
X* given a target and lu, ask the device what	*
X* it is, and find the correct driver table	*
X* entry.					*
X\***********************************************/
Xstruct	scsidevs	*scsi_probedev(unit,target,lu,scsi_switch)
X
Xstruct	scsi_switch *scsi_switch;
Xint	unit,target,lu;
X{
X	char	*dtype,*desc;
X	struct scsi_inquiry_data	inqbuf;
X	int	len,type,remov;
X	char	manu[32];
X	char	model[32];
X	char	version[32];
X
X	bzero(&inqbuf,sizeof(inqbuf));
X	/***********************************************\
X	* Ask the device what it is			*
X	\***********************************************/
X#ifdef	DEBUG
X	if((target == 0) && (lu == 0))
X		scsi_debug = 0xfff;
X	else
X		scsi_debug = 0;
X#endif	DEBUG
X	if(scsi_ready(	unit,
X			target,
X			lu,
X			scsi_switch,
X			SCSI_NOSLEEP | SCSI_NOMASK) != COMPLETE)
X	{
X		return(struct scsidevs *)0;
X	}
X	if(scsi_inquire(unit,
X			target,
X			lu,
X			scsi_switch,
X			&inqbuf,
X			SCSI_NOSLEEP | SCSI_NOMASK) != COMPLETE)
X	{
X		return(struct scsidevs *)0;
X	}
X
X	/***********************************************\
X	* note what BASIC type of device it is		*
X	\***********************************************/
X	if(scsi_debug & SHOWINQUIRY)
X	{
X		desc=(char *)&inqbuf;
X		printf("inq: %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
X		desc[0], desc[1], desc[2], desc[3],
X		desc[4], desc[5], desc[6], desc[7],
X		desc[8], desc[9], desc[10], desc[11],
X		desc[12]);
X	}
X	type = inqbuf.device_type;
X	remov = inqbuf.removable;
X	switch(type)
X	{
X		case T_DIRECT:
X			dtype="direct";
X			break;
X		case T_SEQUENTIAL:
X			dtype="sequential";
X			break;
X		case T_PRINTER:
X			dtype="printer";
X			break;
X		case T_PROCESSOR:
X			dtype="processor";
X			break;
X		case T_READONLY:
X			dtype="readonly";
X			break;
X		case T_WORM:
X			dtype="worm";
X			break;
X		case T_SCANNER:
X			dtype="scanner";
X			break;
X		case T_OPTICAL:
X			dtype="optical";
X			break;
X		case T_CHANGER:
X			dtype="changer";
X			break;
X		case T_COMM:
X			dtype="communication";
X			break;
X		default:
X			dtype="unknown";
X			break;
X	}
X	/***********************************************\
X	* Then if it's advanced enough, more detailed	*
X	* information					*
X	\***********************************************/
X	if(inqbuf.ansii_version > 0) 
X	{
X		if ((len = inqbuf.additional_length 
X				+ ( (char *)inqbuf.unused
X				  - (char *)&inqbuf))
X			> (sizeof(struct scsi_inquiry_data) - 1))
X			len = sizeof(struct scsi_inquiry_data) - 1;
X		desc=inqbuf.vendor;
X		desc[len-(desc - (char *)&inqbuf)] = 0;
X		strncpy(manu,inqbuf.vendor,8);manu[8]=0;
X		strncpy(model,inqbuf.product,16);model[16]=0;
X		strncpy(version,inqbuf.revision,4);version[4]=0;
X	}
X	else
X	/***********************************************\
X	* If not advanced enough, use default values	*
X	\***********************************************/
X	{
X		desc="early protocol device";
X		strncpy(manu,"unknown",8);
X		strncpy(model,"unknown",16);
X		strncpy(version,"????",4);
X	}
X	printf("  dev%d,lu%d: type %d(%s),%s '%s%s%s' scsi%d\n"
X		,target
X		,lu
X		,type
X		,dtype
X		,remov?"removable":"fixed"
X		,manu
X		,model
X		,version
X		,inqbuf.ansii_version
X	);
X	/***********************************************\
X	* Try make as good a match as possible with	*
X	* available sub drivers	 			*
X	\***********************************************/
X	return(selectdev(unit,target,lu,&scsi_switch,
X		type,remov,manu,model,version));
X}
X
X/***********************************************\
X* Try make as good a match as possible with	*
X* available sub drivers	 			*
X\***********************************************/
Xstruct	scsidevs	
X*selectdev(unit,target,lu,dvr_switch,type,remov,manu,model,rev)
Xint	unit,target,lu;
Xstruct	scsi_switch *dvr_switch;
Xint	type,remov;
Xchar	*manu,*model,*rev;
X{
X	int	numents = (sizeof(knowndevs)/sizeof(struct scsidevs)) - 1;
X	int	count = 0;
X	int			bestmatches;
X	struct	scsidevs	*bestmatch = (struct scsidevs *)0;
X	struct	scsidevs	*thisentry = knowndevs;
X
X	thisentry--;
X	while( count++ < numents)
X	{
X		thisentry++;
X		if(type != thisentry->type)
X		{
X			continue;
X		}
X		if(bestmatches < 1)
X		{
X			bestmatches = 1;
X			bestmatch = thisentry;
X		}
X		if(remov != thisentry->removable)
X		{
X			continue;
X		}
X		if(bestmatches < 2)
X		{
X			bestmatches = 2;
X			bestmatch = thisentry;
X		}
X		if(thisentry->showme)
X			printf("\n%s-\n%s-",thisentry->manufacturer, manu);
X		if(strcmp(thisentry->manufacturer, manu))
X		{
X			continue;
X		}
X		if(bestmatches < 3)
X		{
X			bestmatches = 3;
X			bestmatch = thisentry;
X		}
X		if(thisentry->showme)
X			printf("\n%s-\n%s-",thisentry->model, model);
X		if(strcmp(thisentry->model, model))
X		{
X			continue;
X		}
X		if(bestmatches < 4)
X		{
X			bestmatches = 4;
X			bestmatch = thisentry;
X		}
X		if(thisentry->showme)
X			printf("\n%s-\n%s-",thisentry->version, rev);
X		if(strcmp(thisentry->version, rev))
X		{
X			continue;
X		}
X		if(bestmatches < 5)
X		{
X			bestmatches = 5;
X			bestmatch = thisentry;
X			break;
X		}
X	}
X	return(bestmatch);
X}
X
Xstatic	int recurse = 0;
X/***********************************************\
X* Do a scsi operation asking a device if it is	*
X* ready. Use the scsi_cmd routine in the switch *
X* table.					*
X\***********************************************/
Xscsi_ready(unit,target,lu,scsi_switch, flags)
Xstruct	scsi_switch *scsi_switch;
X{
X	struct	scsi_test_unit_ready scsi_cmd;
X	struct	scsi_xfer scsi_xfer;
X	volatile int rval;
X	int	key;
X
X	bzero(&scsi_cmd, sizeof(scsi_cmd));
X	bzero(&scsi_xfer, sizeof(scsi_xfer));
X	scsi_cmd.op_code = TEST_UNIT_READY;
X
X	scsi_xfer.flags=flags | INUSE;
X	scsi_xfer.adapter=unit;
X	scsi_xfer.targ=target;
X	scsi_xfer.lu=lu;
X	scsi_xfer.cmd=(struct scsi_generic *)&scsi_cmd;
X	scsi_xfer.retries=8;
X	scsi_xfer.timeout=10000;
X	scsi_xfer.cmdlen=sizeof(scsi_cmd);
X	scsi_xfer.data=0;
X	scsi_xfer.datalen=0;
X	scsi_xfer.resid=0;
X	scsi_xfer.when_done=0;
X	scsi_xfer.done_arg=0;
Xretry:	scsi_xfer.error=0;
X	/*******************************************************\
X	* do not use interrupts					*
X	\*******************************************************/
X	rval = (*(scsi_switch->scsi_cmd))(&scsi_xfer);
X	if (rval != COMPLETE)
X	{
X		if(scsi_debug)
X		{
X			printf("scsi error, rval = 0x%x\n",rval);
X			printf("code from driver: 0x%x\n",scsi_xfer.error);
X		}
X		switch(scsi_xfer.error)
X		{
X		case	XS_SENSE:
X		/*******************************************************\
X		* Any sense value is illegal except UNIT ATTENTION	*
X		* In which case we need to check again to get the	*
X		* correct response.					*
X		*( especially exabytes)					*
X		\*******************************************************/
X			if(scsi_xfer.sense.error_class == 7 )
X			{
X				key = scsi_xfer.sense.ext.extended.sense_key ;
X				switch(key)
X				{ 
X				case	2:	/* not ready BUT PRESENT! */
X						return(COMPLETE);
X				case	6:
X					for(rval = 0 ;rval < 1000000 ;rval++);
X					if(scsi_xfer.retries--)
X					{
X						scsi_xfer.flags &= ~ITSDONE;
X						goto retry;
X					}
X					return(COMPLETE);
X				default:
X					if(scsi_debug)
X						printf("%d:%d,key=%x.",
X						target,lu,key);
X				}
X			}
X			return(HAD_ERROR);
X		case	XS_BUSY:
X			for(rval = 0 ;rval < 1000000 ;rval++);
X			if(scsi_xfer.retries--)
X			{
X				scsi_xfer.flags &= ~ITSDONE;
X				goto retry;
X			}
X			return(COMPLETE);	/* it's busy so it's there */
X		case	XS_TIMEOUT:
X		default:
X			return(HAD_ERROR);
X		}
X	}
X	return(COMPLETE);
X}
X/***********************************************\
X* Do a scsi operation asking a device what it is*
X* Use the scsi_cmd routine in the switch table.	*
X\***********************************************/
Xscsi_inquire(unit,target,lu,scsi_switch,inqbuf, flags)
Xstruct	scsi_switch *scsi_switch;
Xu_char	*inqbuf;
X{
X	struct	scsi_inquiry scsi_cmd;
X	struct	scsi_xfer scsi_xfer;
X	volatile int rval;
X
X	bzero(&scsi_cmd, sizeof(scsi_cmd));
X	bzero(&scsi_xfer, sizeof(scsi_xfer));
X	scsi_cmd.op_code = INQUIRY;
X	scsi_cmd.length = sizeof(struct scsi_inquiry_data);
X
X	scsi_xfer.flags=flags | SCSI_DATA_IN | INUSE;
X	scsi_xfer.adapter=unit;
X	scsi_xfer.targ=target;
X	scsi_xfer.lu=lu;
X	scsi_xfer.retries=8;
X	scsi_xfer.timeout=10000;
X	scsi_xfer.cmd=(struct scsi_generic *)&scsi_cmd;
X	scsi_xfer.cmdlen= sizeof(struct scsi_inquiry);
X	scsi_xfer.data=inqbuf;
X	scsi_xfer.datalen=sizeof(struct scsi_inquiry_data);
X	scsi_xfer.resid=sizeof(struct scsi_inquiry_data);
X	scsi_xfer.when_done=0;
X	scsi_xfer.done_arg=0;
Xretry:	scsi_xfer.error=0;
X	/*******************************************************\
X	* do not use interrupts					*
X	\*******************************************************/
X	if ((*(scsi_switch->scsi_cmd))(&scsi_xfer) != COMPLETE)
X	{
X		switch(scsi_xfer.error)
X		{
X		case	XS_SENSE:
X		/*******************************************************\
X		* Any sense value is illegal except UNIT ATTENTION	*
X		* In which case we need to check again to get the	*
X		* correct response.					*
X		*( especially exabytes)					*
X		\*******************************************************/
X			if((scsi_xfer.sense.error_class == 7 )
X			 && (scsi_xfer.sense.ext.extended.sense_key == 6))
X			{ /* it's changed so it's there */
X				for(rval = 0 ;rval < 1000000 ;rval++);
X				{
X					scsi_xfer.flags &= ~ITSDONE;
X					goto retry;
X				}
X				return( COMPLETE);
X			}
X			return(HAD_ERROR);
X		case	XS_BUSY:
X			for(rval = 0 ;rval < 1000000 ;rval++);
X			if(scsi_xfer.retries--)
X			{
X				scsi_xfer.flags &= ~ITSDONE;
X				goto retry;
X			}
X			return(COMPLETE);	/* it's busy so it's there */
X		case	XS_TIMEOUT:
X		default:
X			return(HAD_ERROR);
X		}
X	}
X	return(COMPLETE);
X}
X
X
X
X
X/***********************************************\
X* Utility routines often used in SCSI stuff	*
X\***********************************************/
X
X/***********************************************\
X* convert a physical address to 3 bytes, 	*
X* MSB at the lowest address,			*
X* LSB at the highest.				*
X\***********************************************/
X
Xlto3b(val, bytes)
Xu_char *bytes;
X{
X	*bytes++ = (val&0xff0000)>>16;
X	*bytes++ = (val&0xff00)>>8;
X	*bytes = val&0xff;
X}
X
X/***********************************************\
X* The reverse of lto3b				*
X\***********************************************/
X_3btol(bytes)
Xu_char *bytes;
X{
X	int rc;
X	rc = (*bytes++ << 16);
X	rc += (*bytes++ << 8);
X	rc += *bytes;
X	return(rc);
X}
X
END-of-scsi/scsiconf.c
echo x - scsi/scsi_all.h
sed 's/^X//' >scsi/scsi_all.h << 'END-of-scsi/scsi_all.h'
X/*
X * HISTORY
X * $Log: scsi_all.h,v $
X * 
X */
X
X/*
X * SCSI general  interface description
X */
X
X
X/*
X * Largely written by Julian Elischer (julian@tfs.com)
X * for TRW Financial Systems.
X *
X * TRW Financial Systems, in accordance with their agreement with Carnegie
X * Mellon University, makes this software available to CMU to distribute
X * or use in any manner that they see fit as long as this message is kept with 
X * the software. For this reason TFS also grants any other persons or
X * organisations permission to use or modify this software.
X *
X * TFS supplies this software to be publicly redistributed
X * on the understanding that TFS is not responsible for the correct
X * functioning of this software in any circumstances.
X *
X */
X
X/*
X * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
X */
X
X/*
X * SCSI command format
X */
X
X
Xstruct scsi_generic
X{
X	u_char	opcode;
X	u_char	bytes[11];
X};
X
Xstruct scsi_test_unit_ready
X{
X	u_char	op_code;
X	u_char	:5;
X	u_char	lun:3;
X	u_char	unused[3];
X	u_char	link:1;
X	u_char	flag:4;
X	u_char	:3;
X};
X
Xstruct scsi_send_diag
X{
X	u_char	op_code;
X	u_char	uol:1;
X	u_char	dol:1;
X	u_char	selftest:1;
X	u_char	:1;
X	u_char	pf:1;
X	u_char	lun:3;
X	u_char	unused[1];
X	u_char	paramlen[2];
X	u_char	link:1;
X	u_char	flag:4;
X	u_char	:3;
X};
X
Xstruct scsi_sense
X{
X	u_char	op_code;
X	u_char	:5;
X	u_char	lun:3;	
X	u_char	unused[2];
X	u_char	length;
X	u_char	link:1;
X	u_char	flag:1;
X	u_char	:6;
X};
X
Xstruct scsi_inquiry
X{
X	u_char	op_code;
X	u_char	:5;
X	u_char	lun:3;	
X	u_char	unused[2];
X	u_char	length;
X	u_char	link:1;
X	u_char	flag:1;
X	u_char	:6;
X};
X
Xstruct scsi_mode_sense
X{
X	u_char	op_code;
X	u_char	:3;
X	u_char	dbd:1;
X	u_char	rsvd:1;
X	u_char	lun:3;	
X	u_char	page_code:6;
X	u_char	page_ctrl:2;
X	u_char	unused;
X	u_char	length;
X	u_char	link:1;
X	u_char	flag:1;
X	u_char	:6;
X};
X
Xstruct scsi_mode_sense_big
X{
X	u_char	op_code;
X	u_char	:3;
X	u_char	dbd:1;
X	u_char	rsvd:1;
X	u_char	lun:3;	
X	u_char	page_code:6;
X	u_char	page_ctrl:2;
X	u_char	unused[4];
X	u_char	length[2];
X	u_char	link:1;
X	u_char	flag:1;
X	u_char	:6;
X};
X
Xstruct scsi_mode_select
X{
X	u_char	op_code;
X	u_char	sp:1;
X	u_char	:3;
X	u_char	pf:1;
X	u_char	lun:3;	
X	u_char	unused[2];
X	u_char	length;
X	u_char	link:1;
X	u_char	flag:1;
X	u_char	:6;
X};
X
Xstruct scsi_mode_select_big
X{
X	u_char	op_code;
X	u_char	sp:1;
X	u_char	:3;
X	u_char	pf:1;
X	u_char	lun:3;	
X	u_char	unused[5];
X	u_char	length[2];
X	u_char	link:1;
X	u_char	flag:1;
X	u_char	:6;
X};
X
Xstruct scsi_reserve
X{
X	u_char	op_code;
X	u_char	:5;
X	u_char	lun:3;	
X	u_char	unused[2];
X	u_char	length;
X	u_char	link:1;
X	u_char	flag:1;
X	u_char	:6;
X};
X
Xstruct scsi_release
X{
X	u_char	op_code;
X	u_char	:5;
X	u_char	lun:3;	
X	u_char	unused[2];
X	u_char	length;
X	u_char	link:1;
X	u_char	flag:1;
X	u_char	:6;
X};
X
Xstruct scsi_prevent
X{
X	u_char	op_code;
X	u_char	:5;
X	u_char	lun:3;
X	u_char	unused[2];
X	u_char	prevent:1;
X	u_char	:7;
X	u_char	link:1;
X	u_char	flag:1;
X	u_char	:6;
X};
X#define	PR_PREVENT 1
X#define PR_ALLOW   0
X
X/*
X * Opcodes
X */
X
X#define	TEST_UNIT_READY		0x00
X#define REQUEST_SENSE		0x03
X#define INQUIRY			0x12
X#define MODE_SELECT		0x15
X#define MODE_SENSE		0x1a
X#define START_STOP		0x1b
X#define RESERVE      		0x16
X#define RELEASE      		0x17
X#define PREVENT_ALLOW		0x1e
X#define POSITION_TO_ELEMENT	0x2b
X#define	MODE_SENSE_BIG		0x54
X#define	MODE_SELECT_BIG		0x55
X#define MOVE_MEDIUM     	0xa5
X#define READ_ELEMENT_STATUS	0xb8
X
X
X/*
X * sense data format
X */
X#define T_DIRECT	0
X#define T_SEQUENTIAL	1
X#define T_PRINTER	2
X#define T_PROCESSOR	3
X#define T_WORM		4
X#define T_READONLY	5
X#define T_SCANNER 	6
X#define T_OPTICAL 	7
X#define T_CHANGER	8
X#define T_COMM		9
X
X#define T_REMOV		1
X#define	T_FIXED		0
X
Xstruct scsi_inquiry_data
X{
X	u_char	device_type:5;
X	u_char	device_qualifier:3;
X	u_char	dev_qual2:7;
X	u_char	removable:1;
X	u_char	ansii_version:3;
X	u_char	:5;
X	u_char	response_format;
X	u_char	additional_length;
X	u_char	unused[2];
X	u_char	:3;
X	u_char	can_link:1;
X	u_char	can_sync:1;
X	u_char	:3;
X	char	vendor[8];
X	char	product[16];
X	char	revision[4];
X	u_char	extra[8];
X};
X
X
Xstruct	scsi_sense_data
X{
X	u_char	error_code:4;
X	u_char	error_class:3;
X	u_char	valid:1;
X	union
X	{
X		struct
X		{
X			u_char	blockhi:5;
X			u_char	vendor:3;
X			u_char	blockmed;
X			u_char	blocklow;
X		} unextended;
X		struct
X		{
X			u_char	segment;
X			u_char	sense_key:4;
X			u_char	:1;
X			u_char	ili:1;
X			u_char	eom:1;
X			u_char	filemark:1;
X			u_char	info[4];
X			u_char	extra_len;
X			/* allocate enough room to hold new stuff
X			u_char	cmd_spec_info[4];
X			u_char	add_sense_code;
X			u_char	add_sense_code_qual;
X			u_char	fru;
X			u_char	sense_key_spec_1:7;
X			u_char	sksv:1;
X			u_char	sense_key_spec_2;
X			u_char	sense_key_spec_3;
X			( by increasing 16 to 26 below) */
X			u_char	extra_bytes[26];
X		} extended;
X	}ext;
X};
Xstruct	scsi_sense_data_new
X{
X	u_char	error_code:7;
X	u_char	valid:1;
X	union
X	{
X		struct
X		{
X			u_char	blockhi:5;
X			u_char	vendor:3;
X			u_char	blockmed;
X			u_char	blocklow;
X		} unextended;
X		struct
X		{
X			u_char	segment;
X			u_char	sense_key:4;
X			u_char	:1;
X			u_char	ili:1;
X			u_char	eom:1;
X			u_char	filemark:1;
X			u_char	info[4];
X			u_char	extra_len;
X			u_char	cmd_spec_info[4];
X			u_char	add_sense_code;
X			u_char	add_sense_code_qual;
X			u_char	fru;
X			u_char	sense_key_spec_1:7;
X			u_char	sksv:1;
X			u_char	sense_key_spec_2;
X			u_char	sense_key_spec_3;
X			u_char	extra_bytes[16];
X		} extended;
X	}ext;
X};
X
Xstruct	blk_desc
X{
X	u_char	density;
X	u_char	nblocks[3];
X	u_char	reserved;
X	u_char	blklen[3];
X};
X
Xstruct scsi_mode_header
X{
X	u_char	data_length;	/* Sense data length */
X	u_char	medium_type;
X	u_char	dev_spec;
X	u_char	blk_desc_len;
X};
X
Xstruct scsi_mode_header_big
X{
X	u_char	data_length[2];	/* Sense data length */
X	u_char	medium_type;
X	u_char	dev_spec;
X	u_char	unused[2];
X	u_char	blk_desc_len[2];
X};
X
X
X/*
X * Status Byte
X */
X#define	SCSI_OK		0x00
X#define	SCSI_CHECK		0x02
X#define	SCSI_BUSY		0x08	
X#define SCSI_INTERM		0x10
END-of-scsi/scsi_all.h
exit