aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Pelletier <plr.vincent@gmail.com>2013-05-21 16:30:58 -0400
committerTejun Heo <tj@kernel.org>2013-05-21 19:34:34 -0400
commit966fbe193f47c68e70a80ec9991098e88e7959cb (patch)
tree1a352f4f241a75b99148ef645c9f56afba863dc9
parente628dc999e43a9dd51fb6bd810772c277f934484 (diff)
libata: Add atapi_dmadir force flag
Some device require DMADIR to be enabled, but are not detected as such by atapi_id_dmadir. One such example is "Asus Serillel 2" SATA-host-to-PATA-device bridge: the bridge itself requires DMADIR, even if the bridged device does not. As atapi_dmadir module parameter can cause problems with some devices (as per Tejun Heo's memory), enabling it globally may not be possible depending on the hardware. This patch adds atapi_dmadir in the form of a "force" horkage value, allowing global, per-bus and per-device control. Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--Documentation/kernel-parameters.txt2
-rw-r--r--drivers/ata/libata-core.c3
-rw-r--r--include/linux/libata.h1
3 files changed, 5 insertions, 1 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index c3bfacb92910..489815e3e484 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1456,6 +1456,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1456 1456
1457 * dump_id: dump IDENTIFY data. 1457 * dump_id: dump IDENTIFY data.
1458 1458
1459 * atapi_dmadir: Enable ATAPI DMADIR bridge support
1460
1459 If there are multiple matching configurations changing 1461 If there are multiple matching configurations changing
1460 the same attribute, the last one is used. 1462 the same attribute, the last one is used.
1461 1463
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 5f7d5f9ee820..c97a244c099a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2395,7 +2395,7 @@ int ata_dev_configure(struct ata_device *dev)
2395 cdb_intr_string = ", CDB intr"; 2395 cdb_intr_string = ", CDB intr";
2396 } 2396 }
2397 2397
2398 if (atapi_dmadir || atapi_id_dmadir(dev->id)) { 2398 if (atapi_dmadir || (dev->horkage & ATA_HORKAGE_ATAPI_DMADIR) || atapi_id_dmadir(dev->id)) {
2399 dev->flags |= ATA_DFLAG_DMADIR; 2399 dev->flags |= ATA_DFLAG_DMADIR;
2400 dma_dir_string = ", DMADIR"; 2400 dma_dir_string = ", DMADIR";
2401 } 2401 }
@@ -6496,6 +6496,7 @@ static int __init ata_parse_force_one(char **cur,
6496 { "nosrst", .lflags = ATA_LFLAG_NO_SRST }, 6496 { "nosrst", .lflags = ATA_LFLAG_NO_SRST },
6497 { "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST }, 6497 { "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
6498 { "rstonce", .lflags = ATA_LFLAG_RST_ONCE }, 6498 { "rstonce", .lflags = ATA_LFLAG_RST_ONCE },
6499 { "atapi_dmadir", .horkage_on = ATA_HORKAGE_ATAPI_DMADIR },
6499 }; 6500 };
6500 char *start = *cur, *p = *cur; 6501 char *start = *cur, *p = *cur;
6501 char *id, *val, *endp; 6502 char *id, *val, *endp;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 47e029236f6e..c886dc87aa81 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -399,6 +399,7 @@ enum {
399 ATA_HORKAGE_BROKEN_FPDMA_AA = (1 << 15), /* skip AA */ 399 ATA_HORKAGE_BROKEN_FPDMA_AA = (1 << 15), /* skip AA */
400 ATA_HORKAGE_DUMP_ID = (1 << 16), /* dump IDENTIFY data */ 400 ATA_HORKAGE_DUMP_ID = (1 << 16), /* dump IDENTIFY data */
401 ATA_HORKAGE_MAX_SEC_LBA48 = (1 << 17), /* Set max sects to 65535 */ 401 ATA_HORKAGE_MAX_SEC_LBA48 = (1 << 17), /* Set max sects to 65535 */
402 ATA_HORKAGE_ATAPI_DMADIR = (1 << 18), /* device requires dmadir */
402 403
403 /* DMA mask for user DMA control: User visible values; DO NOT 404 /* DMA mask for user DMA control: User visible values; DO NOT
404 renumber */ 405 renumber */