]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/linux/libata.h
libata: Add a per-host flag to opt-in into parallel port probes
[linux-2.6-omap-h63xx.git] / include / linux / libata.h
index ed3f26eb5df1421287ea41d17feed10be87cafeb..b6b8a7f3ec66064778cf2b63b6eaa4a03dc25495 100644 (file)
@@ -213,10 +213,11 @@ enum {
        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 */
        ATA_PFLAG_INITIALIZING  = (1 << 7), /* being initialized, don't touch */
        ATA_PFLAG_RESETTING     = (1 << 8), /* reset in progress */
+       ATA_PFLAG_UNLOADING     = (1 << 9), /* driver is being unloaded */
+       ATA_PFLAG_UNLOADED      = (1 << 10), /* driver is unloaded */
 
        ATA_PFLAG_SUSPENDED     = (1 << 17), /* port is suspended (power) */
        ATA_PFLAG_PM_PENDING    = (1 << 18), /* PM operation pending */
@@ -238,6 +239,7 @@ enum {
        /* host set flags */
        ATA_HOST_SIMPLEX        = (1 << 0),     /* Host is simplex, one DMA channel per host only */
        ATA_HOST_STARTED        = (1 << 1),     /* Host started */
+       ATA_HOST_PARALLEL_SCAN  = (1 << 2),     /* Ports on this host can be scanned in parallel */
 
        /* bits 24:31 of host->flags are reserved for LLD specific flags */
 
@@ -1285,26 +1287,62 @@ static inline int ata_link_active(struct ata_link *link)
        return ata_tag_valid(link->active_tag) || link->sactive;
 }
 
-extern struct ata_link *__ata_port_next_link(struct ata_port *ap,
-                                            struct ata_link *link,
-                                            bool dev_only);
+/*
+ * Iterators
+ *
+ * ATA_LITER_* constants are used to select link iteration mode and
+ * ATA_DITER_* device iteration mode.
+ *
+ * For a custom iteration directly using ata_{link|dev}_next(), if
+ * @link or @dev, respectively, is NULL, the first element is
+ * returned.  @dev and @link can be any valid device or link and the
+ * next element according to the iteration mode will be returned.
+ * After the last element, NULL is returned.
+ */
+enum ata_link_iter_mode {
+       ATA_LITER_EDGE,         /* if present, PMP links only; otherwise,
+                                * host link.  no slave link */
+       ATA_LITER_HOST_FIRST,   /* host link followed by PMP or slave links */
+       ATA_LITER_PMP_FIRST,    /* PMP links followed by host link,
+                                * slave link still comes after host link */
+};
+
+enum ata_dev_iter_mode {
+       ATA_DITER_ENABLED,
+       ATA_DITER_ENABLED_REVERSE,
+       ATA_DITER_ALL,
+       ATA_DITER_ALL_REVERSE,
+};
 
-#define __ata_port_for_each_link(link, ap) \
-       for ((link) = __ata_port_next_link((ap), NULL, false); (link); \
-            (link) = __ata_port_next_link((ap), (link), false))
+extern struct ata_link *ata_link_next(struct ata_link *link,
+                                     struct ata_port *ap,
+                                     enum ata_link_iter_mode mode);
 
-#define ata_port_for_each_link(link, ap) \
-       for ((link) = __ata_port_next_link((ap), NULL, true); (link); \
-            (link) = __ata_port_next_link((ap), (link), true))
+extern struct ata_device *ata_dev_next(struct ata_device *dev,
+                                      struct ata_link *link,
+                                      enum ata_dev_iter_mode mode);
 
-#define ata_link_for_each_dev(dev, link) \
-       for ((dev) = (link)->device; \
-            (dev) < (link)->device + ata_link_max_devices(link) || ((dev) = NULL); \
-            (dev)++)
+/*
+ * Shortcut notation for iterations
+ *
+ * ata_for_each_link() iterates over each link of @ap according to
+ * @mode.  @link points to the current link in the loop.  @link is
+ * NULL after loop termination.  ata_for_each_dev() works the same way
+ * except that it iterates over each device of @link.
+ *
+ * Note that the mode prefixes ATA_{L|D}ITER_ shouldn't need to be
+ * specified when using the following shorthand notations.  Only the
+ * mode itself (EDGE, HOST_FIRST, ENABLED, etc...) should be
+ * specified.  This not only increases brevity but also makes it
+ * impossible to use ATA_LITER_* for device iteration or vice-versa.
+ */
+#define ata_for_each_link(link, ap, mode) \
+       for ((link) = ata_link_next(NULL, (ap), ATA_LITER_##mode); (link); \
+            (link) = ata_link_next((link), (ap), ATA_LITER_##mode))
 
-#define ata_link_for_each_dev_reverse(dev, link) \
-       for ((dev) = (link)->device + ata_link_max_devices(link) - 1; \
-            (dev) >= (link)->device || ((dev) = NULL); (dev)--)
+#define ata_for_each_dev(dev, link, mode) \
+       for ((dev) = ata_dev_next(NULL, (link), ATA_DITER_##mode); (dev); \
+            (dev) = ata_dev_next((dev), (link), ATA_DITER_##mode))
 
 /**
  *     ata_ncq_enabled - Test whether NCQ is enabled
@@ -1481,6 +1519,7 @@ extern void sata_pmp_error_handler(struct ata_port *ap);
 
 extern const struct ata_port_operations ata_sff_port_ops;
 extern const struct ata_port_operations ata_bmdma_port_ops;
+extern const struct ata_port_operations ata_bmdma32_port_ops;
 
 /* PIO only, sg_tablesize and dma_boundary limits can be removed */
 #define ATA_PIO_SHT(drv_name)                                  \
@@ -1508,6 +1547,8 @@ extern void ata_sff_exec_command(struct ata_port *ap,
                                 const struct ata_taskfile *tf);
 extern unsigned int ata_sff_data_xfer(struct ata_device *dev,
                        unsigned char *buf, unsigned int buflen, int rw);
+extern unsigned int ata_sff_data_xfer32(struct ata_device *dev,
+                       unsigned char *buf, unsigned int buflen, int rw);
 extern unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev,
                        unsigned char *buf, unsigned int buflen, int rw);
 extern u8 ata_sff_irq_on(struct ata_port *ap);