source: trunk/src/wnaspi32/winaspi32.cpp@ 3541

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

PD:Implemented working ASPI

File size: 11.9 KB
Line 
1#include <os2win.h>
2#include <stdlib.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <errno.h>
6#include <fcntl.h>
7#include <memory.h>
8// #include <unistd.h>
9
10#include "aspi.h"
11#include "wnaspi32.h"
12#include <winreg.h>
13#include "options.h"
14#include "debugtools.h"
15
16//#include "srbos2.h"
17//#include "odinaspi.h"
18#include "aspilib.h"
19//#include "callback.h"
20
21DEFAULT_DEBUG_CHANNEL(aspi)
22
23static void
24ASPI_DebugPrintCmd(SRB_ExecSCSICmd *prb)
25{
26 BYTE cmd;
27 int i;
28 BYTE *cdb;
29
30 switch (prb->CDBByte[0]) {
31 case CMD_INQUIRY:
32 TRACE("{\n");
33 TRACE("\tEVPD: %d\n", prb->CDBByte[1] & 1);
34 TRACE("\tLUN: %d\n", (prb->CDBByte[1] & 0xc) >> 1);
35 TRACE("\tPAGE CODE: %d\n", prb->CDBByte[2]);
36 TRACE("\tALLOCATION LENGTH: %d\n", prb->CDBByte[4]);
37 TRACE("\tCONTROL: %d\n", prb->CDBByte[5]);
38 TRACE("}\n");
39 break;
40 case CMD_SCAN_SCAN:
41 TRACE("Transfer Length: %d\n", prb->CDBByte[4]);
42 break;
43 }
44
45 TRACE("Host Adapter: %d\n", prb->SRB_HaId);
46 TRACE("Flags: %d\n", prb->SRB_Flags);
47 if (TARGET_TO_HOST(prb)) {
48 TRACE("\tData transfer: Target to host. Length checked.\n");
49 }
50 else if (HOST_TO_TARGET(prb)) {
51 TRACE("\tData transfer: Host to target. Length checked.\n");
52 }
53 else if (NO_DATA_TRANSFERED(prb)) {
54 TRACE("\tData transfer: none\n");
55 }
56 else {
57 WARN("\tTransfer by scsi cmd. Length not checked.\n");
58 }
59
60 TRACE("\tResidual byte length reporting %s\n", prb->SRB_Flags & 0x4 ? "enabled" : "disabled");
61 TRACE("\tLinking %s\n", prb->SRB_Flags & 0x2 ? "enabled" : "disabled");
62 TRACE("\tPosting %s\n", prb->SRB_Flags & 0x1 ? "enabled" : "disabled");
63 TRACE("Target: %d\n", prb->SRB_Target);
64 TRACE("Lun: %d\n", prb->SRB_Lun);
65 TRACE("BufLen: %ld\n", prb->SRB_BufLen);
66 TRACE("SenseLen: %d\n", prb->SRB_SenseLen);
67 TRACE("BufPtr: %p\n", prb->SRB_BufPointer);
68 TRACE("CDB Length: %d\n", prb->SRB_CDBLen);
69 TRACE("POST Proc: %lx\n", (DWORD) prb->SRB_PostProc);
70 cdb = &prb->CDBByte[0];
71 cmd = prb->CDBByte[0];
72 if (TRACE_ON(aspi))
73 {
74 DPRINTF("CDB buffer[");
75 for (i = 0; i < prb->SRB_CDBLen; i++) {
76 if (i != 0) DPRINTF(",");
77 DPRINTF("%02x", *cdb++);
78 }
79 DPRINTF("]\n");
80 }
81}
82
83static void
84ASPI_PrintSenseArea(SRB_ExecSCSICmd *prb)
85{
86 int i;
87 BYTE *cdb;
88
89 if (TRACE_ON(aspi))
90 {
91 cdb = &prb->CDBByte[0];
92 DPRINTF("SenseArea[");
93 for (i = 0; i < prb->SRB_SenseLen; i++) {
94 if (i) DPRINTF(",");
95 DPRINTF("%02x", *cdb++);
96 }
97 DPRINTF("]\n");
98 }
99}
100
101static void
102ASPI_DebugPrintResult(SRB_ExecSCSICmd *prb)
103{
104
105 switch (prb->CDBByte[0]) {
106 case CMD_INQUIRY:
107 TRACE("Vendor: '%s'\n", prb->SRB_BufPointer + INQUIRY_VENDOR);
108 break;
109 case CMD_TEST_UNIT_READY:
110 ASPI_PrintSenseArea(prb);
111 break;
112 }
113}
114
115
116static WORD
117ASPI_ExecScsiCmd( scsiObj *aspi,
118 SRB_ExecSCSICmd *lpPRB)
119{
120 int status;
121 int error_code = 0;
122 LONG rc;
123
124 ASPI_DebugPrintCmd(lpPRB);
125
126 lpPRB->SRB_Status = SS_PENDING;
127
128 if (!lpPRB->SRB_CDBLen)
129 {
130 WARN("Failed: lpPRB->SRB_CDBLen = 0.\n");
131 lpPRB->SRB_Status = SS_ERR;
132 return SS_ERR;
133 }
134
135 if(MaxCDBStatus<lpPRB->SRB_CDBLen)
136 {
137 WARN("Failed: lpPRB->SRB_CDBLen > 64.\n");
138 lpPRB->SRB_Status = SS_ERR;
139 return SS_ERR;
140 }
141
142 if(lpPRB->SRB_BufLen>65536) // Check Max 64k!!
143 {
144 WARN("Failed: lpPRB->SRB_BufLen > 65536.\n");
145 lpPRB->SRB_Status = SS_BUFFER_TO_BIG;
146 return SS_BUFFER_TO_BIG;
147 }
148
149 // copy up to LUN SRBOS2 has no WORD for padding like in WINE
150 memcpy( &aspi->SRBlock,
151 lpPRB,
152 6* sizeof(BYTE) + sizeof(DWORD));
153 aspi->SRBlock.flags |= SRB_Post;
154 aspi->SRBlock.u.cmd.sense_len = 32; // length of sense buffer
155 aspi->SRBlock.u.cmd.data_ptr = NULL; // pointer to data buffer
156 aspi->SRBlock.u.cmd.link_ptr = NULL; // pointer to next SRB
157 aspi->SRBlock.u.cmd.cdb_len = lpPRB->SRB_CDBLen; // SCSI command length
158 memcpy( &aspi->SRBlock.u.cmd.cdb_st[0],
159 &lpPRB->CDBByte[0],
160 lpPRB->SRB_CDBLen);
161
162 if (HOST_TO_TARGET(lpPRB))
163 {
164 // Write: Copy all Data to Communication Buffer
165 if (lpPRB->SRB_BufLen)
166 {
167 memcpy( aspi->buffer,
168 lpPRB->SRB_BufPointer,
169 lpPRB->SRB_BufLen);
170 }
171 }
172
173 rc = aspi->SendSRBlock();
174
175 if(!rc)
176 {
177 if( aspi->waitPost())
178 {
179 if (TARGET_TO_HOST(lpPRB))
180 {
181 // Was Read : Copy all Data from Communication Buffer
182 if (lpPRB->SRB_BufLen)
183 {
184 memcpy( lpPRB->SRB_BufPointer,
185 aspi->buffer,
186 lpPRB->SRB_BufLen);
187 }
188 }
189
190 if (lpPRB->SRB_SenseLen)
191 {
192 int sense_len = lpPRB->SRB_SenseLen;
193 if (lpPRB->SRB_SenseLen > 32)
194 sense_len = 32;
195 memcpy( SENSE_BUFFER(lpPRB),
196 &aspi->SRBlock.u.cmd.cdb_st[aspi->SRBlock.u.cmd.cdb_len],
197 sense_len);
198 }
199
200 /* now do posting */
201
202 if (lpPRB->SRB_PostProc)
203 {
204 if (ASPI_POSTING(lpPRB))
205 {
206 TRACE("Post Routine (%lx) called\n", (DWORD) lpPRB->SRB_PostProc);
207 (*lpPRB->SRB_PostProc)();
208 }
209 else
210 if (lpPRB->SRB_Flags & SRB_EVENT_NOTIFY)
211 {
212 TRACE("Setting event %04x\n", (HANDLE)lpPRB->SRB_PostProc);
213 SetEvent((HANDLE)lpPRB->SRB_PostProc); /* FIXME: correct ? */
214 }
215 }
216 }
217 lpPRB->SRB_Status = aspi->SRBlock.status;
218 lpPRB->SRB_HaStat = aspi->SRBlock.u.cmd.ha_status;
219 lpPRB->SRB_TargStat = aspi->SRBlock.u.cmd.target_status;
220 }
221 else
222 lpPRB->SRB_Status = SS_ERR;
223
224
225 ASPI_DebugPrintResult(lpPRB);
226
227 return lpPRB->SRB_Status;
228
229}
230
231/*******************************************************************
232 * GetASPI32SupportInfo32 [WNASPI32.0]
233 *
234 * Checks if the ASPI subsystem is initialized correctly.
235 *
236 * RETURNS
237 * HIWORD: 0.
238 * HIBYTE of LOWORD: status (SS_COMP or SS_FAILED_INIT)
239 * LOBYTE of LOWORD: # of host adapters.
240 */
241DWORD WINAPI GetASPI32SupportInfo()
242{
243 LONG rc;
244 scsiObj *aspi;
245 ULONG hmtxDriver;
246 BYTE bNumDrv;
247 HKEY hkeyDrvInfo;
248 DWORD dwType;
249 DWORD dwData;
250 DWORD dwSize;
251 ULONG ulParam, ulReturn;
252 BYTE brc;
253
254 bNumDrv = 0;
255
256 aspi= new scsiObj();
257
258 if( fGainDrvAccess( FALSE, &hmtxDriver) ) // Do nonblocking call for info
259 {
260
261 if(aspi->init(65535)==TRUE)
262 {
263
264 bNumDrv = aspi->getNumHosts();
265 brc = SS_COMP;
266 rc = RegOpenKeyA ( HKEY_LOCAL_MACHINE,
267 "Software\\ODIN\\ASPIROUT",
268 &hkeyDrvInfo);
269 if(ERROR_SUCCESS==rc)
270 {
271 dwData = bNumDrv;
272 RegSetValueExA( hkeyDrvInfo,
273 "NumAdapers",
274 NULL,
275 REG_DWORD,
276 (LPBYTE)&dwData,
277 sizeof(DWORD));
278 RegCloseKey( hkeyDrvInfo);
279 }
280
281 aspi->close();
282 delete aspi;
283 }
284 else
285 brc = SS_FAILED_INIT;
286
287 fReleaseDrvAccess( hmtxDriver);
288 }
289 else
290 {
291 // Driver is used by other process/thread
292 // so try get value form registry
293
294 brc = SS_FAILED_INIT;
295 rc = RegOpenKeyA ( HKEY_LOCAL_MACHINE,
296 "Software\\ODIN\\ASPIROUT",
297 &hkeyDrvInfo);
298
299 if(ERROR_SUCCESS!=rc)
300 return ((SS_FAILED_INIT << 8) | bNumDrv);
301
302 dwSize = sizeof(DWORD);
303 rc = RegQueryValueExA( hkeyDrvInfo,
304 "NumAdapers",
305 NULL,
306 &dwType,
307 (BYTE*)&dwData,
308 &dwSize);
309
310 RegCloseKey( hkeyDrvInfo);
311
312 if( (ERROR_SUCCESS==rc) &&
313 (REG_DWORD != dwType) )
314 {
315 bNumDrv = 0xFF & dwData;
316 brc = SS_COMP;
317 }
318 }
319
320 return ((brc << 8) | bNumDrv); /* FIXME: get # of host adapters installed */
321}
322
323/***********************************************************************
324 * SendASPI32Command32 (WNASPI32.1)
325 */
326DWORD __cdecl SendASPI32Command(LPSRB lpSRB)
327{
328 DWORD dwRC;
329 ULONG ulParam, ulReturn;
330 BYTE bRC;
331 scsiObj *aspi;
332 ULONG hmtxDriver;
333 LONG rc;
334
335 if(NULL==lpSRB)
336 return SS_INVALID_SRB; // Not sure what to return here but that is an error
337
338 aspi = new scsiObj();
339
340 // test first for a valid command
341 if( (SC_HA_INQUIRY!=lpSRB->common.SRB_Cmd) &&
342 (SC_GET_DEV_TYPE!=lpSRB->common.SRB_Cmd) &&
343 (SC_EXEC_SCSI_CMD!=lpSRB->common.SRB_Cmd) &&
344 (SC_ABORT_SRB!=lpSRB->common.SRB_Cmd) &&
345 (SC_RESET_DEV!=lpSRB->common.SRB_Cmd) )
346 return SS_INVALID_SRB; // shoud be invalid command
347
348 dwRC = SS_ERR;
349
350 if( fGainDrvAccess( TRUE, &hmtxDriver) ) // Block if a SRB is pending
351 {
352 if(aspi->init(65535)==TRUE)
353 {
354 switch (lpSRB->common.SRB_Cmd)
355 {
356 case SC_HA_INQUIRY:
357 aspi->SRBlock.cmd=SRB_Inquiry; // host adapter inquiry
358 aspi->SRBlock.ha_num=lpSRB->inquiry.SRB_HaId; // host adapter number
359 aspi->SRBlock.flags=0; // no flags set
360 rc = aspi->SendSRBlock();
361
362 if (!rc)
363 {
364 memcpy( lpSRB,
365 &aspi->SRBlock,
366 sizeof(SRB_HaInquiry) );
367 dwRC = aspi->SRBlock.status;
368 }
369 break;
370
371 case SC_GET_DEV_TYPE:
372 memcpy( &aspi->SRBlock,
373 lpSRB,
374 sizeof(SRB_GDEVBlock));
375 aspi->SRBlock.flags = 0;
376
377 rc = aspi->SendSRBlock();
378
379 if (!rc)
380 {
381 memcpy( lpSRB,
382 &aspi->SRBlock,
383 sizeof(SRB_GDEVBlock) );
384
385 lpSRB->devtype.SRB_Rsvd1 = 0x00;
386 dwRC = aspi->SRBlock.status;
387 }
388
389 break;
390 case SC_EXEC_SCSI_CMD:
391 dwRC = ASPI_ExecScsiCmd( aspi,
392 &lpSRB->cmd);
393 break;
394
395 case SC_ABORT_SRB:
396 dwRC = SS_INVALID_SRB; // We don't do async ASPI so no way to abort
397 break;
398
399 case SC_RESET_DEV:
400 memset( &aspi->SRBlock,
401 0,
402 sizeof(SRBOS2) );
403 aspi->SRBlock.cmd = lpSRB->reset.SRB_Cmd; /* ASPI command code = SC_RESET_DEV */
404 aspi->SRBlock.status = lpSRB->reset.SRB_Status; /* ASPI command status byte */
405 aspi->SRBlock.ha_num = lpSRB->reset.SRB_HaId; /* ASPI host adapter number */
406 aspi->SRBlock.flags = SRB_Post;
407 aspi->SRBlock.u.res.target = lpSRB->reset.SRB_Target; /* Target's SCSI ID */
408 aspi->SRBlock.u.res.lun = lpSRB->reset.SRB_Lun; /* Target's LUN number */
409
410 rc = aspi->SendSRBlock();
411
412 if (!rc)
413 {
414 aspi->waitPost();
415 lpSRB->reset.SRB_Status = aspi->SRBlock.status;
416 lpSRB->reset.SRB_Flags = aspi->SRBlock.flags;
417 lpSRB->reset.SRB_Hdr_Rsvd = 0;
418 memset( lpSRB->reset.SRB_Rsvd1,
419 0,
420 12 );
421 lpSRB->reset.SRB_HaStat = aspi->SRBlock.u.res.ha_status; /* Host Adapter Status */
422 lpSRB->reset.SRB_TargStat = aspi->SRBlock.u.res.target_status; /* Target Status */
423 lpSRB->reset.SRB_PostProc = NULL; /* Post routine */
424 lpSRB->reset.SRB_Rsvd2 = NULL; /* Reserved */
425 memset( lpSRB->reset.SRB_Rsvd3,
426 0,
427 32); /* Reserved */
428 dwRC = aspi->SRBlock.status;
429 }
430 break;
431 } // end switch (lpSRB->common.SRB_Cmd)
432
433 aspi->close();
434 delete aspi;
435 }
436 else
437 {
438 dwRC = bRC;
439 }
440
441 fReleaseDrvAccess( hmtxDriver);
442 }
443 else
444 {
445 dwRC = SS_NO_ASPI;
446 }
447
448 return dwRC;
449}
450
451
452/***********************************************************************
453 * GetASPI32DLLVersion32 (WNASPI32.3)
454 */
455DWORD WINAPI GetASPI32DLLVersion()
456{
457 return (DWORD)1;
458}
459
Note: See TracBrowser for help on using the repository browser.