Category : C Source Code
Archive   : GTAK201S.ZIP
Filename : SCSIASPI.C
* $Id: scsiaspi.c,v 1.2 1992/09/02 19:05:35 ak Rel $
*****************************************************************************
* $Log: scsiaspi.c,v $
* Revision 1.2 1992/09/02 19:05:35 ak
* Version 2.0
* - EMX version
* - AIX version
* - SCSI-2 commands
* - ADD Driver
* - blocksize support
*
* Revision 1.1.1.1 1992/01/06 20:27:32 ak
* Interface now based on ST01 and ASPI.
* AHA_DRVR no longer supported.
* Files reorganized.
*
* Revision 1.1 1992/01/06 20:27:30 ak
* Initial revision
*
*****************************************************************************/
static char *rcsid = "$Id: scsiaspi.c,v 1.2 1992/09/02 19:05:35 ak Rel $";
#include
#include
#include
#include
#ifdef OS2
#error "ASPI interface not usable for OS/2"
#endif
#include
#include
#include
#include "aspi.h"
#include "scsi.h"
static int trace;
static int handle;
static void (_far * api)(SRB _far *);
SenseMode senseMode = SenseKey;
static long blocksize = 512;
#define ASPI(srb) (*api)(srb)
static void
fatal(char *msg, ...)
{
va_list ap;
fprintf(stderr, "Fatal SCSI error: ");
va_start(ap, msg);
vfprintf(stderr, msg, ap);
va_end (ap);
fprintf(stderr, "\n");
exit (2);
}
static void
command(SRB *srb)
{
int i;
printf("SCSI op:");
for (i = 0; i < srb->u.cmd.cdb_len; ++i)
printf(" %02X", srb->u.cmd.cdb_st[i]);
printf("\n");
}
static void
status(SRB *srb)
{
int i;
printf("SCSI status:");
for (i = 0; i < srb->u.cmd.sense_len; ++i) {
if (i && (i % 16) == 0)
printf("\n ");
printf(" %02X", srb->u.cmd.cdb_st[srb->u.cmd.cdb_len + i]);
}
printf("\n");
}
void
scsi_init(void)
{
union REGS r;
struct SREGS sr;
char *cp;
#ifndef OS2
if (_osmajor >= 10)
fatal("Cannot use SCSI interface in OS/2 DOS mode\n");
#endif
if ((handle = open("SCSIMGR$", O_BINARY|O_RDWR)) < 0)
fatal("SCSI Manager not found\n");
r.x.ax = 0x4402; /* Ioctl Read */
sr.ds = FP_SEG((void _far *)&api);
r.x.dx = FP_OFF((void _far *)&api);
r.x.cx = 4;
r.x.bx = handle;
intdosx(&r, &r, &sr);
if (r.x.cflag)
fatal("SCSI Manager Ioctl failure\n");
if ((cp = getenv("TAPEMODE")) != NULL)
senseMode = atoi(cp);
}
void
scsi_file(int fd)
{
scsi_init();
}
void
scsi_term(void)
{
close(handle);
}
void
scsi_trace(int level)
{
trace = level;
}
void *
scsi_alloc(void)
{
void *p = malloc(sizeof(SRB));
if (p == NULL)
fatal("No memory for SCSI Request Block\n");
}
void
scsi_free(void *p)
{
free(p);
}
int
scsi_start(void *ctrl,
int target, int lun,
void *cdb, int cdb_len, int sense_len,
void far *data, long data_len,
int readflag)
{
SRB *srb = ctrl;
srb->cmd = SRB_Command;
srb->status = SRB_Busy;
srb->ha_num = 0;
srb->flags = data_len ? readflag ? SRB_Read : SRB_Write
: SRB_NoTransfer;
srb->u.cmd.target = target;
srb->u.cmd.lun = lun;
srb->u.cmd.data_len = data_len;
srb->u.cmd.sense_len = sense_len;
srb->u.cmd.data_ptr = data;
srb->u.cmd.link_ptr = 0;
srb->u.cmd.cdb_len = cdb_len;
memcpy(srb->u.cmd.cdb_st+0, cdb, cdb_len);
memset(srb->u.cmd.cdb_st+cdb_len, 0, sense_len);
if (trace)
command(srb);
ASPI(srb);
if (trace >= 2)
printf("SRB status: %02X\n", srb->status);
switch (srb->status) {
case SRB_Busy:
case SRB_Error:
return ComeAgain;
case SRB_Done:
return NoError;
default:
return DriverError + srb->status;
}
}
int
scsi_wait(void *ctrl, void *sense, int wait)
{
SRB *srb = ctrl;
int i, slen, ret;
unsigned char *sptr;
for (;;) {
if (trace >= 2)
printf("SRB status: %02X\n", srb->status);
switch (srb->status) {
case SRB_Busy:
if (wait) {
union REGS r;
/* DESQview - give up timeslice */
r.x.ax = 0x1000;
int86(0x15, &r, &r);
/* Windows 3+ - give up timeslice */
r.x.ax = 0x1680;
int86(0x2F, &r, &r);
continue;
}
return ComeAgain;
case SRB_Error:
break;
case SRB_Done:
return NoError;
default:
return DriverError + srb->status;
}
break;
}
if (srb->u.cmd.ha_status) {
if (trace)
printf("SCSI host adapter error: %02X\n",
srb->u.cmd.ha_status);
return HostError + srb->u.cmd.ha_status;
}
switch (srb->u.cmd.target_status) {
case GoodStatus:
return NoError;
case CheckStatus:
break;
default:
if (trace)
printf("SCSI completion status: %02X\n",
srb->u.cmd.target_status);
return StatusError + srb->u.cmd.target_status;
}
slen = srb->u.cmd.sense_len ? srb->u.cmd.sense_len : 14;
memcpy(sense, srb->u.cmd.cdb_st + srb->u.cmd.cdb_len, slen);
if (trace)
status(srb);
sptr = (unsigned char *)sense;
if ((sptr[0] & 0x7E) != 0x70)
return ExtendedError + (sptr[0] & 0x7F);
if (srb->u.cmd.sense_len <= 2)
return UnknownError;
return SenseKey + (sptr[2] & 0x0F);
}
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)
{
SRB srb;
int ret;
ret = scsi_start(&srb,
target, lun,
cdb, cdb_len, sense_len,
data, data_len,
readflag);
while (ret == ComeAgain)
ret = scsi_wait(&srb, sense, 1);
return ret;
}
int
scsi_reset(int target, int lun, int bus)
{
SRB srb;
srb.cmd = SRB_Reset;
srb.status = SRB_Busy;
srb.ha_num = 0;
srb.flags = SRB_NoTransfer;
srb.u.res.target = target;
srb.u.res.lun = lun;
ASPI(&srb);
for (;;) {
switch (srb.status) {
case SRB_Busy:
continue;
case SRB_Done:
return NoError;
default:
return DriverError + srb.status;
}
}
}
long
scsi_get_blocksize(int target, int lun)
{
return blocksize;
}
long
scsi_set_blocksize(int target, int lun, long size)
{
long old = blocksize;
blocksize = size;
return old;
}
int
scsi_set_trace(int level)
{
int old = trace;
trace = level;
return old;
}
char *
scsi_error(int code)
{
static char text[80];
static ErrorTable driverTab[] = {
SRB_Aborted, "Command aborted",
SRB_BadAbort, "Could not abort",
SRB_InvalidCmd, "Invalid ASPI request",
SRB_InvalidHA, "Invalid host adapter",
SRB_BadDevice, "Device not installed",
-1
};
static ErrorTable hostTab[] = {
/* Adaptec 154x host adapter status */
SRB_NoError, "No error",
SRB_Timeout, "Selection timeout",
SRB_DataLength, "Data length error",
SRB_BusFree, "Unexpected bus free",
SRB_BusSequence, "Target bus sequence failure",
-1
};
if (code == 0)
return "No error";
if (code == ComeAgain)
return "Busy";
switch (ErrorClass(code)) {
case SenseKey:
return senseTab[code & 0x0F];
case 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 StatusError:
sprintf(text, "Target status: %s",
find_error(targetStatusTab, ErrorCode(code)));
break;
case DriverError:
sprintf(text, "Driver error: %s",
find_error(driverTab, ErrorCode(code)));
break;
case SystemError:
sprintf(text, "System error: %u", ErrorCode(code));
break;
case HostError:
sprintf(text, "Host adapter error: %s",
find_error(hostTab, ErrorCode(code)));
break;
default:
sprintf(text, "Other error: %04X", code);
break;
}
return text;
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/