mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 21:54:11 +08:00
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: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
parent
c77a036bec
commit
4a9c7b3359
@ -4156,29 +4156,33 @@ static int cable_is_40wire(struct ata_port *ap)
|
||||
struct ata_link *link;
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
return 0;
|
||||
/* 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
|
||||
because
|
||||
- In many setups only the one drive (slave if present)
|
||||
will give a valid detect
|
||||
- If you have a non detect capable drive you don't
|
||||
want it to colour the choice
|
||||
*/
|
||||
/* 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 because
|
||||
* - in many setups only the one drive (slave if present) will
|
||||
* give a valid detect
|
||||
* - if you have a non detect capable drive you don't want it
|
||||
* to colour the choice
|
||||
*/
|
||||
ata_port_for_each_link(link, ap) {
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (!ata_is_40wire(dev))
|
||||
if (ata_dev_enabled(dev) && !ata_is_40wire(dev))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -603,6 +603,9 @@ void ata_scsi_error(struct Scsi_Host *host)
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
int devno = dev->devno;
|
||||
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
ehc->saved_xfer_mode[devno] = dev->xfer_mode;
|
||||
if (ata_ncq_enabled(dev))
|
||||
ehc->saved_ncq_enabled |= 1 << devno;
|
||||
@ -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 */
|
||||
ata_link_for_each_dev(dev, link) {
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
if (!(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) {
|
||||
struct ata_ering_entry *ent;
|
||||
|
||||
@ -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_ncq = !!(ehc->saved_ncq_enabled & (1 << dev->devno));
|
||||
|
||||
if (!ata_dev_enabled(dev))
|
||||
continue;
|
||||
|
||||
if (dev->xfer_mode != saved_xfer_mode ||
|
||||
ata_ncq_enabled(dev) != saved_ncq)
|
||||
dev->flags |= ATA_DFLAG_DUBIOUS_XFER;
|
||||
|
Loading…
Reference in New Issue
Block a user