Changeset 211 for trunk/src/os2ahci/ctxhook.c
- Timestamp:
- Jul 24, 2023, 5:51:46 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/ctxhook.c
r209 r211 4 4 * Copyright (c) 2011 thi.guten Software Development 5 5 * Copyright (c) 2011 Mensys B.V. 6 * Copyright (c) 2013-202 1David Azarewicz <david@88watts.net>6 * Copyright (c) 2013-2023 David Azarewicz <david@88watts.net> 7 7 * 8 8 * Authors: Christian Mueller, Markus Thielen … … 31 31 32 32 /* port restart context hook and input data */ 33 ULONG restart_ctxhook_h;33 ULONG RestartCtxHook_h; 34 34 volatile u32 ports_to_restart[MAX_AD]; 35 35 36 36 /* port reset context hook and input data */ 37 ULONG reset_ctxhook_h;38 ULONG th_ reset_watchdog;37 ULONG ResetCtxHook_h; 38 ULONG th_watchdog; 39 39 volatile u32 ports_to_reset[MAX_AD]; 40 40 IORB_QUEUE abort_queue; … … 42 42 /* trigger engine context hook and input data */ 43 43 ULONG engine_ctxhook_h; 44 45 #define QUEUEDEPTH 8 46 static struct _ctxq_ 47 { 48 ULONG ulHandle; 49 ULONG ulArg; 50 } CtxQueue[QUEUEDEPTH] = {0}; 51 static ULONG ulCtxStatusFlag = 0; 52 53 void SafeArmCtxHook(ULONG ulHandle, ULONG armData) 54 { 55 USHORT i; 56 57 i = LockInc(&ulCtxStatusFlag); 58 59 if (i) 60 { 61 i--; 62 if (i < QUEUEDEPTH) 63 { 64 CtxQueue[i].ulHandle = ulHandle; 65 CtxQueue[i].ulArg = armData; 66 } 67 } 68 else 69 { 70 KernArmHook(ulHandle, armData, 0); 71 } 72 } 73 74 void ClearThreadStatus(ULONG ulHandle) 75 { 76 USHORT i; 77 78 i = LockDec(&ulCtxStatusFlag); 79 80 if (i) 81 { 82 i--; 83 if (i < QUEUEDEPTH) 84 { 85 KernArmHook(CtxQueue[i].ulHandle, CtxQueue[i].ulArg, 0); 86 } 87 else 88 { 89 KernArmHook(ulHandle, 0, 0); 90 } 91 } 92 } 44 93 45 94 /****************************************************************************** … … 78 127 * in the interrupt and error handlers. 79 128 */ 80 void _Syscall restart_ctxhook(ULONG parm)129 void _Syscall RestartCtxHook(ULONG parm) 81 130 { 82 131 IORB_QUEUE done_queue; … … 85 134 IORBH FAR16DATA *vIorb; 86 135 IORBH FAR16DATA *vNext; 136 IORBH *pIorb; 137 ADD_WORKSPACE *aws; 87 138 u8 *port_mmio; 88 139 int rearm_ctx_hook; … … 97 148 rearm_ctx_hook = 0; 98 149 99 DPRINTF(DBG_FUNCBEG, DBG_PREFIX": restart_ctxhook() started\n"); 150 AhciStats.ulSoftErrorCount++; 151 DPRINTF(0, DBG_PREFIX": BEG\n"); 100 152 memset(&done_queue, 0x00, sizeof(done_queue)); 101 153 102 154 spin_lock(drv_lock); 155 156 if (th_watchdog != 0) 157 { 158 /* watchdog timer still active -- just reset it */ 159 Timer_CancelTimer(th_watchdog); 160 th_watchdog = 0; 161 } 103 162 104 163 for (a = 0; a < ad_info_cnt; a++) … … 124 183 need_reset = 0; 125 184 126 DPRINTF(DBG_DETAILED, DBG_PREFIX": port %d, TF_DATA:0x%x\n", p, readl(port_mmio + PORT_TFDATA));185 DPRINTF(DBG_DETAILED, DBG_PREFIX": port=%d TF_DATA=0x%x\n", p, readl(port_mmio + PORT_TFDATA)); 127 186 128 187 /* get "current command slot"; only valid if there are no NCQ cmds */ 129 188 ccs = (int) ((readl(port_mmio + PORT_CMD) >> 8) & 0x1f); 130 DPRINTF(DBG_DETAILED, DBG_PREFIX": PORT_CMD =0x%x\n", ccs);189 DPRINTF(DBG_DETAILED, DBG_PREFIX": PORT_CMD=0x%x\n", ccs); 131 190 132 191 for (vIorb = ai->ports[p].iorb_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext) 133 192 { 134 IORBH *pIorb = Far16ToFlat(vIorb);135 ADD_WORKSPACE *aws = add_workspace(pIorb);193 pIorb = Far16ToFlat(vIorb); 194 aws = add_workspace(pIorb); 136 195 vNext = pIorb->f16NxtIORB; 137 196 138 197 if (aws->queued_hw) 139 198 { 199 if (aws->timer != 0) 200 { 201 Timer_CancelTimer(aws->timer); 202 aws->timer = 0; 203 } 204 140 205 if (ai->ports[p].ncq_cmds & (1UL << aws->cmd_slot)) 141 206 { … … 144 209 aws->no_ncq = 1; 145 210 need_reset = 1; 211 DPRINTF(0, DBG_PREFIX": failing IORB: %x NCQ slot=%x\n", vIorb, aws->cmd_slot); 212 #ifdef DEBUG 213 DumpIorb(pIorb, vIorb); 214 #endif 146 215 } 147 216 else … … 152 221 { 153 222 /* this is the non-NCQ command that failed */ 154 DPRINTF(0, DBG_PREFIX": failing IORB: %x\n", vIorb); 223 DPRINTF(0, DBG_PREFIX": failing IORB: %x slot=%x\n", vIorb, aws->cmd_slot); 224 #ifdef DEBUG 225 DumpIorb(pIorb, vIorb); 226 #endif 155 227 vProblemIorb = vIorb; 156 228 } … … 179 251 if (ai->ports[p].ncq_cmds != 0 || ai->ports[p].reg_cmds != 0) 180 252 { 181 DPRINTF(0, DBG_PREFIX": warning: commands issued not 0 (%08 lx/%08lx); resetting...\n",253 DPRINTF(0, DBG_PREFIX": warning: commands issued not 0 (%08x/%08x); resetting...\n", 182 254 ai->ports[p].ncq_cmds, ai->ports[p].reg_cmds); 183 255 need_reset = 1; … … 260 332 spin_unlock(drv_lock); 261 333 334 DPRINTF(0, DBG_PREFIX": Resuming\n"); 262 335 /* call notification routine on all IORBs which have completed */ 263 336 for (vIorb = done_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext) 264 337 { 265 IORBH *pIorb = Far16ToFlat(vIorb);338 pIorb = Far16ToFlat(vIorb); 266 339 vNext = pIorb->f16NxtIORB; 267 340 … … 278 351 spin_unlock(drv_lock); 279 352 280 DPRINTF( DBG_FUNCEND, DBG_PREFIX": restart_ctxhook() completed\n");353 DPRINTF(0, DBG_PREFIX": END Rearm=%x\n", rearm_ctx_hook); 281 354 282 355 /* Check whether we have to rearm ourselves because some adapters were busy … … 285 358 if (rearm_ctx_hook) 286 359 { 287 msleep(250); 288 KernArmHook(restart_ctxhook_h, 0, 0); 289 } 360 /* we cannot rearm ourself because we will execute immediately leaving 361 * no time to process and clear the reason we need to rearm. Therefore 362 * we set the timer again. 363 */ 364 Timer_StartTimerMS(&th_watchdog, 250, WatchdogTimer, RestartCtxHook_h); 365 } 366 367 ClearThreadStatus(RestartCtxHook_h); 290 368 KernThunkStackTo16(); 291 369 } … … 317 395 * the upstream code might reuse the IORBs before we're done with them. 318 396 */ 319 void _Syscall reset_ctxhook(ULONG parm)397 void _Syscall ResetCtxHook(ULONG ulArg) 320 398 { 321 399 IORB_QUEUE done_queue; … … 323 401 IORBH FAR16DATA *vIorb; 324 402 IORBH FAR16DATA *vNext; 403 IORBH *pIorb; 404 ADD_WORKSPACE *aws; 325 405 int rearm_ctx_hook; 326 406 int a; … … 332 412 rearm_ctx_hook = 0; 333 413 334 DPRINTF(DBG_FUNCBEG, DBG_PREFIX": reset_ctxhook() started\n"); 414 AhciStats.ulHardErrorCount++; 415 DPRINTF(0, DBG_PREFIX": BEG Arg=%x\n", ulArg); 335 416 memset(&done_queue, 0x00, sizeof(done_queue)); 336 417 418 if (th_watchdog != 0) 419 { 420 /* watchdog timer still active -- just reset it */ 421 Timer_CancelTimer(th_watchdog); 422 th_watchdog = 0; 423 } 424 337 425 spin_lock(drv_lock); 338 426 339 if (th_reset_watchdog != 0) 340 { 341 /* watchdog timer still active -- just reset it */ 342 Timer_CancelTimer(th_reset_watchdog); 343 th_reset_watchdog = 0; 427 if (ulArg) 428 { 429 /* Move the timed-out IORB to the abort queue. Since it's possible that the 430 * IORB has completed after the timeout has expired but before we got to 431 * this line of code, we'll check the return code of iorb_queue_del(): If it 432 * returns an error, the IORB must have completed a few microseconds ago and 433 * there is no timeout. 434 */ 435 vIorb = (IORBH FAR16DATA *)CastULONGToFar16(ulArg); 436 pIorb = Far16ToFlat(vIorb); 437 a = iorb_unit_adapter(pIorb); 438 p = iorb_unit_port(pIorb); 439 if (iorb_queue_del(&ad_infos[a].ports[p].iorb_queue, vIorb) == 0) 440 { 441 pIorb = Far16ToFlat(vIorb); 442 iorb_queue_add(&abort_queue, vIorb, pIorb); 443 pIorb->ErrorCode = IOERR_ADAPTER_TIMEOUT; 444 } 344 445 } 345 446 … … 347 448 for (vIorb = abort_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext) 348 449 { 349 IORBH *pIorb = Far16ToFlat(vIorb);450 pIorb = Far16ToFlat(vIorb); 350 451 vNext = pIorb->f16NxtIORB; 351 452 a = iorb_unit_adapter(pIorb); 352 453 p = iorb_unit_port(pIorb); 353 454 ai = ad_infos + a; 455 aws = add_workspace(pIorb); 354 456 355 457 if (ai->busy) … … 365 467 366 468 /* reset port if the IORB has already been queued to hardware */ 367 if (add_workspace(pIorb)->queued_hw) 368 { 469 if (aws->queued_hw) 470 { 471 if (aws->timer != 0) 472 { 473 Timer_CancelTimer(aws->timer); 474 aws->timer = 0; 475 } 476 369 477 /* prepare port reset */ 370 478 ports_to_reset[a] |= (1UL << p); … … 411 519 { 412 520 IORBH *pIorb = Far16ToFlat(vIorb); 413 ADD_WORKSPACE *aws = add_workspace(pIorb);414 521 vNext = pIorb->f16NxtIORB; 522 523 aws = add_workspace(pIorb); 415 524 416 525 if (aws->queued_hw) … … 421 530 /* we can retry this IORB */ 422 531 iorb_requeue(pIorb); 423 424 532 } 425 533 else … … 438 546 spin_unlock(drv_lock); 439 547 548 DPRINTF(0, DBG_PREFIX": Resuming\n"); 549 440 550 /* complete all aborted IORBs */ 441 551 for (vIorb = done_queue.vRoot; vIorb != FAR16NULL; vIorb = vNext) 442 552 { 443 IORBH *pIorb = Far16ToFlat(vIorb);553 pIorb = Far16ToFlat(vIorb); 444 554 vNext = pIorb->f16NxtIORB; 445 555 … … 457 567 spin_unlock(drv_lock); 458 568 459 DPRINTF( DBG_FUNCEND, DBG_PREFIX": reset_ctxhook() completed\n");569 DPRINTF(0, DBG_PREFIX": END Rearm=%x\n", rearm_ctx_hook); 460 570 461 571 /* Check whether we have to rearm ourselves because some adapters were busy … … 468 578 * we set the timer again. 469 579 */ 470 //msleep(250); 471 //KernArmHook(reset_ctxhook_h, 0, 0); 472 Timer_StartTimerMS(&th_reset_watchdog, 250, reset_watchdog, 0); 473 } 474 580 Timer_StartTimerMS(&th_watchdog, 250, WatchdogTimer, ResetCtxHook_h); 581 } 582 583 ClearThreadStatus(ResetCtxHook_h); 475 584 KernThunkStackTo16(); 476 585 }
Note:
See TracChangeset
for help on using the changeset viewer.