Ignore:
Timestamp:
Mar 27, 2013, 5:55:26 AM (12 years ago)
Author:
David Azarewicz
Message:

Fix spin-up / power-up issue on some hardware
Changes to debug output
Fixup makefiles

File:
1 edited

Legend:

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

    r145 r148  
    142142  }
    143143
     144  ddprintf("ahci_save_bios_config: BIOS AHCI mode is %d\n", ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN);
     145
    144146  if ((ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) == 0 &&
    145147      ai->pci->vendor == PCI_VENDOR_ID_INTEL) {
     
    165167
    166168      if (i == HOST_CAP) {
    167         printf(" -");
    168         if (val & HOST_CAP_64)         printf(" 64bit");
    169         if (val & HOST_CAP_NCQ)        printf(" ncq");
    170         if (val & HOST_CAP_SNTF)       printf(" sntf");
    171         if (val & HOST_CAP_MPS)        printf(" mps");
    172         if (val & HOST_CAP_SSS)        printf(" sss");
    173         if (val & HOST_CAP_ALPM)       printf(" alpm");
    174         if (val & HOST_CAP_LED)        printf(" led");
    175         if (val & HOST_CAP_CLO)        printf(" clo");
    176         if (val & HOST_CAP_ONLY)       printf(" ahci_only");
    177         if (val & HOST_CAP_PMP)        printf(" pmp");
    178         if (val & HOST_CAP_FBS)        printf(" fbs");
    179         if (val & HOST_CAP_PIO_MULTI)  printf(" pio_multi");
    180         if (val & HOST_CAP_SSC)        printf(" ssc");
    181         if (val & HOST_CAP_PART)       printf(" part");
    182         if (val & HOST_CAP_CCC)        printf(" ccc");
    183         if (val & HOST_CAP_EMS)        printf(" ems");
    184         if (val & HOST_CAP_SXS)        printf(" sxs");
    185         printf(" cmd_slots:%d", (u16) ((val >> 8) & 0x1f) + 1);
    186         printf(" ports:%d",     (u16) (val & 0x1f) + 1);
     169        printf_nts(" -");
     170        if (val & HOST_CAP_64)         printf_nts(" 64bit");
     171        if (val & HOST_CAP_NCQ)        printf_nts(" ncq");
     172        if (val & HOST_CAP_SNTF)       printf_nts(" sntf");
     173        if (val & HOST_CAP_MPS)        printf_nts(" mps");
     174        if (val & HOST_CAP_SSS)        printf_nts(" sss");
     175        if (val & HOST_CAP_ALPM)       printf_nts(" alpm");
     176        if (val & HOST_CAP_LED)        printf_nts(" led");
     177        if (val & HOST_CAP_CLO)        printf_nts(" clo");
     178        if (val & HOST_CAP_ONLY)       printf_nts(" ahci_only");
     179        if (val & HOST_CAP_PMP)        printf_nts(" pmp");
     180        if (val & HOST_CAP_FBS)        printf_nts(" fbs");
     181        if (val & HOST_CAP_PIO_MULTI)  printf_nts(" pio_multi");
     182        if (val & HOST_CAP_SSC)        printf_nts(" ssc");
     183        if (val & HOST_CAP_PART)       printf_nts(" part");
     184        if (val & HOST_CAP_CCC)        printf_nts(" ccc");
     185        if (val & HOST_CAP_EMS)        printf_nts(" ems");
     186        if (val & HOST_CAP_SXS)        printf_nts(" sxs");
     187        printf_nts(" cmd_slots:%d", (u16) ((val >> 8) & 0x1f) + 1);
     188        printf_nts(" ports:%d",     (u16) (val & 0x1f) + 1);
    187189
    188190      } else if (i == HOST_CTL) {
    189         printf(" -");
    190         if (val & HOST_AHCI_EN)        printf(" ahci_enabled");
    191         if (val & HOST_IRQ_EN)         printf(" irq_enabled");
    192         if (val & HOST_RESET)          printf(" resetting");
     191        printf_nts(" -");
     192        if (val & HOST_AHCI_EN)        printf_nts(" ahci_enabled");
     193        if (val & HOST_IRQ_EN)         printf_nts(" irq_enabled");
     194        if (val & HOST_RESET)          printf_nts(" resetting");
    193195
    194196      } else if (i == HOST_CAP2) {
    195         printf(" -");
    196         if (val & HOST_CAP2_BOH)       printf(" boh");
    197         if (val & HOST_CAP2_NVMHCI)    printf(" nvmhci");
    198         if (val & HOST_CAP2_APST)      printf(" apst");
     197        printf_nts(" -");
     198        if (val & HOST_CAP2_BOH)       printf_nts(" boh");
     199        if (val & HOST_CAP2_NVMHCI)    printf_nts(" nvmhci");
     200        if (val & HOST_CAP2_APST)      printf_nts(" apst");
    199201      }
    200       printf("\n");
     202      printf_nts("\n");
    201203    }
    202204  }
     
    287289int ahci_restore_bios_config(AD_INFO *ai)
    288290{
    289   ddprintf("restoring AHCI BIOS configuration\n");
     291  ddprintf("ahci_restore_bios_config: restoring AHCI BIOS configuration on adapter %d\n", ad_no(ai));
    290292
    291293  /* Restore saved BIOS configuration; please note that HOST_CTL is restored
     
    349351int ahci_restore_initial_config(AD_INFO *ai)
    350352{
    351   ddprintf("restoring initial configuration\n");
     353  ddprintf("ahci_restore_initial_config: restoring initial configuration on adapter %d\n", ad_no(ai));
    352354
    353355  /* restore saved BIOS configuration */
     
    448450
    449451  /* couldn't enable AHCI mode */
    450   dprintf("failed to enable AHCI mode on adapter #%d\n", ad_no(ai));
     452  dprintf("failed to enable AHCI mode on adapter %d\n", ad_no(ai));
    451453  return(1);
     454}
     455
     456int ahci_reset_controller(AD_INFO *ai)
     457{
     458    u32 tmp;
     459    int timeout = 1000;
     460
     461    dprintf("controller reset starting on adapter %d\n", ad_no(ai));
     462    /* we must be in AHCI mode, before using anything
     463     * AHCI-specific, such as HOST_RESET.
     464     */
     465    ahci_enable_ahci(ai);
     466
     467    /* global controller reset */
     468    tmp = readl(ai->mmio + HOST_CTL);
     469    if ((tmp & HOST_RESET) == 0) {
     470        writel(ai->mmio + HOST_CTL, tmp | HOST_RESET);
     471        readl(ai->mmio + HOST_CTL); /* flush */
     472    }
     473
     474    /*
     475     * to perform host reset, OS should set HOST_RESET
     476     * and poll until this bit is read to be "0".
     477     * reset must complete within 1 second, or
     478     * the hardware should be considered fried.
     479     */
     480    while (((tmp = readl(ai->mmio + HOST_CTL)) & HOST_RESET) == HOST_RESET) {
     481        mdelay(10);
     482        timeout -= 10;
     483        if (timeout <= 0) {
     484          dprintf("controller reset failed (0x%lx)\n", tmp);
     485          return(-1);
     486        }
     487    }
     488
     489    /* turn on AHCI mode */
     490    ahci_enable_ahci(ai);
     491
     492    /* Some registers might be cleared on reset.  Restore
     493     * initial values.
     494     */
     495    ahci_restore_initial_config(ai);
     496
     497        if (ai->pci->vendor == PCI_VENDOR_ID_INTEL) {
     498                u32 tmp16 = 0;
     499
     500        ddprintf("ahci_reset_controller: intel detected\n");
     501                /* configure PCS */
     502                pci_read_conf(ai->bus, ai->dev_func, 0x92, sizeof(u16), &tmp16);
     503                if ((tmp16 & ai->port_map) != ai->port_map) {
     504            ddprintf("ahci_reset_controller: updating PCS %x/%x\n", (u16)tmp16, ai->port_map);
     505                        tmp16 |= ai->port_map;
     506                        pci_write_conf(ai->bus, ai->dev_func, 0x92, sizeof(u16), tmp16);
     507                }
     508        }
     509
     510    return 0;
    452511}
    453512
     
    487546  }
    488547
     548  ahci_reset_controller(ai);
     549
    489550  if (ahci_enable_ahci(ai)) {
    490551    goto exit_port_scan;
     
    492553
    493554  /* perform port scan */
    494   dprintf("scanning ports on adapter #%d\n", ad_no(ai));
     555  dprintf("ahci_scan_ports: scanning ports on adapter %d\n", ad_no(ai));
    495556  for (p = 0; p < AHCI_MAX_PORTS; p++) {
    496557    if (ai->port_map & (1UL << p)) {
     558
     559      dprintf("ahci_scan_ports: Wait till not busy on port %d\n", p);
     560      /* wait until all active commands have completed on this port */
     561      while (ahci_port_busy(ai, p)) {
     562        msleep(250);
     563      }
    497564
    498565      if (!init_complete) {
     
    506573        rc = ahci_reset_port(ai, p, 0);
    507574      } else {
    508         ddprintf("(re)starting port #%d\n", p);
     575        ddprintf("ahci_scan_ports: (re)starting port %d\n", p);
    509576        ahci_stop_port(ai, p);
    510577        rc = ahci_start_port(ai, p, 0);
     
    517584
    518585      /* this port seems to have a device attached and ready for commands */
    519       ddprintf("port #%d seems to be attached to a device; probing...\n", p);
     586      ddprintf("ahci_scan_ports: port %d seems to be attached to a device; probing...\n", p);
    520587
    521588      /* Get ATA(PI) identity. The so-called signature gives us a hint whether
     
    575642  int i;
    576643
    577   dprintf("completing initialization of adapter #%d\n", ad_no(ai));
     644  dprintf("ahci_complete_init: completing initialization of adapter #%d\n", ad_no(ai));
    578645
    579646  /* register IRQ handlers; each IRQ level is registered only once */
     
    609676    if (ai->port_map & (1UL << p)) {
    610677      if (init_reset) {
     678        dprintf("ahci_complete_init: resetting port %d\n", p);
    611679        ahci_reset_port(ai, p, 1);
    612680      } else {
    613         dprintf("restarting port #%d\n", p);
     681        dprintf("ahci_complete_init: restarting port #%d\n", p);
    614682        ahci_stop_port(ai, p);
    615683        ahci_start_port(ai, p, 1);
     
    648716  u8 _far *port_mmio = port_base(ai, p);
    649717  u32 tmp;
    650   int timeout = 5000;
    651 
    652   dprintf("resetting port %d.%d\n", ad_no(ai), p);
     718  int timeout;
     719
     720  dprintf("ahci_reset_port: resetting port %d.%d\n", ad_no(ai), p);
    653721  if (debug > 1) {
    654     printf("command engine status:\n");
     722    printf(" PORT_CMD       = 0x%lx\n", readl(port_mmio + PORT_CMD));
     723    printf("ahci_reset_port: command engine status:\n");
    655724    printf(" PORT_SCR_ACT   = 0x%lx\n", readl(port_mmio + PORT_SCR_ACT));
    656725    printf(" PORT_CMD_ISSUE = 0x%lx\n", readl(port_mmio + PORT_CMD_ISSUE));
     
    673742  writel(port_mmio + PORT_SCR_ERR, tmp);
    674743
     744  /* power up and spin up the drive if necessary */
     745  if (((tmp = readl(port_mmio + PORT_CMD)) & (PORT_CMD_SPIN_UP|PORT_CMD_POWER_ON)) != (PORT_CMD_SPIN_UP|PORT_CMD_POWER_ON)) {
     746    writel(port_mmio + PORT_CMD, tmp | PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON);
     747  }
     748
    675749  /* set link speed and power management options */
    676   ddprintf("setting link speed and power management options\n");
    677   tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000ff0UL;
     750  ddprintf("ahci_reset_port: setting link speed and power management options\n");
     751  tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000fffUL; //DAZ
    678752  tmp |= ((u32) link_speed[ad_no(ai)][p] & 0x0f) << 4;
    679753  tmp |= ((u32) link_power[ad_no(ai)][p] & 0x0f) << 8;
    680   writel(port_mmio + PORT_SCR_CTL, tmp);
     754  //DAZ writel(port_mmio + PORT_SCR_CTL, tmp);
    681755
    682756  /* issue COMRESET on the port */
    683   ddprintf("issuing COMRESET on port\n");
    684   tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x0000000fUL;
     757  ddprintf("ahci_reset_port: issuing COMRESET on port %d\n", p);
     758  //DAZ tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x0000000fUL;
    685759  writel(port_mmio + PORT_SCR_CTL, tmp | 1);
    686760  readl(port_mmio + PORT_SCR_CTL);  /* flush */
     
    693767
    694768  /* wait for communication to be re-established after port reset */
     769  timeout = 5000;
    695770  while (((tmp = readl(port_mmio + PORT_SCR_STAT)) & 3) != 3) {
    696771    mdelay(10);
     
    708783
    709784  /* start port so we can receive the COMRESET FIS */
    710   ddprintf("starting port again\n");
     785  ddprintf("ahci_reset_port: starting port %d again\n", p);
    711786  ahci_start_port(ai, p, ei);
    712787
    713788  /* wait for device to be ready ((PxTFD & (BSY | DRQ | ERR)) == 0) */
     789  timeout = 5000;
    714790  while (((tmp = readl(port_mmio + PORT_TFDATA)) & 0x89) != 0) {
    715791    mdelay(10);
     
    722798    }
    723799  }
    724   ddprintf(" PORT_TFDATA   = 0x%lx\n", readl(port_mmio + PORT_TFDATA));
     800  ddprintf("ahci_reset_port: PORT_TFDATA   = 0x%lx\n", readl(port_mmio + PORT_TFDATA));
    725801
    726802  return(0);
     
    734810  u8 _far *port_mmio = port_base(ai, p);
    735811  u32 status;
    736 
     812  //int timeout;
     813
     814  dprintf("ahci_start_port %d.%d\n", ad_no(ai), p);
    737815  /* check whether device presence is detected and link established */
     816
     817#if 0
     818  /* wait for communication to be re-established after port reset */
     819  timeout = 5000;
     820  while (((status = readl(port_mmio + PORT_SCR_STAT)) & 3) != 3) {
     821    mdelay(10);
     822    timeout -= 10;
     823    if (timeout <= 0) {
     824      dprintf("ahci_start_port #%d (PORT_SCR_STAT = 0x%lx)\n", p, status);
     825      return(-1);
     826    }
     827  }
     828#endif
     829
    738830  status = readl(port_mmio + PORT_SCR_STAT);
    739   ddprintf(" PORT_SCR_STAT = 0x%lx\n", status);
     831  ddprintf("ahci_start_port: PORT_SCR_STAT = 0x%lx\n", status);
    740832  if ((status & 0xf) != 3) {
    741833    return(-1);
     
    744836  /* clear SError, if any */
    745837  status = readl(port_mmio + PORT_SCR_ERR);
    746   ddprintf(" PORT_SCR_ERR  = 0x%lx\n", status);
     838  ddprintf("ahci_start_port: PORT_SCR_ERR  = 0x%lx\n", status);
    747839  writel(port_mmio + PORT_SCR_ERR, status);
    748840
     
    827919  u32 tmp;
    828920  int rc;
     921
     922  dprintf("ahci_stop_port %d.%d\n", ad_no(ai), p);
    829923
    830924  /* disable port interrupts */
Note: See TracChangeset for help on using the changeset viewer.