Skip to content

Commit

Permalink
[SCSI] bfa: fix the issue of not handling scsi_cmnd sg chaining case
Browse files Browse the repository at this point in the history
Currently the driver doesn't take into consideraion of possible sg chaining
when it walks through the sg list. This is fixed by using the sg_next()
which automatically handles the chaining case. Obosolete code is removed
as a result of this change.

Signed-off-by: Jing Huang <huangj@brocade.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
Jing Huang authored and James Bottomley committed Apr 11, 2010
1 parent b504293 commit 2eba0d4
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 34 deletions.
29 changes: 0 additions & 29 deletions drivers/scsi/bfa/bfa_cb_ioim_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,35 +116,6 @@ bfa_cb_ioim_get_timeout(struct bfad_ioim_s *dio)
return 0;
}

/**
* Get SG element for the I/O request given the SG element index
*/
static inline union bfi_addr_u
bfa_cb_ioim_get_sgaddr(struct bfad_ioim_s *dio, int sgeid)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
struct scatterlist *sge;
u64 addr;

sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
addr = (u64) sg_dma_address(sge);

return *((union bfi_addr_u *) &addr);
}

static inline u32
bfa_cb_ioim_get_sglen(struct bfad_ioim_s *dio, int sgeid)
{
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
struct scatterlist *sge;
u32 len;

sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
len = sg_dma_len(sge);

return len;
}

/**
* Get Command Reference Number for the I/O request. 0 if none.
*/
Expand Down
22 changes: 17 additions & 5 deletions drivers/scsi/bfa/bfa_ioim.c
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,9 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
static struct fcp_cmnd_s cmnd_z0 = { 0 };
struct bfi_sge_s *sge;
u32 pgdlen = 0;
u64 addr;
struct scatterlist *sg;
struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;

/**
* check for room in queue to send request now
Expand All @@ -754,8 +757,10 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
*/
sge = &m->sges[0];
if (ioim->nsges) {
sge->sga = bfa_cb_ioim_get_sgaddr(ioim->dio, 0);
pgdlen = bfa_cb_ioim_get_sglen(ioim->dio, 0);
sg = (struct scatterlist *)scsi_sglist(cmnd);
addr = (u64) sg_dma_address(sg);
sge->sga = *(union bfi_addr_u *) &addr;
pgdlen = sg_dma_len(sg);
sge->sg_len = pgdlen;
sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST;
Expand Down Expand Up @@ -868,20 +873,27 @@ bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
struct bfi_sge_s *sge;
struct bfa_sgpg_s *sgpg;
u32 pgcumsz;
u64 addr;
struct scatterlist *sg;
struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;

sgeid = BFI_SGE_INLINE;
ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q);

sg = scsi_sglist(cmnd);
sg = sg_next(sg);

do {
sge = sgpg->sgpg->sges;
nsges = ioim->nsges - sgeid;
if (nsges > BFI_SGPG_DATA_SGES)
nsges = BFI_SGPG_DATA_SGES;

pgcumsz = 0;
for (i = 0; i < nsges; i++, sge++, sgeid++) {
sge->sga = bfa_cb_ioim_get_sgaddr(ioim->dio, sgeid);
sge->sg_len = bfa_cb_ioim_get_sglen(ioim->dio, sgeid);
for (i = 0; i < nsges; i++, sge++, sgeid++, sg = sg_next(sg)) {
addr = (u64) sg_dma_address(sg);
sge->sga = *(union bfi_addr_u *) &addr;
sge->sg_len = sg_dma_len(sg);
pgcumsz += sge->sg_len;

/**
Expand Down

0 comments on commit 2eba0d4

Please sign in to comment.