|
@@ -1784,6 +1784,13 @@ 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);
|
|
|
+
|
|
|
+ /* 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);
|
|
|
|
|
@@ -3352,6 +3359,10 @@ 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 |
|
|
|
+ ATA_HORKAGE_DMA_RW_ONLY },
|
|
|
+
|
|
|
/* Devices we expect to fail diagnostics */
|
|
|
|
|
|
/* Devices where NCQ should be avoided */
|
|
@@ -3679,6 +3690,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);
|
|
|
|
|
@@ -4722,8 +4753,8 @@ static void fill_result_tf(struct ata_queued_cmd *qc)
|
|
|
{
|
|
|
struct ata_port *ap = qc->ap;
|
|
|
|
|
|
- ap->ops->tf_read(ap, &qc->result_tf);
|
|
|
qc->result_tf.flags = qc->tf.flags;
|
|
|
+ ap->ops->tf_read(ap, &qc->result_tf);
|
|
|
}
|
|
|
|
|
|
/**
|