diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 0c82d33..4ad76f1 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,24 @@ static int nv_hardreset(struct ata_link *link, unsigned int *class, return -EAGAIN; } +#include +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 */ + return 0; + } + return 1; +} + static void nv_nf2_freeze(struct ata_port *ap) { void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr;