Index: ata-chipset.c =================================================================== --- ata-chipset.c (revision 197412) +++ ata-chipset.c (working copy) @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1360,6 +1361,15 @@ ata_amd_chipinit(device_t dev) /* * ATI chipset support functions */ + +/* 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 + int ata_ati_ident(device_t dev) { @@ -1375,6 +1385,11 @@ ata_ati_ident(device_t dev) { ATA_ATI_IXP600_S1, 0x00, 0, ATIAHCI, ATA_SA300, "IXP600" }, { ATA_ATI_IXP700, 0x00, 0, ATIPATA, ATA_UDMA6, "IXP700" }, { ATA_ATI_IXP700_S1, 0x00, 0, ATIAHCI, ATA_SA300, "IXP700" }, + { ATA_ATI_IXP700_S2, 0x00, 0, ATIAHCI, ATA_SA300, "IXP700/800" }, + { ATA_ATI_IXP700_S3, 0x00, 0, ATIAHCI, ATA_SA300, "IXP700/800" }, + { ATA_ATI_IXP700_S4, 0x00, 0, ATIAHCI, ATA_SA300, "IXP700/800" }, + { ATA_ATI_IXP800_S1, 0x00, 0, ATIAHCI, ATA_SA300, "IXP800" }, + { ATA_ATI_IXP800_S2, 0x00, 0, ATIAHCI, ATA_SA300, "IXP800" }, { 0, 0, 0, 0, 0, 0}}; if (!(ctlr->chip = ata_match_chip(dev, ids))) @@ -1392,6 +1407,30 @@ ata_ati_ident(device_t dev) ctlr->chipinit = ata_sii_chipinit; break; case ATIAHCI: + /* + * 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; + uint32_t creg; + + cfg->subclass = PCIS_STORAGE_SATA; + cfg->progif = PCIP_STORAGE_SATA_AHCI_1_0; + + /* XXX: should be configured on resume too */ + creg = pci_read_config(dev, ATI_PCI_MISC_CTRL, 4); + pci_write_config(dev, ATI_PCI_MISC_CTRL, + creg | 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, + creg & ~ATI_PCI_MISCCTRL_ENABLE_WR, 4); + } ctlr->chipinit = ata_ahci_chipinit; break; } @@ -1406,9 +1445,8 @@ ata_ati_chipinit(device_t dev) if (ata_setup_interrupt(dev)) return ENXIO; - /* IXP600 & IXP700 only have 1 PATA channel */ - if ((ctlr->chip->chipid == ATA_ATI_IXP600) || - (ctlr->chip->chipid == ATA_ATI_IXP700)) + /* IXP600 only have 1 PATA channel */ + if (ctlr->chip->chipid == ATA_ATI_IXP600) ctlr->channels = 1; ctlr->setmode = ata_ati_setmode; Index: ata-pci.h =================================================================== --- ata-pci.h (revision 197412) +++ ata-pci.h (working copy) @@ -108,6 +108,11 @@ struct ata_connect_task { #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_IXP800_S1 0x43941002 +#define ATA_ATI_IXP800_S2 0x43951002 #define ATA_CENATEK_ID 0x16ca #define ATA_CENATEK_ROCKET 0x000116ca