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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)scsi-os2.c 1.8 99/09/07 Copyright 1998 J. Schilling, C. Wohlgemuth */
  2. #ifndef lint
  3. static char __sccsid[] =
  4. "@(#)scsi-os2.c 1.8 99/09/07 Copyright 1998 J. Schilling, C. Wohlgemuth";
  5. #endif
  6. /*
  7.  * Interface for the OS/2 ASPI-Router ASPIROUT.SYS ((c) D. Dorau).
  8.  * This additional driver is a prerequisite for using cdrecord.
  9.  * Get it from HOBBES or LEO.
  10.  *
  11.  * Copyright (c) 1998 J. Schilling
  12.  * Copyright (c) 1998 C. Wohlgemuth for this interface.
  13.  */
  14. /*
  15.  * This program is free software; you can redistribute it and/or modify
  16.  * it under the terms of the GNU General Public License as published by
  17.  * the Free Software Foundation; either version 2, or (at your option)
  18.  * any later version.
  19.  *
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU General Public License for more details.
  24.  *
  25.  * You should have received a copy of the GNU General Public License
  26.  * along with this program; see the file COPYING.  If not, write to
  27.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  28.  */
  29. #undef sense
  30. /*#define DEBUG*/
  31. /*#define DEBUG2*/
  32. /*#define SCANDEBUG*/
  33. /* For AspiRouter */
  34. #include "scg/srb_os2.h"
  35. #define FILE_OPEN 0x0001
  36. #define OPEN_SHARE_DENYREADWRITE 0x0010
  37. #define OPEN_ACCESS_READWRITE 0x0002
  38. #define DC_SEM_SHARED 0x01
  39. #define OBJ_TILE 0x0040
  40. #define PAG_READ 0x0001
  41. #define PAG_WRITE 0x0002
  42. #define PAG_COMMIT 0x0010
  43. typedef unsigned long LHANDLE;
  44. typedef unsigned long ULONG;
  45. typedef unsigned char *PSZ;
  46. typedef unsigned short USHORT;
  47. typedef unsigned char UCHAR;
  48. typedef LHANDLE HFILE;
  49. typedef ULONG HEV;
  50. #define MAX_SCG 16 /* Max # of SCSI controllers */
  51. #define MAX_TGT 16
  52. #define MAX_LUN 8
  53. struct scg_local {
  54. short scgfiles[MAX_SCG][MAX_TGT][MAX_LUN];
  55. };
  56. #define scglocal(p) ((struct scg_local *)((p)->local)) 
  57. #define MAX_DMA_OS2 (63*1024) /* ASPI-Router allows up to 64k */
  58. LOCAL void *buffer = NULL;
  59. LOCAL HFILE driver_handle = 0;
  60. LOCAL HEV postSema = 0;
  61. #ifdef XXX
  62. LOCAL int fileHandle;
  63. #endif
  64. LOCAL BOOL open_driver __PR((void));
  65. LOCAL BOOL close_driver __PR((void));
  66. LOCAL ULONG wait_post __PR((ULONG ulTimeOut));
  67. LOCAL BOOL  init_buffer __PR((void* mem));
  68. EXPORT void exit_func __PR((void));
  69. #ifdef SCANDEBUG
  70. LOCAL ULONG test_unit_ready_aspi __PR(( UCHAR busno, UCHAR tgt, UCHAR tlun));
  71. #endif
  72. EXPORT void
  73. exit_func()
  74. {
  75. if (!close_driver())
  76. fprintf(stderr, "Cannot close OS/2-ASPI-Router!n");
  77. }
  78. EXPORT int
  79. scsi_open(scgp, device, busno, tgt, tlun)
  80. SCSI *scgp;
  81. char *device;
  82. int busno;
  83. int tgt;
  84. int tlun;
  85. {
  86. register int b;
  87. register int t;
  88. register int l;
  89. register int f;
  90. register int nopen = 0;
  91. if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) {
  92. errno = EINVAL;
  93. if (scgp->errstr)
  94. js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
  95. "Illegal value for busno, target or lun '%d,%d,%d'",
  96. busno, tgt, tlun);
  97. return (-1);
  98. }
  99. if ((device != NULL && *device != '') || (busno == -2 && tgt == -2)) {
  100. errno = EINVAL;
  101. if (scgp->errstr)
  102. js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
  103. "Open by 'devname' not supported on this OS");
  104. return (-1);
  105. }
  106. if (scgp->local == NULL) {
  107. scgp->local = malloc(sizeof(struct scg_local));
  108. if (scgp->local == NULL)
  109. return (0);
  110. for (b=0; b < MAX_SCG; b++) {
  111. for (t=0; t < MAX_TGT; t++) {
  112. for (l=0; l < MAX_LUN ; l++)
  113. scglocal(scgp)->scgfiles[b][t][l] = (short)-1;
  114. }
  115. }
  116. }
  117. if (!open_driver()) /* Try to open ASPI-Router */
  118. return (-1);
  119. atexit(exit_func); /* Install Exit Function which closes the ASPI-Router */
  120.   
  121. if (busno >= 0 && tgt >= 0 && tlun >= 0) {
  122. scglocal(scgp)->scgfiles[busno][tgt][tlun] = 1; /* We do not need it anywhere */
  123. #ifdef XXX
  124. fileHandle = open("test.wav", O_BINARY|O_RDWR|O_CREAT|O_SYNC, S_IREAD|S_IWRITE);
  125. if (fileHandle == -1) {
  126. fileHandle = 0;
  127. printf("Cannot open testfile.n");
  128. }
  129. #endif
  130. return (1);
  131. } else {
  132. for (b=0; b < MAX_SCG; b++) {
  133. for (t=0; t < MAX_TGT; t++) {
  134. for (l=0; l < MAX_LUN ; l++) {
  135. #ifdef SCANDEBUG
  136. f = test_unit_ready_aspi(b, t, l);
  137. if (f == 0) {
  138. scglocal(scgp)->scgfiles[b][t][l] = (short)f;
  139. scglocal(scgp)->scgfiles[b][t][l] = (short)1;
  140. nopen++;
  141. } else if (scgp->debug) {
  142. errmsg("open '0x%x 0x%x 0x%x'n",
  143. b, t, l);
  144. }
  145. #else
  146. scglocal(scgp)->scgfiles[b][t][l] = (short)1;
  147. nopen++;
  148. #endif
  149. }
  150. }
  151. }
  152. }
  153. return (nopen);
  154. }
  155. EXPORT int
  156. scsi_close(scgp)
  157. SCSI *scgp;
  158. {
  159. exit_func();
  160. return (0);
  161. }
  162. LOCAL long
  163. scsi_maxdma(scgp)
  164. SCSI *scgp;
  165. {
  166. long maxdma = MAX_DMA_OS2;
  167. return (maxdma);
  168. }
  169. EXPORT void *
  170. scsi_getbuf(scgp, amt)
  171. SCSI *scgp;
  172. long amt;
  173. {
  174. ULONG rc;
  175. if (amt <= 0 || amt > scsi_maxdma(scgp))
  176. return ((void *)0);
  177. #ifdef DEBUG
  178. printf("scsi_getbuf: %ld bytesn", amt);
  179. #endif
  180. rc = DosAllocMem(&buffer, amt, OBJ_TILE | PAG_READ | PAG_WRITE | PAG_COMMIT);
  181. if (rc) {
  182. fprintf(stderr, "Cannot allocate buffer.n");
  183. return ((void *)0);
  184. }
  185. scgp->bufbase = buffer;
  186. #ifdef DEBUG
  187. printf("Buffer allocated at: 0x%xn", scgp->bufbase);
  188. #endif
  189. /* Lock memory */
  190. if (init_buffer(scgp->bufbase))
  191. return (scgp->bufbase);
  192. fprintf(stderr, "Cannot lock memory buffer.n");
  193. return ((void *)0); /* Error */
  194. }
  195. EXPORT void
  196. scsi_freebuf(scgp)
  197. SCSI *scgp;
  198. {
  199. if (scgp->bufbase && DosFreeMem(scgp->bufbase))
  200. fprintf(stderr, "Cannot free buffer memory for ASPI-Router!n"); /* Free our memory buffer if not already done */
  201. if (buffer == scgp->bufbase)
  202. buffer = NULL;
  203. scgp->bufbase = NULL;
  204. }
  205. EXPORT
  206. BOOL scsi_havebus(scgp, busno)
  207. SCSI *scgp;
  208. int busno;
  209. {
  210. register int t;
  211. register int l;
  212. if (busno < 0 || busno >= MAX_SCG)
  213. return (FALSE);
  214. if (scgp->local == NULL)
  215. return (FALSE);
  216. for (t=0; t < MAX_TGT; t++) {
  217. for (l=0; l < MAX_LUN ; l++)
  218. if (scglocal(scgp)->scgfiles[busno][t][l] >= 0)
  219. return (TRUE);
  220. }
  221. return (FALSE);
  222. }
  223. EXPORT
  224. int scsi_fileno(scgp, busno, tgt, tlun)
  225. SCSI *scgp;
  226. int busno;
  227. int tgt;
  228. int tlun;
  229. {
  230. if (busno < 0 || busno >= MAX_SCG ||
  231.     tgt < 0 || tgt >= MAX_TGT ||
  232.     tlun < 0 || tlun >= MAX_LUN)
  233. return (-1);
  234. if (scgp->local == NULL)
  235. return (-1);
  236. return ((int)scglocal(scgp)->scgfiles[busno][tgt][tlun]);
  237. }
  238. EXPORT int
  239. scsi_initiator_id(scgp)
  240. SCSI *scgp;
  241. {
  242. return (-1);
  243. }
  244. EXPORT int
  245. scsi_isatapi(scgp)
  246. SCSI *scgp;
  247. {
  248. return (FALSE);
  249. }
  250. EXPORT
  251. int scsireset(scgp)
  252. SCSI *scgp;
  253. {
  254. ULONG rc; /* return value */
  255. Ulong cbreturn;
  256. Ulong cbParam;
  257. BOOL success;
  258. SRB SRBlock;
  259. SRBlock.cmd = SRB_Reset; /* reset device */
  260. SRBlock.ha_num = scgp->scsibus;/* host adapter number */
  261. SRBlock.flags = SRB_Post; /* posting enabled */
  262. SRBlock.u.res.target = scgp->target; /* target id */
  263. SRBlock.u.res.lun = scgp->lun; /* target LUN */
  264. rc = DosDevIOCtl(driver_handle, 0x92, 0x02, (void*) &SRBlock, sizeof(SRB), &cbParam,
  265. (void*) &SRBlock, sizeof(SRB), &cbreturn);
  266. if (rc) {
  267. fprintf(stderr, "DosDevIOCtl() failed in resetDevice.n");
  268. return (1); /* DosDevIOCtl failed */
  269. } else {
  270. success = wait_post(40000); /** wait for SRB being processed */
  271. if (success)
  272. return (2);
  273. }
  274. if (SRBlock.status != SRB_Done)
  275. return (3);
  276. #ifdef DEBUG
  277. printf("resetDevice of host: %d target: %d lun: %d successful.n", scgp->scsibus, scgp->target, scgp->lun);
  278. printf("SRBlock.ha_status: 0x%x, SRBlock.target_status: 0x%x, SRBlock.satus: 0x%xn",
  279.  SRBlock.u.cmd.ha_status, SRBlock.u.cmd.target_status, SRBlock.status);
  280. #endif
  281. return (0);
  282. }
  283. LOCAL int
  284. scsi_send(scgp, f, sp)
  285. SCSI *scgp;
  286. int f;
  287. struct scg_cmd *sp;
  288. {
  289. ULONG rc; /* return value */
  290. SRB SRBlock;
  291. Ulong cbreturn;
  292. Ulong cbParam;
  293. UCHAR* ptr;
  294. static int done = 0;
  295. if (!f) { /* Set in scsi_open() */
  296. sp->error = SCG_FATAL;
  297. return (-1);
  298. }
  299. if (sp->cdb_len > sizeof(SRBlock.u.cmd.cdb_st)) { /* commandsize too big */
  300. sp->error = SCG_FATAL;
  301. fprintf(stderr, "sp->cdb_len > SRBlock.u.cmd.cdb_st. Fatal error in scsi_send, exiting...n");
  302. return (-1);
  303. }
  304. /* clear command block */
  305. fillbytes((caddr_t)&SRBlock.u.cmd.cdb_st, sizeof(SRBlock.u.cmd.cdb_st), '');
  306. /* copy cdrecord command into SRB */
  307. movebytes(&sp->cdb, &SRBlock.u.cmd.cdb_st, sp->cdb_len);
  308. /* execute SCSI command */
  309. SRBlock.cmd = SRB_Command;
  310. SRBlock.ha_num = scgp->scsibus; /* host adapter number */
  311. SRBlock.flags = 0;
  312. SRBlock.flags = SRB_Post; /* flags */
  313. SRBlock.u.cmd.target = scgp->target; /* Target SCSI ID */
  314. SRBlock.u.cmd.lun = scgp->lun; /* Target SCSI LUN */
  315. SRBlock.u.cmd.data_len = sp->size; /* # of bytes transferred */
  316. SRBlock.u.cmd.data_ptr = 0; /* pointer to data buffer */
  317. SRBlock.u.cmd.sense_len = sp->sense_len;/* length of sense buffer */
  318. SRBlock.u.cmd.link_ptr = 0; /* pointer to next SRB */
  319. SRBlock.u.cmd.cdb_len = sp->cdb_len; /* SCSI command length */
  320. if (sp->flags & SCG_RECV_DATA) {
  321. SRBlock.flags |= SRB_Read;
  322. } else {
  323. if (sp->size > 0) {
  324. SRBlock.flags |= SRB_Write;
  325. if (scgp->bufbase != sp->addr) {/* Copy only if data not in ASPI-Mem */
  326. movebytes(sp->addr, scgp->bufbase, sp->size);
  327. } else {
  328. /* SRBlock.flags |= SRB_NoTransfer;*/
  329. }
  330. #ifdef DEBUG2
  331. printf("data_len=0d%d, sp->size=0d%d, sp->addr0x%x, buffer0x%xn",
  332. SRBlock.u.cmd.data_len, sp->size, sp->addr, scgp->bufbase);
  333. printf("Input cdb[](0x): %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %xn",
  334. SRBlock.u.cmd.cdb_st[0], SRBlock.u.cmd.cdb_st[1],
  335. SRBlock.u.cmd.cdb_st[2], SRBlock.u.cmd.cdb_st[3], SRBlock.u.cmd.cdb_st[4], SRBlock.u.cmd.cdb_st[5],
  336. SRBlock.u.cmd.cdb_st[6], SRBlock.u.cmd.cdb_st[7], SRBlock.u.cmd.cdb_st[8], SRBlock.u.cmd.cdb_st[9],
  337. SRBlock.u.cmd.cdb_st[10], SRBlock.u.cmd.cdb_st[11], SRBlock.u.cmd.cdb_st[12], SRBlock.u.cmd.cdb_st[13],
  338. SRBlock.u.cmd.cdb_st[14], SRBlock.u.cmd.cdb_st[15], SRBlock.u.cmd.cdb_st[16], SRBlock.u.cmd.cdb_st[17],
  339. SRBlock.u.cmd.cdb_st[18], SRBlock.u.cmd.cdb_st[19], SRBlock.u.cmd.cdb_st[20], SRBlock.u.cmd.cdb_st[21]);
  340. #endif
  341. #ifdef XXX
  342. if (fileHandle)
  343. write(fileHandle, sp->addr, sp->size);
  344. #endif
  345. }
  346. }
  347. sp->error = SCG_NO_ERROR;
  348. sp->sense_count = 0;
  349. sp->u_scb.cmd_scb[0] = 0;
  350. sp->resid = 0;
  351. #ifdef DEBUG2
  352. printf("Input cdb[](0x): %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %xn",
  353.  SRBlock.u.cmd.cdb_st[0], SRBlock.u.cmd.cdb_st[1],
  354.  SRBlock.u.cmd.cdb_st[2], SRBlock.u.cmd.cdb_st[3], SRBlock.u.cmd.cdb_st[4], SRBlock.u.cmd.cdb_st[5],
  355.  SRBlock.u.cmd.cdb_st[6], SRBlock.u.cmd.cdb_st[7], SRBlock.u.cmd.cdb_st[8], SRBlock.u.cmd.cdb_st[9],
  356.  SRBlock.u.cmd.cdb_st[10], SRBlock.u.cmd.cdb_st[11], SRBlock.u.cmd.cdb_st[12], SRBlock.u.cmd.cdb_st[13],
  357.  SRBlock.u.cmd.cdb_st[14], SRBlock.u.cmd.cdb_st[15], SRBlock.u.cmd.cdb_st[16], SRBlock.u.cmd.cdb_st[17],
  358.  SRBlock.u.cmd.cdb_st[18], SRBlock.u.cmd.cdb_st[19], SRBlock.u.cmd.cdb_st[20], SRBlock.u.cmd.cdb_st[21]);
  359. printf("data_len=0x%x, sense_len=0x%x, cdb_len=0x%xn",
  360.  SRBlock.u.cmd.data_len, SRBlock.u.cmd.sense_len, SRBlock.u.cmd.cdb_len);
  361. ptr = (UCHAR*)&sp->cdb;
  362. printf("buffer(0x): %x %x %x %x %x %x, addr=%xn",
  363.  *(ptr), *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
  364.  *(ptr+5), sp->addr);
  365. #endif
  366. done++;
  367. rc = DosDevIOCtl(driver_handle, 0x92, 0x02,
  368.  (void*) &SRBlock, sizeof(SRB), &cbParam,
  369.  (void*) &SRBlock, sizeof(SRB), &cbreturn);
  370. if (rc) {
  371. fprintf(stderr, "DosDevIOCtl() in sendCommand failed.n");
  372. sp->error = SCG_FATAL;
  373. sp->ux_errno = EIO; /* Sp鋞er vielleicht errno einsetzen */
  374. return (rc);
  375. } else {
  376. rc = wait_post(sp->timeout*1000);
  377. if (rc) {
  378. if (rc == 640) {
  379. sp->error = SCG_TIMEOUT;
  380. fprintf(stderr, "Timeout during SCSI-Command.n");
  381. return (1);
  382. }
  383. sp->error = SCG_FATAL;
  384. fprintf(stderr, "Fatal Error during DosWaitEventSem().n");
  385. return (1);
  386. }
  387. #ifdef DEBUG2
  388. printf("wait_post() returned rc=%xn", rc);
  389. printf("Done cdb[](0x): %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %xn",
  390.  SRBlock.u.cmd.cdb_st[0], SRBlock.u.cmd.cdb_st[1],
  391.  SRBlock.u.cmd.cdb_st[2], SRBlock.u.cmd.cdb_st[3], SRBlock.u.cmd.cdb_st[4], SRBlock.u.cmd.cdb_st[5],
  392.  SRBlock.u.cmd.cdb_st[6], SRBlock.u.cmd.cdb_st[7], SRBlock.u.cmd.cdb_st[8], SRBlock.u.cmd.cdb_st[9],
  393.  SRBlock.u.cmd.cdb_st[10], SRBlock.u.cmd.cdb_st[11], SRBlock.u.cmd.cdb_st[12], SRBlock.u.cmd.cdb_st[13],
  394.  SRBlock.u.cmd.cdb_st[14], SRBlock.u.cmd.cdb_st[15], SRBlock.u.cmd.cdb_st[16], SRBlock.u.cmd.cdb_st[17],
  395.  SRBlock.u.cmd.cdb_st[18], SRBlock.u.cmd.cdb_st[19], SRBlock.u.cmd.cdb_st[20], SRBlock.u.cmd.cdb_st[21],
  396.  SRBlock.u.cmd.cdb_st[22], SRBlock.u.cmd.cdb_st[23], SRBlock.u.cmd.cdb_st[24], SRBlock.u.cmd.cdb_st[25],
  397.  SRBlock.u.cmd.cdb_st[26], SRBlock.u.cmd.cdb_st[27]);
  398. printf("data_len=0x%x, sense_len=0x%x, cdb_len=0x%x, SRBlock.status=0x%x, size=0x%x, target_status=0x%xn",
  399.  SRBlock.u.cmd.data_len, SRBlock.u.cmd.sense_len, SRBlock.u.cmd.cdb_len, SRBlock.status,
  400.  sp->size, SRBlock.u.cmd.target_status);
  401. ptr = (UCHAR*)scgp->bufbase;
  402. printf("buffer(0x): %x %x %x %x %x %x, buffer=%xn",
  403.  *(ptr), *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
  404.  *(ptr+5), scgp->bufbase);
  405. #endif
  406. if (SRBlock.status == SRB_Done) { /* succesful completion */
  407. #ifdef DEBUG
  408. printf("Command successful finished. SRBlock.status=0x%xnn", SRBlock.status);
  409. #endif
  410. sp->sense_count = 0;
  411. sp->resid = 0;
  412. if (sp->flags & SCG_RECV_DATA) {
  413. if (sp->addr && sp->size) {
  414. if (scgp->bufbase != sp->addr) /* Copy only if data not in ASPI-Mem */
  415. movebytes(scgp->bufbase, sp->addr, SRBlock.u.cmd.data_len);
  416. ptr = (UCHAR*)sp->addr;
  417. sp->resid = sp->size - SRBlock.u.cmd.data_len;/*nicht 黚ertragene bytes. Korrekt berechnet???*/
  418. }
  419. } /* end of if (sp->flags & SCG_RECV_DATA) */
  420. if (SRBlock.u.cmd.target_status == SRB_CheckStatus) { /* Sense data valid */
  421. sp->sense_count = (int)SRBlock.u.cmd.sense_len;
  422. if (sp->sense_count > sp->sense_len)
  423. sp->sense_count = sp->sense_len;
  424. ptr = (UCHAR*)&SRBlock.u.cmd.cdb_st;
  425. ptr += SRBlock.u.cmd.cdb_len;
  426. fillbytes(&sp->u_sense.Sense, sizeof(sp->u_sense.Sense), '');
  427. movebytes(ptr, &sp->u_sense.Sense, sp->sense_len);
  428. sp->u_scb.cmd_scb[0] = SRBlock.u.cmd.target_status;
  429. sp->ux_errno = EIO; /* Sp鋞er differenzieren? */
  430. }
  431. return (0);
  432. }
  433. /* SCSI-Error occured */
  434. sp->error = SCG_RETRYABLE;
  435. #ifdef DEBUG2
  436. printf("Done cdb[](0x): %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %xn",
  437.  SRBlock.u.cmd.cdb_st[0], SRBlock.u.cmd.cdb_st[1],
  438.  SRBlock.u.cmd.cdb_st[2], SRBlock.u.cmd.cdb_st[3], SRBlock.u.cmd.cdb_st[4], SRBlock.u.cmd.cdb_st[5],
  439.  SRBlock.u.cmd.cdb_st[6], SRBlock.u.cmd.cdb_st[7], SRBlock.u.cmd.cdb_st[8], SRBlock.u.cmd.cdb_st[9],
  440.  SRBlock.u.cmd.cdb_st[10], SRBlock.u.cmd.cdb_st[11], SRBlock.u.cmd.cdb_st[12], SRBlock.u.cmd.cdb_st[13],
  441.  SRBlock.u.cmd.cdb_st[14], SRBlock.u.cmd.cdb_st[15], SRBlock.u.cmd.cdb_st[16], SRBlock.u.cmd.cdb_st[17],
  442.  SRBlock.u.cmd.cdb_st[18], SRBlock.u.cmd.cdb_st[19], SRBlock.u.cmd.cdb_st[20], SRBlock.u.cmd.cdb_st[21],
  443.  SRBlock.u.cmd.cdb_st[22], SRBlock.u.cmd.cdb_st[23], SRBlock.u.cmd.cdb_st[24], SRBlock.u.cmd.cdb_st[25],
  444.  SRBlock.u.cmd.cdb_st[26], SRBlock.u.cmd.cdb_st[27]);
  445. printf("data_len=0x%x, cdb_len=0x%x, SRBlock.status=0x%x, flags=0x%x, ha_status=0x%x, target_status=0x%xn",
  446.  SRBlock.u.cmd.data_len, SRBlock.u.cmd.cdb_len, SRBlock.status,
  447.  sp->flags, SRBlock.u.cmd.ha_status, SRBlock.u.cmd.target_status);
  448. ptr = (UCHAR*)scgp->bufbase;
  449. printf("buffer(0x): %x %x %x %x %x %x, buffer=%xn",
  450.  *(ptr), *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
  451.  *(ptr+5), scgp->bufbase);
  452. #endif
  453. if (SRBlock.u.cmd.target_status == SRB_CheckStatus) { /* Sense data valid */
  454. sp->sense_count = (int)SRBlock.u.cmd.sense_len;
  455. if (sp->sense_count > sp->sense_len)
  456. sp->sense_count = sp->sense_len;
  457. ptr = (UCHAR*)&SRBlock.u.cmd.cdb_st;
  458. ptr += SRBlock.u.cmd.cdb_len;
  459. fillbytes(&sp->u_sense.Sense, sizeof(sp->u_sense.Sense), '');
  460. movebytes(ptr, &sp->u_sense.Sense, sp->sense_len);
  461. sp->u_scb.cmd_scb[0] = SRBlock.u.cmd.target_status;
  462. sp->ux_errno = EIO;
  463. }
  464. if (sp->flags & SCG_RECV_DATA) {
  465. if (sp->addr && sp->size) {
  466. if (scgp->bufbase != sp->addr) /* Copy only if data not in ASPI-Mem */
  467. movebytes(scgp->bufbase, sp->addr, SRBlock.u.cmd.data_len);
  468. }
  469. }
  470. #ifdef really
  471. sp->resid = SRBlock.u.cmd.data_len;/* XXXXX Got no Data ????? */
  472. #else
  473. sp->resid = sp->size - SRBlock.u.cmd.data_len;
  474. #endif
  475. return (0);
  476. }
  477. }
  478. /***************************************************************************
  479.  *                                                                         *
  480.  *  BOOL open_driver()                                                     *
  481.  *                                                                         *
  482.  *  Opens the ASPI Router device driver and sets device_handle.            *
  483.  *  Returns:                                                               *
  484.  *    TRUE - Success                                                       *
  485.  *    FALSE - Unsuccessful opening of device driver                        *
  486.  *                                                                         *
  487.  *  Preconditions: ASPI Router driver has be loaded                        *
  488.  *                                                                         *
  489.  ***************************************************************************/
  490. LOCAL BOOL
  491. open_driver()
  492. {
  493. ULONG rc; /* return value */
  494. ULONG ActionTaken; /* return value */
  495. USHORT openSemaReturn; /* return value */
  496. Ulong cbreturn;
  497. Ulong cbParam;
  498. if (driver_handle) /* ASPI-Router already opened */
  499. return (TRUE);
  500. rc = DosOpen((PSZ) "aspirou$", /* open driver*/
  501. &driver_handle,
  502. &ActionTaken,
  503. 0,
  504. 0,
  505. FILE_OPEN,
  506. OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE,
  507. NULL);
  508. if (rc) {
  509. fprintf(stderr, "Cannot open ASPI-Router!n");
  510. return (FALSE); /* opening failed -> return false*/
  511. }
  512. /* Init semaphore */
  513. if (DosCreateEventSem(NULL, &postSema, /* create event semaphore */
  514.  DC_SEM_SHARED, 0)) {
  515. DosClose(driver_handle);
  516. fprintf(stderr, "Cannot create event semaphore!n");
  517. return (FALSE);
  518. }
  519. rc = DosDevIOCtl(driver_handle, 0x92, 0x03, /* pass semaphore handle */
  520. (void*) &postSema, sizeof(HEV), /* to driver  */
  521. &cbParam, (void*) &openSemaReturn,
  522. sizeof(USHORT), &cbreturn);
  523. if (rc||openSemaReturn) { /* Error */
  524. DosCloseEventSem(postSema);
  525. DosClose(driver_handle);
  526. return (FALSE);
  527. }
  528. return (TRUE);
  529. }
  530. /***************************************************************************
  531.  *                                                                         *
  532.  *  BOOL close_driver()                                                    *
  533.  *                                                                         *
  534.  *  Closes the device driver                                               *
  535.  *  Returns:                                                               *
  536.  *    TRUE - Success                                                       *
  537.  *    FALSE - Unsuccessful closing of device driver                        *
  538.  *                                                                         *
  539.  *  Preconditions: ASPI Router driver has be opened with open_driver       *
  540.  *                                                                         *
  541.  ***************************************************************************/
  542. LOCAL BOOL
  543. close_driver()
  544. {
  545. ULONG rc; /* return value */
  546. if (driver_handle) {
  547. rc = DosClose(driver_handle);
  548. if (rc)
  549. return (FALSE); /* closing failed -> return false */
  550. driver_handle = 0;
  551. if (DosCloseEventSem(postSema))
  552. fprintf(stderr, "Cannot close event semaphore!n");
  553. if (buffer && DosFreeMem(buffer))
  554. fprintf(stderr, "Cannot free buffer memory for ASPI-Router!n"); /* Free our memory buffer if not already done */
  555. buffer = NULL;
  556. }
  557. return (TRUE);
  558. }
  559. #ifdef SCANDEBUG
  560. /***************************************************************************/
  561. /*                                                                         */
  562. /*  ULONG test_unit_ready_aspi(UCHAR busno, UCHAR tgt, UCHAR tlun)         */
  563. /*                                                                         */
  564. /*  Sends a SRB containing a test unit ready command                       */
  565. /*  Returns:                                                               */
  566. /*    0  - Success                                                         */
  567. /*    1  - DevIOCtl failed                                                 */
  568. /*    2  - Semaphore access failure                                        */
  569. /*    3  - SCSI command failed                                             */
  570. /*                                                                         */
  571. /*  Preconditions: init() has to be called successfully before             */
  572. /*                                                                         */
  573. /***************************************************************************/
  574. ULONG test_unit_ready_aspi( UCHAR busno, UCHAR tgt, UCHAR tlun)
  575. {
  576. ULONG rc; /* return value */
  577. BOOL  success; /* return value */
  578. Ulong cbreturn;
  579. Ulong cbParam;
  580. SRB SRBlock;
  581.   
  582. SRBlock.cmd = SRB_Command; /* execute SCSI cmd */
  583. SRBlock.ha_num = busno; /* host adapter number */
  584. SRBlock.flags = SRB_NoTransfer | SRB_Post; /* no data transfer, posting enabled */
  585. SRBlock.u.cmd.target = tgt; /* Target SCSI ID */
  586. SRBlock.u.cmd.lun = tlun; /* Target SCSI LUN */
  587. SRBlock.u.cmd.data_len = 0; /* # of bytes transferred */
  588. SRBlock.u.cmd.sense_len = 32; /* length of sense buffer */
  589. SRBlock.u.cmd.data_ptr = 0; /* pointer to data buffer */
  590. SRBlock.u.cmd.link_ptr = 0; /* pointer to next SRB */
  591. SRBlock.u.cmd.cdb_len = 6; /* SCSI command length */
  592. SRBlock.u.cmd.cdb_st[0] = 0x0; /* test unit ready command */
  593. SRBlock.u.cmd.cdb_st[1] = (tlun << 5); /* lun */
  594. SRBlock.u.cmd.cdb_st[2] = 0;
  595. SRBlock.u.cmd.cdb_st[3] = 0;
  596. SRBlock.u.cmd.cdb_st[4] = 0;
  597. SRBlock.u.cmd.cdb_st[5] = 0;
  598. rc = DosDevIOCtl(driver_handle, 0x92, 0x02, (void*) &SRBlock, sizeof(SRB), &cbParam,
  599.    (void*) &SRBlock, sizeof(SRB), &cbreturn);
  600. if (rc) {
  601. return 1; /* DosDevIOCtl failed */
  602. } else {
  603. success = wait_post(40000); /* wait for SRB being processed */
  604. if (success) return 2; /* semaphore could not be accessed */
  605. }
  606. if (SRBlock.status != SRB_Done) return 3;
  607. if (SRBlock.u.cmd.ha_status != SRB_NoError) return 3;
  608. if (SRBlock.u.cmd.target_status != SRB_NoStatus) return 3;
  609. return (0);
  610. }
  611. #endif /* SCANDEBUG */
  612. LOCAL ULONG
  613. wait_post(ULONG ulTimeOut)
  614. {
  615. ULONG count = 0;
  616. ULONG rc; /* return value */
  617. /* rc = DosWaitEventSem(postSema, -1);*/ /* wait forever*/
  618. rc = DosWaitEventSem(postSema, ulTimeOut);
  619. if (!rc)
  620. DosResetEventSem(postSema, &count); /* ?????????? */
  621. return (rc);
  622. }
  623. LOCAL BOOL 
  624. init_buffer(mem)
  625. void *mem;
  626. {
  627. ULONG rc; /* return value */
  628. USHORT lockSegmentReturn; /* return value */
  629. Ulong cbreturn;
  630. Ulong cbParam;
  631. rc = DosDevIOCtl(driver_handle, 0x92, 0x04, /* pass buffers pointer */
  632. (void*) mem, sizeof(void*), /* to driver */
  633. &cbParam, (void*) &lockSegmentReturn,
  634. sizeof(USHORT), &cbreturn);
  635. if (rc)
  636. return (FALSE); /* DosDevIOCtl failed */
  637. if (lockSegmentReturn)
  638. return (FALSE); /* Driver could not lock segment */
  639. return (TRUE);
  640. }
  641. #define sense u_sense.Sense