Commit 2a11587d authored by Jeff Garzik's avatar Jeff Garzik

[libata] add DMA blacklist

Blacklist devices that seem to have some problem with DMA.

From drivers/ide/ide-dma.c blacklist.
parent 87475e1f
...@@ -1700,6 +1700,70 @@ void ata_bus_reset(struct ata_port *ap) ...@@ -1700,6 +1700,70 @@ void ata_bus_reset(struct ata_port *ap)
DPRINTK("EXIT\n"); DPRINTK("EXIT\n");
} }
static void ata_pr_blacklisted(struct ata_port *ap, struct ata_device *dev)
{
printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n",
ap->id, dev->devno);
}
static const char * ata_dma_blacklist [] = {
"WDC AC11000H",
"WDC AC22100H",
"WDC AC32500H",
"WDC AC33100H",
"WDC AC31600H",
"WDC AC32100H",
"WDC AC23200L",
"Compaq CRD-8241B",
"CRD-8400B",
"CRD-8480B",
"CRD-8480C",
"CRD-8482B",
"CRD-84",
"SanDisk SDP3B",
"SanDisk SDP3B-64",
"SANYO CD-ROM CRD",
"HITACHI CDR-8",
"HITACHI CDR-8335",
"HITACHI CDR-8435",
"Toshiba CD-ROM XM-6202B",
"CD-532E-A",
"E-IDE CD-ROM CR-840",
"CD-ROM Drive/F5A",
"WPI CDD-820",
"SAMSUNG CD-ROM SC-148C",
"SAMSUNG CD-ROM SC",
"SanDisk SDP3B-64",
"SAMSUNG CD-ROM SN-124",
"ATAPI CD-ROM DRIVE 40X MAXIMUM",
"_NEC DV5800A",
};
static int ata_dma_blacklisted(struct ata_port *ap, struct ata_device *dev)
{
unsigned char model_num[40];
char *s;
unsigned int len;
int i;
ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
sizeof(model_num));
s = &model_num[0];
len = strnlen(s, sizeof(model_num));
/* ATAPI specifies that empty space is blank-filled; remove blanks */
while ((len > 0) && (s[len - 1] == ' ')) {
len--;
s[len] = 0;
}
for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++)
if (!strncmp(ata_dma_blacklist[i], s, len))
return 1;
return 0;
}
static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift) static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
{ {
struct ata_device *master, *slave; struct ata_device *master, *slave;
...@@ -1712,17 +1776,37 @@ static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift) ...@@ -1712,17 +1776,37 @@ static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
if (shift == ATA_SHIFT_UDMA) { if (shift == ATA_SHIFT_UDMA) {
mask = ap->udma_mask; mask = ap->udma_mask;
if (ata_dev_present(master)) if (ata_dev_present(master)) {
mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff); mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
if (ata_dev_present(slave)) if (ata_dma_blacklisted(ap, master)) {
mask = 0;
ata_pr_blacklisted(ap, master);
}
}
if (ata_dev_present(slave)) {
mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff); mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
if (ata_dma_blacklisted(ap, slave)) {
mask = 0;
ata_pr_blacklisted(ap, slave);
}
}
} }
else if (shift == ATA_SHIFT_MWDMA) { else if (shift == ATA_SHIFT_MWDMA) {
mask = ap->mwdma_mask; mask = ap->mwdma_mask;
if (ata_dev_present(master)) if (ata_dev_present(master)) {
mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07); mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07);
if (ata_dev_present(slave)) if (ata_dma_blacklisted(ap, master)) {
mask = 0;
ata_pr_blacklisted(ap, master);
}
}
if (ata_dev_present(slave)) {
mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07); mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07);
if (ata_dma_blacklisted(ap, slave)) {
mask = 0;
ata_pr_blacklisted(ap, slave);
}
}
} }
else if (shift == ATA_SHIFT_PIO) { else if (shift == ATA_SHIFT_PIO) {
mask = ap->pio_mask; mask = ap->pio_mask;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment