Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Apr 2009 14:49:10 -0400
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        freebsd-current@FreeBSD.org
Cc:        Ian Freislich <ianf@clue.co.za>, Diego Depaoli <trebestie@gmail.com>
Subject:   Re: SATA DVD drive no longer works
Message-ID:  <200904221449.12678.jkim@FreeBSD.org>
In-Reply-To: <83e5fb980904220858g4b009527w315425b72c536d3a@mail.gmail.com>
References:  <E1LwePl-0001v6-Ic@clue.co.za> <83e5fb980904220858g4b009527w315425b72c536d3a@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--Boundary-00=_oa27J69VBdrMQvQ
Content-Type: text/plain;
  charset="utf-8"
Content-Transfer-Encoding: 8bit
Content-Disposition: inline

On Wednesday 22 April 2009 11:58 am, Diego Depaoli wrote:
> 2009/4/22 Ian Freislich <ianf@clue.co.za>:
> > I have a DVD drive that was in the past detected as:
> >
> > <TSSTcorp CDDVDW SH-S223F SB00>
> >
> > It's been a long time since I tried to use it because it's only
> > been able to play about 1/10 of my DVD colloction.  It's now
> > with a recent (>4 days old CURRENT) not even detected.
> >
> > My ATA hardware is detected as follows:
> >
> > atapci1: <nVidia nForce MCP67 SATA300 controller> port
> > 0xc480-0xc487,0xc400-0xc403,0xc080-0xc087,0xc000-0xc003,0xbc00-0x
> >bc0f mem 0xfe9f6000-0xfe9f7fff irq 22 at device 9.0 on pci0
> > atapci1: [ITHREAD]
> > atapci1: AHCI Version 01.10 controller with 4 ports PM supported
> > ata2: <ATA channel 0> on atapci1
> > If I 'atacontrol reinit ata2' (where the drive is connected) it
> > takes much less time than the other controlers which have nothing
> > on them, but it still turns up no hardware:
> >
> > [brane] /var/db/pkg # time atacontrol reinit ata2
> > Master:      no device present
> > Slave:       no device present
>
> same here with AMD780G chipset.

I don't think ATI/AMD SB700 issue is related to the nVidia problem.  
Please try the attached patch for ATI/AMD south bridge.  It is not a 
complete patch yet but you should be able to use "combined mode" for 
SB700, I think. ;-)

Jung-uk Kim

--Boundary-00=_oa27J69VBdrMQvQ
Content-Type: text/plain;
  charset="utf-8";
  name="ata-ati.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="ata-ati.diff"

--- sys/dev/ata/ata-pci.h	30 Mar 2009 22:18:38 -0000	1.104
+++ sys/dev/ata/ata-pci.h	22 Apr 2009 18:44:04 -0000
@@ -108,6 +108,11 @@
 #define ATA_ATI_IXP600_S1       0x43801002
 #define ATA_ATI_IXP700          0x439c1002
 #define ATA_ATI_IXP700_S1       0x43901002
+#define	ATA_ATI_IXP700_S2	0x43911002
+#define	ATA_ATI_IXP700_S3	0x43921002
+#define	ATA_ATI_IXP700_S4	0x43931002
+#define	ATA_ATI_IXP700_S5	0x43941002
+#define	ATA_ATI_IXP700_S6	0x43951002
 
 #define ATA_CENATEK_ID          0x16ca
 #define ATA_CENATEK_ROCKET      0x000116ca
@@ -458,6 +463,7 @@
 int ata_ahci_ch_detach(device_t dev);
 int ata_ahci_ch_suspend(device_t dev);
 int ata_ahci_ch_resume(device_t dev);
+int ata_ahci_ctlr_reset(device_t dev);
 void ata_ahci_reset(device_t dev);
 int ata_marvell_edma_chipinit(device_t);
 int ata_sii_chipinit(device_t);
--- sys/dev/ata/chipsets/ata-ahci.c	30 Mar 2009 22:18:38 -0000	1.20
+++ sys/dev/ata/chipsets/ata-ahci.c	22 Apr 2009 18:44:04 -0000
@@ -52,7 +52,6 @@
 #include <ata_if.h>
 
 /* local prototypes */
-static int ata_ahci_ctlr_reset(device_t dev);
 static int ata_ahci_suspend(device_t dev);
 static int ata_ahci_status(device_t dev);
 static int ata_ahci_begin_transaction(struct ata_request *request);
@@ -155,7 +154,7 @@
     return 0;
 }
 
-static int
+int
 ata_ahci_ctlr_reset(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(dev);
--- sys/dev/ata/chipsets/ata-ati.c	9 Oct 2008 12:56:57 -0000	1.1
+++ sys/dev/ata/chipsets/ata-ati.c	22 Apr 2009 18:44:04 -0000
@@ -44,6 +44,7 @@
 #include <machine/stdarg.h>
 #include <machine/resource.h>
 #include <machine/bus.h>
+#include <sys/pciio.h>
 #include <sys/rman.h>
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pcireg.h>
@@ -54,14 +55,26 @@
 /* local prototypes */
 static int ata_ati_chipinit(device_t dev);
 static void ata_ati_setmode(device_t dev, int mode);
+static int ata_ati_ahci_chipinit(device_t dev);
+static int ata_ati_ahci_resume(device_t dev);
+static void ata_ati_ahci_fixup(device_t dev);
 
 /* misc defines */
 #define ATI_PATA	0x01
 #define ATI_SATA	0x02
 #define ATI_AHCI	0x04
 #define SII_MEMIO       1
+#define	ATI_FORCE_AHCI	0x01
+#define	ATI_INTx_BUG	0x02
 #define SII_BUG         0x04
+#define	ATI_SMBUS_DEV	0x4385
 
+/* Misc Control Register */
+#define	ATI_PCI_MISC_CTRL		0x40
+#define	ATI_PCI_MISCCTRL_ENABLE_WR	0x00000001
+
+/* MSI Control Register */
+#define	ATI_PCI_MSI_CTRL		0x50
 
 /*
  * ATI chipset support functions
@@ -81,7 +94,16 @@
      { ATA_ATI_IXP600_S1, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP600" },
      { ATA_ATI_IXP700,    0x00, ATI_PATA, 0, ATA_UDMA6, "IXP700" },
      { ATA_ATI_IXP700_S1, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" },
+     { ATA_ATI_IXP700_S2, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" },
+     { ATA_ATI_IXP700_S3, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" },
+     { ATA_ATI_IXP700_S4, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" },
+     { ATA_ATI_IXP700_S5, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" },
+     { ATA_ATI_IXP700_S6, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" },
      { 0, 0, 0, 0, 0, 0}};
+    struct pci_devinfo *dinfo;
+    pcicfgregs *cfg;
+    device_t smbdev;
+    uint8_t revid;
 
     if (pci_get_vendor(dev) != ATA_ATI_ID)
 	return ENXIO;
@@ -105,7 +127,43 @@
 	ctlr->chipinit = ata_sii_chipinit;
 	break;
     case ATI_AHCI:
-	ctlr->chipinit = ata_ahci_chipinit;
+	/* Force AHCI mode on SATA controllers if IDE mode is set. */
+	if ((ctlr->chip->chipid == ATA_ATI_IXP600_S1 ||
+	    ctlr->chip->chipid == ATA_ATI_IXP700_S1) &&
+	    pci_get_subclass(dev) == PCIS_STORAGE_IDE) {
+	    ctlr->chip->cfg2 = ATI_FORCE_AHCI;
+	    dinfo = device_get_ivars(dev);
+	    cfg = &dinfo->cfg;
+	    cfg->subclass = PCIS_STORAGE_SATA;
+	    cfg->progif = PCIP_STORAGE_SATA_AHCI_1_0;
+	    if (cfg->msi.msi_location == 0) {
+		cfg->msi.msi_location = ATI_PCI_MSI_CTRL;
+		cfg->msi.msi_ctrl = pci_read_config(dev,
+		    ATI_PCI_MSI_CTRL + PCIR_MSI_CTRL, 2) &
+		    ~PCIM_MSICTRL_MME_MASK;
+		cfg->msi.msi_msgnum =
+		    1 << ((cfg->msi.msi_ctrl & PCIM_MSICTRL_MMC_MASK) >> 1);
+		cfg->msi.msi_ctrl |= cfg->msi.msi_msgnum << 4;
+	    }
+	}
+	/*
+	 * Some IXP700 revisions require INTx even with MSI.
+	 * XXX Chip revision must be obtained from SMBUS device.
+	 */
+	if ((ctlr->chip->chipid == ATA_ATI_IXP700_S1 ||
+	    ctlr->chip->chipid == ATA_ATI_IXP700_S2 ||
+	    ctlr->chip->chipid == ATA_ATI_IXP700_S3 ||
+	    ctlr->chip->chipid == ATA_ATI_IXP700_S4 ||
+	    ctlr->chip->chipid == ATA_ATI_IXP700_S5) &&
+	    (smbdev = pci_find_device(ATA_ATI_ID, ATI_SMBUS_DEV)) != NULL) {
+		revid = pci_get_revid(smbdev);
+		if (revid >= 0x30 && revid < 0x3b)
+		    ctlr->chip->cfg2 |= ATI_INTx_BUG;
+	}
+	if (ctlr->chip->cfg2 != 0)
+	    ctlr->chipinit = ata_ati_ahci_chipinit;
+	else
+	    ctlr->chipinit = ata_ahci_chipinit;
 	break;
     }
     return 0;
@@ -119,9 +177,8 @@
     if (ata_setup_interrupt(dev, ata_generic_intr))
 	return ENXIO;
 
-    /* IXP600 & IXP700 only have 1 PATA channel */
-    if ((ctlr->chip->chipid == ATA_ATI_IXP600) ||
-	(ctlr->chip->chipid == ATA_ATI_IXP700))
+    /* IXP600 only has 1 PATA channel */
+    if (ctlr->chip->chipid == ATA_ATI_IXP600)
 	ctlr->channels = 1;
 
     ctlr->setmode = ata_ati_setmode;
@@ -192,6 +249,49 @@
     }
 }
 
+static int
+ata_ati_ahci_chipinit(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(dev);
+    int error;
+
+    ata_ati_ahci_fixup(dev);
+    error = ata_ahci_chipinit(dev);
+    if ((ctlr->chip->cfg2 & ATI_FORCE_AHCI) != 0)
+	ctlr->resume = ata_ati_ahci_resume;
+    if ((ctlr->chip->cfg2 & ATI_INTx_BUG) != 0)
+	pci_write_config(dev, PCIR_COMMAND,
+	    pci_read_config(dev, PCIR_COMMAND, 2) & ~PCIM_CMD_INTxDIS, 2);
+    return (error);
+}
+
+static int
+ata_ati_ahci_resume(device_t dev)
+{
+
+    ata_ati_ahci_fixup(dev);
+    return (ata_ahci_ctlr_reset(dev));
+}
+
+static void
+ata_ati_ahci_fixup(device_t dev)
+{
+    struct pci_devinfo *dinfo = device_get_ivars(dev);
+    pcicfgregs *cfg = &dinfo->cfg;
+    uint32_t ctrl;
+
+    ctrl = pci_read_config(dev, ATI_PCI_MISC_CTRL, 4);
+    pci_write_config(dev, ATI_PCI_MISC_CTRL,
+	ctrl | ATI_PCI_MISCCTRL_ENABLE_WR, 4);
+    pci_write_config(dev, PCIR_SUBCLASS, cfg->subclass, 1);
+    pci_write_config(dev, PCIR_PROGIF, cfg->progif, 1);
+    if (cfg->msi.msi_location != 0)
+	pci_write_config(dev, cfg->msi.msi_location + PCIR_MSI_CTRL,
+	    cfg->msi.msi_ctrl, 2);
+    pci_write_config(dev, ATI_PCI_MISC_CTRL,
+	ctrl & ~ATI_PCI_MISCCTRL_ENABLE_WR, 4);
+}
+
 ATA_DECLARE_DRIVER(ata_ati);
 MODULE_DEPEND(ata_ati, ata_ahci, 1, 1, 1);
 MODULE_DEPEND(ata_ati, ata_sii, 1, 1, 1);

--Boundary-00=_oa27J69VBdrMQvQ--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904221449.12678.jkim>