|
@@ -3048,6 +3048,8 @@ int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel)
|
|
|
static int ata_dev_set_mode(struct ata_device *dev)
|
|
|
{
|
|
|
struct ata_eh_context *ehc = &dev->link->eh_context;
|
|
|
+ const char *dev_err_whine = "";
|
|
|
+ int ign_dev_err = 0;
|
|
|
unsigned int err_mask;
|
|
|
int rc;
|
|
|
|
|
@@ -3057,41 +3059,57 @@ static int ata_dev_set_mode(struct ata_device *dev)
|
|
|
|
|
|
err_mask = ata_dev_set_xfermode(dev);
|
|
|
|
|
|
+ if (err_mask & ~AC_ERR_DEV)
|
|
|
+ goto fail;
|
|
|
+
|
|
|
+ /* revalidate */
|
|
|
+ ehc->i.flags |= ATA_EHI_POST_SETMODE;
|
|
|
+ rc = ata_dev_revalidate(dev, ATA_DEV_UNKNOWN, 0);
|
|
|
+ ehc->i.flags &= ~ATA_EHI_POST_SETMODE;
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
/* Old CFA may refuse this command, which is just fine */
|
|
|
if (dev->xfer_shift == ATA_SHIFT_PIO && ata_id_is_cfa(dev->id))
|
|
|
- err_mask &= ~AC_ERR_DEV;
|
|
|
+ ign_dev_err = 1;
|
|
|
|
|
|
/* Some very old devices and some bad newer ones fail any kind of
|
|
|
SET_XFERMODE request but support PIO0-2 timings and no IORDY */
|
|
|
if (dev->xfer_shift == ATA_SHIFT_PIO && !ata_id_has_iordy(dev->id) &&
|
|
|
dev->pio_mode <= XFER_PIO_2)
|
|
|
- err_mask &= ~AC_ERR_DEV;
|
|
|
+ ign_dev_err = 1;
|
|
|
|
|
|
/* Early MWDMA devices do DMA but don't allow DMA mode setting.
|
|
|
Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */
|
|
|
if (dev->xfer_shift == ATA_SHIFT_MWDMA &&
|
|
|
dev->dma_mode == XFER_MW_DMA_0 &&
|
|
|
(dev->id[63] >> 8) & 1)
|
|
|
- err_mask &= ~AC_ERR_DEV;
|
|
|
+ ign_dev_err = 1;
|
|
|
|
|
|
- if (err_mask) {
|
|
|
- ata_dev_printk(dev, KERN_ERR, "failed to set xfermode "
|
|
|
- "(err_mask=0x%x)\n", err_mask);
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
+ /* if the device is actually configured correctly, ignore dev err */
|
|
|
+ if (dev->xfer_mode == ata_xfer_mask2mode(ata_id_xfermask(dev->id)))
|
|
|
+ ign_dev_err = 1;
|
|
|
|
|
|
- ehc->i.flags |= ATA_EHI_POST_SETMODE;
|
|
|
- rc = ata_dev_revalidate(dev, ATA_DEV_UNKNOWN, 0);
|
|
|
- ehc->i.flags &= ~ATA_EHI_POST_SETMODE;
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
+ if (err_mask & AC_ERR_DEV) {
|
|
|
+ if (!ign_dev_err)
|
|
|
+ goto fail;
|
|
|
+ else
|
|
|
+ dev_err_whine = " (device error ignored)";
|
|
|
+ }
|
|
|
|
|
|
DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n",
|
|
|
dev->xfer_shift, (int)dev->xfer_mode);
|
|
|
|
|
|
- ata_dev_printk(dev, KERN_INFO, "configured for %s\n",
|
|
|
- ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode)));
|
|
|
+ ata_dev_printk(dev, KERN_INFO, "configured for %s%s\n",
|
|
|
+ ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode)),
|
|
|
+ dev_err_whine);
|
|
|
+
|
|
|
return 0;
|
|
|
+
|
|
|
+ fail:
|
|
|
+ ata_dev_printk(dev, KERN_ERR, "failed to set xfermode "
|
|
|
+ "(err_mask=0x%x)\n", err_mask);
|
|
|
+ return -EIO;
|
|
|
}
|
|
|
|
|
|
/**
|