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