From 7152764700559b6a4041fdaba345df9a5cd962f0 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Mon, 2 Apr 2007 11:28:52 +0800 Subject: libata: reorder HSM_ST_FIRST for easier decoding (take 3) patch 1/4: Reorder HSM_ST_FIRST, such that the task state transition is easier decoded with human eyes. Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- include/linux/libata.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index e3f32f3189b2..c7b5e661fe59 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -315,11 +315,11 @@ enum { enum hsm_task_states { HSM_ST_IDLE, /* no command on going */ + HSM_ST_FIRST, /* (waiting the device to) + write CDB or first data block */ HSM_ST, /* (waiting the device to) transfer data */ HSM_ST_LAST, /* (waiting the device to) complete command */ HSM_ST_ERR, /* error */ - HSM_ST_FIRST, /* (waiting the device to) - write CDB or first data block */ }; enum ata_completion_errors { -- cgit v1.2.3 From 18d6e9d51891f91af4e7351cbab3cb180bb9f430 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Mon, 2 Apr 2007 11:34:15 +0800 Subject: libata: Limit max sector to 128 for TORiSAN DVD drives (take 3) patch 3/4: The TORiSAN drive locks up when max sector == 256. Limit max sector to 128 for the TORiSAN DRD-N216 drives. (http://bugzilla.kernel.org/show_bug.cgi?id=6710) Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 6 ++++++ include/linux/ata.h | 1 + include/linux/libata.h | 1 + 3 files changed, 8 insertions(+) (limited to 'include') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index e07142b4bb54..84f6f8575966 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1784,6 +1784,9 @@ int ata_dev_configure(struct ata_device *dev) dev->max_sectors = ATA_MAX_SECTORS; } + if (ata_device_blacklisted(dev) & ATA_HORKAGE_MAX_SEC_128) + dev->max_sectors = min(ATA_MAX_SECTORS_128, dev->max_sectors); + if (ap->ops->dev_config) ap->ops->dev_config(ap, dev); @@ -3352,6 +3355,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, { "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA }, + /* Weird ATAPI devices */ + { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, + /* Devices we expect to fail diagnostics */ /* Devices where NCQ should be avoided */ diff --git a/include/linux/ata.h b/include/linux/ata.h index c331da2da5f7..6caeb98e29dd 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -40,6 +40,7 @@ enum { ATA_MAX_DEVICES = 2, /* per bus/port */ ATA_MAX_PRD = 256, /* we could make these 256/256 */ ATA_SECT_SIZE = 512, + ATA_MAX_SECTORS_128 = 128, ATA_MAX_SECTORS = 256, ATA_MAX_SECTORS_LBA48 = 65535,/* TODO: 65536? */ diff --git a/include/linux/libata.h b/include/linux/libata.h index c7b5e661fe59..c04aec360406 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -311,6 +311,7 @@ enum { ATA_HORKAGE_DIAGNOSTIC = (1 << 0), /* Failed boot diag */ ATA_HORKAGE_NODMA = (1 << 1), /* DMA problems */ ATA_HORKAGE_NONCQ = (1 << 2), /* Don't use NCQ */ + ATA_HORKAGE_MAX_SEC_128 = (1 << 3), /* Limit max sects to 128 */ }; enum hsm_task_states { -- cgit v1.2.3 From 6f23a31d1cbe791a1ce86ffa9b23251ab0a1ef45 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Mon, 2 Apr 2007 11:39:25 +0800 Subject: libata: Limit ATAPI DMA to R/W commands only for TORiSAN DVD drives (take 3) patch 4/4: Limit ATAPI DMA to R/W commands only for TORiSAN DRD-N216 DVD-ROM drives (http://bugzilla.kernel.org/show_bug.cgi?id=6710) Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 27 ++++++++++++++++++++++++++- include/linux/libata.h | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 84f6f8575966..cf2338cbe4ea 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1787,6 +1787,10 @@ int ata_dev_configure(struct ata_device *dev) if (ata_device_blacklisted(dev) & ATA_HORKAGE_MAX_SEC_128) dev->max_sectors = min(ATA_MAX_SECTORS_128, dev->max_sectors); + /* limit ATAPI DMA to R/W commands only */ + if (ata_device_blacklisted(dev) & ATA_HORKAGE_DMA_RW_ONLY) + dev->horkage |= ATA_HORKAGE_DMA_RW_ONLY; + if (ap->ops->dev_config) ap->ops->dev_config(ap, dev); @@ -3356,7 +3360,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA }, /* Weird ATAPI devices */ - { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, + { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 | + ATA_HORKAGE_DMA_RW_ONLY }, /* Devices we expect to fail diagnostics */ @@ -3680,6 +3685,26 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; int rc = 0; /* Assume ATAPI DMA is OK by default */ + /* some drives can only do ATAPI DMA on read/write */ + if (unlikely(qc->dev->horkage & ATA_HORKAGE_DMA_RW_ONLY)) { + struct scsi_cmnd *cmd = qc->scsicmd; + u8 *scsicmd = cmd->cmnd; + + switch (scsicmd[0]) { + case READ_10: + case WRITE_10: + case READ_12: + case WRITE_12: + case READ_6: + case WRITE_6: + /* atapi dma maybe ok */ + break; + default: + /* turn off atapi dma */ + return 1; + } + } + if (ap->ops->check_atapi_dma) rc = ap->ops->check_atapi_dma(qc); diff --git a/include/linux/libata.h b/include/linux/libata.h index c04aec360406..0cfbcb6f08eb 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -312,6 +312,7 @@ enum { ATA_HORKAGE_NODMA = (1 << 1), /* DMA problems */ ATA_HORKAGE_NONCQ = (1 << 2), /* Don't use NCQ */ ATA_HORKAGE_MAX_SEC_128 = (1 << 3), /* Limit max sects to 128 */ + ATA_HORKAGE_DMA_RW_ONLY = (1 << 4), /* ATAPI DMA for RW only */ }; enum hsm_task_states { -- cgit v1.2.3