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

SCSI/ASPI

开发平台:

MultiPlatform

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