scsi-wnt.c
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:21k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)scsi-wnt.c 1.16 99/09/08 Copyright 1998, 1999 J. Schilling, A.L. Faber */
  2. #ifndef lint
  3. static char ___sccsid[] =
  4. "@(#)scsi-wnt.c 1.16 99/09/08 Copyright 1998, 1999 J. Schilling, A.L. Faber";
  5. #endif
  6. /*
  7.  * Interface for the Win32 ASPI library.
  8.  * You need wnaspi32.dll and aspi32.sys
  9.  * Both can be installed from ASPI_ME
  10.  *
  11.  * Copyright (c) 1998 J. Schilling
  12.  * Copyright (c) 1999 A.L. Faber for the first implementation
  13.  *    of this interface.
  14.  * TODO:
  15.  * - DMA resid handling
  16.  * - better handling of maxDMA
  17.  * - SCSI reset support
  18.  */
  19. /*
  20.  * This program is free software; you can redistribute it and/or modify
  21.  * it under the terms of the GNU General Public License as published by
  22.  * the Free Software Foundation; either version 2, or (at your option)
  23.  * any later version.
  24.  *
  25.  * This program is distributed in the hope that it will be useful,
  26.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  28.  * GNU General Public License for more details.
  29.  *
  30.  * You should have received a copy of the GNU General Public License
  31.  * along with this program; see the file COPYING.  If not, write to
  32.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  33.  */
  34. /*
  35.  * Include for Win32 ASPI AspiRouter
  36.  *
  37.  * NOTE: aspi-win32.h includes Windows.h and Windows.h includes
  38.  *  Base.h which has a second typedef for BOOL.
  39.  *  We define BOOL to make all local code use BOOL
  40.  *  from Windows.h and use the hidden __SBOOL for
  41.  *  our global interfaces.
  42.  */
  43. #define BOOL WBOOL /* This is the Win BOOL */
  44. #define format __format
  45. #include <scg/aspi-win32.h>
  46. #undef format
  47. #ifdef __CYGWIN32__ /* Use dlopen() */
  48. #include <dlfcn.h>
  49. #endif
  50. /*
  51.  * Local defines and constants
  52.  */
  53. /*#define DEBUG_WNTASPI*/
  54. #define MAX_SCG 16 /* Max # of SCSI controllers */
  55. #define MAX_TGT 16 /* Max # of SCSI Targets */
  56. #define MAX_LUN 8 /* Max # of SCSI LUNs */
  57. #ifdef DEBUG_WNTASPI
  58. #endif
  59. struct scg_local {
  60. int dummy;
  61. };
  62. #define scglocal(p) ((struct scg_local *)((p)->local)) 
  63. /*
  64.  * Local variables
  65.  */
  66. LOCAL int busses;
  67. LOCAL DWORD (*pfnGetASPI32SupportInfo)(void) = NULL;
  68. LOCAL DWORD (*pfnSendASPI32Command)(LPSRB) = NULL;
  69. LOCAL BOOL (*pfnGetASPI32Buffer)(PASPI32BUFF) = NULL;
  70. LOCAL BOOL (*pfnFreeASPI32Buffer)(PASPI32BUFF) = NULL;
  71. LOCAL BOOL (*pfnTranslateASPI32Address)(PDWORD, PDWORD) = NULL;
  72. LOCAL BOOL AspiLoaded = FALSE;
  73. LOCAL HANDLE hAspiLib = NULL; /* Used for Loadlib */
  74. #define MAX_DMA_WNT (63L*1024L) /* ASPI-Driver  allows up to 64k ??? */
  75. /*
  76.  * Local function prototypes
  77.  */
  78. LOCAL void exit_func __PR((void));
  79. #ifdef DEBUG_WNTASPI
  80. LOCAL void DebugScsiSend __PR((SRB_ExecSCSICmd s, int bDisplayBuffer));
  81. #endif
  82. LOCAL void copy_sensedata __PR((SRB_ExecSCSICmd *cp, struct scg_cmd *sp));
  83. LOCAL void set_error __PR((SRB_ExecSCSICmd *cp, struct scg_cmd *sp));
  84. LOCAL BOOL open_driver __PR((SCSI *scgp));
  85. LOCAL BOOL close_driver __PR((void));
  86. LOCAL int ha_inquiry __PR((SCSI *scgp, int id, SRB_HAInquiry *ip));
  87. LOCAL int resetSCSIBus __PR((void));
  88. LOCAL int scsiabort __PR((SCSI *scgp, SRB_ExecSCSICmd *sp));
  89. LOCAL void
  90. exit_func()
  91. {
  92. if (!close_driver())
  93. errmsgno(EX_BAD, "Cannot close Win32-ASPI-Driver.n");
  94. }
  95. EXPORT int
  96. scsi_open(scgp, device, busno, tgt, tlun)
  97. SCSI *scgp;
  98. char *device;
  99. int busno;
  100. int tgt;
  101. int tlun;
  102. {
  103. if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) {
  104. errno = EINVAL;
  105. if (scgp->errstr)
  106. js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
  107. "Illegal value for busno, target or lun '%d,%d,%d'",
  108. busno, tgt, tlun);
  109. return (-1);
  110. }
  111. if ((device != NULL && *device != '') || (busno == -2 && tgt == -2)) {
  112. errno = EINVAL;
  113. if (scgp->errstr)
  114. js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
  115. "Open by 'devname' not supported on this OS");
  116. return (-1);
  117. }
  118. /*
  119.  *  Check if variables are within the range
  120.  */
  121. if (tgt >= 0 && tgt >= 0 && tlun >= 0) {
  122. /*
  123.  * This is the non -scanbus case.
  124.  */
  125. ;
  126. } else if (tgt != -1 || tgt != -1 || tlun != -1) {
  127. errno = EINVAL;
  128. return (-1);
  129. }
  130. if (scgp->local == NULL) {
  131. scgp->local = malloc(sizeof(struct scg_local));
  132. if (scgp->local == NULL)
  133. return (0);
  134. }
  135. /*
  136.  * Try to open ASPI-Router
  137.  */
  138. if (!open_driver(scgp))
  139. return (-1);
  140. /*
  141.  * More than we have ...
  142.  */
  143. if (busno >= busses) {
  144. close_driver();
  145. return (-1);
  146. }
  147. /*
  148.  * Install Exit Function which closes the ASPI-Router
  149.  */
  150. atexit(exit_func);
  151. /*
  152.  * Success after all
  153.  */
  154. return (1);
  155. }
  156. EXPORT int
  157. scsi_close(scgp)
  158. SCSI *scgp;
  159. {
  160. exit_func();
  161. return (0);
  162. }
  163. LOCAL long
  164. scsi_maxdma(scgp)
  165. SCSI *scgp;
  166. {
  167. return (MAX_DMA_WNT);
  168. }
  169. EXPORT void *
  170. scsi_getbuf(scgp, amt)
  171. SCSI *scgp;
  172. long amt;
  173. {
  174. if (amt <= 0 || amt > scsi_maxdma(scgp)) {
  175. errmsgno(EX_BAD,
  176. "scsi_getbuf: buffer out of range; requested size is %ld bytesn", amt);
  177. return ((void *)0);
  178. }
  179. if (scgp->debug)
  180. printf("scsi_getbuf: %ld bytesn", amt);
  181. scgp->bufbase = malloc((size_t)(amt));
  182. return (scgp->bufbase);
  183. }
  184. EXPORT void
  185. scsi_freebuf(scgp)
  186. SCSI *scgp;
  187. {
  188. if (scgp->bufbase)
  189. free(scgp->bufbase);
  190. scgp->bufbase = NULL;
  191. }
  192. EXPORT __SBOOL
  193. scsi_havebus(scgp, busno)
  194. SCSI *scgp;
  195. int busno;
  196. {
  197. if (busno < 0 || busno >= busses)
  198. return (FALSE);
  199. return (TRUE);
  200. }
  201. EXPORT int
  202. scsi_fileno(scgp, busno, tgt, tlun)
  203. SCSI *scgp;
  204. int busno;
  205. int tgt;
  206. int tlun;
  207. {
  208. if (busno < 0 || busno >= busses ||
  209.     tgt < 0 || tgt >= MAX_TGT ||
  210.     tlun < 0 || tlun >= MAX_LUN)
  211. return (-1);
  212. /*
  213.  * Return fake
  214.  */
  215. return (1);
  216. }
  217. EXPORT int
  218. scsi_initiator_id(scgp)
  219. SCSI *scgp;
  220. {
  221. SRB_HAInquiry s;
  222. if (ha_inquiry(scgp, scgp->scsibus, &s) < 0)
  223. return (-1);
  224. return (s.HA_SCSI_ID);
  225. }
  226. EXPORT int
  227. scsi_isatapi(scgp)
  228. SCSI *scgp;
  229. {
  230. return (-1); /* XXX Need to add real test */
  231. }
  232. /*
  233.  * XXX scsireset not yet tested
  234.  */
  235. EXPORT int
  236. scsireset(scgp)
  237. SCSI *scgp;
  238. {
  239. DWORD Status = 0;
  240. DWORD EventStatus = WAIT_OBJECT_0;
  241. HANDLE Event  = NULL;
  242. SRB_BusDeviceReset s;
  243. if (scgp->debug)
  244. printf("Attempting to reset SCSI devicen");
  245. /*
  246.  * Check if ASPI library is loaded
  247.  */
  248. if (AspiLoaded == FALSE) {
  249. printf("error in scsireset: ASPI driver not loaded !n");
  250. return (FALSE);
  251. }
  252. memset(&s, 0, sizeof(s)); /* Clear SRB_BesDeviceReset structure */
  253. Event = CreateEvent(NULL, TRUE, FALSE, NULL);
  254. /*
  255.  * Set structure variables
  256.  */
  257. s.SRB_Cmd = SC_RESET_DEV; /* ASPI command code = SC_RESET_DEV */
  258. s.SRB_HaId = scgp->scsibus; /* ASPI host adapter number */
  259. s.SRB_Flags = SRB_EVENT_NOTIFY; /* Flags */
  260. s.SRB_Target = scgp->target; /* Target's SCSI ID */
  261. s.SRB_Lun = scgp->lun; /* Target's LUN number */
  262. s.SRB_PostProc = (LPVOID)Event; /* Post routine */
  263. /*
  264.  * Initiate SCSI command
  265.  */
  266. Status = pfnSendASPI32Command((LPSRB)&s);
  267. /*
  268.  * Check status
  269.  */
  270. if (Status == SS_PENDING) {
  271. /*
  272.  * Wait till command completes
  273.  */
  274. EventStatus = WaitForSingleObject(Event, INFINITE);
  275. }
  276. /**************************************************/
  277. /* Reset event to non-signaled state.             */
  278. /**************************************************/
  279. if (EventStatus == WAIT_OBJECT_0) {
  280. /*
  281.  * Clear event
  282.  */
  283. ResetEvent(Event);
  284. }
  285. /*
  286.  * Close the event handle
  287.  */
  288. CloseHandle(Event);
  289. /*
  290.  * Check condition
  291.  */
  292. if (s.SRB_Status != SS_COMP) {
  293. printf("ERROR! 0x%08Xn", s.SRB_Status);
  294. /*
  295.  * Indicate that error has occured
  296.  */
  297. return (FALSE);
  298. }
  299. if (scgp->debug)
  300. printf("Reset SCSI device completedn");
  301. /*
  302.  * Everything went OK
  303.  */
  304. return (TRUE);
  305. }
  306. #ifdef DEBUG_WNTASPI
  307. LOCAL void
  308. DebugScsiSend(s, bDisplayBuffer)
  309. SRB_ExecSCSICmd s;
  310. int bDisplayBuffer;
  311. {
  312. int i;
  313. printf("nnDebugScsiSendn");
  314. printf("s.SRB_Cmd          = 0x%02xn", s.SRB_Cmd);
  315. printf("s.SRB_HaId         = 0x%02xn", s.SRB_HaId);
  316. printf("s.SRB_Flags        = 0x%02xn", s.SRB_Flags); 
  317. printf("s.SRB_Target       = 0x%02xn", s.SRB_Target); 
  318. printf("s.SRB_Lun          = 0x%02xn", s.SRB_Lun);
  319. printf("s.SRB_BufLen       = 0x%02xn", s.SRB_BufLen);
  320. printf("s.SRB_BufPointer   = %xn",     s.SRB_BufPointer);
  321. printf("s.SRB_CDBLen       = 0x%02xn", s.SRB_CDBLen);
  322. printf("s.SRB_SenseLen     = 0x%02xn", s.SRB_SenseLen);
  323. printf("s.CDBByte          =");
  324. for (i=0; i < min(s.SRB_CDBLen, 16); i++) {
  325. printf(" %02X ", s.CDBByte[i]);
  326. }
  327. printf("n");
  328. /*
  329. if (bDisplayBuffer != 0 && s.SRB_BufLen >= 8) {
  330. printf("s.SRB_BufPointer   =");
  331. for (i=0; i < 8; i++) {
  332. printf(" %02X ", ((char*)s.SRB_BufPointer)[i]);
  333. }
  334. printf("n");
  335. }
  336. */
  337. printf("Debug donen");
  338. }
  339. #endif
  340. LOCAL void
  341. copy_sensedata(cp, sp)
  342. SRB_ExecSCSICmd *cp;
  343. struct scg_cmd *sp;
  344. {
  345. sp->sense_count = cp->SRB_SenseLen;
  346. if (sp->sense_count > sp->sense_len)
  347. sp->sense_count = sp->sense_len;
  348. memset(&sp->u_sense.Sense, 0x00, sizeof(sp->u_sense.Sense));
  349. memcpy(&sp->u_sense.Sense, cp->SenseArea, sp->sense_len);
  350. sp->u_scb.cmd_scb[0] = cp->SRB_TargStat;
  351. }
  352. /*
  353.  * Set error flags
  354.  */
  355. LOCAL void
  356. set_error(cp, sp)
  357. SRB_ExecSCSICmd *cp;
  358. struct scg_cmd *sp;
  359. {
  360. switch (cp->SRB_Status) {
  361. case SS_COMP: /* 0x01 SRB completed without error  */
  362. sp->error = SCG_NO_ERROR;
  363. sp->ux_errno = 0;
  364. break;
  365. case SS_PENDING: /* 0x00 SRB being processed          */
  366. /*
  367.  * XXX Could SS_PENDING happen ???
  368.  */
  369. case SS_ABORTED: /* 0x02 SRB aborted                  */
  370. case SS_ABORT_FAIL: /* 0x03 Unable to abort SRB          */
  371. case SS_ERR: /* 0x04 SRB completed with error     */
  372. default:
  373. sp->error = SCG_RETRYABLE;
  374. sp->ux_errno = EIO;
  375. break;
  376. case SS_INVALID_CMD: /* 0x80 Invalid ASPI command         */
  377. case SS_INVALID_HA: /* 0x81 Invalid host adapter number  */
  378. case SS_NO_DEVICE: /* 0x82 SCSI device not installed    */
  379. case SS_INVALID_SRB: /* 0xE0 Invalid parameter set in SRB */
  380. case SS_ILLEGAL_MODE: /* 0xE2 Unsupported Windows mode     */
  381. case SS_NO_ASPI: /* 0xE3 No ASPI managers             */
  382. case SS_FAILED_INIT: /* 0xE4 ASPI for windows failed init */
  383. case SS_MISMATCHED_COMPONENTS: /* 0xE7 The DLLs/EXEs of ASPI don't  */
  384. /*      version check                */
  385. case SS_NO_ADAPTERS: /* 0xE8 No host adapters to manager  */
  386. case SS_ASPI_IS_SHUTDOWN: /* 0xEA Call came to ASPI after      */
  387. /*      PROCESS_DETACH               */
  388. case SS_BAD_INSTALL: /* 0xEB The DLL or other components  */
  389. /*      are installed wrong          */
  390. sp->error = SCG_FATAL;
  391. sp->ux_errno = EINVAL;
  392. break;
  393. #ifdef XXX
  394. case SS_OLD_MANAGER: /* 0xE1 ASPI manager doesn't support */
  395. /*      windows                      */
  396. #endif
  397. case SS_BUFFER_ALIGN: /* 0xE1 Buffer not aligned (replaces */
  398. /*      SS_OLD_MANAGER in Win32)     */
  399. sp->error = SCG_FATAL;
  400. sp->ux_errno = EFAULT;
  401. break;
  402. case SS_ASPI_IS_BUSY: /* 0xE5 No resources available to    */
  403. /*      execute command              */
  404. sp->error = SCG_RETRYABLE;
  405. sp->ux_errno = EBUSY;
  406. break;
  407. #ifdef XXX
  408. case SS_BUFFER_TO_BIG: /* 0xE6 Buffer size too big to handle*/
  409. #endif
  410. case SS_BUFFER_TOO_BIG: /* 0xE6 Correct spelling of 'too'    */
  411. case SS_INSUFFICIENT_RESOURCES: /* 0xE9 Couldn't allocate resources  */
  412. /*      needed to init               */
  413. sp->error = SCG_RETRYABLE;
  414. sp->ux_errno = ENOMEM;
  415. break;
  416. }
  417. }
  418. LOCAL int
  419. scsi_send(scgp, f, sp)
  420. SCSI *scgp;
  421. int f;
  422. struct scg_cmd *sp;
  423. {
  424. DWORD Status = 0;
  425. DWORD EventStatus = WAIT_OBJECT_0;
  426. HANDLE Event  = NULL;
  427. SRB_ExecSCSICmd s;
  428. /*
  429.  * Check if ASPI library is loaded
  430.  */
  431. if (AspiLoaded == FALSE) {
  432. errmsgno(EX_BAD, "error in scsi_send: ASPI driver not loaded.n");
  433. sp->error = SCG_FATAL;
  434. return (-1);
  435. }
  436. if (f < 0) {
  437. sp->error = SCG_FATAL;
  438. return (-1);
  439. }
  440. /*
  441.  * Initialize variables
  442.  */
  443. sp->error = SCG_NO_ERROR;
  444. sp->sense_count = 0;
  445. sp->u_scb.cmd_scb[0] = 0;
  446. sp->resid = 0;
  447. memset(&s, 0, sizeof(s)); /* Clear SRB structure */
  448. /*
  449.  * Check cbd_len > the maximum command pakket that can be handled by ASPI
  450.  */
  451. if (sp->cdb_len > 16) {
  452. sp->error = SCG_FATAL;
  453. sp->ux_errno = EINVAL;
  454. printf("sp->cdb_len > sizeof(SRB_ExecSCSICmd.CDBByte). Fatal error in scsi_send, exiting...n");
  455. return (-1);
  456. }
  457. /*
  458.  * copy cdrecord command into SRB
  459.  */
  460. movebytes(&sp->cdb, &(s.CDBByte), sp->cdb_len);
  461. Event = CreateEvent(NULL, TRUE, FALSE, NULL);
  462. /*
  463.  * Fill ASPI structure
  464.  */
  465. s.SRB_Cmd = SC_EXEC_SCSI_CMD; /* SCSI Command */
  466. s.SRB_HaId = scgp->scsibus; /* Host adapter number */
  467. s.SRB_Flags = SRB_EVENT_NOTIFY; /* Flags */
  468. s.SRB_Target = scgp->target; /* Target SCSI ID */
  469. s.SRB_Lun = scgp->lun; /* Target SCSI LUN */
  470. s.SRB_BufLen = sp->size; /* # of bytes transferred */
  471. s.SRB_BufPointer= sp->addr; /* pointer to data buffer */
  472. s.SRB_CDBLen = sp->cdb_len; /* SCSI command length */
  473. s.SRB_PostProc = Event; /* Post proc event */
  474. s.SRB_SenseLen = SENSE_LEN; /* Lenght of sense buffer */
  475. /*
  476.  * Do we receive data from this ASPI command?
  477.  */
  478. if (sp->flags & SCG_RECV_DATA) {
  479. s.SRB_Flags |= SRB_DIR_IN;
  480. } else {
  481. /*
  482.  * Set direction to output
  483.  */
  484. if (sp->size > 0) {
  485. s.SRB_Flags |= SRB_DIR_OUT;
  486. }
  487. }
  488. #ifdef DEBUG_WNTASPI
  489. /*
  490.  * Dump some debug information when enabled
  491.  */
  492. DebugScsiSend(s, TRUE);
  493. /* DebugScsiSend(s, (s.SRB_Flags&SRB_DIR_OUT) == SRB_DIR_OUT);*/
  494. #endif
  495. /*
  496.  * ------------ Send SCSI command --------------------------
  497.  */
  498. ResetEvent(Event); /* Clear event handle      */
  499. Status = pfnSendASPI32Command((LPSRB)&s);/* Initiate SCSI command    */
  500. if (Status == SS_PENDING) { /* If in progress      */
  501. /*
  502.  * Wait untill command completes, or times out.
  503.  */
  504. EventStatus = WaitForSingleObject(Event, sp->timeout*1000L);
  505. /* EventStatus = WaitForSingleObject(Event, 10L);*/
  506. if (EventStatus == WAIT_OBJECT_0)
  507. ResetEvent(Event); /* Clear event, time out     */
  508. if (s.SRB_Status == SS_PENDING) {/* Check if we got a timeout*/
  509. if (scgp->debug)
  510. printf("Timeout....n");
  511. scsiabort(scgp, &s);
  512. ResetEvent(Event); /* Clear event, time out     */
  513. CloseHandle(Event); /* Close the event handle    */
  514. sp->error = SCG_TIMEOUT;
  515. return (1); /* Return error      */
  516. }
  517. }
  518. CloseHandle(Event); /* Close the event handle    */
  519. /*
  520.  * Check ASPI command status
  521.  */
  522. if (s.SRB_Status != SS_COMP) {
  523. if (scgp->debug)
  524. printf("Error in scsi_send: s.SRB_Status is 0x%xn", s.SRB_Status);
  525. set_error(&s, sp); /* Set error flags      */
  526. copy_sensedata(&s, sp); /* Copy sense and status     */
  527. if (scgp->debug)
  528. printf("Mapped to: error %d errno: %dn", sp->error, sp->ux_errno);
  529. return (1);
  530. }
  531. /*
  532.  * Return success
  533.  */
  534. return (0);
  535. }
  536. /***************************************************************************
  537.  *                                                                         *
  538.  *  BOOL open_driver()                                                     *
  539.  *                                                                         *
  540.  *  Opens the ASPI Router device driver and sets device_handle.            *
  541.  *  Returns:                                                               *
  542.  *    TRUE - Success                                                       *
  543.  *    FALSE - Unsuccessful opening of device driver                        *
  544.  *                                                                         *
  545.  *  Preconditions: ASPI Router driver has be loaded                        *
  546.  *                                                                         *
  547.  ***************************************************************************/
  548. LOCAL BOOL
  549. open_driver(scgp)
  550. SCSI *scgp;
  551. {
  552. DWORD astatus;
  553. BYTE HACount;
  554. BYTE ASPIStatus;
  555. int i;
  556. #ifdef DEBUG_WNTASPI
  557. printf("enter open_drivern");
  558. #endif
  559. /*
  560.  * Check if ASPI library is already loaded yet
  561.  */
  562. if (AspiLoaded == TRUE)
  563. return (TRUE);
  564. /*
  565.  * Load the ASPI library
  566.  */
  567. #ifdef __CYGWIN32__
  568. hAspiLib = dlopen("WNASPI32", RTLD_NOW);
  569. #else
  570. hAspiLib = LoadLibrary("WNASPI32");
  571. #endif
  572. /*
  573.  * Check if ASPI library is loaded correctly
  574.  */
  575. if (hAspiLib == NULL) {
  576. printf("Can not load ASPI driver! ");
  577. return (FALSE);
  578. }
  579.   
  580. /*
  581.  * Get a pointer to GetASPI32SupportInfo function
  582.  * and a pointer to SendASPI32Command function
  583.  */
  584. #ifdef __CYGWIN32__
  585. pfnGetASPI32SupportInfo = (DWORD(*)(void))dlsym(hAspiLib, "GetASPI32SupportInfo");
  586. pfnSendASPI32Command = (DWORD(*)(LPSRB))dlsym(hAspiLib, "SendASPI32Command");
  587. #else
  588. pfnGetASPI32SupportInfo = (DWORD(*)(void))GetProcAddress(hAspiLib, "GetASPI32SupportInfo");
  589. pfnSendASPI32Command = (DWORD(*)(LPSRB))GetProcAddress(hAspiLib, "SendASPI32Command");
  590. #endif
  591. if ((pfnGetASPI32SupportInfo == NULL) || (pfnSendASPI32Command == NULL)) {
  592. printf("ASPI function not found in library!");
  593. return (FALSE);
  594. }
  595. #ifdef __CYGWIN32__
  596. pfnGetASPI32Buffer = (BOOL(*)(PASPI32BUFF))dlsym(hAspiLib, "GetASPI32Buffer");
  597. pfnFreeASPI32Buffer = (BOOL(*)(PASPI32BUFF))dlsym(hAspiLib, "FreeASPI32Buffer");
  598. pfnTranslateASPI32Address = (BOOL(*)(PDWORD, PDWORD))dlsym(hAspiLib, "TranslateASPI32Address");
  599. #else
  600. pfnGetASPI32Buffer = (BOOL(*)(PASPI32BUFF))GetProcAddress(hAspiLib, "GetASPI32Buffer");
  601. pfnFreeASPI32Buffer = (BOOL(*)(PASPI32BUFF))GetProcAddress(hAspiLib, "FreeASPI32Buffer");
  602. pfnTranslateASPI32Address = (BOOL(*)(PDWORD, PDWORD))GetProcAddress(hAspiLib, "TranslateASPI32Address");
  603. #endif
  604. /*
  605.  * Set AspiLoaded variable
  606.  */
  607. AspiLoaded = TRUE;
  608. astatus = pfnGetASPI32SupportInfo();
  609. ASPIStatus = HIBYTE(LOWORD(astatus));
  610. HACount    = LOBYTE(LOWORD(astatus));
  611. if (scgp->debug)
  612. printf("open_driver %X HostASPIStatus=0x%x HACount=0x%xn", astatus, ASPIStatus, HACount);
  613. if (ASPIStatus != SS_COMP && ASPIStatus != SS_NO_ADAPTERS) {
  614. printf("Could not find any host adaptersn");
  615. printf("ASPIStatus == 0x%02X", ASPIStatus);
  616. return (FALSE);
  617. }
  618. busses = HACount;
  619. #ifdef DEBUG_WNTASPI
  620. printf("open_driver HostASPIStatus=0x%x HACount=0x%xn", ASPIStatus, HACount);
  621. printf("leaving open_drivern");
  622. #endif
  623. for (i=0; i < busses; i++) {
  624. SRB_HAInquiry s;
  625. ha_inquiry(scgp, i, &s);
  626. }
  627. /*
  628.  * Indicate that library loaded/initialized properly
  629.  */
  630. return (TRUE);
  631. }
  632. /***************************************************************************
  633.  *                                                                         *
  634.  *  BOOL close_driver()                                                    *
  635.  *                                                                         *
  636.  *  Closes the device driver                                               *
  637.  *  Returns:                                                               *
  638.  *    TRUE - Success                                                       *
  639.  *    FALSE - Unsuccessful closing of device driver                        *
  640.  *                                                                         *
  641.  *  Preconditions: ASPI Router driver has be opened with open_driver       *
  642.  *                                                                         *
  643.  ***************************************************************************/
  644. LOCAL BOOL
  645. close_driver()
  646. {
  647. /*
  648.  * If library is loaded
  649.  */
  650. if (hAspiLib) {
  651. /*
  652.  * Clear all variables
  653.  */
  654. AspiLoaded = FALSE;
  655. pfnGetASPI32SupportInfo = NULL;
  656. pfnSendASPI32Command = NULL;
  657. pfnGetASPI32Buffer = NULL;
  658. pfnFreeASPI32Buffer = NULL;
  659. pfnTranslateASPI32Address = NULL;
  660. /*
  661.  * Free ASPI library, we do not need it any longer
  662.  */
  663. #ifdef __CYGWIN32__
  664. dlclose(hAspiLib);
  665. #else
  666. FreeLibrary(hAspiLib);
  667. #endif
  668. hAspiLib = NULL;
  669. }
  670. /*
  671.  * Indicate that shutdown has been finished properly
  672.  */
  673. return (TRUE);
  674. }
  675. LOCAL int
  676. ha_inquiry(scgp, id, ip)
  677. SCSI *scgp;
  678. int id;
  679. SRB_HAInquiry *ip;
  680. {
  681. DWORD Status;
  682. ip->SRB_Cmd = SC_HA_INQUIRY;
  683. ip->SRB_HaId = id;
  684. ip->SRB_Flags = 0;
  685. ip->SRB_Hdr_Rsvd= 0;
  686. Status = pfnSendASPI32Command((LPSRB)ip);
  687. if (scgp->debug) {
  688. printf("Status : %dn", Status);
  689. printf("hacount: %dn", ip->HA_Count);
  690. printf("SCSI id: %dn", ip->HA_SCSI_ID);
  691. printf("Manager: '%.16s'n", ip->HA_ManagerId);
  692. printf("Identif: '%.16s'n", ip->HA_Identifier);
  693. scsiprbytes("Unique:", ip->HA_Unique, 16);
  694. }
  695. if (ip->SRB_Status != SS_COMP)
  696. return (-1);
  697. return (0);
  698. }
  699. LOCAL int
  700. resetSCSIBus(void)
  701. {
  702. DWORD Status;
  703. HANDLE Event;
  704. SRB_BusDeviceReset s;
  705. printf("Attempting to reset SCSI busn");
  706. Event = CreateEvent(NULL, TRUE, FALSE, NULL);
  707. memset(&s, 0, sizeof(s)); /* Clear SRB_BesDeviceReset structure */
  708. /*
  709.  * Set structure variables
  710.  */
  711. s.SRB_Cmd = SC_RESET_DEV;
  712. s.SRB_PostProc = (LPVOID)Event;
  713. /*
  714.  * Clear event
  715.  */
  716. ResetEvent(Event);
  717. /*
  718.  * Initiate SCSI command
  719.  */
  720. Status = pfnSendASPI32Command((LPSRB)&s);
  721. /*
  722.  * Check status
  723.  */
  724. if (Status == SS_PENDING) {
  725. /*
  726.  * Wait till command completes
  727.  */
  728. WaitForSingleObject(Event, INFINITE);
  729. }
  730. /*
  731.  * Close the event handle
  732.  */
  733. CloseHandle(Event);
  734. /*
  735.  * Check condition
  736.  */
  737. if (s.SRB_Status != SS_COMP) {
  738. printf("ERROR  0x%08Xn", s.SRB_Status);
  739. /*
  740.  * Indicate that error has occured
  741.  */
  742. return (FALSE);
  743. }
  744. /*
  745.  * Everything went OK
  746.  */
  747. return (TRUE);
  748. }
  749. LOCAL int
  750. scsiabort(scgp, sp)
  751. SCSI *scgp;
  752. SRB_ExecSCSICmd *sp;
  753. {
  754. DWORD Status = 0;
  755. SRB_Abort s;
  756. if (scgp->debug)
  757. printf("Attempting to abort SCSI commandn");
  758. /*
  759.  * Check if ASPI library is loaded
  760.  */
  761. if (AspiLoaded == FALSE) {
  762. printf("error in scsiabort: ASPI driver not loaded !n");
  763. return (FALSE);
  764. }
  765. /*
  766.  * Set structure variables
  767.  */
  768. s.SRB_Cmd = SC_ABORT_SRB; /* ASPI command code = SC_ABORT_SRB */
  769. s.SRB_HaId = scgp->scsibus; /* ASPI host adapter number */
  770. s.SRB_Flags = 0; /* Flags */
  771. s.SRB_ToAbort = (LPSRB)&sp; /* sp */
  772. /*
  773.  * Initiate SCSI abort
  774.  */
  775. Status = pfnSendASPI32Command((LPSRB)&s);
  776. /*
  777.  * Check condition
  778.  */
  779. if (s.SRB_Status != SS_COMP) {
  780. printf("Abort ERROR! 0x%08Xn", s.SRB_Status);
  781. /*
  782.  * Indicate that error has occured
  783.  */
  784. return (FALSE);
  785. }
  786. if (scgp->debug)
  787. printf("Abort SCSI command completedn");
  788. /*
  789.  * Everything went OK
  790.  */
  791. return (TRUE);
  792. }