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 {
*/
#defineAHCI_PRDT_NUMBER257
-/* AHCI base address */
-#defineAHCI_BASE_REG 6 /* BAR5 is the only useful register */
+/* PCI register number for AHCI register set */
+#defineAHCI_PCI_RNUM 0x24
/* various global HBA capability bits */
#defineAHCI_HBA_CAP_NP (0x1f 0) /* number of ports */