diff options
author | Andy Whitcroft <apw@canonical.com> | 2012-03-08 11:32:35 +0000 |
---|---|---|
committer | John Rigby <john.rigby@linaro.org> | 2012-06-25 12:17:07 -0600 |
commit | ca1f02934fe9e787964e697af602ba06d0c962fd (patch) | |
tree | 7ae12c3ae9a5f8f517a426e20a246a82c6c9fd6b | |
parent | f9b761cb9967b2dbca7e22c2e73bbbd3356681ef (diff) |
UBUNTU: SAUCE: ata_piix: defer disks to the Hyper-V drivers by default
When we are hosted on a Microsoft Hyper-V hypervisor the guest disks
are exposed both via the Hyper-V paravirtualised drivers and via an
emulated SATA disk drive. In this case we want to use the paravirtualised
drivers if we can as they are much more efficient. Note that the Hyper-V
paravirtualised drivers only expose the virtual hard disk devices, the
CDROM/DVD devices must still be enumerated.
Check the disk type when picking up its ID and if it appears to be a
disk just report it disconnected.
BugLink: http://bugs.launchpad.net/bugs/929545
BugLink: http://bugs.launchpad.net/bugs/942316
Signed-off-by: Andy Whitcroft <apw@canonical.com>
-rw-r--r-- | drivers/ata/ata_piix.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 7857e8fd0a3..de29a866cef 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -94,6 +94,9 @@ #include <scsi/scsi_host.h> #include <linux/libata.h> #include <linux/dmi.h> +#ifdef CONFIG_X86 +#include <asm/hypervisor.h> +#endif #define DRV_NAME "ata_piix" #define DRV_VERSION "2.13" @@ -188,6 +191,29 @@ static int piix_pci_device_resume(struct pci_dev *pdev); static unsigned int in_module_init = 1; +static int prefer_ms_hyperv = 1; + +unsigned int ata_piix_read_id(struct ata_device *dev, + struct ata_taskfile *tf, u16 *id) +{ + int ret = ata_do_dev_read_id(dev, tf, id); + +#ifdef CONFIG_X86 + /* XXX: note that the device id is in little-endian order, the caller + * will shift it to host order, but we are working with little-endian. + * As this is _only_ used on x86 we can actually directly access it + * as host is also little-endian. + */ + if (!ret && prefer_ms_hyperv && x86_hyper == &x86_hyper_ms_hyperv && + ata_id_is_ata(id)) { + ata_dev_printk(dev, KERN_WARNING, "ATA disk ignored deferring to Hyper-V paravirt driver\n"); + + return AC_ERR_DEV|AC_ERR_NODEV_HINT; + } +#endif + return ret; +} + static const struct pci_device_id piix_pci_tbl[] = { /* Intel PIIX3 for the 430HX etc */ { 0x8086, 0x7010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_mwdma }, @@ -361,6 +387,7 @@ static struct ata_port_operations piix_pata_ops = { .set_piomode = piix_set_piomode, .set_dmamode = piix_set_dmamode, .prereset = piix_pata_prereset, + .read_id = ata_piix_read_id, }; static struct ata_port_operations piix_vmw_ops = { @@ -1705,3 +1732,5 @@ static void __exit piix_exit(void) module_init(piix_init); module_exit(piix_exit); + +module_param(prefer_ms_hyperv, int, 0); |