Patrik Stridvall | 9633632 | 1999-10-24 22:13:47 +0000 | [diff] [blame] | 1 | #include "config.h" |
| 2 | |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 3 | #include <assert.h> |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 4 | #include <stdlib.h> |
Alexandre Julliard | 383da68 | 2000-02-10 22:15:21 +0000 | [diff] [blame] | 5 | #include <stdio.h> |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 6 | #include <sys/types.h> |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 7 | #include <errno.h> |
| 8 | #include <fcntl.h> |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 9 | #include <memory.h> |
| 10 | #include <unistd.h> |
Marcus Meissner | 317af32 | 1999-02-17 13:51:06 +0000 | [diff] [blame] | 11 | |
| 12 | #include "winbase.h" |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 13 | #include "aspi.h" |
| 14 | #include "wnaspi32.h" |
David Elliott | c3bcd6c | 2000-03-08 19:41:49 +0000 | [diff] [blame] | 15 | #include "winescsi.h" |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 16 | #include "debugtools.h" |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 17 | |
Alexandre Julliard | 383da68 | 2000-02-10 22:15:21 +0000 | [diff] [blame] | 18 | DEFAULT_DEBUG_CHANNEL(aspi); |
Patrik Stridvall | b4b9fae | 1999-04-19 14:56:29 +0000 | [diff] [blame] | 19 | |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 20 | /* FIXME! |
| 21 | * 1) Residual byte length reporting not handled |
| 22 | * 2) Make this code re-entrant for multithreading |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 23 | * -- Added CriticalSection to OpenDevices function |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 24 | * 3) Only linux supported so far |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 25 | * 4) Leaves sg devices open. This may or may not be okay. A better solution |
| 26 | * would be to close the file descriptors when the thread/process using |
| 27 | * them no longer needs them. |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 28 | */ |
| 29 | |
| 30 | #ifdef linux |
Patrik Stridvall | 1ed4ecf | 1999-06-26 14:58:24 +0000 | [diff] [blame] | 31 | |
| 32 | static ASPI_DEVICE_INFO *ASPI_open_devices = NULL; |
Alexandre Julliard | 301df6b | 2001-08-16 18:12:56 +0000 | [diff] [blame] | 33 | static CRITICAL_SECTION ASPI_CritSection = CRITICAL_SECTION_INIT("ASPI_CritSection"); |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 34 | |
Patrik Stridvall | 7b0a088 | 2000-01-09 21:42:42 +0000 | [diff] [blame] | 35 | #endif /* defined(linux) */ |
| 36 | |
| 37 | |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 38 | BOOL WINAPI WNASPI32_LibMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad) |
| 39 | { |
Patrik Stridvall | 7b0a088 | 2000-01-09 21:42:42 +0000 | [diff] [blame] | 40 | #ifdef linux |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 41 | switch( fdwReason ) |
| 42 | { |
| 43 | case DLL_PROCESS_ATTACH: |
Alexandre Julliard | 0618746 | 2001-01-17 22:03:18 +0000 | [diff] [blame] | 44 | SCSI_Init(); |
| 45 | break; |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 46 | case DLL_PROCESS_DETACH: |
Alexandre Julliard | 0618746 | 2001-01-17 22:03:18 +0000 | [diff] [blame] | 47 | DeleteCriticalSection( &ASPI_CritSection ); |
| 48 | break; |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 49 | case DLL_THREAD_ATTACH: |
| 50 | case DLL_THREAD_DETACH: |
| 51 | break; |
| 52 | } |
Patrik Stridvall | 7b0a088 | 2000-01-09 21:42:42 +0000 | [diff] [blame] | 53 | #endif /* defined(linux) */ |
Alexandre Julliard | 0618746 | 2001-01-17 22:03:18 +0000 | [diff] [blame] | 54 | return TRUE; |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 55 | } |
Patrik Stridvall | 1ed4ecf | 1999-06-26 14:58:24 +0000 | [diff] [blame] | 56 | |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 57 | |
Patrik Stridvall | 7b0a088 | 2000-01-09 21:42:42 +0000 | [diff] [blame] | 58 | #ifdef linux |
| 59 | |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 60 | static int |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 61 | ASPI_OpenDevice(SRB_ExecSCSICmd *prb) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 62 | { |
| 63 | int fd; |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 64 | DWORD hc; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 65 | ASPI_DEVICE_INFO *curr; |
| 66 | |
| 67 | /* search list of devices to see if we've opened it already. |
| 68 | * There is not an explicit open/close in ASPI land, so hopefully |
| 69 | * keeping a device open won't be a problem. |
| 70 | */ |
| 71 | |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 72 | EnterCriticalSection(&ASPI_CritSection); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 73 | for (curr = ASPI_open_devices; curr; curr = curr->next) { |
| 74 | if (curr->hostId == prb->SRB_HaId && |
| 75 | curr->target == prb->SRB_Target && |
| 76 | curr->lun == prb->SRB_Lun) { |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 77 | LeaveCriticalSection(&ASPI_CritSection); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 78 | return curr->fd; |
| 79 | } |
| 80 | } |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 81 | LeaveCriticalSection(&ASPI_CritSection); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 82 | |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 83 | if (prb->SRB_HaId > ASPI_GetNumControllers()) |
| 84 | return -1; |
| 85 | |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 86 | hc = ASPI_GetHCforController( prb->SRB_HaId ); |
| 87 | fd = SCSI_OpenDevice( HIWORD(hc), LOWORD(hc), prb->SRB_Target, prb->SRB_Lun); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 88 | |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 89 | if (fd == -1) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 90 | return -1; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 91 | |
| 92 | /* device is now open */ |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 93 | /* FIXME: Let users specify SCSI timeout in registry */ |
| 94 | SCSI_LinuxSetTimeout( fd, SCSI_DEFAULT_TIMEOUT ); |
Patrik Stridvall | 3c0211f | 2001-09-11 00:32:32 +0000 | [diff] [blame] | 95 | |
Alexandre Julliard | 90476d6 | 2000-02-16 22:47:24 +0000 | [diff] [blame] | 96 | curr = HeapAlloc( GetProcessHeap(), 0, sizeof(ASPI_DEVICE_INFO) ); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 97 | curr->fd = fd; |
| 98 | curr->hostId = prb->SRB_HaId; |
| 99 | curr->target = prb->SRB_Target; |
| 100 | curr->lun = prb->SRB_Lun; |
| 101 | |
| 102 | /* insert new record at beginning of open device list */ |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 103 | EnterCriticalSection(&ASPI_CritSection); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 104 | curr->next = ASPI_open_devices; |
| 105 | ASPI_open_devices = curr; |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 106 | LeaveCriticalSection(&ASPI_CritSection); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 107 | return fd; |
| 108 | } |
| 109 | |
| 110 | |
| 111 | static void |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 112 | ASPI_DebugPrintCmd(SRB_ExecSCSICmd *prb) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 113 | { |
| 114 | BYTE cmd; |
| 115 | int i; |
| 116 | BYTE *cdb; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 117 | |
| 118 | switch (prb->CDBByte[0]) { |
| 119 | case CMD_INQUIRY: |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 120 | TRACE("INQUIRY {\n"); |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 121 | TRACE("\tEVPD: %d\n", prb->CDBByte[1] & 1); |
| 122 | TRACE("\tLUN: %d\n", (prb->CDBByte[1] & 0xc) >> 1); |
| 123 | TRACE("\tPAGE CODE: %d\n", prb->CDBByte[2]); |
| 124 | TRACE("\tALLOCATION LENGTH: %d\n", prb->CDBByte[4]); |
| 125 | TRACE("\tCONTROL: %d\n", prb->CDBByte[5]); |
| 126 | TRACE("}\n"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 127 | break; |
| 128 | case CMD_SCAN_SCAN: |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 129 | TRACE("Transfer Length: %d\n", prb->CDBByte[4]); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 130 | break; |
| 131 | } |
| 132 | |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 133 | TRACE("Host Adapter: %d\n", prb->SRB_HaId); |
| 134 | TRACE("Flags: %d\n", prb->SRB_Flags); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 135 | if (TARGET_TO_HOST(prb)) { |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 136 | TRACE("\tData transfer: Target to host. Length checked.\n"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 137 | } |
| 138 | else if (HOST_TO_TARGET(prb)) { |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 139 | TRACE("\tData transfer: Host to target. Length checked.\n"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 140 | } |
| 141 | else if (NO_DATA_TRANSFERED(prb)) { |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 142 | TRACE("\tData transfer: none\n"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 143 | } |
| 144 | else { |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 145 | WARN("\tTransfer by scsi cmd. Length not checked.\n"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 146 | } |
| 147 | |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 148 | TRACE("\tResidual byte length reporting %s\n", prb->SRB_Flags & 0x4 ? "enabled" : "disabled"); |
| 149 | TRACE("\tLinking %s\n", prb->SRB_Flags & 0x2 ? "enabled" : "disabled"); |
| 150 | TRACE("\tPosting %s\n", prb->SRB_Flags & 0x1 ? "enabled" : "disabled"); |
| 151 | TRACE("Target: %d\n", prb->SRB_Target); |
| 152 | TRACE("Lun: %d\n", prb->SRB_Lun); |
| 153 | TRACE("BufLen: %ld\n", prb->SRB_BufLen); |
| 154 | TRACE("SenseLen: %d\n", prb->SRB_SenseLen); |
| 155 | TRACE("BufPtr: %p\n", prb->SRB_BufPointer); |
| 156 | TRACE("CDB Length: %d\n", prb->SRB_CDBLen); |
| 157 | TRACE("POST Proc: %lx\n", (DWORD) prb->SRB_PostProc); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 158 | cdb = &prb->CDBByte[0]; |
| 159 | cmd = prb->CDBByte[0]; |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 160 | if (TRACE_ON(aspi)) { |
Alexandre Julliard | 15de615 | 1999-08-04 12:22:42 +0000 | [diff] [blame] | 161 | DPRINTF("CDB buffer["); |
| 162 | for (i = 0; i < prb->SRB_CDBLen; i++) { |
| 163 | if (i != 0) DPRINTF(","); |
| 164 | DPRINTF("%02x", *cdb++); |
| 165 | } |
| 166 | DPRINTF("]\n"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 167 | } |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 168 | } |
| 169 | |
| 170 | static void |
Andreas Mohr | 482122a | 2000-12-09 03:06:18 +0000 | [diff] [blame] | 171 | ASPI_PrintCDBArea(SRB_ExecSCSICmd *prb) |
| 172 | { |
| 173 | if (TRACE_ON(aspi)) |
| 174 | { |
| 175 | int i; |
| 176 | DPRINTF("CDB["); |
| 177 | for (i = 0; i < prb->SRB_CDBLen; i++) { |
| 178 | if (i) DPRINTF(","); |
| 179 | DPRINTF("%02x", prb->CDBByte[i]); |
| 180 | } |
| 181 | DPRINTF("]\n"); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | static void |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 186 | ASPI_PrintSenseArea(SRB_ExecSCSICmd *prb) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 187 | { |
| 188 | int i; |
Alexandre Julliard | ab170a9 | 2000-09-27 00:25:24 +0000 | [diff] [blame] | 189 | BYTE *rqbuf = prb->SenseArea; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 190 | |
Alexandre Julliard | 15de615 | 1999-08-04 12:22:42 +0000 | [diff] [blame] | 191 | if (TRACE_ON(aspi)) |
| 192 | { |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 193 | DPRINTF("Request Sense reports:\n"); |
| 194 | if ((rqbuf[0]&0x7f)!=0x70) { |
Andreas Mohr | 4d47ec2 | 2000-09-06 19:42:19 +0000 | [diff] [blame] | 195 | DPRINTF("\tInvalid sense header: 0x%02x instead of 0x70\n", rqbuf[0]&0x7f); |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 196 | return; |
| 197 | } |
| 198 | DPRINTF("\tCurrent command read filemark: %s\n",(rqbuf[2]&0x80)?"yes":"no"); |
| 199 | DPRINTF("\tEarly warning passed: %s\n",(rqbuf[2]&0x40)?"yes":"no"); |
Andreas Mohr | 4d47ec2 | 2000-09-06 19:42:19 +0000 | [diff] [blame] | 200 | DPRINTF("\tIncorrect blocklength: %s\n",(rqbuf[2]&0x20)?"yes":"no"); |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 201 | DPRINTF("\tSense Key: %d\n",rqbuf[2]&0xf); |
| 202 | if (rqbuf[0]&0x80) |
| 203 | DPRINTF("\tResidual Length: %d\n",rqbuf[3]*0x1000000+rqbuf[4]*0x10000+rqbuf[5]*0x100+rqbuf[6]); |
| 204 | DPRINTF("\tAdditional Sense Length: %d\n",rqbuf[7]); |
| 205 | DPRINTF("\tAdditional Sense Code: %d\n",rqbuf[12]); |
| 206 | DPRINTF("\tAdditional Sense Code Qualifier: %d\n",rqbuf[13]); |
| 207 | if (rqbuf[15]&0x80) { |
| 208 | DPRINTF("\tIllegal Param is in %s\n",(rqbuf[15]&0x40)?"the CDB":"the Data Out Phase"); |
| 209 | if (rqbuf[15]&0x8) { |
| 210 | DPRINTF("Pointer at %d, bit %d\n",rqbuf[16]*256+rqbuf[17],rqbuf[15]&0x7); |
| 211 | } |
| 212 | } |
Alexandre Julliard | 15de615 | 1999-08-04 12:22:42 +0000 | [diff] [blame] | 213 | DPRINTF("SenseArea["); |
| 214 | for (i = 0; i < prb->SRB_SenseLen; i++) { |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 215 | if (i) DPRINTF(","); |
| 216 | DPRINTF("%02x", *rqbuf++); |
Alexandre Julliard | 15de615 | 1999-08-04 12:22:42 +0000 | [diff] [blame] | 217 | } |
| 218 | DPRINTF("]\n"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 219 | } |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 220 | } |
| 221 | |
| 222 | static void |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 223 | ASPI_DebugPrintResult(SRB_ExecSCSICmd *prb) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 224 | { |
| 225 | |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 226 | TRACE("SRB_Status: %x\n", prb->SRB_Status); |
| 227 | TRACE("SRB_HaStat: %x\n", prb->SRB_HaStat); |
| 228 | TRACE("SRB_TargStat: %x\n", prb->SRB_TargStat); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 229 | switch (prb->CDBByte[0]) { |
| 230 | case CMD_INQUIRY: |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 231 | TRACE("Vendor: '%s'\n", prb->SRB_BufPointer + INQUIRY_VENDOR); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 232 | break; |
| 233 | case CMD_TEST_UNIT_READY: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 234 | ASPI_PrintSenseArea(prb); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 235 | break; |
| 236 | } |
| 237 | } |
| 238 | |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 239 | /* Posting must be done in such a way that as soon as the SRB_Status is set |
| 240 | * we don't touch the SRB anymore because it could possibly be freed |
| 241 | * if the app is doing ASPI polling |
| 242 | */ |
| 243 | static DWORD |
| 244 | WNASPI32_DoPosting( SRB_ExecSCSICmd *lpPRB, DWORD status ) |
| 245 | { |
| 246 | void (*SRB_PostProc)() = lpPRB->SRB_PostProc; |
| 247 | BYTE SRB_Flags = lpPRB->SRB_Flags; |
| 248 | if( status == SS_PENDING ) |
| 249 | { |
| 250 | WARN("Tried posting SS_PENDING\n"); |
| 251 | return SS_PENDING; |
| 252 | } |
| 253 | lpPRB->SRB_Status = status; |
| 254 | /* lpPRB is NOT safe, it could be freed in another thread */ |
| 255 | |
| 256 | if (SRB_PostProc) |
| 257 | { |
| 258 | if (SRB_Flags & 0x1) |
| 259 | { |
| 260 | TRACE("Post Routine (%lx) called\n", (DWORD) SRB_PostProc); |
| 261 | /* Even though lpPRB could have been freed by |
| 262 | * the program.. that's unlikely if it planned |
| 263 | * to use it in the PostProc |
| 264 | */ |
| 265 | (*SRB_PostProc)(lpPRB); |
| 266 | } |
| 267 | else if (SRB_Flags & SRB_EVENT_NOTIFY) { |
| 268 | TRACE("Setting event %04x\n", (HANDLE)SRB_PostProc); |
| 269 | SetEvent((HANDLE)SRB_PostProc); |
| 270 | } |
| 271 | } |
| 272 | return SS_PENDING; |
| 273 | } |
| 274 | |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 275 | static WORD |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 276 | ASPI_ExecScsiCmd(SRB_ExecSCSICmd *lpPRB) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 277 | { |
| 278 | struct sg_header *sg_hd, *sg_reply_hdr; |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 279 | WORD ret; |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 280 | DWORD status; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 281 | int in_len, out_len; |
| 282 | int error_code = 0; |
| 283 | int fd; |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 284 | DWORD SRB_Status; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 285 | |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 286 | /* FIXME: hackmode */ |
| 287 | #define MAKE_TARGET_TO_HOST(lpPRB) \ |
| 288 | if (!TARGET_TO_HOST(lpPRB)) { \ |
| 289 | WARN("program was not sending target_to_host for cmd %x (flags=%x),correcting.\n",lpPRB->CDBByte[0],lpPRB->SRB_Flags); \ |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 290 | lpPRB->SRB_Flags |= 0x08; \ |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 291 | } |
| 292 | #define MAKE_HOST_TO_TARGET(lpPRB) \ |
| 293 | if (!HOST_TO_TARGET(lpPRB)) { \ |
| 294 | WARN("program was not sending host_to_target for cmd %x (flags=%x),correcting.\n",lpPRB->CDBByte[0],lpPRB->SRB_Flags); \ |
| 295 | lpPRB->SRB_Flags |= 0x10; \ |
| 296 | } |
| 297 | switch (lpPRB->CDBByte[0]) { |
| 298 | case 0x12: /* INQUIRY */ |
| 299 | case 0x5a: /* MODE_SENSE_10 */ |
| 300 | case 0xa4: /* REPORT_KEY (DVD) MMC-2 */ |
| 301 | case 0xad: /* READ DVD STRUCTURE MMC-2 */ |
| 302 | MAKE_TARGET_TO_HOST(lpPRB) |
| 303 | break; |
| 304 | case 0xa3: /* SEND KEY (DVD) MMC-2 */ |
| 305 | MAKE_HOST_TO_TARGET(lpPRB) |
| 306 | break; |
| 307 | default: |
| 308 | if ((((lpPRB->SRB_Flags & 0x18) == 0x00) || |
| 309 | ((lpPRB->SRB_Flags & 0x18) == 0x18) |
| 310 | ) && lpPRB->SRB_BufLen |
| 311 | ) { |
Patrik Stridvall | 3c0211f | 2001-09-11 00:32:32 +0000 | [diff] [blame] | 312 | FIXME("command 0x%02x, no data transfer specified, but buflen is %ld!!!\n",lpPRB->CDBByte[0],lpPRB->SRB_BufLen); |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 313 | } |
| 314 | break; |
| 315 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 316 | ASPI_DebugPrintCmd(lpPRB); |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 317 | if (lpPRB->SRB_HaId > ASPI_GetNumControllers()) { |
| 318 | ERR("Failed: Wanted hostadapter %d, but we have only %d.\n", |
| 319 | lpPRB->SRB_HaId,ASPI_GetNumControllers() |
| 320 | ); |
| 321 | return WNASPI32_DoPosting( lpPRB, SS_INVALID_HA ); |
| 322 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 323 | fd = ASPI_OpenDevice(lpPRB); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 324 | if (fd == -1) { |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 325 | return WNASPI32_DoPosting( lpPRB, SS_NO_DEVICE ); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 326 | } |
| 327 | |
| 328 | sg_hd = NULL; |
| 329 | sg_reply_hdr = NULL; |
| 330 | |
| 331 | lpPRB->SRB_Status = SS_PENDING; |
| 332 | |
| 333 | if (!lpPRB->SRB_CDBLen) { |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 334 | ERR("Failed: lpPRB->SRB_CDBLen = 0.\n"); |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 335 | return WNASPI32_DoPosting( lpPRB, SS_INVALID_SRB ); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 336 | } |
| 337 | |
| 338 | /* build up sg_header + scsi cmd */ |
| 339 | if (HOST_TO_TARGET(lpPRB)) { |
| 340 | /* send header, command, and then data */ |
| 341 | in_len = SCSI_OFF + lpPRB->SRB_CDBLen + lpPRB->SRB_BufLen; |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 342 | sg_hd = (struct sg_header *) HeapAlloc(GetProcessHeap(), 0, in_len); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 343 | memset(sg_hd, 0, SCSI_OFF); |
| 344 | memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen); |
| 345 | if (lpPRB->SRB_BufLen) { |
| 346 | memcpy(((BYTE *) sg_hd) + SCSI_OFF + lpPRB->SRB_CDBLen, lpPRB->SRB_BufPointer, lpPRB->SRB_BufLen); |
| 347 | } |
| 348 | } |
| 349 | else { |
| 350 | /* send header and command - no data */ |
| 351 | in_len = SCSI_OFF + lpPRB->SRB_CDBLen; |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 352 | sg_hd = (struct sg_header *) HeapAlloc(GetProcessHeap(), 0, in_len); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 353 | memset(sg_hd, 0, SCSI_OFF); |
| 354 | memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen); |
| 355 | } |
| 356 | |
| 357 | if (TARGET_TO_HOST(lpPRB)) { |
| 358 | out_len = SCSI_OFF + lpPRB->SRB_BufLen; |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 359 | sg_reply_hdr = (struct sg_header *) HeapAlloc(GetProcessHeap(), 0, out_len); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 360 | memset(sg_reply_hdr, 0, SCSI_OFF); |
| 361 | sg_hd->reply_len = out_len; |
| 362 | } |
| 363 | else { |
| 364 | out_len = SCSI_OFF; |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 365 | sg_reply_hdr = (struct sg_header *) HeapAlloc(GetProcessHeap(), 0, out_len); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 366 | memset(sg_reply_hdr, 0, SCSI_OFF); |
| 367 | sg_hd->reply_len = out_len; |
| 368 | } |
| 369 | |
David Elliott | 8466fc3 | 2000-07-15 15:15:31 +0000 | [diff] [blame] | 370 | SCSI_Fix_CMD_LEN(fd, lpPRB->CDBByte[0], lpPRB->SRB_CDBLen); |
| 371 | |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 372 | if(!SCSI_LinuxDeviceIo( fd, |
| 373 | sg_hd, in_len, |
| 374 | sg_reply_hdr, out_len, |
| 375 | &status) ) |
| 376 | { |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 377 | goto error_exit; |
| 378 | } |
| 379 | |
| 380 | if (sg_reply_hdr->result != 0) { |
| 381 | error_code = sg_reply_hdr->result; |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 382 | WARN("reply header error (%d)\n", sg_reply_hdr->result); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 383 | goto error_exit; |
| 384 | } |
| 385 | |
| 386 | if (TARGET_TO_HOST(lpPRB) && lpPRB->SRB_BufLen) { |
| 387 | memcpy(lpPRB->SRB_BufPointer, sg_reply_hdr + 1, lpPRB->SRB_BufLen); |
| 388 | } |
| 389 | |
| 390 | /* copy in sense buffer to amount that is available in client */ |
| 391 | if (lpPRB->SRB_SenseLen) { |
| 392 | int sense_len = lpPRB->SRB_SenseLen; |
| 393 | if (lpPRB->SRB_SenseLen > 16) |
| 394 | sense_len = 16; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 395 | |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 396 | /* CDB is fixed in WNASPI32 */ |
Alexandre Julliard | ab170a9 | 2000-09-27 00:25:24 +0000 | [diff] [blame] | 397 | memcpy(lpPRB->SenseArea, &sg_reply_hdr->sense_buffer[0], sense_len); |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 398 | |
Andreas Mohr | 482122a | 2000-12-09 03:06:18 +0000 | [diff] [blame] | 399 | ASPI_PrintCDBArea(lpPRB); |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 400 | ASPI_PrintSenseArea(lpPRB); |
| 401 | } |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 402 | |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 403 | SRB_Status = SS_COMP; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 404 | lpPRB->SRB_HaStat = HASTAT_OK; |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 405 | lpPRB->SRB_TargStat = sg_reply_hdr->target_status << 1; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 406 | |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 407 | HeapFree(GetProcessHeap(), 0, sg_reply_hdr); |
| 408 | HeapFree(GetProcessHeap(), 0, sg_hd); |
| 409 | |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 410 | /* FIXME: Should this be != 0 maybe? */ |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 411 | if( lpPRB->SRB_TargStat == 2 ) { |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 412 | SRB_Status = SS_ERR; |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 413 | switch (lpPRB->CDBByte[0]) { |
| 414 | case 0xa4: /* REPORT_KEY (DVD) MMC-2 */ |
| 415 | case 0xa3: /* SEND KEY (DVD) MMC-2 */ |
| 416 | SRB_Status = SS_COMP; |
| 417 | lpPRB->SRB_TargStat = 0; |
| 418 | FIXME("Program wants to do DVD Region switching, but fails (non compliant DVD drive). Ignoring....\n"); |
| 419 | break; |
| 420 | } |
| 421 | } |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 422 | |
| 423 | ASPI_DebugPrintResult(lpPRB); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 424 | /* now do posting */ |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 425 | ret = WNASPI32_DoPosting( lpPRB, SRB_Status ); |
| 426 | |
| 427 | switch (lpPRB->CDBByte[0]) { |
| 428 | case CMD_INQUIRY: |
| 429 | if (SRB_Status == SS_COMP) |
| 430 | return SS_COMP; /* some junk expects ss_comp here. */ |
| 431 | /*FALLTHROUGH*/ |
| 432 | default: |
Patrik Stridvall | 3c0211f | 2001-09-11 00:32:32 +0000 | [diff] [blame] | 433 | break; |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 434 | } |
| 435 | |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 436 | /* In real WNASPI32 stuff really is always pending because ASPI does things |
| 437 | in the background, but we are not doing that (yet) */ |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 438 | |
| 439 | return ret; |
Patrik Stridvall | 3c0211f | 2001-09-11 00:32:32 +0000 | [diff] [blame] | 440 | |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 441 | error_exit: |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 442 | SRB_Status = SS_ERR; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 443 | if (error_code == EBUSY) { |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 444 | WNASPI32_DoPosting( lpPRB, SS_ASPI_IS_BUSY ); |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 445 | TRACE("Device busy\n"); |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 446 | } else |
| 447 | FIXME("Failed\n"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 448 | |
| 449 | /* I'm not sure exactly error codes work here |
| 450 | * We probably should set lpPRB->SRB_TargStat, SRB_HaStat ? |
| 451 | */ |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 452 | WARN("error_exit\n"); |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 453 | HeapFree(GetProcessHeap(), 0, sg_reply_hdr); |
| 454 | HeapFree(GetProcessHeap(), 0, sg_hd); |
David Elliott | a555ceb | 2000-03-09 18:44:02 +0000 | [diff] [blame] | 455 | WNASPI32_DoPosting( lpPRB, SRB_Status ); |
| 456 | return SS_PENDING; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 457 | } |
Patrik Stridvall | 7b0a088 | 2000-01-09 21:42:42 +0000 | [diff] [blame] | 458 | |
| 459 | #endif /* defined(linux) */ |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 460 | |
| 461 | |
| 462 | /******************************************************************* |
Patrik Stridvall | 8b216b3 | 2001-06-19 18:20:47 +0000 | [diff] [blame] | 463 | * GetASPI32SupportInfo [WNASPI32.1] |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 464 | * |
| 465 | * Checks if the ASPI subsystem is initialized correctly. |
| 466 | * |
| 467 | * RETURNS |
| 468 | * HIWORD: 0. |
| 469 | * HIBYTE of LOWORD: status (SS_COMP or SS_FAILED_INIT) |
Patrik Stridvall | 3c0211f | 2001-09-11 00:32:32 +0000 | [diff] [blame] | 470 | * LOBYTE of LOWORD: # of host adapters. |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 471 | */ |
Patrik Stridvall | bf8943c | 2000-10-02 03:39:34 +0000 | [diff] [blame] | 472 | DWORD __cdecl GetASPI32SupportInfo(void) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 473 | { |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 474 | DWORD controllers = ASPI_GetNumControllers(); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 475 | |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 476 | if (!controllers) |
| 477 | return SS_NO_ADAPTERS << 8; |
| 478 | return (SS_COMP << 8) | controllers ; |
| 479 | } |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 480 | |
| 481 | /*********************************************************************** |
Patrik Stridvall | 8b216b3 | 2001-06-19 18:20:47 +0000 | [diff] [blame] | 482 | * SendASPI32Command (WNASPI32.2) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 483 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 484 | DWORD __cdecl SendASPI32Command(LPSRB lpSRB) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 485 | { |
| 486 | #ifdef linux |
| 487 | switch (lpSRB->common.SRB_Cmd) { |
| 488 | case SC_HA_INQUIRY: |
| 489 | lpSRB->inquiry.SRB_Status = SS_COMP; /* completed successfully */ |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 490 | lpSRB->inquiry.HA_Count = ASPI_GetNumControllers(); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 491 | lpSRB->inquiry.HA_SCSI_ID = 7; /* not always ID 7 */ |
David Elliott | 8466fc3 | 2000-07-15 15:15:31 +0000 | [diff] [blame] | 492 | strcpy(lpSRB->inquiry.HA_ManagerId, "ASPI for WIN32"); /* max 15 chars, don't change */ |
| 493 | strcpy(lpSRB->inquiry.HA_Identifier, "Wine host"); /* FIXME: return host adapter name */ |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 494 | memset(lpSRB->inquiry.HA_Unique, 0, 16); /* default HA_Unique content */ |
| 495 | lpSRB->inquiry.HA_Unique[6] = 0x02; /* Maximum Transfer Length (128K, Byte> 4-7) */ |
David Elliott | 8466fc3 | 2000-07-15 15:15:31 +0000 | [diff] [blame] | 496 | lpSRB->inquiry.HA_Unique[3] = 0x08; /* Maximum number of SCSI targets */ |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 497 | FIXME("ASPI: Partially implemented SC_HA_INQUIRY for adapter %d.\n", lpSRB->inquiry.SRB_HaId); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 498 | return SS_COMP; |
Marcus Meissner | 12085e9 | 2000-03-26 13:36:16 +0000 | [diff] [blame] | 499 | |
Marcus Meissner | eb71e50 | 1999-09-19 12:08:18 +0000 | [diff] [blame] | 500 | case SC_GET_DEV_TYPE: { |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 501 | /* FIXME: We should return SS_NO_DEVICE if the device is not configured */ |
| 502 | /* FIXME: We should return SS_INVALID_HA if HostAdapter!=0 */ |
Marcus Meissner | eb71e50 | 1999-09-19 12:08:18 +0000 | [diff] [blame] | 503 | SRB tmpsrb; |
| 504 | char inqbuf[200]; |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 505 | DWORD ret; |
Marcus Meissner | eb71e50 | 1999-09-19 12:08:18 +0000 | [diff] [blame] | 506 | |
| 507 | memset(&tmpsrb,0,sizeof(tmpsrb)); |
| 508 | |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 509 | /* Copy header */ |
| 510 | memcpy(&tmpsrb.common,&(lpSRB->common),sizeof(tmpsrb.common)); |
Patrik Stridvall | 3c0211f | 2001-09-11 00:32:32 +0000 | [diff] [blame] | 511 | |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 512 | tmpsrb.cmd.SRB_Flags |= 8; /* target to host */ |
| 513 | tmpsrb.cmd.SRB_Cmd = SC_EXEC_SCSI_CMD; |
| 514 | tmpsrb.cmd.SRB_Target = lpSRB->devtype.SRB_Target; |
| 515 | tmpsrb.cmd.SRB_Lun = lpSRB->devtype.SRB_Lun; |
Marcus Meissner | eb71e50 | 1999-09-19 12:08:18 +0000 | [diff] [blame] | 516 | tmpsrb.cmd.SRB_BufLen = sizeof(inqbuf); |
| 517 | tmpsrb.cmd.SRB_BufPointer = inqbuf; |
| 518 | tmpsrb.cmd.CDBByte[0] = 0x12; /* INQUIRY */ |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 519 | /* FIXME: handle lun */ |
Marcus Meissner | eb71e50 | 1999-09-19 12:08:18 +0000 | [diff] [blame] | 520 | tmpsrb.cmd.CDBByte[4] = sizeof(inqbuf); |
| 521 | tmpsrb.cmd.SRB_CDBLen = 6; |
Marcus Meissner | 12085e9 | 2000-03-26 13:36:16 +0000 | [diff] [blame] | 522 | |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 523 | ret = ASPI_ExecScsiCmd(&tmpsrb.cmd); |
Marcus Meissner | 12085e9 | 2000-03-26 13:36:16 +0000 | [diff] [blame] | 524 | |
| 525 | lpSRB->devtype.SRB_Status = tmpsrb.cmd.SRB_Status; |
Marcus Meissner | 5b66f70 | 1999-12-20 04:02:48 +0000 | [diff] [blame] | 526 | lpSRB->devtype.SRB_DeviceType = inqbuf[0]&0x1f; |
Marcus Meissner | 12085e9 | 2000-03-26 13:36:16 +0000 | [diff] [blame] | 527 | |
Marcus Meissner | 5b66f70 | 1999-12-20 04:02:48 +0000 | [diff] [blame] | 528 | TRACE("returning devicetype %d for target %d\n",inqbuf[0]&0x1f,tmpsrb.cmd.SRB_Target); |
Marcus Meissner | 12085e9 | 2000-03-26 13:36:16 +0000 | [diff] [blame] | 529 | if (ret!=SS_PENDING) /* Any error is passed down directly */ |
| 530 | return ret; |
| 531 | /* FIXME: knows that the command is finished already, pass final Status */ |
| 532 | return tmpsrb.cmd.SRB_Status; |
Marcus Meissner | eb71e50 | 1999-09-19 12:08:18 +0000 | [diff] [blame] | 533 | } |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 534 | case SC_EXEC_SCSI_CMD: |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 535 | return ASPI_ExecScsiCmd(&lpSRB->cmd); |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 536 | case SC_ABORT_SRB: |
| 537 | FIXME("Not implemented SC_ABORT_SRB\n"); |
| 538 | break; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 539 | case SC_RESET_DEV: |
Alexandre Julliard | a099a55 | 1999-06-12 15:45:58 +0000 | [diff] [blame] | 540 | FIXME("Not implemented SC_RESET_DEV\n"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 541 | break; |
David Elliott | 8b8a343 | 2000-01-08 22:25:02 +0000 | [diff] [blame] | 542 | case SC_GET_DISK_INFO: |
Patrik Stridvall | 3c0211f | 2001-09-11 00:32:32 +0000 | [diff] [blame] | 543 | /* here we have to find out the int13 / bios association. |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 544 | * We just say we do not have any. |
| 545 | */ |
| 546 | FIXME("SC_GET_DISK_INFO always return 'int13 unassociated disk'.\n"); |
| 547 | lpSRB->diskinfo.SRB_DriveFlags = 0; /* disk is not int13 served */ |
| 548 | return SS_COMP; |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 549 | default: |
Marcus Meissner | 8cd83a9 | 2000-03-24 19:45:47 +0000 | [diff] [blame] | 550 | FIXME("Unknown command %d\n", lpSRB->common.SRB_Cmd); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 551 | } |
| 552 | return SS_INVALID_SRB; |
| 553 | #else |
| 554 | return SS_INVALID_SRB; |
| 555 | #endif |
| 556 | } |
| 557 | |
| 558 | |
| 559 | /*********************************************************************** |
Patrik Stridvall | 8b216b3 | 2001-06-19 18:20:47 +0000 | [diff] [blame] | 560 | * GetASPI32DLLVersion (WNASPI32.4) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 561 | */ |
Patrik Stridvall | bf8943c | 2000-10-02 03:39:34 +0000 | [diff] [blame] | 562 | DWORD __cdecl GetASPI32DLLVersion(void) |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 563 | { |
| 564 | #ifdef linux |
David Elliott | 8466fc3 | 2000-07-15 15:15:31 +0000 | [diff] [blame] | 565 | TRACE("Returning version 1\n"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 566 | return (DWORD)1; |
| 567 | #else |
David Elliott | 8466fc3 | 2000-07-15 15:15:31 +0000 | [diff] [blame] | 568 | FIXME("Please add SCSI support for your operating system, returning 0\n"); |
Alexandre Julliard | d30dfd2 | 1998-09-27 18:28:36 +0000 | [diff] [blame] | 569 | return (DWORD)0; |
| 570 | #endif |
| 571 | } |
| 572 | |
Patrik Stridvall | bf8943c | 2000-10-02 03:39:34 +0000 | [diff] [blame] | 573 | /*********************************************************************** |
Patrik Stridvall | 8b216b3 | 2001-06-19 18:20:47 +0000 | [diff] [blame] | 574 | * GetASPI32Buffer (WNASPI32.8) |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 575 | * Supposed to return a DMA capable large SCSI buffer. |
Patrik Stridvall | 3c0211f | 2001-09-11 00:32:32 +0000 | [diff] [blame] | 576 | * Our implementation does not use those at all, all buffer stuff is |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 577 | * done in the kernel SG device layer. So we just heapalloc the buffer. |
Patrik Stridvall | bf8943c | 2000-10-02 03:39:34 +0000 | [diff] [blame] | 578 | */ |
Patrik Stridvall | 3c0211f | 2001-09-11 00:32:32 +0000 | [diff] [blame] | 579 | BOOL __cdecl GetASPI32Buffer(PASPI32BUFF pab) |
Andreas Mohr | 4d47ec2 | 2000-09-06 19:42:19 +0000 | [diff] [blame] | 580 | { |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 581 | pab->AB_BufPointer = HeapAlloc(GetProcessHeap(), |
| 582 | pab->AB_ZeroFill?HEAP_ZERO_MEMORY:0, |
| 583 | pab->AB_BufLen |
| 584 | ); |
| 585 | if (!pab->AB_BufPointer) return FALSE; |
Andreas Mohr | 4d47ec2 | 2000-09-06 19:42:19 +0000 | [diff] [blame] | 586 | return TRUE; |
| 587 | } |
| 588 | |
Patrik Stridvall | bf8943c | 2000-10-02 03:39:34 +0000 | [diff] [blame] | 589 | /*********************************************************************** |
Patrik Stridvall | 8b216b3 | 2001-06-19 18:20:47 +0000 | [diff] [blame] | 590 | * FreeASPI32Buffer (WNASPI32.14) |
Patrik Stridvall | bf8943c | 2000-10-02 03:39:34 +0000 | [diff] [blame] | 591 | */ |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 592 | BOOL __cdecl FreeASPI32Buffer(PASPI32BUFF pab) |
Andreas Mohr | 4d47ec2 | 2000-09-06 19:42:19 +0000 | [diff] [blame] | 593 | { |
Marcus Meissner | 485c3ef | 2001-06-06 20:19:07 +0000 | [diff] [blame] | 594 | HeapFree(GetProcessHeap(),0,pab->AB_BufPointer); |
Andreas Mohr | 4d47ec2 | 2000-09-06 19:42:19 +0000 | [diff] [blame] | 595 | return TRUE; |
| 596 | } |
| 597 | |
Patrik Stridvall | bf8943c | 2000-10-02 03:39:34 +0000 | [diff] [blame] | 598 | /*********************************************************************** |
Patrik Stridvall | 8b216b3 | 2001-06-19 18:20:47 +0000 | [diff] [blame] | 599 | * TranslateASPI32Address (WNASPI32.7) |
Patrik Stridvall | bf8943c | 2000-10-02 03:39:34 +0000 | [diff] [blame] | 600 | */ |
Andreas Mohr | 4d47ec2 | 2000-09-06 19:42:19 +0000 | [diff] [blame] | 601 | BOOL __cdecl TranslateASPI32Address(LPDWORD pdwPath, LPDWORD pdwDEVNODE) |
| 602 | { |
| 603 | FIXME("(%p, %p), stub !\n", pdwPath, pdwDEVNODE); |
| 604 | return TRUE; |
| 605 | } |