diff options
author | Tejun Heo <tj@kernel.org> | 2009-07-08 20:27:50 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-07-14 22:41:46 -0400 |
commit | d0cb43b35d64877b2944bd37719708be5d7bbf99 (patch) | |
tree | 7b282b1070613c552143d143f74e407c2ccb4b6e /drivers/ata | |
parent | fe2c4d018fc6127610fef677e020b3bb41cfaaaf (diff) |
libata: implement and use HORKAGE_NOSETXFER, take#2
PIONEER DVD-RW DVRTD08 times out SETXFER if no media is present. The
device is SATA and simply skipping SETXFER works around the problem.
Implement ATA_HORKAGE_NOSETXFER and apply it to the device.
Reported by Moritz Rigler in the following thread.
http://thread.gmane.org/gmane.linux.ide/36790
and by Lars in bko#9540.
Updated to whine and ignore NOSETXFER if PATA component is detected as
suggested by Alan Cox.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Moritz Rigler <linux-ide@momail.e4ward.com>
Reported-by: Lars <lars21ce@gmx.de>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 045a486a09ea..2c6aedaef718 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -3392,17 +3392,27 @@ int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel) | |||
3392 | 3392 | ||
3393 | static int ata_dev_set_mode(struct ata_device *dev) | 3393 | static int ata_dev_set_mode(struct ata_device *dev) |
3394 | { | 3394 | { |
3395 | struct ata_port *ap = dev->link->ap; | ||
3395 | struct ata_eh_context *ehc = &dev->link->eh_context; | 3396 | struct ata_eh_context *ehc = &dev->link->eh_context; |
3397 | const bool nosetxfer = dev->horkage & ATA_HORKAGE_NOSETXFER; | ||
3396 | const char *dev_err_whine = ""; | 3398 | const char *dev_err_whine = ""; |
3397 | int ign_dev_err = 0; | 3399 | int ign_dev_err = 0; |
3398 | unsigned int err_mask; | 3400 | unsigned int err_mask = 0; |
3399 | int rc; | 3401 | int rc; |
3400 | 3402 | ||
3401 | dev->flags &= ~ATA_DFLAG_PIO; | 3403 | dev->flags &= ~ATA_DFLAG_PIO; |
3402 | if (dev->xfer_shift == ATA_SHIFT_PIO) | 3404 | if (dev->xfer_shift == ATA_SHIFT_PIO) |
3403 | dev->flags |= ATA_DFLAG_PIO; | 3405 | dev->flags |= ATA_DFLAG_PIO; |
3404 | 3406 | ||
3405 | err_mask = ata_dev_set_xfermode(dev); | 3407 | if (nosetxfer && ap->flags & ATA_FLAG_SATA && ata_id_is_sata(dev->id)) |
3408 | dev_err_whine = " (SET_XFERMODE skipped)"; | ||
3409 | else { | ||
3410 | if (nosetxfer) | ||
3411 | ata_dev_printk(dev, KERN_WARNING, | ||
3412 | "NOSETXFER but PATA detected - can't " | ||
3413 | "skip SETXFER, might malfunction\n"); | ||
3414 | err_mask = ata_dev_set_xfermode(dev); | ||
3415 | } | ||
3406 | 3416 | ||
3407 | if (err_mask & ~AC_ERR_DEV) | 3417 | if (err_mask & ~AC_ERR_DEV) |
3408 | goto fail; | 3418 | goto fail; |
@@ -4297,6 +4307,12 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4297 | /* Devices which aren't very happy with higher link speeds */ | 4307 | /* Devices which aren't very happy with higher link speeds */ |
4298 | { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, | 4308 | { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, |
4299 | 4309 | ||
4310 | /* | ||
4311 | * Devices which choke on SETXFER. Applies only if both the | ||
4312 | * device and controller are SATA. | ||
4313 | */ | ||
4314 | { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER }, | ||
4315 | |||
4300 | /* End Marker */ | 4316 | /* End Marker */ |
4301 | { } | 4317 | { } |
4302 | }; | 4318 | }; |