Commit 59d0952b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev

Pull libata update from Jeff Garzik:
 "Changes, all of them boring and minor:

  1) Ugly MSFT Hyper-V workaround in ata_piix

  2) Fix a longstanding error recovery delay caused by excessive
     re-re-retries, when media errors occur.

  3) Minor hw-specific workarounds and quirks

  4) New PATA driver for ep93xx"

* tag 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  PATA host controller driver for ep93xx
  [libata] Add " 2GB ATA Flash Disk"/"ADMA428M" to DMA blacklist
  ata_generic: Skip is_intel_ider() check when ata_generic=1 is set
  libata-eh don't waste time retrying media errors (v3)
  ata_piix: defer disks to the Hyper-V drivers by default
  libata: add a host flag to ignore detected ATA devices
parents 1259f6ee 2fff2751
...@@ -416,6 +416,15 @@ config PATA_EFAR ...@@ -416,6 +416,15 @@ config PATA_EFAR
If unsure, say N. If unsure, say N.
config PATA_EP93XX
tristate "Cirrus Logic EP93xx PATA support"
depends on ARCH_EP93XX
help
This option enables support for the PATA controller in
the Cirrus Logic EP9312 and EP9315 ARM CPU.
If unsure, say N.
config PATA_HPT366 config PATA_HPT366
tristate "HPT 366/368 PATA support" tristate "HPT 366/368 PATA support"
depends on PCI depends on PCI
......
...@@ -43,6 +43,7 @@ obj-$(CONFIG_PATA_CS5535) += pata_cs5535.o ...@@ -43,6 +43,7 @@ obj-$(CONFIG_PATA_CS5535) += pata_cs5535.o
obj-$(CONFIG_PATA_CS5536) += pata_cs5536.o obj-$(CONFIG_PATA_CS5536) += pata_cs5536.o
obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o
obj-$(CONFIG_PATA_EFAR) += pata_efar.o obj-$(CONFIG_PATA_EFAR) += pata_efar.o
obj-$(CONFIG_PATA_EP93XX) += pata_ep93xx.o
obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o
obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o
obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o
......
...@@ -177,7 +177,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id ...@@ -177,7 +177,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
if ((id->driver_data & ATA_GEN_CLASS_MATCH) && all_generic_ide == 0) if ((id->driver_data & ATA_GEN_CLASS_MATCH) && all_generic_ide == 0)
return -ENODEV; return -ENODEV;
if (id->driver_data & ATA_GEN_INTEL_IDER) if ((id->driver_data & ATA_GEN_INTEL_IDER) && !all_generic_ide)
if (!is_intel_ider(dev)) if (!is_intel_ider(dev))
return -ENODEV; return -ENODEV;
......
...@@ -1554,6 +1554,39 @@ static bool piix_broken_system_poweroff(struct pci_dev *pdev) ...@@ -1554,6 +1554,39 @@ static bool piix_broken_system_poweroff(struct pci_dev *pdev)
return false; return false;
} }
static int prefer_ms_hyperv = 1;
module_param(prefer_ms_hyperv, int, 0);
static void piix_ignore_devices_quirk(struct ata_host *host)
{
#if IS_ENABLED(CONFIG_HYPERV_STORAGE)
static const struct dmi_system_id ignore_hyperv[] = {
{
/* On Hyper-V hypervisors the disks are exposed on
* both the emulated SATA controller and on the
* paravirtualised drivers. The CD/DVD devices
* are only exposed on the emulated controller.
* Request we ignore ATA devices on this host.
*/
.ident = "Hyper-V Virtual Machine",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR,
"Microsoft Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
},
},
{ } /* terminate list */
};
const struct dmi_system_id *dmi = dmi_first_match(ignore_hyperv);
if (dmi && prefer_ms_hyperv) {
host->flags |= ATA_HOST_IGNORE_ATA;
dev_info(host->dev, "%s detected, ATA device ignore set\n",
dmi->ident);
}
#endif
}
/** /**
* piix_init_one - Register PIIX ATA PCI device with kernel services * piix_init_one - Register PIIX ATA PCI device with kernel services
* @pdev: PCI device to register * @pdev: PCI device to register
...@@ -1669,6 +1702,9 @@ static int __devinit piix_init_one(struct pci_dev *pdev, ...@@ -1669,6 +1702,9 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
} }
host->flags |= ATA_HOST_PARALLEL_SCAN; host->flags |= ATA_HOST_PARALLEL_SCAN;
/* Allow hosts to specify device types to ignore when scanning. */
piix_ignore_devices_quirk(host);
pci_set_master(pdev); pci_set_master(pdev);
return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
} }
......
...@@ -1973,6 +1973,12 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, ...@@ -1973,6 +1973,12 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
if (class == ATA_DEV_ATA) { if (class == ATA_DEV_ATA) {
if (!ata_id_is_ata(id) && !ata_id_is_cfa(id)) if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
goto err_out; goto err_out;
if (ap->host->flags & ATA_HOST_IGNORE_ATA &&
ata_id_is_ata(id)) {
ata_dev_dbg(dev,
"host indicates ignore ATA devices, ignored\n");
return -ENOENT;
}
} else { } else {
if (ata_id_is_ata(id)) if (ata_id_is_ata(id))
goto err_out; goto err_out;
...@@ -4051,6 +4057,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ...@@ -4051,6 +4057,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA },
{ "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA },
{ "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA },
{ "2GB ATA Flash Disk", "ADMA428M", ATA_HORKAGE_NODMA },
/* Odd clown on sil3726/4726 PMPs */ /* Odd clown on sil3726/4726 PMPs */
{ "Config Disk", NULL, ATA_HORKAGE_DISABLE }, { "Config Disk", NULL, ATA_HORKAGE_DISABLE },
......
...@@ -2046,6 +2046,26 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, ...@@ -2046,6 +2046,26 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,
return action; return action;
} }
/**
* ata_eh_worth_retry - analyze error and decide whether to retry
* @qc: qc to possibly retry
*
* Look at the cause of the error and decide if a retry
* might be useful or not. We don't want to retry media errors
* because the drive itself has probably already taken 10-30 seconds
* doing its own internal retries before reporting the failure.
*/
static inline int ata_eh_worth_retry(struct ata_queued_cmd *qc)
{
if (qc->flags & AC_ERR_MEDIA)
return 0; /* don't retry media errors */
if (qc->flags & ATA_QCFLAG_IO)
return 1; /* otherwise retry anything from fs stack */
if (qc->err_mask & AC_ERR_INVALID)
return 0; /* don't retry these */
return qc->err_mask != AC_ERR_DEV; /* retry if not dev error */
}
/** /**
* ata_eh_link_autopsy - analyze error and determine recovery action * ata_eh_link_autopsy - analyze error and determine recovery action
* @link: host link to perform autopsy on * @link: host link to perform autopsy on
...@@ -2120,9 +2140,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) ...@@ -2120,9 +2140,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)
qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
/* determine whether the command is worth retrying */ /* determine whether the command is worth retrying */
if (qc->flags & ATA_QCFLAG_IO || if (ata_eh_worth_retry(qc))
(!(qc->err_mask & AC_ERR_INVALID) &&
qc->err_mask != AC_ERR_DEV))
qc->flags |= ATA_QCFLAG_RETRY; qc->flags |= ATA_QCFLAG_RETRY;
/* accumulate error info */ /* accumulate error info */
......
This diff is collapsed.
...@@ -247,6 +247,7 @@ enum { ...@@ -247,6 +247,7 @@ enum {
ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host only */ ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host only */
ATA_HOST_STARTED = (1 << 1), /* Host started */ ATA_HOST_STARTED = (1 << 1), /* Host started */
ATA_HOST_PARALLEL_SCAN = (1 << 2), /* Ports on this host can be scanned in parallel */ ATA_HOST_PARALLEL_SCAN = (1 << 2), /* Ports on this host can be scanned in parallel */
ATA_HOST_IGNORE_ATA = (1 << 3), /* Ignore ATA devices on this host. */
/* bits 24:31 of host->flags are reserved for LLD specific flags */ /* bits 24:31 of host->flags are reserved for LLD specific flags */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment