This is in drivers/pci/quirks.c. Note that to activate it, you use mbp_force_ahci=1 on the kernel command line. Also note that, IIRC, earlier MBP's required a 0x40 instead of a 0x60 written to config word 0x90.
static bool quirk_mbp_sata_dev(struct pci_dev *pdev)
{
printk(KERN_INFO "Quirking ahci device %04x:%04x\n", pdev->vendor, pdev->device);
pci_write_config_word(pdev, 0x90, 0x60); /* AHCI - 6 ports enabled */
pdev->class = PCI_CLASS_STORAGE_SATA_AHCI;
// pci_write_config_dword(pdev, 0x9c, 0);
pci_write_config_byte(pdev, PCI_CLASS_PROG, 0x01);
pci_write_config_byte(pdev, PCI_CLASS_DEVICE, 0x06);
/* The PCI device ID will have been changed */
pci_read_config_word(pdev, PCI_DEVICE_ID, &pdev->device);
printk(KERN_DEBUG "ICH AHCI quirk: SATA AHCI controller has device ID %04x:%04x\n", pdev->vendor, pdev->device);
return false;
}
static void quirk_mbp_sata(struct pci_dev *pdev)
{
int ret = 0;
if (!mbp_force_ahci)
return;
if (quirk_mbp_sata_dev(pdev))
return; /* nothing to do */
/* Try to allocate the resource on BAR 5.
* If we have a bad alignment, don't even try,
* thus neatly avoiding a scary warning.
*/
if (pci_resource_alignment(pdev, &pdev->resource[5]))
ret = pci_assign_resource(pdev, 5);
if (!ret) {
printk (KERN_INFO "Quirked ICH SATA controller to AHCI mode\n");
return;
}
mbp_force_ahci = 0;
printk (KERN_ERR "MBP ICH AHCI quirk: pci_assign_resource returned %d\n", ret);
}
/* On resume, the device will have been reset to IDE mode, so we need to re-quirk */
static void quirk_mbp_sata_resume(struct pci_dev *pdev)
{
if (mbp_force_ahci && !quirk_mbp_sata_dev(pdev)) {
pci_update_resource(pdev, 5);
printk (KERN_INFO "Re-quirked ICH SATA controller to AHCI mode\n");
}
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3b28, quirk_mbp_sata); /* MacBook Pro (6,1) force AHCI */
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, 0x3b29, quirk_mbp_sata_resume); /* MacBook Pro (6,1) force AHCI on resume. Note that the original quirk will have changed the device ID */
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3b20, quirk_mbp_sata); /* iMac 11,1 force AHCI */
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, 0x3b22, quirk_mbp_sata_resume); /* iMac 11,1 force AHCI on resume. Note that the original quirk will have changed the device ID */
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1c01, quirk_mbp_sata); /* iMac 8,1 force AHCI */
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, 0x1c03, quirk_mbp_sata_resume); /* iMac 8,1 force AHCI on resume. Note that the original quirk will have changed the device ID */
--------------------------------------------------------------------------------------------------------------------------------- CUT HERE ------------------------------------------
And this is in drivers/pci/pci-driver.c. Note that I have swapped the fixup and resume.
This is in drivers/ pci/quirks. c. Note that to activate it, you use mbp_force_ahci=1 on the kernel command line. Also note that, IIRC, earlier MBP's required a 0x40 instead of a 0x60 written to config word 0x90.
static bool mbp_force_ahci; param(mbp_ force_ahci, bool, 0444); PARM_DESC( mbp_force_ ahci, "AHCI mode for MacBook Pro");
module_
MODULE_
static bool quirk_mbp_ sata_dev( struct pci_dev *pdev) config_ word(pdev, 0x90, 0x60); /* AHCI - 6 ports enabled */ STORAGE_ SATA_AHCI; config_ dword(pdev, 0x9c, 0); config_ byte(pdev, PCI_CLASS_PROG, 0x01); config_ byte(pdev, PCI_CLASS_DEVICE, 0x06); config_ word(pdev, PCI_DEVICE_ID, &pdev->device);
{
printk(KERN_INFO "Quirking ahci device %04x:%04x\n", pdev->vendor, pdev->device);
pci_write_
pdev->class = PCI_CLASS_
// pci_write_
pci_write_
pci_write_
/* The PCI device ID will have been changed */
pci_read_
printk(KERN_DEBUG "ICH AHCI quirk: SATA AHCI controller has device ID %04x:%04x\n", pdev->vendor, pdev->device);
return false;
}
static void quirk_mbp_ sata(struct pci_dev *pdev)
{
int ret = 0;
if (!mbp_force_ahci)
return;
if (quirk_ mbp_sata_ dev(pdev) )
return; /* nothing to do */
/* Try to allocate the resource on BAR 5. alignment( pdev, &pdev-> resource[ 5])) resource( pdev, 5);
* If we have a bad alignment, don't even try,
* thus neatly avoiding a scary warning.
*/
if (pci_resource_
ret = pci_assign_
if (!ret) {
printk (KERN_INFO "Quirked ICH SATA controller to AHCI mode\n");
return;
}
mbp_force_ahci = 0;
printk (KERN_ERR "MBP ICH AHCI quirk: pci_assign_resource returned %d\n", ret);
}
/* On resume, the device will have been reset to IDE mode, so we need to re-quirk */ sata_resume( struct pci_dev *pdev) mbp_sata_ dev(pdev) ) { resource( pdev, 5);
static void quirk_mbp_
{
if (mbp_force_ahci && !quirk_
pci_update_
printk (KERN_INFO "Re-quirked ICH SATA controller to AHCI mode\n");
}
}
DECLARE_ PCI_FIXUP_ EARLY(PCI_ VENDOR_ ID_INTEL, 0x3b28, quirk_mbp_sata); /* MacBook Pro (6,1) force AHCI */ PCI_FIXUP_ RESUME_ EARLY(PCI_ VENDOR_ ID_INTEL, 0x3b29, quirk_mbp_ sata_resume) ; /* MacBook Pro (6,1) force AHCI on resume. Note that the original quirk will have changed the device ID */
DECLARE_
DECLARE_ PCI_FIXUP_ EARLY(PCI_ VENDOR_ ID_INTEL, 0x3b20, quirk_mbp_sata); /* iMac 11,1 force AHCI */ PCI_FIXUP_ RESUME_ EARLY(PCI_ VENDOR_ ID_INTEL, 0x3b22, quirk_mbp_ sata_resume) ; /* iMac 11,1 force AHCI on resume. Note that the original quirk will have changed the device ID */
DECLARE_
DECLARE_ PCI_FIXUP_ EARLY(PCI_ VENDOR_ ID_INTEL, 0x1c01, quirk_mbp_sata); /* iMac 8,1 force AHCI */ PCI_FIXUP_ RESUME_ EARLY(PCI_ VENDOR_ ID_INTEL, 0x1c03, quirk_mbp_ sata_resume) ; /* iMac 8,1 force AHCI on resume. Note that the original quirk will have changed the device ID */
DECLARE_
------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- --- CUT HERE ------- ------- ------- ------- ------- -------
And this is in drivers/ pci/pci- driver. c. Note that I have swapped the fixup and resume.
static void pci_pm_ default_ resume_ early(struct pci_dev *pci_dev)
pci_fixup_ device( pci_fixup_ resume_ early, pci_dev);
pci_restore_ standard_ config( pci_dev) ;
{
}