in sata_mv.c [3763:3905]
static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
{
struct pci_dev *pdev = to_pci_dev(host->dev);
struct mv_host_priv *hpriv = host->private_data;
u32 hp_flags = hpriv->hp_flags;
switch (board_idx) {
case chip_5080:
hpriv->ops = &mv5xxx_ops;
hp_flags |= MV_HP_GEN_I;
switch (pdev->revision) {
case 0x1:
hp_flags |= MV_HP_ERRATA_50XXB0;
break;
case 0x3:
hp_flags |= MV_HP_ERRATA_50XXB2;
break;
default:
dev_warn(&pdev->dev,
"Applying 50XXB2 workarounds to unknown rev\n");
hp_flags |= MV_HP_ERRATA_50XXB2;
break;
}
break;
case chip_504x:
case chip_508x:
hpriv->ops = &mv5xxx_ops;
hp_flags |= MV_HP_GEN_I;
switch (pdev->revision) {
case 0x0:
hp_flags |= MV_HP_ERRATA_50XXB0;
break;
case 0x3:
hp_flags |= MV_HP_ERRATA_50XXB2;
break;
default:
dev_warn(&pdev->dev,
"Applying B2 workarounds to unknown rev\n");
hp_flags |= MV_HP_ERRATA_50XXB2;
break;
}
break;
case chip_604x:
case chip_608x:
hpriv->ops = &mv6xxx_ops;
hp_flags |= MV_HP_GEN_II;
switch (pdev->revision) {
case 0x7:
mv_60x1b2_errata_pci7(host);
hp_flags |= MV_HP_ERRATA_60X1B2;
break;
case 0x9:
hp_flags |= MV_HP_ERRATA_60X1C0;
break;
default:
dev_warn(&pdev->dev,
"Applying B2 workarounds to unknown rev\n");
hp_flags |= MV_HP_ERRATA_60X1B2;
break;
}
break;
case chip_7042:
hp_flags |= MV_HP_PCIE | MV_HP_CUT_THROUGH;
if (pdev->vendor == PCI_VENDOR_ID_TTI &&
(pdev->device == 0x2300 || pdev->device == 0x2310))
{
/*
* Highpoint RocketRAID PCIe 23xx series cards:
*
* Unconfigured drives are treated as "Legacy"
* by the BIOS, and it overwrites sector 8 with
* a "Lgcy" metadata block prior to Linux boot.
*
* Configured drives (RAID or JBOD) leave sector 8
* alone, but instead overwrite a high numbered
* sector for the RAID metadata. This sector can
* be determined exactly, by truncating the physical
* drive capacity to a nice even GB value.
*
* RAID metadata is at: (dev->n_sectors & ~0xfffff)
*
* Warn the user, lest they think we're just buggy.
*/
dev_warn(&pdev->dev, "Highpoint RocketRAID"
" BIOS CORRUPTS DATA on all attached drives,"
" regardless of if/how they are configured."
" BEWARE!\n");
dev_warn(&pdev->dev, "For data safety, do not"
" use sectors 8-9 on \"Legacy\" drives,"
" and avoid the final two gigabytes on"
" all RocketRAID BIOS initialized drives.\n");
}
fallthrough;
case chip_6042:
hpriv->ops = &mv6xxx_ops;
hp_flags |= MV_HP_GEN_IIE;
if (board_idx == chip_6042 && mv_pci_cut_through_okay(host))
hp_flags |= MV_HP_CUT_THROUGH;
switch (pdev->revision) {
case 0x2: /* Rev.B0: the first/only public release */
hp_flags |= MV_HP_ERRATA_60X1C0;
break;
default:
dev_warn(&pdev->dev,
"Applying 60X1C0 workarounds to unknown rev\n");
hp_flags |= MV_HP_ERRATA_60X1C0;
break;
}
break;
case chip_soc:
if (soc_is_65n(hpriv))
hpriv->ops = &mv_soc_65n_ops;
else
hpriv->ops = &mv_soc_ops;
hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
MV_HP_ERRATA_60X1C0;
break;
default:
dev_alert(host->dev, "BUG: invalid board index %u\n", board_idx);
return -EINVAL;
}
hpriv->hp_flags = hp_flags;
if (hp_flags & MV_HP_PCIE) {
hpriv->irq_cause_offset = PCIE_IRQ_CAUSE;
hpriv->irq_mask_offset = PCIE_IRQ_MASK;
hpriv->unmask_all_irqs = PCIE_UNMASK_ALL_IRQS;
} else {
hpriv->irq_cause_offset = PCI_IRQ_CAUSE;
hpriv->irq_mask_offset = PCI_IRQ_MASK;
hpriv->unmask_all_irqs = PCI_UNMASK_ALL_IRQS;
}
return 0;
}