Date: Fri, 6 Nov 2009 10:45:37 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r198980 - stable/8/sys/dev/ata/chipsets Message-ID: <200911061045.nA6Ajbvr013888@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911061045.nA6Ajbvr013888>