Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8989805d authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik
Browse files

libata-link: add PMP links



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: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent dbd82616
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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;
+47 −6
Original line number Diff line number Diff line
@@ -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; \