|
@@ -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);
|
|
|
|