mirror of
https://github.com/torvalds/linux.git
synced 2024-11-02 02:01:29 +00:00
[SCSI] bfa: fix the issue of not handling scsi_cmnd sg chaining case
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>
This commit is contained in:
parent
b504293fe9
commit
2eba0d4c00
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
@ -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;
|
||||
@ -868,10 +873,16 @@ 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;
|
||||
@ -879,9 +890,10 @@ bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
|
||||
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;
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user