]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/linux/libata.h
[PATCH] libata: Add support for SATA attachment to SAS adapters
[linux-2.6-omap-h63xx.git] / include / linux / libata.h
index 20b1cf527c609a575ff468b91f7a4106a8464a8b..cf5eb1da3e32a923f8b0d2e81979ddb4776d8711 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <asm/scatterlist.h>
 #include <asm/io.h>
 #include <linux/ata.h>
 #include <linux/workqueue.h>
@@ -130,6 +131,7 @@ enum {
        ATA_DFLAG_CFG_MASK      = (1 << 8) - 1,
 
        ATA_DFLAG_PIO           = (1 << 8), /* device currently in PIO mode */
+       ATA_DFLAG_SUSPENDED     = (1 << 9), /* device suspended */
        ATA_DFLAG_INIT_MASK     = (1 << 16) - 1,
 
        ATA_DFLAG_DETACH        = (1 << 16),
@@ -159,22 +161,28 @@ enum {
        ATA_FLAG_HRST_TO_RESUME = (1 << 11), /* hardreset to resume phy */
        ATA_FLAG_SKIP_D2H_BSY   = (1 << 12), /* can't wait for the first D2H
                                              * Register FIS clearing BSY */
-
        ATA_FLAG_DEBUGMSG       = (1 << 13),
-       ATA_FLAG_FLUSH_PORT_TASK = (1 << 14), /* flush port task */
 
-       ATA_FLAG_EH_PENDING     = (1 << 15), /* EH pending */
-       ATA_FLAG_EH_IN_PROGRESS = (1 << 16), /* EH in progress */
-       ATA_FLAG_FROZEN         = (1 << 17), /* port is frozen */
-       ATA_FLAG_RECOVERED      = (1 << 18), /* recovery action performed */
-       ATA_FLAG_LOADING        = (1 << 19), /* boot/loading probe */
-       ATA_FLAG_UNLOADING      = (1 << 20), /* module is unloading */
-       ATA_FLAG_SCSI_HOTPLUG   = (1 << 21), /* SCSI hotplug scheduled */
+       /* The following flag belongs to ap->pflags but is kept in
+        * ap->flags because it's referenced in many LLDs and will be
+        * removed in not-too-distant future.
+        */
+       ATA_FLAG_DISABLED       = (1 << 23), /* port is disabled, ignore it */
+
+       /* bits 24:31 of ap->flags are reserved for LLD specific flags */
 
-       ATA_FLAG_DISABLED       = (1 << 22), /* port is disabled, ignore it */
-       ATA_FLAG_SUSPENDED      = (1 << 23), /* port is suspended (power) */
+       /* struct ata_port pflags */
+       ATA_PFLAG_EH_PENDING    = (1 << 0), /* EH pending */
+       ATA_PFLAG_EH_IN_PROGRESS = (1 << 1), /* EH in progress */
+       ATA_PFLAG_FROZEN        = (1 << 2), /* port is frozen */
+       ATA_PFLAG_RECOVERED     = (1 << 3), /* recovery action performed */
+       ATA_PFLAG_LOADING       = (1 << 4), /* boot/loading probe */
+       ATA_PFLAG_UNLOADING     = (1 << 5), /* module is unloading */
+       ATA_PFLAG_SCSI_HOTPLUG  = (1 << 6), /* SCSI hotplug scheduled */
 
-       /* bits 24:31 of ap->flags are reserved for LLDD specific flags */
+       ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */
+       ATA_PFLAG_SUSPENDED     = (1 << 17), /* port is suspended (power) */
+       ATA_PFLAG_PM_PENDING    = (1 << 18), /* PM operation pending */
 
        /* struct ata_queued_cmd flags */
        ATA_QCFLAG_ACTIVE       = (1 << 0), /* cmd not yet ack'd to scsi lyer */
@@ -247,15 +255,24 @@ enum {
        ATA_EH_REVALIDATE       = (1 << 0),
        ATA_EH_SOFTRESET        = (1 << 1),
        ATA_EH_HARDRESET        = (1 << 2),
+       ATA_EH_SUSPEND          = (1 << 3),
+       ATA_EH_RESUME           = (1 << 4),
+       ATA_EH_PM_FREEZE        = (1 << 5),
 
        ATA_EH_RESET_MASK       = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
-       ATA_EH_PERDEV_MASK      = ATA_EH_REVALIDATE,
+       ATA_EH_PERDEV_MASK      = ATA_EH_REVALIDATE | ATA_EH_SUSPEND |
+                                 ATA_EH_RESUME | ATA_EH_PM_FREEZE,
 
        /* ata_eh_info->flags */
        ATA_EHI_HOTPLUGGED      = (1 << 0),  /* could have been hotplugged */
+       ATA_EHI_RESUME_LINK     = (1 << 1),  /* resume link (reset modifier) */
+       ATA_EHI_NO_AUTOPSY      = (1 << 2),  /* no autopsy */
+       ATA_EHI_QUIET           = (1 << 3),  /* be quiet */
 
        ATA_EHI_DID_RESET       = (1 << 16), /* already reset this port */
 
+       ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
+
        /* max repeat if error condition is still set after ->error_handler */
        ATA_EH_MAX_REPEAT       = 5,
 
@@ -485,6 +502,7 @@ struct ata_port {
        const struct ata_port_operations *ops;
        spinlock_t              *lock;
        unsigned long           flags;  /* ATA_FLAG_xxx */
+       unsigned int            pflags; /* ATA_PFLAG_xxx */
        unsigned int            id;     /* unique id req'd by scsi midlyr */
        unsigned int            port_no; /* unique port #; from zero */
        unsigned int            hard_port_no;   /* hardware port #; from zero */
@@ -534,6 +552,9 @@ struct ata_port {
        struct list_head        eh_done_q;
        wait_queue_head_t       eh_wait_q;
 
+       pm_message_t            pm_mesg;
+       int                     *pm_result;
+
        void                    *private_data;
 
        u8                      sector_buf[ATA_SECT_SIZE]; /* owned by EH */
@@ -588,6 +609,9 @@ struct ata_port_operations {
        void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
                           u32 val);
 
+       int (*port_suspend) (struct ata_port *ap, pm_message_t mesg);
+       int (*port_resume) (struct ata_port *ap);
+
        int (*port_start) (struct ata_port *ap);
        void (*port_stop) (struct ata_port *ap);
 
@@ -621,9 +645,18 @@ struct ata_timing {
 
 #define FIT(v,vmin,vmax)       max_t(short,min_t(short,v,vmax),vmin)
 
-extern const unsigned long sata_deb_timing_boot[];
-extern const unsigned long sata_deb_timing_eh[];
-extern const unsigned long sata_deb_timing_before_fsrst[];
+extern const unsigned long sata_deb_timing_normal[];
+extern const unsigned long sata_deb_timing_hotplug[];
+extern const unsigned long sata_deb_timing_long[];
+
+static inline const unsigned long *
+sata_ehc_deb_timing(struct ata_eh_context *ehc)
+{
+       if (ehc->i.flags & ATA_EHI_HOTPLUGGED)
+               return sata_deb_timing_hotplug;
+       else
+               return sata_deb_timing_normal;
+}
 
 extern void ata_port_probe(struct ata_port *);
 extern void __sata_phy_reset(struct ata_port *ap);
@@ -643,17 +676,30 @@ extern void ata_std_ports(struct ata_ioports *ioaddr);
 extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                             unsigned int n_ports);
 extern void ata_pci_remove_one (struct pci_dev *pdev);
-extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state);
+extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg);
+extern void ata_pci_device_do_resume(struct pci_dev *pdev);
+extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
 extern int ata_pci_device_resume(struct pci_dev *pdev);
 extern int ata_pci_clear_simplex(struct pci_dev *pdev);
 #endif /* CONFIG_PCI */
 extern int ata_device_add(const struct ata_probe_ent *ent);
 extern void ata_port_detach(struct ata_port *ap);
+extern void ata_host_set_init(struct ata_host_set *, struct device *,
+                             unsigned long, const struct ata_port_operations *);
 extern void ata_host_set_remove(struct ata_host_set *host_set);
 extern int ata_scsi_detect(struct scsi_host_template *sht);
 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
 extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
 extern int ata_scsi_release(struct Scsi_Host *host);
+extern void ata_sas_port_destroy(struct ata_port *);
+extern struct ata_port *ata_sas_port_alloc(struct ata_host_set *,
+                                          struct ata_port_info *, struct Scsi_Host *);
+extern int ata_sas_port_init(struct ata_port *);
+extern int ata_sas_port_start(struct ata_port *ap);
+extern void ata_sas_port_stop(struct ata_port *ap);
+extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *);
+extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
+                           struct ata_port *ap);
 extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
 extern int sata_scr_valid(struct ata_port *ap);
 extern int sata_scr_read(struct ata_port *ap, int reg, u32 *val);
@@ -662,9 +708,10 @@ extern int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val);
 extern int ata_port_online(struct ata_port *ap);
 extern int ata_port_offline(struct ata_port *ap);
 extern int ata_scsi_device_resume(struct scsi_device *);
-extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t state);
-extern int ata_device_resume(struct ata_device *);
-extern int ata_device_suspend(struct ata_device *, pm_message_t state);
+extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg);
+extern int ata_host_set_suspend(struct ata_host_set *host_set,
+                               pm_message_t mesg);
+extern void ata_host_set_resume(struct ata_host_set *host_set);
 extern int ata_ratelimit(void);
 extern unsigned int ata_busy_sleep(struct ata_port *ap,
                                   unsigned long timeout_pat,
@@ -824,19 +871,24 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
        (ehi)->desc_len = 0; \
 } while (0)
 
-static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi)
+static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi)
 {
        if (ehi->flags & ATA_EHI_HOTPLUGGED)
                return;
 
-       ehi->flags |= ATA_EHI_HOTPLUGGED;
+       ehi->flags |= ATA_EHI_HOTPLUGGED | ATA_EHI_RESUME_LINK;
        ehi->hotplug_timestamp = jiffies;
 
-       ehi->err_mask |= AC_ERR_ATA_BUS;
        ehi->action |= ATA_EH_SOFTRESET;
        ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1;
 }
 
+static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi)
+{
+       __ata_ehi_hotplugged(ehi);
+       ehi->err_mask |= AC_ERR_ATA_BUS;
+}
+
 /*
  * qc helpers
  */
@@ -887,6 +939,9 @@ static inline unsigned int ata_tag_internal(unsigned int tag)
        return tag == ATA_MAX_QUEUE - 1;
 }
 
+/*
+ * device helpers
+ */
 static inline unsigned int ata_class_enabled(unsigned int class)
 {
        return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI;
@@ -917,6 +972,22 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev)
        return ata_class_absent(dev->class);
 }
 
+static inline unsigned int ata_dev_ready(const struct ata_device *dev)
+{
+       return ata_dev_enabled(dev) && !(dev->flags & ATA_DFLAG_SUSPENDED);
+}
+
+/*
+ * port helpers
+ */
+static inline int ata_port_max_devices(const struct ata_port *ap)
+{
+       if (ap->flags & ATA_FLAG_SLAVE_POSS)
+               return 2;
+       return 1;
+}
+
+
 static inline u8 ata_chk_status(struct ata_port *ap)
 {
        return ap->ops->check_status(ap);