home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * $Id: scsi-aix.c,v 1.2 1992/09/12 18:10:50 ak Exp $
- *****************************************************************************
- * $Log: scsi-aix.c,v $
- * Revision 1.2 1992/09/12 18:10:50 ak
- * Added scsi_name
- * Added device name support to tctl.c
- *
- * Revision 1.1 1992/09/02 19:05:17 ak
- * Initial revision
- *
- *****************************************************************************/
-
- static char *rcsid = "$Id: scsi-aix.c,v 1.2 1992/09/12 18:10:50 ak Exp $";
-
- #include <stdio.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <sys/devinfo.h>
- #include <sys/scsi.h>
- #include <sys/tape.h>
-
- #define _far
-
- #include "scsi.h"
- #include "tapedrvr.h"
-
- #define CDB_LEN 12
- #define SENSE_LEN 40
-
- typedef unsigned char BYTE;
-
- typedef struct SCB { int dummy; } SCB;
-
- static BYTE sense_cmd[6] = { CmdRequestSense, 0, 0, 0, 0, 0 };
- static int hdev;
- static int trace = 0;
- static int blocksize = 512;
- enum SenseMode senseMode = Sensekey;
-
- static void
- fatal(char *msg, ...)
- {
- va_list ap;
- fprintf(stderr, "Fatal SCSI error: ");
- va_start(ap, msg);
- vfprintf(stderr, msg, ap);
- va_end (ap);
- perror(" ");
- fprintf(stderr, "\n");
- exit (2);
- }
-
- command(BYTE *cdb, int len)
- {
- int i;
- fprintf(stderr, "SCSI op:");
- for (i = 0; i < len; ++i)
- fprintf(stderr, " %02X", cdb[i]);
- fprintf(stderr, "\n");
- }
-
- status(BYTE *sense, int len)
- {
- int i;
- fprintf(stderr, "SCSI status:");
- for (i = 0; i < len; ++i) {
- if (i && (i % 16) == 0)
- fprintf(stderr, "\n ");
- fprintf(stderr, " %02X", sense[i]);
- }
- fprintf(stderr, "\n");
- }
-
- void
- scsi_name(char *name)
- {
- char *cp;
-
- if (!name) {
- name = getenv("TAPE");
- if (name == NULL)
- fatal("Missing environment name TAPE\n");
- }
- while (*name == '+')
- ++name;
-
- hdev = openx(name, O_RDWR, 0, SC_DIAGNOSTIC);
- if (hdev < 0)
- fatal("Cannot access device %s", name);
-
- if ((cp = getenv("TAPEMODE")) != NULL)
- senseMode = atoi(cp);
- }
-
- void
- scsi_file(int fd)
- {
- char *cp;
-
- hdev = fd;
-
- if ((cp = getenv("TAPEMODE")) != NULL)
- senseMode = atoi(cp);
- }
-
- void
- scsi_init(void)
- {
- scsi_name(NULL);
- }
-
- void
- scsi_term(void)
- {
- close(hdev);
- }
-
- void
- scsi_trace(int level)
- {
- trace = level;
- }
-
- void *
- scsi_alloc(void)
- {
- void *p = malloc(sizeof(SCB));
- if (p == NULL)
- fatal("No memory for SCSI Control Block\n");
- }
-
- void
- scsi_free(void *p)
- {
- free(p);
- }
-
- int
- scsi_cmd(int target, int lun,
- void *cdb, int cdb_len, void *sense, int sense_len,
- void _far *data, long data_len,
- int readflag)
- {
- BYTE cmd, *sptr;
- int rc, ern;
- struct sc_iocmd io;
-
- if (cdb_len > CDB_LEN || sense_len > SENSE_LEN)
- return SenseKey+IllegalRequest;
-
- if (trace)
- command(cdb, cdb_len);
-
- io.data_length = data_len;
- io.buffer = data;
- io.timeout_value = 2 * 3600;
- io.flags = data_len ? (readflag ? B_READ : B_WRITE) : 0;
- io.command_length = cdb_len;
- memcpy(io.scsi_cdb, cdb, cdb_len);
- rc = ioctl(hdev, STIOCMD, &io);
- ern = errno;
-
- if (trace >= 2) {
- if (rc < 0)
- fprintf(stderr, "ioctl errno %d\n", errno);
- if (io.status_validity == 1)
- fprintf(stderr, "SCSI bus status %X\n", io.scsi_bus_status);
- if (io.status_validity == 2)
- fprintf(stderr, "adapter status %X\n", io.adapter_status);
- }
-
- if (rc >= 0)
- return NoError;
- if (ern != EIO)
- return SystemError + ern;
- if (io.status_validity == 1 && io.scsi_bus_status != CheckStatus)
- return StatusError + io.scsi_bus_status;
- if (io.status_validity == 2)
- return HostError + io.adapter_status;
-
- /* CheckStatus */
-
- if (io.scsi_cdb[0] == CmdRequestSense)
- return StatusError + CheckStatus;
-
- io.data_length = sense_len;
- io.buffer = sense;
- io.timeout_value = 20;
- io.flags = B_READ;
- io.command_length = sizeof sense_cmd;
- memcpy(io.scsi_cdb, sense_cmd, sizeof sense_cmd);
- io.scsi_cdb[4] = sense_len;
- rc = ioctl(hdev, STIOCMD, &io);
- ern = errno;
-
- if (rc < 0)
- return SystemError + ern;
- if (io.status_validity == 1)
- return StatusError + io.scsi_bus_status;
- if (io.status_validity == 2)
- return HostError + io.adapter_status;
-
- if (trace)
- status(sense, sense_len);
-
- sptr = (BYTE *)sense;
- if ((sptr[0] & 0x7E) != 0x70)
- return sptr[0] ? ExtendedError + (sptr[0] & 0x7F) : 0;
- if (sense_len <= 2)
- return UnknownError;
- return sptr[2] ? SenseKey + (sptr[2] & 0x0F) : 0;
- }
-
- int
- scsi_start(void *dcb,
- int target, int lun,
- void *cdb, int cdb_len, int sense_len,
- void _far *data, long data_len,
- int readflag)
- {
- return DriverError;
- }
-
- int
- scsi_wait(void *dcb, void *sense, int wait)
- {
- return DriverError;
- }
-
- int
- scsi_reset(int target, int lun, int bus)
- {
- return DriverError;
- }
-
- long
- scsi_get_blocksize(int target, int lun)
- {
- return blocksize;
- }
-
- long
- scsi_set_blocksize(int target, int lun, long size)
- {
- int rc;
- struct stchgp chgp;
-
- chgp.st_ecc = ST_NOECC;
- chgp.st_blksize = size;
- rc = ioctl(hdev, STIOCHGP, &chgp);
- if (rc < 0)
- return SystemError + errno;
- blocksize = size;
- return blocksize;
- }
-
- int
- scsi_set_trace(int level)
- {
- return DriverError;
- }
-
- char *
- scsi_error(int code)
- {
- static char text[80], *cp;
-
- if (code == 0)
- return "No error";
- if (code == ComeAgain)
- return "Busy";
- switch (ErrorClass(code)) {
- case ErrorClass(SenseKey):
- return senseTab[code & 0x0F];
- case ErrorClass(ExtendedError):
- switch (senseMode) {
- case TDC3600:
- sprintf(text, "Error code: %s",
- find_error(tdc3600ercd, ErrorCode(code)));
- break;
- default:
- sprintf(text, "Additional sense code: %02X",
- ErrorCode(code));
- }
- break;
- case ErrorClass(StatusError):
- sprintf(text, "Target status: %s",
- find_error(targetStatusTab, ErrorCode(code)));
- break;
- case ErrorClass(DriverError):
- sprintf(text, "Operation not implemented");
- break;
- case ErrorClass(SystemError):
- cp = strerror(ErrorCode(code));
- if (cp)
- strcpy(text, cp);
- else
- sprintf(text, "System error: %u", ErrorCode(code));
- break;
- case ErrorClass(HostError):
- sprintf(text, "Host adapter error: %u", ErrorCode(code));
- break;
- default:
- sprintf(text, "Other error: %04X", code);
- break;
- }
- return text;
- }
-