source: trunk/src/wnaspi32/aspilib.cpp@ 5120

Last change on this file since 5120 was 4977, checked in by sandervl, 25 years ago

PD: init bugfix

File size: 22.9 KB
Line 
1/* $Id: aspilib.cpp,v 1.7 2001-01-19 23:04:26 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//***************************************************************************
34scsiObj::scsiObj() : buffer(NULL), hmtxDriver(0), postSema(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//***************************************************************************
48scsiObj::~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//***************************************************************************
65BOOL 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//***************************************************************************
95BOOL 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//***************************************************************************
117BOOL 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//***************************************************************************
150BOOL 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//***************************************************************************
173BOOL 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//***************************************************************************
204BOOL scsiObj::init(ULONG bufsize)
205{
206 BOOL success;
207 APIRET rc;
208
209
210 rc = DosCreateMutexSem(WNASPI32_MUTEX_NAME, (HMTX*)&hmtxDriver,
211 0, FALSE);
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//***************************************************************************
246BOOL 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//***************************************************************************
293BOOL 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//***************************************************************************
318ULONG 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//***************************************************************************
350ULONG 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//***************************************************************************
385ULONG 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//***************************************************************************
425ULONG 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//***************************************************************************
445ULONG 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//***************************************************************************
458ULONG 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//***************************************************************************
474BOOL 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//***************************************************************************
491BOOL 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//***************************************************************************
Note: See TracBrowser for help on using the repository browser.