Changeset 178 for trunk/src/os2ahci/os2ahci.c
- Timestamp:
- Nov 29, 2016, 5:30:22 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/os2ahci.c
r176 r178 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-201 5David Azarewicz6 * Copyright (c) 2013-2016 David Azarewicz 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen … … 29 29 #include "ioctl.h" 30 30 #include "version.h" 31 #include "devhdr.h" 31 32 32 33 /* -------------------------- macros and constants ------------------------- */ 33 34 /* parse integer command line parameter */35 #define drv_parm_int(s, value, type, radix) \36 { \37 char _far *_ep; \38 if ((s)[1] != ':') { \39 cprintf("%s: missing colon (:) after /%c\n", drv_name, *(s)); \40 goto init_fail; \41 } \42 value = (type) strtol((s) + 2, \43 (const char _far* _far*) &_ep, \44 radix); \45 s = _ep; \46 }47 48 #define drv_parm_int_optional(s, value, type, radix) \49 { \50 char _far *_ep; \51 if ((s)[1] == ':') { \52 value = (type) strtol((s) + 2, (const char _far* _far*) &_ep, radix); \53 s = _ep; \54 } else { \55 value++; \56 } \57 }58 34 59 35 /* set two-dimensional array of port options */ … … 70 46 } 71 47 72 /* constants for undefined kernel exit routine;73 * see register_krnl_exit() func */74 #define DevHlp_RegisterKrnlExit 0x006f75 76 48 #define FLAG_KRNL_EXIT_ADD 0x1000 77 49 #define FLAG_KRNL_EXIT_REMOVE 0x2000 … … 87 59 /* -------------------------- function prototypes -------------------------- */ 88 60 89 void _cdecl small_code_ (void); 90 91 static int add_unit_info (IORB_CONFIGURATION _far *iorb_conf, int dt_ai, 92 int a, int p, int d, int scsi_id); 93 94 static void register_krnl_exit (void); 61 extern int SetPsdPutc(void); 62 static int add_unit_info(IORB_CONFIGURATION *iorb_conf, int dt_ai, int a, int p, int d, int scsi_id); 95 63 96 64 /* ------------------------ global/static variables ------------------------ */ 97 98 int debug = 0; /* if > 0, print debug messages to COM1 */ 99 int thorough_scan = 1; /* if != 0, perform thorough PCI scan */ 100 int init_reset = 1; /* if != 0, reset ports during init */ 101 int force_write_cache; /* if != 0, force write cache */ 102 int verbosity = 0; /* default is quiet. 1=show sign on banner, >1=show adapter info during boot */ 103 int use_lvm_info = 1; 104 int wrap_trace_buffer = 0; 105 long com_baud = 0; 106 107 PFN Device_Help = 0; /* pointer to device helper entry point */ 108 ULONG RMFlags = 0; /* required by resource manager library */ 109 PFN RM_Help0 = NULL; /* required by resource manager library */ 110 PFN RM_Help3 = NULL; /* required by resource manager library */ 111 HDRIVER rm_drvh; /* resource manager driver handle */ 112 char rm_drvname[80]; /* driver name as returned by RM */ 113 USHORT add_handle; /* driver handle (RegisterDeviceClass) */ 114 UCHAR timer_pool[TIMER_POOL_SIZE]; /* timer pool */ 115 char drv_name[] = "OS2AHCI"; /* driver name as string */ 65 int thorough_scan = 1; /* if != 0, perform thorough PCI scan */ 66 int init_reset = 1; /* if != 0, reset ports during init */ 67 int force_write_cache; /* if != 0, force write cache */ 68 int verbosity = 0; /* default is quiet. 1=show sign on banner, >1=show adapter info during boot */ 69 int use_lvm_info = 1; 70 long com_baud = 0; 71 72 HDRIVER rm_drvh; /* resource manager driver handle */ 73 USHORT add_handle; /* driver handle (RegisterDeviceClass) */ 74 char drv_name[] = "OS2AHCI"; /* driver name as string */ 116 75 117 76 /* resource manager driver information structure */ 118 DRIVERSTRUCT rm_drvinfo = { 119 drv_name, /* driver name */ 120 "AHCI SATA Driver", /* driver description */ 121 DVENDOR, /* vendor name */ 122 DMAJOR, /* RM interface version major */ 123 DMINOR, /* RM interface version minor */ 124 BLD_YEAR, BLD_MONTH, BLD_DAY, /* date */ 125 0, /* driver flags */ 126 DRT_ADDDM, /* driver type */ 127 DRS_ADD, /* driver sub type */ 128 NULL /* driver callback */ 77 static DRIVERSTRUCT rm_drvinfo = 78 { 79 NULL, /* We cannot do Flat to Far16 conversion at compile time */ 80 NULL, /* so we put NULLs in all the Far16 fields and then fill */ 81 NULL, /* them in at run time */ 82 DMAJOR, 83 DMINOR, 84 BLD_YEAR, BLD_MONTH, BLD_DAY, 85 0, 86 DRT_ADDDM, 87 DRS_ADD, 88 NULL 129 89 }; 130 90 131 ULONGdrv_lock; /* driver-level spinlock */132 IORB_QUEUE 133 AD_INFO 134 int 135 u16 136 int 137 int 138 int 91 SpinLock_t drv_lock; /* driver-level spinlock */ 92 IORB_QUEUE driver_queue; /* driver-level IORB queue */ 93 AD_INFO ad_infos[MAX_AD]; /* adapter information list */ 94 int ad_info_cnt; /* number of entries in ad_infos[] */ 95 u16 ad_ignore; /* bitmap with adapter indexes to ignore */ 96 int init_complete; /* if != 0, initialization has completed */ 97 int suspended; 98 int resume_sleep_flag; 139 99 140 100 /* apapter/port-specific options saved when parsing the command line */ 141 u8 emulate_scsi[MAX_AD][AHCI_MAX_PORTS]; 142 u8 enable_ncq[MAX_AD][AHCI_MAX_PORTS]; 143 u8 link_speed[MAX_AD][AHCI_MAX_PORTS]; 144 u8 link_power[MAX_AD][AHCI_MAX_PORTS]; 145 u8 track_size[MAX_AD][AHCI_MAX_PORTS]; 146 u8 port_ignore[MAX_AD][AHCI_MAX_PORTS]; 147 148 static char init_msg[] = "%s driver version %d.%02d\n"; 149 static char exit_msg[] = "%s driver *not* installed\n"; 101 u8 emulate_scsi[MAX_AD][AHCI_MAX_PORTS]; 102 u8 enable_ncq[MAX_AD][AHCI_MAX_PORTS]; 103 u8 link_speed[MAX_AD][AHCI_MAX_PORTS]; 104 u8 link_power[MAX_AD][AHCI_MAX_PORTS]; 105 u8 track_size[MAX_AD][AHCI_MAX_PORTS]; 106 u8 port_ignore[MAX_AD][AHCI_MAX_PORTS]; 107 150 108 char BldLevel[] = BLDLEVEL; 151 109 … … 158 116 * packet for IDC calls, so they can be handled by gen_ioctl. 159 117 */ 160 USHORT _cdecl c_strat(RPH _far *req)118 void StrategyHandler(REQPACKET *prp) 161 119 { 162 120 u16 rc; 163 121 164 switch (req->Cmd) { 165 166 case CMDInitBase: 167 rc = init_drv((RPINITIN _far *) req); 168 break; 169 170 case CMDShutdown: 171 rc = exit_drv(((RPSAVERESTORE _far *) req)->FuncCode); 172 break; 173 174 case CMDGenIOCTL: 175 rc = gen_ioctl((RP_GENIOCTL _far *) req); 176 break; 177 178 case CMDOpen: 179 build_user_info(1); 180 rc = STDON; 181 break; 182 183 case CMDINPUT: 184 rc = char_dev_input((RP_RWV _far *) req); 185 break; 186 187 case CMDSaveRestore: 188 rc = sr_drv(((RPSAVERESTORE _far *) req)->FuncCode); 189 break; 190 191 case CMDClose: 192 case CMDInputS: 193 case CMDInputF: 122 switch (prp->bCommand) 123 { 124 case STRATEGY_BASEDEVINIT: 125 rc = init_drv(prp); 126 break; 127 128 case STRATEGY_SHUTDOWN: 129 rc = exit_drv(prp->save_restore.Function); 130 break; 131 132 case STRATEGY_GENIOCTL: 133 rc = gen_ioctl(prp); 134 break; 135 136 case STRATEGY_OPEN: 137 build_user_info(); 138 rc = RPDONE; 139 break; 140 141 case STRATEGY_READ: 142 rc = char_dev_input(prp); 143 break; 144 145 case STRATEGY_SAVERESTORE: 146 rc = sr_drv(prp->save_restore.Function); 147 break; 148 149 case STRATEGY_INITCOMPLETE: 150 case STRATEGY_CLOSE: 151 case STRATEGY_INPUTSTATUS: 152 case STRATEGY_FLUSHINPUT: 194 153 /* noop */ 195 rc = STDON;154 rc = RPDONE; 196 155 break; 197 156 198 157 default: 199 rc = STDON | STATUS_ERR_UNKCMD; 200 break; 201 } 202 203 return(rc); 158 rc = RPDONE | RPERR_BADCOMMAND; 159 break; 160 } 161 162 prp->usStatus = rc; 163 } 164 165 void IdcHandler(REQPACKET *prp) 166 { 167 StrategyHandler(prp); 204 168 } 205 169 … … 208 172 * the PCI bus for supported AHCI adapters, etc. 209 173 */ 210 USHORT init_drv(R PINITIN _far*req)174 USHORT init_drv(REQPACKET *req) 211 175 { 212 176 static int init_drv_called; 213 177 static int init_drv_failed; 214 RPINITOUT _far *rsp = (RPINITOUT _far *) req;215 DDD_PARM_LIST _far *ddd_pl = (DDD_PARM_LIST _far *) req->InitArgs;216 178 APIRET rmrc; 217 char _far *cmd_line; 218 char _far *s; 179 const char *pszCmdLine, *cmd_line; 219 180 int adapter_index = -1; 220 181 int port_index = -1; 221 int invert_option; 222 int optval; 223 u16 vendor; 224 u16 device; 225 226 if (init_drv_called) { 227 /* This is the init call for the second (legacy IBMS506$) character 182 int iInvertOption; 183 int iStatus; 184 185 if (init_drv_called) 186 { 187 /* This is the init call for the second (IBMS506$) character 228 188 * device driver. If the main driver failed initialization, fail this 229 189 * one as well. 230 190 */ 231 rsp->CodeEnd = (u16) end_of_code; 232 rsp->DataEnd = (u16) &end_of_data; 233 return(STDON | ((init_drv_failed) ? ERROR_I24_QUIET_INIT_FAIL : 0)); 234 } 191 return(RPDONE | ((init_drv_failed) ? RPERR_INITFAIL : 0)); 192 } 193 D32g_DbgLevel = 0; 235 194 init_drv_called = 1; 236 195 suspended = 0; … … 238 197 memset(ad_infos, 0, sizeof(ad_infos)); 239 198 memset(emulate_scsi, 1, sizeof(emulate_scsi)); /* set default enabled */ 240 241 /* set device helper entry point */ 242 Device_Help = req->DevHlpEP; 199 UtSetDriverName("OS2AHCI$"); 200 Header.ulCaps |= DEV_ADAPTER_DD; /* DAZ This flag is not really needed. */ 243 201 244 202 /* create driver-level spinlock */ 245 DevHelp_CreateSpinLock(&drv_lock); 246 247 /* initialize libc code */ 248 init_libc(); 203 KernAllocSpinLock(&drv_lock); 249 204 250 205 /* register driver with resource manager */ 251 if ((rmrc = RMCreateDriver(&rm_drvinfo, &rm_drvh)) != RMRC_SUCCESS) { 252 cprintf("%s: failed to register driver with resource manager (rc = %d)\n", 253 drv_name, rmrc); 206 rm_drvinfo.DrvrName = drv_name; 207 rm_drvinfo.DrvrDescript = "AHCI SATA Driver"; 208 rm_drvinfo.VendorName = DVENDOR; 209 if ((rmrc = RMCreateDriver(&rm_drvinfo, &rm_drvh)) != RMRC_SUCCESS) 210 { 211 iprintf("%s: failed to register driver with resource manager (rc = %d)", drv_name, rmrc); 254 212 goto init_fail; 255 213 } 256 214 257 /* parse command line parameters */ 258 cmd_line = (char _far *) ((u32) ddd_pl & 0xffff0000l) + ddd_pl->cmd_line_args; 259 260 for (s = cmd_line; *s != 0; s++) { 261 if (*s == '/') { 262 if ((invert_option = (s[1] == '!')) != 0) { 263 s++; 264 } 265 s++; 266 switch (tolower(*s)) { 267 268 case '\0': 269 /* end of command line; can only happen if command line is incorrect */ 270 cprintf("%s: incomplete command line option\n", drv_name); 271 goto init_fail; 272 273 case 'b': 274 drv_parm_int(s, com_baud, u32, 10); 275 break; 276 277 case 'c': 278 /* set COM port base address for debug messages */ 279 drv_parm_int(s, com_base, u16, 16); 280 if (com_base == 1) com_base = 0x3f8; 281 if (com_base == 2) com_base = 0x2f8; 282 break; 283 284 case 'd': 285 /* increase debug level */ 286 drv_parm_int_optional(s, debug, int, 10); 287 break; 288 289 case 'g': 290 /* add specfied PCI ID as a supported generic AHCI adapter */ 291 drv_parm_int(s, vendor, u16, 16); 292 s--; 293 drv_parm_int(s, device, u16, 16); 294 if (add_pci_id(vendor, device)) { 295 cprintf("%s: failed to add PCI ID %04x:%04x\n", drv_name, vendor, device); 296 goto init_fail; 297 } 298 thorough_scan = 1; 299 break; 300 301 case 't': 302 /* perform thorough PCI scan (i.e. look for individual supported PCI IDs) */ 303 thorough_scan = !invert_option; 304 break; 305 306 case 'r': 307 /* reset ports during initialization */ 308 init_reset = !invert_option; 309 break; 310 311 case 'f': 312 /* force write cache regardless of IORB flags */ 313 force_write_cache = 1; 314 break; 315 316 case 'a': 317 /* set adapter index for adapter and port-related options */ 318 drv_parm_int(s, adapter_index, int, 10); 319 if (adapter_index < 0 || adapter_index >= MAX_AD) { 320 cprintf("%s: invalid adapter index (%d)\n", drv_name, adapter_index); 321 goto init_fail; 322 } 323 break; 324 325 case 'p': 326 /* set port index for port-related options */ 327 drv_parm_int(s, port_index, int, 10); 328 if (port_index < 0 || port_index >= AHCI_MAX_PORTS) { 329 cprintf("%s: invalid port index (%d)\n", drv_name, port_index); 330 goto init_fail; 331 } 332 break; 333 334 case 'i': 335 /* ignore current adapter index */ 336 if (adapter_index >= 0) { 337 if (port_index >= 0) port_ignore[adapter_index][port_index] = !invert_option; 338 else ad_ignore |= 1U << adapter_index; 339 } 340 break; 341 342 case 's': 343 /* enable SCSI emulation for ATAPI devices */ 344 set_port_option(emulate_scsi, !invert_option); 345 break; 346 347 case 'n': 348 /* enable NCQ */ 349 set_port_option(enable_ncq, !invert_option); 350 break; 351 352 case 'l': 353 /* set link speed or power savings */ 354 s++; 355 switch (tolower(*s)) { 356 case 's': 357 /* set link speed */ 358 drv_parm_int(s, optval, int, 10); 359 set_port_option(link_speed, optval); 360 break; 361 case 'p': 362 /* set power management */ 363 drv_parm_int(s, optval, int, 10); 364 set_port_option(link_power, optval); 365 break; 366 default: 367 cprintf("%s: invalid link parameter (%c)\n", drv_name, *s); 368 goto init_fail; 369 } 370 /* need to reset the port in order to establish link settings */ 371 init_reset = 1; 372 break; 373 374 case '4': 375 /* enable 4K sector geometry enhancement (track size = 56) */ 376 if (!invert_option) { 377 set_port_option(track_size, 56); 378 } 379 break; 380 381 case 'z': 382 /* Specify to not use the LVM information. There is no reason why anyone would 383 * want to do this, but previous versions of this driver did not have LVM capability, 384 * so this switch is here temporarily just in case. 385 */ 386 use_lvm_info = !invert_option; 387 break; 388 389 case 'v': 390 /* be verbose during boot */ 391 drv_parm_int_optional(s, verbosity, int, 10); 392 break; 393 394 case 'w': 395 /* Specify to allow the trace buffer to wrap when full. */ 396 wrap_trace_buffer = !invert_option; 397 break; 398 399 case 'q': 400 /* Temporarily output a non-fatal message to get anyone using this 401 * undocumented switch to stop using it. This will be removed soon 402 * and the error will become fatal. 403 */ 404 cprintf("%s: unknown option: /%c\n", drv_name, *s); 405 break; 406 407 default: 408 cprintf("%s: unknown option: /%c\n", drv_name, *s); 409 goto init_fail; 410 } 411 } 412 } 413 414 if (com_baud) init_com(com_baud); /* initialize com port for debug output */ 415 416 /* initialize trace buffer if applicable */ 417 if (debug > 0 && com_base == 0) { 418 /* debug is on, but COM port is off -> use our trace buffer */ 419 trace_init(AHCI_DEBUG_BUF_SIZE); 420 } else { 421 trace_init(AHCI_INFO_BUF_SIZE); 422 } 423 424 ntprintf("BldLevel: %s\n", BldLevel); 425 ntprintf("CmdLine: %Fs\n", cmd_line); 215 pszCmdLine = cmd_line = req->init_in.szArgs; 216 iStatus = 0; 217 while (*pszCmdLine) 218 { 219 if (*pszCmdLine++ != '/') continue; /* Ignore anything that doesn't start with '/' */ 220 /* pszCmdLine now points to first char of argument */ 221 222 if ((iInvertOption = (*pszCmdLine == '!')) != 0) pszCmdLine++; 223 224 if (ArgCmp(pszCmdLine, "B:")) 225 { 226 pszCmdLine += 2; 227 com_baud = strtol(pszCmdLine, &pszCmdLine, 0); 228 continue; 229 } 230 231 if (ArgCmp(pszCmdLine, "C:")) 232 { 233 pszCmdLine += 2; 234 /* set COM port base address for debug messages */ 235 D32g_ComBase = strtol(pszCmdLine, &pszCmdLine, 0); 236 if (D32g_ComBase == 1) D32g_ComBase = 0x3f8; 237 if (D32g_ComBase == 2) D32g_ComBase = 0x2f8; 238 continue; 239 } 240 241 if (ArgCmp(pszCmdLine, "D")) 242 { 243 pszCmdLine++; 244 if (*pszCmdLine == ':') 245 { 246 pszCmdLine++; 247 D32g_DbgLevel = strtol(pszCmdLine, &pszCmdLine, 0); 248 } 249 else D32g_DbgLevel++; /* increase debug level */ 250 continue; 251 } 252 253 if (ArgCmp(pszCmdLine, "G:")) 254 { 255 u16 usVendor; 256 u16 usDevice; 257 258 pszCmdLine += 2; 259 /* add specfied PCI ID as a supported generic AHCI adapter */ 260 usVendor = strtol(pszCmdLine, &pszCmdLine, 16); 261 if (*pszCmdLine != ':') break; 262 pszCmdLine++; 263 usDevice = strtol(pszCmdLine, &pszCmdLine, 16); 264 if (add_pci_id(usVendor, usDevice)) 265 { 266 iprintf("%s: failed to add PCI ID %04x:%04x", drv_name, usVendor, usDevice); 267 iStatus = 1; 268 } 269 thorough_scan = 1; 270 continue; 271 } 272 273 if (ArgCmp(pszCmdLine, "T")) 274 { 275 pszCmdLine++; 276 /* perform thorough PCI scan (i.e. look for individual supported PCI IDs) */ 277 thorough_scan = !iInvertOption; 278 continue; 279 } 280 281 if (ArgCmp(pszCmdLine, "R")) 282 { 283 pszCmdLine++; 284 /* reset ports during initialization */ 285 init_reset = !iInvertOption; 286 continue; 287 } 288 289 if (ArgCmp(pszCmdLine, "F")) 290 { 291 pszCmdLine++; 292 /* force write cache regardless of IORB flags */ 293 force_write_cache = 1; 294 continue; 295 } 296 297 if (ArgCmp(pszCmdLine, "A:")) 298 { 299 pszCmdLine += 2; 300 /* set adapter index for adapter and port-related options */ 301 adapter_index = strtol(pszCmdLine, &pszCmdLine, 0); 302 if (adapter_index < 0 || adapter_index >= MAX_AD) 303 { 304 iprintf("%s: invalid adapter index (%d)", drv_name, adapter_index); 305 iStatus = 1; 306 } 307 continue; 308 } 309 310 if (ArgCmp(pszCmdLine, "P:")) 311 { 312 pszCmdLine += 2; 313 /* set port index for port-related options */ 314 port_index = strtol(pszCmdLine, &pszCmdLine, 0); 315 if (port_index < 0 || port_index >= AHCI_MAX_PORTS) 316 { 317 iprintf("%s: invalid port index (%d)", drv_name, port_index); 318 iStatus = 1; 319 } 320 continue; 321 } 322 323 if (ArgCmp(pszCmdLine, "I")) 324 { 325 pszCmdLine++; 326 /* ignore current adapter index */ 327 if (adapter_index >= 0) 328 { 329 if (port_index >= 0) port_ignore[adapter_index][port_index] = !iInvertOption; 330 else ad_ignore |= 1U << adapter_index; 331 } 332 continue; 333 } 334 335 if (ArgCmp(pszCmdLine, "S")) 336 { 337 pszCmdLine++; 338 /* enable SCSI emulation for ATAPI devices */ 339 set_port_option(emulate_scsi, !iInvertOption); 340 continue; 341 } 342 343 if (ArgCmp(pszCmdLine, "N")) 344 { 345 pszCmdLine++; 346 /* enable NCQ */ 347 set_port_option(enable_ncq, !iInvertOption); 348 continue; 349 } 350 351 if (ArgCmp(pszCmdLine, "LS:")) 352 { 353 int optval; 354 355 pszCmdLine += 3; 356 /* set link speed */ 357 optval = strtol(pszCmdLine, &pszCmdLine, 0); 358 set_port_option(link_speed, optval); 359 /* need to reset the port in order to establish link settings */ 360 init_reset = 1; 361 continue; 362 } 363 364 if (ArgCmp(pszCmdLine, "LP:")) 365 { 366 int optval; 367 368 pszCmdLine += 3; 369 /* set power management */ 370 optval = strtol(pszCmdLine, &pszCmdLine, 0); 371 set_port_option(link_power, optval); 372 /* need to reset the port in order to establish link settings */ 373 init_reset = 1; 374 continue; 375 } 376 377 if (ArgCmp(pszCmdLine, "4")) 378 { 379 pszCmdLine++; 380 /* enable 4K sector geometry enhancement (track size = 56) */ 381 if (!iInvertOption) set_port_option(track_size, 56); 382 continue; 383 } 384 385 if (ArgCmp(pszCmdLine, "Z")) 386 { 387 pszCmdLine++; 388 /* Specify to not use the LVM information. There is no reason why anyone would 389 * want to do this, but previous versions of this driver did not have LVM capability, 390 * so this switch is here temporarily just in case. 391 */ 392 use_lvm_info = !iInvertOption; 393 continue; 394 } 395 396 if (ArgCmp(pszCmdLine, "V")) 397 { 398 pszCmdLine++; 399 if (*pszCmdLine == ':') 400 { 401 pszCmdLine++; 402 verbosity = strtol(pszCmdLine, &pszCmdLine, 0); 403 } 404 else verbosity++; /* increase verbosity level */ 405 continue; 406 } 407 408 if (ArgCmp(pszCmdLine, "W")) 409 { 410 pszCmdLine++; 411 /* Specify to allow the trace buffer to wrap when full. */ 412 D32g_DbgBufWrap = !iInvertOption; 413 continue; 414 } 415 416 iprintf("Unrecognized switch: %s", pszCmdLine-1); 417 iStatus = 1; /* unrecognized argument */ 418 } 419 420 if (iStatus) goto init_fail; 421 422 if (com_baud) InitComPort(com_baud); 423 424 NTPRINTF("BldLevel: %s\n", BldLevel); 425 NTPRINTF("CmdLine: %s\n", cmd_line); 426 /* 427 if (sizeof(ADD_WORKSPACE) > ADD_WORKSPACE_SIZE) 428 { 429 dprintf(0,"ADD_WORKSPACE size is too big! %d>16\n", sizeof(ADD_WORKSPACE)); 430 goto init_fail; 431 } 432 */ 426 433 427 434 /* print initialization message */ 428 ciprintf( init_msg, drv_name, DMAJOR, DMINOR);435 ciprintf("%s driver version %d.%02d", drv_name, DMAJOR, DMINOR); 429 436 430 437 #ifdef TESTVER … … 435 442 scan_pci_bus(); 436 443 437 if (ad_info_cnt > 0) { 444 if (ad_info_cnt > 0) 445 { 438 446 /* initialization succeeded and we found at least one AHCI adapter */ 439 ADD_InitTimer(timer_pool, sizeof(timer_pool)); 440 441 if (DevHelp_RegisterDeviceClass(drv_name, (PFN) add_entry, 0, 1, &add_handle)){442 cprintf("%s: couldn't register device class\n", drv_name);447 448 if (Dev32Help_RegisterDeviceClass(drv_name, add_entry, 0, 1, &add_handle)) 449 { 450 iprintf("%s: couldn't register device class", drv_name); 443 451 goto init_fail; 444 452 } 445 453 454 Timer_InitTimer(TIMER_COUNT); 455 446 456 /* allocate context hooks */ 447 if (DevHelp_AllocateCtxHook(mk_NPFN(restart_hook), &restart_ctxhook_h) != 0 || 448 DevHelp_AllocateCtxHook(mk_NPFN(reset_hook), &reset_ctxhook_h) != 0 || 449 DevHelp_AllocateCtxHook(mk_NPFN(engine_hook), &engine_ctxhook_h)) { 450 cprintf("%s: failed to allocate task-time context hooks\n", drv_name); 451 goto init_fail; 452 } 453 454 rsp->CodeEnd = (u16) end_of_code; 455 rsp->DataEnd = (u16) &end_of_data; 457 KernAllocateContextHook(restart_ctxhook, 0, &restart_ctxhook_h); 458 KernAllocateContextHook(reset_ctxhook, 0, &reset_ctxhook_h); 459 KernAllocateContextHook(engine_ctxhook, 0, &engine_ctxhook_h); 456 460 457 461 /* register kernel exit routine for trap dumps */ 458 register_krnl_exit(); 459 460 return(STDON); 461 462 } else { 462 Dev32Help_RegisterKrnlExit(shutdown_driver, FLAG_KRNL_EXIT_ADD, TYPE_KRNL_EXIT_INT13); 463 464 return(RPDONE); 465 466 } 467 else 468 { 463 469 /* no adapters found */ 464 ciprintf(" No adapters found.\n");470 ciprintf("%s: No adapters found.", drv_name); 465 471 } 466 472 467 473 init_fail: 468 474 /* initialization failed; set segment sizes to 0 and return error */ 469 rsp->CodeEnd = 0;470 rsp->DataEnd = 0;471 475 init_drv_failed = 1; 472 476 473 /* free context hooks */ 474 if (engine_ctxhook_h != 0) DevHelp_FreeCtxHook(engine_ctxhook_h); 475 if (reset_ctxhook_h != 0) DevHelp_FreeCtxHook(reset_ctxhook_h); 476 if (restart_ctxhook_h != 0) DevHelp_FreeCtxHook(restart_ctxhook_h); 477 478 if (rm_drvh != 0) { 477 if (rm_drvh != 0) 478 { 479 479 /* remove driver from resource manager */ 480 480 RMDestroyDriver(rm_drvh); 481 481 } 482 482 483 ciprintf( exit_msg, drv_name);484 return( STDON | ERROR_I24_QUIET_INIT_FAIL);483 ciprintf("%s driver *not* installed", drv_name); 484 return(RPDONE | RPERR_INITFAIL); 485 485 } 486 486 … … 491 491 * commands for ATA disks) are implemented here. 492 492 */ 493 USHORT gen_ioctl(R P_GENIOCTL _far*ioctl)494 { 495 dprintf("IOCTL 0x%x/0x%x\n", (u16) ioctl->Category, (u16) ioctl->Function);496 497 switch (ioctl-> Category) {498 493 USHORT gen_ioctl(REQPACKET *ioctl) 494 { 495 DPRINTF(2,"IOCTL 0x%x/0x%x\n", ioctl->ioctl.bCategory, ioctl->ioctl.bFunction); 496 497 switch (ioctl->ioctl.bCategory) 498 { 499 499 case OS2AHCI_IOCTL_CATEGORY: 500 switch (ioctl->Function) { 500 switch (ioctl->ioctl.bFunction) 501 { 501 502 502 503 case OS2AHCI_IOCTL_GET_DEVLIST: … … 514 515 case DSKSP_CAT_SMART: 515 516 return(ioctl_smart(ioctl)); 516 517 } 518 519 return(STDON | STATUS_ERR_UNKCMD); 517 } 518 519 return(RPDONE | RPERR_BADCOMMAND); 520 520 } 521 521 … … 525 525 * dump similar to IBM1S506.ADD/DANIS506.ADD (TODO). 526 526 */ 527 USHORT char_dev_input(RP_RWV _far *rwrb) 528 { 529 return(trace_char_dev(rwrb)); 527 USHORT char_dev_input(REQPACKET *pPacket) 528 { 529 void *LinAdr; 530 531 if (Dev32Help_PhysToLin(pPacket->io.ulAddress, pPacket->io.usCount, &LinAdr)) 532 { 533 pPacket->io.usCount = 0; 534 return RPDONE | RPERR_GENERAL; 535 } 536 537 pPacket->io.usCount = dCopyToUser(LinAdr, pPacket->io.usCount); 538 539 return RPDONE; 530 540 } 531 541 … … 542 552 USHORT exit_drv(int func) 543 553 { 544 dprintf("exit_drv(%d) called\n", func); 545 546 if (func == 0) { 554 DPRINTF(2,"exit_drv(%d) called\n", func); 555 556 if (func == 0) 557 { 547 558 /* we're only interested in the second phase of the shutdown */ 548 return( STDON);559 return(RPDONE); 549 560 } 550 561 551 562 suspend(); 552 return( STDON);563 return(RPDONE); 553 564 } 554 565 … … 559 570 USHORT sr_drv(int func) 560 571 { 561 dprintf("sr_drv(%d) called\n", func);572 DPRINTF(2,"sr_drv(%d) called\n", func); 562 573 563 574 if (func) resume(); 564 575 else suspend(); 565 576 566 return( STDON);577 return(RPDONE); 567 578 } 568 579 … … 578 589 * details. 579 590 */ 580 void _cdecl _far _loadds add_entry(IORBH _far *first_iorb)581 { 582 IORBH _far *iorb;583 IORBH _far *next = NULL;591 void add_entry(IORBH FAR16DATA *vFirstIorb) 592 { 593 IORBH FAR16DATA *vIorb; 594 IORBH FAR16DATA *vNext = NULL; 584 595 585 596 spin_lock(drv_lock); 586 597 587 for (iorb = first_iorb; iorb != NULL; iorb = next) { 598 for (vIorb=vFirstIorb; vIorb!=NULL; vIorb=vNext) 599 { 600 IORBH *pIorb = Far16ToFlat(vIorb); 601 588 602 /* Queue this IORB. Queues primarily exist on port level but there are 589 603 * some requests which affect the whole driver, most notably 590 604 * IOCC_CONFIGURATION. In either case, adding the IORB to the driver or 591 605 * port queue will change the links, thus we need to save the original 592 * link in ' next'.606 * link in 'vNext'. 593 607 */ 594 next = (iorb->RequestControl | IORB_CHAIN) ? iorb->pNxtIORB : 0; 595 596 iorb->Status = 0; 597 iorb->ErrorCode = 0; 598 memset(&iorb->ADDWorkSpace, 0x00, sizeof(ADD_WORKSPACE)); 599 600 if (iorb_driver_level(iorb)) { 608 vNext = (pIorb->RequestControl | IORB_CHAIN) ? pIorb->pNxtIORB : NULL; 609 610 pIorb->Status = 0; 611 pIorb->ErrorCode = 0; 612 memset(&pIorb->ADDWorkSpace, 0x00, sizeof(ADD_WORKSPACE)); 613 614 if (iorb_driver_level(pIorb)) 615 { 601 616 /* driver-level IORB */ 602 iorb->UnitHandle = 0; 603 iorb_queue_add(&driver_queue, iorb); 604 605 } else { 617 pIorb->UnitHandle = 0; 618 iorb_queue_add(&driver_queue, vIorb, pIorb); 619 620 } 621 else 622 { 606 623 /* port-level IORB */ 607 int a = iorb_unit_adapter( iorb);608 int p = iorb_unit_port( iorb);609 int d = iorb_unit_device( iorb);624 int a = iorb_unit_adapter(pIorb); 625 int p = iorb_unit_port(pIorb); 626 int d = iorb_unit_device(pIorb); 610 627 611 628 if (a >= ad_info_cnt || 612 629 p > ad_infos[a].port_max || 613 630 d > ad_infos[a].ports[p].dev_max || 614 (ad_infos[a].port_map & (1UL << p)) == 0) { 631 (ad_infos[a].port_map & (1UL << p)) == 0) 632 { 615 633 616 634 /* unit handle outside of the allowed range */ 617 dprintf("warning: IORB for %d.%d.%d out of range\n", a, p, d);618 iorb->Status = IORB_ERROR;619 iorb->ErrorCode = IOERR_CMD_SYNTAX;620 iorb_complete( iorb);635 DPRINTF(0,"warning: IORB for %d.%d.%d out of range\n", a, p, d); 636 pIorb->Status = IORB_ERROR; 637 pIorb->ErrorCode = IOERR_CMD_SYNTAX; 638 iorb_complete(vIorb, pIorb); 621 639 continue; 622 640 } 623 641 624 iorb_queue_add(&ad_infos[a].ports[p].iorb_queue, iorb);642 iorb_queue_add(&ad_infos[a].ports[p].iorb_queue, vIorb, pIorb); 625 643 } 626 644 } … … 649 667 int i; 650 668 651 for (i = 0; i < 3 || !init_complete; i++) { 652 if (trigger_engine_1() == 0) { 669 for (i = 0; i < 3 || !init_complete; i++) 670 { 671 if (trigger_engine_1() == 0) 672 { 653 673 /* done -- all IORBs have been sent on their way */ 654 674 return; … … 659 679 * keep trying in the background. 660 680 */ 661 DevHelp_ArmCtxHook(0, engine_ctxhook_h);681 KernArmHook(engine_ctxhook_h, 0, 0); 662 682 } 663 683 … … 710 730 int trigger_engine_1(void) 711 731 { 712 IORBH _far *iorb; 713 IORBH _far *next; 732 IORBH FAR16DATA *vIorb; 733 IORBH *pIorb; 734 IORBH FAR16DATA *vNext; 714 735 int iorbs_sent = 0; 715 736 int a; … … 719 740 720 741 /* process driver-level IORBs */ 721 if ((iorb = driver_queue.root) != NULL && !add_workspace(iorb)->processing) { 722 send_iorb(iorb); 723 iorbs_sent++; 742 if ((vIorb = driver_queue.vRoot) != NULL) 743 { 744 pIorb = Far16ToFlat(vIorb); 745 746 if (!add_workspace(pIorb)->processing) 747 { 748 send_iorb(vIorb, pIorb); 749 iorbs_sent++; 750 } 724 751 } 725 752 726 753 /* process port-level IORBs */ 727 for (a = 0; a < ad_info_cnt; a++) { 754 for (a = 0; a < ad_info_cnt; a++) 755 { 728 756 AD_INFO *ai = ad_infos + a; 729 if (ai->busy) { 757 if (ai->busy) 758 { 730 759 /* adapter is busy; don't process any IORBs */ 731 760 continue; 732 761 } 733 for (p = 0; p <= ai->port_max; p++) { 762 for (p = 0; p <= ai->port_max; p++) 763 { 734 764 /* send all queued IORBs on this port */ 735 next = NULL; 736 for (iorb = ai->ports[p].iorb_queue.root; iorb != NULL; iorb = next) { 737 next = iorb->pNxtIORB; 738 if (!add_workspace(iorb)->processing) { 739 send_iorb(iorb); 765 vNext = NULL; 766 for (vIorb = ai->ports[p].iorb_queue.vRoot; vIorb != NULL; vIorb = vNext) 767 { 768 pIorb = Far16ToFlat(vIorb); 769 770 vNext = pIorb->pNxtIORB; 771 if (!add_workspace(pIorb)->processing) 772 { 773 send_iorb(vIorb, pIorb); 740 774 iorbs_sent++; 741 775 } … … 755 789 * functions and re-aquire it when done. 756 790 */ 757 void send_iorb(IORBH _far *iorb)791 void send_iorb(IORBH FAR16DATA *vIorb, IORBH *pIorb) 758 792 { 759 793 /* Mark IORB as "processing" before doing anything else. Once the IORB is … … 762 796 * IORB. 763 797 */ 764 add_workspace( iorb)->processing = 1;798 add_workspace(pIorb)->processing = 1; 765 799 spin_unlock(drv_lock); 766 800 767 switch ( iorb->CommandCode) {768 801 switch (pIorb->CommandCode) 802 { 769 803 case IOCC_CONFIGURATION: 770 iocc_configuration( iorb);804 iocc_configuration(vIorb, pIorb); 771 805 break; 772 806 773 807 case IOCC_DEVICE_CONTROL: 774 iocc_device_control( iorb);808 iocc_device_control(vIorb, pIorb); 775 809 break; 776 810 777 811 case IOCC_UNIT_CONTROL: 778 iocc_unit_control( iorb);812 iocc_unit_control(vIorb, pIorb); 779 813 break; 780 814 781 815 case IOCC_GEOMETRY: 782 iocc_geometry( iorb);816 iocc_geometry(vIorb, pIorb); 783 817 break; 784 818 785 819 case IOCC_EXECUTE_IO: 786 iocc_execute_io( iorb);820 iocc_execute_io(vIorb, pIorb); 787 821 break; 788 822 789 823 case IOCC_UNIT_STATUS: 790 iocc_unit_status( iorb);824 iocc_unit_status(vIorb, pIorb); 791 825 break; 792 826 793 827 case IOCC_ADAPTER_PASSTHRU: 794 iocc_adapter_passthru( iorb);828 iocc_adapter_passthru(vIorb, pIorb); 795 829 break; 796 830 797 831 default: 798 832 /* unsupported call */ 799 iorb_seterr( iorb, IOERR_CMD_NOT_SUPPORTED);800 iorb_done( iorb);833 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED); 834 iorb_done(vIorb, pIorb); 801 835 break; 802 836 } … … 809 843 * Handle IOCC_CONFIGURATION requests. 810 844 */ 811 void iocc_configuration(IORBH _far *iorb)845 void iocc_configuration(IORBH FAR16DATA *vIorb, IORBH *pIorb) 812 846 { 813 847 int a; 814 848 815 switch (iorb->CommandModifier) { 849 switch (pIorb->CommandModifier) 850 { 816 851 817 852 case IOCM_COMPLETE_INIT: … … 820 855 * use interrupts, timers and context hooks instead of polling). 821 856 */ 822 if (!init_complete) { 823 dprintf("leaving initialization mode\n"); 824 for (a = 0; a < ad_info_cnt; a++) { 857 if (!init_complete) 858 { 859 DPRINTF(1,"leaving initialization mode\n"); 860 for (a = 0; a < ad_info_cnt; a++) 861 { 825 862 lock_adapter(ad_infos + a); 826 863 ahci_complete_init(ad_infos + a); … … 828 865 init_complete = 1; 829 866 830 /* DAZ turn off COM port output if on */831 //com_base = 0;832 833 867 /* release all adapters */ 834 for (a = 0; a < ad_info_cnt; a++) { 868 for (a = 0; a < ad_info_cnt; a++) 869 { 835 870 unlock_adapter(ad_infos + a); 836 871 } 872 DPRINTF(1,"leaving initialization mode 2\n"); 837 873 838 874 #ifdef LEGACY_APM … … 840 876 apm_init(); 841 877 #endif 842 843 build_user_info(0); 844 } 845 iorb_done(iorb); 878 } 879 iorb_done(vIorb, pIorb); 846 880 break; 847 881 848 882 case IOCM_GET_DEVICE_TABLE: 849 883 /* construct a device table */ 850 iocm_device_table( iorb);884 iocm_device_table(vIorb, pIorb); 851 885 break; 852 886 853 887 default: 854 iorb_seterr( iorb, IOERR_CMD_NOT_SUPPORTED);855 iorb_done( iorb);888 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED); 889 iorb_done(vIorb, pIorb); 856 890 break; 857 891 } … … 861 895 * Handle IOCC_DEVICE_CONTROL requests. 862 896 */ 863 void iocc_device_control(IORBH _far *iorb) 864 { 865 AD_INFO *ai = ad_infos + iorb_unit_adapter(iorb); 866 IORBH _far *ptr; 867 IORBH _far *next = NULL; 868 int p = iorb_unit_port(iorb); 869 int d = iorb_unit_device(iorb); 870 871 switch (iorb->CommandModifier) { 897 void iocc_device_control(IORBH FAR16DATA *vIorb, IORBH *pIorb) 898 { 899 AD_INFO *ai = ad_infos + iorb_unit_adapter(pIorb); 900 IORBH FAR16DATA *vPtr; 901 IORBH FAR16DATA *vNext = NULL; 902 int p = iorb_unit_port(pIorb); 903 int d = iorb_unit_device(pIorb); 904 905 switch (pIorb->CommandModifier) 906 { 872 907 873 908 case IOCM_ABORT: 874 909 /* abort all pending commands on specified port and device */ 875 910 spin_lock(drv_lock); 876 for (ptr = ai->ports[p].iorb_queue.root; ptr != NULL; ptr = next) { 877 next = ptr->pNxtIORB; 911 for (vPtr = ai->ports[p].iorb_queue.vRoot; vPtr != NULL; vPtr = vNext) 912 { 913 IORBH *pPtr = Far16ToFlat(vPtr); 914 915 vNext = pPtr->pNxtIORB; 878 916 /* move all matching IORBs to the abort queue */ 879 if (ptr != iorb && iorb_unit_device(ptr) == d) { 880 iorb_queue_del(&ai->ports[p].iorb_queue, ptr); 881 iorb_queue_add(&abort_queue, ptr); 882 ptr->ErrorCode = IOERR_CMD_ABORTED; 917 if (vPtr != vIorb && iorb_unit_device(pPtr) == d) 918 { 919 iorb_queue_del(&ai->ports[p].iorb_queue, vPtr); 920 iorb_queue_add(&abort_queue, vPtr, pPtr); 921 pPtr->ErrorCode = IOERR_CMD_ABORTED; 883 922 } 884 923 } … … 886 925 887 926 /* trigger reset context hook which will finish the abort processing */ 888 DevHelp_ArmCtxHook(0, reset_ctxhook_h);927 KernArmHook(reset_ctxhook_h, 0, 0); 889 928 break; 890 929 … … 896 935 * and ATAPI in the same driver, this won't be required. 897 936 */ 898 iorb_seterr( iorb, IOERR_CMD_NOT_SUPPORTED);937 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED); 899 938 break; 900 939 … … 904 943 /* unit control commands to lock, unlock and eject media */ 905 944 /* will be supported later... */ 906 iorb_seterr( iorb, IOERR_CMD_NOT_SUPPORTED);945 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED); 907 946 break; 908 947 909 948 default: 910 iorb_seterr( iorb, IOERR_CMD_NOT_SUPPORTED);911 break; 912 } 913 914 iorb_done( iorb);949 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED); 950 break; 951 } 952 953 iorb_done(vIorb, pIorb); 915 954 } 916 955 … … 918 957 * Handle IOCC_UNIT_CONTROL requests. 919 958 */ 920 void iocc_unit_control(IORBH _far *iorb)921 { 922 IORB_UNIT_CONTROL _far *iorb_uc = (IORB_UNIT_CONTROL _far *) iorb;923 int a = iorb_unit_adapter( iorb);924 int p = iorb_unit_port( iorb);925 int d = iorb_unit_device( iorb);959 void iocc_unit_control(IORBH FAR16DATA *vIorb, IORBH *pIorb) 960 { 961 IORB_UNIT_CONTROL *pIorb_uc = (IORB_UNIT_CONTROL *)pIorb; 962 int a = iorb_unit_adapter(pIorb); 963 int p = iorb_unit_port(pIorb); 964 int d = iorb_unit_device(pIorb); 926 965 927 966 spin_lock(drv_lock); 928 switch ( iorb->CommandModifier) {929 967 switch (pIorb->CommandModifier) 968 { 930 969 case IOCM_ALLOCATE_UNIT: 931 970 /* allocate unit for exclusive access */ 932 if (ad_infos[a].ports[p].devs[d].allocated) { 933 iorb_seterr(iorb, IOERR_UNIT_ALLOCATED); 934 } else { 971 if (ad_infos[a].ports[p].devs[d].allocated) 972 { 973 iorb_seterr(pIorb, IOERR_UNIT_ALLOCATED); 974 } 975 else 976 { 935 977 ad_infos[a].ports[p].devs[d].allocated = 1; 936 978 } … … 939 981 case IOCM_DEALLOCATE_UNIT: 940 982 /* deallocate exclusive access to unit */ 941 if (!ad_infos[a].ports[p].devs[d].allocated) { 942 iorb_seterr(iorb, IOERR_UNIT_NOT_ALLOCATED); 943 } else { 983 if (!ad_infos[a].ports[p].devs[d].allocated) 984 { 985 iorb_seterr(pIorb, IOERR_UNIT_NOT_ALLOCATED); 986 } 987 else 988 { 944 989 ad_infos[a].ports[p].devs[d].allocated = 0; 945 990 } … … 954 999 * IOCC_CONFIGURATION/IOCM_GET_DEVICE_TABLE calls. 955 1000 */ 956 if (!ad_infos[a].ports[p].devs[d].allocated) { 957 iorb_seterr(iorb, IOERR_UNIT_NOT_ALLOCATED); 1001 if (!ad_infos[a].ports[p].devs[d].allocated) 1002 { 1003 iorb_seterr(pIorb, IOERR_UNIT_NOT_ALLOCATED); 958 1004 break; 959 1005 } 960 ad_infos[a].ports[p].devs[d].unit_info = iorb_uc->pUnitInfo;1006 ad_infos[a].ports[p].devs[d].unit_info = pIorb_uc->pUnitInfo; 961 1007 break; 962 1008 963 1009 default: 964 iorb_seterr( iorb, IOERR_CMD_NOT_SUPPORTED);1010 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED); 965 1011 break; 966 1012 } 967 1013 968 1014 spin_unlock(drv_lock); 969 iorb_done( iorb);1015 iorb_done(vIorb, pIorb); 970 1016 } 971 1017 … … 993 1039 * 1..n emulated devices; SCSI target ID increments sequentially 994 1040 */ 995 void iocm_device_table(IORBH _far *iorb) 996 { 997 IORB_CONFIGURATION _far *iorb_conf; 998 DEVICETABLE _far *dt; 999 char _far *pos; 1041 void iocm_device_table(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1042 { 1043 IORB_CONFIGURATION *pIorb_conf; 1044 DEVICETABLE FAR16DATA *vDt; 1045 DEVICETABLE *pDt; 1046 char *pPos; 1000 1047 int scsi_units = 0; 1001 1048 int scsi_id = 1; … … 1006 1053 int d; 1007 1054 1008 iorb_conf = (IORB_CONFIGURATION _far *) iorb; 1009 dt = iorb_conf->pDeviceTable; 1055 pIorb_conf = (IORB_CONFIGURATION *)pIorb; 1056 vDt = pIorb_conf->pDeviceTable; 1057 pDt = Far16ToFlat(vDt); 1010 1058 1011 1059 spin_lock(drv_lock); 1012 1060 1013 1061 /* initialize device table header */ 1014 dt->ADDLevelMajor = ADD_LEVEL_MAJOR;1015 dt->ADDLevelMinor = ADD_LEVEL_MINOR;1016 dt->ADDHandle = add_handle;1017 dt->TotalAdapters = ad_info_cnt + 1;1062 pDt->ADDLevelMajor = ADD_LEVEL_MAJOR; 1063 pDt->ADDLevelMinor = ADD_LEVEL_MINOR; 1064 pDt->ADDHandle = add_handle; 1065 pDt->TotalAdapters = ad_info_cnt + 1; 1018 1066 1019 1067 /* set start of adapter and device information tables */ 1020 p os = (char _far *) (dt->pAdapter + dt->TotalAdapters);1068 pPos = (char*)&pDt->pAdapter[pDt->TotalAdapters]; 1021 1069 1022 1070 /* go through all adapters, including the virtual SCSI adapter */ 1023 for (dta = 0; dta < dt->TotalAdapters; dta++) { 1024 ADAPTERINFO _far *ptr = (ADAPTERINFO _far *) pos; 1071 for (dta = 0; dta < pDt->TotalAdapters; dta++) 1072 { 1073 ADAPTERINFO *pPtr = (ADAPTERINFO *)pPos; 1025 1074 1026 1075 /* sanity check for sufficient space in device table */ 1027 if ((u32) (ptr + 1) - (u32) dt > iorb_conf->DeviceTableLen) { 1028 dprintf("error: device table provided by DASD too small\n"); 1029 iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE); 1076 if ((u32)(pPtr + 1) - (u32)pDt > pIorb_conf->DeviceTableLen) 1077 { 1078 DPRINTF(0,"error: device table provided by DASD too small\n"); 1079 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE); 1030 1080 goto iocm_device_table_done; 1031 1081 } 1032 1082 1033 dt->pAdapter[dta] = (ADAPTERINFO _near *) ((u32) ptr & 0xffff); 1034 memset(ptr, 0x00, sizeof(*ptr)); 1035 1036 ptr->AdapterIOAccess = AI_IOACCESS_BUS_MASTER; 1037 ptr->AdapterHostBus = AI_HOSTBUS_OTHER | AI_BUSWIDTH_32BIT; 1038 ptr->AdapterFlags = AF_16M | AF_HW_SCATGAT; 1039 ptr->MaxHWSGList = AHCI_MAX_SG / 2; /* AHCI S/G elements are 22 bits */ 1040 1041 if (dta < ad_info_cnt) { 1083 pDt->pAdapter[dta] = MakeNear16PtrFromDiff(pIorb_conf->pDeviceTable, pDt, pPtr); 1084 1085 //DPRINTF(2,"iocm_device_table: ptr=%x dta=%x pAdapter[dta]=%x pDeviceTable=%x\n", 1086 // ptr, dta, dt->pAdapter[dta], iorb_conf->pDeviceTable); 1087 memset(pPtr, 0x00, sizeof(*pPtr)); 1088 1089 pPtr->AdapterIOAccess = AI_IOACCESS_BUS_MASTER; 1090 pPtr->AdapterHostBus = AI_HOSTBUS_OTHER | AI_BUSWIDTH_32BIT; 1091 pPtr->AdapterFlags = AF_16M | AF_HW_SCATGAT; 1092 pPtr->MaxHWSGList = AHCI_MAX_SG / 2; /* AHCI S/G elements are 22 bits */ 1093 1094 if (dta < ad_info_cnt) 1095 { 1042 1096 /* this is a physical AHCI adapter */ 1043 1097 AD_INFO *ad_info = ad_infos + dta; 1044 1098 1045 ptr->AdapterDevBus = AI_DEVBUS_ST506 | AI_DEVBUS_32BIT; 1046 sprintf(ptr->AdapterName, "AHCI_%d", dta); 1047 1048 if (!ad_info->port_scan_done) { 1099 pPtr->AdapterDevBus = AI_DEVBUS_ST506 | AI_DEVBUS_32BIT; 1100 sprintf(pPtr->AdapterName, "AHCI_%d", dta); 1101 1102 if (!ad_info->port_scan_done) 1103 { 1049 1104 /* first call; need to scan AHCI hardware for devices */ 1050 if (ad_info->busy) { 1051 dprintf("error: port scan requested while adapter was busy\n"); 1052 iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE); 1105 if (ad_info->busy) 1106 { 1107 DPRINTF(0,"error: port scan requested while adapter was busy\n"); 1108 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE); 1053 1109 goto iocm_device_table_done; 1054 1110 } … … 1059 1115 ad_info->busy = 0; 1060 1116 1061 if (rc != 0) { 1062 dprintf("error: port scan failed on adapter #%d\n", dta); 1063 iorb_seterr(iorb, IOERR_CMD_SW_RESOURCE); 1117 if (rc != 0) 1118 { 1119 DPRINTF(0,"error: port scan failed on adapter #%d\n", dta); 1120 iorb_seterr(pIorb, IOERR_CMD_SW_RESOURCE); 1064 1121 goto iocm_device_table_done; 1065 1122 } … … 1068 1125 1069 1126 /* insert physical (i.e. AHCI) devices into the device table */ 1070 for (p = 0; p <= ad_info->port_max; p++) { 1071 for (d = 0; d <= ad_info->ports[p].dev_max; d++) { 1072 if (ad_info->ports[p].devs[d].present) { 1073 if (ad_info->ports[p].devs[d].atapi && emulate_scsi[dta][p]) { 1127 for (p = 0; p <= ad_info->port_max; p++) 1128 { 1129 for (d = 0; d <= ad_info->ports[p].dev_max; d++) 1130 { 1131 if (ad_info->ports[p].devs[d].present) 1132 { 1133 if (ad_info->ports[p].devs[d].atapi && emulate_scsi[dta][p]) 1134 { 1074 1135 /* report this unit as SCSI unit */ 1075 1136 scsi_units++; 1076 1137 //continue; 1077 1138 } 1078 if (add_unit_info(iorb_conf, dta, dta, p, d, 0)) { 1139 if (add_unit_info(pIorb_conf, dta, dta, p, d, 0)) 1140 { 1079 1141 goto iocm_device_table_done; 1080 1142 } … … 1082 1144 } 1083 1145 } 1084 1085 } else { 1146 } 1147 else 1148 { 1086 1149 /* this is the virtual SCSI adapter */ 1087 if (scsi_units == 0) { 1150 if (scsi_units == 0) 1151 { 1088 1152 /* not a single unit to be emulated via SCSI */ 1089 dt->TotalAdapters--;1153 pDt->TotalAdapters--; 1090 1154 break; 1091 1155 } 1092 1156 1093 1157 /* set adapter name and bus type to mimic a SCSI controller */ 1094 p tr->AdapterDevBus = AI_DEVBUS_SCSI_2 | AI_DEVBUS_16BIT;1095 sprintf(p tr->AdapterName, "AHCI_SCSI_0");1158 pPtr->AdapterDevBus = AI_DEVBUS_SCSI_2 | AI_DEVBUS_16BIT; 1159 sprintf(pPtr->AdapterName, "AHCI_SCSI_0"); 1096 1160 1097 1161 /* add all ATAPI units to be emulated by this virtual adaper */ 1098 for (a = 0; a < ad_info_cnt; a++) { 1162 for (a = 0; a < ad_info_cnt; a++) 1163 { 1099 1164 AD_INFO *ad_info = ad_infos + a; 1100 1165 1101 for (p = 0; p <= ad_info->port_max; p++) { 1102 for (d = 0; d <= ad_info->ports[p].dev_max; d++) { 1103 if (ad_info->ports[p].devs[d].present && ad_info->ports[p].devs[d].atapi && emulate_scsi[a][p]) { 1104 if (add_unit_info(iorb_conf, dta, a, p, d, scsi_id++)) { 1166 for (p = 0; p <= ad_info->port_max; p++) 1167 { 1168 for (d = 0; d <= ad_info->ports[p].dev_max; d++) 1169 { 1170 if (ad_info->ports[p].devs[d].present && ad_info->ports[p].devs[d].atapi && emulate_scsi[a][p]) 1171 { 1172 if (add_unit_info(pIorb_conf, dta, a, p, d, scsi_id++)) 1173 { 1105 1174 goto iocm_device_table_done; 1106 1175 } … … 1112 1181 1113 1182 /* calculate offset for next adapter */ 1114 p os = (char _far *) (ptr->UnitInfo + ptr->AdapterUnits);1183 pPos = (char *)(pPtr->UnitInfo + pPtr->AdapterUnits); 1115 1184 } 1116 1185 1117 1186 iocm_device_table_done: 1118 1187 spin_unlock(drv_lock); 1119 iorb_done( iorb);1188 iorb_done(vIorb, pIorb); 1120 1189 } 1121 1190 … … 1123 1192 * Handle IOCC_GEOMETRY requests. 1124 1193 */ 1125 void iocc_geometry(IORBH _far *iorb)1126 { 1127 switch ( iorb->CommandModifier) {1128 1194 void iocc_geometry(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1195 { 1196 switch (pIorb->CommandModifier) 1197 { 1129 1198 case IOCM_GET_MEDIA_GEOMETRY: 1130 1199 case IOCM_GET_DEVICE_GEOMETRY: 1131 add_workspace( iorb)->idempotent = 1;1132 ahci_get_geometry( iorb);1200 add_workspace(pIorb)->idempotent = 1; 1201 ahci_get_geometry(vIorb, pIorb); 1133 1202 break; 1134 1203 1135 1204 default: 1136 iorb_seterr( iorb, IOERR_CMD_NOT_SUPPORTED);1137 iorb_done( iorb);1205 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED); 1206 iorb_done(vIorb, pIorb); 1138 1207 } 1139 1208 } … … 1142 1211 * Handle IOCC_EXECUTE_IO requests. 1143 1212 */ 1144 void iocc_execute_io(IORBH _far *iorb)1145 { 1146 switch ( iorb->CommandModifier) {1147 1213 void iocc_execute_io(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1214 { 1215 switch (pIorb->CommandModifier) 1216 { 1148 1217 case IOCM_READ: 1149 add_workspace( iorb)->idempotent = 1;1150 ahci_read( iorb);1218 add_workspace(pIorb)->idempotent = 1; 1219 ahci_read(vIorb, pIorb); 1151 1220 break; 1152 1221 1153 1222 case IOCM_READ_VERIFY: 1154 add_workspace( iorb)->idempotent = 1;1155 ahci_verify( iorb);1223 add_workspace(pIorb)->idempotent = 1; 1224 ahci_verify(vIorb, pIorb); 1156 1225 break; 1157 1226 1158 1227 case IOCM_WRITE: 1159 add_workspace( iorb)->idempotent = 1;1160 ahci_write( iorb);1228 add_workspace(pIorb)->idempotent = 1; 1229 ahci_write(vIorb, pIorb); 1161 1230 break; 1162 1231 1163 1232 case IOCM_WRITE_VERIFY: 1164 add_workspace( iorb)->idempotent = 1;1165 ahci_write( iorb);1233 add_workspace(pIorb)->idempotent = 1; 1234 ahci_write(vIorb, pIorb); 1166 1235 break; 1167 1236 1168 1237 default: 1169 iorb_seterr( iorb, IOERR_CMD_NOT_SUPPORTED);1170 iorb_done( iorb);1238 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED); 1239 iorb_done(vIorb, pIorb); 1171 1240 } 1172 1241 } … … 1175 1244 * Handle IOCC_UNIT_STATUS requests. 1176 1245 */ 1177 void iocc_unit_status(IORBH _far *iorb)1178 { 1179 switch ( iorb->CommandModifier) {1180 1246 void iocc_unit_status(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1247 { 1248 switch (pIorb->CommandModifier) 1249 { 1181 1250 case IOCM_GET_UNIT_STATUS: 1182 add_workspace( iorb)->idempotent = 1;1183 ahci_unit_ready( iorb);1251 add_workspace(pIorb)->idempotent = 1; 1252 ahci_unit_ready(vIorb, pIorb); 1184 1253 break; 1185 1254 1186 1255 default: 1187 iorb_seterr( iorb, IOERR_CMD_NOT_SUPPORTED);1188 iorb_done( iorb);1256 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED); 1257 iorb_done(vIorb, pIorb); 1189 1258 } 1190 1259 } … … 1193 1262 * Handle IOCC_ADAPTER_PASSTHROUGH requests. 1194 1263 */ 1195 void iocc_adapter_passthru(IORBH _far *iorb) 1196 { 1197 switch (iorb->CommandModifier) { 1264 void iocc_adapter_passthru(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1265 { 1266 switch (pIorb->CommandModifier) 1267 { 1198 1268 1199 1269 case IOCM_EXECUTE_CDB: 1200 add_workspace( iorb)->idempotent = 0;1201 ahci_execute_cdb( iorb);1270 add_workspace(pIorb)->idempotent = 0; 1271 ahci_execute_cdb(vIorb, pIorb); 1202 1272 break; 1203 1273 1204 1274 case IOCM_EXECUTE_ATA: 1205 add_workspace( iorb)->idempotent = 0;1206 ahci_execute_ata( iorb);1275 add_workspace(pIorb)->idempotent = 0; 1276 ahci_execute_ata(vIorb, pIorb); 1207 1277 break; 1208 1278 1209 1279 default: 1210 iorb_seterr( iorb, IOERR_CMD_NOT_SUPPORTED);1211 iorb_done( iorb);1280 iorb_seterr(pIorb, IOERR_CMD_NOT_SUPPORTED); 1281 iorb_done(vIorb, pIorb); 1212 1282 } 1213 1283 } … … 1217 1287 * adapter-level spinlock aquired. 1218 1288 */ 1219 void iorb_queue_add(IORB_QUEUE _far *queue, IORBH _far *iorb) 1220 { 1221 if (iorb_priority(iorb) { 1289 void iorb_queue_add(IORB_QUEUE *queue, IORBH FAR16DATA *vIorb, IORBH *pIorb) 1290 { 1291 if (iorb_priority(pIorb) 1292 { 1222 1293 /* priority IORB; insert at first position */ 1223 iorb->pNxtIORB = queue->root; 1224 queue->root = iorb; 1225 1226 } else { 1294 pIorb->pNxtIORB = queue->vRoot; 1295 queue->vRoot = vIorb; 1296 } 1297 else 1298 { 1227 1299 /* append IORB to end of queue */ 1228 iorb->pNxtIORB = NULL; 1229 1230 if (queue->root == NULL) { 1231 queue->root = iorb; 1232 } else { 1233 queue->tail->pNxtIORB = iorb; 1234 } 1235 queue->tail = iorb; 1236 } 1237 1238 if (debug) { 1300 pIorb->pNxtIORB = NULL; 1301 1302 if (queue->vRoot == NULL) 1303 { 1304 queue->vRoot = vIorb; 1305 } 1306 else 1307 { 1308 ((IORBH *)Far16ToFlat(queue->vTail))->pNxtIORB = vIorb; 1309 } 1310 queue->vTail = vIorb; 1311 } 1312 1313 if (D32g_DbgLevel) 1314 { 1239 1315 /* determine queue type (local, driver, abort or port) and minimum debug 1240 1316 * level; otherwise, queue debug prints can become really confusing. … … 1243 1319 int min_debug = 1; 1244 1320 1245 if ((u32) queue >> 16 == (u32) (void _far *) &queue >> 16) { 1321 if ((u32)queue >> 16 == (u32)&queue >> 16) /* DAZ this is bogus */ 1322 { 1246 1323 /* this queue is on the stack */ 1247 1324 queue_type = "local"; 1248 1325 min_debug = 2; 1249 1326 1250 } else if (queue == &driver_queue) { 1327 } 1328 else if (queue == &driver_queue) 1329 { 1251 1330 queue_type = "driver"; 1252 1331 1253 } else if (queue == &abort_queue) { 1332 } 1333 else if (queue == &abort_queue) 1334 { 1254 1335 queue_type = "abort"; 1255 1336 min_debug = 2; 1256 1337 1257 } else { 1338 } 1339 else 1340 { 1258 1341 queue_type = "port"; 1259 1342 } 1260 1343 1261 if (debug > min_debug) { 1262 aprintf("IORB %Fp queued (cmd = %d/%d, queue = %Fp [%s], timeout = %ld)\n", 1263 iorb, iorb->CommandCode, iorb->CommandModifier, queue, queue_type, 1264 iorb->Timeout); 1265 } 1344 DPRINTF(min_debug,"IORB %x queued (cmd=%d/%d queue=%x [%s], timeout=%d)\n", 1345 vIorb, pIorb->CommandCode, pIorb->CommandModifier, queue, queue_type, 1346 pIorb->Timeout); 1266 1347 } 1267 1348 } … … 1271 1352 * the adapter-level spinlock aquired. 1272 1353 */ 1273 int iorb_queue_del(IORB_QUEUE _far *queue, IORBH _far *iorb)1274 { 1275 IORBH _far *_iorb;1276 IORBH _far *_prev = NULL;1354 int iorb_queue_del(IORB_QUEUE *queue, IORBH FAR16DATA *vIorb) 1355 { 1356 IORBH FAR16DATA *_vIorb; 1357 IORBH FAR16DATA *_vPrev = NULL; 1277 1358 int found = 0; 1278 1359 1279 for (_iorb = queue->root; _iorb != NULL; _iorb = _iorb->pNxtIORB) { 1280 if (_iorb == iorb) { 1360 for (_vIorb = queue->vRoot; _vIorb != NULL; ) 1361 { 1362 IORBH *_pIorb = Far16ToFlat(_vIorb); 1363 if (_vIorb == vIorb) 1364 { 1365 1281 1366 /* found the IORB to be removed */ 1282 if (_prev != NULL) { 1283 _prev->pNxtIORB = _iorb->pNxtIORB; 1284 } else { 1285 queue->root = _iorb->pNxtIORB; 1286 } 1287 if (_iorb == queue->tail) { 1288 queue->tail = _prev; 1367 if (_vPrev != NULL) 1368 { 1369 ((IORBH*)Far16ToFlat(_vPrev))->pNxtIORB = _pIorb->pNxtIORB; 1370 } 1371 else 1372 { 1373 queue->vRoot = _pIorb->pNxtIORB; 1374 } 1375 if (_vIorb == queue->vTail) 1376 { 1377 queue->vTail = _vPrev; 1289 1378 } 1290 1379 found = 1; 1291 1380 break; 1292 1381 } 1293 _prev = _iorb; 1294 } 1295 1296 if (found) { 1297 ddprintf("IORB %Fp removed (queue = %Fp)\n", iorb, queue); 1298 } else { 1299 dprintf("IORB %Fp not found in queue %Fp\n", iorb, queue); 1382 _vPrev = _vIorb; 1383 _vIorb = _pIorb->pNxtIORB; 1384 } 1385 1386 if (found) 1387 { 1388 DPRINTF(3,"IORB %x removed (queue = %x)\n", vIorb, queue); 1389 } 1390 else 1391 { 1392 DPRINTF(2,"IORB %x not found in queue %x\n", vIorb, queue); 1300 1393 } 1301 1394 … … 1309 1402 * status to the specified error code. 1310 1403 */ 1311 void iorb_seterr(IORBH _far *iorb, USHORT error_code)1312 { 1313 iorb->ErrorCode = error_code;1314 iorb->Status |= IORB_ERROR;1404 void iorb_seterr(IORBH *pIorb, USHORT error_code) 1405 { 1406 pIorb->ErrorCode = error_code; 1407 pIorb->Status |= IORB_ERROR; 1315 1408 } 1316 1409 … … 1333 1426 * See abort_ctxhook() for an example. 1334 1427 */ 1335 void iorb_done(IORBH _far *iorb)1336 { 1337 int a = iorb_unit_adapter( iorb);1338 int p = iorb_unit_port( iorb);1428 void iorb_done(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1429 { 1430 int a = iorb_unit_adapter(pIorb); 1431 int p = iorb_unit_port(pIorb); 1339 1432 1340 1433 /* remove IORB from corresponding queue */ 1341 1434 spin_lock(drv_lock); 1342 if (iorb_driver_level(iorb)) { 1343 iorb_queue_del(&driver_queue, iorb); 1344 } else { 1345 iorb_queue_del(&ad_infos[a].ports[p].iorb_queue, iorb); 1346 } 1347 aws_free(add_workspace(iorb)); 1435 if (iorb_driver_level(pIorb)) 1436 { 1437 iorb_queue_del(&driver_queue, vIorb); 1438 } 1439 else 1440 { 1441 iorb_queue_del(&ad_infos[a].ports[p].iorb_queue, vIorb); 1442 } 1443 aws_free(add_workspace(pIorb)); 1348 1444 spin_unlock(drv_lock); 1349 1445 1350 iorb_complete( iorb);1446 iorb_complete(vIorb, pIorb); 1351 1447 } 1352 1448 … … 1358 1454 * the next request to us before even returning from this function. 1359 1455 */ 1360 void iorb_complete(IORBH _far *iorb) 1361 { 1362 iorb->Status |= IORB_DONE; 1363 1364 ddprintf("IORB %Fp complete (status = 0x%04x, error = 0x%04x)\n", 1365 iorb, iorb->Status, iorb->ErrorCode); 1366 1367 if (iorb->RequestControl & IORB_ASYNC_POST) { 1368 iorb->NotifyAddress(iorb); 1456 void iorb_complete(IORBH FAR16DATA *vIorb, IORBH *pIorb) 1457 { 1458 pIorb->Status |= IORB_DONE; 1459 1460 DPRINTF(1,"IORB %x complete status=0x%04x error=0x%04x\n", 1461 vIorb, pIorb->Status, pIorb->ErrorCode); 1462 1463 if (pIorb->RequestControl & IORB_ASYNC_POST) 1464 { 1465 Dev32Help_CallFar16((PFNFAR16)pIorb->NotifyAddress, vIorb); 1369 1466 } 1370 1467 } … … 1379 1476 * - no_ncq 1380 1477 */ 1381 void iorb_requeue(IORBH _far *iorb)1382 { 1383 ADD_WORKSPACE _far *aws = add_workspace(iorb);1478 void iorb_requeue(IORBH *pIorb) 1479 { 1480 ADD_WORKSPACE *aws = add_workspace(pIorb); 1384 1481 u16 no_ncq = aws->no_ncq; 1385 1482 u16 unaligned = aws->unaligned; … … 1398 1495 * be called with the spinlock held to prevent race conditions. 1399 1496 */ 1400 void aws_free(ADD_WORKSPACE _far *aws) 1401 { 1402 if (aws->timer != 0) { 1403 ADD_CancelTimer(aws->timer); 1497 void aws_free(ADD_WORKSPACE *aws) 1498 { 1499 if (aws->timer != 0) 1500 { 1501 Timer_CancelTimer(aws->timer); 1404 1502 aws->timer = 0; 1405 1503 } 1406 1504 1407 if (aws->buf != NULL) { 1408 free(aws->buf); 1505 if (aws->buf != NULL) 1506 { 1507 MemFree(aws->buf); 1409 1508 aws->buf = NULL; 1410 1509 } … … 1421 1520 1422 1521 spin_lock(drv_lock); 1423 while (ai->busy) { 1522 while (ai->busy) 1523 { 1424 1524 spin_unlock(drv_lock); 1425 timer_init(&Timer, 250);1426 while (! timer_check_and_block(&Timer));1525 TimerInit(&Timer, 250); 1526 while (!TimerCheckAndBlock(&Timer)); 1427 1527 spin_lock(drv_lock); 1428 1528 } … … 1444 1544 * separate function which is invoked via a context hook. 1445 1545 */ 1446 void _cdecl _far timeout_callback(ULONG timer_handle, ULONG p1, ULONG p2) 1447 { 1448 IORBH _far *iorb = (IORBH _far *) p1; 1449 int a = iorb_unit_adapter(iorb); 1450 int p = iorb_unit_port(iorb); 1451 1452 ADD_CancelTimer(timer_handle); 1453 dprintf("timeout for IORB %Fp\n", iorb); 1546 void __syscall timeout_callback(ULONG timer_handle, ULONG p1) 1547 { 1548 IORBH FAR16DATA *vIorb = (IORBH FAR16DATA *)CastULONGToFar16(p1); 1549 IORBH *pIorb = Far16ToFlat(vIorb); 1550 int a = iorb_unit_adapter(pIorb); 1551 int p = iorb_unit_port(pIorb); 1552 1553 Timer_CancelTimer(timer_handle); 1554 DPRINTF(0,"timeout for IORB %x\n", vIorb); 1454 1555 1455 1556 /* Move the timed-out IORB to the abort queue. Since it's possible that the … … 1460 1561 */ 1461 1562 spin_lock(drv_lock); 1462 if (iorb_queue_del(&ad_infos[a].ports[p].iorb_queue, iorb) == 0) { 1463 iorb_queue_add(&abort_queue, iorb); 1464 iorb->ErrorCode = IOERR_ADAPTER_TIMEOUT; 1563 if (iorb_queue_del(&ad_infos[a].ports[p].iorb_queue, vIorb) == 0) 1564 { 1565 iorb_queue_add(&abort_queue, vIorb, pIorb); 1566 pIorb->ErrorCode = IOERR_ADAPTER_TIMEOUT; 1465 1567 } 1466 1568 spin_unlock(drv_lock); … … 1477 1579 * will process our IORB as well. 1478 1580 */ 1479 DevHelp_ArmCtxHook(0, reset_ctxhook_h);1581 KernArmHook(reset_ctxhook_h, 0, 0); 1480 1582 1481 1583 /* Set up a watchdog timer which calls the context hook manually in case … … 1485 1587 * does in the early boot phase. 1486 1588 */ 1487 ADD_StartTimerMS(&th_reset_watchdog, 5000, (PFN) reset_watchdog, 0, 0);1589 Timer_StartTimerMS(&th_reset_watchdog, 5000, reset_watchdog, 0); 1488 1590 } 1489 1591 … … 1499 1601 * problems during the early boot phase. 1500 1602 */ 1501 void _ cdecl _far reset_watchdog(ULONG timer_handle, ULONG p1, ULONG p2)1603 void __syscall reset_watchdog(ULONG timer_handle, ULONG p1) 1502 1604 { 1503 1605 /* reset watchdog timer */ 1504 ADD_CancelTimer(timer_handle);1505 dprintf("reset watchdog invoked\n");1606 Timer_CancelTimer(timer_handle); 1607 DPRINTF(0,"reset watchdog invoked\n"); 1506 1608 1507 1609 /* call context hook manually */ 1508 1610 reset_ctxhook(0); 1509 }1510 1511 /******************************************************************************1512 * small_code_ - this dummy func resolves the undefined reference linker1513 * error that occurrs when linking WATCOM objects with DDK's link.exe1514 */1515 void _cdecl small_code_(void)1516 {1517 1611 } 1518 1612 … … 1528 1622 * index of the virtual SCSI adapter. 1529 1623 */ 1530 static int add_unit_info(IORB_CONFIGURATION _far *iorb_conf, int dta,1624 static int add_unit_info(IORB_CONFIGURATION *pIorb_conf, int dta, 1531 1625 int a, int p, int d, int scsi_id) 1532 1626 { 1533 DEVICETABLE _far *dt = iorb_conf->pDeviceTable; 1534 ADAPTERINFO _far *ptr = (ADAPTERINFO _far *) (((u32) dt & 0xffff0000U) + 1535 (u16) dt->pAdapter[dta]); 1536 UNITINFO _far *ui = ptr->UnitInfo + ptr->AdapterUnits; 1627 DEVICETABLE *pDt = Far16ToFlat(pIorb_conf->pDeviceTable); 1628 ADAPTERINFO *pPtr; 1629 UNITINFO *pUi; 1537 1630 AD_INFO *ai = ad_infos + a; 1538 1631 1539 if ((u32) (ui + 1) - (u32) dt > iorb_conf->DeviceTableLen) { 1540 dprintf("error: device table provided by DASD too small\n"); 1541 iorb_seterr(&iorb_conf->iorbh, IOERR_CMD_SW_RESOURCE); 1632 pPtr = (ADAPTERINFO *)MakeFlatFromNear16(pIorb_conf->pDeviceTable, pDt->pAdapter[dta]); 1633 //DPRINTF(2,"add_unit_info: ptr=%x dta=%x pAdapter[dta]=%x pDeviceTable=%x\n", 1634 // ptr, dta, dt->pAdapter[dta], iorb_conf->pDeviceTable); 1635 1636 pUi = &pPtr->UnitInfo[pPtr->AdapterUnits]; 1637 1638 if ((u32)(pUi + 1) - (u32)pDt > pIorb_conf->DeviceTableLen) 1639 { 1640 DPRINTF(0,"error: device table provided by DASD too small\n"); 1641 iorb_seterr(&pIorb_conf->iorbh, IOERR_CMD_SW_RESOURCE); 1542 1642 return(-1); 1543 1643 } 1544 1644 1545 if (ai->ports[p].devs[d].unit_info == NULL) { 1645 if (ai->ports[p].devs[d].unit_info == NULL) 1646 { 1546 1647 /* provide original information about this device (unit) */ 1547 memset(ui, 0x00, sizeof(*ui)); 1548 ui->AdapterIndex = dta; /* device table adapter index */ 1549 ui->UnitHandle = iorb_unit(a, p, d); /* physical adapter index */ 1550 ui->UnitIndex = ptr->AdapterUnits; 1551 ui->UnitType = ai->ports[p].devs[d].dev_type; 1552 ui->QueuingCount = ai->ports[p].devs[d].ncq_max;; 1553 if (ai->ports[p].devs[d].removable) { 1554 ui->UnitFlags |= UF_REMOVABLE; 1648 memset(pUi, 0x00, sizeof(*pUi)); 1649 pUi->AdapterIndex = dta; /* device table adapter index */ 1650 pUi->UnitHandle = iorb_unit(a, p, d); /* physical adapter index */ 1651 pUi->UnitIndex = pPtr->AdapterUnits; 1652 pUi->UnitType = ai->ports[p].devs[d].dev_type; 1653 pUi->QueuingCount = ai->ports[p].devs[d].ncq_max; 1654 if (ai->ports[p].devs[d].removable) 1655 { 1656 pUi->UnitFlags |= UF_REMOVABLE; 1555 1657 } 1556 1658 if (scsi_id > 0) { 1557 1659 /* set fake SCSI ID for this unit */ 1558 ui->UnitSCSITargetID = scsi_id; 1559 } 1560 } else { 1660 pUi->UnitSCSITargetID = scsi_id; 1661 } 1662 } 1663 else 1664 { 1561 1665 /* copy updated device (unit) information (IOCM_CHANGE_UNITINFO) */ 1562 memcpy( ui, ai->ports[p].devs[d].unit_info, sizeof(*ui));1563 } 1564 1565 p tr->AdapterUnits++;1666 memcpy(pUi, ai->ports[p].devs[d].unit_info, sizeof(*pUi)); 1667 } 1668 1669 pPtr->AdapterUnits++; 1566 1670 return(0); 1567 1671 } 1568 1672 1569 /*******************************************************************************1570 * Register kernel exit handler for trap dumps. Our exit handler will be called1571 * right before the kernel starts a dump; that's where we reset the controller1572 * so it supports BIOS int13 I/O calls.1573 */1574 static void register_krnl_exit(void)1575 {1576 _asm {1577 push ds1578 push es1579 push bx1580 push si1581 push di1582 1583 mov ax, FLAG_KRNL_EXIT_ADD1584 mov cx, TYPE_KRNL_EXIT_INT131585 mov bx, SEG asm_krnl_exit1586 mov si, OFFSET asm_krnl_exit1587 mov dl, DevHlp_RegisterKrnlExit1588 1589 call dword ptr [Device_Help]1590 1591 pop di1592 pop si1593 pop bx1594 pop es1595 pop ds1596 }1597 1598 dprintf("Registered kernel exit routine for INT13 mode\n");1599 }1600
Note:
See TracChangeset
for help on using the changeset viewer.