2011-02-16 19:46:03

by Jeff Garzik

[permalink] [raw]
Subject: Re: [Patch] enable AHCI mode on certain ich chipsets

On 02/16/2011 04:05 AM, Joerg Dorchain wrote:
> Hello all,
>
> this patch allows to force ICH7/8/9 into AHCI mode. This is needed
> because some BIOSes do not make AHCI-mode operation available to the
> user.
> As the Intel documentation states that the OS should not carry
> out the operation - the user must force this on the kernel
> commandline using quirk_ich_force_ahci
>
> As this quirk gets called whilst the PCI subsystem is
> walking the PCI bus, we declare this quirk against the LPC
> (device 00:1f.0), so that we can frob 00:1f.2 before the PCI
> code has scanned it.
> Note: the pci id might change due to this (e.g. from 27c4 to 27c5)
>
> For working suspend/resume, the next patch is required, too.
>
> Bye,
>
> Joerg
>
>
> Signed-Off-By: joerg Dorchain<[email protected]>
>
> --- linux/drivers/pci/quirks.c.orig 2011-02-04 18:29:03.000000000 +0100
> +++ linux/drivers/pci/quirks.c 2011-02-12 07:07:57.000000000 +0100
> @@ -2684,6 +2684,74 @@
> DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0020, quirk_hotplug_bridge);
>
> /*
> + * Force ICH7/8/9 into AHCI mode. This is needed because some
> + * BIOSes do not make AHCI-mode operation available to the user.
> + * As the Intel documentation states that the OS should not carry
> + * out the operation - the user must force this on the kernel
> + * commandline using quirk_ich_force_ahci
> + *
> + * As this quirk gets called whilst the PCI subsystem is
> + * walking the PCI bus, we declare this quirk against the LPC
> + * (device 00:1f.0), so that we can frob 00:1f.2 before the PCI
> + * code has scanned it.
> + * Note: the pci id might change due to this (e.g. from 27c4 to 27c5)
> + *
> + */
> +
> +static bool ich_force_ahci_mode; /* defaults to false */
> +
> +static int __init ich789_force_ahci_mode_setup(char *str)
> +{
> + ich_force_ahci_mode = true;
> + return 0;
> +}
> +early_param("quirk_ich_force_ahci", ich789_force_ahci_mode_setup);
> +
> +static void ich789_force_ahci_mode(struct pci_dev *pdev)
> +{
> + u8 amrval;
> + u8 sclkgc;
> + const int ich89_address_map_reg = 0x90;
> + const int ich89_sata_clock_gen_config_reg = 0x9c;
> +
> + if (!ich_force_ahci_mode)
> + return;
> +
> + /* ICH8 datasheet section 12.1.33 */
> + if (!pci_bus_read_config_byte(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
> + ich89_address_map_reg,&amrval)) {
> +
> + if (amrval& (BIT(6) | BIT(7))) {
> + dev_printk(KERN_DEBUG,&pdev->dev,
> + "ICH7/8/9 SATA controller not in IDE mode. Not modifying.\n");
> + return;
> + }
> + if (amrval& (BIT(0) | BIT(1)))
> + dev_printk(KERN_DEBUG,&pdev->dev,
> + "ICH7/8/9 in SATA/PATA combined mode. Untested.\n");
> + /* AHCI mode */
> + amrval |= BIT(6);
> + amrval&= ~BIT(7);
> + pci_bus_read_config_byte(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
> + ich89_sata_clock_gen_config_reg,&sclkgc);
> + dev_printk(KERN_DEBUG,&pdev->dev, "sclkgc is %#0x\n", sclkgc);
> + pci_bus_write_config_byte(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
> + ich89_address_map_reg, amrval);
> + dev_printk(KERN_DEBUG,&pdev->dev, "Forced ICH7/8/9 mode PIIX->AHCI\n");

How is the assignment of the AHCI BAR handled? Does this happen
automatically because it's an early fixup?

That is traditionally the stumbling block...

Jeff


2011-02-17 16:37:06

by Matthew Garrett

[permalink] [raw]
Subject: Re: [Patch] enable AHCI mode on certain ich chipsets

On Wed, Feb 16, 2011 at 02:45:56PM -0500, Jeff Garzik wrote:

> How is the assignment of the AHCI BAR handled? Does this happen
> automatically because it's an early fixup?
>
> That is traditionally the stumbling block...

Yes, because it's an early fixup the kernel should allocate it itself.
It's small enough that I'd hope we don't have trouble finding one...

--
Matthew Garrett | [email protected]

2011-02-17 17:48:02

by Joerg Dorchain

[permalink] [raw]
Subject: Re: [Patch] enable AHCI mode on certain ich chipsets

On Wed, Feb 16, 2011 at 02:45:56PM -0500, Jeff Garzik wrote:
> >this patch allows to force ICH7/8/9 into AHCI mode. This is needed
> >because some BIOSes do not make AHCI-mode operation available to the
> >user.
> >As the Intel documentation states that the OS should not carry
> >out the operation - the user must force this on the kernel
> >commandline using quirk_ich_force_ahci
> >
> >As this quirk gets called whilst the PCI subsystem is
> >walking the PCI bus, we declare this quirk against the LPC
> >(device 00:1f.0), so that we can frob 00:1f.2 before the PCI
> >code has scanned it.
> >Note: the pci id might change due to this (e.g. from 27c4 to 27c5)
> >
> >For working suspend/resume, the next patch is required, too.
> >
> >Bye,
> >
> >Joerg
> >
> >
> >Signed-Off-By: joerg Dorchain<[email protected]>
> >
> >--- linux/drivers/pci/quirks.c.orig 2011-02-04 18:29:03.000000000 +0100
> >+++ linux/drivers/pci/quirks.c 2011-02-12 07:07:57.000000000 +0100
> >@@ -2684,6 +2684,74 @@
> > DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0020, quirk_hotplug_bridge);
> >
> > /*
> >+ * Force ICH7/8/9 into AHCI mode. This is needed because some
> >+ * BIOSes do not make AHCI-mode operation available to the user.
> >+ * As the Intel documentation states that the OS should not carry
> >+ * out the operation - the user must force this on the kernel
> >+ * commandline using quirk_ich_force_ahci
> >+ *
> >+ * As this quirk gets called whilst the PCI subsystem is
> >+ * walking the PCI bus, we declare this quirk against the LPC
> >+ * (device 00:1f.0), so that we can frob 00:1f.2 before the PCI
> >+ * code has scanned it.
> >+ * Note: the pci id might change due to this (e.g. from 27c4 to 27c5)
> >+ *
> >+ */
> >+
> >+static bool ich_force_ahci_mode; /* defaults to false */
> >+
> >+static int __init ich789_force_ahci_mode_setup(char *str)
> >+{
> >+ ich_force_ahci_mode = true;
> >+ return 0;
> >+}
> >+early_param("quirk_ich_force_ahci", ich789_force_ahci_mode_setup);
> >+
> >+static void ich789_force_ahci_mode(struct pci_dev *pdev)
> >+{
> >+ u8 amrval;
> >+ u8 sclkgc;
> >+ const int ich89_address_map_reg = 0x90;
> >+ const int ich89_sata_clock_gen_config_reg = 0x9c;
> >+
> >+ if (!ich_force_ahci_mode)
> >+ return;
> >+
> >+ /* ICH8 datasheet section 12.1.33 */
> >+ if (!pci_bus_read_config_byte(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
> >+ ich89_address_map_reg,&amrval)) {
> >+
> >+ if (amrval& (BIT(6) | BIT(7))) {
> >+ dev_printk(KERN_DEBUG,&pdev->dev,
> >+ "ICH7/8/9 SATA controller not in IDE mode. Not modifying.\n");
> >+ return;
> >+ }
> >+ if (amrval& (BIT(0) | BIT(1)))
> >+ dev_printk(KERN_DEBUG,&pdev->dev,
> >+ "ICH7/8/9 in SATA/PATA combined mode. Untested.\n");
> >+ /* AHCI mode */
> >+ amrval |= BIT(6);
> >+ amrval&= ~BIT(7);
> >+ pci_bus_read_config_byte(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
> >+ ich89_sata_clock_gen_config_reg,&sclkgc);
> >+ dev_printk(KERN_DEBUG,&pdev->dev, "sclkgc is %#0x\n", sclkgc);
> >+ pci_bus_write_config_byte(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
> >+ ich89_address_map_reg, amrval);
> >+ dev_printk(KERN_DEBUG,&pdev->dev, "Forced ICH7/8/9 mode PIIX->AHCI\n");
>
> How is the assignment of the AHCI BAR handled? Does this happen
> automatically because it's an early fixup?

For me, it does:
Region 0: I/O ports at b400 [size=8]
Region 1: I/O ports at b080 [size=4]
Region 2: I/O ports at b000 [size=8]
Region 3: I/O ports at ac80 [size=4]
Region 4: I/O ports at ac00 [size=16]
Region 5: Memory at fe837800 (32-bit, non-prefetchable) [size=1K]

>
> That is traditionally the stumbling block...

This quirk relies on the fact the the device on 00:1f.0 is
scanned earlier than the device at 00:1f.2, so when the scan
reaches 00:1f.2, the device there is just ok for the ahci driver.

Bye,

Joerg


Attachments:
(No filename) (3.79 kB)
signature.asc (267.00 B)
Digital signature
Download all attachments

2011-02-17 22:52:40

by Mark Lord

[permalink] [raw]
Subject: Re: [Patch] enable AHCI mode on certain ich chipsets

On 11-02-17 11:36 AM, Matthew Garrett wrote:
> On Wed, Feb 16, 2011 at 02:45:56PM -0500, Jeff Garzik wrote:
>
>> How is the assignment of the AHCI BAR handled? Does this happen
>> automatically because it's an early fixup?
>>
>> That is traditionally the stumbling block...
>
> Yes, because it's an early fixup the kernel should allocate it itself.
> It's small enough that I'd hope we don't have trouble finding one...


It works here (the AHCI BAR setup) with this patch,
though the workaround itself doesn't work because my
Dell machine requires extra/secret fiddling to switch
things fully over to AHCI.

The patch does seem harmless enough to include in the kernel, though.