Changeset 69 for trunk/src/os2ahci/os2ahci.c
- Timestamp:
- Jan 7, 2011, 4:54:46 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/os2ahci.c
r67 r69 107 107 break; 108 108 109 case CMDShutdown: 110 rc = exit_drv(((RPSAVERESTORE _far *) req)->FuncCode); 111 break; 112 109 113 default: 110 114 rc = STDON | STATUS_ERR_UNKCMD; … … 284 288 cprintf(exit_msg); 285 289 return(STDON | ERROR_I24_QUIET_INIT_FAIL); 290 } 291 292 /****************************************************************************** 293 * Device driver exit handler. This handler is called when OS/2 shuts down and 294 * flushes the write caches of all attached devices. 295 * 296 * NOTE: Errors are ignored because there's no way we could stop the shutdown 297 * or do something about the error, unless retrying endlessly is 298 * considered an option. 299 */ 300 USHORT exit_drv(int func) 301 { 302 int a; 303 int p; 304 int d; 305 306 dprintf("exit_drv(%d) called\n", func); 307 308 if (func == 0) { 309 /* we're only interested in the second phase of the shutdown */ 310 return(STDON); 311 } 312 313 for (a = 0; a < ad_info_cnt; a++) { 314 AD_INFO *ai = ad_infos + a; 315 316 for (p = 0; p <= ai->port_max; p++) { 317 for (d = 0; d <= ai->ports[p].dev_max; d++) { 318 if (ai->ports[p].devs[d].present) { 319 ahci_flush_cache(ai, p, d); 320 } 321 } 322 } 323 } 324 325 return(STDON); 286 326 } 287 327 … … 1035 1075 1036 1076 /****************************************************************************** 1077 * Timeout handler for I/O commands. Since timeout handling can involve 1078 * lengthy operations like port resets, the main code is located in a 1079 * separate function which is invoked via a context hook. 1080 */ 1081 void _cdecl _far timeout_callback(ULONG timer_handle, ULONG p1, 1082 ULONG p2) 1083 { 1084 IORBH _far *iorb = (IORBH _far *) p1; 1085 int a = iorb_unit_adapter(iorb); 1086 int p = iorb_unit_port(iorb); 1087 1088 ADD_CancelTimer(timer_handle); 1089 dprintf("timeout for IORB %Fp\n", iorb); 1090 1091 /* Move the timed-out IORB to the abort queue. Since it's possible that the 1092 * IORB has completed after the timeout has expired but before we got to 1093 * this line of code, we'll check the return code of iorb_queue_del(): If it 1094 * returns an error, the IORB must have completed a few microseconds ago and 1095 * there is no timeout. 1096 */ 1097 spin_lock(drv_lock); 1098 if (iorb_queue_del(&ad_infos[a].ports[p].iorb_queue, iorb) == 0) { 1099 iorb_queue_add(&abort_queue, iorb); 1100 iorb->ErrorCode = IOERR_ADAPTER_TIMEOUT; 1101 } 1102 spin_unlock(drv_lock); 1103 1104 /* Trigger abort processing function. We don't really care whether this 1105 * succeeds because the only reason why it would fail should be multiple 1106 * calls to DevHelp_ArmCtxHook() before the context hook had a chance to 1107 * start executing, which leaves two scenarios: 1108 * 1109 * - We succeded in arming the context hook. Fine. 1110 * 1111 * - We armed the context hook a second time before it had a chance to 1112 * start executing. In this case, the already scheduled context hook 1113 * will process our IORB as well. 1114 */ 1115 DevHelp_ArmCtxHook(0, reset_ctxhook_h); 1116 } 1117 1118 /****************************************************************************** 1037 1119 * small_code_ - this dummy func resolves the undefined reference linker 1038 1120 * error that occurrs when linking WATCOM objects with DDK's link.exe
Note:
See TracChangeset
for help on using the changeset viewer.