libata-link: add PMP links
authorTejun Heo <htejun@gmail.com>
Mon, 6 Aug 2007 09:36:23 +0000 (18:36 +0900)
committerJeff Garzik <jeff@garzik.org>
Fri, 12 Oct 2007 18:55:31 +0000 (14:55 -0400)
Add link->pmp, ap->nr_pmp_links, ap->pmp_link[], and implement/update
link helpers.

printk helpers are updated such that port and link are identifed as
'ataP:' if no PMP is attached, while device is identified as
'ataP.DD:'.  If PMP is attached, they become 'ataP:', 'ataP.LL:' and
'ataP.LL' - ie. link and device are identified their PMP number.

If PPM is attached (ap->nr_pmp_links != 0), ata_for_each_link()
iterates over PMP links, while __ata_for_each_link() iterates over the
host link + PMP links.  If PMP is not attached (ap->nr_pmp_links ==
0), both iterate over only the host link.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/ata/libata-core.c
include/linux/libata.h

index dcae590cc9b4ac1863ec481c14d32216af18af2f..af9c0ab600dcc313812bb2383ee9043e631c7c84 100644 (file)
@@ -6064,13 +6064,14 @@ void ata_dev_init(struct ata_device *dev)
  *     ata_link_init - Initialize an ata_link structure
  *     @ap: ATA port link is attached to
  *     @link: Link structure to initialize
+ *     @pmp: Port multiplier port number
  *
  *     Initialize @link.
  *
  *     LOCKING:
  *     Kernel thread context (may sleep)
  */
-static void ata_link_init(struct ata_port *ap, struct ata_link *link)
+static void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
 {
        int i;
 
@@ -6078,6 +6079,7 @@ static void ata_link_init(struct ata_port *ap, struct ata_link *link)
        memset(link, 0, offsetof(struct ata_link, device[0]));
 
        link->ap = ap;
+       link->pmp = pmp;
        link->active_tag = ATA_TAG_POISON;
        link->hw_sata_spd_limit = UINT_MAX;
 
@@ -6173,7 +6175,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
 
        ap->cbl = ATA_CBL_NONE;
 
-       ata_link_init(ap, &ap->link);
+       ata_link_init(ap, &ap->link, 0);
 
 #ifdef ATA_IRQ_TRAP
        ap->stats.unhandled_irq = 1;
index bfa155789993707863fc24273833d6b0713e5ef8..7a1793bd237144b866c72a7e00711017d53b2e71 100644 (file)
@@ -515,6 +515,7 @@ struct ata_acpi_gtm {
 
 struct ata_link {
        struct ata_port         *ap;
+       int                     pmp;            /* port multiplier port # */
 
        unsigned int            active_tag;     /* active tag on this link */
        u32                     sactive;        /* active NCQ commands */
@@ -563,6 +564,9 @@ struct ata_port {
 
        struct ata_link         link;   /* host default link */
 
+       int                     nr_pmp_links;   /* nr of available PMP links */
+       struct ata_link         *pmp_link;      /* array of PMP links */
+
        struct ata_port_stats   stats;
        struct ata_host         *host;
        struct device           *dev;
@@ -926,11 +930,17 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
 #define ata_port_printk(ap, lv, fmt, args...) \
        printk(lv"ata%u: "fmt, (ap)->print_id , ##args)
 
-#define ata_link_printk(link, lv, fmt, args...) \
-       printk(lv"ata%u: "fmt, (link)->ap->print_id , ##args)
+#define ata_link_printk(link, lv, fmt, args...) do { \
+       if ((link)->ap->nr_pmp_links) \
+               printk(lv"ata%u.%02u: "fmt, (link)->ap->print_id, \
+                      (link)->pmp , ##args); \
+       else \
+               printk(lv"ata%u: "fmt, (link)->ap->print_id , ##args); \
+       } while(0)
 
 #define ata_dev_printk(dev, lv, fmt, args...) \
-       printk(lv"ata%u.%02u: "fmt, (dev)->link->ap->print_id, (dev)->devno , ##args)
+       printk(lv"ata%u.%02u: "fmt, (dev)->link->ap->print_id, \
+              (dev)->link->pmp + (dev)->devno , ##args)
 
 /*
  * ata_eh_info helpers
@@ -1039,15 +1049,46 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev)
 /*
  * link helpers
  */
+static inline int ata_is_host_link(const struct ata_link *link)
+{
+       return link == &link->ap->link;
+}
+
 static inline int ata_link_max_devices(const struct ata_link *link)
 {
-       if (link->ap->flags & ATA_FLAG_SLAVE_POSS)
+       if (ata_is_host_link(link) && link->ap->flags & ATA_FLAG_SLAVE_POSS)
                return 2;
        return 1;
 }
 
-#define ata_port_for_each_link(lk, ap) \
-       for ((lk) = &(ap)->link; (lk); (lk) = NULL)
+static inline struct ata_link *ata_port_first_link(struct ata_port *ap)
+{
+       if (ap->nr_pmp_links)
+               return ap->pmp_link;
+       return &ap->link;
+}
+
+static inline struct ata_link *ata_port_next_link(struct ata_link *link)
+{
+       struct ata_port *ap = link->ap;
+
+       if (link == &ap->link) {
+               if (!ap->nr_pmp_links)
+                       return NULL;
+               return ap->pmp_link;
+       }
+
+       if (++link - ap->pmp_link < ap->nr_pmp_links)
+               return link;
+       return NULL;
+}
+
+#define __ata_port_for_each_link(lk, ap) \
+       for ((lk) = &(ap)->link; (lk); (lk) = ata_port_next_link(lk))
+
+#define ata_port_for_each_link(link, ap) \
+       for ((link) = ata_port_first_link(ap); (link); \
+            (link) = ata_port_next_link(link))
 
 #define ata_link_for_each_dev(dev, link) \
        for ((dev) = (link)->device; \