#include <std.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <dos.h>
#include <string.h>
#include <malloc.h>
#include <process.h>
#include "global.h"
#include "request.h"
#include "callaspi.h"
#define SenseText(x,y,z,str) sprintf(&str[strlen(str)], "%x, %x, %x", x,y,z)
#define Error(x) say(x)
#define FLAG_DEFAULT 0x00
#define FLAG_POST 0x01
static const char MgrString[]="SCSIMGR$";
static pfr ASPI_Entry = (pfr) NULL;
/***************************************************************************
*
* (...)
*
***************************************************************************/
static int l_ioctl(unsigned int Handle, unsigned char function, void far *argdx, unsigned int argcx)
{
union {
struct {
unsigned int Offset;
unsigned int Segment;
} X;
void far *ptr;
} Split;
union REGS in, out;
struct SREGS segs;
Split.ptr = argdx;
segs.ds = Split.X.Segment;
in.h.ah = 0x44;
in.h.al = function;
in.x.bx = Handle;
in.x.cx = argcx;
in.x.dx = Split.X.Offset;
int86x( 0x21, &in, &out, &segs);
return (out.x.ax);
}
/***************************************************************************
*
* (...)
*
***************************************************************************/
static int OpenASPI (void)
{
int Handle;
Handle = open((char *)MgrString, O_RDWR);
if (Handle == -1)
{
printf("ASPI driver not found. Loading...\n");
// system("loadaspi.bat");
// execlp("command","command","/c","loadaspi.bat", NULL);
/*
* NOTE: You must put the name of the calling EXE file as
* arg!!!
*/
execlp("aspitsr.exe","aspitsr.exe","/r","main.exe", NULL);
exit(0);
}
if (l_ioctl(Handle, 2, &ASPI_Entry, 4) == -1)
return -1;
close(Handle);
// printf("ASPI manager entry point at %Fp\n", ASPI_Entry);
return 0;
}
/***************************************************************************
*
* (...)
*
***************************************************************************/
void InitRequest (Req,HA,TID,LUN,DataPtr,Count,CDB,CDBLen,post_func)
IO_REQ *Req;
int HA;
int TID;
int LUN;
void far *DataPtr;
unsigned long Count;
char *CDB;
int CDBLen;
void far *post_func;
{
ClearReq(Req);
Req->Command = ASPI_EXEC_COMMAND;
Req->HANumber = HA;
Req->Flags = FLAG_DEFAULT;
Req->TargetID = TID;
Req->TargetLUN = LUN;
Req->DataPtr = (char far *)DataPtr;
Req->DataCount = Count;
Req->SenseCount = 16; /*NUMSENSEBYTES*/
Req->CDBLen = CDBLen;
if (post_func)
{Req->Flags |= FLAG_POST;
Req->post_func = post_func;
}
memcpy(Req->CDB.CDB, CDB, CDBLen);
}
/***************************************************************************
*
* (...)
*
***************************************************************************/
int DoASPI (void *Req, int ShowResp, FLAG post)
{
char *Msg;
char StrBuff[80];
if (ASPI_Entry == NULL)
{
if (OpenASPI())
{
error("Failed to open ASPI manager");
return 1;
}
}
/* Test */
// ((union ReqUnion *)Req)->IO_Req.Req.Flags = 0;
ASPI_Entry(Req);
if (post)
return (0);
else
while (((union ReqUnion *)Req)->IO_Req.Req.Status == ASPI_REQS_REQINPROGRESS)
;
if (ShowResp) {
switch (((union ReqUnion *)Req)->IO_Req.Req.Status) {
case ASPI_REQS_NOERROR:
return 0;
// break;
case ASPI_REQS_REQINPROGRESS:
Msg = "Completion error";
break;
case ASPI_REQS_REQABORTED:
Msg = "Request aborted";
break;
case ASPI_REQS_ERROR:
if (((union ReqUnion *)Req)->IO_Req.Req.HAStatus == ASPI_HAS_NOERROR) {
switch (((union ReqUnion *)Req)->IO_Req.Req.TStatus) {
case ASPI_TS_NOERROR:
Msg = "Deformed response";
break;
case ASPI_TS_CHECKCOND:
{
unsigned char *SenseBuff = &(((union ReqUnion *)Req)->IO_Req.Req.CDB.CDB[((union ReqUnion *)Req)->IO_Req.Req.CDBLen]);
strcpy(StrBuff, "Check condition. ");
Msg = StrBuff;
SenseText(SenseBuff[2], SenseBuff[12], SenseBuff[13], StrBuff);
}
break;
case ASPI_TS_BUSY:
Msg = "Device busy";
break;
case ASPI_TS_RESERVED:
Msg = "Device reservation conflict";
break;
default:
Msg = "Unknown device status";
break;
}
} else {
switch (((union ReqUnion *)Req)->IO_Req.Req.HAStatus) {
case ASPI_HAS_SELTIMEOUT:
Msg = "Device not responding";
break;
case ASPI_HAS_OVERRUN:
Msg = "Data over run";
break;
case ASPI_HAS_BUSFREE:
Msg = "Unexpected bus free";
break;
case ASPI_HAS_BADPHASE:
Msg = "Unexpected SCSI phase";
break;
default:
Msg = "Unknown device status";
break;
}
}
break;
case ASPI_REQS_BADREQ:
Msg = "Ill formed request";
break;
case ASPI_REQS_BADHANUM:
Msg = "Bad host adapter number";
break;
case ASPI_REQS_NODEV:
Msg = "Out of device descriptors";
break;
// case ASPI_REQS_REQINPROGRESS:
default:
Msg = "Completion error";
break;
}
error(Msg);
}
return (((union ReqUnion *)Req)->IO_Req.Req.Status != ASPI_REQS_NOERROR);
}