Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 212813
b: refs/heads/master
c: 6c8ea89
h: refs/heads/master
i:
  212811: d62bc9c
v: v3
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Oct 22, 2010
1 parent ace4700 commit 2fbee79
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6b7ae9545ad9875a289f4191c0216b473e313cb9
refs/heads/master: 6c8ea89cecd780faa4f4c8ed8b3b6ab88f9fa841
21 changes: 15 additions & 6 deletions trunk/drivers/ata/libata-eh.c
Original file line number Diff line number Diff line change
Expand Up @@ -3232,7 +3232,7 @@ static int ata_eh_maybe_retry_flush(struct ata_device *dev)
static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
struct ata_device **r_failed_dev)
{
struct ata_port *ap = link->ap;
struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL;
struct ata_eh_context *ehc = &link->eh_context;
struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL;
unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM;
Expand Down Expand Up @@ -3278,9 +3278,12 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
}
}

rc = ap->ops->set_lpm(link, policy, hints);
if (!rc && ap->slave_link)
rc = ap->ops->set_lpm(ap->slave_link, policy, hints);
if (ap) {
rc = ap->ops->set_lpm(link, policy, hints);
if (!rc && ap->slave_link)
rc = ap->ops->set_lpm(ap->slave_link, policy, hints);
} else
rc = sata_pmp_set_lpm(link, policy, hints);

/*
* Attribute link config failure to the first (LPM) enabled
Expand Down Expand Up @@ -3412,8 +3415,14 @@ static int ata_eh_schedule_probe(struct ata_device *dev)
ehc->saved_ncq_enabled &= ~(1 << dev->devno);

/* the link maybe in a deep sleep, wake it up */
if (link->lpm_policy > ATA_LPM_MAX_POWER)
link->ap->ops->set_lpm(link, ATA_LPM_MAX_POWER, ATA_LPM_EMPTY);
if (link->lpm_policy > ATA_LPM_MAX_POWER) {
if (ata_is_host_link(link))
link->ap->ops->set_lpm(link, ATA_LPM_MAX_POWER,
ATA_LPM_EMPTY);
else
sata_pmp_set_lpm(link, ATA_LPM_MAX_POWER,
ATA_LPM_EMPTY);
}

/* Record and count probe trials on the ering. The specific
* error mask used is irrelevant. Because a successful device
Expand Down
48 changes: 44 additions & 4 deletions trunk/drivers/ata/libata-pmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,27 @@ int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val)
return 0;
}

/**
* sata_pmp_set_lpm - configure LPM for a PMP link
* @link: PMP link to configure LPM for
* @policy: target LPM policy
* @hints: LPM hints
*
* Configure LPM for @link. This function will contain any PMP
* specific workarounds if necessary.
*
* LOCKING:
* EH context.
*
* RETURNS:
* 0 on success, -errno on failure.
*/
int sata_pmp_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
unsigned hints)
{
return sata_link_scr_lpm(link, policy, true);
}

/**
* sata_pmp_read_gscr - read GSCR block of SATA PMP
* @dev: PMP device
Expand Down Expand Up @@ -365,6 +386,9 @@ static void sata_pmp_quirks(struct ata_port *ap)
if (vendor == 0x1095 && devid == 0x3726) {
/* sil3726 quirks */
ata_for_each_link(link, ap, EDGE) {
/* link reports offline after LPM */
link->flags |= ATA_LFLAG_NO_LPM;

/* Class code report is unreliable and SRST
* times out under certain configurations.
*/
Expand All @@ -380,6 +404,9 @@ static void sata_pmp_quirks(struct ata_port *ap)
} else if (vendor == 0x1095 && devid == 0x4723) {
/* sil4723 quirks */
ata_for_each_link(link, ap, EDGE) {
/* link reports offline after LPM */
link->flags |= ATA_LFLAG_NO_LPM;

/* class code report is unreliable */
if (link->pmp < 2)
link->flags |= ATA_LFLAG_ASSUME_ATA;
Expand All @@ -392,6 +419,9 @@ static void sata_pmp_quirks(struct ata_port *ap)
} else if (vendor == 0x1095 && devid == 0x4726) {
/* sil4726 quirks */
ata_for_each_link(link, ap, EDGE) {
/* link reports offline after LPM */
link->flags |= ATA_LFLAG_NO_LPM;

/* Class code report is unreliable and SRST
* times out under certain configurations.
* Config device can be at port 0 or 5 and
Expand Down Expand Up @@ -952,15 +982,25 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
if (rc)
goto link_fail;

/* Connection status might have changed while resetting other
* links, check SATA_PMP_GSCR_ERROR before returning.
*/

/* clear SNotification */
rc = sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf);
if (rc == 0)
sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf);

/*
* If LPM is active on any fan-out port, hotplug wouldn't
* work. Return w/ PHY event notification disabled.
*/
ata_for_each_link(link, ap, EDGE)
if (link->lpm_policy > ATA_LPM_MAX_POWER)
return 0;

/*
* Connection status might have changed while resetting other
* links, enable notification and check SATA_PMP_GSCR_ERROR
* before returning.
*/

/* enable notification */
if (pmp_dev->flags & ATA_DFLAG_AN) {
gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY;
Expand Down
8 changes: 8 additions & 0 deletions trunk/drivers/ata/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ extern int ata_ering_map(struct ata_ering *ering,
#ifdef CONFIG_SATA_PMP
extern int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *val);
extern int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val);
extern int sata_pmp_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
unsigned hints);
extern int sata_pmp_attach(struct ata_device *dev);
#else /* CONFIG_SATA_PMP */
static inline int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *val)
Expand All @@ -188,6 +190,12 @@ static inline int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val)
return -EINVAL;
}

static inline int sata_pmp_set_lpm(struct ata_link *link,
enum ata_lpm_policy policy, unsigned hints)
{
return -EINVAL;
}

static inline int sata_pmp_attach(struct ata_device *dev)
{
return -EINVAL;
Expand Down

0 comments on commit 2fbee79

Please sign in to comment.