1 | /* $Id: aspilib.cpp,v 1.5 2000-09-15 13:25:46 sandervl Exp $ */
|
---|
2 | /*
|
---|
3 | * ASPI Router Library
|
---|
4 | * for Odin WNASPI32.DLL
|
---|
5 | *
|
---|
6 | * This is a sample library which shows how to send SRB's to the
|
---|
7 | * ASPI Router device driver. USE AT YOUR OWN RISK!!
|
---|
8 | *
|
---|
9 | * Copyright (C) 1997 Daniel Dorau
|
---|
10 | * Copyright (C) 2000 Przemyslaw Dobrowolski <dobrawka@asua.org.pl>
|
---|
11 | *
|
---|
12 | */
|
---|
13 | #define INCL_DOSFILEMGR
|
---|
14 | #define INCL_DOSDEVICES
|
---|
15 | #define INCL_DOSDEVIOCTL
|
---|
16 | #define INCL_DOSSEMAPHORES
|
---|
17 | #define INCL_DOSMEMMGR
|
---|
18 | #define INCL_DOSERRORS
|
---|
19 | #include <os2wrap.h>
|
---|
20 | #include <string.h>
|
---|
21 | #include <stdio.h>
|
---|
22 | #include <misc.h>
|
---|
23 | #include "aspilib.h"
|
---|
24 |
|
---|
25 | #define WNASPI32_MUTEX_NAME "\\SEM32\\ODIN\\ASPIROUT"
|
---|
26 |
|
---|
27 | //***************************************************************************
|
---|
28 | //* *
|
---|
29 | //* scsiObj() *
|
---|
30 | //* *
|
---|
31 | //* Standard constructor *
|
---|
32 | //* *
|
---|
33 | //***************************************************************************
|
---|
34 | scsiObj::scsiObj() : buffer(NULL), hmtxDriver(0)
|
---|
35 | {
|
---|
36 | memset(&SRBlock, 0, sizeof(SRBlock));
|
---|
37 | memset(&AbortSRB, 0, sizeof(AbortSRB));
|
---|
38 | }
|
---|
39 |
|
---|
40 |
|
---|
41 | //***************************************************************************
|
---|
42 | //* *
|
---|
43 | //* ~scsiObj() *
|
---|
44 | //* *
|
---|
45 | //* Standard destructor *
|
---|
46 | //* *
|
---|
47 | //***************************************************************************
|
---|
48 | scsiObj::~scsiObj()
|
---|
49 | {
|
---|
50 | }
|
---|
51 |
|
---|
52 |
|
---|
53 | //***************************************************************************
|
---|
54 | //* *
|
---|
55 | //* BOOL openDriver() *
|
---|
56 | //* *
|
---|
57 | //* Opens the ASPI Router device driver and sets device_handle. *
|
---|
58 | //* Returns: *
|
---|
59 | //* TRUE - Success *
|
---|
60 | //* FALSE - Unsuccessful opening of device driver *
|
---|
61 | //* *
|
---|
62 | //* Preconditions: ASPI Router driver has be loaded *
|
---|
63 | //* *
|
---|
64 | //***************************************************************************
|
---|
65 | BOOL scsiObj::openDriver()
|
---|
66 | {
|
---|
67 | ULONG rc; // return value
|
---|
68 | ULONG ActionTaken; // return value
|
---|
69 |
|
---|
70 | rc = DosOpen((PSZ) "aspirou$", // open driver
|
---|
71 | &driver_handle,
|
---|
72 | &ActionTaken,
|
---|
73 | 0,
|
---|
74 | 0,
|
---|
75 | FILE_OPEN,
|
---|
76 | OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE,
|
---|
77 | NULL);
|
---|
78 | if (rc) return FALSE; // opening failed -> return false
|
---|
79 | return TRUE;
|
---|
80 | }
|
---|
81 |
|
---|
82 |
|
---|
83 | //***************************************************************************
|
---|
84 | //* *
|
---|
85 | //* BOOL closeDriver() *
|
---|
86 | //* *
|
---|
87 | //* Closes the device driver *
|
---|
88 | //* Returns: *
|
---|
89 | //* TRUE - Success *
|
---|
90 | //* FALSE - Unsuccessful closing of device driver *
|
---|
91 | //* *
|
---|
92 | //* Preconditions: ASPI Router driver has be opened with openDriver *
|
---|
93 | //* *
|
---|
94 | //***************************************************************************
|
---|
95 | BOOL scsiObj::closeDriver()
|
---|
96 | {
|
---|
97 | ULONG rc; // return value
|
---|
98 |
|
---|
99 | rc = DosClose(driver_handle);
|
---|
100 | if (rc) return FALSE; // closing failed -> return false
|
---|
101 | return TRUE;
|
---|
102 | }
|
---|
103 |
|
---|
104 |
|
---|
105 | //***************************************************************************
|
---|
106 | //* *
|
---|
107 | //* BOOL initSemaphore() *
|
---|
108 | //* *
|
---|
109 | //* Creates a new Event Semaphore and passes its handle to ASPI Router. *
|
---|
110 | //* Returns: *
|
---|
111 | //* TRUE - Success *
|
---|
112 | //* FALSE - Unsuccessful creation of event semaphore *
|
---|
113 | //* *
|
---|
114 | //* Preconditions: driver_handle has to be set with openDriver *
|
---|
115 | //* *
|
---|
116 | //***************************************************************************
|
---|
117 | BOOL scsiObj::initSemaphore()
|
---|
118 | {
|
---|
119 | ULONG rc; // return value
|
---|
120 | USHORT openSemaReturn; // return value
|
---|
121 | unsigned long cbreturn;
|
---|
122 | unsigned long cbParam;
|
---|
123 |
|
---|
124 | rc = DosCreateEventSem(NULL, &postSema, // create event semaphore
|
---|
125 | DC_SEM_SHARED, 0);
|
---|
126 | if (rc) return FALSE; // DosCreateEventSem failed
|
---|
127 | rc = DosDevIOCtl(driver_handle, 0x92, 0x03, // pass semaphore handle
|
---|
128 | (void*) &postSema, sizeof(HEV), // to driver
|
---|
129 | &cbParam, (void*) &openSemaReturn,
|
---|
130 | sizeof(USHORT), &cbreturn);
|
---|
131 | if (rc) return FALSE; // DosDevIOCtl failed
|
---|
132 | if (openSemaReturn) return FALSE; // Driver could not open semaphore
|
---|
133 |
|
---|
134 | return TRUE;
|
---|
135 | }
|
---|
136 |
|
---|
137 |
|
---|
138 | //***************************************************************************
|
---|
139 | //* *
|
---|
140 | //* BOOL closeSemaphore() *
|
---|
141 | //* *
|
---|
142 | //* Closes the Event Semaphore *
|
---|
143 | //* Returns: *
|
---|
144 | //* TRUE - Success *
|
---|
145 | //* FALSE - Unsuccessful closing of event semaphore *
|
---|
146 | //* *
|
---|
147 | //* Preconditions: init_Semaphore has to be called successfully before *
|
---|
148 | //* *
|
---|
149 | //***************************************************************************
|
---|
150 | BOOL scsiObj::closeSemaphore()
|
---|
151 | {
|
---|
152 | ULONG rc; // return value
|
---|
153 |
|
---|
154 | rc = DosCloseEventSem(postSema); // close event semaphore
|
---|
155 | if (rc) return FALSE; // DosCloseEventSem failed
|
---|
156 | return TRUE;
|
---|
157 | }
|
---|
158 |
|
---|
159 |
|
---|
160 | //***************************************************************************
|
---|
161 | //* *
|
---|
162 | //* BOOL initBuffer() *
|
---|
163 | //* *
|
---|
164 | //* Sends the address of the data buffer to ASPI Router so that it can *
|
---|
165 | //* lock down the segment. *
|
---|
166 | //* Returns: *
|
---|
167 | //* TRUE - Success *
|
---|
168 | //* FALSE - Unsuccessful locking of buffer segment *
|
---|
169 | //* *
|
---|
170 | //* Preconditions: (called from init()) *
|
---|
171 | //* *
|
---|
172 | //***************************************************************************
|
---|
173 | BOOL scsiObj::initBuffer()
|
---|
174 | {
|
---|
175 | ULONG rc; // return value
|
---|
176 | USHORT lockSegmentReturn; // return value
|
---|
177 | unsigned long cbreturn;
|
---|
178 | unsigned long cbParam;
|
---|
179 |
|
---|
180 | rc = DosDevIOCtl(driver_handle, 0x92, 0x04, // pass buffer pointer
|
---|
181 | (void*) buffer, sizeof(PVOID), // to driver
|
---|
182 | &cbParam, (void*) &lockSegmentReturn,
|
---|
183 | sizeof(USHORT), &cbreturn);
|
---|
184 | if (rc) return FALSE; // DosDevIOCtl failed
|
---|
185 | if (lockSegmentReturn) return FALSE; // Driver could not lock segment
|
---|
186 |
|
---|
187 | return TRUE;
|
---|
188 | }
|
---|
189 |
|
---|
190 |
|
---|
191 | //***************************************************************************
|
---|
192 | //* *
|
---|
193 | //* BOOL init(ULONG bufsize) *
|
---|
194 | //* *
|
---|
195 | //* This inits the ASPI library and ASPI router driver. *
|
---|
196 | //* Allocates the data buffer and passes its address to the driver *
|
---|
197 | //* Returns: *
|
---|
198 | //* TRUE - Success *
|
---|
199 | //* FALSE - Unsuccessful initialization of driver and library *
|
---|
200 | //* *
|
---|
201 | //* Preconditions: ASPI router device driver has to be loaded *
|
---|
202 | //* *
|
---|
203 | //***************************************************************************
|
---|
204 | BOOL scsiObj::init(ULONG bufsize)
|
---|
205 | {
|
---|
206 | BOOL success;
|
---|
207 | APIRET rc;
|
---|
208 |
|
---|
209 |
|
---|
210 | rc = DosCreateMutexSem(WNASPI32_MUTEX_NAME, (HMTX*)&hmtxDriver,
|
---|
211 | 0, TRUE);
|
---|
212 | if(rc == ERROR_DUPLICATE_NAME) {
|
---|
213 | rc = DosOpenMutexSem(WNASPI32_MUTEX_NAME, (HMTX*)&hmtxDriver);
|
---|
214 | }
|
---|
215 | if(rc != NO_ERROR) {
|
---|
216 | dprintf(("scsiObj::init: DosCreate/OpenMutexSem failed! (rc=%d)", rc));
|
---|
217 | return FALSE;
|
---|
218 | }
|
---|
219 |
|
---|
220 | rc = DosAllocMem(&buffer, bufsize, OBJ_TILE | PAG_READ | PAG_WRITE | PAG_COMMIT);
|
---|
221 | if (rc) return FALSE;
|
---|
222 | success=openDriver(); // call openDriver member function
|
---|
223 | if (!success) return FALSE;
|
---|
224 | success=initSemaphore(); // call initSemaphore member function
|
---|
225 | if (!success) return FALSE;
|
---|
226 |
|
---|
227 | success=initBuffer();
|
---|
228 |
|
---|
229 | return TRUE;
|
---|
230 | }
|
---|
231 |
|
---|
232 |
|
---|
233 | //***************************************************************************
|
---|
234 | //* *
|
---|
235 | //* BOOL close() *
|
---|
236 | //* *
|
---|
237 | //* This closes the ASPI library and ASPI router driver and frees *
|
---|
238 | //* the memory allocated for the data buffer.
|
---|
239 | //* Returns: *
|
---|
240 | //* TRUE - Success *
|
---|
241 | //* FALSE - Unsuccessful closing of library and driver *
|
---|
242 | //* *
|
---|
243 | //* Preconditions: init() should be called successfully before *
|
---|
244 | //* *
|
---|
245 | //***************************************************************************
|
---|
246 | BOOL scsiObj::close()
|
---|
247 | {
|
---|
248 | BOOL success;
|
---|
249 | ULONG rc;
|
---|
250 |
|
---|
251 | success=closeSemaphore(); // call closeSemaphore member function
|
---|
252 | if (!success)
|
---|
253 | {
|
---|
254 | dprintf(("scsiObj::close: closeSemaphore() unsuccessful."));
|
---|
255 | return FALSE;
|
---|
256 | }
|
---|
257 | success=closeDriver(); // call closeDriver member function
|
---|
258 | if (!success)
|
---|
259 | {
|
---|
260 | dprintf(("scsiObj::close: closeDriver() unsucessful."));
|
---|
261 | return FALSE;
|
---|
262 | }
|
---|
263 | rc = DosFreeMem(buffer);
|
---|
264 | if (rc)
|
---|
265 | {
|
---|
266 | dprintf(("scsiObj::close: DosFreeMem unsuccessful. return code: %ld", rc));
|
---|
267 | return FALSE;
|
---|
268 | }
|
---|
269 | if(hmtxDriver) {
|
---|
270 | rc = DosCloseMutexSem((HMTX)hmtxDriver);
|
---|
271 | if(rc != NO_ERROR) {
|
---|
272 | dprintf(("scsiObj::close: DosCloseMutexSem unsuccessful. return code: %ld", rc));
|
---|
273 | return FALSE;
|
---|
274 | }
|
---|
275 | }
|
---|
276 |
|
---|
277 | return TRUE;
|
---|
278 | }
|
---|
279 |
|
---|
280 |
|
---|
281 | //***************************************************************************
|
---|
282 | //* *
|
---|
283 | //* BOOL waitPost() *
|
---|
284 | //* *
|
---|
285 | //* Waits for postSema being posted by device driver *
|
---|
286 | //* Returns: *
|
---|
287 | //* TRUE - Success *
|
---|
288 | //* FALSE - Unsuccessful access of event semaphore *
|
---|
289 | //* *
|
---|
290 | //* Preconditions: init() has to be called successfully before *
|
---|
291 | //* *
|
---|
292 | //***************************************************************************
|
---|
293 | BOOL scsiObj::waitPost()
|
---|
294 | {
|
---|
295 | ULONG count=0;
|
---|
296 | ULONG rc; // return value
|
---|
297 |
|
---|
298 | rc = DosWaitEventSem(postSema, -1); // wait forever
|
---|
299 | if (rc) return FALSE; // DosWaitEventSem failed
|
---|
300 | rc = DosResetEventSem(postSema, &count); // reset semaphore
|
---|
301 | if (rc) return FALSE; // DosResetEventSem failed
|
---|
302 | return TRUE;
|
---|
303 | }
|
---|
304 |
|
---|
305 | //***************************************************************************
|
---|
306 | //* *
|
---|
307 | //* ULONG HA_inquiry(UCHAR ha) *
|
---|
308 | //* *
|
---|
309 | //* Sends a SRB containing a Host Adapter Inquiry command *
|
---|
310 | //* Returns: *
|
---|
311 | //* 0 - Success *
|
---|
312 | //* 1 - DevIOCtl failed *
|
---|
313 | //* 2 - Host Adapter not installed *
|
---|
314 | //* *
|
---|
315 | //* Preconditions: driver has to be opened *
|
---|
316 | //* *
|
---|
317 | //***************************************************************************
|
---|
318 | ULONG scsiObj::HA_inquiry(UCHAR ha)
|
---|
319 | {
|
---|
320 | ULONG rc; // return value
|
---|
321 | unsigned long cbreturn;
|
---|
322 | unsigned long cbParam;
|
---|
323 |
|
---|
324 | SRBlock.cmd=SRB_Inquiry; // host adapter inquiry
|
---|
325 | SRBlock.ha_num=ha; // host adapter number
|
---|
326 | SRBlock.flags=0; // no flags set
|
---|
327 |
|
---|
328 | rc = DosDevIOCtl(driver_handle, 0x92, 0x02, (void*) &SRBlock, sizeof(SRBOS2), &cbParam,
|
---|
329 | (void*) &SRBlock, sizeof(SRBOS2), &cbreturn);
|
---|
330 | if (rc)
|
---|
331 | return 1; // DosDevIOCtl failed
|
---|
332 | if (SRBlock.status != SRB_Done) return 2;
|
---|
333 | return 0;
|
---|
334 | }
|
---|
335 |
|
---|
336 |
|
---|
337 | //***************************************************************************
|
---|
338 | //* *
|
---|
339 | //* ULONG getDeviceType(UCHAR id, UCHAR lun) *
|
---|
340 | //* *
|
---|
341 | //* Sends a SRB containing a Get Device Type command *
|
---|
342 | //* Returns: *
|
---|
343 | //* 0 - Success *
|
---|
344 | //* 1 - DevIOCtl failed *
|
---|
345 | //* 2 - Device not installed *
|
---|
346 | //* *
|
---|
347 | //* Preconditions: driver has to be opened *
|
---|
348 | //* *
|
---|
349 | //***************************************************************************
|
---|
350 | ULONG scsiObj::getDeviceType(UCHAR ha_num, UCHAR id, UCHAR lun)
|
---|
351 | {
|
---|
352 | ULONG rc; // return value
|
---|
353 | unsigned long cbreturn;
|
---|
354 | unsigned long cbParam;
|
---|
355 |
|
---|
356 | SRBlock.cmd=SRB_Device; // get device type
|
---|
357 | SRBlock.ha_num=ha_num; // host adapter number
|
---|
358 | SRBlock.flags=0; // no flags set
|
---|
359 | SRBlock.u.dev.target=id; // target id
|
---|
360 | SRBlock.u.dev.lun=lun; // target LUN
|
---|
361 |
|
---|
362 | rc = DosDevIOCtl(driver_handle, 0x92, 0x02, (void*) &SRBlock, sizeof(SRBOS2), &cbParam,
|
---|
363 | (void*) &SRBlock, sizeof(SRBOS2), &cbreturn);
|
---|
364 | if (rc)
|
---|
365 | return 1; // DosDevIOCtl failed
|
---|
366 | if (SRBlock.status != SRB_Done) return 2;
|
---|
367 | return 0;
|
---|
368 | }
|
---|
369 |
|
---|
370 |
|
---|
371 | //***************************************************************************
|
---|
372 | //* *
|
---|
373 | //* ULONG resetDevice(UCHAR id, UCHAR lun) *
|
---|
374 | //* *
|
---|
375 | //* Sends a SRB containing a Reset Device command *
|
---|
376 | //* Returns: *
|
---|
377 | //* 0 - Success *
|
---|
378 | //* 1 - DevIOCtl failed *
|
---|
379 | //* 2 - Semaphore access failure *
|
---|
380 | //* 3 - SCSI command failed *
|
---|
381 | //* *
|
---|
382 | //* Preconditions: init() has to be called successfully before *
|
---|
383 | //* *
|
---|
384 | //***************************************************************************
|
---|
385 | ULONG scsiObj::resetDevice(UCHAR ha_num,UCHAR id, UCHAR lun)
|
---|
386 | {
|
---|
387 | ULONG rc; // return value
|
---|
388 | unsigned long cbreturn;
|
---|
389 | unsigned long cbParam;
|
---|
390 | BOOL success;
|
---|
391 |
|
---|
392 | SRBlock.cmd=SRB_Reset; // reset device
|
---|
393 | SRBlock.ha_num=ha_num; // host adapter number
|
---|
394 | SRBlock.flags=SRB_Post; // posting enabled
|
---|
395 | SRBlock.u.res.target=id; // target id
|
---|
396 | SRBlock.u.res.lun=lun; // target LUN
|
---|
397 |
|
---|
398 | rc = DosDevIOCtl(driver_handle, 0x92, 0x02, (void*) &SRBlock, sizeof(SRBOS2), &cbParam,
|
---|
399 | (void*) &SRBlock, sizeof(SRBOS2), &cbreturn);
|
---|
400 | if (rc)
|
---|
401 | return 1; // DosDevIOCtl failed
|
---|
402 | else
|
---|
403 | {
|
---|
404 | success=waitPost(); // wait for SRB being processed
|
---|
405 | if (!success) return 2; // semaphore could not be accessed
|
---|
406 | }
|
---|
407 | if (SRBlock.status != SRB_Done) return 3;
|
---|
408 | return 0;
|
---|
409 | }
|
---|
410 |
|
---|
411 |
|
---|
412 | //***************************************************************************
|
---|
413 | //* *
|
---|
414 | //* ULONG abort() *
|
---|
415 | //* *
|
---|
416 | //* Sends a SRB containing a Get Device Type command *
|
---|
417 | //* Returns: *
|
---|
418 | //* 0 - Success *
|
---|
419 | //* 1 - DevIOCtl failed *
|
---|
420 | //* 2 - Abort SRB not successful *
|
---|
421 | //* *
|
---|
422 | //* Preconditions: driver has to be opened *
|
---|
423 | //* *
|
---|
424 | //***************************************************************************
|
---|
425 | ULONG scsiObj::abort()
|
---|
426 | {
|
---|
427 | ULONG rc; // return value
|
---|
428 | unsigned long cbreturn;
|
---|
429 | unsigned long cbParam;
|
---|
430 |
|
---|
431 | AbortSRB.cmd=SRBOS2_Abort; // abort SRB
|
---|
432 | AbortSRB.ha_num=0; // host adapter number
|
---|
433 | AbortSRB.flags=0; // no flags set
|
---|
434 | AbortSRB.u.abt.srb=&SRBlock; // SRB to abort
|
---|
435 |
|
---|
436 | rc = DosDevIOCtl(driver_handle, 0x92, 0x02, (void*) &AbortSRB, sizeof(SRBOS2), &cbParam,
|
---|
437 | (void*) &AbortSRB, sizeof(SRBOS2), &cbreturn);
|
---|
438 | if (rc)
|
---|
439 | return 1; // DosDevIOCtl failed
|
---|
440 | if (SRBlock.status != SRB_Done) return 2;
|
---|
441 | return 0;
|
---|
442 | }
|
---|
443 | //***************************************************************************
|
---|
444 | //***************************************************************************
|
---|
445 | ULONG scsiObj::getNumHosts()
|
---|
446 | { int i,j=0;
|
---|
447 | ULONG rc;
|
---|
448 |
|
---|
449 | for (i=0;i<15;i++)
|
---|
450 | {
|
---|
451 | rc=HA_inquiry(i);
|
---|
452 | if (rc==0) j++;
|
---|
453 | }
|
---|
454 | return j;
|
---|
455 | }
|
---|
456 | //***************************************************************************
|
---|
457 | //***************************************************************************
|
---|
458 | ULONG scsiObj::SendSRBlock(VOID)
|
---|
459 | {
|
---|
460 | ULONG ulParam, ulReturn;
|
---|
461 |
|
---|
462 | return DosDevIOCtl( (HFILE) driver_handle,
|
---|
463 | 0x92,
|
---|
464 | 0x02,
|
---|
465 | (void*) &SRBlock,
|
---|
466 | sizeof(SRBOS2),
|
---|
467 | &ulParam,
|
---|
468 | (void*) &SRBlock,
|
---|
469 | sizeof(SRBOS2),
|
---|
470 | &ulReturn);
|
---|
471 | }
|
---|
472 | //***************************************************************************
|
---|
473 | //***************************************************************************
|
---|
474 | BOOL scsiObj::access(BOOL fWait)
|
---|
475 | {
|
---|
476 | APIRET rc;
|
---|
477 |
|
---|
478 | if(!fWait) {
|
---|
479 | rc = DosRequestMutexSem((HMTX) hmtxDriver, SEM_INDEFINITE_WAIT);
|
---|
480 | }
|
---|
481 | else rc = DosRequestMutexSem((HMTX) hmtxDriver, 100);
|
---|
482 |
|
---|
483 | if(rc != NO_ERROR) {
|
---|
484 | dprintf(("scsiObj::access: DosRequestMutexSem failed with rc = %d", rc));
|
---|
485 | return FALSE;
|
---|
486 | }
|
---|
487 | return TRUE;
|
---|
488 | }
|
---|
489 | //***************************************************************************
|
---|
490 | //***************************************************************************
|
---|
491 | BOOL scsiObj::release()
|
---|
492 | {
|
---|
493 | APIRET rc;
|
---|
494 |
|
---|
495 | rc = DosReleaseMutexSem((HMTX)hmtxDriver);
|
---|
496 | if(rc != NO_ERROR) {
|
---|
497 | dprintf(("scsiObj::access: DosReleaseMutexSem failed with rc = %d", rc));
|
---|
498 | return FALSE;
|
---|
499 | }
|
---|
500 |
|
---|
501 | return TRUE;
|
---|
502 | }
|
---|
503 | //***************************************************************************
|
---|
504 | //***************************************************************************
|
---|