From 2428427e49beddd8ebc53054219fac2cc9ffee23 Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Wed, 17 Oct 2007 09:21:19 +0200 Subject: [SCSI] ide-scsi: use scsi_sg_count() instead of ->use_sg Signed-off-by: Jens Axboe --- drivers/scsi/ide-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index d297f64cd43..bd74f6c44b6 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -807,7 +807,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd, memcpy (pc->c, cmd->cmnd, cmd->cmd_len); pc->buffer = NULL; pc->sg = scsi_sglist(cmd); - pc->last_sg = sg_last(pc->sg, cmd->use_sg); + pc->last_sg = sg_last(pc->sg, scsi_sg_count(cmd)); pc->b_count = 0; pc->request_transfer = pc->buffer_size = scsi_bufflen(cmd); pc->scsi_cmd = cmd; -- cgit v1.2.3 From 8bf50f71cbfc7d043f0f135da72b3feefeaa0eb8 Mon Sep 17 00:00:00 2001 From: "Mike Miller (OS Dev)" Date: Wed, 17 Oct 2007 10:10:04 +0200 Subject: cciss: disable DMA refetch on Smart Array P600 This patch disables DMA refetch in the PCI bridge. We have disabled DMA prefetch for quite some time. Testing with XEN revealed another ASIC bug. If dom0 resides on a P600 the board can can an MCA bi accessing invalid memory addresses. Apparently, we need to disable both prefetch and refetch. My understanding is a refetch operation should not occur but it is a valid thing to do if prefetched data is no longer available for whatever reason. Please consider this patch for inclusion. Signed-off-by: Mike Miller Signed-off-by: Alex Chiang -------------------------------------------------------------------------------- Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 3fb7e8bc436..e330c26c5ad 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3035,15 +3035,20 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) } #endif - /* Disabling DMA prefetch for the P600 - * An ASIC bug may result in a prefetch beyond - * physical memory. + /* Disabling DMA prefetch and refetch for the P600. + * An ASIC bug may result in accesses to invalid memory addresses. + * We've disabled prefetch for some time now. Testing with XEN + * kernels revealed a bug in the refetch if dom0 resides on a P600. */ if(board_id == 0x3225103C) { __u32 dma_prefetch; + __u32 dma_refetch; dma_prefetch = readl(c->vaddr + I2O_DMA1_CFG); dma_prefetch |= 0x8000; writel(dma_prefetch, c->vaddr + I2O_DMA1_CFG); + pci_read_config_dword(pdev, PCI_COMMAND_PARITY, &dma_refetch); + dma_refetch |= 0x1; + pci_write_config_dword(pdev, PCI_COMMAND_PARITY, dma_refetch); } #ifdef CCISS_DEBUG -- cgit v1.2.3 From c79d88b7fa48bc21ffd09903a98b93bf0744bce3 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 17 Oct 2007 13:16:35 +0200 Subject: [SCSI] ide-scsi: remove usage of sg_last() We want to remove sg_last(), it's a very expensive interface. So keep track of number of sg entries in the sg list, instead of comparing with the last entry. Signed-off-by: Jens Axboe --- drivers/scsi/ide-scsi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index bd74f6c44b6..fa7ba64483f 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -70,7 +70,7 @@ typedef struct idescsi_pc_s { u8 *buffer; /* Data buffer */ u8 *current_position; /* Pointer into the above buffer */ struct scatterlist *sg; /* Scatter gather table */ - struct scatterlist *last_sg; /* Last sg element */ + unsigned int sg_cnt; /* Number of entries in sg */ int b_count; /* Bytes transferred from current entry */ struct scsi_cmnd *scsi_cmd; /* SCSI command */ void (*done)(struct scsi_cmnd *); /* Scsi completion routine */ @@ -192,7 +192,7 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne } bcount -= count; pc->b_count += count; if (pc->b_count == pc->sg->length) { - if (pc->sg == pc->last_sg) + if (!--pc->sg_cnt) break; pc->sg = sg_next(pc->sg); pc->b_count = 0; @@ -229,7 +229,7 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign } bcount -= count; pc->b_count += count; if (pc->b_count == pc->sg->length) { - if (pc->sg == pc->last_sg) + if (!--pc->sg_cnt) break; pc->sg = sg_next(pc->sg); pc->b_count = 0; @@ -807,7 +807,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd, memcpy (pc->c, cmd->cmnd, cmd->cmd_len); pc->buffer = NULL; pc->sg = scsi_sglist(cmd); - pc->last_sg = sg_last(pc->sg, scsi_sg_count(cmd)); + pc->sg_cnt = scsi_sg_count(cmd); pc->b_count = 0; pc->request_transfer = pc->buffer_size = scsi_bufflen(cmd); pc->scsi_cmd = cmd; -- cgit v1.2.3 From f5c0dde4c66421a3a2d7d6fa604a712c9b0744e5 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 17 Oct 2007 13:42:11 +0200 Subject: [SCSI] Remove full sg table memset() We don't need to do that anymore, since blk_rq_map_sg() clears individual entries. Signed-off-by: Jens Axboe --- drivers/scsi/scsi_lib.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index aac8a02cbe8..0c86be71bb3 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -764,8 +764,6 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) if (unlikely(!sgl)) goto enomem; - memset(sgl, 0, sizeof(*sgl) * sgp->size); - /* * first loop through, set initial index and return value */ -- cgit v1.2.3