Changeset 161 for trunk


Ignore:
Timestamp:
May 31, 2013, 11:15:02 PM (12 years ago)
Author:
David Azarewicz
Message:

Suspend/resume changes

Location:
trunk/src/os2ahci
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/os2ahci/README

    r160 r161  
    386386  Removed unused IDC entry point.
    387387  Some work on suspend/resume routines.
     388  Suspend/resume is only supported on eCS systems with ACPI.
    388389
    389390v.1.27 23-Apr-2013 - David Azarewicz
  • trunk/src/os2ahci/ahci.c

    r160 r161  
    122122};
    123123
     124void ahci_dump_host_regs(AD_INFO *ai, int bios_regs)
     125{
     126  #ifdef DEBUG
     127  int i;
     128  u32 version;
     129
     130  aprintf("AHCI global controller registers:\n");
     131  for (i = 0; i <= HOST_CAP2; i += sizeof(u32)) {
     132    u32 val;
     133
     134    if (bios_regs) val = ai->bios_config[i/sizeof(u32)];
     135    else
     136    {
     137      /* HOST_CAP2 only exists for AHCI V1.2 and later */
     138      if ((i == HOST_CAP2) && (version < 0x00010200L)) val = 0;
     139      else val = readl(ai->mmio + i);
     140    }
     141    if (i == HOST_VERSION) version = val;
     142
     143    ntprintf(" %02x: %08lx", i, val);
     144
     145    if (i == HOST_CAP) {
     146      ntprintf(" -");
     147      if (val & HOST_CAP_64)         ntprintf(" 64bit");
     148      if (val & HOST_CAP_NCQ)        ntprintf(" ncq");
     149      if (val & HOST_CAP_SNTF)       ntprintf(" sntf");
     150      if (val & HOST_CAP_MPS)        ntprintf(" mps");
     151      if (val & HOST_CAP_SSS)        ntprintf(" sss");
     152      if (val & HOST_CAP_ALPM)       ntprintf(" alpm");
     153      if (val & HOST_CAP_LED)        ntprintf(" led");
     154      if (val & HOST_CAP_CLO)        ntprintf(" clo");
     155      if (val & HOST_CAP_ONLY)       ntprintf(" ahci_only");
     156      if (val & HOST_CAP_PMP)        ntprintf(" pmp");
     157      if (val & HOST_CAP_FBS)        ntprintf(" fbs");
     158      if (val & HOST_CAP_PIO_MULTI)  ntprintf(" pio_multi");
     159      if (val & HOST_CAP_SSC)        ntprintf(" ssc");
     160      if (val & HOST_CAP_PART)       ntprintf(" part");
     161      if (val & HOST_CAP_CCC)        ntprintf(" ccc");
     162      if (val & HOST_CAP_EMS)        ntprintf(" ems");
     163      if (val & HOST_CAP_SXS)        ntprintf(" sxs");
     164      ntprintf(" cmd_slots:%d", (u16) ((val >> 8) & 0x1f) + 1);
     165      ntprintf(" ports:%d",     (u16) (val & 0x1f) + 1);
     166    } else if (i == HOST_CTL) {
     167      ntprintf(" -");
     168      if (val & HOST_AHCI_EN)        ntprintf(" ahci_enabled");
     169      if (val & HOST_IRQ_EN)         ntprintf(" irq_enabled");
     170      if (val & HOST_RESET)          ntprintf(" resetting");
     171    } else if (i == HOST_CAP2) {
     172      ntprintf(" -");
     173      if (val & HOST_CAP2_BOH)       ntprintf(" boh");
     174      if (val & HOST_CAP2_NVMHCI)    ntprintf(" nvmhci");
     175      if (val & HOST_CAP2_APST)      ntprintf(" apst");
     176    }
     177    ntprintf("\n");
     178  }
     179  #endif
     180}
     181
     182void ahci_dump_port_regs(AD_INFO *ai, int p)
     183{
     184  #ifdef DEBUG
     185  u8 _far *port_mmio = port_base(ai, p);
     186
     187  aprintf("AHCI port %d registers:\n", p);
     188  ntprintf(" PORT_CMD       = 0x%lx\n", readl(port_mmio + PORT_CMD));
     189  ntprintf("command engine status:\n");
     190  ntprintf(" PORT_SCR_ACT   = 0x%lx\n", readl(port_mmio + PORT_SCR_ACT));
     191  ntprintf(" PORT_CMD_ISSUE = 0x%lx\n", readl(port_mmio + PORT_CMD_ISSUE));
     192  ntprintf("link/device status:\n");
     193  ntprintf(" PORT_SCR_STAT  = 0x%lx\n", readl(port_mmio + PORT_SCR_STAT));
     194  ntprintf(" PORT_SCR_CTL   = 0x%lx\n", readl(port_mmio + PORT_SCR_CTL));
     195  ntprintf(" PORT_SCR_ERR   = 0x%lx\n", readl(port_mmio + PORT_SCR_ERR));
     196  ntprintf(" PORT_TFDATA    = 0x%lx\n", readl(port_mmio + PORT_TFDATA));
     197  ntprintf("interrupt status:\n");
     198  ntprintf(" PORT_IRQ_STAT  = 0x%lx\n", readl(port_mmio + PORT_IRQ_STAT));
     199  ntprintf(" PORT_IRQ_MASK  = 0x%lx\n", readl(port_mmio + PORT_IRQ_MASK));
     200  ntprintf(" HOST_IRQ_STAT  = 0x%lx\n", readl(ai->mmio + HOST_IRQ_STAT));
     201  #endif
     202}
     203
    124204/******************************************************************************
    125205 * Save BIOS configuration of AHCI adapter. As a side effect, this also saves
     
    143223
    144224  ddprintf("ahci_save_bios_config: BIOS AHCI mode is %d\n", ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN);
     225
     226  /* HOST_CAP2 only exists for AHCI V1.2 and later */
     227  if (ai->bios_config[HOST_VERSION / sizeof(u32)] >= 0x00010200L) {
     228    ai->bios_config[HOST_CAP2 / sizeof(u32)] = readl(ai->mmio + HOST_CAP2);
     229  } else {
     230    ai->bios_config[HOST_CAP2 / sizeof(u32)] = 0;
     231  }
    145232
    146233#if 0
     
    154241#endif
    155242
    156   /* HOST_CAP2 only exists for AHCI V1.2 and later */
    157   if (ai->bios_config[HOST_VERSION / sizeof(u32)] >= 0x00010200L) {
    158     ai->bios_config[HOST_CAP2 / sizeof(u32)] = readl(ai->mmio + HOST_CAP2);
    159   } else {
    160     ai->bios_config[HOST_CAP2 / sizeof(u32)] = 0;
    161   }
    162 
     243  #ifdef DEBUG
    163244  /* print AHCI register debug information */
    164   #ifdef DEBUG
    165   if (debug) {
    166     aprintf("AHCI global controller registers:\n");
    167     for (i = 0; i <= HOST_CAP2 / sizeof(u32); i++) {
    168       u32 val = ai->bios_config[i];
    169       aprintf(" %02x: %08lx", i, val);
    170 
    171       if (i == HOST_CAP) {
    172         ntprintf(" -");
    173         if (val & HOST_CAP_64)         ntprintf(" 64bit");
    174         if (val & HOST_CAP_NCQ)        ntprintf(" ncq");
    175         if (val & HOST_CAP_SNTF)       ntprintf(" sntf");
    176         if (val & HOST_CAP_MPS)        ntprintf(" mps");
    177         if (val & HOST_CAP_SSS)        ntprintf(" sss");
    178         if (val & HOST_CAP_ALPM)       ntprintf(" alpm");
    179         if (val & HOST_CAP_LED)        ntprintf(" led");
    180         if (val & HOST_CAP_CLO)        ntprintf(" clo");
    181         if (val & HOST_CAP_ONLY)       ntprintf(" ahci_only");
    182         if (val & HOST_CAP_PMP)        ntprintf(" pmp");
    183         if (val & HOST_CAP_FBS)        ntprintf(" fbs");
    184         if (val & HOST_CAP_PIO_MULTI)  ntprintf(" pio_multi");
    185         if (val & HOST_CAP_SSC)        ntprintf(" ssc");
    186         if (val & HOST_CAP_PART)       ntprintf(" part");
    187         if (val & HOST_CAP_CCC)        ntprintf(" ccc");
    188         if (val & HOST_CAP_EMS)        ntprintf(" ems");
    189         if (val & HOST_CAP_SXS)        ntprintf(" sxs");
    190         ntprintf(" cmd_slots:%d", (u16) ((val >> 8) & 0x1f) + 1);
    191         ntprintf(" ports:%d",     (u16) (val & 0x1f) + 1);
    192 
    193       } else if (i == HOST_CTL) {
    194         ntprintf(" -");
    195         if (val & HOST_AHCI_EN)        ntprintf(" ahci_enabled");
    196         if (val & HOST_IRQ_EN)         ntprintf(" irq_enabled");
    197         if (val & HOST_RESET)          ntprintf(" resetting");
    198 
    199       } else if (i == HOST_CAP2) {
    200         ntprintf(" -");
    201         if (val & HOST_CAP2_BOH)       ntprintf(" boh");
    202         if (val & HOST_CAP2_NVMHCI)    ntprintf(" nvmhci");
    203         if (val & HOST_CAP2_APST)      ntprintf(" apst");
    204       }
    205       ntprintf("\n");
    206     }
    207   }
     245  if (debug) ahci_dump_host_regs(ai, 1);
    208246  #endif
    209247
     
    353391
    354392  /* restore saved BIOS configuration */
    355   writel(ai->mmio + HOST_CCC,       ai->bios_config[HOST_CCC / sizeof(u32)]);
    356   writel(ai->mmio + HOST_CCC_PORTS, ai->bios_config[HOST_CCC_PORTS / sizeof(u32)]);
    357   writel(ai->mmio + HOST_EM_CTL,    ai->bios_config[HOST_EM_CTL / sizeof(u32)]);
    358   writel(ai->mmio + HOST_CTL,       ai->bios_config[HOST_CTL / sizeof(u32)]);
     393  //writel(ai->mmio + HOST_CCC,       ai->bios_config[HOST_CCC / sizeof(u32)]);
     394  //writel(ai->mmio + HOST_CCC_PORTS, ai->bios_config[HOST_CCC_PORTS / sizeof(u32)]);
     395  //writel(ai->mmio + HOST_EM_CTL,    ai->bios_config[HOST_EM_CTL / sizeof(u32)]);
     396  //writel(ai->mmio + HOST_CTL,       ai->bios_config[HOST_CTL / sizeof(u32)]);
     397
     398  writel(ai->mmio + HOST_CAP, ai->bios_config[HOST_CAP / sizeof(u32)]);
     399  if (ai->bios_config[HOST_CAP2 / sizeof(u32)])
     400    writel(ai->mmio + HOST_CAP2, ai->bios_config[HOST_CAP2 / sizeof(u32)]);
     401  writel(ai->mmio + HOST_PORTS_IMPL, ai->bios_config[HOST_PORTS_IMPL / sizeof(u32)]);
    359402
    360403  /* flush PCI MMIO delayed write buffers */
    361   readl(ai->mmio + HOST_CTL);
    362 
    363   /* (re-)enable AHCI mode */
    364   ahci_enable_ahci(ai);
     404  readl(ai->mmio + HOST_PORTS_IMPL);
    365405
    366406  return(0);
     407}
     408
     409int ahci_reset_controller(AD_INFO *ai)
     410{
     411    u32 tmp;
     412    TIMER Timer;
     413
     414    dprintf("controller reset starting on adapter %d\n", ad_no(ai));
     415    /* we must be in AHCI mode, before using anything
     416     * AHCI-specific, such as HOST_RESET.
     417     */
     418    ahci_enable_ahci(ai);
     419
     420    /* global controller reset */
     421    tmp = readl(ai->mmio + HOST_CTL);
     422    if ((tmp & HOST_RESET) == 0) {
     423        writel(ai->mmio + HOST_CTL, tmp | HOST_RESET);
     424        readl(ai->mmio + HOST_CTL); /* flush */
     425    }
     426
     427    /*
     428     * to perform host reset, OS should set HOST_RESET
     429     * and poll until this bit is read to be "0".
     430     * reset must complete within 1 second, or
     431     * the hardware should be considered fried.
     432     */
     433    timer_init(&Timer, 1000);
     434    while (((tmp = readl(ai->mmio + HOST_CTL)) & HOST_RESET) != 0) {
     435      if (timer_check_and_block(&Timer)) {
     436        dprintf("controller reset failed (0x%lx)\n", tmp);
     437        return(-1);
     438      }
     439    }
     440
     441    /* turn on AHCI mode */
     442    ahci_enable_ahci(ai);
     443
     444    /* Some registers might be cleared on reset.  Restore
     445     * initial values.
     446     */
     447    ahci_restore_initial_config(ai);
     448
     449    if (ai->pci->vendor == PCI_VENDOR_ID_INTEL) {
     450      u32 tmp16 = 0;
     451
     452      ddprintf("ahci_reset_controller: intel detected\n");
     453      /* configure PCS */
     454      pci_read_conf(ai->bus, ai->dev_func, 0x92, sizeof(u16), &tmp16);
     455      if ((tmp16 & ai->port_map) != ai->port_map) {
     456        ddprintf("ahci_reset_controller: updating PCS %x/%x\n", (u16)tmp16, ai->port_map);
     457        tmp16 |= ai->port_map;
     458        pci_write_conf(ai->bus, ai->dev_func, 0x92, sizeof(u16), tmp16);
     459      }
     460    }
     461
     462    return 0;
    367463}
    368464
     
    633729
    634730  /* enable adapter-level interrupts */
    635   writel(ai->mmio + HOST_CTL, HOST_IRQ_EN);
     731  writel(ai->mmio + HOST_CTL, readl(ai->mmio + HOST_CTL) | HOST_IRQ_EN);
    636732  readl(ai->mmio + HOST_CTL); /* flush */
    637733
     
    661757
    662758  dprintf("ahci_reset_port: resetting port %d.%d\n", ad_no(ai), p);
    663   if (debug > 1) {
    664     aprintf(" PORT_CMD       = 0x%lx\n", readl(port_mmio + PORT_CMD));
    665     aprintf("ahci_reset_port: command engine status:\n");
    666     aprintf(" PORT_SCR_ACT   = 0x%lx\n", readl(port_mmio + PORT_SCR_ACT));
    667     aprintf(" PORT_CMD_ISSUE = 0x%lx\n", readl(port_mmio + PORT_CMD_ISSUE));
    668     aprintf("link/device status:\n");
    669     aprintf(" PORT_SCR_STAT  = 0x%lx\n", readl(port_mmio + PORT_SCR_STAT));
    670     aprintf(" PORT_SCR_CTL   = 0x%lx\n", readl(port_mmio + PORT_SCR_CTL));
    671     aprintf(" PORT_SCR_ERR   = 0x%lx\n", readl(port_mmio + PORT_SCR_ERR));
    672     aprintf(" PORT_TFDATA    = 0x%lx\n", readl(port_mmio + PORT_TFDATA));
    673     aprintf("interrupt status:\n");
    674     aprintf(" PORT_IRQ_STAT  = 0x%lx\n", readl(port_mmio + PORT_IRQ_STAT));
    675     aprintf(" PORT_IRQ_MASK  = 0x%lx\n", readl(port_mmio + PORT_IRQ_MASK));
    676     aprintf(" HOST_IRQ_STAT  = 0x%lx\n", readl(ai->mmio + HOST_IRQ_STAT));
    677   }
     759  if (debug > 1) ahci_dump_port_regs(ai, p);
    678760
    679761  /* stop port engines (we don't care whether there is an error doing so) */
     
    13671449       */
    13681450      DevHelp_ArmCtxHook(0, engine_ctxhook_h);
    1369 //      DevHelp_EOI(irq);
    13701451    } else {
    13711452      spin_lock(drv_lock);
    13721453      trigger_engine();
    1373 //      DevHelp_EOI(irq);
    13741454      spin_unlock(drv_lock);
    13751455    }
  • trunk/src/os2ahci/apm.c

    r160 r161  
    11/******************************************************************************
    2  * apm.c - Functions to interface with the APM driver.
     2 * apm.c - Functions to interface with the legacy APM driver, and suspend / resume functions.
    33 *
    44 * Copyright (c) 2011 thi.guten Software Development
     
    2727#include "os2ahci.h"
    2828
     29/* Legacy APM support is not needed on eCS systems with ACPI and is more
     30 * reliable without it enabled.
     31 */
     32#ifdef LEGACY_APM
     33
    2934#include <apmcalls.h>
    30 
    31 /* -------------------------- macros and constants ------------------------- */
    32 
    33 /* ------------------------ typedefs and structures ------------------------ */
    34 
    35 /* -------------------------- function prototypes -------------------------- */
    36 
    37 /* ------------------------ global/static variables ------------------------ */
    38 
    3935USHORT _far _cdecl apm_event    (APMEVENT _far *evt);
    40 
    41 /* ----------------------------- start of code ----------------------------- */
    4236
    4337/******************************************************************************
     
    9488  return(0);
    9589}
     90#endif /* LEGACY_APM */
    9691
    9792/******************************************************************************
     
    143138  init_complete = 0;
    144139
    145 #if 0
    146   /* restore BIOS configuration for each adapter and release the adapter */
    147   for (a = 0; a < ad_info_cnt; a++) {
    148     ahci_restore_bios_config(ad_infos + a);
    149   }
    150 #endif
    151 
    152140  /* TODO: put the device into the D3 state */
    153141
     
    171159  for (a = 0; a < ad_info_cnt; a++) {
    172160    AD_INFO *ai = ad_infos + a;
     161
     162    //ahci_reset_controller(ai);
    173163
    174164    /* Complete initialization of this adapter; this will restart the ports
     
    184174  /* unlock all adapters now that we have set the init_complete flag */
    185175  for (a = 0; a < ad_info_cnt; a++) {
    186     unlock_adapter(ad_infos + a);
     176    AD_INFO *ai = ad_infos + a;
     177    unlock_adapter(ai);
    187178  }
    188179
    189180  suspended = 0;
     181
     182  /* restart engine to resume IORB processing */
     183  resume_sleep_flag = 5000;
     184  DevHelp_ArmCtxHook(0, engine_ctxhook_h);
     185
    190186  dprintf("resume() finished\n");
    191187}
  • trunk/src/os2ahci/ctxhook.c

    r138 r161  
    217217            if (req_sense(problem_iorb, 0) == 0) {
    218218              /* execute request sense on slot #0 before anything else comes along */
    219               ADD_StartTimerMS(&aws->timer, 5000, (PFN) timeout_callback, 
     219              ADD_StartTimerMS(&aws->timer, 5000, (PFN) timeout_callback,
    220220                               problem_iorb, 0);
    221221              aws->cmd_slot = 0;
     
    430430
    431431  dprintf("engine_ctxhook() started\n");
     432  if (resume_sleep_flag) {
     433    msleep(resume_sleep_flag);
     434    resume_sleep_flag = 0;
     435  }
    432436
    433437  spin_lock(drv_lock);
  • trunk/src/os2ahci/os2ahci.c

    r160 r161  
    135135int             init_complete;     /* if != 0, initialization has completed */
    136136int             suspended;
     137int             resume_sleep_flag;
    137138
    138139/* apapter/port-specific options saved when parsing the command line */
     
    222223  init_drv_called = 1;
    223224  suspended = 0;
     225  resume_sleep_flag = 0;
    224226
    225227  /* set device helper entry point */
     
    513515 * Device driver exit handler. This handler is called when OS/2 shuts down and
    514516 * flushes the write caches of all attached devices. Since this is effectively
    515  * the same we do when suspending, we'll call out to the corresponding APM
     517 * the same we do when suspending, we'll call out to the corresponding suspend
    516518 * function.
    517519 *
     
    619621 * all IORBs have been sent.
    620622 *
    621  * NOTE: While initialization has not completed (or during APM suspend/resume
     623 * NOTE: While initialization has not completed (or during suspend/resume
    622624 *       operations), this function will loop indefinitely because we can't
    623625 *       rely on interrupt handlers or context hooks and complex IORBs
     
    742744   * IORB.
    743745   */
    744   while (suspended) DevHelp_ProcBlock((ULONG)&send_iorb, 1, WAIT_IS_INTERRUPTABLE);
    745746  add_workspace(iorb)->processing = 1;
    746747  spin_unlock(drv_lock);
     
    817818      }
    818819
     820      #ifdef LEGACY_APM
    819821      /* register APM hook */
    820822      apm_init();
     823      #endif
    821824
    822825      if (!TRACE_ACTIVE) build_user_info();
  • trunk/src/os2ahci/os2ahci.h

    r160 r161  
    3434 */
    3535
     36/* Global feature defines
     37 * DEBUG = enable debug logging routines to be compled in.
     38 * LEGACY_APM = enable the legacy APM interface to be compiled in.
     39 *   Legacy APM support is not needed on eCS systems with ACPI and is more reliable without it enabled.
     40 */
    3641#define DEBUG
     42//#define LEGACY_APM
     43
    3744#define INCL_NOPMAPI
    3845#define INCL_DOSINFOSEG
     
    517524extern void    ahci_execute_cdb             (IORBH _far *iorb);
    518525extern void    ahci_execute_ata             (IORBH _far *iorb);
     526extern void ahci_dump_host_regs(AD_INFO *ai, int bios_regs);
     527extern void ahci_dump_port_regs(AD_INFO *ai, int p);
     528extern int ahci_reset_controller(AD_INFO *ai);
    519529
    520530/* libc.c */
     
    612622extern int           init_complete; /* if != 0, initialization has completed */
    613623extern int           suspended;     /* indicates if the driver is suspended */
     624extern int           resume_sleep_flag;
    614625
    615626extern u16           com_base;      /* debug COM port base address */
Note: See TracChangeset for help on using the changeset viewer.