home *** CD-ROM | disk | FTP | other *** search
- /*
- ** TapeIO: performs operations to the tape unit via SCSI-direct for BTNtape
- ** Version 3.0 03/14/94
- **
- ** (c) Copyright 1990, 1994 Robert Rethemeyer.
- ** This code is freely distributable and redistributable,
- ** for non-commercial purposes, provided this notice is included.
- **
- ** This code was derived from programs written by Robert Mitchell.
- */
-
- #define _STRICT_ANSI
- #include <exec/types.h>
- #include <exec/io.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <devices/scsidisk.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "btn.h"
- #include "tplink.h"
-
- #include <proto/exec.h>
- #include <pragmas/exec_pragmas.h>
-
- #define DBUG 0
-
- /* SCSI commands used by handler */
- #define CMD_TEST_UNIT_READY 0x00
- #define CMD_REWIND 0x01
- #define CMD_REQUEST_SENSE 0x03
- #define CMD_SCSI_READ 0x08
- #define CMD_SCSI_WRITE 0x0a
- #define CMD_FILEMARK 0x10
- #define CMD_SPACE 0x11
- #define CMD_INQUIRY 0x12
- #define CMD_MODE_SELECT 0x15
- #define CMD_MODE_SENSE 0x1a
- #define CMD_LOAD_UNLOAD 0x1b
- #define CMD_READ_CAPACITY 0x25
-
- extern UBYTE *cdb;
- extern UBYTE *sns;
- extern UBYTE *inq;
- extern struct SCSICmd *cmd;
- extern UBYTE *TapeBuff[2];
- extern struct IOStdReq *ior;
- extern ULONG blknum;
- extern ULONG blksize;
- extern ULONG numblks;
- extern ULONG TBSize;
- extern ULONG rwlen;
- extern ULONG rdlen;
- extern ULONG expect;
- extern ULONG bugmask;
- extern long filenum;
- extern long lastwrtn;
- extern long actual;
- extern long Boff;
- extern long reserved;
- extern long tpsize;
- extern struct tplink *linktp;
- extern BOOL inprog;
- extern BOOL bswap;
- extern BOOL dbug;
- extern char dbb[80];
- extern UBYTE Lun;
- extern UBYTE varblk;
- extern UBYTE fixedbit;
-
- long TapeIO(int toper, long bn, int ctl)
- {
- char *z; int i; ULONG bc;
-
- if(inprog) {
- WaitIO((struct IORequest *)ior);
- inprog = FALSE;
- if(actual<0) actual = cmd->scsi_Actual;
- if(cdb[0]==CMD_SCSI_READ) Mprintf("%ld bytes\n",actual);
- if(ior->io_Error) return((long)(ior->io_Error));
- }
- if(toper == TFINISH) return(0L);
- cmd->scsi_Command = cdb;
- cmd->scsi_CmdLength = 6;
- cmd->scsi_Status = 0;
- cmd->scsi_Length = 0;
- cmd->scsi_Actual = 0;
- cmd->scsi_Flags = 0;
- ior->io_Command = HD_SCSICMD;
- ior->io_Data = (APTR) cmd;
- ior->io_Length = sizeof(struct SCSICmd);
- ior->io_Error = 0;
- for (i=0 ; i<10; i++) cdb[i] = 0x00;
-
- switch(toper) {
-
- case TWRITE:
- if(varblk) bc = expect = cmd->scsi_Length = Boff;
- else {
- bc = ((Boff-1)/blksize)+1;
- cmd->scsi_Length = expect = bc * blksize;
- }
- if(DAC) if((blknum+bc)>tpsize) return(FAKEOM);
- if(bswap) swapbytes(TapeBuff[bn]);
- cdb[0] = CMD_SCSI_WRITE;
- cdb[1] = Lun | fixedbit;
- *((UWORD *)&cdb[2]) = (SEQ) ? (UWORD)(bc>>8) : (UWORD) blknum;
- cdb[4] = (UBYTE) bc & 0xff;
- /* cmd->scsi_Data = (UWORD *) TapeBuff[bn]; */ /* 2090A bug fix */
- cmd->scsi_Data = (UWORD *) ((ULONG) TapeBuff[bn] | bugmask);
- cmd->scsi_Flags = SCSIF_WRITE;
- actual = bc;
- Mprintf("Writing block %lu: %lu bytes\n",blknum,expect);
- break;
-
- case TREAD:
- if(DAC) if((blknum+numblks)>tpsize) return(FAKEOM);
- cdb[0] = CMD_SCSI_READ;
- cdb[1] = Lun | fixedbit;
- *((UWORD *)&cdb[2]) = (SEQ) ? (UWORD)(rdlen>>8) : (UWORD) blknum;
- cdb[4] = (UBYTE) rdlen & 0xff;
- cmd->scsi_Data = (UWORD *) TapeBuff[bn];
- cmd->scsi_Length = expect = rwlen;
- cmd->scsi_Flags = SCSIF_READ;
- actual = -1;
- Mprintf("Reading block %lu:",blknum);
- break;
-
- case TSENSE:
- for (i=0 ; i<32; i++) sns[i] = 0;
- cdb[0] = CMD_REQUEST_SENSE;
- cdb[1] = Lun;
- cdb[4] = 32; /* extended sense */
- cmd->scsi_Length = 32;
- cmd->scsi_Data = (UWORD *) sns;
- cmd->scsi_Flags = SCSIF_READ;
- break;
-
- case TREWIND:
- cdb[0] = CMD_REWIND;
- cdb[1] = Lun;
- filenum = reserved;
- lastwrtn = -1;
- Mprintf("Rewinding\n");
- break;
-
- case INQUIRY: /* read drive information */
- cdb[0] = CMD_INQUIRY;
- cdb[1] = Lun;
- cdb[4] = 36;
- cmd->scsi_Length = 36;
- cmd->scsi_Data = (UWORD *) inq;
- cmd->scsi_Flags = SCSIF_READ;
- break;
-
- case TREADY: /* test unit ready */
- cdb[0] = CMD_TEST_UNIT_READY;
- cdb[1] = Lun;
- break;
-
- case MDSNS:
- for (i=0 ; i<12; i++) sns[i] = 0;
- cdb[0] = CMD_MODE_SENSE;
- cdb[1] = Lun;
- cdb[4] = 12;
- cmd->scsi_Length = 12;
- cmd->scsi_Data = (UWORD *) sns;
- cmd->scsi_Flags = SCSIF_READ;
- break;
-
- case WFMARK: /* write file mark */
- cdb[0] = CMD_FILEMARK;
- cdb[1] = Lun;
- cdb[4] = (UBYTE) bn;
- if(bn) Mprintf("Writing filemark\n");
- break;
-
- case TSKIPF: /* skip over filemarks */
- cdb[0] = CMD_SPACE;
- cdb[1] = Lun | 0x01;
- cdb[2] = (UBYTE) (bn >> 16);
- cdb[3] = (UBYTE) (bn >> 8);
- cdb[4] = (UBYTE) bn;
- break;
-
- case TSKIPE: /* skip to end-of-data */
- cdb[0] = CMD_SPACE;
- cdb[1] = Lun | 0x03;
- Mprintf("Skipping to end of data\n");
- break;
-
- case TRETEN: /* retension tape */
- cdb[0] = CMD_LOAD_UNLOAD;
- cdb[1] = Lun;
- cdb[4] = 0x03;
- Mprintf("Retensioning\n");
- break;
-
- case TEJECT: /* eject tape */
- cdb[0] = CMD_LOAD_UNLOAD;
- cdb[1] = Lun;
- cdb[4] = 0x00;
- Mprintf("Ejecting tape\n");
- break;
-
- case RDCAP: /* read tape capacity. 3M drive only */
- cdb[0] = CMD_READ_CAPACITY;
- cdb[1] = Lun;
- cmd->scsi_CmdLength = 10;
- cmd->scsi_Length = 8;
- cmd->scsi_Data = (UWORD *) sns;
- cmd->scsi_Flags = SCSIF_READ;
- break;
-
- case RAWCMD: /* write user-provided control command */
- i = 0;
- z = (char *)TapeBuff[bn];
- while(*z!='\n' && i<10) cdb[i++] = (UBYTE) strtoul(z,&z,16);
- cdb[1] |= Lun;
- if(cdb[0] == CMD_REWIND) { blknum = filenum = reserved; lastwrtn = -1; }
- if(cdb[0] >= 0x20) cmd->scsi_CmdLength = 10;
- if(cdb[0] >= 0xa0) cmd->scsi_CmdLength = 12;
- cmd->scsi_Data = (UWORD *) sns;
- Mprintf("Raw command %02X\n",cdb[0]);
- break;
-
- case MDSET: /* set fixed-mode block length */
- cdb[0] = CMD_MODE_SELECT;
- cdb[1] = Lun;
- cdb[4] = 12;
- for (i=0 ; i<12; i++) sns[i] = 0x00;
- sns[2] = 0x10; /* buffered mode */
- sns[3] = 8;
- if(!bn) *((ULONG *)&sns[8]) = blksize & 0x00ffffff; /* block length */
- cmd->scsi_Length = 12;
- cmd->scsi_Data = (UWORD *) sns;
- cmd->scsi_Flags = SCSIF_WRITE;
- Mprintf("Mode Select, new block size %lu\n",blksize);
- break;
-
- case USRMODE: /* write user-provided mode-select data */
- for (i=0 ; i<64; i++) sns[i] = 0x00;
- i = 0;
- z = (char *)TapeBuff[bn];
- while(*z!='\n' && i<64) sns[i++] = (UBYTE) strtoul(z,&z,16);
- cdb[0] = CMD_MODE_SELECT;
- cdb[1] = Lun;
- cdb[4] = i;
- cmd->scsi_Length = i;
- cmd->scsi_Data = (UWORD *) sns;
- cmd->scsi_Flags = SCSIF_WRITE;
- Mprintf("User Mode-Select\n");
- break;
-
- }
-
- #ifdef DBUG
- if(dbug) Mprintf("CDB= %02X %02X %02X %02X %02X %02X ADR=%08X LEN=%X\n",
- cdb[0],cdb[1],cdb[2],cdb[3],cdb[4],cdb[5],
- cmd->scsi_Data, cmd->scsi_Length);
- #endif
-
- if(ctl == CTLWAIT) {
- DoIO ((struct IORequest *)ior); /* start sync io */
- if(actual<0) actual = cmd->scsi_Actual;
- if(cdb[0]==CMD_SCSI_READ) Mprintf("%ld bytes\n",actual);
- return((long)(ior->io_Error));
- }
- else {
- SendIO((struct IORequest *)ior); /* start async io */
- inprog = TRUE;
- return(0L);
- }
- }
-
-