Ignore:
Timestamp:
Nov 29, 2016, 5:30:22 AM (9 years ago)
Author:
David Azarewicz
Message:

Major reorganization

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/os2ahci/ctxhook.c

    r161 r178  
    44 * Copyright (c) 2011 thi.guten Software Development
    55 * Copyright (c) 2011 Mensys B.V.
     6 * Copyright (c) 2013-2016 David Azarewicz
    67 *
    78 * Authors: Christian Mueller, Markus Thielen
     
    8788 * in the interrupt and error handlers.
    8889 */
    89 void restart_ctxhook(ULONG parm)
     90void _Syscall restart_ctxhook(ULONG parm)
    9091{
    9192  IORB_QUEUE done_queue;
    9293  AD_INFO *ai;
    93   IORBH _far *problem_iorb;
    94   IORBH _far *iorb;
    95   IORBH _far *next = NULL;
    96   u8 _far *port_mmio;
     94  IORBH FAR16DATA *vProblemIorb;
     95  IORBH FAR16DATA *vIorb;
     96  IORBH FAR16DATA *vNext = NULL;
     97  u8 *port_mmio;
    9798  int rearm_ctx_hook = 0;
    9899  int need_reset;
     
    101102  int p;
    102103
    103   dprintf("restart_ctxhook() started\n");
     104  DPRINTF(2,"restart_ctxhook() started\n");
    104105  memset(&done_queue, 0x00, sizeof(done_queue));
    105106
    106107  spin_lock(drv_lock);
    107108
    108   for (a = 0; a < ad_info_cnt; a++) {
     109  for (a = 0; a < ad_info_cnt; a++)
     110  {
    109111    ai = ad_infos + a;
    110112
    111     if (ai->busy) {
     113    if (ai->busy)
     114    {
    112115      /* this adapter is busy; leave it alone for now */
    113116      rearm_ctx_hook = 1;
     
    115118    }
    116119
    117     for (p = 0; p <= ai->port_max; p++) {
    118       if (ports_to_restart[a] & (1UL << p)) {
     120    for (p = 0; p <= ai->port_max; p++)
     121    {
     122      if (ports_to_restart[a] & (1UL << p))
     123      {
    119124        ports_to_restart[a] &= ~(1UL << p);
    120125
    121126        /* restart this port */
    122127        port_mmio = port_base(ai, p);
    123         problem_iorb = NULL;
     128        vProblemIorb = NULL;
    124129        need_reset = 0;
    125130
    126         dprintf("port %d, TF_DATA: 0x%lx\n", p, readl(port_mmio + PORT_TFDATA));
     131        DPRINTF(2,"port %d, TF_DATA: 0x%x\n", p, readl(port_mmio + PORT_TFDATA));
    127132
    128133        /* get "current command slot"; only valid if there are no NCQ cmds */
    129134        ccs = (int) ((readl(port_mmio + PORT_CMD) >> 8) & 0x1f);
    130         ddprintf(" PORT_CMD      = 0x%x\n", ccs);
    131 
    132         for (iorb = ai->ports[p].iorb_queue.root; iorb != NULL; iorb = next) {
    133           ADD_WORKSPACE _far *aws = add_workspace(iorb);
    134           next = iorb->pNxtIORB;
    135 
    136           if (aws->queued_hw) {
    137             if (ai->ports[p].ncq_cmds & (1UL << aws->cmd_slot)) {
     135        DPRINTF(3," PORT_CMD      = 0x%x\n", ccs);
     136
     137        for (vIorb = ai->ports[p].iorb_queue.vRoot; vIorb != NULL; vIorb = vNext)
     138        {
     139          IORBH *pIorb = Far16ToFlat(vIorb);
     140          ADD_WORKSPACE *aws = add_workspace(pIorb);
     141          vNext = pIorb->pNxtIORB;
     142
     143          if (aws->queued_hw)
     144          {
     145            if (ai->ports[p].ncq_cmds & (1UL << aws->cmd_slot))
     146            {
    138147              /* NCQ command; force non-NCQ mode and trigger port reset */
    139148              ai->ports[p].ncq_cmds &= ~(1UL << aws->cmd_slot);
    140149              aws->no_ncq = 1;
    141150              need_reset = 1;
    142             } else {
     151            }
     152            else
     153            {
    143154              /* regular command; clear cmd bit and identify problem IORB */
    144155              ai->ports[p].reg_cmds &= ~(1UL << aws->cmd_slot);
    145               if (aws->cmd_slot == ccs) {
     156              if (aws->cmd_slot == ccs)
     157              {
    146158                /* this is the non-NCQ command that failed */
    147                 ddprintf("failing IORB: %Fp\n", iorb);
    148                 problem_iorb = iorb;
     159                DPRINTF(0,"failing IORB: %x\n", vIorb);
     160                vProblemIorb = vIorb;
    149161              }
    150162            }
    151163            /* we can requeue all IORBs unconditionally (see function comment) */
    152             if (aws->retries++ < MAX_RETRIES) {
    153               iorb_requeue(iorb);
    154 
    155             } else {
     164            if (aws->retries++ < MAX_RETRIES)
     165            {
     166              iorb_requeue(pIorb);
     167            }
     168            else
     169            {
    156170              /* retry count exceeded; consider IORB aborted */
    157               iorb_seterr(iorb, IOERR_CMD_ABORTED);
    158               iorb_queue_del(&ai->ports[p].iorb_queue, iorb);
    159               iorb_queue_add(&done_queue, iorb);
    160               if (iorb == problem_iorb) {
     171              iorb_seterr(pIorb, IOERR_CMD_ABORTED);
     172              iorb_queue_del(&ai->ports[p].iorb_queue, vIorb);
     173              iorb_queue_add(&done_queue, vIorb, pIorb);
     174              if (vIorb == vProblemIorb)
     175              {
    161176                /* no further analysis -- we're done with this one */
    162                 problem_iorb = NULL;
     177                vProblemIorb = NULL;
    163178              }
    164179            }
     
    167182
    168183        /* sanity check: issued command bitmaps should be 0 now */
    169         if (ai->ports[p].ncq_cmds != 0 || ai->ports[p].reg_cmds != 0) {
    170           dprintf("warning: commands issued not 0 (%08lx/%08lx); resetting...\n",
     184        if (ai->ports[p].ncq_cmds != 0 || ai->ports[p].reg_cmds != 0)
     185        {
     186          DPRINTF(0,"warning: commands issued not 0 (%08lx/%08lx); resetting...\n",
    171187                  ai->ports[p].ncq_cmds, ai->ports[p].reg_cmds);
    172188          need_reset = 1;
    173189        }
    174190
    175         if (!need_reset) {
    176           if ((readl(port_mmio + PORT_TFDATA) & 0x88) != 0) {
     191        if (!need_reset)
     192        {
     193          if ((readl(port_mmio + PORT_TFDATA) & 0x88) != 0)
     194          {
    177195            /* device is not in an idle state */
    178196            need_reset = 1;
     
    183201        ai->busy = 1;
    184202        spin_unlock(drv_lock);
    185         if (need_reset) {
     203        if (need_reset)
     204        {
    186205          ahci_reset_port(ai, p, 1);
    187         } else {
     206        }
     207        else
     208        {
    188209          ahci_stop_port(ai, p);
    189210          ahci_start_port(ai, p, 1);
     
    197218        ai->ports[p].cmd_slot = 0;
    198219
    199         if (problem_iorb != NULL) {
     220        if (vProblemIorb != NULL)
     221        {
     222          IORBH *pProblemIorb = Far16ToFlat(vProblemIorb);
    200223          /* get details about the error that caused this IORB to fail */
    201           if (need_reset) {
     224          if (need_reset)
     225          {
    202226            /* no way to retrieve error details after a reset */
    203             iorb_seterr(problem_iorb, IOERR_DEVICE_NONSPECIFIC);
    204             iorb_queue_del(&ai->ports[p].iorb_queue, problem_iorb);
    205             iorb_queue_add(&done_queue, problem_iorb);
    206 
    207           } else {
     227            iorb_seterr(pProblemIorb, IOERR_DEVICE_NONSPECIFIC);
     228            iorb_queue_del(&ai->ports[p].iorb_queue, vProblemIorb);
     229            iorb_queue_add(&done_queue, vProblemIorb, pProblemIorb);
     230
     231          }
     232          else
     233          {
    208234            /* get sense information */
    209             ADD_WORKSPACE _far *aws = add_workspace(problem_iorb);
    210             int d = iorb_unit_device(problem_iorb);
    211             int (*req_sense)(IORBH _far *, int) = (ai->ports[p].devs[d].atapi) ?
     235            ADD_WORKSPACE *aws = add_workspace(pProblemIorb);
     236            int d = iorb_unit_device(pProblemIorb);
     237            int (*req_sense)(IORBH FAR16DATA *, IORBH *, int) = (ai->ports[p].devs[d].atapi) ?
    212238                                                   atapi_req_sense : ata_req_sense;
    213239
     
    215241            aws->queued_hw = 1;
    216242
    217             if (req_sense(problem_iorb, 0) == 0) {
     243            if (req_sense(vProblemIorb, pProblemIorb, 0) == 0)
     244            {
    218245              /* execute request sense on slot #0 before anything else comes along */
    219               ADD_StartTimerMS(&aws->timer, 5000, (PFN) timeout_callback,
    220                                problem_iorb, 0);
     246              Timer_StartTimerMS(&aws->timer, 5000, timeout_callback, CastFar16ToULONG(vProblemIorb));
    221247              aws->cmd_slot = 0;
    222248              ai->ports[p].reg_cmds = 1;
     
    224250              readl(port_mmio); /* flush */
    225251
    226             } else {
     252            }
     253            else
     254            {
    227255              /* IORB is expected to contain the error code; just move to done queue */
    228               iorb_queue_del(&ai->ports[p].iorb_queue, problem_iorb);
    229               iorb_queue_add(&done_queue, problem_iorb);
     256              iorb_queue_del(&ai->ports[p].iorb_queue, vProblemIorb);
     257              iorb_queue_add(&done_queue, vProblemIorb, pProblemIorb);
    230258            }
    231259          }
     
    238266
    239267  /* call notification routine on all IORBs which have completed */
    240   for (iorb = done_queue.root; iorb != NULL; iorb = next) {
    241     next = iorb->pNxtIORB;
     268  for (vIorb = done_queue.vRoot; vIorb != NULL; vIorb = vNext)
     269  {
     270    IORBH *pIorb = Far16ToFlat(vIorb);
     271    vNext = pIorb->pNxtIORB;
    242272
    243273    spin_lock(drv_lock);
    244     aws_free(add_workspace(iorb));
     274    aws_free(add_workspace(pIorb));
    245275    spin_unlock(drv_lock);
    246276
    247     iorb_complete(iorb);
     277    iorb_complete(vIorb, pIorb);
    248278  }
    249279
     
    253283  spin_unlock(drv_lock);
    254284
    255   dprintf("restart_ctxhook() completed\n");
     285  DPRINTF(2,"restart_ctxhook() completed\n");
    256286
    257287  /* Check whether we have to rearm ourselves because some adapters were busy
    258288   * when we wanted to restart ports on them.
    259289   */
    260   if (rearm_ctx_hook) {
     290  if (rearm_ctx_hook)
     291  {
    261292    msleep(250);
    262     DevHelp_ArmCtxHook(0, restart_ctxhook_h);
     293    KernArmHook(restart_ctxhook_h, 0, 0);
    263294  }
    264295}
     
    290321 * the upstream code might reuse the IORBs before we're done with them.
    291322 */
    292 void reset_ctxhook(ULONG parm)
     323void _Syscall reset_ctxhook(ULONG parm)
    293324{
    294325  IORB_QUEUE done_queue;
    295326  AD_INFO *ai;
    296   IORBH _far *iorb;
    297   IORBH _far *next = NULL;
     327  IORBH FAR16DATA *vIorb;
     328  IORBH FAR16DATA *vNext = NULL;
    298329  int rearm_ctx_hook = 0;
    299330  int a;
    300331  int p;
    301332
    302   dprintf("reset_ctxhook() started\n");
     333  DPRINTF(2,"reset_ctxhook() started\n");
    303334  memset(&done_queue, 0x00, sizeof(done_queue));
    304335
    305336  spin_lock(drv_lock);
    306337
    307   if (th_reset_watchdog != 0) {
     338  if (th_reset_watchdog != 0)
     339  {
    308340    /* watchdog timer still active -- just reset it */
    309     ADD_CancelTimer(th_reset_watchdog);
     341    Timer_CancelTimer(th_reset_watchdog);
    310342    th_reset_watchdog = 0;
    311343  }
    312344
    313345  /* add ports of active IORBs from the abort queue to ports_to_reset[] */
    314   for (iorb = abort_queue.root; iorb != NULL; iorb = next) {
    315     next = iorb->pNxtIORB;
    316     a = iorb_unit_adapter(iorb);
    317     p = iorb_unit_port(iorb);
     346  for (vIorb = abort_queue.vRoot; vIorb != NULL; vIorb = vNext)
     347  {
     348    IORBH *pIorb = Far16ToFlat(vIorb);
     349    vNext = pIorb->pNxtIORB;
     350    a = iorb_unit_adapter(pIorb);
     351    p = iorb_unit_port(pIorb);
    318352    ai = ad_infos + a;
    319353
    320     if (ai->busy) {
     354    if (ai->busy)
     355    {
    321356      /* this adapter is busy; leave it alone for now */
    322357      rearm_ctx_hook = 1;
     
    325360
    326361    /* move IORB to the local 'done' queue */
    327     iorb_queue_del(&abort_queue, iorb);
    328     iorb_queue_add(&done_queue, iorb);
     362    iorb_queue_del(&abort_queue, vIorb);
     363    iorb_queue_add(&done_queue, vIorb, pIorb);
    329364
    330365    /* reset port if the IORB has already been queued to hardware */
    331     if (add_workspace(iorb)->queued_hw) {
     366    if (add_workspace(pIorb)->queued_hw)
     367    {
    332368      /* prepare port reset */
    333369      ports_to_reset[a] |= (1UL << p);
     
    336372
    337373  /* reset all ports in 'ports_to_reset[]' */
    338   for (a = 0; a < ad_info_cnt; a++) {
     374  for (a = 0; a < ad_info_cnt; a++)
     375  {
    339376    ai = ad_infos + a;
    340377
    341     if (ai->busy) {
     378    if (ai->busy)
     379    {
    342380      /* this adapter is busy; leave it alone for now */
    343381      rearm_ctx_hook = 1;
     
    345383    }
    346384
    347     for (p = 0; p <= ai->port_max; p++) {
    348       if (ports_to_reset[a] & (1UL << p)) {
     385    for (p = 0; p <= ai->port_max; p++)
     386    {
     387      if (ports_to_reset[a] & (1UL << p))
     388      {
    349389        ports_to_reset[a] &= ~(1UL << p);
    350390
     
    366406
    367407        /* retry or abort all remaining active commands on this port */
    368         for (iorb = ai->ports[p].iorb_queue.root; iorb != NULL; iorb = next) {
    369           ADD_WORKSPACE _far *aws = add_workspace(iorb);
    370           next = iorb->pNxtIORB;
    371 
    372           if (aws->queued_hw) {
     408        for (vIorb = ai->ports[p].iorb_queue.vRoot; vIorb != NULL; vIorb = vNext)
     409        {
     410          IORBH *pIorb = Far16ToFlat(vIorb);
     411          ADD_WORKSPACE *aws = add_workspace(pIorb);
     412          vNext = pIorb->pNxtIORB;
     413
     414          if (aws->queued_hw)
     415          {
    373416            /* this IORB had already been queued to HW when we reset the port */
    374             if (aws->idempotent && aws->retries++ < MAX_RETRIES) {
     417            if (aws->idempotent && aws->retries++ < MAX_RETRIES)
     418            {
    375419              /* we can retry this IORB */
    376               iorb_requeue(iorb);
    377 
    378             } else {
     420              iorb_requeue(pIorb);
     421
     422            }
     423            else
     424            {
    379425              /* we cannot retry this IORB; consider it aborted */
    380               iorb->ErrorCode = IOERR_CMD_ABORTED;
    381               iorb_queue_del(&ai->ports[p].iorb_queue, iorb);
    382               iorb_queue_add(&done_queue, iorb);
     426              pIorb->ErrorCode = IOERR_CMD_ABORTED;
     427              iorb_queue_del(&ai->ports[p].iorb_queue, vIorb);
     428              iorb_queue_add(&done_queue, vIorb, pIorb);
    383429            }
    384430          }
     
    391437
    392438  /* complete all aborted IORBs */
    393   for (iorb = done_queue.root; iorb != NULL; iorb = next) {
    394     next = iorb->pNxtIORB;
     439  for (vIorb = done_queue.vRoot; vIorb != NULL; vIorb = vNext)
     440  {
     441    IORBH *pIorb = Far16ToFlat(vIorb);
     442    vNext = pIorb->pNxtIORB;
    395443
    396444    spin_lock(drv_lock);
    397     aws_free(add_workspace(iorb));
     445    aws_free(add_workspace(pIorb));
    398446    spin_unlock(drv_lock);
    399447
    400     iorb->Status |= IORB_ERROR;
    401     iorb_complete(iorb);
     448    pIorb->Status |= IORB_ERROR;
     449    iorb_complete(vIorb, pIorb);
    402450  }
    403451
     
    407455  spin_unlock(drv_lock);
    408456
    409   dprintf("reset_ctxhook() completed\n");
     457  DPRINTF(2,"reset_ctxhook() completed\n");
    410458
    411459  /* Check whether we have to rearm ourselves because some adapters were busy
    412460   * when we wanted to reset ports on them.
    413461   */
    414   if (rearm_ctx_hook) {
     462  if (rearm_ctx_hook)
     463  {
    415464    msleep(250);
    416     DevHelp_ArmCtxHook(0, reset_ctxhook_h);
     465    KernArmHook(reset_ctxhook_h, 0, 0);
    417466  }
    418467}
     
    424473 * busy system. Either way, this requires some task-time help.
    425474 */
    426 void engine_ctxhook(ULONG parm)
     475void _Syscall engine_ctxhook(ULONG parm)
    427476{
    428477  int iorbs_sent;
    429478  int i;
    430479
    431   dprintf("engine_ctxhook() started\n");
    432   if (resume_sleep_flag) {
     480  DPRINTF(2,"engine_ctxhook() started\n");
     481  if (resume_sleep_flag)
     482  {
    433483    msleep(resume_sleep_flag);
    434484    resume_sleep_flag = 0;
     
    436486
    437487  spin_lock(drv_lock);
    438   for (i = 0; i < 10; i++) {
    439     if ((iorbs_sent = trigger_engine_1()) == 0) {
    440       break;
    441     }
     488  for (i = 0; i < 10; i++)
     489  {
     490    if ((iorbs_sent = trigger_engine_1()) == 0) break;
    442491  }
    443492  spin_unlock(drv_lock);
    444493
    445   dprintf("engine_ctxhook() completed\n");
    446 
    447   if (iorbs_sent != 0) {
     494  DPRINTF(2,"engine_ctxhook() completed\n");
     495
     496  if (iorbs_sent != 0)
     497  {
    448498    /* need to rearm ourselves for another run */
    449499    msleep(250);
    450     DevHelp_ArmCtxHook(0, engine_ctxhook_h);
     500    KernArmHook(engine_ctxhook_h, 0, 0);
    451501  }
    452502}
Note: See TracChangeset for help on using the changeset viewer.