[PATCH] ieee1394: sbp2: stricter dma_sync | |
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] | |
On 5 Aug, Boaz Harrosh wrote:
> Stefan Richter wrote:
>> Boaz Harrosh wrote:
>>> From re-inspecting the code I can see that the struct sbp2_command_orb
>>> might have problems with none DMA coherent ARCHs.
>>
>> Hmm. This would be a bug. But from what I see while scrolling through
>> fw-sbp2 and through sbp2, they both do it right. Well, to be very
>> strict, sbp2 should dma_sync_single_for_cpu() at a slightly different
>> place than it does now. I shall patch this.
>>
>
> Yes I agree with you. Keep me posted I'll review the code
Two dma_sync_single_for_cpu() were called in the wrong place.
Luckily they were merely for DMA_TO_DEVICE, hence nobody noticed.
Also reorder the matching dma_sync_single_for_device() a little bit
so that they reside in the same functions as their counterparts.
This also avoids syncing the s/g table for requests which don't use it.
Signed-off-by: Stefan Richter <stefanr@xxxxxxxxxxxxxxxxx>
---
drivers/ieee1394/sbp2.c | 33 ++++++++++++++++-----------------
1 file changed, 16 insertions(+), 17 deletions(-)
On a related note, sbp2 lacks error checks for the DMA mapping when the
ORB pool is created and when the request buffer is mapped. I leave that
as a ToDo for sometime later.
Index: linux-2.6.27-rc2/drivers/ieee1394/sbp2.c
===================================================================
--- linux-2.6.27-rc2.orig/drivers/ieee1394/sbp2.c
+++ linux-2.6.27-rc2/drivers/ieee1394/sbp2.c
@@ -1522,6 +1522,10 @@ static void sbp2_prep_command_orb_sg(str
orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
orb->data_descriptor_lo = cmd->sge_dma;
+ dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
+ sizeof(cmd->scatter_gather_element),
+ DMA_TO_DEVICE);
+
/* loop through and fill out our SBP-2 page tables
* (and split up anything too large) */
for (i = 0, sg_count = 0; i < count; i++, sg = sg_next(sg)) {
@@ -1548,6 +1552,11 @@ static void sbp2_prep_command_orb_sg(str
sbp2util_cpu_to_be32_buffer(sg_element,
(sizeof(struct sbp2_unrestricted_page_table)) *
sg_count);
+
+ dma_sync_single_for_device(hi->host->device.parent,
+ cmd->sge_dma,
+ sizeof(cmd->scatter_gather_element),
+ DMA_TO_DEVICE);
}
}
@@ -1555,12 +1564,14 @@ static void sbp2_create_command_orb(stru
struct sbp2_command_info *cmd,
struct scsi_cmnd *SCpnt)
{
- struct sbp2_fwhost_info *hi = lu->hi;
+ struct device *dev = lu->hi->host->device.parent;
struct sbp2_command_orb *orb = &cmd->command_orb;
u32 orb_direction;
unsigned int scsi_request_bufflen = scsi_bufflen(SCpnt);
enum dma_data_direction dma_dir = SCpnt->sc_data_direction;
+ dma_sync_single_for_cpu(dev, cmd->command_orb_dma,
+ sizeof(struct sbp2_command_orb), DMA_TO_DEVICE);
/*
* Set-up our command ORB.
*
@@ -1592,7 +1603,7 @@ static void sbp2_create_command_orb(stru
orb->data_descriptor_lo = 0x0;
orb->misc |= ORB_SET_DIRECTION(1);
} else
- sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_sg_count(SCpnt),
+ sbp2_prep_command_orb_sg(orb, lu->hi, cmd, scsi_sg_count(SCpnt),
scsi_sglist(SCpnt),
orb_direction, dma_dir);
@@ -1600,6 +1611,9 @@ static void sbp2_create_command_orb(stru
memset(orb->cdb, 0, sizeof(orb->cdb));
memcpy(orb->cdb, SCpnt->cmnd, SCpnt->cmd_len);
+
+ dma_sync_single_for_device(dev, cmd->command_orb_dma,
+ sizeof(struct sbp2_command_orb), DMA_TO_DEVICE);
}
static void sbp2_link_orb_command(struct sbp2_lu *lu,
@@ -1613,14 +1627,6 @@ static void sbp2_link_orb_command(struct
size_t length;
unsigned long flags;
- dma_sync_single_for_device(hi->host->device.parent,
- cmd->command_orb_dma,
- sizeof(struct sbp2_command_orb),
- DMA_TO_DEVICE);
- dma_sync_single_for_device(hi->host->device.parent, cmd->sge_dma,
- sizeof(cmd->scatter_gather_element),
- DMA_TO_DEVICE);
-
/* check to see if there are any previous orbs to use */
spin_lock_irqsave(&lu->cmd_orb_lock, flags);
last_orb = lu->last_orb;
@@ -1778,13 +1784,6 @@ static int sbp2_handle_status_write(stru
else
cmd = sbp2util_find_command_for_orb(lu, sb->ORB_offset_lo);
if (cmd) {
- dma_sync_single_for_cpu(hi->host->device.parent,
- cmd->command_orb_dma,
- sizeof(struct sbp2_command_orb),
- DMA_TO_DEVICE);
- dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
- sizeof(cmd->scatter_gather_element),
- DMA_TO_DEVICE);
/* Grab SCSI command pointers and check status. */
/*
* FIXME: If the src field in the status is 1, the ORB DMA must
--
Stefan Richter
-=====-==--- =--- -=---
http://arcgraph.de/sr/
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Site Home] [Kernel Newbies] [Share Photos] [IDE] [Security] [Git] [Netfilter] [Bugtraq] [Rubini] [Photo] [Yosemite] [Yosemite News] [MIPS Linux] [ARM Linux] [Linux Security] [Linux RAID] [Linux ATA RAID] [Samba] [Video 4 Linux] [Device Mapper] [Linux Resources]
![]() |
![]() |