aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_cs5530.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_cs5530.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_cs5530.c')
-rw-r--r--drivers/ata/pata_cs5530.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index e1818fdd9159..f876aeddf1a1 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -349,6 +349,11 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
349 .port_ops = &cs5530_port_ops 349 .port_ops = &cs5530_port_ops
350 }; 350 };
351 const struct ata_port_info *ppi[] = { &info, NULL }; 351 const struct ata_port_info *ppi[] = { &info, NULL };
352 int rc;
353
354 rc = pcim_enable_device(pdev);
355 if (rc)
356 return rc;
352 357
353 /* Chip initialisation */ 358 /* Chip initialisation */
354 if (cs5530_init_chip()) 359 if (cs5530_init_chip())
@@ -364,10 +369,19 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
364#ifdef CONFIG_PM 369#ifdef CONFIG_PM
365static int cs5530_reinit_one(struct pci_dev *pdev) 370static int cs5530_reinit_one(struct pci_dev *pdev)
366{ 371{
372 struct ata_host *host = dev_get_drvdata(&pdev->dev);
373 int rc;
374
375 rc = ata_pci_device_do_resume(pdev);
376 if (rc)
377 return rc;
378
367 /* If we fail on resume we are doomed */ 379 /* If we fail on resume we are doomed */
368 if (cs5530_init_chip()) 380 if (cs5530_init_chip())
369 BUG(); 381 return -EIO;
370 return ata_pci_device_resume(pdev); 382
383 ata_host_resume(host);
384 return 0;
371} 385}
372#endif /* CONFIG_PM */ 386#endif /* CONFIG_PM */
373 387