diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -67,6 +67,8 @@ enum { SIL_INTR_STEERING = (1 << 1), SIL_QUIRK_MOD15WRITE = (1 << 0), SIL_QUIRK_UDMA5MAX = (1 << 1), + + SIL_DMA_BOUNDARY = 0xffffffffU, }; static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); @@ -74,6 +76,8 @@ static void sil_dev_config(struct ata_po static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void sil_post_set_mode (struct ata_port *ap); +static void sil_qc_prep(struct ata_queued_cmd *qc); + static struct pci_device_id sil_pci_tbl[] = { { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, @@ -126,13 +130,13 @@ static Scsi_Host_Template sil_sht = { .eh_strategy_handler = ata_scsi_error, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = LIBATA_MAX_PRD, + .sg_tablesize = ATA_MAX_PRD, .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, .use_clustering = ATA_SHT_USE_CLUSTERING, .proc_name = DRV_NAME, - .dma_boundary = ATA_DMA_BOUNDARY, + .dma_boundary = SIL_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, .bios_param = ata_std_bios_param, .ordered_flush = 1, @@ -152,7 +156,7 @@ static struct ata_port_operations sil_op .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, + .qc_prep = sil_qc_prep, .qc_issue = ata_qc_issue_prot, .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, @@ -197,10 +201,10 @@ static const struct { unsigned long xfer_mode;/* data transfer mode register */ } sil_port[] = { /* port 0 ... */ - { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4 }, - { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4 }, - { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4 }, - { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4 }, + { 0x80, 0x8A, 0x10, 0x100, 0x148, 0xb4 }, + { 0xC0, 0xCA, 0x18, 0x180, 0x1c8, 0xf4 }, + { 0x280, 0x28A, 0x210, 0x300, 0x348, 0x2b4 }, + { 0x2C0, 0x2CA, 0x218, 0x380, 0x3c8, 0x2f4 }, /* ... port 3 */ }; @@ -210,6 +214,39 @@ MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, sil_pci_tbl); MODULE_VERSION(DRV_VERSION); + +static inline void sil_fill_sg(struct ata_queued_cmd *qc) +{ + struct scatterlist *sg = qc->sg; + struct ata_port *ap = qc->ap; + unsigned int idx, nelem; + + assert(sg != NULL); + assert(qc->n_elem > 0); + + idx = 0; + for (nelem = qc->n_elem; nelem; nelem--,sg++) { + u32 addr = sg_dma_address(sg); + u32 sg_len = sg_dma_len(sg); + + ap->prd[idx].addr = cpu_to_le32(addr); + ap->prd[idx].flags_len = cpu_to_le32(sg_len); + + idx++; + } + + if (idx) + ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); +} + +static void sil_qc_prep(struct ata_queued_cmd *qc) +{ + if (!(qc->flags & ATA_QCFLAG_DMAMAP)) + return; + + sil_fill_sg(qc); +} + static unsigned char sil_get_device_cache_line(struct pci_dev *pdev) { u8 cache_line = 0;