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

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

open + init aspirout during dll load

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