home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 500-599 / ff558.lzh / BTNtape / src / tapeio.c < prev    next >
C/C++ Source or Header  |  1991-10-28  |  7KB  |  253 lines

  1. /*
  2. **  TapeIO: performs operations to the tape unit via SCSI-direct for BTNtape
  3. **     Version 2.1  10/22/91
  4. **
  5. **   (c) Copyright 1990, 1991  Robert Rethemeyer.
  6. **     This code is freely distributable and redistributable,
  7. **     for non-commercial purposes, provided this notice is included.
  8. **
  9. **   This code was derived from programs written by Robert Mitchell.
  10. */
  11.  
  12. #include <exec/types.h>
  13. #include <exec/io.h>
  14. #include <libraries/dos.h>
  15. #include <libraries/dosextens.h>
  16. #include <devices/scsidisk.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19.  
  20. #define DBUG 0
  21.  
  22. #if defined AZTEC_C
  23.   #include <functions.h>
  24. /*#define strtoul strtol */
  25. #elif defined LATTICE
  26.   #include <proto/exec.h>
  27. #endif
  28.  
  29. #include "tape.h"
  30. #include "tplink.h"
  31.  
  32. /* SCSI commands used by handler */
  33. #define CMD_TEST_UNIT_READY   0x00
  34. #define CMD_REWIND            0x01
  35. #define CMD_REQUEST_SENSE     0x03
  36. #define CMD_SCSI_READ         0x08
  37. #define CMD_SCSI_WRITE        0x0a
  38. #define CMD_FILEMARK          0x10
  39. #define CMD_SPACE             0x11
  40. #define CMD_INQUIRY           0x12
  41. #define CMD_MODE_SELECT       0x15
  42. #define CMD_MODE_SENSE        0x1a
  43. #define CMD_LOAD_UNLOAD       0x1b
  44. #define CMD_READ_CAPACITY     0x25
  45.  
  46. extern UBYTE  *cdb;
  47. extern UBYTE  *sns;
  48. extern UBYTE  *inq;
  49. extern struct SCSICmd  *cmd;
  50. extern UBYTE  *TapeBuff[2];
  51. extern struct IOStdReq *ior;
  52. extern ULONG  blknum;
  53. extern ULONG  blksize;
  54. extern ULONG  numblks;
  55. extern ULONG  TBSize;
  56. extern ULONG  rwlen;
  57. extern ULONG  tranlen;
  58. extern ULONG  bugmask;
  59. extern long   reserved;
  60. extern long   tpsize;
  61. extern struct tplink  *linktp;
  62. extern int    inprog;
  63. extern char   dbb[80];
  64. extern UBYTE  Lun;
  65. extern UBYTE  fixedbit;
  66. extern long   NewTape();
  67.  
  68. long TapeIO(int toper, int bn, int ctl)
  69. {
  70.  char *z;  int i;
  71.  
  72.  if(inprog) {
  73.     WaitIO((struct IORequest *)ior);
  74.     inprog = FALSE;
  75.     if(ior->io_Error)  return((long)(ior->io_Error));
  76.  }
  77.  if(toper == TFINISH) return(0L);
  78.  cmd->scsi_Command = cdb;
  79.  cmd->scsi_CmdLength = 6;
  80.  cmd->scsi_Status = 0;
  81.  cmd->scsi_Length = 0;
  82.  cmd->scsi_Flags  = 0;
  83.  ior->io_Command = HD_SCSICMD;
  84.  ior->io_Data = (APTR) cmd;
  85.  ior->io_Length = sizeof(struct SCSICmd);
  86.  ior->io_Error = 0;
  87.  for (i=0 ; i<10; i++) cdb[i] = 0x00;
  88.  
  89.  switch(toper) {
  90.  
  91.   case TWRITE:
  92.     if(DAC && ((blknum+numblks)>tpsize)) return(FAKEOM);
  93.     cdb[0] = CMD_SCSI_WRITE;
  94.     cdb[1] = Lun | fixedbit;
  95.     *((UWORD *)&cdb[2]) = (SEQ) ? (UWORD)(tranlen>>8) : (UWORD) blknum;
  96.     cdb[4] = (UBYTE) tranlen & 0xff;
  97.  /* cmd->scsi_Data = (UWORD *) TapeBuff[bn]; */      /* 2090A bug fix */
  98.     cmd->scsi_Data = (UWORD *) ((ULONG) TapeBuff[bn] | bugmask);
  99.     cmd->scsi_Length = rwlen;
  100.     cmd->scsi_Flags = SCSIF_WRITE;
  101.     MPR2("Writing block %u x %d\n",blknum,tranlen);
  102.     break;
  103.  
  104.   case TREAD:
  105.     if(DAC && ((blknum+numblks)>tpsize)) return(FAKEOM);
  106.     cdb[0] = CMD_SCSI_READ;
  107.     cdb[1] = Lun | fixedbit;
  108.     *((UWORD *)&cdb[2]) = (SEQ) ? (UWORD)(tranlen>>8) : (UWORD) blknum;
  109.     cdb[4] = (UBYTE) tranlen & 0xff;
  110.     cmd->scsi_Data = (UWORD *) TapeBuff[bn];
  111.     cmd->scsi_Length = rwlen;
  112.     cmd->scsi_Flags = SCSIF_READ;
  113.     MPR2("Reading block %u x %d\n",blknum,tranlen);
  114.     break;
  115.  
  116.   case TSENSE:
  117.     for (i=0 ; i<32; i++) sns[i] = 0;
  118.     cdb[0] = CMD_REQUEST_SENSE;
  119.     cdb[1] = Lun;
  120.     cdb[4] = 32;  /* extended sense */
  121.     cmd->scsi_Length = 32;
  122.     cmd->scsi_Data = (UWORD *) sns;
  123.     cmd->scsi_Flags = SCSIF_READ;
  124.     break;
  125.  
  126.   case TREWIND:
  127.     cdb[0] = CMD_REWIND;
  128.     cdb[1] = Lun;
  129.     MPR0("Rewinding\n");
  130.     break;
  131.  
  132.   case INQUIRY:  /* read drive information */
  133.     cdb[0] = CMD_INQUIRY;
  134.     cdb[1] = Lun;
  135.     cdb[4] = 36;
  136.     cmd->scsi_Length = 36;
  137.     cmd->scsi_Data = (UWORD *) inq;
  138.     cmd->scsi_Flags = SCSIF_READ;
  139.     break;
  140.  
  141.   case TREADY:  /* test unit ready */
  142.     cdb[0] = CMD_TEST_UNIT_READY;
  143.     cdb[1] = Lun;
  144.     break;
  145.  
  146.   case MDSNS:
  147.     for (i=0 ; i<12; i++) sns[i] = 0;
  148.     cdb[0] = CMD_MODE_SENSE;
  149.     cdb[1] = Lun;
  150.     cdb[4] = 12;
  151.     cmd->scsi_Length = 12;
  152.     cmd->scsi_Data = (UWORD *) sns;
  153.     cmd->scsi_Flags = SCSIF_READ;
  154.     break;
  155.  
  156.   case WFMARK:  /* write file mark */
  157.     cdb[0] = CMD_FILEMARK;
  158.     cdb[1] = Lun;
  159.     cdb[4] = (UBYTE) bn & 0xff;
  160.     MPR0("Writing filemark\n");
  161.     break;
  162.  
  163.   case TSKIPF:   /* skip over filemarks */
  164.     cdb[0] = CMD_SPACE;
  165.     cdb[1] = Lun | 0x01;
  166.     cdb[3] = (UBYTE) bn >> 8;
  167.     cdb[4] = (UBYTE) bn & 0xff;
  168.     break;
  169.  
  170.   case TSKIPE:   /* skip to end-of-data */
  171.     cdb[0] = CMD_SPACE;
  172.     cdb[1] = Lun | 0x03;
  173.     MPR0("Skipping to end of data\n");
  174.     break;
  175.  
  176.   case TRETEN:  /* retension tape */
  177.     cdb[0] = CMD_LOAD_UNLOAD;
  178.     cdb[1] = Lun;
  179.     cdb[4] = 0x03;
  180.     MPR0("Retensioning\n");
  181.     break;
  182.  
  183.   case RDCAP:  /* read tape capacity.  3M drive only */
  184.     cdb[0] = CMD_READ_CAPACITY;
  185.     cdb[1] = Lun;
  186.     cmd->scsi_CmdLength = 10;
  187.     cmd->scsi_Length = 8;
  188.     cmd->scsi_Data = (UWORD *) sns;
  189.     cmd->scsi_Flags = SCSIF_READ;
  190.     break;
  191.  
  192.   case RAWCMD:  /* write user-provided control command */
  193.     i = 0;
  194.     z = (char *)TapeBuff[bn];
  195.     while(*z!='\n' && i<10)  cdb[i++] = (UBYTE) 0xff & strtoul (z,&z,16);
  196.     cdb[1] |= Lun;
  197.     if(cdb[0] == CMD_REWIND) blknum = reserved;
  198.     if(cdb[0] >= 0x20) cmd->scsi_CmdLength = 10;
  199.     if(cdb[0] >= 0xa0) cmd->scsi_CmdLength = 12;
  200.     cmd->scsi_Data = (UWORD *) sns;
  201.     MPR1("Raw command %02X\n",cdb[0]);
  202.     break;
  203.  
  204.   case MDSET:  /* set fixed-mode block length */
  205.     cdb[0] = CMD_MODE_SELECT;
  206.     cdb[1] = Lun;
  207.     cdb[4] = 12;
  208.     for (i=0 ; i<12; i++) sns[i] = 0x00;
  209.     sns[2] = 0x10;  /* buffered mode */
  210.     sns[3] = 8;
  211.     if(!bn) *((ULONG *)&sns[8]) = blksize & 0x00ffffff; /* block length */
  212.     cmd->scsi_Length = 12;
  213.     cmd->scsi_Data = (UWORD *) sns;
  214.     cmd->scsi_Flags = SCSIF_WRITE;
  215.     MPR1("Mode Select block size %d\n",blksize);
  216.     break;
  217.  
  218.   case USRMODE:  /* write user-provided mode-select data */
  219.     for (i=0 ; i<64; i++) sns[i] = 0x00;
  220.     i = 0;
  221.     z = (char *)TapeBuff[bn];
  222.     while(*z!='\n' && i<64)  sns[i++] = (UBYTE) 0xff & strtoul (z,&z,16);
  223.     cdb[0] = CMD_MODE_SELECT;
  224.     cdb[1] = Lun;
  225.     cdb[4] = i;
  226.     cmd->scsi_Length = i;
  227.     cmd->scsi_Data = (UWORD *) sns;
  228.     cmd->scsi_Flags  = SCSIF_WRITE;
  229.     MPR0("User Mode-Select\n");
  230.     break;
  231.  
  232.   }
  233.  
  234. #if DBUG
  235.   MPR3("CDB = %02x %02x %02x",cdb[0],cdb[1],cdb[2]);
  236.   MPR3("%02x %02x %02x\n",cdb[3],cdb[4],cdb[5]);
  237.   MPR1("ADDR = %X\n", cmd->scsi_Data );
  238.   MPR1("LENG = %X\n\n", cmd->scsi_Length );
  239.   return(0L);
  240. #endif
  241.  
  242.   if(ctl == CTLWAIT) {
  243.        DoIO ((struct IORequest *)ior);    /* start sync io */
  244.        return((long)(ior->io_Error));
  245.   }
  246.   else {
  247.        SendIO((struct IORequest *)ior);  /* start async io */
  248.        inprog = TRUE;
  249.        return(0L);
  250.   }
  251. }
  252.  
  253.