aboutsummaryrefslogtreecommitdiff
path: root/drivers/ata
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-pmp.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 04a486a3e7b..0f9386d4a5a 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -257,19 +257,6 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info)
goto fail;
}
- /* turn off notification till fan-out ports are reset and configured */
- if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) {
- gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY;
-
- err_mask = sata_pmp_write(dev->link, SATA_PMP_GSCR_FEAT_EN,
- gscr[SATA_PMP_GSCR_FEAT_EN]);
- if (err_mask) {
- rc = -EIO;
- reason = "failed to write GSCR_FEAT_EN";
- goto fail;
- }
- }
-
if (print_info) {
ata_dev_printk(dev, KERN_INFO, "Port Multiplier %s, "
"0x%04x:0x%04x r%d, %d ports, feat 0x%x/0x%x\n",
@@ -860,6 +847,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
struct ata_link *pmp_link = &ap->link;
struct ata_device *pmp_dev = pmp_link->device;
struct ata_eh_context *pmp_ehc = &pmp_link->eh_context;
+ u32 *gscr = pmp_dev->gscr;
struct ata_link *link;
struct ata_device *dev;
unsigned int err_mask;
@@ -897,6 +885,22 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
if (rc)
goto pmp_fail;
+ /* PHY event notification can disturb reset and other recovery
+ * operations. Turn it off.
+ */
+ if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) {
+ gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY;
+
+ err_mask = sata_pmp_write(pmp_link, SATA_PMP_GSCR_FEAT_EN,
+ gscr[SATA_PMP_GSCR_FEAT_EN]);
+ if (err_mask) {
+ ata_link_printk(pmp_link, KERN_WARNING,
+ "failed to disable NOTIFY (err_mask=0x%x)\n",
+ err_mask);
+ goto pmp_fail;
+ }
+ }
+
/* handle disabled links */
rc = sata_pmp_eh_handle_disabled_links(ap);
if (rc)
@@ -919,10 +923,10 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
/* enable notification */
if (pmp_dev->flags & ATA_DFLAG_AN) {
- pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY;
+ gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY;
- err_mask = sata_pmp_write(pmp_dev->link, SATA_PMP_GSCR_FEAT_EN,
- pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN]);
+ err_mask = sata_pmp_write(pmp_link, SATA_PMP_GSCR_FEAT_EN,
+ gscr[SATA_PMP_GSCR_FEAT_EN]);
if (err_mask) {
ata_dev_printk(pmp_dev, KERN_ERR, "failed to write "
"PMP_FEAT_EN (Emask=0x%x)\n", err_mask);