SATA DVD drive no longer works
Jung-uk Kim
jkim at FreeBSD.org
Wed Apr 22 18:49:28 UTC 2009
On Wednesday 22 April 2009 11:58 am, Diego Depaoli wrote:
> 2009/4/22 Ian Freislich <ianf at 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
-------------- next part --------------
--- 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);
More information about the freebsd-current
mailing list