mirror of https://gitee.com/openkylin/linux.git
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: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
dbd826168d
commit
8989805d6d
|
@ -6064,13 +6064,14 @@ void ata_dev_init(struct ata_device *dev)
|
||||||
* ata_link_init - Initialize an ata_link structure
|
* ata_link_init - Initialize an ata_link structure
|
||||||
* @ap: ATA port link is attached to
|
* @ap: ATA port link is attached to
|
||||||
* @link: Link structure to initialize
|
* @link: Link structure to initialize
|
||||||
|
* @pmp: Port multiplier port number
|
||||||
*
|
*
|
||||||
* Initialize @link.
|
* Initialize @link.
|
||||||
*
|
*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
* Kernel thread context (may sleep)
|
* 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;
|
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]));
|
memset(link, 0, offsetof(struct ata_link, device[0]));
|
||||||
|
|
||||||
link->ap = ap;
|
link->ap = ap;
|
||||||
|
link->pmp = pmp;
|
||||||
link->active_tag = ATA_TAG_POISON;
|
link->active_tag = ATA_TAG_POISON;
|
||||||
link->hw_sata_spd_limit = UINT_MAX;
|
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;
|
ap->cbl = ATA_CBL_NONE;
|
||||||
|
|
||||||
ata_link_init(ap, &ap->link);
|
ata_link_init(ap, &ap->link, 0);
|
||||||
|
|
||||||
#ifdef ATA_IRQ_TRAP
|
#ifdef ATA_IRQ_TRAP
|
||||||
ap->stats.unhandled_irq = 1;
|
ap->stats.unhandled_irq = 1;
|
||||||
|
|
|
@ -515,6 +515,7 @@ struct ata_acpi_gtm {
|
||||||
|
|
||||||
struct ata_link {
|
struct ata_link {
|
||||||
struct ata_port *ap;
|
struct ata_port *ap;
|
||||||
|
int pmp; /* port multiplier port # */
|
||||||
|
|
||||||
unsigned int active_tag; /* active tag on this link */
|
unsigned int active_tag; /* active tag on this link */
|
||||||
u32 sactive; /* active NCQ commands */
|
u32 sactive; /* active NCQ commands */
|
||||||
|
@ -563,6 +564,9 @@ struct ata_port {
|
||||||
|
|
||||||
struct ata_link link; /* host default link */
|
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_port_stats stats;
|
||||||
struct ata_host *host;
|
struct ata_host *host;
|
||||||
struct device *dev;
|
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...) \
|
#define ata_port_printk(ap, lv, fmt, args...) \
|
||||||
printk(lv"ata%u: "fmt, (ap)->print_id , ##args)
|
printk(lv"ata%u: "fmt, (ap)->print_id , ##args)
|
||||||
|
|
||||||
#define ata_link_printk(link, lv, fmt, args...) \
|
#define ata_link_printk(link, lv, fmt, args...) do { \
|
||||||
printk(lv"ata%u: "fmt, (link)->ap->print_id , ##args)
|
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...) \
|
#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
|
* ata_eh_info helpers
|
||||||
|
@ -1039,15 +1049,46 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev)
|
||||||
/*
|
/*
|
||||||
* link helpers
|
* 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)
|
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 2;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ata_port_for_each_link(lk, ap) \
|
static inline struct ata_link *ata_port_first_link(struct ata_port *ap)
|
||||||
for ((lk) = &(ap)->link; (lk); (lk) = NULL)
|
{
|
||||||
|
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) \
|
#define ata_link_for_each_dev(dev, link) \
|
||||||
for ((dev) = (link)->device; \
|
for ((dev) = (link)->device; \
|
||||||
|
|
Loading…
Reference in New Issue