diff options
author | Tejun Heo <tj@kernel.org> | 2009-10-15 10:37:32 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-10-16 06:21:54 -0400 |
commit | 4f7c2874995ac48a4622755b8bd159eb2fb6d8f4 (patch) | |
tree | ab355d2b7392a8db4807bb7b31eb61190afa01e0 /drivers/ata | |
parent | 6489e3262e6b188a1a009b65e8a94b7aa17645b7 (diff) |
libata: fix PMP initialization
Commit 842faa6c1a1d6faddf3377948e5cf214812c6c90 fixed error handling
during attach by not committing detected device class to dev->class
while attaching a new device. However, this change missed the PMP
class check in the configuration loop causing a new PMP device to go
through ata_dev_configure() as if it were an ATA or ATAPI device.
As PMP device doesn't have a regular IDENTIFY data, this makes
ata_dev_configure() tries to configure a PMP device using an invalid
data. For the most part, it wasn't too harmful and went unnoticed but
this ends up clearing dev->flags which may have ATA_DFLAG_AN set by
sata_pmp_attach(). This means that SATA_PMP_FEAT_NOTIFY ends up being
disabled on PMPs and on PMPs which honor the flag breaks hotplug
support.
This problem was discovered and reported by Ethan Hsiao.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Ethan Hsiao <ethanhsiao@jmicron.com>
Cc: stable@kernel.org
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-eh.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 0a97822da211..bba2ae5df1c2 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -2981,12 +2981,14 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, | |||
2981 | * device detection messages backwards. | 2981 | * device detection messages backwards. |
2982 | */ | 2982 | */ |
2983 | ata_for_each_dev(dev, link, ALL) { | 2983 | ata_for_each_dev(dev, link, ALL) { |
2984 | if (!(new_mask & (1 << dev->devno)) || | 2984 | if (!(new_mask & (1 << dev->devno))) |
2985 | dev->class == ATA_DEV_PMP) | ||
2986 | continue; | 2985 | continue; |
2987 | 2986 | ||
2988 | dev->class = ehc->classes[dev->devno]; | 2987 | dev->class = ehc->classes[dev->devno]; |
2989 | 2988 | ||
2989 | if (dev->class == ATA_DEV_PMP) | ||
2990 | continue; | ||
2991 | |||
2990 | ehc->i.flags |= ATA_EHI_PRINTINFO; | 2992 | ehc->i.flags |= ATA_EHI_PRINTINFO; |
2991 | rc = ata_dev_configure(dev); | 2993 | rc = ata_dev_configure(dev); |
2992 | ehc->i.flags &= ~ATA_EHI_PRINTINFO; | 2994 | ehc->i.flags &= ~ATA_EHI_PRINTINFO; |