svn commit: r198980 - stable/8/sys/dev/ata/chipsets
Alexander Motin
mav at FreeBSD.org
Fri Nov 6 10:45:38 UTC 2009
Author: mav
Date: Fri Nov 6 10:45:37 2009
New Revision: 198980
URL: http://svn.freebsd.org/changeset/base/198980
Log:
MFC r197783:
- Revert r191568 partially. Forcing AHCI mode by changing device subclass
and progif is evil. It doesn't work reliably[1] and we should honor BIOS
configuration by the user.
- If the SATA controller is enbled but combined mode is disabled, mask off
the emulated IDE channel on the legacy IDE controller.
Pointed out by: mav[1]
Modified:
stable/8/sys/dev/ata/chipsets/ata-ati.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/dev/ata/chipsets/ata-ati.c
==============================================================================
--- stable/8/sys/dev/ata/chipsets/ata-ati.c Fri Nov 6 10:38:33 2009 (r198979)
+++ stable/8/sys/dev/ata/chipsets/ata-ati.c Fri Nov 6 10:45:37 2009 (r198980)
@@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$");
#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>
@@ -55,9 +54,6 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_ati_chipinit(device_t dev);
static void ata_ati_setmode(device_t dev, int mode);
-static void ata_ati_ahci_enable(device_t dev);
-static int ata_ati_ahci_chipinit(device_t dev);
-static int ata_ati_ahci_resume(device_t dev);
/* misc defines */
#define ATI_PATA 0x01
@@ -66,13 +62,6 @@ static int ata_ati_ahci_resume(device_t
#define SII_MEMIO 1
#define SII_BUG 0x04
-/* Misc Control Register */
-#define ATI_PCI_MISC_CTRL 0x40
-#define ATI_PCI_MISCCTRL_ENABLE_WR 0x00000001
-
-/* Watchdog Control/Status Register */
-#define ATI_PCI_WD_CTRL 0x44
-#define ATI_PCI_WDCTRL_ENABLE 0x0001
/*
* ATI chipset support functions
@@ -121,19 +110,7 @@ ata_ati_probe(device_t dev)
ctlr->chipinit = ata_sii_chipinit;
break;
case ATI_AHCI:
- /*
- * Force AHCI mode if IDE mode is set from BIOS.
- */
- if ((ctlr->chip->chipid == ATA_ATI_IXP600_S1 ||
- ctlr->chip->chipid == ATA_ATI_IXP700_S1) &&
- pci_get_subclass(dev) == PCIS_STORAGE_IDE) {
- struct pci_devinfo *dinfo = device_get_ivars(dev);
- pcicfgregs *cfg = &dinfo->cfg;
- cfg->subclass = PCIS_STORAGE_SATA;
- cfg->progif = PCIP_STORAGE_SATA_AHCI_1_0;
- ata_ati_ahci_enable(dev);
- }
- ctlr->chipinit = ata_ati_ahci_chipinit;
+ ctlr->chipinit = ata_ahci_chipinit;
break;
}
return (BUS_PROBE_DEFAULT);
@@ -143,13 +120,41 @@ static int
ata_ati_chipinit(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(dev);
+ device_t smbdev;
+ int satacfg;
if (ata_setup_interrupt(dev, ata_generic_intr))
return ENXIO;
- /* IXP600 only has 1 PATA channel */
- if (ctlr->chip->chipid == ATA_ATI_IXP600)
+ switch (ctlr->chip->chipid) {
+ case ATA_ATI_IXP600:
+ /* IXP600 only has 1 PATA channel */
ctlr->channels = 1;
+ break;
+ case ATA_ATI_IXP700:
+ /*
+ * When "combined mode" is enabled, an additional PATA channel is
+ * emulated with two SATA ports and appears on this device.
+ * This mode can only be detected via SMB controller.
+ */
+ smbdev = pci_find_device(ATA_ATI_ID, 0x4385);
+ if (smbdev != NULL) {
+ satacfg = pci_read_config(smbdev, 0xad, 1);
+ if (bootverbose)
+ device_printf(dev, "SATA controller %s (%s%s channel)\n",
+ (satacfg & 0x01) == 0 ? "disabled" : "enabled",
+ (satacfg & 0x08) == 0 ? "" : "combined mode, ",
+ (satacfg & 0x10) == 0 ? "primary" : "secondary");
+
+ /*
+ * If SATA controller is enabled but combined mode is disabled,
+ * we have only one PATA channel. Ignore a non-existent channel.
+ */
+ if ((satacfg & 0x09) == 0x01)
+ ctlr->ichannels &= ~(1 << ((satacfg & 0x10) >> 4));
+ }
+ break;
+ }
ctlr->setmode = ata_ati_setmode;
return 0;
@@ -219,43 +224,6 @@ ata_ati_setmode(device_t dev, int mode)
}
}
-static void
-ata_ati_ahci_enable(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);
- pci_write_config(dev, ATI_PCI_WD_CTRL,
- pci_read_config(dev, ATI_PCI_WD_CTRL, 2) | ATI_PCI_WDCTRL_ENABLE, 2);
- pci_write_config(dev, ATI_PCI_MISC_CTRL,
- ctrl & ~ATI_PCI_MISCCTRL_ENABLE_WR, 4);
-}
-
-static int
-ata_ati_ahci_chipinit(device_t dev)
-{
- struct ata_pci_controller *ctlr = device_get_softc(dev);
- int error;
-
- error = ata_ahci_chipinit(dev);
- ctlr->resume = ata_ati_ahci_resume;
- return (error);
-}
-
-static int
-ata_ati_ahci_resume(device_t dev)
-{
-
- ata_ati_ahci_enable(dev);
- return (ata_ahci_ctlr_reset(dev));
-}
-
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 svn-src-all
mailing list