home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1993 #2 / Image.iso / os2 / gtak212b.zip / SOURCE.ZIP / TAPE / scsi-aix.c < prev    next >
C/C++ Source or Header  |  1992-09-12  |  6KB  |  313 lines

  1. /*****************************************************************************
  2.  * $Id: scsi-aix.c,v 1.2 1992/09/12 18:10:50 ak Exp $
  3.  *****************************************************************************
  4.  * $Log: scsi-aix.c,v $
  5.  * Revision 1.2  1992/09/12  18:10:50  ak
  6.  * Added scsi_name
  7.  * Added device name support to tctl.c
  8.  *
  9.  * Revision 1.1  1992/09/02  19:05:17  ak
  10.  * Initial revision
  11.  *
  12.  *****************************************************************************/
  13.  
  14. static char *rcsid = "$Id: scsi-aix.c,v 1.2 1992/09/12 18:10:50 ak Exp $";
  15.  
  16. #include <stdio.h>
  17. #include <stdarg.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <fcntl.h>
  21. #include <errno.h>
  22. #include <sys/devinfo.h>
  23. #include <sys/scsi.h>
  24. #include <sys/tape.h>
  25.  
  26. #define _far
  27.  
  28. #include "scsi.h"
  29. #include "tapedrvr.h"
  30.  
  31. #define CDB_LEN        12
  32. #define SENSE_LEN    40
  33.  
  34. typedef unsigned char    BYTE;
  35.  
  36. typedef struct SCB { int dummy; } SCB;
  37.  
  38. static BYTE    sense_cmd[6] = { CmdRequestSense, 0, 0, 0, 0, 0 };
  39. static int    hdev;
  40. static int    trace = 0;
  41. static int    blocksize = 512;
  42. enum SenseMode    senseMode = Sensekey;
  43.  
  44. static void
  45. fatal(char *msg, ...)
  46. {
  47.     va_list ap;
  48.     fprintf(stderr, "Fatal SCSI error: ");
  49.     va_start(ap, msg);
  50.     vfprintf(stderr, msg, ap);
  51.     va_end (ap);
  52.     perror(" ");
  53.     fprintf(stderr, "\n");
  54.     exit (2);
  55. }
  56.  
  57. command(BYTE *cdb, int len)
  58. {
  59.     int i;
  60.     fprintf(stderr, "SCSI op:");
  61.     for (i = 0; i < len; ++i)
  62.         fprintf(stderr, " %02X", cdb[i]);
  63.     fprintf(stderr, "\n");
  64. }
  65.  
  66. status(BYTE *sense, int len)
  67. {
  68.     int i;
  69.     fprintf(stderr, "SCSI status:");
  70.     for (i = 0; i < len; ++i) {
  71.         if (i && (i % 16) == 0)
  72.             fprintf(stderr, "\n            ");
  73.         fprintf(stderr, " %02X", sense[i]);
  74.     }
  75.     fprintf(stderr, "\n");
  76. }
  77.  
  78. void
  79. scsi_name(char *name)
  80. {
  81.     char *cp;
  82.  
  83.     if (!name) {
  84.         name = getenv("TAPE");
  85.         if (name == NULL)
  86.             fatal("Missing environment name TAPE\n");
  87.     }
  88.     while (*name == '+')
  89.         ++name;
  90.  
  91.     hdev = openx(name, O_RDWR, 0, SC_DIAGNOSTIC);
  92.     if (hdev < 0)
  93.         fatal("Cannot access device %s", name);
  94.  
  95.     if ((cp = getenv("TAPEMODE")) != NULL)
  96.         senseMode = atoi(cp);
  97. }
  98.  
  99. void
  100. scsi_file(int fd)
  101. {
  102.     char *cp;
  103.  
  104.     hdev = fd;
  105.  
  106.     if ((cp = getenv("TAPEMODE")) != NULL)
  107.         senseMode = atoi(cp);
  108. }
  109.  
  110. void
  111. scsi_init(void)
  112. {
  113.     scsi_name(NULL);
  114. }
  115.  
  116. void
  117. scsi_term(void)
  118. {
  119.     close(hdev);
  120. }
  121.  
  122. void
  123. scsi_trace(int level)
  124. {
  125.     trace = level;
  126. }
  127.  
  128. void *
  129. scsi_alloc(void)
  130. {
  131.     void *p = malloc(sizeof(SCB));
  132.     if (p == NULL)
  133.         fatal("No memory for SCSI Control Block\n");
  134. }
  135.  
  136. void
  137. scsi_free(void *p)
  138. {
  139.     free(p);
  140. }
  141.  
  142. int
  143. scsi_cmd(int target, int lun,
  144.     void *cdb, int cdb_len,    void *sense, int sense_len,
  145.     void _far *data, long data_len,
  146.     int readflag)
  147. {
  148.     BYTE cmd, *sptr;
  149.     int rc, ern;
  150.     struct sc_iocmd io;
  151.  
  152.     if (cdb_len > CDB_LEN || sense_len > SENSE_LEN)
  153.         return SenseKey+IllegalRequest;
  154.  
  155.     if (trace)
  156.         command(cdb, cdb_len);
  157.  
  158.     io.data_length = data_len;
  159.     io.buffer = data;
  160.     io.timeout_value = 2 * 3600;
  161.     io.flags = data_len ? (readflag ? B_READ : B_WRITE) : 0;
  162.     io.command_length = cdb_len;
  163.     memcpy(io.scsi_cdb, cdb, cdb_len);
  164.     rc = ioctl(hdev, STIOCMD, &io);
  165.     ern = errno;
  166.  
  167.     if (trace >= 2) {
  168.         if (rc < 0)
  169.             fprintf(stderr, "ioctl errno %d\n", errno);
  170.         if (io.status_validity == 1)
  171.             fprintf(stderr, "SCSI bus status %X\n", io.scsi_bus_status);
  172.         if (io.status_validity == 2)
  173.             fprintf(stderr, "adapter status %X\n", io.adapter_status);
  174.     }
  175.  
  176.     if (rc >= 0)
  177.         return NoError;
  178.     if (ern != EIO)
  179.         return SystemError + ern;
  180.     if (io.status_validity == 1 && io.scsi_bus_status != CheckStatus)
  181.         return StatusError + io.scsi_bus_status;
  182.     if (io.status_validity == 2)
  183.         return HostError + io.adapter_status;
  184.  
  185.     /* CheckStatus */
  186.  
  187.     if (io.scsi_cdb[0] == CmdRequestSense)
  188.         return StatusError + CheckStatus;
  189.  
  190.     io.data_length = sense_len;
  191.     io.buffer = sense;
  192.     io.timeout_value = 20;
  193.     io.flags = B_READ;
  194.     io.command_length = sizeof sense_cmd;
  195.     memcpy(io.scsi_cdb, sense_cmd, sizeof sense_cmd);
  196.     io.scsi_cdb[4] = sense_len;
  197.     rc = ioctl(hdev, STIOCMD, &io);
  198.     ern = errno;
  199.  
  200.     if (rc < 0)
  201.         return SystemError + ern;
  202.     if (io.status_validity == 1)
  203.         return StatusError + io.scsi_bus_status;
  204.     if (io.status_validity == 2)
  205.         return HostError + io.adapter_status;
  206.     
  207.     if (trace)
  208.         status(sense, sense_len);
  209.  
  210.     sptr = (BYTE *)sense;
  211.     if ((sptr[0] & 0x7E) != 0x70)
  212.         return sptr[0] ? ExtendedError + (sptr[0] & 0x7F) : 0;
  213.     if (sense_len <= 2)
  214.         return UnknownError;
  215.     return sptr[2] ? SenseKey + (sptr[2] & 0x0F) : 0;
  216. }
  217.  
  218. int
  219. scsi_start(void *dcb, 
  220.     int target, int lun,
  221.     void *cdb, int cdb_len, int sense_len,
  222.     void _far *data, long data_len,
  223.     int readflag)
  224. {
  225.     return DriverError;
  226. }
  227.  
  228. int
  229. scsi_wait(void *dcb, void *sense, int wait)
  230. {
  231.     return DriverError;
  232. }
  233.  
  234. int
  235. scsi_reset(int target, int lun, int bus)
  236. {
  237.     return DriverError;
  238. }
  239.  
  240. long
  241. scsi_get_blocksize(int target, int lun)
  242. {
  243.     return blocksize;
  244. }
  245.  
  246. long
  247. scsi_set_blocksize(int target, int lun, long size)
  248. {
  249.     int rc;
  250.     struct stchgp chgp;
  251.  
  252.     chgp.st_ecc = ST_NOECC;
  253.     chgp.st_blksize = size;
  254.     rc = ioctl(hdev, STIOCHGP, &chgp);
  255.     if (rc < 0)
  256.         return SystemError + errno;
  257.     blocksize = size;
  258.     return blocksize;
  259. }
  260.  
  261. int
  262. scsi_set_trace(int level)
  263. {
  264.     return DriverError;
  265. }
  266.  
  267. char *
  268. scsi_error(int code)
  269. {
  270.     static char text[80], *cp;
  271.  
  272.     if (code == 0)
  273.         return "No error";
  274.     if (code == ComeAgain)
  275.         return "Busy";
  276.     switch (ErrorClass(code)) {
  277.     case ErrorClass(SenseKey):
  278.         return senseTab[code & 0x0F];
  279.     case ErrorClass(ExtendedError):
  280.         switch (senseMode) {
  281.         case TDC3600:
  282.             sprintf(text, "Error code: %s",
  283.                 find_error(tdc3600ercd, ErrorCode(code)));
  284.             break;
  285.         default:
  286.             sprintf(text, "Additional sense code: %02X",
  287.                 ErrorCode(code));
  288.         }
  289.         break;
  290.     case ErrorClass(StatusError):
  291.         sprintf(text, "Target status: %s",
  292.             find_error(targetStatusTab, ErrorCode(code)));
  293.         break;
  294.     case ErrorClass(DriverError):
  295.         sprintf(text, "Operation not implemented");
  296.         break;
  297.     case ErrorClass(SystemError):
  298.         cp = strerror(ErrorCode(code));
  299.         if (cp)
  300.             strcpy(text, cp);
  301.         else
  302.             sprintf(text, "System error: %u", ErrorCode(code));
  303.         break;
  304.     case ErrorClass(HostError):
  305.         sprintf(text, "Host adapter error: %u", ErrorCode(code));
  306.         break;
  307.     default:
  308.         sprintf(text, "Other error: %04X", code);
  309.         break;
  310.     }
  311.     return text;
  312. }
  313.