diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index c5ca313..4b281f2 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -136,7 +136,7 @@ static inline unsigned int pci_calc_resource_flags(unsigned int flags)
 /*
  * Find the extent of a PCI decode..
  */
-static u32 pci_size(u32 base, u32 maxbase, u32 mask)
+u32 pci_size(u32 base, u32 maxbase, u32 mask)
 {
 	u32 size = mask & maxbase;	/* Find the significant bits */
 	if (!size)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index a807797..c11477c 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -893,6 +893,55 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
 
+static void __devinit quirk_ahci_sata(struct pci_dev *pdev)
+{
+	int ret;
+
+	u32 sir, newval;		
+	u16 mode;
+
+	/* Make sure we're in AHCI mode */
+	pci_read_config_word(pdev, 0x90, &mode);
+	pci_write_config_word(pdev, 0x90, 0x40);
+
+	/* 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 AHCI BAR - %d\n", ret);
+		pci_write_config_word(pdev, 0x90, mode);
+		pci_write_config_dword(pdev, 0x94, sir);
+		return;
+	}
+
+	/* 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 3771323..3da97d1 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;
+	u32 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 = (u32)PCI_BASE_ADDRESS_IO_MASK;
+		start = PCIBIOS_MIN_IO;
+	} else {
+		mask = (u32)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 -EBUSY;
+
+	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 0dd93bb..2a1952f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -573,6 +573,7 @@ int pcix_get_mmrbc(struct pci_dev *dev);
 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 __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i);
@@ -635,6 +636,7 @@ void pci_unregister_driver(struct pci_driver *);
 void pci_remove_behind_bridge(struct pci_dev *);
 struct pci_driver *pci_dev_driver(const struct pci_dev *);
 const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
+u32 pci_size(u32 base, u32 maxbase, u32 mask);
 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
 
 void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
