summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2011-12-02 12:52:33 +0000
committermav <mav@FreeBSD.org>2011-12-02 12:52:33 +0000
commit9be1bfa322fff9a906d73bb1d09940d86d489415 (patch)
tree040e683bc3ac608cf9ff74f030ce4a869cacf0a0 /sys/dev
parent2105513eb4dae9b2f0b771b8d025a33650eba4ab (diff)
downloadFreeBSD-src-9be1bfa322fff9a906d73bb1d09940d86d489415.zip
FreeBSD-src-9be1bfa322fff9a906d73bb1d09940d86d489415.tar.gz
Add hw.ahci.force tunable to control whether AHCI drivers should attach
to known AHCI-capable chips (AMD/NVIDIA), configured for legacy emulation. Enabled by default to get additional performance and functionality of AHCI when it can't be enabled by BIOS. Can be disabled to honor BIOS settings if needed for some reason. MFC after: 1 month
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ahci/ahci.c6
-rw-r--r--sys/dev/ata/chipsets/ata-ati.c24
-rw-r--r--sys/dev/ata/chipsets/ata-nvidia.c4
3 files changed, 31 insertions, 3 deletions
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index afa4b99..df4f66a 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -291,6 +291,9 @@ static struct {
#define RECOVERY_REQUEST_SENSE 2
#define recovery_slot spriv_field1
+static int force_ahci = 1;
+TUNABLE_INT("hw.ahci.force", &force_ahci);
+
static int
ahci_probe(device_t dev)
{
@@ -308,7 +311,8 @@ ahci_probe(device_t dev)
for (i = 0; ahci_ids[i].id != 0; i++) {
if (ahci_ids[i].id == devid &&
ahci_ids[i].rev <= revid &&
- (valid || !(ahci_ids[i].quirks & AHCI_Q_NOFORCE))) {
+ (valid || (force_ahci == 1 &&
+ !(ahci_ids[i].quirks & AHCI_Q_NOFORCE)))) {
/* Do not attach JMicrons with single PCI function. */
if (pci_get_vendor(dev) == 0x197b &&
(pci_read_config(dev, 0xdf, 1) & 0x40) == 0)
diff --git a/sys/dev/ata/chipsets/ata-ati.c b/sys/dev/ata/chipsets/ata-ati.c
index 1dfd84b..ada70d7 100644
--- a/sys/dev/ata/chipsets/ata-ati.c
+++ b/sys/dev/ata/chipsets/ata-ati.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_ati_chipinit(device_t dev);
+static int ata_ati_dumb_ch_attach(device_t dev);
static int ata_ati_ixp700_ch_attach(device_t dev);
static int ata_ati_setmode(device_t dev, int target, int mode);
@@ -63,6 +64,8 @@ static int ata_ati_setmode(device_t dev, int target, int mode);
#define SII_MEMIO 1
#define SII_BUG 0x04
+static int force_ahci = 1;
+TUNABLE_INT("hw.ahci.force", &force_ahci);
/*
* ATI chipset support functions
@@ -111,7 +114,10 @@ ata_ati_probe(device_t dev)
ctlr->chipinit = ata_sii_chipinit;
break;
case ATI_AHCI:
- ctlr->chipinit = ata_ahci_chipinit;
+ if (force_ahci == 1 || pci_get_subclass(dev) != PCIS_STORAGE_IDE)
+ ctlr->chipinit = ata_ahci_chipinit;
+ else
+ ctlr->chipinit = ata_ati_chipinit;
break;
}
return (BUS_PROBE_DEFAULT);
@@ -127,6 +133,11 @@ ata_ati_chipinit(device_t dev)
if (ata_setup_interrupt(dev, ata_generic_intr))
return ENXIO;
+ if (ctlr->chip->cfg1 == ATI_AHCI) {
+ ctlr->ch_attach = ata_ati_dumb_ch_attach;
+ ctlr->setmode = ata_sata_setmode;
+ return (0);
+ }
switch (ctlr->chip->chipid) {
case ATA_ATI_IXP600:
/* IXP600 only has 1 PATA channel */
@@ -165,6 +176,17 @@ ata_ati_chipinit(device_t dev)
}
static int
+ata_ati_dumb_ch_attach(device_t dev)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+
+ if (ata_pci_ch_attach(dev))
+ return ENXIO;
+ ch->flags |= ATA_SATA;
+ return (0);
+}
+
+static int
ata_ati_ixp700_ch_attach(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
diff --git a/sys/dev/ata/chipsets/ata-nvidia.c b/sys/dev/ata/chipsets/ata-nvidia.c
index 2edc0f1..580dfca 100644
--- a/sys/dev/ata/chipsets/ata-nvidia.c
+++ b/sys/dev/ata/chipsets/ata-nvidia.c
@@ -65,6 +65,8 @@ static int ata_nvidia_setmode(device_t dev, int target, int mode);
#define NVAHCI 0x04
#define NVNOFORCE 0x08
+static int force_ahci = 1;
+TUNABLE_INT("hw.ahci.force", &force_ahci);
/*
* nVidia chipset support functions
@@ -181,7 +183,7 @@ ata_nvidia_probe(device_t dev)
ata_set_desc(dev);
if ((ctlr->chip->cfg1 & NVAHCI) &&
- ((ctlr->chip->cfg1 & NVNOFORCE) == 0 ||
+ ((force_ahci == 1 && (ctlr->chip->cfg1 & NVNOFORCE) == 0) ||
pci_get_subclass(dev) != PCIS_STORAGE_IDE))
ctlr->chipinit = ata_ahci_chipinit;
else
OpenPOWER on IntegriCloud