aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-05-18 12:15:11 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-19 17:51:48 -0400
commitf1bbfb90e81dd84d59de6370689ee6fe6a71fee0 (patch)
treed4d8357816cbd578e967a2f0bd07f60f02a73a3d /drivers/ata
parentbf1bff6fa9fdd4e92e57d80a5434fd5201c051fc (diff)
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>
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 04a486a3e7b8..0f9386d4a5a0 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)
257 goto fail; 257 goto fail;
258 } 258 }
259 259
260 /* turn off notification till fan-out ports are reset and configured */
261 if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) {
262 gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY;
263
264 err_mask = sata_pmp_write(dev->link, SATA_PMP_GSCR_FEAT_EN,
265 gscr[SATA_PMP_GSCR_FEAT_EN]);
266 if (err_mask) {
267 rc = -EIO;
268 reason = "failed to write GSCR_FEAT_EN";
269 goto fail;
270 }
271 }
272
273 if (print_info) { 260 if (print_info) {
274 ata_dev_printk(dev, KERN_INFO, "Port Multiplier %s, " 261 ata_dev_printk(dev, KERN_INFO, "Port Multiplier %s, "
275 "0x%04x:0x%04x r%d, %d ports, feat 0x%x/0x%x\n", 262 "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)
860 struct ata_link *pmp_link = &ap->link; 847 struct ata_link *pmp_link = &ap->link;
861 struct ata_device *pmp_dev = pmp_link->device; 848 struct ata_device *pmp_dev = pmp_link->device;
862 struct ata_eh_context *pmp_ehc = &pmp_link->eh_context; 849 struct ata_eh_context *pmp_ehc = &pmp_link->eh_context;
850 u32 *gscr = pmp_dev->gscr;
863 struct ata_link *link; 851 struct ata_link *link;
864 struct ata_device *dev; 852 struct ata_device *dev;
865 unsigned int err_mask; 853 unsigned int err_mask;
@@ -897,6 +885,22 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
897 if (rc) 885 if (rc)
898 goto pmp_fail; 886 goto pmp_fail;
899 887
888 /* PHY event notification can disturb reset and other recovery
889 * operations. Turn it off.
890 */
891 if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) {
892 gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY;
893
894 err_mask = sata_pmp_write(pmp_link, SATA_PMP_GSCR_FEAT_EN,
895 gscr[SATA_PMP_GSCR_FEAT_EN]);
896 if (err_mask) {
897 ata_link_printk(pmp_link, KERN_WARNING,
898 "failed to disable NOTIFY (err_mask=0x%x)\n",
899 err_mask);
900 goto pmp_fail;
901 }
902 }
903
900 /* handle disabled links */ 904 /* handle disabled links */
901 rc = sata_pmp_eh_handle_disabled_links(ap); 905 rc = sata_pmp_eh_handle_disabled_links(ap);
902 if (rc) 906 if (rc)
@@ -919,10 +923,10 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
919 923
920 /* enable notification */ 924 /* enable notification */
921 if (pmp_dev->flags & ATA_DFLAG_AN) { 925 if (pmp_dev->flags & ATA_DFLAG_AN) {
922 pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY; 926 gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY;
923 927
924 err_mask = sata_pmp_write(pmp_dev->link, SATA_PMP_GSCR_FEAT_EN, 928 err_mask = sata_pmp_write(pmp_link, SATA_PMP_GSCR_FEAT_EN,
925 pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN]); 929 gscr[SATA_PMP_GSCR_FEAT_EN]);
926 if (err_mask) { 930 if (err_mask) {
927 ata_dev_printk(pmp_dev, KERN_ERR, "failed to write " 931 ata_dev_printk(pmp_dev, KERN_ERR, "failed to write "
928 "PMP_FEAT_EN (Emask=0x%x)\n", err_mask); 932 "PMP_FEAT_EN (Emask=0x%x)\n", err_mask);