aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_it821x.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-03-24 23:22:47 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:16 -0400
commitf08048e94564d009b19038cfbdd800aa83e79c7f (patch)
tree4afa7e4fff9ec716e9acbe746a464cda5daec063 /drivers/ata/pata_it821x.c
parentb558edddb1c42c70a30cfe494984d4be409f7b2b (diff)
libata: PCI device should be powered up before being accessed
PCI device should be powered up or powered up before its PCI regsiters are accessed. Although PCI configuration register access is allowed in D3hot, PCI device is free to reset its status when transiting from D3hot to D0 causing configuration data to change. Many libata SFF drivers which use ata_pci_init_one() read and update configuration registers before calling ata_pci_init_one() which enables the PCI device. Also, in resume paths, some drivers access registers without resuming the PCI device. This patch adds a call to pcim_enable_device() in init path if register is accessed before calling ata_pci_init_one() and make resume paths first resume PCI devices, access PCI configuration regiters then resume ATA host. While at it... * cmd640 was strange in that it set ->resume even when CONFIG_PM is not. This is by-product of minimal build fix. Updated. * In cs5530, Don't BUG() on reinit failure. Just whine and fail resume. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/ata/pata_it821x.c')
-rw-r--r--drivers/ata/pata_it821x.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 257951d03dbb..6bdbb7140dfa 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -759,6 +759,11 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
759 759
760 const struct ata_port_info *ppi[] = { NULL, NULL }; 760 const struct ata_port_info *ppi[] = { NULL, NULL };
761 static char *mode[2] = { "pass through", "smart" }; 761 static char *mode[2] = { "pass through", "smart" };
762 int rc;
763
764 rc = pcim_enable_device(pdev);
765 if (rc)
766 return rc;
762 767
763 /* Force the card into bypass mode if so requested */ 768 /* Force the card into bypass mode if so requested */
764 if (it8212_noraid) { 769 if (it8212_noraid) {
@@ -780,10 +785,17 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
780#ifdef CONFIG_PM 785#ifdef CONFIG_PM
781static int it821x_reinit_one(struct pci_dev *pdev) 786static int it821x_reinit_one(struct pci_dev *pdev)
782{ 787{
788 struct ata_host *host = dev_get_drvdata(&pdev->dev);
789 int rc;
790
791 rc = ata_pci_device_do_resume(pdev);
792 if (rc)
793 return rc;
783 /* Resume - turn raid back off if need be */ 794 /* Resume - turn raid back off if need be */
784 if (it8212_noraid) 795 if (it8212_noraid)
785 it821x_disable_raid(pdev); 796 it821x_disable_raid(pdev);
786 return ata_pci_device_resume(pdev); 797 ata_host_resume(host);
798 return rc;
787} 799}
788#endif 800#endif
789 801