home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 498b.lha / BTNtape_v2.0 / tapeio.c < prev    next >
C/C++ Source or Header  |  1991-04-08  |  7KB  |  249 lines

  1. /*
  2. **  TapeIO: performs operations to the tape unit via SCSI-direct for BTNtape
  3. **     Version 2.0  03/29/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_READ_CAPACITY     0x25
  44.  
  45. extern UBYTE  *cdb;
  46. extern UBYTE  *sns;
  47. extern UBYTE  *inq;
  48. extern struct SCSICmd  *cmd;
  49. extern UBYTE  *TapeBuff[2];
  50. extern struct IOStdReq *ior;
  51. extern ULONG  blknum;
  52. extern ULONG  blksize;
  53. extern ULONG  numblks;
  54. extern ULONG  TBSize;
  55. extern ULONG  rwlen;
  56. extern ULONG  tranlen;
  57. extern ULONG  bugmask;
  58. extern ULONG  fmarks;
  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)
  76.          return((long)((ior->io_Error << 8) + cmd->scsi_Status));
  77.  }
  78.  if(toper == TFINISH) return(0L);
  79.  cmd->scsi_Command = cdb;
  80.  cmd->scsi_CmdLength = 6;
  81.  cmd->scsi_Status = 0;
  82.  ior->io_Command = HD_SCSICMD;
  83.  ior->io_Data = (APTR) cmd;
  84.  ior->io_Length = sizeof(struct SCSICmd);
  85.  ior->io_Error = 0;
  86.  for (i=0 ; i<10; i++) cdb[i] = 0x00;
  87.  
  88.  switch(toper) {
  89.  
  90.   case TWRITE:
  91.     if(DAC && ((blknum+numblks)>=tpsize)) NewTape();
  92.     cdb[0] = CMD_SCSI_WRITE;
  93.     cdb[1] = Lun | fixedbit;
  94.     *((UWORD *)&cdb[2]) = (SEQ) ? (UWORD)(tranlen>>8) : (UWORD) blknum;
  95.     cdb[4] = (UBYTE) tranlen & 0xff;
  96.  /* cmd->scsi_Data = (UWORD *) TapeBuff[bn]; */      /* 2090A bug fix */
  97.     cmd->scsi_Data = (UWORD *) ((ULONG) TapeBuff[bn] | bugmask);
  98.     cmd->scsi_Length = rwlen;
  99.     cmd->scsi_Flags = SCSIF_WRITE;
  100.     MPR2("Writing block %u * %d\n",blknum,tranlen);
  101.     break;
  102.  
  103.   case TREAD:
  104.     if(DAC && ((blknum+numblks)>=tpsize)) NewTape();
  105.     cdb[0] = CMD_SCSI_READ;
  106.     cdb[1] = Lun | fixedbit;
  107.     *((UWORD *)&cdb[2]) = (SEQ) ? (UWORD)(tranlen>>8) : (UWORD) blknum;
  108.     cdb[4] = (UBYTE) tranlen & 0xff;
  109.     cmd->scsi_Data = (UWORD *) TapeBuff[bn];
  110.     cmd->scsi_Length = rwlen;
  111.     cmd->scsi_Flags = SCSIF_READ;
  112.     MPR2("Reading block %u * %d\n",blknum,tranlen);
  113.     break;
  114.  
  115.   case TSENSE:
  116.     for (i=0 ; i<32; i++) sns[i] = 0;
  117.     cdb[0] = CMD_REQUEST_SENSE;
  118.     cdb[1] = Lun;
  119.     cdb[4] = 32;  /* extended sense */
  120.     cmd->scsi_Length = 32;
  121.     cmd->scsi_Data = (UWORD *) sns;
  122.     cmd->scsi_Flags = SCSIF_READ;
  123.     break;
  124.  
  125.   case TREWIND:
  126.     cdb[0] = CMD_REWIND;
  127.     cdb[1] = Lun;
  128.     cmd->scsi_Length = 0;
  129.     cmd->scsi_Flags  = 0;
  130.     MPR0("Rewinding\n");
  131.     break;
  132.  
  133.   case INQUIRY:  /* read drive information */
  134.     cdb[0] = CMD_INQUIRY;
  135.     cdb[1] = Lun;
  136.     cdb[4] = 36;
  137.     cmd->scsi_Length = 36;
  138.     cmd->scsi_Data = (UWORD *) inq;
  139.     cmd->scsi_Flags = SCSIF_READ;
  140.     break;
  141.  
  142.   case TREADY:  /* test unit ready */
  143.     cdb[0] = CMD_TEST_UNIT_READY;
  144.     cdb[1] = Lun;
  145.     cmd->scsi_Length = 0;
  146.     cmd->scsi_Flags = 0;
  147.     break;
  148.  
  149.   case MDSNS:
  150.     for (i=0 ; i<12; i++) sns[i] = 0;
  151.     cdb[0] = CMD_MODE_SENSE;
  152.     cdb[1] = Lun;
  153.     cdb[4] = 12;
  154.     cmd->scsi_Length = 12;
  155.     cmd->scsi_Data = (UWORD *) sns;
  156.     cmd->scsi_Flags = SCSIF_READ;
  157.     break;
  158.  
  159.   case WFMARK:  /* write file mark */
  160.     cdb[0] = CMD_FILEMARK;
  161.     cdb[1] = Lun;
  162.     cdb[4] = (UBYTE) fmarks;
  163.     cmd->scsi_Length = 0;
  164.     cmd->scsi_Flags = 0;
  165.     MPR0("Writing filemark\n");
  166.     break;
  167.  
  168.   case TSKIP:   /* skip over files */
  169.     cdb[0] = CMD_SPACE;
  170.     cdb[1] = Lun | 0x01;  /* space file marks */
  171.     i = fmarks * bn;
  172.     cdb[3] = (UBYTE) i >> 8;
  173.     cdb[4] = (UBYTE) i & 0xff;
  174.     cmd->scsi_Length = 0;
  175.     cmd->scsi_Flags = 0;
  176.     MPR1("Skipping %d file(s)\n",bn);
  177.     break;
  178.  
  179.   case RDCAP:  /* read tape capacity.  3M drive only */
  180.     cdb[0] = CMD_READ_CAPACITY;
  181.     cdb[1] = Lun;
  182.     cmd->scsi_CmdLength = 10;
  183.     cmd->scsi_Length = 8;
  184.     cmd->scsi_Data = (UWORD *) sns;
  185.     cmd->scsi_Flags = SCSIF_READ;
  186.     break;
  187.  
  188.   case RAWCMD:  /* write user-provided control command */
  189.     i = 0;
  190.     z = (char *)TapeBuff[bn];
  191.     while(*z!='\n' && i<10)  cdb[i++] = (UBYTE) 0xff & strtoul (z,&z,16);
  192.     cdb[1] |= Lun;
  193.     if(cdb[0]==CMD_REWIND) blknum = reserved;
  194.     cmd->scsi_Data = (UWORD *) sns;
  195.     cmd->scsi_Length = 0;
  196.     cmd->scsi_Flags  = 0;
  197.     MPR0("Raw command\n");
  198.     break;
  199.  
  200.   case MDSET:  /* set fixed-mode block length */
  201.     cdb[0] = CMD_MODE_SELECT;
  202.     cdb[1] = Lun;
  203.     cdb[4] = 12;
  204.     for (i=0 ; i<12; i++) sns[i] = 0x00;
  205.     sns[2] = 0x10;  /* buffered mode */
  206.     sns[3] = 8;
  207.     if(!bn) *((ULONG *)&sns[8]) = blksize & 0x00ffffff; /* block length */
  208.     cmd->scsi_Length = 12;
  209.     cmd->scsi_Data = (UWORD *) sns;
  210.     cmd->scsi_Flags = SCSIF_WRITE;
  211.     MPR1("Mode Select block size %d\n",blksize);
  212.     break;
  213.  
  214.   case USRMODE:  /* write user-provided mode-select data */
  215.     for (i=0 ; i<64; i++) sns[i] = 0x00;
  216.     i = 0;
  217.     z = (char *)TapeBuff[bn];
  218.     while(*z!='\n' && i<64)  sns[i++] = (UBYTE) 0xff & strtoul (z,&z,16);
  219.     cdb[0] = CMD_MODE_SELECT;
  220.     cdb[1] = Lun;
  221.     cdb[4] = i;
  222.     cmd->scsi_Length = i;
  223.     cmd->scsi_Data = (UWORD *) sns;
  224.     cmd->scsi_Flags  = SCSIF_WRITE;
  225.     MPR0("User Mode-Select\n");
  226.     break;
  227.  
  228.   }
  229.  
  230. #if DBUG
  231.   MPR3("CDB = %02x %02x %02x",cdb[0],cdb[1],cdb[2]);
  232.   MPR3("%02x %02x %02x\n",cdb[3],cdb[4],cdb[5]);
  233.   MPR1("ADDR = %X\n", cmd->scsi_Data );
  234.   MPR1("LENG = %X\n\n", cmd->scsi_Length );
  235.   return(0L);
  236. #endif
  237.  
  238.   if(ctl == CTLWAIT) {
  239.        DoIO ((struct IORequest *)ior);    /* start sync io */
  240.        return((long)((ior->io_Error << 8) + cmd->scsi_Status));
  241.   }
  242.   else {
  243.        SendIO((struct IORequest *)ior);  /* start async io */
  244.        inprog = TRUE;
  245.        return(0L);
  246.   }
  247. }
  248.  
  249.