--- sata_sil.c 2007-04-26 05:08:32.000000000 +0200 +++ sata_sil.c 2007-05-04 20:06:03.000000000 +0200 @@ -43,10 +43,11 @@ #include #include #include +#include #include #define DRV_NAME "sata_sil" -#define DRV_VERSION "2.1" +#define DRV_VERSION "2.1a" enum { SIL_MMIO_BAR = 5, @@ -121,6 +122,7 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance); static void sil_freeze(struct ata_port *ap); static void sil_thaw(struct ata_port *ap); +static int sil_check_atapi_dma(struct ata_queued_cmd *qc); static const struct pci_device_id sil_pci_tbl[] = { @@ -196,6 +198,7 @@ .tf_read = ata_tf_read, .check_status = ata_check_status, .exec_command = ata_exec_command, + .check_atapi_dma = sil_check_atapi_dma, .dev_select = ata_std_dev_select, .post_set_mode = sil_post_set_mode, .bmdma_setup = ata_bmdma_setup, @@ -289,6 +292,22 @@ module_param(slow_down, int, 0444); MODULE_PARM_DESC(slow_down, "Sledgehammer used to work around random problems, by limiting commands to 15 sectors (0=off, 1=on)"); +static int sil_check_atapi_dma(struct ata_queued_cmd *qc) +{ + /* limit zero data size atapi commands to pio as certain sil */ + /* chips seem to have trouble to perform dma for these commands */ + if ( (qc->scsicmd != NULL) && + (qc->scsicmd->sc_data_direction != DMA_NONE) && + (qc->nbytes == 0) ) + { + /* do not allow dma */ + return -1; + } + + /* allow dma */ + return 0; +} + static unsigned char sil_get_device_cache_line(struct pci_dev *pdev) {