From: "Adam Kropelin" <[EMAIL PROTECTED]>
Date: Sun, 15 Apr 2007 12:03:26 -0400

> ESP: data done csr[a6400310] flgs[1] sent[73728]
> ESP: start data addr[c004c000] len[0] write(1)
> esp: esp0: DMA error, csr=a440031e

I know what this bug is, it should be fixed by the following patch,
please give it a try.

I'll also add an assertion on zero transfer length when we start a
data transfer, that should never happen and is specifically what led
to the DMA error in this case.

commit 539d62c1f2b2b9ad2ace13ce2c7fc0aa47db87c3
Author: David S. Miller <[EMAIL PROTECTED]>
Date:   Sat Apr 14 20:03:25 2007 -0700

    [SCSI] SUNESP: Fix partial transfer length calculations.
    
    If we limited the DMA transfer length due to chip limitations
    we might calculate a partial transfer length incorrectly in
    esp_data_bytes_sent().
    
    Fix this by remembering the DMA length we actually used for the
    data phase transfer in esp->data_dma_len.
    
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>

diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c
index dc25b1e..7882fc7 100644
--- a/drivers/scsi/esp.c
+++ b/drivers/scsi/esp.c
@@ -1567,7 +1567,7 @@ static int esp_data_bytes_sent(struct esp *esp, struct 
esp_cmd_entry *ent,
                        ecount |= ((unsigned int)esp_read8(FAS_RLO)) << 16;
        }
 
-       bytes_sent = esp_cur_dma_len(cmd);
+       bytes_sent = esp->data_dma_len;
        bytes_sent -= ecount;
 
        if (!(ent->flags & ESP_CMD_FLAG_WRITE))
@@ -1956,6 +1956,7 @@ again:
                        ent->flags &= ~ESP_CMD_FLAG_WRITE;
 
                dma_len = esp_dma_length_limit(esp, dma_addr, dma_len);
+               esp->data_dma_len = dma_len;
 
                esp_log_datastart("ESP: start data addr[%08x] len[%u] "
                                  "write(%d)\n",
diff --git a/drivers/scsi/esp.h b/drivers/scsi/esp.h
index 2b3d969..bd3237d 100644
--- a/drivers/scsi/esp.h
+++ b/drivers/scsi/esp.h
@@ -364,6 +364,8 @@ struct esp {
        u8                      *command_block;
        dma_addr_t              command_block_dma;
 
+       unsigned int            data_dma_len;
+
        /* The following are used to determine the cause of an IRQ. Upon every
         * IRQ entry we synchronize these with the hardware registers.
         */
-
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to