?? scsi-wnt.c
字號(hào):
/* @(#)scsi-wnt.c 1.17 99/09/17 Copyright 1998, 1999 J. Schilling, A.L. Faber */#ifndef lintstatic char __sccsid[] = "@(#)scsi-wnt.c 1.17 99/09/17 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.17"; /* 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#endifstruct 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_WNTASPILOCAL void DebugScsiSend __PR((SRB_ExecSCSICmd s, int bDisplayBuffer));#endifLOCAL 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));LOCAL int resetSCSIBus __PR((void));LOCAL int scsiabort __PR((SCSI *scgp, SRB_ExecSCSICmd *sp));LOCAL voidexit_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. */EXPORT char *scg__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);}EXPORT intscsi_open(scgp, device, busno, tgt, tlun) SCSI *scgp; char *device; int busno; int tgt; int tlun;{ 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);}EXPORT intscsi_close(scgp) SCSI *scgp;{ exit_func(); return (0);}LOCAL longscsi_maxdma(scgp) SCSI *scgp;{ return (MAX_DMA_WNT);}EXPORT void *scsi_getbuf(scgp, amt) SCSI *scgp; long amt;{ if (amt <= 0 || amt > scsi_maxdma(scgp)) { errmsgno(EX_BAD, "scsi_getbuf: buffer out of range; requested size is %ld bytes\n", amt); return ((void *)0); } if (scgp->debug) printf("scsi_getbuf: %ld bytes\n", amt); scgp->bufbase = malloc((size_t)(amt)); return (scgp->bufbase);}EXPORT voidscsi_freebuf(scgp) SCSI *scgp;{ if (scgp->bufbase) free(scgp->bufbase); scgp->bufbase = NULL;}EXPORT __SBOOLscsi_havebus(scgp, busno) SCSI *scgp; int busno;{ if (busno < 0 || busno >= busses) return (FALSE); return (TRUE);}EXPORT intscsi_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);}EXPORT intscsi_initiator_id(scgp) SCSI *scgp;{ SRB_HAInquiry s; if (ha_inquiry(scgp, scgp->scsibus, &s) < 0) return (-1); return (s.HA_SCSI_ID);}EXPORT intscsi_isatapi(scgp) SCSI *scgp;{ return (-1); /* XXX Need to add real test */}/* * XXX scsireset not yet tested */EXPORT intscsireset(scgp) SCSI *scgp;{ DWORD Status = 0; DWORD EventStatus = WAIT_OBJECT_0; HANDLE Event = NULL; SRB_BusDeviceReset s; if (scgp->debug) printf("Attempting to reset SCSI device\n"); /* * Check if ASPI library is loaded */ if (AspiLoaded == FALSE) { printf("error in scsireset: ASPI driver not loaded !\n"); return (FALSE); } 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 = scgp->scsibus; /* ASPI host adapter number */ s.SRB_Flags = SRB_EVENT_NOTIFY; /* Flags */ s.SRB_Target = scgp->target; /* Target's SCSI ID */ s.SRB_Lun = scgp->lun; /* 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) { printf("ERROR! 0x%08X\n", s.SRB_Status); /* * Indicate that error has occured */ return (FALSE); } if (scgp->debug) printf("Reset SCSI device completed\n"); /* * Everything went OK */ return (TRUE);}#ifdef DEBUG_WNTASPILOCAL voidDebugScsiSend(s, bDisplayBuffer) SRB_ExecSCSICmd s; int bDisplayBuffer;{ int i; printf("\n\nDebugScsiSend\n"); printf("s.SRB_Cmd = 0x%02x\n", s.SRB_Cmd); printf("s.SRB_HaId = 0x%02x\n", s.SRB_HaId); printf("s.SRB_Flags = 0x%02x\n", s.SRB_Flags); printf("s.SRB_Target = 0x%02x\n", s.SRB_Target); printf("s.SRB_Lun = 0x%02x\n", s.SRB_Lun); printf("s.SRB_BufLen = 0x%02x\n", s.SRB_BufLen); printf("s.SRB_BufPointer = %x\n", s.SRB_BufPointer); printf("s.SRB_CDBLen = 0x%02x\n", s.SRB_CDBLen); printf("s.SRB_SenseLen = 0x%02x\n", s.SRB_SenseLen); printf("s.CDBByte ="); for (i=0; i < min(s.SRB_CDBLen, 16); i++) { printf(" %02X ", s.CDBByte[i]); } printf("\n"); /* if (bDisplayBuffer != 0 && s.SRB_BufLen >= 8) { printf("s.SRB_BufPointer ="); for (i=0; i < 8; i++) { printf(" %02X ", ((char*)s.SRB_BufPointer)[i]); } printf("\n"); }*/ printf("Debug done\n");}#endifLOCAL voidcopy_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 voidset_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 */
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -