Hi,

The AHCI driver in nv78 didn't work with the JMicron JMB363 SATA+IDE 
controller on my Gigabyte GA-X38-DQ6 motherboard, so I did a bit of 
debugging to resolve the problem.

Attached are two patches which work for me to fix this problem (and 
the ICH9 SATA controller still works too!):
   ahci-find-registers.patch - fixes a bug in ahci.c (locating registers)
   ahci-relax-checks.patch - relaxes some checks violated by the JMB363

I have submitted two corresponding items at http://bugs.opensolaris.org

Any feedback on these patches?  Would somebody like to sponsor me to get 
fixes incorporated into opensolaris?

Thanks,

Luke.
-------------- next part --------------
diff -r ee58901cb99b usr/src/uts/common/io/sata/adapters/ahci/ahci.c
--- a/usr/src/uts/common/io/sata/adapters/ahci/ahci.c   Sat Dec 22 18:19:42 
2007 -0800
+++ b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c   Thu Dec 27 08:22:30 
2007 +1100
@@ -2948,7 +2969,6 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, a
                 * HBA doesn't support stagger spin-up, force it
                 * to do normal COMRESET
                 */
-               ASSERT(port_cmd_status & AHCI_CMD_STATUS_SUD);
                if (ahci_portp->ahciport_flags &
                    AHCI_PORT_FLAG_SPINUP) {
                        AHCIDBG0(AHCIDBG_INIT, ahci_ctlp,
@@ -2964,7 +2984,8 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, a
                AHCIDBG1(AHCIDBG_INFO, ahci_ctlp,
                    "ahci_port_reset: do normal COMRESET", port);
 
-               ASSERT(port_cmd_status & AHCI_CMD_STATUS_SUD);
+               if (!(port_cmd_status & AHCI_CMD_STATUS_SUD))
+                       cmn_err(CE_WARN, "AHCI_CMD_STATUS_SUD not set")
 
                port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
                    (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
@@ -3107,9 +3128,6 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, a
        if (!(port_task_file & AHCI_TFD_STS_BSY)) {
                cmn_err(CE_WARN, "ahci_port_reset: port %d BSY bit "
                    "is not set after COMINIT signal is received", port);
-               ahci_portp->ahciport_port_state |= SATA_PSTATE_FAILED;
-               rval = AHCI_FAILURE;
-               goto out;
        }
 
        /*
-------------- next part --------------
diff -r ee58901cb99b usr/src/uts/common/io/sata/adapters/ahci/ahci.c
--- a/usr/src/uts/common/io/sata/adapters/ahci/ahci.c   Sat Dec 22 18:19:42 
2007 -0800
+++ b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c   Thu Dec 27 08:22:30 
2007 +1100
@@ -380,6 +380,9 @@ ahci_attach(dev_info_t *dip, ddi_attach_
        ushort_t venid;
        uint8_t revision;
        int i;
+       pci_regspec_t   *regs;
+       int regs_length;
+       int rnumber;
 #if AHCI_DEBUG
        int speed;
 #endif
@@ -418,12 +421,30 @@ ahci_attach(dev_info_t *dip, ddi_attach_
 
        attach_state |= AHCI_ATTACH_STATE_STATEP_ALLOC;
 
+       /* 
+        * search through DDI "reg" property for the AHCI register set
+        */
+       if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
+           DDI_PROP_DONTPASS, "reg", (int **)&regs,
+           (uint_t *)&regs_length) != DDI_PROP_SUCCESS) {
+               cmn_err(CE_WARN, "!Cannot lookup reg property");
+               goto err_out;
+       }
+       for (rnumber = 0; rnumber < regs_length; ++rnumber) {
+               if ((regs[rnumber].pci_phys_hi & PCI_REG_REG_M)==AHCI_PCI_RNUM)
+                       break;
+       }
+       if (rnumber == regs_length) {
+               cmn_err(CE_WARN, "!Cannot find AHCI register set");
+               goto err_out;
+       }
+
        /*
         * Now map the AHCI base address; which includes global
         * registers and port control registers
         */
        status = ddi_regs_map_setup(dip,
-           AHCI_BASE_REG,
+           rnumber,
            (caddr_t *)&ahci_ctlp->ahcictl_ahci_addr,
            0,
            0,
diff -r ee58901cb99b usr/src/uts/common/sys/sata/adapters/ahci/ahcireg.h
--- a/usr/src/uts/common/sys/sata/adapters/ahci/ahcireg.h       Sat Dec 22 
18:19:42 2007 -0800
+++ b/usr/src/uts/common/sys/sata/adapters/ahci/ahcireg.h       Wed Dec 26 
14:07:54 2007 +1100
@@ -53,8 +53,8 @@ extern "C" {
  */
 #define        AHCI_PRDT_NUMBER        257
 
-/* AHCI base address */
-#define        AHCI_BASE_REG   6       /* BAR5 is the only useful register */
+/* PCI register number for AHCI register set */
+#define        AHCI_PCI_RNUM           0x24
 
 /* various global HBA capability bits */
 #define        AHCI_HBA_CAP_NP         (0x1f << 0) /* number of ports */

Reply via email to