Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=51b1c7e19e18e84a44277951dd5c4c4617330baa
Commit:     51b1c7e19e18e84a44277951dd5c4c4617330baa
Parent:     0feeed823af05ca556087a89fdcf644f156f73b8
Author:     Brian King <[EMAIL PROTECTED]>
AuthorDate: Thu Mar 29 12:43:50 2007 -0500
Committer:  James Bottomley <[EMAIL PROTECTED]>
CommitDate: Sun Apr 1 11:19:12 2007 -0500

    [SCSI] ipr: Faster sg list fetch
    
    Improve overall command performance by embedding the scatterlist
    in the command block used by the adapter. This decreases
    the overall number of DMAs required for a single command.
    
    Signed-off-by: Brian King <[EMAIL PROTECTED]>
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
---
 drivers/scsi/ipr.c |   28 +++++++++++++++++++++++-----
 drivers/scsi/ipr.h |   31 ++++++++++++++++---------------
 2 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index aa1fb72..5cf1002 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -480,12 +480,16 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
 {
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
        struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
+       dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr);
 
        memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
        ioarcb->write_data_transfer_length = 0;
        ioarcb->read_data_transfer_length = 0;
        ioarcb->write_ioadl_len = 0;
        ioarcb->read_ioadl_len = 0;
+       ioarcb->write_ioadl_addr =
+               cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl));
+       ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
        ioasa->ioasc = 0;
        ioasa->residual_data_len = 0;
        ioasa->u.gata.status = 0;
@@ -4230,6 +4234,14 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
 
                sglist = scsi_cmd->request_buffer;
 
+               if (ipr_cmd->dma_use_sg <= 
ARRAY_SIZE(ioarcb->add_data.u.ioadl)) {
+                       ioadl = ioarcb->add_data.u.ioadl;
+                       ioarcb->write_ioadl_addr =
+                               
cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) +
+                                           offsetof(struct ipr_ioarcb, 
add_data));
+                       ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
+               }
+
                for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
                        ioadl[i].flags_and_data_len =
                                cpu_to_be32(ioadl_flags | 
sg_dma_len(&sglist[i]));
@@ -4260,6 +4272,11 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
                                                     
scsi_cmd->sc_data_direction);
 
                if (likely(!pci_dma_mapping_error(ipr_cmd->dma_handle))) {
+                       ioadl = ioarcb->add_data.u.ioadl;
+                       ioarcb->write_ioadl_addr =
+                               
cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) +
+                                           offsetof(struct ipr_ioarcb, 
add_data));
+                       ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
                        ipr_cmd->dma_use_sg = 1;
                        ioadl[0].flags_and_data_len =
                                cpu_to_be32(ioadl_flags | length | 
IPR_IOADL_FLAGS_LAST);
@@ -4346,11 +4363,9 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd)
  **/
 static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd)
 {
-       struct ipr_ioarcb *ioarcb;
-       struct ipr_ioasa *ioasa;
-
-       ioarcb = &ipr_cmd->ioarcb;
-       ioasa = &ipr_cmd->ioasa;
+       struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+       struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
+       dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr);
 
        memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
        ioarcb->write_data_transfer_length = 0;
@@ -4359,6 +4374,9 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd 
*ipr_cmd)
        ioarcb->read_ioadl_len = 0;
        ioasa->ioasc = 0;
        ioasa->residual_data_len = 0;
+       ioarcb->write_ioadl_addr =
+               cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl));
+       ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
 }
 
 /**
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 4d06888..50e14f5 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -422,9 +422,25 @@ struct ipr_ioarcb_ata_regs {
        u8 ctl;
 }__attribute__ ((packed, aligned(4)));
 
+struct ipr_ioadl_desc {
+       __be32 flags_and_data_len;
+#define IPR_IOADL_FLAGS_MASK           0xff000000
+#define IPR_IOADL_GET_FLAGS(x) (be32_to_cpu(x) & IPR_IOADL_FLAGS_MASK)
+#define IPR_IOADL_DATA_LEN_MASK                0x00ffffff
+#define IPR_IOADL_GET_DATA_LEN(x) (be32_to_cpu(x) & IPR_IOADL_DATA_LEN_MASK)
+#define IPR_IOADL_FLAGS_READ           0x48000000
+#define IPR_IOADL_FLAGS_READ_LAST      0x49000000
+#define IPR_IOADL_FLAGS_WRITE          0x68000000
+#define IPR_IOADL_FLAGS_WRITE_LAST     0x69000000
+#define IPR_IOADL_FLAGS_LAST           0x01000000
+
+       __be32 address;
+}__attribute__((packed, aligned (8)));
+
 struct ipr_ioarcb_add_data {
        union {
                struct ipr_ioarcb_ata_regs regs;
+               struct ipr_ioadl_desc ioadl[5];
                __be32 add_cmd_parms[10];
        }u;
 }__attribute__ ((packed, aligned(4)));
@@ -456,21 +472,6 @@ struct ipr_ioarcb {
        struct ipr_ioarcb_add_data add_data;
 }__attribute__((packed, aligned (4)));
 
-struct ipr_ioadl_desc {
-       __be32 flags_and_data_len;
-#define IPR_IOADL_FLAGS_MASK           0xff000000
-#define IPR_IOADL_GET_FLAGS(x) (be32_to_cpu(x) & IPR_IOADL_FLAGS_MASK)
-#define IPR_IOADL_DATA_LEN_MASK                0x00ffffff
-#define IPR_IOADL_GET_DATA_LEN(x) (be32_to_cpu(x) & IPR_IOADL_DATA_LEN_MASK)
-#define IPR_IOADL_FLAGS_READ           0x48000000
-#define IPR_IOADL_FLAGS_READ_LAST      0x49000000
-#define IPR_IOADL_FLAGS_WRITE          0x68000000
-#define IPR_IOADL_FLAGS_WRITE_LAST     0x69000000
-#define IPR_IOADL_FLAGS_LAST           0x01000000
-
-       __be32 address;
-}__attribute__((packed, aligned (8)));
-
 struct ipr_ioasa_vset {
        __be32 failing_lba_hi;
        __be32 failing_lba_lo;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to