Ignore:
Timestamp:
May 31, 2013, 2:03:41 AM (12 years ago)
Author:
David Azarewicz
Message:

fixed trap dump kernel exit, some work on suspend/resume routines

File:
1 edited

Legend:

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

    r157 r160  
    7777    if (evt->ulParm2 >> 16 != APM_PWRSTATEREADY) {
    7878      /* we're suspending */
    79       apm_suspend();
     79      suspend();
    8080    }
    8181    break;
     
    8484  case APM_CRITRESUMEEVENT:
    8585    /* we're resuming */
    86     apm_resume();
     86    resume();
    8787    break;
    8888
     
    9696
    9797/******************************************************************************
    98  * APM suspend handler. In a nutshell, it'll turn of interrupts and flush all
     98 * Suspend handler. In a nutshell, it'll turn off interrupts and flush all
    9999 * write caches.
    100100 */
    101 void apm_suspend(void)
     101void suspend(void)
    102102{
    103103  int a;
     
    107107
    108108  if (suspended) return;
    109   dprintf("apm_suspend()\n");
     109  dprintf("suspend()\n");
    110110
    111111  /* restart all ports with interrupts disabled */
     
    132132      }
    133133    }
     134
     135    /* AHCI spec rev1.1 section 8.3.3:
     136     * Software must disable interrupts prior to requesting a transition of the HBA to D3 state.
     137     */
     138    writel(ai->mmio + HOST_CTL, readl(ai->mmio + HOST_CTL) & ~HOST_IRQ_EN);
     139    readl(ai->mmio + HOST_CTL); /* flush */
    134140  }
    135141
     
    137143  init_complete = 0;
    138144
     145#if 0
    139146  /* restore BIOS configuration for each adapter and release the adapter */
    140147  for (a = 0; a < ad_info_cnt; a++) {
    141148    ahci_restore_bios_config(ad_infos + a);
    142     unlock_adapter(ad_infos + a);
    143   }
     149  }
     150#endif
     151
     152  /* TODO: put the device into the D3 state */
    144153
    145154  suspended = 1;
    146   dprintf("apm_suspend() finished\n");
    147 }
    148 
    149 /******************************************************************************
    150  * APM resume handler. All ports are restarted with interrupts enabled using
     155  dprintf("suspend() finished\n");
     156}
     157
     158/******************************************************************************
     159 * Resume handler. All ports are restarted with interrupts enabled using
    151160 * the same function as the IOCM_COMPLETE_INIT handler does.
    152161 */
    153 void apm_resume(void)
     162void resume(void)
    154163{
    155164  int a;
    156165
    157166  if (!suspended) return;
    158   dprintf("apm_resume()\n");
     167  dprintf("resume()\n");
     168
     169  /* TODO: put the device into the D0 state */
    159170
    160171  for (a = 0; a < ad_info_cnt; a++) {
     
    165176     * done to get the adapter and its ports up and running.
    166177     */
    167     lock_adapter(ai);
    168178    ahci_complete_init(ai);
    169179  }
     
    178188
    179189  suspended = 0;
    180   dprintf("apm_resume() finished\n");
    181 }
     190  dprintf("resume() finished\n");
     191}
     192
     193/******************************************************************************
     194 * This is the kernel exit handler for panics and traps.
     195 * Assume the system is trashed and do the absolute minimum necessary
     196 * to put the adapters into a state so that the BIOS can operate the
     197 * adapters. We never need to recover from this as the system will be rebooted.
     198 */
     199void shutdown_driver(void)
     200{
     201  int a;
     202  int p;
     203  u16 i;
     204  u32 tmp;
     205  //int d;
     206
     207  dprintf("shutdown_driver() enter\n");
     208
     209  for (a = 0; a < ad_info_cnt; a++) {
     210    AD_INFO *ai = ad_infos + a;
     211
     212    /* Try to be nice. Wait 50ms for adapter to go not busy.
     213     * If it doesn't go not busy in that time, too bad. Stop it anyway.
     214     */
     215    for (i=0; i<50000 && ai->busy; i++) udelay(1000);
     216
     217    for (p = 0; p <= ai->port_max; p++) {
     218      u8 _far *port_mmio = port_base(ai, p);
     219
     220      /* Wait up to 50ms for port to go not busy. Again stop it
     221       * anyway if it doesn't go not busy in that time.
     222       */
     223      for (i=0; i<50000 && ahci_port_busy(ai, p); i++) udelay(1000);
     224
     225      /* stop port */
     226      writel(port_mmio + PORT_IRQ_MASK, 0); /* disable port interrupts */
     227      writel(port_mmio + PORT_CMD, readl(port_mmio + PORT_CMD) & ~PORT_CMD_FIS_RX); /* disable FIS reception */
     228      while (readl(port_mmio + PORT_CMD) & PORT_CMD_FIS_ON); /* wait for it to stop */
     229      writel(port_mmio + PORT_CMD, readl(port_mmio + PORT_CMD) & ~PORT_CMD_START); /* set port to idle */
     230      while (readl(port_mmio + PORT_CMD) & PORT_CMD_LIST_ON); /* wait for it to stop */
     231
     232      /* clear any pending port IRQs */
     233      tmp = readl(port_mmio + PORT_IRQ_STAT);
     234      if (tmp) writel(port_mmio + PORT_IRQ_STAT, tmp);
     235      writel(ai->mmio + HOST_IRQ_STAT, 1UL << p);
     236
     237      /* reset PxSACT register (tagged command queues, not reset by COMRESET) */
     238      writel(port_mmio + PORT_SCR_ACT, 0);
     239      readl(port_mmio + PORT_SCR_ACT);  /* flush */
     240
     241      #if 0
     242      ahci_start_port(ai, p, 0);
     243
     244      /* flush cache on all attached devices */
     245      for (d = 0; d <= ai->ports[p].dev_max; d++) {
     246        if (ai->ports[p].devs[d].present) {
     247          ahci_flush_cache(ai, p, d);
     248        }
     249      }
     250      #endif
     251    }
     252  }
     253
     254  init_complete = 0;
     255
     256  /* restore BIOS configuration for each adapter */
     257  for (a = 0; a < ad_info_cnt; a++) {
     258    ahci_restore_bios_config(ad_infos + a);
     259  }
     260
     261  dprintf("shutdown_driver() finished\n");
     262}
     263
Note: See TracChangeset for help on using the changeset viewer.