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