Commit 4a9c7b33 authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik

libata: fix device iteration bugs

There were several places where only enabled devices should be
iterated over but device enabledness wasn't checked.

* IDENTIFY data 40 wire check in cable_is_40wire()
* xfer_mode/ncq_enabled saving in ata_scsi_error()
* DUBIOUS_XFER handling in ata_set_mode()

While at it, reformat comments in cable_is_40wire().
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent c77a036b
...@@ -4156,29 +4156,33 @@ static int cable_is_40wire(struct ata_port *ap) ...@@ -4156,29 +4156,33 @@ static int cable_is_40wire(struct ata_port *ap)
struct ata_link *link; struct ata_link *link;
struct ata_device *dev; struct ata_device *dev;
/* If the controller thinks we are 40 wire, we are */ /* If the controller thinks we are 40 wire, we are. */
if (ap->cbl == ATA_CBL_PATA40) if (ap->cbl == ATA_CBL_PATA40)
return 1; return 1;
/* If the controller thinks we are 80 wire, we are */
/* If the controller thinks we are 80 wire, we are. */
if (ap->cbl == ATA_CBL_PATA80 || ap->cbl == ATA_CBL_SATA) if (ap->cbl == ATA_CBL_PATA80 || ap->cbl == ATA_CBL_SATA)
return 0; return 0;
/* If the system is known to be 40 wire short cable (eg laptop),
then we allow 80 wire modes even if the drive isn't sure */ /* If the system is known to be 40 wire short cable (eg
* laptop), then we allow 80 wire modes even if the drive
* isn't sure.
*/
if (ap->cbl == ATA_CBL_PATA40_SHORT) if (ap->cbl == ATA_CBL_PATA40_SHORT)
return 0; return 0;
/* If the controller doesn't know we scan
/* If the controller doesn't know, we scan.
- Note: We look for all 40 wire detects at this point. *
Any 80 wire detect is taken to be 80 wire cable * Note: We look for all 40 wire detects at this point. Any
because * 80 wire detect is taken to be 80 wire cable because
- In many setups only the one drive (slave if present) * - in many setups only the one drive (slave if present) will
will give a valid detect * give a valid detect
- If you have a non detect capable drive you don't * - if you have a non detect capable drive you don't want it
want it to colour the choice * to colour the choice
*/ */
ata_port_for_each_link(link, ap) { ata_port_for_each_link(link, ap) {
ata_link_for_each_dev(dev, link) { ata_link_for_each_dev(dev, link) {
if (!ata_is_40wire(dev)) if (ata_dev_enabled(dev) && !ata_is_40wire(dev))
return 0; return 0;
} }
} }
......
...@@ -603,6 +603,9 @@ void ata_scsi_error(struct Scsi_Host *host) ...@@ -603,6 +603,9 @@ void ata_scsi_error(struct Scsi_Host *host)
ata_link_for_each_dev(dev, link) { ata_link_for_each_dev(dev, link) {
int devno = dev->devno; int devno = dev->devno;
if (!ata_dev_enabled(dev))
continue;
ehc->saved_xfer_mode[devno] = dev->xfer_mode; ehc->saved_xfer_mode[devno] = dev->xfer_mode;
if (ata_ncq_enabled(dev)) if (ata_ncq_enabled(dev))
ehc->saved_ncq_enabled |= 1 << devno; ehc->saved_ncq_enabled |= 1 << devno;
...@@ -2787,6 +2790,9 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) ...@@ -2787,6 +2790,9 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
/* if data transfer is verified, clear DUBIOUS_XFER on ering top */ /* if data transfer is verified, clear DUBIOUS_XFER on ering top */
ata_link_for_each_dev(dev, link) { ata_link_for_each_dev(dev, link) {
if (!ata_dev_enabled(dev))
continue;
if (!(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) { if (!(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) {
struct ata_ering_entry *ent; struct ata_ering_entry *ent;
...@@ -2808,6 +2814,9 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) ...@@ -2808,6 +2814,9 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
u8 saved_xfer_mode = ehc->saved_xfer_mode[dev->devno]; u8 saved_xfer_mode = ehc->saved_xfer_mode[dev->devno];
u8 saved_ncq = !!(ehc->saved_ncq_enabled & (1 << dev->devno)); u8 saved_ncq = !!(ehc->saved_ncq_enabled & (1 << dev->devno));
if (!ata_dev_enabled(dev))
continue;
if (dev->xfer_mode != saved_xfer_mode || if (dev->xfer_mode != saved_xfer_mode ||
ata_ncq_enabled(dev) != saved_ncq) ata_ncq_enabled(dev) != saved_ncq)
dev->flags |= ATA_DFLAG_DUBIOUS_XFER; dev->flags |= ATA_DFLAG_DUBIOUS_XFER;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment