libata: make sure PMP notification is turned off during recovery
PMP notification during reset can make some controllers fail reset processing and needs to be turned off during resets. PMP attach and full-revalidation path did this via sata_pmp_configure() but the quick revalidation wasn't. Move the notification disable code right above fan-out port recovery so that it's always turned off. This fixes obscure reset failures. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
parent
bf1bff6fa9
commit
f1bbfb90e8
|
@ -257,19 +257,6 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info)
|
||||||
goto fail;
|
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) {
|
if (print_info) {
|
||||||
ata_dev_printk(dev, KERN_INFO, "Port Multiplier %s, "
|
ata_dev_printk(dev, KERN_INFO, "Port Multiplier %s, "
|
||||||
"0x%04x:0x%04x r%d, %d ports, feat 0x%x/0x%x\n",
|
"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_link *pmp_link = &ap->link;
|
||||||
struct ata_device *pmp_dev = pmp_link->device;
|
struct ata_device *pmp_dev = pmp_link->device;
|
||||||
struct ata_eh_context *pmp_ehc = &pmp_link->eh_context;
|
struct ata_eh_context *pmp_ehc = &pmp_link->eh_context;
|
||||||
|
u32 *gscr = pmp_dev->gscr;
|
||||||
struct ata_link *link;
|
struct ata_link *link;
|
||||||
struct ata_device *dev;
|
struct ata_device *dev;
|
||||||
unsigned int err_mask;
|
unsigned int err_mask;
|
||||||
|
@ -897,6 +885,22 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
|
||||||
if (rc)
|
if (rc)
|
||||||
goto pmp_fail;
|
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 */
|
/* handle disabled links */
|
||||||
rc = sata_pmp_eh_handle_disabled_links(ap);
|
rc = sata_pmp_eh_handle_disabled_links(ap);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -919,10 +923,10 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
|
||||||
|
|
||||||
/* enable notification */
|
/* enable notification */
|
||||||
if (pmp_dev->flags & ATA_DFLAG_AN) {
|
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,
|
err_mask = sata_pmp_write(pmp_link, SATA_PMP_GSCR_FEAT_EN,
|
||||||
pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN]);
|
gscr[SATA_PMP_GSCR_FEAT_EN]);
|
||||||
if (err_mask) {
|
if (err_mask) {
|
||||||
ata_dev_printk(pmp_dev, KERN_ERR, "failed to write "
|
ata_dev_printk(pmp_dev, KERN_ERR, "failed to write "
|
||||||
"PMP_FEAT_EN (Emask=0x%x)\n", err_mask);
|
"PMP_FEAT_EN (Emask=0x%x)\n", err_mask);
|
||||||
|
|
Loading…
Reference in New Issue