BETA ST-01 scsi driver(p1 of 3)

Michael Grenier mike at cimcor.mn.org
Wed Jan 2 12:05:42 AEST 1991


#!/bin/sh
# This is st01, a shell archive (shar 3.32)
# made 01/02/1991 01:03 UTC by mike at cimcor
# Source directory /usr/mike/scsi1
#
# existing files WILL be overwritten
#
# This is part 1 of a multipart archive                                    
# do not concatenate these parts, unpack them in order with /bin/sh        
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   3681 -rw-r--r-- DIAGRAM
#    441 -rw-r--r-- Makefile
#     35 -rw-r--r-- Master
#    156 -rw-r--r-- Node
#    588 -rw-r--r-- Node.scsi
#   7397 -rw-r--r-- README
#   1567 -rw-r--r-- README1
#     31 -rw-r--r-- Sdevice.scsi
#     31 -rw-r--r-- System
#   1693 -rw-r--r-- mdevice
#     36 -rw-r--r-- mdevice.scsi
#    682 -rw-r--r-- scommands.h
#  50082 -rw-r--r-- scsi.c
#    805 -rw-r--r-- scsiasm.s
#   7896 -rw-r--r-- scsipart.c
#   2074 -rw-r--r-- sdevice
#   2929 -rw-r--r-- st01.h
#   3950 -rw-r--r-- verify.c
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
if test -r shar3_seq_.tmp; then
	echo "Must unpack archives in sequence!"
	next=`cat shar3_seq_.tmp`; echo "Please unpack part $next next"
	exit 1
fi
# ============= DIAGRAM ==============
echo "x - extracting DIAGRAM (Text)"
sed 's/^X//' << 'SHAR_EOF' > DIAGRAM &&
XPath: tarpit!rtmvax!peora!ge-dab!crdgw1!uunet!mcvax!kth!draken!tut!santra!ylo
XFrom: ylo at sauna.HUT.FI (Tatu Yl|nen)
XNewsgroups: comp.unix.microport,comp.unix.i386
XSubject: ST-01 SCSI controller jumper settings
XMessage-ID: <YLO.89Jul1235859 at sauna.HUT.FI>
XDate: 1 Jul 89 20:58:59 GMT
XSender: news at santra.UUCP
XOrganization: Helsinki University of Technology, Finland
XLines: 78
XXref: tarpit comp.unix.microport:1513 comp.unix.i386:1159
X
X
Xumbc3!tron!beser at uunet.uu.net was asking about the jumpers on the ST-01
Xcontroller.  I will post my answer to comp.unix.microport, as this
Xmay be of interest to others as well.
X
X----------
X
XHere is a picture of the card.
X
X  +--------------------------------------------+
X  I   ::::::::::::::::::::::::::::::::::::     I +--
X  I     (50-pin scsi connector)                I I
X  I                                         +----I
X  I                                         +----I
X  I   +----+                 +--+              I I  (mounting bracket)
X  I   I    I    +-----+      I  I              I I
X  I   I    I    I     I      I  I              I I
X  I   I    I    I     I      I  I              I I
X  I   +----+    +-----+      +--+              I I
X  I                                            I I
X  I      E  F           A  B                   I I
X  I       ..             ..    .            +----I
X  I        .             ..    . (0ws)      +----I
X  I         G           C  D                   I I
X  +-+  (intr en. jumpers) (bios addr j.)   +---+ I
X    I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII I     I
X    +--------------------------------------+     I
X             (edge connector)                    I
X
XMemory address
X
Xno jumpers installed       CA000H  (default setting)
Xpins C-D shorted           C8000H
Xpins A-B shorted           CE000H
Xpins A-B & C-D shorted     DE000H
X
XThe memory address set on the card must match the value defined in the driver.
XCheck the driver source for the correct address.  If you want to use a
Xdifferent address, change the define in the source.
X
X
XInterrupt selection
X
XNo jumper installed       interrupts disabled (default configuration)
XE-F shorted               IRQ3
XF-G shorted               IRQ5
X
XInterrupts must be enabled to use my driver under unix.  The interrupt
Xselected must match the value in file "config" in the modules/scsi
Xdirectory.  Check the config file for the correct value; change the value
Xin config file if you wish to use some other value.
X
XNOTE: at least in the card I received, there were no jumper connectors
Xin E, F and G.  There were just holes in the card.  You have to solder the
Xconnection yourself.  It is not a difficult task if you have ever done
Xany soldering, and luckily the card does not cost very much if something
Xgoes wrong...  It is better to ground the soldering iron before doing 
Xanything.
X
XIf I recall correctly, I am using IRQ5, and soldered F&G together with a
Xshort wire.  A friend of mine had both of those interrupts in use,
Xand soldered F to some other interrupt number on the bus and everything
Xworks fine.  However, I can't help with that.  For more info, see
XIBM AT technical manual.  (You might get some help by sending mail to
Xjnopanen at hupu.hut.fi).
X
XIt seems like Seagate has been thinking that the controller would never
Xbe used with unix...
X
X
XI think the 0ws jumper should be connected on most (almost every?)
Xmachines.  On my machine it raised the transfer rate from about 500kB/sec
Xto about 700kB/sec under msdos.  The transfer rate is really cpu-bound
Xas the data transfers are done in software (the card does not support
Xdma), so faster machines might get faster transfer rates (mine is a slow
X16 MHz 386).
X
X  Tatu Yl|nen    ylo at hupu.hut.fi
SHAR_EOF
$TOUCH -am 1027195290 DIAGRAM &&
chmod 0644 DIAGRAM ||
echo "restore of DIAGRAM failed"
set `wc -c DIAGRAM`;Wc_c=$1
if test "$Wc_c" != "3681"; then
	echo original size 3681, current size $Wc_c
fi
# ============= Makefile ==============
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
X#
X# makefile for scsi driver
X#
X# Copyright (c) 8.6.1988 Tatu Yl|nen
X#               All rights reserved.
X#
X#
X
XCFLAGS = -O #-DDEBUG # -DDEBUG0
X
Xall: scsi.o scsiasm.o scsipart verify
X	ld -r -o Driver.o scsi.o scsiasm.o
X
Xverify : verify.c st01.h 
X	$(CC) $(CFLAGS) -o verify verify.c
X	
Xscsi.o: scsi.c st01.h
X
Xscsiasm.o: scsiasm.s
X
Xscsipart: scsipart.c st01.h
X	$(CC) $(CFLAGS) -o scsipart -s scsipart.c
X
Xclean:
X	rm -f *.o scsipart core verify *~
SHAR_EOF
$TOUCH -am 0101185891 Makefile &&
chmod 0644 Makefile ||
echo "restore of Makefile failed"
set `wc -c Makefile`;Wc_c=$1
if test "$Wc_c" != "441"; then
	echo original size 441, current size $Wc_c
fi
# ============= Master ==============
echo "x - extracting Master (Text)"
sed 's/^X//' << 'SHAR_EOF' > Master &&
Xscsi	Iiocrw	ibHc		scsi	0	0	1	15	-1
SHAR_EOF
$TOUCH -am 1027225890 Master &&
chmod 0644 Master ||
echo "restore of Master failed"
set `wc -c Master`;Wc_c=$1
if test "$Wc_c" != "35"; then
	echo original size 35, current size $Wc_c
fi
# ============= Node ==============
echo "x - extracting Node (Text)"
sed 's/^X//' << 'SHAR_EOF' > Node &&
Xscsi	scsi0s0	b	0
Xscsi	scsi0s1	b	1
Xscsi	scsi0s2	b	2
Xscsi	scsi0s3	b	3
Xscsi	scsi0s4	b	4
Xscsi	scsi0s5	b	5
Xscsi	rscsi0s	c	15
Xscsi	rscsi0s0	c	0
Xscsi	rscsi0s1	c	1
SHAR_EOF
$TOUCH -am 1227044490 Node &&
chmod 0644 Node ||
echo "restore of Node failed"
set `wc -c Node`;Wc_c=$1
if test "$Wc_c" != "156"; then
	echo original size 156, current size $Wc_c
fi
# ============= Node.scsi ==============
echo "x - extracting Node.scsi (Text)"
sed 's/^X//' << 'SHAR_EOF' > Node.scsi &&
Xscsi	dsk/2s0		b	0
Xscsi	dsk/2s1		b	1
Xscsi	dsk/2s2		b	2
Xscsi	dsk/2s3		b	3
Xscsi	dsk/2s4		b	4
Xscsi	dsk/2s5		b	5
Xscsi	dsk/2s6		b	6
Xscsi	dsk/2s7		b	7
Xscsi	dsk/2s8		b	8
Xscsi	dsk/2s9		b	9
Xscsi	dsk/2sa		b	10
Xscsi	dsk/2sb		b	11
Xscsi	dsk/2sc		b	12
Xscsi	dsk/2sd		b	13
Xscsi	dsk/2se		b	14
Xscsi	dsk/2sf		b	15
Xscsi	rdsk/2s0	c	0
Xscsi	rdsk/2s1	c	1
Xscsi	rdsk/2s2	c	2
Xscsi	rdsk/2s3	c	3
Xscsi	rdsk/2s4	c	4
Xscsi	rdsk/2s5	c	5
Xscsi	rdsk/2s6	c	6
Xscsi	rdsk/2s7	c	7
Xscsi	rdsk/2s8	c	8
Xscsi	rdsk/2s9	c	9
Xscsi	rdsk/2sa	c	10
Xscsi	rdsk/2sb	c	11
Xscsi	rdsk/2sc	c	12
Xscsi	rdsk/2sd	c	13
Xscsi	rdsk/2se	c	14
Xscsi	rdsk/2sf	c	15
SHAR_EOF
$TOUCH -am 1027195390 Node.scsi &&
chmod 0644 Node.scsi ||
echo "restore of Node.scsi failed"
set `wc -c Node.scsi`;Wc_c=$1
if test "$Wc_c" != "588"; then
	echo original size 588, current size $Wc_c
fi
# ============= README ==============
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
XReadme for ST-01 SCSI driver for microport unix system V
X
X
XCopyright (c) 13.6.1989 Tatu Ylonen
X
X
XI hereby allow use and distribution of this device driver, provided
Xthat no charge is asked for it.
X
X
XThis is an SCSI device driver for Microport Unix System V/386 with
XSeagate ST-01 SCSI adaptor.  (This probably works with other 386 unix
Xas well, but has not been tested).
X
XThis driver offers the following features
X  - can use almost any scsi disks
X  - no limit on disk or partition size
X  - each physical drive can partitioned in upto 15 partitions
X  - supports multiple drives (up to 7) on a single controller
X  - transfer rate four to six times that of the standard MFM disk
X    driver supplied by microport
X
XThe following drawbacks are known
X  - does not use dma, as the controller does not support dma
X  - character devices (raw io) do not work
X  - this is a disk driver only.  SCSI tapes have not been tested.
X  - you cannot boot from the scsi drive (I do not have boot source
X    code)
X  - lots of data movement is done at interrupt time (although this
X    tries to enable higher priority interrupts, like the serial ports)
X
XI have used this for about an year with a Priam 738 (337 megabytes
Xformatted, 20 ms) drive.  Others have used this with Seagate ST227N
Xdrives (64 megabytes).  I have had no problems with the driver (I have
Xnever (after the initial creation of the driver) had a panic that I
Xcould have associated with the driver (and only a couple of panics
Xaltogether)).  The drive has been partitioned to three partitions:
X10MB, 20MB and 307 MB.  (I have never had any problems with large
Xpartitions).  I archieved the best performance when using 1024 byte
Xsectors on the disk.  The ST227N drive had some problems with 1024
Xbyte sectors (the machine rebooting randomly during heavy disk
Xaccesses); I have never had these problems with the Priam disk, and
Xthe Seagate drives appear to work ok with 512 byte sectors.
X
XThe driver works with Dosmerge without any problems.
X
X
XINSTALLATION
X
X(Assuming you have installed the st01 adaptor).
X(BTW, I removed the bios rom on the controller.  It does not work with
Xall drives.  Also, the machine boots faster.  This driver does not
Xneed the rom and will wait for the drives to become ready if needed)
X
X1. Create the directory /etc/atconf/modules/scsi, and copy all files to
X   that directory.
X
X2. Check the config file for correct parameters (major device number,
X   interrupt number).  Major device number and the interrupt number
X   should both be exclusively used for the scsi driver.  (I have heard
X   that some optional driver conflicts with the default major number
X   here, 9)
X
X3. Type make.
X
X4. Add the line 'scsi,' in your system file (usually
X   /etc/atconf/systems/system.std).  Remember to back up your old system
X   file first.  Type mkunix (being logged in as root).
X
X5. Back up your old /unix (move to, say, /unix.old, so that you can
X   boot it if something goes wrong).
X
X6. Bring the system down (init 0).
X
X7. Connect the scsi drive(s).  You will need the appropriate cables.
X   Remember to have terminators in the last drive (if you have only
X   one drive, you need to do nothing, as the terminators are probably
X   connected by default).
X
X8. Reboot.  While booting, you should see a copyright message from the
X   driver, and a message identifying the manufacturer of the drive.
X   The message contains drive number and a manufacturer-specified text
X   (usually drive model).  If the drive has been partitioned, the
X   sizes of the partitions will also be shown.
X
X   If you get repeated messages "someone is sitting on the bus,
X   sending hard reset to scsi bus" (or something like that), it
X   probably means that the drive is not powered on (or that something
X   else is wrong with the connections).
X
X   If you get scsi timeouts when trying to use the disk (at a later
X   time, after formatting), it probably means that the interrupt
X   number is not set correctly.  Check config file and jumpers on the
X   card.
X
X9. Create device i-nodes for the scsi disk.
X   I have the following i-nodes.  Here 9 is the major device number
X   (must match that in config file).  The minor device contains the
X   partition number in the lower four bits, and disk number in the
X   upper four bits.  Partition number 15 is reserved (contains the
X   entire disk, including the partition table).
X
X   The devices /dev/rscsi<drive>s and /dev/scsi<drive>s are mandatory.
X   In addition, you can create as many i-nodes for partitions as you
X   wish.
X
X   Here is a list of scsi-related i-nodes on my system.
X   
Xcrw-------   1 root     sys        9, 15 Apr 22 03:13 /dev/rscsi0s
Xbrw-------   1 root     sys        9, 15 Jan 14 06:01 /dev/scsi0s
Xbrw-------   1 root     sys        9,  0 Jun 13 18:08 /dev/scsi0s0
Xbrw-------   1 root     sys        9,  1 Jun 13 18:08 /dev/scsi0s1
Xbrw-------   1 root     sys        9,  2 Jun 13 18:08 /dev/scsi0s2
X
X10. Run scsipart.  The program asks for drive number.  Enter 0 (or the
X    number of your drive).  When the program asks whether to format,
X    answer yes, and confirm.  Formatting the Priam 337 megabyte disk
X    takes about half an hour.  In that time the driver does not print
X    anything.
X
X    You cannot specify your own defects.  The scsi drive will
X    automatically use all manufacturer-supplied defects, plus those
X    found during formatting.  (The scsi interface supports automatic
X    remapping of bad blocks even after formatting, but the driver does
X    not support this.)
X
X    When formatting is complete, the number of available disk sectors
X    is printed.
X
X    You can now define the partitions.  Note that partitions are
X    defined in sectors, while filesystems for mkfs are specified in
X    1024 byte blocks.  Thus, if you have 512 byte sectors, the lengths
X    of partitions should be twice the number of blocks.  The block 0
X    contains the partition table and cannot be used.  Otherwise, you
X    can freely create the partitions as you wish.  The first partition
X    in the table is number 0, the second number 1 and so on.
X
X    The partitions become valid when you exit scsipart.
X
X    I recommend that you try with several different interleave values
X    for optimal performance.  I got acceptable performance with 1024
X    byte sectors (use them if they work) and interleave 9 (sic).  That
X    was with an early version; the data transfer routines have been
X    optimized quite a bit since then (see the assembler hacks).
X
X11. Create file systems on the partitions.  See mkfs(1M).  Remeber to
X    give the correct block size.  Specify that mkfs leave no
X    interleave (so it is easier to specify the interleave when
X    formatting).
X
X12. Add the partitions to /etc/fstab.  My fstab looks like
X
X/dev/scsi0s0 /tmp
X/dev/scsi0s1 /u2
X/dev/scsi0s2 /u
X
X13.  Reboot.  The partitions should now get mounted and the system be
Xready for use.  (Check /etc/rc2.d if they do not get mounted).  You
Xcan label the file systems (see labelfs(1M) if you don't want to see
Xthe messages from mount.
X
X
XYou can use the file systems just like any other file systems.  All
Xnormal utilities work (except of course things like mkpart etc).  Fsck
Xand others work ok.
X
X----------------
X
XI can give only very limited support to anyone using this.  However,
XI can be reached as
X
X   ylo at hupu.hut.fi
X
Xor my normal mail
X
X  Tatu Ylonen
X  Tunnelitie 14 c 13
X  00320 HELSINKI
X  Finland
X
X  Tel. +358-0-573290
X
SHAR_EOF
$TOUCH -am 1027195290 README &&
chmod 0644 README ||
echo "restore of README failed"
set `wc -c README`;Wc_c=$1
if test "$Wc_c" != "7397"; then
	echo original size 7397, current size $Wc_c
fi
# ============= README1 ==============
echo "x - extracting README1 (Text)"
sed 's/^X//' << 'SHAR_EOF' > README1 &&
XThis version of the ST-01 driver has been somewhat updated
Xand includes support for raw devices...
X
X   mknod /dev/rscsi0s0 c major 0 
X
Xfor the first partition and so forth. The last partition (15)
Xis still reserved for the full disk.
X
XAlso new to this release is some basic bad block management.
XThis is done using the verify command which in turn uses
Xthe SCSI Reassign command.
X
XKnown remaining problems include :
X
X  - No automatic way to reassign blocks in the driver when failure
X    is detected. Normally this is not a problem since drives like
X    the CDC/Imprimis/Seagate Wren series will reassign blocks for
X    you when a bad write or a recoverable read has been detected.
X
X  - Do not kill you program during a raw read or write (or any of
X    the ioctls for that matter) since it may leave the drive
X    working on the command but confused when it tries to reconnect.
X    Eventually, the sleep commands will have to be at a priority
X    less than PZERO once the timeout logic is fully verified.
X
X  - No more than one process should attempt to use the raw device
X    for a given unit at a time...this is due to the sleeps on
X    d[unit].connected (see the source). Each process should sleep
X    on its buffer or something unique.
X
X
XMajor problems ? send email to mike at cimcor.mn.org
X            or                 mike at sp.unisys.com
X
X
XOther notes:
X
XScsi problems are logged to the streams error logger (see strerr(1))
X
XSome tracing is available using strace(1)
X
XMany of the hd(7) ioctls are now supported including support
Xfor the ESIX/BSD fast file system.
X
SHAR_EOF
$TOUCH -am 0101185191 README1 &&
chmod 0644 README1 ||
echo "restore of README1 failed"
set `wc -c README1`;Wc_c=$1
if test "$Wc_c" != "1567"; then
	echo original size 1567, current size $Wc_c
fi
# ============= Sdevice.scsi ==============
echo "x - extracting Sdevice.scsi (Text)"
sed 's/^X//' << 'SHAR_EOF' > Sdevice.scsi &&
Xscsi	Y	1	5	1	5	0	0	df000	e0000
SHAR_EOF
$TOUCH -am 1027195490 Sdevice.scsi &&
chmod 0644 Sdevice.scsi ||
echo "restore of Sdevice.scsi failed"
set `wc -c Sdevice.scsi`;Wc_c=$1
if test "$Wc_c" != "31"; then
	echo original size 31, current size $Wc_c
fi
# ============= System ==============
echo "x - extracting System (Text)"
sed 's/^X//' << 'SHAR_EOF' > System &&
Xscsi	Y	1	5	1	5	0	0	df000	e0000
SHAR_EOF
$TOUCH -am 1027225690 System &&
chmod 0644 System ||
echo "restore of System failed"
set `wc -c System`;Wc_c=$1
if test "$Wc_c" != "31"; then
	echo original size 31, current size $Wc_c
fi
# ============= mdevice ==============
echo "x - extracting mdevice (Text)"
sed 's/^X//' << 'SHAR_EOF' > mdevice &&
Xdu	-	io	du	0	0	1	1	-1
Xfp	-	iHor	fp	0	0	0	1	-1
Xgentty	orwi	icor	sy	0	16	1	1	-1
Xipc	-	io	ipc	0	0	0	1	-1
Xmem	rw	irsco	mm	0	2	1	1	-1
Xmsg	-	io	msg	0	0	0	1	-1
Xosm	orw	ico	osm	0	17	1	1	-1
Xprf	rwi	icor	prf	0	6	1	1	-1
Xs52k	-	ios	s52k	0	0	0	1	-1
Xsem	-	io	sem	0	0	0	1	-1
Xshm	-	io	shm	0	0	0	1	-1
Xsxt	ocrwi	irco	sxt	0	14	1	32	-1
Xxt	Iocrwi	icor	xt	0	13	1	4	-1
Xcpyrt	s	io	cpyrt	0	0	0	1	-1
Xweitek	-	io	weit	0	0	0	1	-1
Xvx	-	ior	vx	0	0	1	1	-1
Xffs	-	ios	ffs	0	0	0	1	-1
Xasy	Iocrwi	iHct	asy	0	3	1	2	-1
Xcmos	Iocrwi	icrH	cmos	0	8	1	1	-1
Xfd	Iocrwi	iHrbc	fd	1	1	1	2	2
Xhd	-	iHro	hd	0	0	1	2	-1
Xkd	Iocrwi	iHrcst	kd	0	5	1	1	-1
Xlp	Iocrwi	icH	lp	0	7	1	3	-1
X* Pseudo Terminal Slave Side             
Xptyp	ocrwiI	ioctG	ptyp	0	51	1	1	-1
X* Pseudo Terminal Master Side             
Xptcp	-	iocSG	ptcp	0	50	1	1	-1	
Xnmi	I	ios	nmi_	0	0	0	1	-1
Xramd	Iocrwi	iobc	ramd	15	15	1	2	-1
Xxsd	-	io	xsd	0	0	0	1	-1
Xxsem	-	io	xsem	0	0	0	1	-1
Xaha	I	iH	aha	0	0	1	3	5
Xschd	-	iGro	schd	0	0	1	2	-1
Xechd	Iocrwi	iGrobc	echd	0	0	0	1	-1
Xscmt	ocrwiI	icroG		scmt	29	29	1	1	-1
Xfha	I	ioH	fha	0	0	1	2	-1
Xecha	ociI	iGco	echa	0	10	0	1	-1
Xclone	-	Scio		cln	0	4	1	1	-1
Xlog	-	Scio		log	0	9	1	1	-1
Xtimod	-	Si		tim	0	0	1	4	-1
Xtirdwr	-	Si		trw	0	0	1	8	-1
Xldterm	-	Si		ldtr	0	0	1	32	-1
Xptem	-	Si		ptem	0	0	1	32	-1
Xptm	-	Scio		ptm	0	11	1	32	-1
Xpts	-	Scio		pts	0	12	1	1	-1
Xiplan	ocrw	iSG		iplan	0	0	1	1	-1
Xpln	oc	iSGc		pln	0	18	1	2	-1
Xippln	ocrw	iSG		ippln	0	0	1	1	-1
Xslip	ocrw	iSG		slip	0	0	1	1	-1
Xsl	Ioci	iHcS		sl	0	19	1	2	-1
Xip	Ioc	iSGc		ip	0	20	1	1	-1
Xtcp	ocrw	iSG		tcp	0	0	1	1	-1
Xudp	ocrw	iSG		udp	0	0	1	1	-1
Xmux	Ioc	iSGc		mux	0	21	1	1	-1
Xudpm	oc	iSGc		udpm	0	22	1	1	-1
Xxkb	oc	icGHo		xkb	0	23	1	1	-1
Xxms	ociI	icHo		xms	0	24	1	1	-1
Xscsi	Iiocrw	ibHc		scsi	2	25	1	15	-1
SHAR_EOF
$TOUCH -am 1027195590 mdevice &&
chmod 0644 mdevice ||
echo "restore of mdevice failed"
set `wc -c mdevice`;Wc_c=$1
if test "$Wc_c" != "1693"; then
	echo original size 1693, current size $Wc_c
fi
# ============= mdevice.scsi ==============
echo "x - extracting mdevice.scsi (Text)"
sed 's/^X//' << 'SHAR_EOF' > mdevice.scsi &&
Xscsi	Iiocrw	ibHc		scsi	2	25	1	15	-1
SHAR_EOF
$TOUCH -am 1027195290 mdevice.scsi &&
chmod 0644 mdevice.scsi ||
echo "restore of mdevice.scsi failed"
set `wc -c mdevice.scsi`;Wc_c=$1
if test "$Wc_c" != "36"; then
	echo original size 36, current size $Wc_c
fi
# ============= scommands.h ==============
echo "x - extracting scommands.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > scommands.h &&
X/*
X   Simple table for scsi diagnostics 
X*/
X
X#define NSCOMM 48
Xstatic char *scommands[NSCOMM] = 
X{ 
X   "Test Unit Ready",
X   "Rezero Unit",
X   "",
X   "Request Sense",
X   "Format Unit",
X   "",
X   "",
X   "Reassign Blocks",
X   "Read",
X   "",
X   "Write",
X   "Seek",
X   "",
X   "",
X   "",
X   "",
X   "",
X   "",
X   "Inquiry",
X   "",
X   "",
X   "Mode Select",
X   "**Reserved**",
X   "Release",
X   "Copy",
X   "",
X   "Mode Sense",
X   "Start/Stop Unit",
X   "",  /* 28 or 0x1c */
X   "",
X   "",
X   "",
X   "",  /* 0x20 */
X   "",  /* 0x21 */
X   "",
X   "", 
X   "",
X   "Read Capacity", /* 0x25 */
X   "",
X   "",
X   "Read", /* 0x28 */
X   "",
X   "Write",
X   "Seek",
X   "",
X   "",
X   "Write and Verify"
X};
SHAR_EOF
$TOUCH -am 1227040190 scommands.h &&
chmod 0644 scommands.h ||
echo "restore of scommands.h failed"
set `wc -c scommands.h`;Wc_c=$1
if test "$Wc_c" != "682"; then
	echo original size 682, current size $Wc_c
fi
# ============= scsi.c ==============
echo "x - extracting scsi.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > scsi.c &&
X/*
X
XSCSI disk driver for unix system V (Microport system V/386)
XThis driver uses the ST-01 controller.  This supports multiple initiators
Xand multiple targets.
X
XCopyright (c) 9.6.1988 Tatu Yl|nen
X              All rights reserved.
X
XHeavily modified by Mike Grenier (mike at cimcor.mn.org)
X*/
X
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/param.h>
X#include <sys/signal.h>
X#include <sys/errno.h>
X#include <sys/dir.h>
X#include <sys/file.h>
X#include <sys/user.h>
X#include <sys/buf.h>
X#include <sys/iobuf.h>
X#include <sys/immu.h>
X#include <sys/region.h>
X#include <sys/proc.h>
X#include <sys/strlog.h>
X#include <sys/vtoc.h>
X#include "st01.h"
X#include "scommands.h"
X#define COPYRIGHT "scsi disk driver V2.0"
X
X#define ASM   /* use certain routines coded in assembly */
X
X#define TICKSPERSECOND HZ /* system timer ticks per second */
X#define RWTIMEOUT       10  /* timeouts for read/write waiting for reconnect */
X                            /* in seconds                                    */
X#define MYSLEEPPRI      (PZERO+1) /* sleeping priority (allow signals) */
X#define PAGESIZE     4096 /* page size in sptalloc */
X
X#define UNITNO(minornum) ((minornum)>>4) /* minor device to unit */
X#define PARTNO(minornum) ((minornum)&15) /* minor device to partition */
X#define BLTOSEC(unit,bl) ((long)(bl)*NBPSCTR/d[unit].blocksize)
X                                 /* converts block number to sector number */
X#define BLPTOSEC(unit,part,bl) (BLTOSEC(unit,bl)+d[unit].parts[part].start)
X                        /* calculates sector number from block and partition */
X
X#define splnointrs() spl6() /* disable any interrupts to this driver (clock!)*/
X
X#define NULL 0
X
X#define SCSIBASE        0x00df000l /* address of the scsi controller(no rom)*/
X#define SCSICONTROLOFS  0x00000a00l /* control/status port offset */
X#define SCSIDATAOFS     0x00000c00l /* data port offset */
X#define SCSIDATAPORTSZ  1024        /* size of data port */
X#define SCSISIZE        4096        /* size of controller memory area */
X
X#define MYADDR          0x80        /* my address as bit mask */
X
X#define CMDENABLE       0x80        /* scsi enable */
X#define CMDENINTR       0x40        /* enable scsi interrupts */
X#define CMDPARENB       0x20        /* enable scsi parity generation */
X#define CMDSTARB        0x10        /* start arbitration bit */
X#define CMDATTN         0x08        /* scsi attention */
X#define CMDBSY          0x04        /* scsi busy */
X#define CMDSEL          0x02        /* scsi select */
X#define CMDRST          0x01        /* scsi reset */
X
X#define STARBCOMPL      0x80        /* arbitration complete bit */
X#define STPARERR        0x40        /* parity error bit */
X#define STSEL           0x20        /* scsi select */
X#define STREQ           0x10        /* scsi req */
X#define STCD            0x08        /* scsi c/d */
X#define STIO            0x04        /* scsi i/o */
X#define STMSG           0x02        /* scsi msg */
X#define STBSY           0x01        /* scsi busy */
X
X#define CMDBASE         (CMDPARENB|CMDENINTR) /* cmd when doing nothing */
X
X#define SCSIREAD        0x28        /* read command code (10-byte) */
X#define SCSIWRITE       0x2a        /* write command code (10-byte) */
X#define SCSIREASSIGN    0x07        /* Reassign blocks (6-byte */
X#define SCSIINQUIRY     0x12        /* inquiry command (6-byte) */
X#define SCSIREADCAPACITY 0x25       /* read drive capacity and block size */
X#define SCSIMODESELECT  0x15        /* select format parameters */
X#define SCSIFORMATUNIT  0x04        /* hard format the scsi drive */
X#define SCSIREQSENSE    0x03        /* request sense command */
X#define SCSITESTREADY   0x00        /* test unit ready command */
X
X#define MSGMYIDENTIFY   0xc0        /* our identify message to send to target */
X
X#define MSGCOMPLETE     0x00        /* command complete */
X#define MSGSAVEDATAPTR  0x02        /* save data pointer */
X#define MSGRESTOREPTR   0x03        /* restore pointer */
X#define MSGDISCONNECT   0x04        /* disconnect message */
X#define MSGIDETECTERR   0x05        /* initiator detected error */
X#define MSGABORT        0x06        /* scsi abort message */
X#define MSGMSGREJECT    0x07        /* message reject */
X#define MSGNOP          0x08        /* no operation message */
X#define MSGIDENTIFY     0x80        /* identify message from target */
X
X#define COK             0 /* command completed successfully */
X#define CNOCONNECT      1 /* no connection could be made to the drive */
X#define CBUSBUSY        2 /* the bus is busy and cannot be cleared */
X#define CTIMEOUT        3 /* timeout waiting for the drive */
X#define CERROR          4 /* an error was returned by the target */
X#define CBUSY           5 /* the drive is busy - wait and retry later */
X#define CDISCONNECT     6 /* target disconnected; this is not an error */
X
Xstatic char *baseaddr=NULL; /* controller base address */
Xstatic char *cmdport;  /* controller command port */
Xchar *scsidataport; /* controller data port */
X
Xstatic SCSIDRIVE d[SCSIMAXDRIVES]; /* drive information */
X
Xstatic char rawiobuf[SCSIDATAPORTSZ]; /* data copied temporarily here */
X
Xstatic char timeouting=0;
Xstatic char intrserviced=0;
X
Xstatic marknotbusy(); /* marks the unit as not busy and starts any pending io */
X
X/* This routine prints out the currently executing command */
Xstatic print_current_command(unit)
Xint unit;
X{
X  printf("scsi: Unit %d Current command is %d : %s\n   start block %d, nblocks %d\n",
X  unit,
X  d[unit].scsicmd, 
X  d[unit].scsicmd > NSCOMM ? "**UNKNOWN**" : scommands[d[unit].scsicmd], 
X  d[unit].logical_block, 
X  d[unit].num_blocks);
X
X}
X
X/* This routine prints out the status indicator for debugging */
X
Xstatic print_status(unit, code)
Xint unit, code;
X{
X  static char *errtbl[] = { "Good", "Check Condition", "Condition Met/Good",
X                     "Reserved", "Target already Busy", "Reserved",
X                     "Reserved", "Reserved", "Linked Cmd - Intermediate Good",
X                     "Reserved", "Intermediate/Condition Good", 
X                     "Reserved", "Reservation Conflict", "Reserved",
X                     "Reserved", "Reserved" };
X
X   strlog(0, unit, 0, SL_ERROR, "\nScsi status on unit %d is %x : %s\n",
X            unit, code, errtbl[ (code >> 1) & 0xf]);
X   print_current_command(unit);
X}
X
X
X
X/* This generates a hard reset on the scsi bus by asserting the reset line */
X
Xstatic resetscsibus()
X{
X  long l;
X  int a;
X
X  printf("scsi: sending hard reset to scsi bus\n");
X  *cmdport=CMDBASE|CMDENABLE|CMDRST;
X  for (l=0;l<10000l;l++); /* keep rst asserted for a while */
X  *cmdport=CMDBASE;
X  for (l=0;l<500000l;l++); /* give some time to recover before returning */
X  for (a=0;a<SCSIMAXDRIVES;a++)
X    d[a].connected=0; /* do this just in case */
X}
X
X/* This arbitrates for the scsi bus and selects the desired target.  This
X   returns a C* result code.  This will also set the connected flag
X   if appropriate.  If there are possibly recoverable errors, this will
X   retry.  The calling procedure should not retry if this returns
X   failure. */
X
Xstatic int arbitrate(unit)
Xint unit;
X{
X  long l;
X  int arbcnt,bsycnt; /* retry counts */
X
X  arbcnt=0;
X  bsycnt=0;
X retryarb:
X  *cmdport=CMDBASE;
X  *scsidataport=MYADDR;
X  *cmdport=(CMDBASE&~CMDENINTR)|CMDSTARB;
X  /* wait for arbitration complete */
X  for (l=0;l<300000l;l++)
X    if (*cmdport & STARBCOMPL)
X      goto gotarb;
X  /* arbitration timeout - someone is keeping the bus reserved. */
X  *cmdport=CMDBASE;
X  if (arbcnt >= 2) /* retry twice, then give up */
X    {
X      strlog(0, unit, 0, SL_ERROR, "scsi: arbitration timeout - someone is sitting on the bus?\n");
X      return CBUSBUSY;
X    }
X  resetscsibus(); /* reset the bus and hope the condition clears */
X  arbcnt++;
X  goto retryarb;
X gotarb:
X  arbcnt=0;
X  *scsidataport|=1<<unit;
X  *cmdport=CMDBASE|CMDENABLE|CMDSEL|CMDATTN;
X  for (l=0;l<200000l;l++)
X    if (*cmdport & STBSY)
X      goto gotbusy;
X  /* timeout waiting for busy */
X  *cmdport=CMDBASE;
X  if (bsycnt >= 2)
X    {
X#ifdef DEBUG0
X      strlog(0, unit, 0, SL_ERROR, "scsi: arbitrate returning CNOCONNECT\n");
X#endif
X      return CNOCONNECT; /* probably no drive present */
X    }
X  bsycnt++;
X  for (l=0;l<2000l;l++); /* give some time for the drive */
X#ifdef DEBUG0
X  strlog(0, unit, 0, SL_ERROR, "scsi: busy timeout on drive %d\n",unit);
X#endif
X  goto retryarb;
X gotbusy:
X  d[unit].connected=1;
X  if (!d[unit].nomsgs)
X    {
X      *cmdport=CMDBASE|CMDENABLE|CMDATTN;
X      for (l=0;l<200000l;l++)
X        if ((*cmdport & (STMSG|STCD|STIO|STREQ)) == (STMSG|STCD|0|STREQ))
X          goto gotmsgreq;
X      /* timeout waiting for msg out */
X      strlog(0, unit, 0, SL_ERROR, "scsi: timeout identify msg out - drive %d does not support messages?\n",
X             unit);
X      d[unit].nomsgs=1; /* don't try messages again */
X      *cmdport=CMDBASE|CMDENABLE;
X      return COK;
X     gotmsgreq:
X      *scsidataport=MSGMYIDENTIFY; /* this enables disconnect */
X      /* fall to successful completion */
X    }
X#ifdef DEBUG
X  if (!(*cmdport & STBSY))
X    {
X      strlog(0, unit, 0, SL_ERROR, "scsi: after successful arbitrate !STBSY\n");
X      for (l=0;l<10000000l;l++);
X      arbcnt++;
X      goto retryarb;
X    }
X#endif /* DEBUG */
X  *cmdport=CMDBASE|CMDENABLE;
X  return COK;
X}
X
X#ifndef ASM
X
X/* This copies data to the scsi data port as fast as possible.  This could
X   even be coded in assembly language for efficiency. */
X
Xstatic sendtoscsi(buf,len)
Xregister char *buf;
Xregister int len;
X{
X  while (len--)
X    *scsidataport=(*buf++);
X}
X
X/* This reads data from the scsi data port as fast as possible. */
X
Xstatic getfromscsi(buf,len)
Xregister char *buf;
Xregister int len;
X{
X  while (len--)
X    *buf++=(*scsidataport);
X}
X
X#endif /* ASM */
X
X/* This implements the scsi data out phase.  There are several operating
X   modes for this.  1) normal as fast as possible io 2) slow io where we
X   check req individually for each character 3) moving data directly from
X   user space. If en error is encountered (such as a protection fault when
X   moving data from user space), this will return 0.  Moving data from
X   user space is only implemented in "fast" mode. */
X
Xstatic int dataout(unit)
Xint unit;
X{
X  register int le;
X  register long l;
X  char slow;
X
X  slow=d[unit].xferslow;
X  for (;d[unit].xferlen > 0;d[unit].xferlen-=le,d[unit].xferbuf+=le)
X    {
X      for (l=0;l<100000l;l++)
X        if (*cmdport & STREQ)
X          goto gotreq;
X      /* timeout */
X      break;
X     gotreq:
X      if ((*cmdport & (STMSG|STCD|STIO)) != (0|0|0))
X        break;
X      if (slow)
X        {
X          le=1;
X          *scsidataport=(*d[unit].xferbuf);
X          continue;
X        }
X      le=d[unit].xferlen;
X      if (le > SCSIDATAPORTSZ)
X        le=SCSIDATAPORTSZ;
X      if (le > d[unit].blocksize)
X        le=d[unit].blocksize;
X      if (d[unit].xferphys)
X        {
X	  if (le > sizeof(rawiobuf))
X	    le=sizeof(rawiobuf);
X          if (copyin(d[unit].xferbuf,rawiobuf,le) == -1)
X            return 0;
X          sendtoscsi(rawiobuf,le);
X        }
X       else
X        sendtoscsi(d[unit].xferbuf,le);
X    }
X  while ((*cmdport & (STMSG|STCD|STIO|STREQ)) == (0|0|0|STREQ))
X    {
X      *scsidataport=0;
X      for (l=0;l<1000l;l++)
X        if (*cmdport & STREQ)
X          break;
X    }
X  return 1;
X}
X
X/* this implements the scsi data in phase.  This copies data from
X   scsi bus to system memory.  There are three modes of operation:
X   1) "slow" transfer to kernel memory 2) "fast" transfer to kernel
X   memory 3) "fast" transfer to user memory */
X
Xstatic int datain(unit)
Xint unit;
X{
X  register int le;
X  register long l;
X  char slow;
X
X  slow=d[unit].xferslow;
X  for (;d[unit].xferlen > 0;d[unit].xferlen-=le,d[unit].xferbuf+=le)
X    {
X      for (l=0;l<100000l;l++)
X        if (*cmdport & STREQ)
X          goto gotreq;
X      /* timeout */
X      break;
X     gotreq:
X      if ((*cmdport & (STMSG|STCD|STIO)) != (0|0|STIO))
X        break;
X      if (slow)
X        {
X          le=1;
X          *d[unit].xferbuf=(*scsidataport);
X          continue;
X        }
X      le=d[unit].xferlen;
X      if (le > SCSIDATAPORTSZ)
X        le=SCSIDATAPORTSZ;
X      if (le > d[unit].blocksize)
X        le=d[unit].blocksize;
SHAR_EOF
echo "End of st01 part 1"
echo "File scsi.c is continued in part 2"
echo "2" > shar3_seq_.tmp
exit 0



More information about the Comp.unix.sysv386 mailing list