Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 76910
b: refs/heads/master
c: c5038fc
h: refs/heads/master
v: v3
  • Loading branch information
Alan Cox authored and Jeff Garzik committed Jan 23, 2008
1 parent 65f4d14 commit bb55994
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a5df2eabdae7cd7840d59cffe621b3658a3a70cb
refs/heads/master: c5038fc05d4aa4ae0671776199459690e4c973cb
36 changes: 20 additions & 16 deletions trunk/drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -950,8 +950,8 @@ unsigned int ata_dev_try_classify(struct ata_device *dev, int present,
if (r_err)
*r_err = err;

/* see if device passed diags: if master then continue and warn later */
if (err == 0 && dev->devno == 0)
/* see if device passed diags: continue and warn later */
if (err == 0)
/* diagnostic fail : do nothing _YET_ */
dev->horkage |= ATA_HORKAGE_DIAGNOSTIC;
else if (err == 1)
Expand Down Expand Up @@ -2262,19 +2262,8 @@ int ata_dev_configure(struct ata_device *dev)
dev->flags |= ATA_DFLAG_DIPM;
}

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");
}
}

/* limit bridge transfers to udma5, 200 sectors */
/* Limit PATA drive on SATA cable bridge transfers to udma5,
200 sectors */
if (ata_dev_knobble(dev)) {
if (ata_msg_drv(ap) && print_info)
ata_dev_printk(dev, KERN_INFO,
Expand Down Expand Up @@ -2303,6 +2292,21 @@ int ata_dev_configure(struct ata_device *dev)
if (ap->ops->dev_config)
ap->ops->dev_config(dev);

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. Do this after the dev_config call as some controllers
with buggy firmware may want to avoid reporting false device
bugs */

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");
}
}

if (ata_msg_probe(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n",
__FUNCTION__, ata_chk_status(ap));
Expand Down Expand Up @@ -3066,7 +3070,7 @@ static int ata_dev_set_mode(struct ata_device *dev)

/* Early MWDMA devices do DMA but don't allow DMA mode setting.
Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */
if (dev->xfer_shift == ATA_SHIFT_MWDMA &&
if (dev->xfer_shift == ATA_SHIFT_MWDMA &&
dev->dma_mode == XFER_MW_DMA_0 &&
(dev->id[63] >> 8) & 1)
err_mask &= ~AC_ERR_DEV;
Expand Down
35 changes: 33 additions & 2 deletions trunk/drivers/ata/pata_it821x.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ static unsigned int it821x_smart_qc_issue_prot(struct ata_queued_cmd *qc)
return ata_qc_issue_prot(qc);
}
printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command);
return AC_ERR_INVALID;
return AC_ERR_DEV;
}

/**
Expand Down Expand Up @@ -516,6 +516,37 @@ static void it821x_dev_config(struct ata_device *adev)
printk("(%dK stripe)", adev->id[146]);
printk(".\n");
}
/* This is a controller firmware triggered funny, don't
report the drive faulty! */
adev->horkage &= ~ATA_HORKAGE_DIAGNOSTIC;
}

/**
* it821x_ident_hack - Hack identify data up
* @ap: Port
*
* Walk the devices on this firmware driven port and slightly
* mash the identify data to stop us and common tools trying to
* use features not firmware supported. The firmware itself does
* some masking (eg SMART) but not enough.
*
* This is a bit of an abuse of the cable method, but it is the
* only method called at the right time. We could modify the libata
* core specifically for ident hacking but while we have one offender
* it seems better to keep the fallout localised.
*/

static int it821x_ident_hack(struct ata_port *ap)
{
struct ata_device *adev;
ata_link_for_each_dev(adev, &ap->link) {
if (ata_dev_enabled(adev)) {
adev->id[84] &= ~(1 << 6); /* No FUA */
adev->id[85] &= ~(1 << 10); /* No HPA */
adev->id[76] = 0; /* No NCQ/AN etc */
}
}
return ata_cable_unknown(ap);
}


Expand Down Expand Up @@ -634,7 +665,7 @@ static struct ata_port_operations it821x_smart_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.cable_detect = ata_cable_unknown,
.cable_detect = it821x_ident_hack,

.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
Expand Down

0 comments on commit bb55994

Please sign in to comment.