[PATCH] dm-crypt: zero key before freeing it
[powerpc.git] / drivers / pci / quirks.c
index 7992bc8..f28ebdd 100644 (file)
@@ -7,6 +7,9 @@
  *
  *  Copyright (c) 1999 Martin Mares <mj@ucw.cz>
  *
+ *  Init/reset quirks for USB host controllers should be in the
+ *  USB quirks file, where their drivers can access reuse it.
+ *
  *  The bridge optimization stuff has been removed. If you really
  *  have a silly BIOS which is unable to set your host bridge right,
  *  use the PowerTweak utility (see http://powertweak.sourceforge.net).
@@ -353,7 +356,7 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int
 /*
  * PIIX4 ACPI: Two IO regions pointed to by longwords at
  *     0x40 (64 bytes of ACPI registers)
- *     0x90 (32 bytes of SMB registers)
+ *     0x90 (16 bytes of SMB registers)
  * and a few strange programmable PIIX4 device resources.
  */
 static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
@@ -363,7 +366,7 @@ static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
        pci_read_config_dword(dev, 0x40, &region);
        quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI");
        pci_read_config_dword(dev, 0x90, &region);
-       quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
+       quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
 
        /* Device resource A has enables for some of the other ones */
        pci_read_config_dword(dev, 0x5c, &res_a);
@@ -414,6 +417,18 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801DB_12,
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801EB_0,                quirk_ich4_lpc_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_ESB_1,            quirk_ich4_lpc_acpi );
 
+static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev)
+{
+       u32 region;
+
+       pci_read_config_dword(dev, 0x40, &region);
+       quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, "ICH6 ACPI/GPIO/TCO");
+
+       pci_read_config_dword(dev, 0x48, &region);
+       quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO");
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi );
+
 /*
  * VIA ACPI: One IO region pointed to by longword at
  *     0x48 or 0x20 (256 bytes of ACPI registers)
@@ -447,11 +462,11 @@ static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev)
 
        pci_read_config_word(dev, 0x70, &hm);
        hm &= PCI_BASE_ADDRESS_IO_MASK;
-       quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c868 HW-mon");
+       quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon");
 
        pci_read_config_dword(dev, 0x90, &smb);
        smb &= PCI_BASE_ADDRESS_IO_MASK;
-       quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c868 SMB");
+       quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB");
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C686_4,     quirk_vt82c686_acpi );
 
@@ -632,28 +647,6 @@ static void quirk_via_irq(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
 
-/*
- * PIIX3 USB: We have to disable USB interrupts that are
- * hardwired to PIRQD# and may be shared with an
- * external device.
- *
- * Legacy Support Register (LEGSUP):
- *     bit13:  USB PIRQ Enable (USBPIRQDEN),
- *     bit4:   Trap/SMI On IRQ Enable (USBSMIEN).
- *
- * We mask out all r/wc bits, too.
- */
-static void __devinit quirk_piix3_usb(struct pci_dev *dev)
-{
-       u16 legsup;
-
-       pci_read_config_word(dev, 0xc0, &legsup);
-       legsup &= 0x50ef;
-       pci_write_config_word(dev, 0xc0, legsup);
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82371SB_2,  quirk_piix3_usb );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82371AB_2,  quirk_piix3_usb );
-
 /*
  * VIA VT82C598 has its device ID settable and many BIOSes
  * set it to the ID of VT82C597 for backward compatibility.
@@ -922,6 +915,12 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
                        case 0x186a: /* M6Ne notebook */
                                asus_hides_smbus = 1;
                        }
+               if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) {
+                       switch (dev->subsystem_device) {
+                       case 0x1882: /* M6V notebook */
+                               asus_hides_smbus = 1;
+                       }
+               }
        } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_HP)) {
                if (dev->device ==  PCI_DEVICE_ID_INTEL_82855PM_HB)
                        switch(dev->subsystem_device) {
@@ -932,6 +931,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
                if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
                        switch (dev->subsystem_device) {
                        case 0x12bc: /* HP D330L */
+                       case 0x12bd: /* HP D530 */
                                asus_hides_smbus = 1;
                        }
        } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) {
@@ -966,6 +966,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82865_HB,   asus
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_7205_0,     asus_hides_smbus_hostbridge );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge );
 
 static void __init asus_hides_smbus_lpc(struct pci_dev *dev)
 {
@@ -990,6 +991,23 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,      PCI_DEVICE_ID_INTEL_82801CA_12, as
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801EB_0,  asus_hides_smbus_lpc );
 
+static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
+{
+       u32 val, rcba;
+       void __iomem *base;
+
+       if (likely(!asus_hides_smbus))
+               return;
+       pci_read_config_dword(dev, 0xF0, &rcba);
+       base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); /* use bits 31:14, 16 kB aligned */
+       if (base == NULL) return;
+       val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */
+       writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */
+       iounmap(base);
+       printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n");
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH6_1,     asus_hides_smbus_lpc_ich6 );
+
 /*
  * SiS 96x south bridge: BIOS typically hides SMBus device...
  */
@@ -1002,234 +1020,6 @@ static void __init quirk_sis_96x_smbus(struct pci_dev *dev)
        pci_read_config_byte(dev, 0x77, &val);
 }
 
-
-#define UHCI_USBLEGSUP         0xc0            /* legacy support */
-#define UHCI_USBCMD            0               /* command register */
-#define UHCI_USBSTS            2               /* status register */
-#define UHCI_USBINTR           4               /* interrupt register */
-#define UHCI_USBLEGSUP_DEFAULT 0x2000          /* only PIRQ enable set */
-#define UHCI_USBCMD_RUN                (1 << 0)        /* RUN/STOP bit */
-#define UHCI_USBCMD_GRESET     (1 << 2)        /* Global reset */
-#define UHCI_USBCMD_CONFIGURE  (1 << 6)        /* config semaphore */
-#define UHCI_USBSTS_HALTED     (1 << 5)        /* HCHalted bit */
-
-#define OHCI_CONTROL           0x04
-#define OHCI_CMDSTATUS         0x08
-#define OHCI_INTRSTATUS                0x0c
-#define OHCI_INTRENABLE                0x10
-#define OHCI_INTRDISABLE       0x14
-#define OHCI_OCR               (1 << 3)        /* ownership change request */
-#define OHCI_CTRL_IR           (1 << 8)        /* interrupt routing */
-#define OHCI_INTR_OC           (1 << 30)       /* ownership change */
-
-#define EHCI_HCC_PARAMS                0x08            /* extended capabilities */
-#define EHCI_USBCMD            0               /* command register */
-#define EHCI_USBCMD_RUN                (1 << 0)        /* RUN/STOP bit */
-#define EHCI_USBSTS            4               /* status register */
-#define EHCI_USBSTS_HALTED     (1 << 12)       /* HCHalted bit */
-#define EHCI_USBINTR           8               /* interrupt register */
-#define EHCI_USBLEGSUP         0               /* legacy support register */
-#define EHCI_USBLEGSUP_BIOS    (1 << 16)       /* BIOS semaphore */
-#define EHCI_USBLEGSUP_OS      (1 << 24)       /* OS semaphore */
-#define EHCI_USBLEGCTLSTS      4               /* legacy control/status */
-#define EHCI_USBLEGCTLSTS_SOOE (1 << 13)       /* SMI on ownership change */
-
-int usb_early_handoff __devinitdata = 0;
-static int __init usb_handoff_early(char *str)
-{
-       usb_early_handoff = 1;
-       return 0;
-}
-__setup("usb-handoff", usb_handoff_early);
-
-static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
-{
-       unsigned long base = 0;
-       int wait_time, delta;
-       u16 val, sts;
-       int i;
-
-       for (i = 0; i < PCI_ROM_RESOURCE; i++)
-               if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
-                       base = pci_resource_start(pdev, i);
-                       break;
-               }
-
-       if (!base)
-               return;
-
-       /*
-        * stop controller
-        */
-       sts = inw(base + UHCI_USBSTS);
-       val = inw(base + UHCI_USBCMD);
-       val &= ~(u16)(UHCI_USBCMD_RUN | UHCI_USBCMD_CONFIGURE);
-       outw(val, base + UHCI_USBCMD);
-
-       /*
-        * wait while it stops if it was running
-        */
-       if ((sts & UHCI_USBSTS_HALTED) == 0)
-       {
-               wait_time = 1000;
-               delta = 100;
-
-               do {
-                       outw(0x1f, base + UHCI_USBSTS);
-                       udelay(delta);
-                       wait_time -= delta;
-                       val = inw(base + UHCI_USBSTS);
-                       if (val & UHCI_USBSTS_HALTED)
-                               break;
-               } while (wait_time > 0);
-       }
-
-       /*
-        * disable interrupts & legacy support
-        */
-       outw(0, base + UHCI_USBINTR);
-       outw(0x1f, base + UHCI_USBSTS);
-       pci_read_config_word(pdev, UHCI_USBLEGSUP, &val);
-       if (val & 0xbf) 
-               pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT);
-               
-}
-
-static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
-{
-       void __iomem *base;
-       int wait_time;
-
-       base = ioremap_nocache(pci_resource_start(pdev, 0),
-                                    pci_resource_len(pdev, 0));
-       if (base == NULL) return;
-
-       if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
-               wait_time = 500; /* 0.5 seconds */
-               writel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
-               writel(OHCI_OCR, base + OHCI_CMDSTATUS);
-               while (wait_time > 0 && 
-                               readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
-                       wait_time -= 10;
-                       msleep(10);
-               }
-       }
-
-       /*
-        * disable interrupts
-        */
-       writel(~(u32)0, base + OHCI_INTRDISABLE);
-       writel(~(u32)0, base + OHCI_INTRSTATUS);
-
-       iounmap(base);
-}
-
-static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
-{
-       int wait_time, delta;
-       void __iomem *base, *op_reg_base;
-       u32 hcc_params, val, temp;
-       u8 cap_length;
-
-       base = ioremap_nocache(pci_resource_start(pdev, 0),
-                               pci_resource_len(pdev, 0));
-       if (base == NULL) return;
-
-       cap_length = readb(base);
-       op_reg_base = base + cap_length;
-       hcc_params = readl(base + EHCI_HCC_PARAMS);
-       hcc_params = (hcc_params >> 8) & 0xff;
-       if (hcc_params) {
-               pci_read_config_dword(pdev, 
-                                       hcc_params + EHCI_USBLEGSUP,
-                                       &val);
-               if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) {
-                       /*
-                        * Ok, BIOS is in smm mode, try to hand off...
-                        */
-                       pci_read_config_dword(pdev,
-                                               hcc_params + EHCI_USBLEGCTLSTS,
-                                               &temp);
-                       pci_write_config_dword(pdev,
-                                               hcc_params + EHCI_USBLEGCTLSTS,
-                                               temp | EHCI_USBLEGCTLSTS_SOOE);
-                       val |= EHCI_USBLEGSUP_OS;
-                       pci_write_config_dword(pdev, 
-                                               hcc_params + EHCI_USBLEGSUP, 
-                                               val);
-
-                       wait_time = 500;
-                       do {
-                               msleep(10);
-                               wait_time -= 10;
-                               pci_read_config_dword(pdev,
-                                               hcc_params + EHCI_USBLEGSUP,
-                                               &val);
-                       } while (wait_time && (val & EHCI_USBLEGSUP_BIOS));
-                       if (!wait_time) {
-                               /*
-                                * well, possibly buggy BIOS...
-                                */
-                               printk(KERN_WARNING "EHCI early BIOS handoff "
-                                               "failed (BIOS bug ?)\n");
-                               pci_write_config_dword(pdev,
-                                               hcc_params + EHCI_USBLEGSUP,
-                                               EHCI_USBLEGSUP_OS);
-                               pci_write_config_dword(pdev,
-                                               hcc_params + EHCI_USBLEGCTLSTS,
-                                               0);
-                       }
-               }
-       }
-
-       /*
-        * halt EHCI & disable its interrupts in any case
-        */
-       val = readl(op_reg_base + EHCI_USBSTS);
-       if ((val & EHCI_USBSTS_HALTED) == 0) {
-               val = readl(op_reg_base + EHCI_USBCMD);
-               val &= ~EHCI_USBCMD_RUN;
-               writel(val, op_reg_base + EHCI_USBCMD);
-
-               wait_time = 2000;
-               delta = 100;
-               do {
-                       writel(0x3f, op_reg_base + EHCI_USBSTS);
-                       udelay(delta);
-                       wait_time -= delta;
-                       val = readl(op_reg_base + EHCI_USBSTS);
-                       if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
-                               break;
-                       }
-               } while (wait_time > 0);
-       }
-       writel(0, op_reg_base + EHCI_USBINTR);
-       writel(0x3f, op_reg_base + EHCI_USBSTS);
-
-       iounmap(base);
-
-       return;
-}
-
-
-
-static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
-{
-       if (!usb_early_handoff)
-               return;
-
-       if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */
-               quirk_usb_handoff_uhci(pdev);
-       } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */
-               quirk_usb_handoff_ohci(pdev);
-       } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x20)) { /* EHCI */
-               quirk_usb_disable_ehci(pdev);
-       }
-
-       return;
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
-
 /*
  * ... This is further complicated by the fact that some SiS96x south
  * bridges pretend to be 85C503/5513 instead.  In that case see if we
@@ -1308,6 +1098,23 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_EESSC,      quirk_alder_ioapic );
 #endif
 
+enum ide_combined_type { COMBINED = 0, IDE = 1, LIBATA = 2 };
+/* Defaults to combined */
+static enum ide_combined_type combined_mode;
+
+static int __init combined_setup(char *str)
+{
+       if (!strncmp(str, "ide", 3))
+               combined_mode = IDE;
+       else if (!strncmp(str, "libata", 6))
+               combined_mode = LIBATA;
+       else /* "combined" or anything else defaults to old behavior */
+               combined_mode = COMBINED;
+
+       return 1;
+}
+__setup("combined_mode=", combined_setup);
+
 #ifdef CONFIG_SCSI_SATA_INTEL_COMBINED
 static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
 {
@@ -1374,6 +1181,19 @@ static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
        if (prog & comb)
                return;
 
+       /* Don't reserve any so the IDE driver can get them (but only if
+        * combined_mode=ide).
+        */
+       if (combined_mode == IDE)
+               return;
+
+       /* Grab them both for libata if combined_mode=libata. */
+       if (combined_mode == LIBATA) {
+               request_region(0x1f0, 8, "libata");     /* port 0 */
+               request_region(0x170, 8, "libata");     /* port 1 */
+               return;
+       }
+
        /* SATA port is in legacy mode.  Reserve port so that
         * IDE driver does not attempt to use it.  If request_region
         * fails, it will be obvious at boot time, so we don't bother
@@ -1453,6 +1273,21 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos);
 
+
+static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
+{
+       /* rev 1 ncr53c810 chips don't set the class at all which means
+        * they don't get their resources remapped. Fix that here.
+        */
+
+       if (dev->class == PCI_CLASS_NOT_DEFINED) {
+               printk(KERN_INFO "NCR 53c810 rev 1 detected, setting PCI class.\n");
+               dev->class = PCI_CLASS_STORAGE_SCSI;
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
+
+
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
 {
        while (f < end) {