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

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

added logging

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