Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6bbfd53d authored by Alan Cox's avatar Alan Cox Committed by Jeff Garzik
Browse files

libata: handle broken cable reporting



One or two ancient drives predated the cable spec and didn't sent the
valid bits for the field. I had hoped to leave this out of libata as a
piece of historical annoyance but a recent CD drive shows the same bug so
we have to import support for it.

Same concept as Bartlomiej's changes old IDE except that as we have
centralised blacklists we can avoid keeping another private table of stuff

Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 73946f9f
Loading
Loading
Loading
Loading
+20 −1
Original line number Original line Diff line number Diff line
@@ -4241,6 +4241,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
	{ "ST340823A",		NULL,		ATA_HORKAGE_HPA_SIZE, },
	{ "ST340823A",		NULL,		ATA_HORKAGE_HPA_SIZE, },
	{ "ST320413A",		NULL,		ATA_HORKAGE_HPA_SIZE, },
	{ "ST320413A",		NULL,		ATA_HORKAGE_HPA_SIZE, },


	/* Devices which get the IVB wrong */
	{ "QUANTUM FIREBALLlct10 05", "A03.0900", ATA_HORKAGE_IVB, },
	{ "TSSTcorp CDDVDW SH-S202J", "SB00",	  ATA_HORKAGE_IVB, },

	/* End Marker */
	/* End Marker */
	{ }
	{ }
};
};
@@ -4301,6 +4305,21 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
	return (dev->horkage & ATA_HORKAGE_NODMA) ? 1 : 0;
	return (dev->horkage & ATA_HORKAGE_NODMA) ? 1 : 0;
}
}


/**
 *	ata_is_40wire		-	check drive side detection
 *	@dev: device
 *
 *	Perform drive side detection decoding, allowing for device vendors
 *	who can't follow the documentation.
 */

static int ata_is_40wire(struct ata_device *dev)
{
	if (dev->horkage & ATA_HORKAGE_IVB)
		return ata_drive_40wire_relaxed(dev->id);
	return ata_drive_40wire(dev->id);
}

/**
/**
 *	ata_dev_xfermask - Compute supported xfermask of the given device
 *	ata_dev_xfermask - Compute supported xfermask of the given device
 *	@dev: Device to compute xfermask for
 *	@dev: Device to compute xfermask for
@@ -4370,7 +4389,7 @@ static void ata_dev_xfermask(struct ata_device *dev)
	if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA))
	if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA))
		/* UDMA/44 or higher would be available */
		/* UDMA/44 or higher would be available */
		if ((ap->cbl == ATA_CBL_PATA40) ||
		if ((ap->cbl == ATA_CBL_PATA40) ||
		    (ata_drive_40wire(dev->id) &&
		    (ata_is_40wire(dev) &&
		    (ap->cbl == ATA_CBL_PATA_UNK ||
		    (ap->cbl == ATA_CBL_PATA_UNK ||
		     ap->cbl == ATA_CBL_PATA80))) {
		     ap->cbl == ATA_CBL_PATA80))) {
			ata_dev_printk(dev, KERN_WARNING,
			ata_dev_printk(dev, KERN_WARNING,
+9 −0
Original line number Original line Diff line number Diff line
@@ -537,6 +537,15 @@ static inline int ata_drive_40wire(const u16 *dev_id)
	return 1;
	return 1;
}
}


static inline int ata_drive_40wire_relaxed(const u16 *dev_id)
{
	if (ata_id_is_sata(dev_id))
		return 0;	/* SATA */
	if ((dev_id[93] & 0x2000) == 0x2000)
		return 0;	/* 80 wire */
	return 1;
}

static inline int atapi_cdb_len(const u16 *dev_id)
static inline int atapi_cdb_len(const u16 *dev_id)
{
{
	u16 tmp = dev_id[0] & 0x3;
	u16 tmp = dev_id[0] & 0x3;
+1 −0
Original line number Original line Diff line number Diff line
@@ -339,6 +339,7 @@ enum {
	ATA_HORKAGE_SKIP_PM	= (1 << 5),	/* Skip PM operations */
	ATA_HORKAGE_SKIP_PM	= (1 << 5),	/* Skip PM operations */
	ATA_HORKAGE_HPA_SIZE	= (1 << 6),	/* native size off by one */
	ATA_HORKAGE_HPA_SIZE	= (1 << 6),	/* native size off by one */
	ATA_HORKAGE_IPM		= (1 << 7),	/* Link PM problems */
	ATA_HORKAGE_IPM		= (1 << 7),	/* Link PM problems */
	ATA_HORKAGE_IVB		= (1 << 8),	/* cbl det validity bit bugs */


	 /* DMA mask for user DMA control: User visible values; DO NOT
	 /* DMA mask for user DMA control: User visible values; DO NOT
	    renumber */
	    renumber */