Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: ata_piix: add workaround for Samsung DB-P70 libata: Keep shadow last_ctl up to date during resets sata_mv: fix MSI irq race condition
This commit is contained in:
Коммит
37e79a43ac
|
@ -1289,6 +1289,39 @@ static const int *__devinit piix_init_sata_map(struct pci_dev *pdev,
|
|||
return map;
|
||||
}
|
||||
|
||||
static bool piix_no_sidpr(struct ata_host *host)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
|
||||
/*
|
||||
* Samsung DB-P70 only has three ATA ports exposed and
|
||||
* curiously the unconnected first port reports link online
|
||||
* while not responding to SRST protocol causing excessive
|
||||
* detection delay.
|
||||
*
|
||||
* Unfortunately, the system doesn't carry enough DMI
|
||||
* information to identify the machine but does have subsystem
|
||||
* vendor and device set. As it's unclear whether the
|
||||
* subsystem vendor/device is used only for this specific
|
||||
* board, the port can't be disabled solely with the
|
||||
* information; however, turning off SIDPR access works around
|
||||
* the problem. Turn it off.
|
||||
*
|
||||
* This problem is reported in bnc#441240.
|
||||
*
|
||||
* https://bugzilla.novell.com/show_bug.cgi?id=441420
|
||||
*/
|
||||
if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2920 &&
|
||||
pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG &&
|
||||
pdev->subsystem_device == 0xb049) {
|
||||
dev_printk(KERN_WARNING, host->dev,
|
||||
"Samsung DB-P70 detected, disabling SIDPR\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int __devinit piix_init_sidpr(struct ata_host *host)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(host->dev);
|
||||
|
@ -1302,6 +1335,10 @@ static int __devinit piix_init_sidpr(struct ata_host *host)
|
|||
if (hpriv->map[i] == IDE)
|
||||
return 0;
|
||||
|
||||
/* is it blacklisted? */
|
||||
if (piix_no_sidpr(host))
|
||||
return 0;
|
||||
|
||||
if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR))
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -2066,6 +2066,7 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
|
|||
iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
|
||||
udelay(20); /* FIXME: flush */
|
||||
iowrite8(ap->ctl, ioaddr->ctl_addr);
|
||||
ap->last_ctl = ap->ctl;
|
||||
|
||||
/* wait the port to become ready */
|
||||
return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
|
||||
|
@ -2190,8 +2191,10 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
|
|||
}
|
||||
|
||||
/* set up device control */
|
||||
if (ap->ioaddr.ctl_addr)
|
||||
if (ap->ioaddr.ctl_addr) {
|
||||
iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
|
||||
ap->last_ctl = ap->ctl;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sff_postreset);
|
||||
|
||||
|
@ -2534,6 +2537,7 @@ void ata_bus_reset(struct ata_port *ap)
|
|||
if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
|
||||
/* set up device control for ATA_FLAG_SATA_RESET */
|
||||
iowrite8(ap->ctl, ioaddr->ctl_addr);
|
||||
ap->last_ctl = ap->ctl;
|
||||
}
|
||||
|
||||
DPRINTK("EXIT\n");
|
||||
|
|
|
@ -2218,12 +2218,13 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
|
|||
else
|
||||
handled = mv_host_intr(host, pending_irqs);
|
||||
}
|
||||
spin_unlock(&host->lock);
|
||||
|
||||
/* for MSI: unmask; interrupt cause bits will retrigger now */
|
||||
if (using_msi)
|
||||
writel(hpriv->main_irq_mask, hpriv->main_irq_mask_addr);
|
||||
|
||||
spin_unlock(&host->lock);
|
||||
|
||||
return IRQ_RETVAL(handled);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче