Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c621b140 authored by Alan Cox's avatar Alan Cox Committed by Jeff Garzik
Browse files

[PATCH] libata: ata_piix 450NX errata



Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 9da305eb
Loading
Loading
Loading
Loading
+43 −1
Original line number Diff line number Diff line
@@ -619,6 +619,40 @@ static int piix_disable_ahci(struct pci_dev *pdev)
	return rc;
}

/**
 *	piix_check_450nx_errata	-	Check for problem 450NX setup
 *	
 *	Check for the present of 450NX errata #19 and errata #25. If
 *	they are found return an error code so we can turn off DMA
 */

static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
{
	struct pci_dev *pdev = NULL;
	u16 cfg;
	u8 rev;
	int no_piix_dma = 0;
	
	while((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev)) != NULL)
	{
		/* Look for 450NX PXB. Check for problem configurations
		   A PCI quirk checks bit 6 already */
		pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
		pci_read_config_word(pdev, 0x41, &cfg);
		/* Only on the original revision: IDE DMA can hang */
		if(rev == 0x00)
			no_piix_dma = 1;
		/* On all revisions below 5 PXB bus lock must be disabled for IDE */
		else if(cfg & (1<<14) && rev < 5)
			no_piix_dma = 2;
	}
	if(no_piix_dma)
		dev_printk(KERN_WARNING, &ata_dev->dev, "450NX errata present, disabling IDE DMA.\n");
	if(no_piix_dma == 2)
		dev_printk(KERN_WARNING, &ata_dev->dev, "A BIOS update may resolve this.\n");
	return no_piix_dma;
}		

/**
 *	piix_init_one - Register PIIX ATA PCI device with kernel services
 *	@pdev: PCI device to register
@@ -693,7 +727,15 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
			   "combined mode detected (p=%u, s=%u)\n",
			   pata_chan, sata_chan);
	}

	if (piix_check_450nx_errata(pdev)) {
		/* This writes into the master table but it does not
		   really matter for this errata as we will apply it to
		   all the PIIX devices on the board */
		port_info[0]->mwdma_mask = 0;
		port_info[0]->udma_mask = 0;
		port_info[1]->mwdma_mask = 0;
		port_info[1]->udma_mask = 0;
	}
	return ata_pci_init_one(pdev, port_info, 2);
}