diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 36 | ||||
-rw-r--r-- | drivers/ata/pata_it821x.c | 35 |
2 files changed, 53 insertions, 18 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ee72994500a3..627703cba9a6 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -950,8 +950,8 @@ unsigned int ata_dev_try_classify(struct ata_device *dev, int present, | |||
950 | if (r_err) | 950 | if (r_err) |
951 | *r_err = err; | 951 | *r_err = err; |
952 | 952 | ||
953 | /* see if device passed diags: if master then continue and warn later */ | 953 | /* see if device passed diags: continue and warn later */ |
954 | if (err == 0 && dev->devno == 0) | 954 | if (err == 0) |
955 | /* diagnostic fail : do nothing _YET_ */ | 955 | /* diagnostic fail : do nothing _YET_ */ |
956 | dev->horkage |= ATA_HORKAGE_DIAGNOSTIC; | 956 | dev->horkage |= ATA_HORKAGE_DIAGNOSTIC; |
957 | else if (err == 1) | 957 | else if (err == 1) |
@@ -2262,19 +2262,8 @@ int ata_dev_configure(struct ata_device *dev) | |||
2262 | dev->flags |= ATA_DFLAG_DIPM; | 2262 | dev->flags |= ATA_DFLAG_DIPM; |
2263 | } | 2263 | } |
2264 | 2264 | ||
2265 | if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) { | 2265 | /* Limit PATA drive on SATA cable bridge transfers to udma5, |
2266 | /* Let the user know. We don't want to disallow opens for | 2266 | 200 sectors */ |
2267 | rescue purposes, or in case the vendor is just a blithering | ||
2268 | idiot */ | ||
2269 | if (print_info) { | ||
2270 | ata_dev_printk(dev, KERN_WARNING, | ||
2271 | "Drive reports diagnostics failure. This may indicate a drive\n"); | ||
2272 | ata_dev_printk(dev, KERN_WARNING, | ||
2273 | "fault or invalid emulation. Contact drive vendor for information.\n"); | ||
2274 | } | ||
2275 | } | ||
2276 | |||
2277 | /* limit bridge transfers to udma5, 200 sectors */ | ||
2278 | if (ata_dev_knobble(dev)) { | 2267 | if (ata_dev_knobble(dev)) { |
2279 | if (ata_msg_drv(ap) && print_info) | 2268 | if (ata_msg_drv(ap) && print_info) |
2280 | ata_dev_printk(dev, KERN_INFO, | 2269 | ata_dev_printk(dev, KERN_INFO, |
@@ -2303,6 +2292,21 @@ int ata_dev_configure(struct ata_device *dev) | |||
2303 | if (ap->ops->dev_config) | 2292 | if (ap->ops->dev_config) |
2304 | ap->ops->dev_config(dev); | 2293 | ap->ops->dev_config(dev); |
2305 | 2294 | ||
2295 | if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) { | ||
2296 | /* Let the user know. We don't want to disallow opens for | ||
2297 | rescue purposes, or in case the vendor is just a blithering | ||
2298 | idiot. Do this after the dev_config call as some controllers | ||
2299 | with buggy firmware may want to avoid reporting false device | ||
2300 | bugs */ | ||
2301 | |||
2302 | if (print_info) { | ||
2303 | ata_dev_printk(dev, KERN_WARNING, | ||
2304 | "Drive reports diagnostics failure. This may indicate a drive\n"); | ||
2305 | ata_dev_printk(dev, KERN_WARNING, | ||
2306 | "fault or invalid emulation. Contact drive vendor for information.\n"); | ||
2307 | } | ||
2308 | } | ||
2309 | |||
2306 | if (ata_msg_probe(ap)) | 2310 | if (ata_msg_probe(ap)) |
2307 | ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n", | 2311 | ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n", |
2308 | __FUNCTION__, ata_chk_status(ap)); | 2312 | __FUNCTION__, ata_chk_status(ap)); |
@@ -3066,7 +3070,7 @@ static int ata_dev_set_mode(struct ata_device *dev) | |||
3066 | 3070 | ||
3067 | /* Early MWDMA devices do DMA but don't allow DMA mode setting. | 3071 | /* Early MWDMA devices do DMA but don't allow DMA mode setting. |
3068 | Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */ | 3072 | Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */ |
3069 | if (dev->xfer_shift == ATA_SHIFT_MWDMA && | 3073 | if (dev->xfer_shift == ATA_SHIFT_MWDMA && |
3070 | dev->dma_mode == XFER_MW_DMA_0 && | 3074 | dev->dma_mode == XFER_MW_DMA_0 && |
3071 | (dev->id[63] >> 8) & 1) | 3075 | (dev->id[63] >> 8) & 1) |
3072 | err_mask &= ~AC_ERR_DEV; | 3076 | err_mask &= ~AC_ERR_DEV; |
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index ca9aae09daed..109ddd42c266 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c | |||
@@ -430,7 +430,7 @@ static unsigned int it821x_smart_qc_issue_prot(struct ata_queued_cmd *qc) | |||
430 | return ata_qc_issue_prot(qc); | 430 | return ata_qc_issue_prot(qc); |
431 | } | 431 | } |
432 | printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command); | 432 | printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command); |
433 | return AC_ERR_INVALID; | 433 | return AC_ERR_DEV; |
434 | } | 434 | } |
435 | 435 | ||
436 | /** | 436 | /** |
@@ -516,6 +516,37 @@ static void it821x_dev_config(struct ata_device *adev) | |||
516 | printk("(%dK stripe)", adev->id[146]); | 516 | printk("(%dK stripe)", adev->id[146]); |
517 | printk(".\n"); | 517 | printk(".\n"); |
518 | } | 518 | } |
519 | /* This is a controller firmware triggered funny, don't | ||
520 | report the drive faulty! */ | ||
521 | adev->horkage &= ~ATA_HORKAGE_DIAGNOSTIC; | ||
522 | } | ||
523 | |||
524 | /** | ||
525 | * it821x_ident_hack - Hack identify data up | ||
526 | * @ap: Port | ||
527 | * | ||
528 | * Walk the devices on this firmware driven port and slightly | ||
529 | * mash the identify data to stop us and common tools trying to | ||
530 | * use features not firmware supported. The firmware itself does | ||
531 | * some masking (eg SMART) but not enough. | ||
532 | * | ||
533 | * This is a bit of an abuse of the cable method, but it is the | ||
534 | * only method called at the right time. We could modify the libata | ||
535 | * core specifically for ident hacking but while we have one offender | ||
536 | * it seems better to keep the fallout localised. | ||
537 | */ | ||
538 | |||
539 | static int it821x_ident_hack(struct ata_port *ap) | ||
540 | { | ||
541 | struct ata_device *adev; | ||
542 | ata_link_for_each_dev(adev, &ap->link) { | ||
543 | if (ata_dev_enabled(adev)) { | ||
544 | adev->id[84] &= ~(1 << 6); /* No FUA */ | ||
545 | adev->id[85] &= ~(1 << 10); /* No HPA */ | ||
546 | adev->id[76] = 0; /* No NCQ/AN etc */ | ||
547 | } | ||
548 | } | ||
549 | return ata_cable_unknown(ap); | ||
519 | } | 550 | } |
520 | 551 | ||
521 | 552 | ||
@@ -634,7 +665,7 @@ static struct ata_port_operations it821x_smart_port_ops = { | |||
634 | .thaw = ata_bmdma_thaw, | 665 | .thaw = ata_bmdma_thaw, |
635 | .error_handler = ata_bmdma_error_handler, | 666 | .error_handler = ata_bmdma_error_handler, |
636 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 667 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
637 | .cable_detect = ata_cable_unknown, | 668 | .cable_detect = it821x_ident_hack, |
638 | 669 | ||
639 | .bmdma_setup = ata_bmdma_setup, | 670 | .bmdma_setup = ata_bmdma_setup, |
640 | .bmdma_start = ata_bmdma_start, | 671 | .bmdma_start = ata_bmdma_start, |