Skip to content

Commit

Permalink
[SCSI] ipr: Faster sg list fetch
Browse files Browse the repository at this point in the history
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 <brking@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
  • Loading branch information
Brian King authored and James Bottomley committed Apr 1, 2007
1 parent 0feeed8 commit 51b1c7e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 20 deletions.
28 changes: 23 additions & 5 deletions drivers/scsi/ipr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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]));
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}

/**
Expand Down
31 changes: 16 additions & 15 deletions drivers/scsi/ipr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 51b1c7e

Please sign in to comment.