aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-02-06 20:34:08 -0500
committerJeff Garzik <jeff@garzik.org>2008-02-11 14:29:47 -0500
commit4055dee7f525a702a060ea08a3fb9f045317355f (patch)
tree1239fe8cdb67bebbc126cf959d3f4376e4a9236c /drivers/ata/libata-core.c
parent7585eb1b7cf4bbace37ce18500809140c8eeccc3 (diff)
libata: ignore deverr on SETXFER if mode is configured
Some controllers (VIA CX700) raise device error on SETXFER even after mode configuration succeeded. Update ata_dev_set_mode() such that device error is ignored if transfer mode is configured correctly. To implement this, device is revalidated even after device error on SETXFER. This fixes kernel bugzilla bug 8563. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3011919f3ec8..004dae4ea5bc 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3048,6 +3048,8 @@ int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel)
3048static int ata_dev_set_mode(struct ata_device *dev) 3048static int ata_dev_set_mode(struct ata_device *dev)
3049{ 3049{
3050 struct ata_eh_context *ehc = &dev->link->eh_context; 3050 struct ata_eh_context *ehc = &dev->link->eh_context;
3051 const char *dev_err_whine = "";
3052 int ign_dev_err = 0;
3051 unsigned int err_mask; 3053 unsigned int err_mask;
3052 int rc; 3054 int rc;
3053 3055
@@ -3057,41 +3059,57 @@ static int ata_dev_set_mode(struct ata_device *dev)
3057 3059
3058 err_mask = ata_dev_set_xfermode(dev); 3060 err_mask = ata_dev_set_xfermode(dev);
3059 3061
3062 if (err_mask & ~AC_ERR_DEV)
3063 goto fail;
3064
3065 /* revalidate */
3066 ehc->i.flags |= ATA_EHI_POST_SETMODE;
3067 rc = ata_dev_revalidate(dev, ATA_DEV_UNKNOWN, 0);
3068 ehc->i.flags &= ~ATA_EHI_POST_SETMODE;
3069 if (rc)
3070 return rc;
3071
3060 /* Old CFA may refuse this command, which is just fine */ 3072 /* Old CFA may refuse this command, which is just fine */
3061 if (dev->xfer_shift == ATA_SHIFT_PIO && ata_id_is_cfa(dev->id)) 3073 if (dev->xfer_shift == ATA_SHIFT_PIO && ata_id_is_cfa(dev->id))
3062 err_mask &= ~AC_ERR_DEV; 3074 ign_dev_err = 1;
3063 3075
3064 /* Some very old devices and some bad newer ones fail any kind of 3076 /* Some very old devices and some bad newer ones fail any kind of
3065 SET_XFERMODE request but support PIO0-2 timings and no IORDY */ 3077 SET_XFERMODE request but support PIO0-2 timings and no IORDY */
3066 if (dev->xfer_shift == ATA_SHIFT_PIO && !ata_id_has_iordy(dev->id) && 3078 if (dev->xfer_shift == ATA_SHIFT_PIO && !ata_id_has_iordy(dev->id) &&
3067 dev->pio_mode <= XFER_PIO_2) 3079 dev->pio_mode <= XFER_PIO_2)
3068 err_mask &= ~AC_ERR_DEV; 3080 ign_dev_err = 1;
3069 3081
3070 /* Early MWDMA devices do DMA but don't allow DMA mode setting. 3082 /* Early MWDMA devices do DMA but don't allow DMA mode setting.
3071 Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */ 3083 Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */
3072 if (dev->xfer_shift == ATA_SHIFT_MWDMA && 3084 if (dev->xfer_shift == ATA_SHIFT_MWDMA &&
3073 dev->dma_mode == XFER_MW_DMA_0 && 3085 dev->dma_mode == XFER_MW_DMA_0 &&
3074 (dev->id[63] >> 8) & 1) 3086 (dev->id[63] >> 8) & 1)
3075 err_mask &= ~AC_ERR_DEV; 3087 ign_dev_err = 1;
3076 3088
3077 if (err_mask) { 3089 /* if the device is actually configured correctly, ignore dev err */
3078 ata_dev_printk(dev, KERN_ERR, "failed to set xfermode " 3090 if (dev->xfer_mode == ata_xfer_mask2mode(ata_id_xfermask(dev->id)))
3079 "(err_mask=0x%x)\n", err_mask); 3091 ign_dev_err = 1;
3080 return -EIO;
3081 }
3082 3092
3083 ehc->i.flags |= ATA_EHI_POST_SETMODE; 3093 if (err_mask & AC_ERR_DEV) {
3084 rc = ata_dev_revalidate(dev, ATA_DEV_UNKNOWN, 0); 3094 if (!ign_dev_err)
3085 ehc->i.flags &= ~ATA_EHI_POST_SETMODE; 3095 goto fail;
3086 if (rc) 3096 else
3087 return rc; 3097 dev_err_whine = " (device error ignored)";
3098 }
3088 3099
3089 DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n", 3100 DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n",
3090 dev->xfer_shift, (int)dev->xfer_mode); 3101 dev->xfer_shift, (int)dev->xfer_mode);
3091 3102
3092 ata_dev_printk(dev, KERN_INFO, "configured for %s\n", 3103 ata_dev_printk(dev, KERN_INFO, "configured for %s%s\n",
3093 ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode))); 3104 ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode)),
3105 dev_err_whine);
3106
3094 return 0; 3107 return 0;
3108
3109 fail:
3110 ata_dev_printk(dev, KERN_ERR, "failed to set xfermode "
3111 "(err_mask=0x%x)\n", err_mask);
3112 return -EIO;
3095} 3113}
3096 3114
3097/** 3115/**