aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-07-03 03:07:27 -0400
committerJeff Garzik <jeff@garzik.org>2006-07-05 22:16:28 -0400
commit500530f652f9e5dabe7571b018dec47742ce0f16 (patch)
treecb9653c45a7e37d9bfe8dcc3923ed6b33ca134ea /include
parentd6f26d1f1f1128a896f38a7f8426daed0a1205a2 (diff)
[PATCH] libata: reimplement controller-wide PM
Reimplement controller-wide PM. ata_host_set_suspend/resume() are defined to suspend and resume a host_set. While suspended, EHs for all ports in the host_set are pegged using ATA_FLAG_SUSPENDED and frozen. Because SCSI device hotplug is done asynchronously against the rest of libata EH and the same mutex is used when adding new device, suspend cannot wait for hotplug to complete. So, if SCSI device hotplug is in progress, suspend fails with -EBUSY. In most cases, host_set resume is followed by device resume. As each resume operation requires a reset, a single host_set-wide resume operation may result in multiple resets. To avoid this, resume waits upto 1 second giving PM to request resume for devices. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/libata.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 5ac262608199..6cc497a2b6da 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -182,6 +182,7 @@ enum {
182 182
183 ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */ 183 ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */
184 ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ 184 ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */
185 ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */
185 186
186 /* struct ata_queued_cmd flags */ 187 /* struct ata_queued_cmd flags */
187 ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ 188 ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */
@@ -549,6 +550,9 @@ struct ata_port {
549 struct list_head eh_done_q; 550 struct list_head eh_done_q;
550 wait_queue_head_t eh_wait_q; 551 wait_queue_head_t eh_wait_q;
551 552
553 pm_message_t pm_mesg;
554 int *pm_result;
555
552 void *private_data; 556 void *private_data;
553 557
554 u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */ 558 u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */
@@ -603,6 +607,9 @@ struct ata_port_operations {
603 void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, 607 void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
604 u32 val); 608 u32 val);
605 609
610 int (*port_suspend) (struct ata_port *ap, pm_message_t mesg);
611 int (*port_resume) (struct ata_port *ap);
612
606 int (*port_start) (struct ata_port *ap); 613 int (*port_start) (struct ata_port *ap);
607 void (*port_stop) (struct ata_port *ap); 614 void (*port_stop) (struct ata_port *ap);
608 615
@@ -667,6 +674,8 @@ extern void ata_std_ports(struct ata_ioports *ioaddr);
667extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, 674extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
668 unsigned int n_ports); 675 unsigned int n_ports);
669extern void ata_pci_remove_one (struct pci_dev *pdev); 676extern void ata_pci_remove_one (struct pci_dev *pdev);
677extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t state);
678extern void ata_pci_device_do_resume(struct pci_dev *pdev);
670extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state); 679extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state);
671extern int ata_pci_device_resume(struct pci_dev *pdev); 680extern int ata_pci_device_resume(struct pci_dev *pdev);
672extern int ata_pci_clear_simplex(struct pci_dev *pdev); 681extern int ata_pci_clear_simplex(struct pci_dev *pdev);
@@ -687,6 +696,9 @@ extern int ata_port_online(struct ata_port *ap);
687extern int ata_port_offline(struct ata_port *ap); 696extern int ata_port_offline(struct ata_port *ap);
688extern int ata_scsi_device_resume(struct scsi_device *); 697extern int ata_scsi_device_resume(struct scsi_device *);
689extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t state); 698extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t state);
699extern int ata_host_set_suspend(struct ata_host_set *host_set,
700 pm_message_t mesg);
701extern void ata_host_set_resume(struct ata_host_set *host_set);
690extern int ata_ratelimit(void); 702extern int ata_ratelimit(void);
691extern unsigned int ata_busy_sleep(struct ata_port *ap, 703extern unsigned int ata_busy_sleep(struct ata_port *ap,
692 unsigned long timeout_pat, 704 unsigned long timeout_pat,