news@bungi.com.ogi.edu (05/17/91)
I thought the attached message from 'comp.periphs.scsi' might be of interest given the recent discussion of Teac SCSI floppy drives. I found of particular interest the note at the end of the article mentioning the Sun Common SCSI Architecture mailing list and the availability of a Teac device driver. Best regards, johnc --------------------- attached message ---------------------- From: Harvey_Taylor@mindlink.bc.ca (Harvey Taylor) Newsgroups: comp.periphs.scsi Subject: Teac 235-JS info needed Message-ID: <5821@mindlink.bc.ca> Date: 11 May 91 16:24:15 GMT Organization: MIND LINK! - British Columbia, Canada Lines: 42 To: johnc Status: RO Well at long & dear last, my Teac Scsi Floppy arrived. It seems that I have a different version of the TEAC FDH-235JS SCSI floppy than the hardware spec (both JS & HS) . What I want to do is put it in auto density sense as mentioned in the SCSA driver Readme (see below). The problem is that there is a new row of shorting blocks which are undocumented. These are at the back beside the power connector & are labelled from front to back: AC AE IR RY D2 D1 D0 : The factory config was AE & D0 shorted. So, does anybody know the blocks to set for auto density sense mode on the 235JS? Does anybody know what all the blocks configure? There are the User settable blocks, as well: EJC J H G F LEV HDS STL : PAR, MON are the only two documented in the hardware specification. And finally, has anybody got a copy of the "FC-1-01 Software Specification" out of Teac? -het PS. Jonathan Hue maintains the SCSA mailing list. Here is a clip: |Re:The Sun Common SCSI Architecture mailing list. Send your subscription |request to scsa-request@island.com, submissions to scsa@island.com. There |are people there who can answer your questions. There's even a complete |SCSA driver in the archives to control a TEAC SCSI floppy. "DOS ... is still a real mode only non-reentrant interrupt handler, and always will be." - Russell William Harvey Taylor Meta Media Productions uunet!van-bc!rsoft!mindlink!Harvey_Taylor a186@mindlink.bc.ca -- John Connin: manatee Orlando, Florida UUCP: {uunet,ge-dab,ucf-cs}!tarpit!tous!manatee!johnc
swansonc@acc.stolaf.edu (Chris Swanson) (05/20/91)
>>>>> On 17 May 91 01:54:20 GMT, >>>>> in message <9105162154.AA00422@manatee.UUCP>, >>>>> news@bungi.com.mu.edu wrote: news> I thought the attached message from 'comp.periphs.scsi' might be news> of interest given the recent discussion of Teac SCSI floppy news> drives. I found of particular interest the note at the end of news> the article mentioning the Sun Common SCSI Architecture mailing news> list and the availability of a Teac device driver. news> Best regards, johnc news> --------------------- attached message ---------------------- news> From: Harvey_Taylor@mindlink.bc.ca (Harvey Taylor) Newsgroups: news> comp.periphs.scsi Subject: Teac 235-JS info needed Message-ID: news> <5821@mindlink.bc.ca> Date: 11 May 91 16:24:15 GMT Organization: news> MIND LINK! - British Columbia, Canada Lines: 42 To: johnc news> Status: RO news> Well at long & dear last, my Teac Scsi Floppy arrived. Greetings, Does anybody have a list of suppliers and prices for SCSI floppy drives? Thank's in advance, -=Chris P.S. Please reply via e-mail. I will post a follow-up if there is interest. -- Chris Swanson, Chem/CS/Pre-med Undergrad, St. Olaf College, Northfield,MN 55057 DDN: [CDS6] INTERNET: swansonc@acc.stolaf.edu UUCP: uunet!stolaf!swansonc AT&T: Work: (507)-645-4528 Home: (507)-663-6424 I would deny this reality, but that wouldn't pay the bills...
sverre@lars.Seri.GOV (Sverre Froyen) (05/20/91)
> It seems that I have a different version of the TEAC FDH-235JS SCSI > floppy than the hardware spec (both JS & HS) . What I want to do is > put it in auto density sense as mentioned in the SCSA driver Readme > (see below). Just so that nobody gets confused: TEAC FD-235HS-302 1.44MB / 720kB does NOT support auto density sense TEAC FD-235JS-501-U 2.88MB / 1.44MB / 720kB does support auto density sense (provided you get the 501-U) I have gotten the 235HS to work on the pc532 with minimal changes to scsi_hi.c. I have also compiled (calling it ported would be an overstatement) the mtools package which allows me to read and write MSDOS format diskettes. Sverre
news@bungi.com.mu.edu (05/21/91)
Attached is a copy of the Sun SCSA TEAC floppy driver mentioned in a previous posting. Best regards, johnc ================== Attachment ================== Subject: SCSA TEAC floppy driver This driver is a first version SCSA top-level floppy driver, but maybe elements are usable in other applications (I am working on porting VME bus and IEEE488 devices (via SCSI) from older SUN SCSI implementations to SCSA) Please report bugs, flames and suggestions to me (and/or the SCSA mailing list, many thanks to Jonathan Hue (hue@island.com) for creating this list !) and let me know if you are interested to receive updates. Fons Ullings fons@nat.vu.nl : This is a shar archive. Extract with sh, not csh. : This archive ends with exit, so do not worry about trailing junk. : --------------------------- cut here -------------------------- PATH=/bin:/usr/bin:/usr/ucb echo Extracting 'README' sed 's/^X//' > 'README' << '+ END-OF-FILE ''README' XDear SCSA developer, X X XThis is a >>first<< version of a SCSA floppy driver that makes it possible Xto use a TEAC embedded floppy drive (TEAC FD-235HS-300) to SUN 4/20's X(other SUN4 models do have embedded Intel floppy controllers) X XYou do need some experience adding device drivers to BSD/SunOS, Xotherwise DO read SUN related documents first ('writing a device driver', etc) Xand PLEASE save original copies of files anyway.... X Xinstall steps (in short): X X1. move 'szdef.h' and 'sz.c' to the './sys/scsi/targets' directory X2. apply the diffs to the './sys/sun/conf.c' file with potentially X different block/character device numbers depending on the SunOS release ! X this one is ok for SunOS4.1.1 X3. add the line: X scsi/targets/sz.c optional sz scsibus X to the file './sys/sun4c/conf/files' X4. add the line: X disk sz0 at scsibus0 target 5 lun 0 # TEAC SCSI floppy X to your config file './sys/sun4c/conf/your_SUN4C_config_file' X5. config your kernel again (see SunOS documentation) X6. make your kernel (it should compile 'sz.c'...) X7. make sure that there is NO other SCSI device on the bus with address '5'. X8. make sure that there is only ONE SCSI device (at the end of the cable(s)) X with terminators installed X9. strap the TEAC floppy drive (see TEAC manual for auto density sense): X X X 50 SCSI 1 X ::::::::::::::::::::::::::::::::: : < NO strap X X < strap X : < NO strap gives ID=5 X X VCC GND X | | | | < power X strap > XX. | | | | X strap > .XX X Xand on the SCSI controller board: X X ::X:XXXX:: X Xin words: XEJC, J, G, PAR, MON are OUT XH, F, LEV, HDS, STL are IN X X10. boot the new kernel, and with the floppy powered on, it should X give the message: X X sz0: TEAC FC-1 HF 00RV L X sz0 at esp0 target 5 lun 0 X X11. make both the block and character device, with the right R/W permissions X for your site, and with matching (major) numbers from './sys/sun/conf.c' !! X X mknod /dev/fz0c b 50 0 X mknod /dev/rfz0c c 104 0 X X12. try to read an already formatted floppy (720K or 1.44Mbyte) X X dd if=/dev/rfz0c of=/dev/null count=1 X X13. use the 'mtools' package from Emmet P. Gray (great stuff !) to handle X MSDOS flops (with all references to '/dev/rfd0c' changed to '/dev/rfz0c') X X14. use 'newfs' and 'mount' to use the drive as an UNIX file system X X XPlease report bugs, flames and suggestions to me and let me know if you are Xinterested to receive updates, because I have still marked a (large) number Xof issues 'TODO' (see the 'sz.c' source). XNote that I do not have ANY relationship with TEAC, just used their SCSI floppy. X XI really would like to thank the SUN SCSA and SBus engineering groups in the XUSA that did send me an early draft for free of the SCSA documents and do Xhave supported me very nicely in many ways already..... ! (thanks again) X X(Sun Microsystems >> the Netherlands << quoted $8 per page ! for the final X SCSA draft, uhmm, not so nice, but ok, their choice) X XGood Luck X X XFons Ullings, VU, Amsterdam, The Netherlands Xemail: fons@nat.vu.nl + END-OF-FILE README chmod 'u=rw,g=r,o=r' 'README' set `wc -c 'README'` count=$1 case $count in 3278) :;; *) echo 'Bad character count in ''README' >&2 echo 'Count should be 3278' >&2 esac echo Extracting 'conf.c.diff' sed 's/^X//' > 'conf.c.diff' << '+ END-OF-FILE ''conf.c.diff' X2c2 X< static char sccsid[] = "@(#)conf.c 5.91 90/06/26 SMI"; X--- X> static char sccsid[] = "@(#)conf.c 5.91 90/06/26 SMI AHU 910114"; X194a195,208 X> #include "sz.h" X> #if NSZ > 0 X> extern int szopen(), szclose(), szstrategy(), szread(), szwrite(); X> extern int szioctl(), szsize(); X> #else X> #define szopen nodev X> #define szclose nodev X> #define szstrategy nodev X> #define szread nodev X> #define szwrite nodev X> #define szioctl nodev X> #define szsize 0 X> #endif X> X379a394,395 X> { szopen, szclose, szstrategy, nodev, /*50*/ X> szsize, 0 }, X1322a1339,1343 X> }, X> { X> szopen, szclose, szread, szwrite, /*104*/ X> szioctl, nulldev, nulldev, 0, X> 0, 0, + END-OF-FILE conf.c.diff chmod 'u=rw,g=r,o=r' 'conf.c.diff' set `wc -c 'conf.c.diff'` count=$1 case $count in 677) :;; *) echo 'Bad character count in ''conf.c.diff' >&2 echo 'Count should be 677' >&2 esac echo Extracting 'sz.c' sed 's/^X//' > 'sz.c' << '+ END-OF-FILE ''sz.c' X/* X * SCSA compatible SCSI floppy driver for TEAC FD-235HS-300 X * X * Copyright (c) 1990/1991 A.Ullings, Vrije Universiteit, Amsterdam. X * Limited rights to use and modify are hereby granted for non-commercial X * purposes, provided that all copyright notices remain intact. X * X * email: fons@nat.vu.nl X * X * @(#)sz.c 1.14 1/14/91 X * X * X * this driver has been tested with: X * SUN4/20 SunOS4.0.3 X * SUN4/60 + WREN-IV SunOS4.1 X * SUN4/20 + WREN-V SunOS4.1.1 X * X * and works OK with the 'mtools' package from Emmet P. Gray, X * and as character and block device with both 720K and 1.44M 3.5inch floppy's X * X * TODO X * - test multiple units support. X * - add 'format' ioctl (easy) X * - add 'dk' statistics for 'iostat/vmstat' (how ?, the old way ??). X * - should add partition support ???! and the capacity should X * always get updated after a media change is sensed. X * - the code assumes that DEV_BSIZE is 512 () X * - SCSA allocs should be restartable iff no resources (??!!) X * - there MUST be a method to avoid copying data by mapping X * kernel addresses via 'buf' structures.... X * - should add non OPENPROM code version (but for which machines ?? X * the other SUN kernels I know of are using the old SCSI layers X * described in STB jun/jul 1989 X * - is the 'szsize()' implementation correct ?? X * - cleanup INQUIRY messages printout at startup time X * - add dynamic loading support when this becomes available for X * SCSA drivers (see SBulletin December 1990) X */ X X#include <scsi/scsi.h> X#include <scsi/targets/szdef.h> X Xstatic struct scsi_device *szunits[SZ_MAXUNIT]; Xstatic int szpri = 0; /* device priority */ Xstatic int szflag = 0; /* SCSA 'flag' used in SCSI operations */ X X#define SZAUTOSENSE /* TEAC auto density sense option enable */ X#define SZ_DEBUG /* DEBUG code enable */ X#ifdef SZ_DEBUG Xint szdebug = 0; X#define TRACE(fmt, p0, p1, p2) if(szdebug)printf(fmt, p0, p1, p2) X#else X#define TRACE(fmt, p0, p1, p2) ; X#endif X Xint szslave(), szattach(), szopen(), szclose(), szread(), szwrite(); Xint szstrategy(), szioctl(), szsize(); Xvoid szintr(); Xextern int nodev(); X X#ifdef OPENPROMS Xstruct dev_ops sz_ops = { X 1, X szslave, X szattach, X szopen, X szclose, X szread, X szwrite, X szstrategy, X nodev, X 0, X szioctl X}; X X#else XNO OPENPROMS; X#endif X X/* X * message functions and tables X */ Xstatic char *szmesg(); /* message lookup function */ Xchar *sz_keys[]; /* SCSI key table */ Xchar *sz_codes[]; /* SCSI/TEAC extended sense code table */ Xchar *sz_reasons[]; /* SCSA pkt_reason table */ X X/* X */ Xint Xszslave(devp) Xstruct scsi_device *devp; X{ X struct scsi_address *scsi_addr = &devp->sd_address; X struct scsi_pkt *pkt; X struct sz_device *un; X char id[32]; X X TRACE("szslave: target=%d lun=%d\n", X scsi_addr->a_target, scsi_addr->a_lun, 0); X switch(scsi_slave(devp, 0)) { X case SCSIPROBE_NOMEM: X case SCSIPROBE_FAILURE: X case SCSIPROBE_NORESP: X case SCSIPROBE_NONCCS: X printf("sz%d: offline\n", devp->sd_dev->devi_unit); X return(0); X case SCSIPROBE_EXISTS: X bzero(id, sizeof(id)); X bcopy(devp->sd_inq->inq_vid, id, 8+16+4); X/* should be cleaner here.... */ X printf("sz%d: %s\n", devp->sd_dev->devi_unit, id); X } X X un = (struct sz_device *)kmem_zalloc(sizeof(struct sz_device)); X if(!un) { /* should be a panic() */ X printf("sz: kmem_zalloc failed\n"); X return(0); X } X (struct sz_device *)devp->sd_private = un; X szunits[devp->sd_dev->devi_unit] = devp; X X pkt = get_pktiopb(&devp->sd_address, (caddr_t *)&un->un_sense, X CDB_GROUP0, 1, SZ_SENSE_LENGTH, B_READ, NULL_FUNC); X if(!pkt) { /* should be a panic() */ X printf("sz: get_pktiopb failed\n"); X return(0); X } X un->un_sense_pkt = pkt; X pkt->pkt_pmon = -1; /* no performance monitor */ X pkt->pkt_comp = szintr; X pkt->pkt_time = 0; X X szpri = MAX(szpri, ipltospl(devp->sd_dev->devi_intr->int_pri)); X devp->sd_dev->devi_driver = &sz_ops; X devp->sd_present = 1; X return(1); X} X X/* X * szsetmode(mod, medium) X * setup a SCSI/TEAC mode structure to some defaults X */ Xstatic Xszsetmode(mode, medium) Xstruct scsi_mode *mode; Xint medium; X{ X bzero(mode, sizeof(struct scsi_mode)); /* all zeros */ X mode->mod_medium_type = medium; /* fill in medium */ X mode->mod_block_length = 8; /* block descriptor only */ X mode->mod_density_code = SZ_DENSITY_MFM; /* high density */ X mode->mod_block_length_0 = 0x00; /* 512 bytes/block */ X mode->mod_block_length_1 = 0x02; X mode->mod_block_length_2 = 0x00; X} X X/* X */ Xint Xszattach(devp) Xstruct scsi_device *devp; X{ X struct scsi_pkt *pkt; X caddr_t arg; X X pkt = get_pktiopb(&devp->sd_address, &arg, X CDB_GROUP0, 1, sizeof(struct scsi_mode), B_WRITE, NULL_FUNC); X if(!pkt) { X TRACE("szattach: get_pktiopb failed\n", 0, 0, 0); X return; X } X szsetmode(arg, SZ_MEDIUM_AUTO); X makecom_g0(pkt, devp, FLAG_NOINTR|FLAG_NODISCON, X SCMD_MODE_SELECT, 0, sizeof(struct scsi_mode)); X (void) scsi_poll(pkt); X free_pktiopb(pkt, arg, sizeof(struct scsi_mode)); X} X X/* X */ Xint Xszstrategy(bp) Xstruct buf *bp; X{ X struct scsi_device *devp; X struct sz_device *un; X struct diskhd *dp; X daddr_t bn; X register s; X X devp = szunits[SZ_UNIT(bp->b_dev)]; X un = (struct sz_device *)devp->sd_private; X dp = &un->un_utab; X X bp->b_flags &= ~(B_DONE|B_ERROR); X X if(bp != &un->un_sbuf) { X bn = dkblock(bp); X if(bn >= un->un_capacity) { X if(bn > un->un_capacity) X bp->b_flags |= B_ERROR; X bp->b_resid = bp->b_bcount; X TRACE("szstrategy: bn=%d > %d\n", X bn, un->un_capacity, 0); X iodone(bp); X return; X } X } X X s = splr(szpri); X if(dp->b_actf == (struct buf *)NULL) X dp->b_actf = bp; X else X dp->b_actl->av_forw = bp; X dp->b_actl = bp; X bp->av_forw = (struct buf *)NULL; X if(dp->b_forw == (struct buf *)NULL) { X szstart(devp); X } X (void) splx(s); X} X X/* X */ Xszstart(devp) Xstruct scsi_device *devp; X{ X struct sz_device *un = (struct sz_device *)devp->sd_private; X struct diskhd *dp = &un->un_utab; X struct buf *bp; X struct scsi_pkt *pkt; X daddr_t bn; X daddr_t overflow; X int count; X int cmd; X X if(dp->b_forw || ((bp = dp->b_actf) == (struct buf *)NULL)) { X TRACE("szstart: dp->b_forw BUSY\n", 0, 0, 0); X return; X } X dp->b_forw = bp; /* this is the active one */ X dp->b_actf = bp->av_forw; /* next in queue */ X bp->av_forw = (struct buf *)NULL; /* */ X bp->av_back = (struct buf *)NULL; /* no resource yet */ X X if(bp != &un->un_sbuf) { X pkt = scsi_resalloc(&devp->sd_address, CDB_GROUP0, X 0, (opaque_t)bp, NULL_FUNC); X if(!pkt) { X TRACE("szstart: scsi_resalloc failed\n", 0, 0, 0); X bp->b_flags |= B_ERROR; X szdone(devp); X return; X } X bn = dkblock(bp); X count = bp->b_bcount / SZ_DEV_BSIZE; X bp->b_resid = 0; X overflow = bn + count - un->un_capacity; X if(overflow > 0) { X TRACE("szstart: overflow %d\n", overflow, 0, 0); X count -= overflow; X bp->b_resid = overflow * SZ_DEV_BSIZE; X } X cmd = bp->b_flags & B_READ ? SCMD_READ : SCMD_WRITE; X } else { X pkt = un->un_sbuf_pkt; X bn = bp->b_blkno; X count = bp->b_resid; X bp->b_resid = 0; X cmd = un->un_scmd; X } X X TRACE("szstart: cmd=0x%x bn=%d count=%d\n", cmd, bn, count); X/* assume SCSI GROUP1 if not GROUP0..... */ X if(CDB_GROUPID(cmd) == 0) X makecom_g0(pkt, devp, szflag, cmd, (int)bn, count); X else X makecom_g1(pkt, devp, szflag, cmd, (int)bn, count); X X pkt->pkt_pmon = -1; X pkt->pkt_comp = szintr; X pkt->pkt_time = SZ_TIMEOUT + count; /* 1 sec / block ?? */ X pkt->pkt_private = (opaque_t)bp; X X (struct scsi_pkt *)bp->av_back = pkt; X X if(pkt_transport(pkt) <= 0) { X TRACE("szstart: pkt_transport failed\n", 0, 0, 0); X bp->b_flags |= B_ERROR; X szdone(devp); X return; X } X} X X/* X * szdone(devp) X * finish up the current active transfer, and startup a X * new one if any. X */ Xszdone(devp) Xstruct scsi_device *devp; X{ X struct sz_device *un = (struct sz_device *)devp->sd_private; X struct scsi_pkt *pkt; X struct diskhd *dp = &un->un_utab; X struct buf *bp; X X bp = dp->b_forw; /* save the current active */ X dp->b_forw = NULL; /* and mark done */ X if(dp->b_actf) { /* is there a next one */ X szstart(devp); X } X if(pkt = (struct scsi_pkt *)bp->av_back) { /* resource anyway ?? */ X if(bp != &un->un_sbuf) { X scsi_resfree(pkt); X } X } X if(bp->b_flags & B_ERROR) X if(bp->b_error == 0) X bp->b_error = 0xff; /* ?? */ X iodone(bp); X} X X/* X * szcommand(dev, cmd, flag, addr, n, cdb123, cdb4) X * run a SCSI (special) command in queued interrupt mode X */ Xstatic Xszcommand(dev, cmd, flag, addr, n, cdb123, cdb4) Xdev_t dev; /* device */ Xint cmd; /* SCSI GROUP0/GROUP1 command */ Xint flag; /* B_READ/B_WRITE */ Xcaddr_t addr; /* DMA data address, if any */ Xint n; /* DMA data bytecount, if any */ Xdaddr_t cdb123; /* SCSI CDB address/blocknumber field */ Xint cdb4; /* SCSI CDB transfer field */ X{ X struct scsi_device *devp = szunits[SZ_UNIT(dev)]; X struct sz_device *un = (struct sz_device *)devp->sd_private; X struct scsi_pkt *pkt; X register struct buf *bp; X register int r; X register int s; X caddr_t arg; X X bp = &un->un_sbuf; X X s = splr(szpri); X while(bp->b_flags & B_BUSY) { X bp->b_flags |= B_WANTED; X (void) sleep((caddr_t)bp, PRIBIO); X } X bp->b_flags = B_BUSY | flag; X (void) splx(s); X X bp->b_error = 0; /* !! */ X bp->b_dev = dev; X bp->b_bcount = n; /* number of data xfer bytes */ X bp->b_blkno = cdb123; /* SCSI blocknumber field */ X bp->b_resid = cdb4; /* SCSI transfer length field */ X/* get_pktiopb doesn't accept n == 0..... */ X if(n) { X pkt = get_pktiopb(&devp->sd_address, &arg, X CDB_GROUPID(cmd) == 0 ? CDB_GROUP0 : CDB_GROUP1, X 1, n, flag, SLEEP_FUNC); X } else { X pkt = scsi_pktalloc(&devp->sd_address, X CDB_GROUPID(cmd) == 0 ? CDB_GROUP0 : CDB_GROUP1, X 1, SLEEP_FUNC); X } X bp->b_un.b_addr = arg; X if(!pkt) { X TRACE("szcommand: get_pktiopb failed\n", 0, 0, 0); X bp->b_flags &= ~B_BUSY; X if(bp->b_flags & B_WANTED) X wakeup((caddr_t)bp); X return(-1); X } X if(n && ((bp->b_flags & B_READ) == 0)) X bcopy(addr, bp->b_un.b_addr, n); X X un->un_sbuf_pkt = pkt; /* save the allocated packet */ X un->un_scmd = cmd; /* copy special command */ X TRACE("szcommand: cmd=0x%x b_bcount=%d b_un.b_addr=0x%x\n", X cmd, bp->b_bcount, bp->b_un.b_addr); X szstrategy(bp); X iowait(bp); X X if(n && (bp->b_flags & B_READ)) X bcopy(bp->b_un.b_addr, addr, n); X X if(n) { X free_pktiopb(pkt, bp->b_un.b_addr, n); X } else { X scsi_resfree(pkt); X } X X r = bp->b_flags & B_ERROR ? bp->b_error : bp->b_resid; X TRACE("szcommand: b_resid=%d r=0x%x\n", bp->b_resid, r, 0); X bp->b_flags &= ~B_BUSY; X if(bp->b_flags & B_WANTED) X wakeup((caddr_t)bp); X return(r); X} X X/* X */ Xvoid Xszintr(pkt) Xstruct scsi_pkt *pkt; X{ X struct buf *bp; X struct scsi_device *devp; X struct sz_device *un; X struct scsi_status *ss; X X bp = (struct buf *)pkt->pkt_private; X devp = szunits[SZ_UNIT(bp->b_dev)]; X un = (struct sz_device *)devp->sd_private; X TRACE("szintr: pkt_reason=0x%x state=0x%x\n", X pkt->pkt_reason, pkt->pkt_state, 0); X if((pkt->pkt_reason != CMD_CMPLT) || X ((pkt->pkt_state & STATE_GOT_STATUS) == 0)) { X printf("sz%d: hard SCSI error 0x%x %s\n", SZ_UNIT(bp->b_dev), X pkt->pkt_reason, X szmesg(sz_reasons, (int)pkt->pkt_reason)); X bp->b_flags |= B_ERROR; X szdone(devp); X return; X } X if(pkt == un->un_sense_pkt) { /* REQUEST sense */ X struct scsi_extended_sense *es = un->un_sense; X X if(es->es_key != KEY_UNIT_ATTENTION) { X printf("sz%d: %s %s\n", SZ_UNIT(bp->b_dev), X szmesg(sz_keys, (int)es->es_key), X szmesg(sz_codes, (int)es->es_add_info[4])); X bp->b_error = es->es_key; X bp->b_flags |= B_ERROR; X szdone(devp); X return; X } X TRACE("szintr: sense_pkt restart\n", 0, 0, 0); X/* restart the original request.... */ X pkt = (struct scsi_pkt *)bp->av_back; X if(pkt_transport(pkt) <= 0) { X TRACE("szintr: pkt_transport failed\n", 0, 0, 0); X bp->b_flags |= B_ERROR; X szdone(devp); X return; X } X return; X X } X ss = (struct scsi_status *)pkt->pkt_scbp; X if(ss->sts_chk) { /* status check condition */ X pkt = un->un_sense_pkt; X makecom_g0(pkt, devp, FLAG_NODISCON, X SCMD_REQUEST_SENSE, 0, SZ_SENSE_LENGTH); X bzero((caddr_t)un->un_sense, SZ_SENSE_LENGTH); X pkt->pkt_private = (opaque_t)bp; X if(pkt_transport(pkt) <= 0) { X TRACE("szintr: pkt_transport failed\n", 0, 0, 0); X bp->b_flags |= B_ERROR; X szdone(devp); X return; X } X return; X } X bp->b_resid += pkt->pkt_resid; /* */ X TRACE("szintr: OK resid=%d count=%d 0x%x\n", X bp->b_resid, bp->b_bcount, bp->b_flags); X szdone(devp); X} X X/* X * sztrack(dev) X * try to (auto) sense the current floppy density X * X */ Xsztrack(dev) Xdev_t dev; X{ X int r; X int medium; X struct scsi_device *devp; X struct sz_device *un; X X devp = szunits[SZ_UNIT(dev)]; X un = (struct sz_device *)devp->sd_private; X X#ifdef SZAUTOSENSE X/* just select the TEAC autosense option HDS with the correct FDD options... */ X szsetmode(&un->un_mode, SZ_MEDIUM_AUTO); X if(szcommand(dev, SCMD_MODE_SELECT, B_WRITE, X (caddr_t)&un->un_mode, sizeof(struct scsi_mode), X (daddr_t)0, sizeof(struct scsi_mode)) < 0) X return(EIO); X return(0); X#else X/* get current density/mode, but maybe we have had power-down... */ X if(szcommand(dev, SCMD_MODE_SENSE, B_READ, X (caddr_t)&un->un_mode, sizeof(struct scsi_mode), X (daddr_t)0, sizeof(struct scsi_mode)) < 0) X return(EIO); X/* so make it 'sane' anyway */ X medium = un->un_mode.mod_medium_type == SZ_MEDIUM_2MB ? X SZ_MEDIUM_2MB : SZ_MEDIUM_1MB; X TRACE("szopen: 0x%x\n", medium, 0, 0); X/* force density code, block_length, etc... */ X szsetmode(&un->un_mode, medium); X if(szcommand(dev, SCMD_MODE_SELECT, B_WRITE, X (caddr_t)&un->un_mode, sizeof(struct scsi_mode), X (daddr_t)0, sizeof(struct scsi_mode)) < 0) X return(EIO); X/* will current setting work ?? */ X if((r = szcommand(dev, SCMD_VERIFY, B_READ, X (caddr_t)0, 0, (daddr_t)0, 1)) == 0) X return(0); X if(r != KEY_MEDIUM_ERROR && r != KEY_MISCOMPARE) X return(EIO); X/* no, flip the medium... */ X un->un_mode.mod_medium_type = medium == SZ_MEDIUM_2MB ? X SZ_MEDIUM_1MB : SZ_MEDIUM_2MB; X if(szcommand(dev, SCMD_MODE_SELECT, B_WRITE, X (caddr_t)&un->un_mode, sizeof(struct scsi_mode), X (daddr_t)0, sizeof(struct scsi_mode)) < 0) X return(EIO); X/* and retry */ X if((r = szcommand(dev, SCMD_VERIFY, B_READ, X (caddr_t)0, 0, (daddr_t)0, 1)) == 0) X return(0); X return(EIO); X#endif SZAUTOSENSE X} X X/* X */ Xszopen(dev) Xdev_t dev; X{ X int unit = SZ_UNIT(dev); X struct scsi_device *devp; X struct sz_device *un; X X TRACE("szopen: unit=%d\n", unit, 0, 0); X if(unit >= SZ_MAXUNIT) X return(ENXIO); X if((devp = szunits[SZ_UNIT(dev)]) == (struct scsi_device *)0) X return(ENXIO); X un = (struct sz_device *)devp->sd_private; X if(un->un_openf) X return(0); X if(sztrack(dev)) X return(EIO); X if(szcommand(dev, SCMD_MODE_SENSE, B_READ, X (caddr_t)&un->un_mode, sizeof(struct scsi_mode), X (daddr_t)0, sizeof(struct scsi_mode)) < 0) X return(EIO); X un->un_capacity = ((daddr_t)un->un_mode.mod_num_block_2 << 16) | X (un->un_mode.mod_num_block_1 << 8) | X (un->un_mode.mod_num_block_0); X TRACE("szopen: capacity=%d\n", un->un_capacity, 0, 0); X un->un_openf = 1; X return(0); X} X X/* X */ Xszclose(dev) Xdev_t dev; X{ X int unit = SZ_UNIT(dev); X struct scsi_device *devp; X struct sz_device *un; X X devp = szunits[unit]; X un = (struct sz_device *)devp->sd_private; X un->un_openf = 0; X return(0); X} X X/* X * szminphys(bp) X * allow only 'SZ_DMA_SIZE' transfers (SCSI) X */ Xszminphys(bp) Xstruct buf *bp; X{ X#define SZ_DMA_SIZE (255*SZ_DEV_BSIZE) X if(bp->b_bcount > SZ_DMA_SIZE) X bp->b_bcount = SZ_DMA_SIZE; X} X X/* X */ Xszread(dev, uio) Xdev_t dev; Xstruct uio *uio; X{ X struct sz_device *un; X struct scsi_device *devp; X int unit = SZ_UNIT(dev); X X if(unit >= SZ_MAXUNIT) X return(ENXIO); X if(uio->uio_offset & (SZ_DEV_BSIZE - 1)) X return(EINVAL); X if(uio->uio_iov->iov_len & (SZ_DEV_BSIZE - 1)) X return(EINVAL); X devp = szunits[unit]; X un = (struct sz_device *)devp->sd_private; X return(physio(szstrategy, &un->un_rbuf, dev, B_READ, szminphys, uio)); X/* X */ Xszwrite(dev, uio) Xdev_t dev; Xstruct uio *uio; X{ X struct sz_device *un; X struct scsi_device *devp; X int unit = SZ_UNIT(dev); X X if(unit >= SZ_MAXUNIT) X return(ENXIO); X if(uio->uio_offset & (SZ_DEV_BSIZE - 1)) X return(EINVAL); X if(uio->uio_iov->iov_len & (SZ_DEV_BSIZE - 1)) X return(EINVAL); X devp = szunits[unit]; X un = (struct sz_device *)devp->sd_private; X return(physio(szstrategy, &un->un_rbuf, dev, B_WRITE, szminphys, uio)); X} X X/* X * X * SUN's disk 'ioctl' structure for floppy's is a problem... X * So for now there is just enough support to let 'newfs', 'mkfs' X * and 'dkinfo' work X */ Xszioctl(dev, cmd, data, flag) Xdev_t dev; Xregister int cmd; Xcaddr_t data; X{ X struct scsi_device *devp = szunits[SZ_UNIT(dev)]; X struct sz_device *un = (struct sz_device *)devp->sd_private; X X TRACE("szioctl: dev=0x%x cmd=0x%x\n", dev, cmd, 0); X switch(cmd) { X case DKIOCGGEOM: X ((struct dk_geom *)data)->dkg_ncyl = 80; X ((struct dk_geom *)data)->dkg_acyl = 0; X ((struct dk_geom *)data)->dkg_bcyl = 0; X ((struct dk_geom *)data)->dkg_nhead = 2; X ((struct dk_geom *)data)->dkg_bhead = 0; X ((struct dk_geom *)data)->dkg_nsect = un->un_capacity / 160; X ((struct dk_geom *)data)->dkg_intrlv = 0; X ((struct dk_geom *)data)->dkg_gap1 = 0; X ((struct dk_geom *)data)->dkg_gap2 = 0; X ((struct dk_geom *)data)->dkg_apc = 0; X return(0); X X case DKIOCGPART: X ((struct dk_map *)data)->dkl_cylno = 0; X ((struct dk_map *)data)->dkl_nblk = un->un_capacity; X return(0); X X case DKIOCINFO: X ((struct dk_info *)data)->dki_ctlr = 0x0; X ((struct dk_info *)data)->dki_unit = SZ_UNIT(dev); /* ?? */ X ((struct dk_info *)data)->dki_ctype = DKC_SCSI_CCS; X ((struct dk_info *)data)->dki_flags = 0; X return(0); X X case DKIOCSCMD: X break; X } X return(ENXIO); X} X X/* X * szsize(dev) X * return the maximum number of blocks for the block device. X * seems to be consulted only at startup time ??!, so give the X * maximum then.... and this routine is even called when the unit X * is marked NOT present, uhmm X */ Xszsize(dev) Xdev_t dev; X{ X struct scsi_device *devp; X struct sz_device *un; X X if((devp = szunits[SZ_UNIT(dev)]) == (struct scsi_device *)0) X return(-1); X un = (struct sz_device *)devp->sd_private; X TRACE("szsize: %d\n", un->un_capacity, 0, 0); X return(un->un_capacity ? un->un_capacity : SZ_SIZE); X} X X/* X * szmesg(cp, no) X * return a string that matches the number from a message table X */ Xstatic char * Xszmesg(cp, no) Xchar **cp; X{ X while(*cp[1]) { X if(*cp[0] == no) X return(*cp + 1); X cp++; X } X return(""); X X} X X/* X * SCSI sense key messages X */ Xchar *sz_keys[] = { X "\000KEY_NO_SENSE", X "\001KEY_RECOVERABLE_ERROR", X "\002KEY_NOT_READY", X "\003KEY_MEDIUM_ERROR", X "\004KEY_HARDWARE_ERROR", X "\005KEY_ILLEGAL_REQUEST", X "\006KEY_UNIT_ATTENTION", X "\007KEY_WRITE_PROTECT", X "\010KEY_BLANK_CHECK", X "\011KEY_VENDOR_UNIQUE", X "\012KEY_COPY_ABORTED", X "\013KEY_ABORTED_COMMAND", X "\014KEY_EQUAL", X "\015KEY_VOLUME_OVERFLOW", X "\016KEY_MISCOMPARE", X "\017KEY_RESERVED", X "\000", X}; X X/* X * TEAC extended code messages X */ Xchar *sz_codes[] = { X "\001No Index Signal", X "\004Drive Not Ready", X "\006Track Zero Found", X "\020ID CRC Error", X "\021Data CRC Error", X "\022No Address Mark in ID Field", X "\023No Address Mark in Data Field", X "\024No Record Found", X "\025Seek Error", X "\027Read Retries", X "\040Invalid Command", X "\041Illegal Logical Block", X "\044Illegal CDB Field", X "\045Invalid LUN", X "\046Invalid Field in Parameters", X "\047Write Protected", X "\050Medium Changed", X "\051Power/Device Reset", X "\052Parameters Changed", X "\053FDC Error", X "\060Incompatible Cartridge", X "\061Medium Format Corrupted", X "\084Internal Controller Error", X "\087SCSI Parity Error", X "\090Write Command Aborted", X "\214Deleted Data Address Mark", X "\240Selftest Error", X "\241Terminator Power Off", X "\242Strap SW set Error", X "\000", X}; X X/* X * SCSA packet fail reason messages X */ Xchar *sz_reasons[] = { X "\000no transport errors", X "\001stopped with not normal state", X "\002dma direction error occurred", X "\003unspecified transport error", X "\004SCSI bus reset destroyed command", X "\005Command transport aborted", X "\006Command timed out", X "\007Data Overrun", X "\010Command Overrun", X "\011Status Overrun", X "\012Message not Command Complete", X "\013Target refused Message Out phase", X "\014Extended Identify message rejected", X "\015Detected Error message rejected", X "\016Abort message rejected", X "\017Reject message rejected", X "\020No Operation message rejected", X "\021Parity Error message rejected", X "\022Bus Device Reset message rejected", X "\023Identify message rejected", X "\000", X}; + END-OF-FILE sz.c chmod 'u=rw,g=r,o=r' 'sz.c' set `wc -c 'sz.c'` count=$1 case $count in 20289) :;; *) echo 'Bad character count in ''sz.c' >&2 echo 'Count should be 20289' >&2 esac echo Extracting 'szdef.h' sed 's/^X//' > 'szdef.h' << '+ END-OF-FILE ''szdef.h' X/* X * SCSA compatible SCSI floppy driver includes for TEAC FD-235HS-300 X * X * Copyright (c) 1990/1991 A.Ullings, Vrije Universiteit, Amsterdam. X * Limited rights to use and modify are hereby granted for non-commercial X * purposes, provided that all copyright notices remain intact. X * X * email: fons@nat.vu.nl X * X * @(#)szdef.h 1.5 1/14/91 X * X */ X X/* X * SCSA doesn't bother about modes... ?? X * from the TEAC FC-1-00 Software Specification X */ Xstruct scsi_mode { X u_char mod_00; X u_char mod_medium_type; X#define SZ_MEDIUM_AUTO 0x02 X#define SZ_MEDIUM_1MB 0x80 X#define SZ_MEDIUM_2MB 0x88 X u_char mod_02; X u_char mod_block_length; X u_char mod_density_code; X#define SZ_DENSITY_FM 0x01 X#define SZ_DENSITY_MFM 0x02 X u_char mod_num_block_2; X u_char mod_num_block_1; X u_char mod_num_block_0; X u_char mod_08; X u_char mod_block_length_2; X u_char mod_block_length_1; X u_char mod_block_length_0; X}; X X/* X */ Xstruct sz_device { X struct scsi_pkt *un_sense_pkt; /* request sense packet */ X struct scsi_pkt *un_sbuf_pkt; /* special function packet */ X struct scsi_extended_sense *un_sense; X short un_openf; /* opened flag */ X short un_scmd; /* special command */ X struct buf un_sbuf; /* specials buffer header */ X struct buf un_rbuf; /* raw I/O header */ X struct diskhd un_utab; /* queue header */ X struct scsi_mode un_mode; /* per drive mode */ X daddr_t un_capacity; /* number of blocks */ X}; X X#define SZ_MAXUNIT 1 X#define SZ_UNIT(dev) ((minor(dev)>>3)&0x07) X#define SZ_DEV_BSIZE DEV_BSIZE X#define SZ_SENSE_LENGTH 16 X#define SZ_MODE_LENGTH sizeof(struct scsi_mode) X#define SZ_TIMEOUT 12 /* 16 retries... */ X#define SZ_SIZE (80*2*18) /* default medium size */ + END-OF-FILE szdef.h chmod 'u=rw,g=r,o=r' 'szdef.h' set `wc -c 'szdef.h'` count=$1 case $count in 1674) :;; *) echo 'Bad character count in ''szdef.h' >&2 echo 'Count should be 1674' >&2 esac exit 0 -- John Connin: manatee Orlando, Florida UUCP: {uunet,ge-dab,ucf-cs}!tarpit!tous!manatee!johnc