summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-core.c19
-rw-r--r--include/linux/libata.h6
2 files changed, 23 insertions, 2 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index e85c2f8cf193..753b0152afd1 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -616,8 +616,11 @@ ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err)
if (r_err)
*r_err = err;
- /* see if device passed diags */
- if (err == 1)
+ /* see if device passed diags: if master then continue and warn later */
+ if (err == 0 && device == 0)
+ /* diagnostic fail : do nothing _YET_ */
+ ap->device[device].horkage |= ATA_HORKAGE_DIAGNOSTIC;
+ else if (err == 1)
/* do nothing */ ;
else if ((device == 0) && (err == 0x81))
/* do nothing */ ;
@@ -1523,6 +1526,18 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
cdb_intr_string);
}
+ if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
+ /* Let the user know. We don't want to disallow opens for
+ rescue purposes, or in case the vendor is just a blithering
+ idiot */
+ if (print_info) {
+ ata_dev_printk(dev, KERN_WARNING,
+"Drive reports diagnostics failure. This may indicate a drive\n");
+ ata_dev_printk(dev, KERN_WARNING,
+"fault or invalid emulation. Contact drive vendor for information.\n");
+ }
+ }
+
ata_set_port_max_cmd_len(ap);
/* limit bridge transfers to udma5, 200 sectors */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index ff67e7524fe9..1ef3d3901b47 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -289,6 +289,11 @@ enum {
* most devices.
*/
ATA_SPINUP_WAIT = 8000,
+
+ /* Horkage types. May be set by libata or controller on drives
+ (some horkage may be drive/controller pair dependant */
+
+ ATA_HORKAGE_DIAGNOSTIC = (1 << 0), /* Failed boot diag */
};
enum hsm_task_states {
@@ -476,6 +481,7 @@ struct ata_device {
/* error history */
struct ata_ering ering;
+ unsigned int horkage; /* List of broken features */
};
/* Offset into struct ata_device. Fields above it are maintained