;
;[1m[32m        ____     ___        ___     ___ ___ ___ ___ ____      ___ ___ ___[0m
;[1m[32m         /  /__//_         /__ /  //_ //__ /  //_    /  / / //_ //__//_  [0m
;[1m[32m        /  /  //__        ___//__//__/___//__//     /  /_/_//  //  \/__  [0m
;
;[1m[32m-----------------------------------------------------------------------------[0m
;   - FOR ABO'S CONTACT US AT:   BP:28 1170 WATERMAEL-BOITSFORT 1 BELGIUM!!...
;
;[1m[32m-----------------------------------------------------------------------------[0m
;                           - DON'T SEND ANY DISKS -
;
;[1m[32m-----------------------------------------------------------------------------[0m
;
;
;
;                      [33m THE LEGENDARY >> SUBSOFTWARE << IN 87/88/89/90/91!!...
;                      [1m[32m ------------------------------------------------------
;
/*
** RewindTape.c - rewind all SCSI tape units
** Copyright (C) 1990 by Ralph Babel, Falkenweg 3, D-6204 Taunusstein, FRG
** all rights reserved - alle Rechte vorbehalten
**
** 05-Jul-1990 created
*/

/*** included files ***/

#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <devices/scsidisk.h>
#include <libraries/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>

/*** external symbol references ***/

void fprintf(BPTR, const char *, ...);

/*** constants ***/

#define MAXBUF 252

/*** structures ***/

struct InquiryData
 {
 UBYTE DeviceType;
 UBYTE Qualifier;
 UBYTE Version;
 UBYTE Reserved;
 };

/*** entry point (RXStartUp.obj) ***/

void __stdargs __saveds main(
ULONG argc,
const char *const argv[])
 {
 BPTR fh;
 UBYTE *sensedata;
 struct MsgPort *mp;
 struct IOStdReq *io;
 struct InquiryData *id;
 ULONG unit;
 struct SCSICmd SC;
 UBYTE command[6];

 if(argc != 0) /* CLI only! */
  {
  fh = Output();

  if((id = AllocMem(sizeof(struct InquiryData), MEMF_CHIP)) != NULL)
   {
   if((sensedata = AllocMem(MAXBUF, MEMF_CHIP)) != NULL)
    {
    if((mp = CreatePort(NULL, 0)) != NULL)
     {
     if((io = CreateStdIO(mp)) != NULL)
      {
      for(unit = 0; unit <= 6; ++unit)
       {
       fprintf(fh, "Unit %ld\n", unit);

       if(OpenDevice("gvpscsi.device", unit, (struct IORequest *)io, 0) == 0)
        {
        io->io_Command = HD_SCSICMD;
        io->io_Length  = sizeof(struct SCSICmd);
        io->io_Data    = (APTR)&SC;

        SC.scsi_Data        = (UWORD *)id;
        SC.scsi_Length      = sizeof(struct InquiryData);
        SC.scsi_Command     = command;
        SC.scsi_CmdLength   = 6;

#ifdef SCSIF_AUTOSENSE

        SC.scsi_Flags       = SCSIF_READ | SCSIF_AUTOSENSE;
        SC.scsi_SenseData   = sensedata;
        SC.scsi_SenseLength = MAXBUF;
        SC.scsi_SenseActual = 0;

#else

        SC.scsi_Flags       = SCSIF_READ;

#endif

        command[0] = 0x12; /* SCSI_INQUIRY */
        command[1] = (unit / 10) % 10 << 5;
        command[2] = 0;
        command[3] = 0;
        command[4] = sizeof(struct InquiryData);
        command[5] = 0;

        (void)DoIO((struct IORequest *)io);

        fprintf(fh, "io_Error         = %d\n",  io->io_Error);
        fprintf(fh, "scsi_Status      = %d\n",  SC.scsi_Status);
        fprintf(fh, "scsi_CmdActual   = %d\n",  SC.scsi_CmdActual);
        fprintf(fh, "scsi_Actual      = %ld\n", SC.scsi_Actual);

#ifdef SCSIF_AUTOSENSE

        fprintf(fh, "scsi_SenseActual = %d\n",  SC.scsi_SenseActual);

        if(SC.scsi_SenseActual != 0)
         {
         UWORD i;

         fprintf(fh, "\nSenseData:");

         for(i = 0; i < SC.scsi_SenseActual; ++i)
          fprintf(fh, " %02x", sensedata[i]);

         fprintf(fh, "\n");
         }

#endif

        if(io->io_Error == 0
        && SC.scsi_Actual >= 1
        && id->DeviceType == 0x01) /* sequential-access device */
         {
         io->io_Command = HD_SCSICMD;
         io->io_Length  = sizeof(struct SCSICmd);
         io->io_Data    = (APTR)&SC;

         SC.scsi_Data        = NULL;
         SC.scsi_Length      = 0;
         SC.scsi_Command     = command;
         SC.scsi_CmdLength   = 6;

#ifdef SCSIF_AUTOSENSE

         SC.scsi_Flags       = SCSIF_READ | SCSIF_AUTOSENSE;
         SC.scsi_SenseData   = sensedata;
         SC.scsi_SenseLength = MAXBUF;
         SC.scsi_SenseActual = 0;

#else

         SC.scsi_Flags       = SCSIF_READ;

#endif

         command[0] = 0x01; /* REWIND */
         command[1] = (unit / 10) % 10 << 5;
         command[2] = 0;
         command[3] = 0;
         command[4] = 0;
         command[5] = 0;

         (void)DoIO((struct IORequest *)io);

         fprintf(fh, "io_Error         = %d\n",  io->io_Error);
         fprintf(fh, "scsi_Status      = %d\n",  SC.scsi_Status);
         fprintf(fh, "scsi_CmdActual   = %d\n",  SC.scsi_CmdActual);
         fprintf(fh, "scsi_Actual      = %ld\n", SC.scsi_Actual);

#ifdef SCSIF_AUTOSENSE

         fprintf(fh, "scsi_SenseActual = %d\n",  SC.scsi_SenseActual);

         if(SC.scsi_SenseActual != 0)
          {
          UWORD i;

          fprintf(fh, "\nSenseData:");

          for(i = 0; i < SC.scsi_SenseActual; ++i)
           fprintf(fh, " %02x", sensedata[i]);

          fprintf(fh, "\n");
          }

#endif

         }

        fprintf(fh, "\n");

        CloseDevice((struct IORequest *)io);
        }
       else
        fprintf(fh, "Error %d while opening SCSI unit %ld.\n",
         io->io_Error, unit);
       }

      DeleteStdIO(io);
      }
     else
      fprintf(fh, "Could not create I/O request.\n");

     DeletePort(mp);
     }
    else
     fprintf(fh, "Could not create message port.\n");

    FreeMem(sensedata, MAXBUF);
    }
   else
    fprintf(fh, "Insufficient free store.\n");

   FreeMem(id, sizeof(struct InquiryData));
   }
  else
   fprintf(fh, "Insufficient free store.\n");
  }
 }
