diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e48fcf0..1e188e8 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -126,7 +126,7 @@ static inline unsigned int pci_calc_resource_flags(unsigned int flags)
 	return IORESOURCE_MEM;
 }
 
-static u64 pci_size(u64 base, u64 maxbase, u64 mask)
+u64 pci_size(u64 base, u64 maxbase, u64 mask)
 {
 	u64 size = mask & maxbase;	/* Find the significant bits */
 	if (!size)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 01d8f8a..7162a45 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -877,6 +877,55 @@ static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_sb600_sata);
 
+static void __devinit quirk_ahci_sata(struct pci_dev *pdev)
+{
+	int ret;
+
+	ret = pcim_iomap_regions(pdev, 1 << 5, "AHCI quirk");
+	
+	if (ret) {
+		u32 sir, newval;		
+		printk (KERN_INFO "AHCI BAR not set - attempting to program... ");
+		/* Need to set the SCRAE bit */
+		pci_read_config_dword(pdev, 0x94, &sir);
+		newval = (sir | 0x200);
+		pci_write_config_dword(pdev, 0x94, newval);
+		pdev->resource[5].flags = IORESOURCE_MEM;
+		ret = pci_allocate_resource(pdev, 5);
+		if (ret) {
+			printk (KERN_INFO "Failed to allocate new region\n");
+			pci_write_config_dword(pdev, 0x94, sir);
+			return;
+		} else 
+			printk (KERN_INFO "Succeeded\n");
+	} else
+		pcim_iounmap_regions(pdev, 1 << 5);
+
+	/* Set PCI_CLASS_STORAGE_SATA */
+	if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
+		pci_write_config_byte(pdev, PCI_CLASS_PROG, 0x01);
+		pci_write_config_byte(pdev, PCI_CLASS_DEVICE, 0x06);
+	}
+	pdev->class = PCI_CLASS_STORAGE_SATA_AHCI;
+	printk (KERN_INFO "Quirked PIIX device to AHCI mode\n");
+}	
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2651, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2652, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2653, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2680, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x27c0, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x27c4, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2820, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2825, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2828, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2920, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2921, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2926, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2928, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x292d, quirk_ahci_sata);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x292e, quirk_ahci_sata);
+
 /*
  *	Serverworks CSB5 IDE does not fully support native mode
  */
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 6dfd861..2773b5f 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -25,6 +25,60 @@
 #include <linux/slab.h>
 #include "pci.h"
 
+int
+pci_allocate_resource(struct pci_dev *dev, int resno)
+{
+	int err;
+	u64 size, mask, reg;
+	resource_size_t start;
+	struct resource *res = &dev->resource[resno];
+	struct resource *bres = pci_find_parent_resource(dev, res);
+
+	if (!bres) {
+		BUG();
+	}
+
+	if (!bres)
+		return -ENOMEM;
+	
+	if (res->flags & IORESOURCE_IO) {
+		mask = (u64)PCI_BASE_ADDRESS_IO_MASK;
+		start = PCIBIOS_MIN_IO;
+	} else {
+		mask = (u64)PCI_BASE_ADDRESS_MEM_MASK;
+		start = PCIBIOS_MIN_MEM;
+	}
+
+	if (resno < 6)
+		reg = PCI_BASE_ADDRESS_0 + 4 * resno;
+	else
+		return -EINVAL;
+
+	pci_write_config_dword(dev, reg, ~0);
+	pci_read_config_dword(dev, reg, &size);
+
+	if (!size || size == 0xffffffff)
+		return 0;
+
+	size = pci_size(0, size, mask);
+	
+	if (res->start != 0 && res->end != 0)
+		release_resource (res);
+
+	err = allocate_resource (bres, res, size+1, start, ~0U, 1024, NULL,
+				 NULL);
+
+	if (err) {
+		printk ("Failed to allocate a resource\n");
+		return err;
+	}
+
+	pci_update_resource (dev, res, resno);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pci_allocate_resource);
 
 void
 pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index fbf3766..502c34e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -549,6 +549,7 @@ void pci_intx(struct pci_dev *dev, int enable);
 int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
 int pcie_get_readrq(struct pci_dev *dev);
 int pcie_set_readrq(struct pci_dev *dev, int rq);
+int pci_allocate_resource(struct pci_dev *dev, int resno);
 void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
 int __must_check pci_assign_resource(struct pci_dev *dev, int i);
 int pci_select_bars(struct pci_dev *dev, unsigned long flags);
@@ -608,6 +609,7 @@ void pci_remove_behind_bridge(struct pci_dev *);
 struct pci_driver *pci_dev_driver(const struct pci_dev *dev);
 const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
 					 struct pci_dev *dev);
+u64 pci_size(u64 base, u64 maxbase, u64 mask);
 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
 		    int pass);
 
