/* @(#)scsi-wnt.c 1.27 01/03/18 Copyright 1998, 1999 J. Schilling, A.L. Faber */
#ifndef lint
static char __sccsid[] =
"@(#)scsi-wnt.c 1.27 01/03/18 Copyright 1998, 1999 J. Schilling, A.L. Faber";
#endif
/*
* Interface for the Win32 ASPI library.
* You need wnaspi32.dll and aspi32.sys
* Both can be installed from ASPI_ME
*
* Warning: you may change this source, but if you do that
* you need to change the _scg_version and _scg_auth* string below.
* You may not return "schily" for an SCG_AUTHOR request anymore.
* Choose your name instead of "schily" and make clear that the version
* string is related to a modified source.
*
* Copyright (c) 1998 J. Schilling
* Copyright (c) 1999 A.L. Faber for the first implementation
* of this interface.
* TODO:
* - DMA resid handling
* - better handling of maxDMA
* - SCSI reset support
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Include for Win32 ASPI AspiRouter
*
* NOTE: aspi-win32.h includes Windows.h and Windows.h includes
* Base.h which has a second typedef for BOOL.
* We define BOOL to make all local code use BOOL
* from Windows.h and use the hidden __SBOOL for
* our global interfaces.
*/
#define BOOL WBOOL /* This is the Win BOOL */
#define format __format
#include <scg/aspi-win32.h>
#undef format
#ifdef __CYGWIN32__ /* Use dlopen() */
#include <dlfcn.h>
#endif
/*
* Warning: you may change this source, but if you do that
* you need to change the _scg_version and _scg_auth* string below.
* You may not return "schily" for an SCG_AUTHOR request anymore.
* Choose your name instead of "schily" and make clear that the version
* string is related to a modified source.
*/
LOCAL char _scg_trans_version[] = "scsi-wnt.c-1.27"; /* The version for this transport*/
/*
* Local defines and constants
*/
/*#define DEBUG_WNTASPI*/
#define MAX_SCG 16 /* Max # of SCSI controllers */
#define MAX_TGT 16 /* Max # of SCSI Targets */
#define MAX_LUN 8 /* Max # of SCSI LUNs */
#ifdef DEBUG_WNTASPI
#endif
struct scg_local {
int dummy;
};
#define scglocal(p) ((struct scg_local *)((p)->local))
/*
* Local variables
*/
LOCAL int busses;
LOCAL DWORD (*pfnGetASPI32SupportInfo)(void) = NULL;
LOCAL DWORD (*pfnSendASPI32Command)(LPSRB) = NULL;
LOCAL BOOL (*pfnGetASPI32Buffer)(PASPI32BUFF) = NULL;
LOCAL BOOL (*pfnFreeASPI32Buffer)(PASPI32BUFF) = NULL;
LOCAL BOOL (*pfnTranslateASPI32Address)(PDWORD, PDWORD) = NULL;
LOCAL BOOL AspiLoaded = FALSE;
LOCAL HANDLE hAspiLib = NULL; /* Used for Loadlib */
#define MAX_DMA_WNT (63L*1024L) /* ASPI-Driver allows up to 64k ??? */
/*
* Local function prototypes
*/
LOCAL void exit_func __PR((void));
#ifdef DEBUG_WNTASPI
LOCAL void DebugScsiSend __PR((SCSI *scgp, SRB_ExecSCSICmd s, int bDisplayBuffer));
#endif
LOCAL void copy_sensedata __PR((SRB_ExecSCSICmd *cp, struct scg_cmd *sp));
LOCAL void set_error __PR((SRB_ExecSCSICmd *cp, struct scg_cmd *sp));
LOCAL BOOL open_driver __PR((SCSI *scgp));
LOCAL BOOL close_driver __PR((void));
LOCAL int ha_inquiry __PR((SCSI *scgp, int id, SRB_HAInquiry *ip));
#ifdef __USED__
LOCAL int resetSCSIBus __PR((SCSI *scgp));
#endif
LOCAL int scsiabort __PR((SCSI *scgp, SRB_ExecSCSICmd *sp));
LOCAL void
exit_func()
{
if (!close_driver())
errmsgno(EX_BAD, "Cannot close Win32-ASPI-Driver.\n");
}
/*
* Return version information for the low level SCSI transport code.
* This has been introduced to make it easier to trace down problems
* in applications.
*/
LOCAL char *
scgo_version(scgp, what)
SCSI *scgp;
int what;
{
if (scgp != (SCSI *)0) {
switch (what) {
case SCG_VERSION:
return (_scg_trans_version);
/*
* If you changed this source, you are not allowed to
* return "schily" for the SCG_AUTHOR request.
*/
case SCG_AUTHOR:
return (_scg_auth_schily);
case SCG_SCCS_ID:
return (__sccsid);
}
}
return ((char *)0);
}
LOCAL int
scgo_open(scgp, device)
SCSI *scgp;
char *device;
{
int busno = scg_scsibus(scgp);
int tgt = scg_target(scgp);
int tlun = scg_lun(scgp);
if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) {
errno = EINVAL;
if (scgp->errstr)
js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
"Illegal value for busno, target or lun '%d,%d,%d'",
busno, tgt, tlun);
return (-1);
}
if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) {
errno = EINVAL;
if (scgp->errstr)
js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
"Open by 'devname' not supported on this OS");
return (-1);
}
/*
* Check if variables are within the range
*/
if (tgt >= 0 && tgt >= 0 && tlun >= 0) {
/*
* This is the non -scanbus case.
*/
;
} else if (tgt != -1 || tgt != -1 || tlun != -1) {
errno = EINVAL;
return (-1);
}
if (scgp->local == NULL) {
scgp->local = malloc(sizeof(struct scg_local));
if (scgp->local == NULL)
return (0);
}
/*
* Try to open ASPI-Router
*/
if (!open_driver(scgp))
return (-1);
/*
* More than we have ...
*/
if (busno >= busses) {
close_driver();
return (-1);
}
/*
* Install Exit Function which closes the ASPI-Router
*/
atexit(exit_func);
/*
* Success after all
*/
return (1);
}
LOCAL int
scgo_close(scgp)
SCSI *scgp;
{
exit_func();
return (0);
}
LOCAL long
scgo_maxdma(scgp, amt)
SCSI *scgp;
long amt;
{
return (MAX_DMA_WNT);
}
LOCAL void *
scgo_getbuf(scgp, amt)
SCSI *scgp;
long amt;
{
if (scgp->debug > 0) {
js_fprintf((FILE *)scgp->errfile,
"scgo_getbuf: %ld bytes\n", amt);
}
scgp->bufbase = malloc((size_t)(amt));
return (scgp->bufbase);
}
LOCAL void
scgo_freebuf(scgp)
SCSI *scgp;
{
if (scgp->bufbase)
free(scgp->bufbase);
scgp->bufbase = NULL;
}
LOCAL __SBOOL
scgo_havebus(scgp, busno)
SCSI *scgp;
int busno;
{
if (busno < 0 || busno >= busses)
return (FALSE);
return (TRUE);
}
LOCAL int
scgo_fileno(scgp, busno, tgt, tlun)
SCSI *scgp;
int busno;
int tgt;
int tlun;
{
if (busno < 0 || busno >= busses ||
tgt < 0 || tgt >= MAX_TGT ||
tlun < 0 || tlun >= MAX_LUN)
return (-1);
/*
* Return fake
*/
return (1);
}
LOCAL int
scgo_initiator_id(scgp)
SCSI *scgp;
{
SRB_HAInquiry s;
if (ha_inquiry(scgp, scg_scsibus(scgp), &s) < 0)
return (-1);
return (s.HA_SCSI_ID);
}
LOCAL int
scgo_isatapi(scgp)
SCSI *scgp;
{
return (-1); /* XXX Need to add real test */
}
/*
* XXX scgo_reset not yet tested
*/
LOCAL int
scgo_reset(scgp, what)
SCSI *scgp;
int what;
{
DWORD Status = 0;
DWORD EventStatus = WAIT_OBJECT_0;
HANDLE Event = NULL;
SRB_BusDeviceReset s;
if (what == SCG_RESET_NOP)
return (0);
if (what != SCG_RESET_BUS) {
errno = EINVAL;
return (-1);
}
/*
* XXX Does this reset TGT or BUS ???
*/
if (scgp->debug > 0) {
js_fprintf((FILE *)scgp->errfile,
"Attempting to reset SCSI device\n");
}
/*
* Check if ASPI library is loaded
*/
if (AspiLoaded == FALSE) {
js_fprintf((FILE *)scgp->errfile,
"error in scgo_reset: ASPI driver not loaded !\n");
return (-1);
}
memset(&s, 0, sizeof(s)); /* Clear SRB_BesDeviceReset structure */
Event = CreateEvent(NULL, TRUE, FALSE, NULL);
/*
* Set structure variables
*/
s.SRB_Cmd = SC_RESET_DEV; /* ASPI command code = SC_RESET_DEV */
s.SRB_HaId = scg_scsibus(scgp); /* ASPI host adapter number */
s.SRB_Flags = SRB_EVENT_NOTIFY; /* Flags */
s.SRB_Target = scg_target(scgp); /* Target's SCSI ID */
s.SRB_Lun = scg_lun(scgp); /* Target's LUN number */
s.SRB_PostProc = (LPVOID)Event; /* Post routine */
/*
* Initiate SCSI command
*/
Status = pfnSendASPI32Command((LPSRB)&s);
/*
* Check status
*/
if (Status == SS_PENDING) {
/*
* Wait till command completes
*/
EventStatus = WaitForSingleObject(Event, INFINITE);
}
/**************************************************/
/* Reset event to non-signaled state. */
/**************************************************/
if (EventStatus == WAIT_OBJECT_0) {
/*
* Clear event
*/
ResetEvent(Event);
}
/*
* Close the event handle
*/
CloseHandle(Event);
/*
* Check condition
*/
if (s.SRB_Status != SS_COMP) {
js_fprintf((FILE *)scgp->errfile,
"ERROR! 0x%08X\n", s.SRB_Status);
/*
* Indicate that error has occured
*/
return (-1);
}
if (scgp->debug > 0) {
js_fprintf((FILE *)scgp->errfile,
"Reset SCSI device completed\n");
}
/*
* Everything went OK
*/
return (0);
}
#ifdef DEBUG_WNTASPI
LOCAL void
DebugScsiSend(scgp, s, bDisplayBuffer)
SCSI *scgp;
SRB_ExecSCSICmd s;
int bDisplayBuffer;
{
int i;
js_fprintf((FILE *)scgp->errfile, "\n\nDebugScsiSend\n");
js_fprintf((FILE *)scgp->errfile, "s.SRB_Cmd = 0x%02x\n", s.SRB_Cmd);
js_fprintf((FILE *)scgp->errfile, "s.SRB_HaId = 0x%02x\n", s.SRB_HaId);
js_fprintf((FILE *)scgp->errfile, "s.SRB_Flags = 0x%02x\n", s.SRB_Flags);
js_fprintf((FILE *)scgp->errfile, "s.SRB_Target = 0x%02x\n", s.SRB_Target);
js_fprintf((FILE *)scgp->errfile, "s.SRB_Lun = 0x%02x\n", s.SRB_Lun);
js_fprintf((FILE *)scgp->errfile, "s.SRB_BufLen = 0x%02x\n", s.SRB_BufLen);
js_fprintf((FILE *)scgp->errfile, "s.SRB_BufPointer = %x\n", s.SRB_BufPointer);
js_fprintf((FILE *)scgp->errfile, "s.SRB_CDBLen = 0x%02x\n", s.SRB_CDBLen);
js_fprintf((FILE *)scgp->errfile, "s.SRB_SenseLen = 0x%02x\n", s.SRB_SenseLen);
js_fprintf((FILE *)scgp->errfile, "s.CDBByte =");
for (i=0; i < min(s.SRB_CDBLen, 16); i++) {
js_fprintf((FILE *)scgp->errfile, " %02X ", s.CDBByte[i]);
}
js_fprintf((FILE *)scgp->errfile, "\n");
/*
if (bDisplayBuffer != 0 && s.SRB_BufLen >= 8) {
js_fprintf((FILE *)scgp->errfile, "s.SRB_BufPointer =");
for (i=0; i < 8; i++) {
js_fprintf((FILE *)scgp->errfile,
" %02X ", ((char*)s.SRB_BufPointer)[i]);
}
js_fprintf((FILE *)scgp->errfile, "\n");
}
*/
js_fprintf((FILE *)scgp->errfile, "Debug done\n");
}
#endif
LOCAL void
copy_sensedata(cp, sp)
SRB_ExecSCSICmd *cp;
struct scg_cmd *sp;
{
sp->sense_count = cp->SRB_SenseLen;
if (sp->sense_count > sp->sense_len)
sp->sense_count = sp->sense_len;
memset(&sp->u_sense.Sense, 0x00, sizeof(sp->u_sense.Sense));
memcpy(&sp->u_sense.Sense, cp->SenseArea, sp->sense_len);
sp->u_scb.cmd_scb[0] = cp->SRB_TargStat;
}
/*
* Set error flags
*/
LOCAL void
set_error(cp, sp)
SRB_ExecSCSICmd *cp;
struct scg_cmd *sp;
{
switch (cp->SRB_Status) {
case SS_COMP: /* 0x01 SRB completed without error */
sp->error = SCG_NO_ERROR;
sp->ux_errno = 0;
break;
case SS_PENDING: /* 0x00 SRB being processed */
/*
* XXX Could SS_PENDING happen ???
*/
case SS_ABORTED: /* 0x02 SRB aborted */
case SS_ABORT_FAIL: /* 0x03 Unable to abort SRB */
case SS_ERR: /* 0x04 SRB completed with error */
default:
sp->error = SCG_RETRYABLE;
sp->ux_errno = EIO;
break;
case SS_INVALID_CMD: /* 0x80 Invalid ASPI command */
case SS_INVALID_HA: /* 0x81 Invalid host adapter number */
case SS_NO_DEVICE: /* 0x82 SCSI device not installed */
case SS_INVALID_SRB: /* 0xE0 Invalid parameter set in SRB */
case SS_ILLEGAL_MODE: /* 0xE2 Unsupported Windows mode */
case SS_NO_ASPI: /* 0xE3 No ASPI managers */
case SS_FAILED_INIT: /* 0xE4 ASPI for windows failed init */
case SS_MISMATCHED_COMPONENTS: /* 0xE7 The DLLs/EXEs of ASPI don't */
/* version check */
case SS_NO_ADAPTERS: /* 0xE8 No host adapters to manager */
case SS_ASPI_IS_SHUTDOWN: /* 0xEA Call came to ASPI after */
/* PROCESS_DETACH */
case SS_BAD_INSTALL: /* 0xEB The DLL or other components */
/* are installed wrong */
sp->error = SCG_FATAL;
sp->ux_errno = EINVAL;
break;
#ifdef XXX
case SS_OLD_MANAGER: /* 0xE1 ASPI manager doesn't support */
/* windows */
#endif
case SS_BUFFER_ALIGN: /* 0xE1 Buffer not aligned (replaces */
/* SS_OLD_MANAGER in Win32) */
sp->error = SCG_FATAL;
sp->ux_errno = EFAULT;
break;
case SS_ASPI_IS_BUSY: /* 0xE5 No resources available to */
/* execute command */
sp->error = SCG_RETRYABLE;
sp->ux_errno = EBUSY;
break;
#ifdef XXX
case SS_BUFFER_TO_BIG: /* 0xE6 Buffer size too big to handle*/
#endif
case SS_BUFFER_TOO_BIG: /* 0xE6 Correct spelling of 'too' */
case SS_INSUFFICIENT_RESOURCES: /* 0xE9 Couldn't allocate resources */
/* needed to init */
sp->error = SCG_RETRYABLE;
sp->ux_errno = ENOMEM;
break;
}
}
LOCAL int
scgo_send(scgp)
SCSI *scgp;
{
struct scg_cmd *sp = scgp->scmd;
DWORD Status = 0;
DWORD EventStatus = WAIT_OBJECT_0;
HANDLE Event = NULL;
SRB_ExecSCSICmd s;
/*
* Check if ASPI library is loaded
*/
if (AspiLoaded == FALSE) {
errmsgno(EX_BAD, "error in scgo_send: ASPI driver not loaded.\n");
sp->error = SCG_FATAL;
return (-1);
}
if (scgp->fd < 0) {
sp->error = SCG_FATAL;
return (-1);
}
/*
* Initialize variables
*/
sp->error = SCG_NO_ERROR;
sp->sense_count = 0;
sp->u_scb.cmd_scb[0] = 0;
sp->resid = 0;
memset(&s, 0, sizeof(s)); /* Clear SRB structure */
/*
* Check cbd_len > the maximum command pakket that can be handled by ASPI
*/
if (sp->cdb_len > 16) {
sp->error = SCG_FATAL;
sp->ux_errno = EINVAL;
js_fprintf((FILE *)scgp->errfile,
"sp->cdb_len > sizeof(SRB_ExecSCSICmd.CDBByte). Fatal error in scgo_send, exiting...\n");
return (-1);
}
/*
* copy cdrecord command into SRB
*/
movebytes(&sp->cdb, &(s.CDBByte), sp->cdb_len);
Event = CreateEvent(NULL, TRUE, FALSE, NULL);
/*
* Fill ASPI structure
*/
s.SRB_Cmd = SC_EXEC_SCSI_CMD; /* SCSI Command */
s.SRB_HaId = scg_scsibus(scgp); /* Host adapter number */
s.SRB_Flags = SRB_EVENT_NOTIFY; /* Flags */
s.SRB_Target = scg_target(scgp); /* Target SCSI ID */
s.SRB_Lun = scg_lun(scgp); /* Target SCSI LUN */
s.SRB_BufLen = sp->size; /* # of bytes transferred */
s.SRB_BufPointer= sp->addr; /* pointer to data buffer */
s.SRB_CDBLen = sp->cdb_len; /* SCSI command length */
s.SRB_PostProc = Event; /* Post proc event */
s.SRB_SenseLen = SENSE_LEN; /* Lenght of sense buffer */
/*
* Do we receive data from this ASPI command?
*/
if (sp->flags & SCG_RECV_DATA) {
s.SRB_Flags |= SRB_DIR_IN;
} else {
/*
* Set direction to output
*/
if (sp->size > 0) {
s.SRB_Flags |= SRB_DIR_OUT;
}
}
#ifdef DEBUG_WNTASPI
/*
* Dump some debug information when enabled
*/
DebugScsiSend(scgp, s, TRUE);
/* DebugScsiSend(scgp, s, (s.SRB_Flags&SRB_DIR_OUT) == SRB_DIR_OUT);*/
#endif
/*
* ------------ Send SCSI command --------------------------
*/
ResetEvent(Event); /* Clear event handle */
Status = pfnSendASPI32Command((LPSRB)&s);/* Initiate SCSI command */
if (Status == SS_PENDING) { /* If in progress */
/*
* Wait untill command completes, or times out.
*/
EventStatus = WaitForSingleObject(Event, sp->timeout*1000L);
/* EventStatus = WaitForSingleObject(Event, 10L);*/
if (EventStatus == WAIT_OBJECT_0)
ResetEvent(Event); /* Clear event, time out */
if (s.SRB_Status == SS_PENDING) {/* Check if we got a timeout*/
if (scgp->debug > 0) {
js_fprintf((FILE *)scgp->errfile,
"Timeout....\n");
}
scsiabort(scgp, &s);
ResetEvent(Event); /* Clear event, time out */
CloseHandle(Event); /* Close the event handle */
sp->error = SCG_TIMEOUT;
return (1); /* Return error */
}
}
CloseHandle(Event); /* Close the event handle */
/*
* Check ASPI command status
*/
if (s.SRB_Status != SS_COMP) {
if (scgp->debug > 0) {
js_fprintf((FILE *)scgp->errfile,
"Error in scgo_send: s.SRB_Status is 0x%x\n", s.SRB_Status);
}
set_error(&s, sp); /* Set error flags */
copy_sensedata(&s, sp); /* Copy sense and status */
if (scgp->debug > 0) {
js_fprintf((FILE *)scgp->errfile,
"Mapped to: error %d errno: %d\n", sp->error, sp->ux_errno);
}
return (1);
}
/*
* Return success
*/
return (0);
}
/***************************************************************************
* *
* BOOL open_driver() *
* *
* Opens the ASPI Router device driver and sets device_handle. *
* Returns: *
* TRUE - Success *
* FALSE - Unsuccessful opening of device driver *
* *
* Preconditions: ASPI Router driver has be loaded *
* *
***************************************************************************/
LOCAL BOOL
open_driver(scgp)
SCSI *scgp;
{
DWORD astatus;
BYTE HACount;
BYTE ASPIStatus;
int i;
#ifdef DEBUG_WNTASPI
js_fprintf((FILE *)scgp->errfile, "enter open_driver\n");
#endif
/*
* Check if ASPI library is already loaded yet
*/
if (AspiLoaded == TRUE)
return (TRUE);
/*
* Load the ASPI library
*/
#ifdef __CYGWIN32__
hAspiLib = dlopen("WNASPI32", RTLD_NOW);
#else
hAspiLib = LoadLibrary("WNASPI32");
#endif
/*
* Check if ASPI library is loaded correctly
*/
if (hAspiLib == NULL) {
js_fprintf((FILE *)scgp->errfile, "Can not load ASPI driver! ");
return (FALSE);
}
/*
* Get a pointer to GetASPI32SupportInfo function
* and a pointer to SendASPI32Command function
*/
#ifdef __CYGWIN32__
pfnGetASPI32SupportInfo = (DWORD(*)(void))dlsym(hAspiLib, "GetASPI32SupportInfo");
pfnSendASPI32Command = (DWORD(*)(LPSRB))dlsym(hAspiLib, "SendASPI32Command");
#else
pfnGetASPI32SupportInfo = (DWORD(*)(void))GetProcAddress(hAspiLib, "GetASPI32SupportInfo");
pfnSendASPI32Command = (DWORD(*)(LPSRB))GetProcAddress(hAspiLib, "SendASPI32Command");
#endif
if ((pfnGetASPI32SupportInfo == NULL) || (pfnSendASPI32Command == NULL)) {
js_fprintf((FILE *)scgp->errfile,
"ASPI function not found in library!");
return (FALSE);
}
#ifdef __CYGWIN32__
pfnGetASPI32Buffer = (BOOL(*)(PASPI32BUFF))dlsym(hAspiLib, "GetASPI32Buffer");
pfnFreeASPI32Buffer = (BOOL(*)(PASPI32BUFF))dlsym(hAspiLib, "FreeASPI32Buffer");
pfnTranslateASPI32Address = (BOOL(*)(PDWORD, PDWORD))dlsym(hAspiLib, "TranslateASPI32Address");
#else
pfnGetASPI32Buffer = (BOOL(*)(PASPI32BUFF))GetProcAddress(hAspiLib, "GetASPI32Buffer");
pfnFreeASPI32Buffer = (BOOL(*)(PASPI32BUFF))GetProcAddress(hAspiLib, "FreeASPI32Buffer");
pfnTranslateASPI32Address = (BOOL(*)(PDWORD, PDWORD))GetProcAddress(hAspiLib, "TranslateASPI32Address");
#endif
/*
* Set AspiLoaded variable
*/
AspiLoaded = TRUE;
astatus = pfnGetASPI32SupportInfo();
ASPIStatus = HIBYTE(LOWORD(astatus));
HACount = LOBYTE(LOWORD(astatus));
if (scgp->debug > 0) {
js_fprintf((FILE *)scgp->errfile,
"open_driver %X HostASPIStatus=0x%x HACount=0x%x\n", astatus, ASPIStatus, HACount);
}
if (ASPIStatus != SS_COMP && ASPIStatus != SS_NO_ADAPTERS) {
js_fprintf((FILE *)scgp->errfile, "Could not find any host adapters\n");
js_fprintf((FILE *)scgp->errfile, "ASPIStatus == 0x%02X", ASPIStatus);
return (FALSE);
}
busses = HACount;
#ifdef DEBUG_WNTASPI
js_fprintf((FILE *)scgp->errfile, "open_driver HostASPIStatus=0x%x HACount=0x%x\n", ASPIStatus, HACount);
js_fprintf((FILE *)scgp->errfile, "leaving open_driver\n");
#endif
for (i=0; i < busses; i++) {
SRB_HAInquiry s;
ha_inquiry(scgp, i, &s);
}
/*
* Indicate that library loaded/initialized properly
*/
return (TRUE);
}
/***************************************************************************
* *
* BOOL close_driver() *
* *
* Closes the device driver *
* Returns: *
* TRUE - Success *
* FALSE - Unsuccessful closing of device driver *
* *
* Preconditions: ASPI Router driver has be opened with open_driver *
* *
***************************************************************************/
LOCAL BOOL
close_driver()
{
/*
* If library is loaded
*/
if (hAspiLib) {
/*
* Clear all variables
*/
AspiLoaded = FALSE;
pfnGetASPI32SupportInfo = NULL;
pfnSendASPI32Command = NULL;
pfnGetASPI32Buffer = NULL;
pfnFreeASPI32Buffer = NULL;
pfnTranslateASPI32Address = NULL;
/*
* Free ASPI library, we do not need it any longer
*/
#ifdef __CYGWIN32__
dlclose(hAspiLib);
#else
FreeLibrary(hAspiLib);
#endif
hAspiLib = NULL;
}
/*
* Indicate that shutdown has been finished properly
*/
return (TRUE);
}
LOCAL int
ha_inquiry(scgp, id, ip)
SCSI *scgp;
int id;
SRB_HAInquiry *ip;
{
DWORD Status;
ip->SRB_Cmd = SC_HA_INQUIRY;
ip->SRB_HaId = id;
ip->SRB_Flags = 0;
ip->SRB_Hdr_Rsvd= 0;
Status = pfnSendASPI32Command((LPSRB)ip);
if (scgp->debug > 0) {
js_fprintf((FILE *)scgp->errfile, "Status : %d\n", Status);
js_fprintf((FILE *)scgp->errfile, "hacount: %d\n", ip->HA_Count);
js_fprintf((FILE *)scgp->errfile, "SCSI id: %d\n", ip->HA_SCSI_ID);
js_fprintf((FILE *)scgp->errfile, "Manager: '%.16s'\n", ip->HA_ManagerId);
js_fprintf((FILE *)scgp->errfile, "Identif: '%.16s'\n", ip->HA_Identifier);
scg_prbytes("Unique:", ip->HA_Unique, 16);
}
if (ip->SRB_Status != SS_COMP)
return (-1);
return (0);
}
#ifdef __USED__
LOCAL int
resetSCSIBus(scgp)
SCSI *scgp;
{
DWORD Status;
HANDLE Event;
SRB_BusDeviceReset s;
js_fprintf((FILE *)scgp->errfile, "Attempting to reset SCSI bus\n");
Event = CreateEvent(NULL, TRUE, FALSE, NULL);
memset(&s, 0, sizeof(s)); /* Clear SRB_BesDeviceReset structure */
/*
* Set structure variables
*/
s.SRB_Cmd = SC_RESET_DEV;
s.SRB_PostProc = (LPVOID)Event;
/*
* Clear event
*/
ResetEvent(Event);
/*
* Initiate SCSI command
*/
Status = pfnSendASPI32Command((LPSRB)&s);
/*
* Check status
*/
if (Status == SS_PENDING) {
/*
* Wait till command completes
*/
WaitForSingleObject(Event, INFINITE);
}
/*
* Close the event handle
*/
CloseHandle(Event);
/*
* Check condition
*/
if (s.SRB_Status != SS_COMP) {
js_fprintf((FILE *)scgp->errfile, "ERROR 0x%08X\n", s.SRB_Status);
/*
* Indicate that error has occured
*/
return (FALSE);
}
/*
* Everything went OK
*/
return (TRUE);
}
#endif /* __USED__ */
LOCAL int
scsiabort(scgp, sp)
SCSI *scgp;
SRB_ExecSCSICmd *sp;
{
DWORD Status = 0;
SRB_Abort s;
if (scgp->debug > 0) {
js_fprintf((FILE *)scgp->errfile,
"Attempting to abort SCSI command\n");
}
/*
* Check if ASPI library is loaded
*/
if (AspiLoaded == FALSE) {
js_fprintf((FILE *)scgp->errfile,
"error in scsiabort: ASPI driver not loaded !\n");
return (FALSE);
}
/*
* Set structure variables
*/
s.SRB_Cmd = SC_ABORT_SRB; /* ASPI command code = SC_ABORT_SRB */
s.SRB_HaId = scg_scsibus(scgp); /* ASPI host adapter number */
s.SRB_Flags = 0; /* Flags */
s.SRB_ToAbort = (LPSRB)&sp; /* sp */
/*
* Initiate SCSI abort
*/
Status = pfnSendASPI32Command((LPSRB)&s);
/*
* Check condition
*/
if (s.SRB_Status != SS_COMP) {
js_fprintf((FILE *)scgp->errfile, "Abort ERROR! 0x%08X\n", s.SRB_Status);
/*
* Indicate that error has occured
*/
return (FALSE);
}
if (scgp->debug > 0)
js_fprintf((FILE *)scgp->errfile, "Abort SCSI command completed\n");
/*
* Everything went OK
*/
return (TRUE);
}
syntax highlighted by Code2HTML, v. 0.9.1