tf.protocol = ATA_PROT_NODATA;
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
- if (err_mask) {
+ if (err_mask && id[2] != 0x738c) {
rc = -EIO;
reason = "SPINUP failed";
goto err_out;
dev->flags |= ATA_DFLAG_FLUSH_EXT;
}
- if (ata_id_hpa_enabled(dev->id))
- dev->n_sectors = ata_hpa_resize(dev);
+ if (!(dev->horkage & ATA_HORKAGE_BROKEN_HPA) &&
+ ata_id_hpa_enabled(dev->id))
+ dev->n_sectors = ata_hpa_resize(dev);
/* config NCQ */
ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
goto fail;
/* verify n_sectors hasn't changed */
- if (dev->class == ATA_DEV_ATA && dev->n_sectors != n_sectors) {
+ if (dev->class == ATA_DEV_ATA && n_sectors &&
+ dev->n_sectors != n_sectors) {
ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
"%llu != %llu\n",
(unsigned long long)n_sectors,
(unsigned long long)dev->n_sectors);
+
+ /* restore original n_sectors */
+ dev->n_sectors = n_sectors;
+
rc = -ENODEV;
goto fail;
}
{ "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, },
{ "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, },
{ "ST9160821AS", "3.CLF", ATA_HORKAGE_NONCQ, },
+ { "SAMSUNG HD401LJ", "ZZ100-15", ATA_HORKAGE_NONCQ, },
- /* Devices with NCQ limits */
+ /* devices which puke on READ_NATIVE_MAX */
+ { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, },
+ { "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA },
+ { "WDC WD2500JD-00HBB0", "WD-WMAL71490727", ATA_HORKAGE_BROKEN_HPA },
+ { "MAXTOR 6L080L4", "A93.0500", ATA_HORKAGE_BROKEN_HPA },
/* End Marker */
{ }
tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+ /* A clean abort indicates an original or just out of spec drive
+ and we should continue as we issue the setup based on the
+ drive reported working geometry */
+ if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED))
+ err_mask = 0;
DPRINTK("EXIT, err_mask=%x\n", err_mask);
return err_mask;
*/
spin_lock_irqsave(ap->lock, flags);
dev->flags &= ~ATA_DFLAG_INIT_MASK;
+ dev->horkage = 0;
spin_unlock_irqrestore(ap->lock, flags);
memset((void *)dev + ATA_DEVICE_CLEAR_OFFSET, 0,