aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_serverworks.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_serverworks.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_serverworks.c')
-rw-r--r--drivers/ata/pata_serverworks.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index a589c0fa0dbb..6702df37cfed 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -498,6 +498,11 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
498 } 498 }
499 }; 499 };
500 const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL }; 500 const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL };
501 int rc;
502
503 rc = pcim_enable_device(pdev);
504 if (rc)
505 return rc;
501 506
502 /* Force master latency timer to 64 PCI clocks */ 507 /* Force master latency timer to 64 PCI clocks */
503 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40); 508 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
@@ -535,11 +540,17 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
535#ifdef CONFIG_PM 540#ifdef CONFIG_PM
536static int serverworks_reinit_one(struct pci_dev *pdev) 541static int serverworks_reinit_one(struct pci_dev *pdev)
537{ 542{
543 struct ata_host *host = dev_get_drvdata(&pdev->dev);
544 int rc;
545
546 rc = ata_pci_device_do_resume(pdev);
547 if (rc)
548 return rc;
549
538 /* Force master latency timer to 64 PCI clocks */ 550 /* Force master latency timer to 64 PCI clocks */
539 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40); 551 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
540 552
541 switch (pdev->device) 553 switch (pdev->device) {
542 {
543 case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE: 554 case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
544 serverworks_fixup_osb4(pdev); 555 serverworks_fixup_osb4(pdev);
545 break; 556 break;
@@ -554,7 +565,9 @@ static int serverworks_reinit_one(struct pci_dev *pdev)
554 serverworks_fixup_ht1000(pdev); 565 serverworks_fixup_ht1000(pdev);
555 break; 566 break;
556 } 567 }
557 return ata_pci_device_resume(pdev); 568
569 ata_host_resume(host);
570 return 0;
558} 571}
559#endif 572#endif
560 573