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