aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_cmd64x.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_cmd64x.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_cmd64x.c')
-rw-r--r--drivers/ata/pata_cmd64x.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 7acbbd9ee469..1c9a8d97f874 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -435,6 +435,11 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
435 }; 435 };
436 const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL }; 436 const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL };
437 u8 mrdmode; 437 u8 mrdmode;
438 int rc;
439
440 rc = pcim_enable_device(pdev);
441 if (rc)
442 return rc;
438 443
439 pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); 444 pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
440 class_rev &= 0xFF; 445 class_rev &= 0xFF;
@@ -470,7 +475,14 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
470#ifdef CONFIG_PM 475#ifdef CONFIG_PM
471static int cmd64x_reinit_one(struct pci_dev *pdev) 476static int cmd64x_reinit_one(struct pci_dev *pdev)
472{ 477{
478 struct ata_host *host = dev_get_drvdata(&pdev->dev);
473 u8 mrdmode; 479 u8 mrdmode;
480 int rc;
481
482 rc = ata_pci_device_do_resume(pdev);
483 if (rc)
484 return rc;
485
474 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); 486 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
475 pci_read_config_byte(pdev, MRDMODE, &mrdmode); 487 pci_read_config_byte(pdev, MRDMODE, &mrdmode);
476 mrdmode &= ~ 0x30; /* IRQ set up */ 488 mrdmode &= ~ 0x30; /* IRQ set up */
@@ -479,7 +491,8 @@ static int cmd64x_reinit_one(struct pci_dev *pdev)
479#ifdef CONFIG_PPC 491#ifdef CONFIG_PPC
480 pci_write_config_byte(pdev, UDIDETCR0, 0xF0); 492 pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
481#endif 493#endif
482 return ata_pci_device_resume(pdev); 494 ata_host_resume(host);
495 return 0;
483} 496}
484#endif 497#endif
485 498