Hello, On 03/01/2010 02:24 AM, Cengiz Günay wrote: > Before and after the swncq-atapi-pio patch I still get awful read > times from the BD-ROM drive: > > $ time dd if=/dev/sr0 of=/dev/null bs=64k count=1024 > 67108864 bytes (67 MB) copied, 106.945 seconds, 628 kB/s > => real 1m46.977s Hmmm... the drive is timing out even on 4k READ10's. This shouldn't really be happening. Can you please try this one? -- tejun
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 0c82d33..84d3eba 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -307,6 +307,7 @@ static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); static int nv_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); +static int nv_check_atapi_dma(struct ata_queued_cmd *qc); static void nv_nf2_freeze(struct ata_port *ap); static void nv_nf2_thaw(struct ata_port *ap); static void nv_ck804_freeze(struct ata_port *ap); @@ -470,6 +471,7 @@ static struct ata_port_operations nv_generic_ops = { .scr_read = nv_scr_read, .scr_write = nv_scr_write, .hardreset = nv_hardreset, + .check_atapi_dma = nv_check_atapi_dma, }; static struct ata_port_operations nv_nf2_ops = { @@ -585,7 +587,7 @@ static const struct ata_port_info nv_port_info[] = { /* SWNCQ */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_NCQ, + ATA_FLAG_NCQ | ATA_FLAG_PIO_POLLING, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, @@ -1614,6 +1616,25 @@ static int nv_hardreset(struct ata_link *link, unsigned int *class, return -EAGAIN; } +#include <scsi/scsi_cmnd.h> +static int nv_check_atapi_dma(struct ata_queued_cmd *qc) +{ + /* Whitelist commands that may use DMA. */ + switch (qc->scsicmd->cmnd[0]) { + case WRITE_12: + case WRITE_10: + case WRITE_6: + case READ_12: + case READ_10: + case READ_6: + case 0xad: /* READ_DVD_STRUCTURE */ + case 0xbe: /* READ_CD */ + if (ata_qc_raw_nbytes(qc) > 4096) + return 0; + } + return 1; +} + static void nv_nf2_freeze(struct ata_port *ap) { void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr;