mirror of https://gitee.com/openkylin/linux.git
[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;
|
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.
|
* 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 };
|
static struct fcp_cmnd_s cmnd_z0 = { 0 };
|
||||||
struct bfi_sge_s *sge;
|
struct bfi_sge_s *sge;
|
||||||
u32 pgdlen = 0;
|
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
|
* 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];
|
sge = &m->sges[0];
|
||||||
if (ioim->nsges) {
|
if (ioim->nsges) {
|
||||||
sge->sga = bfa_cb_ioim_get_sgaddr(ioim->dio, 0);
|
sg = (struct scatterlist *)scsi_sglist(cmnd);
|
||||||
pgdlen = bfa_cb_ioim_get_sglen(ioim->dio, 0);
|
addr = (u64) sg_dma_address(sg);
|
||||||
|
sge->sga = *(union bfi_addr_u *) &addr;
|
||||||
|
pgdlen = sg_dma_len(sg);
|
||||||
sge->sg_len = pgdlen;
|
sge->sg_len = pgdlen;
|
||||||
sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
|
sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
|
||||||
BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST;
|
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 bfi_sge_s *sge;
|
||||||
struct bfa_sgpg_s *sgpg;
|
struct bfa_sgpg_s *sgpg;
|
||||||
u32 pgcumsz;
|
u32 pgcumsz;
|
||||||
|
u64 addr;
|
||||||
|
struct scatterlist *sg;
|
||||||
|
struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;
|
||||||
|
|
||||||
sgeid = BFI_SGE_INLINE;
|
sgeid = BFI_SGE_INLINE;
|
||||||
ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q);
|
ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q);
|
||||||
|
|
||||||
|
sg = scsi_sglist(cmnd);
|
||||||
|
sg = sg_next(sg);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
sge = sgpg->sgpg->sges;
|
sge = sgpg->sgpg->sges;
|
||||||
nsges = ioim->nsges - sgeid;
|
nsges = ioim->nsges - sgeid;
|
||||||
|
@ -879,9 +890,10 @@ bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
|
||||||
nsges = BFI_SGPG_DATA_SGES;
|
nsges = BFI_SGPG_DATA_SGES;
|
||||||
|
|
||||||
pgcumsz = 0;
|
pgcumsz = 0;
|
||||||
for (i = 0; i < nsges; i++, sge++, sgeid++) {
|
for (i = 0; i < nsges; i++, sge++, sgeid++, sg = sg_next(sg)) {
|
||||||
sge->sga = bfa_cb_ioim_get_sgaddr(ioim->dio, sgeid);
|
addr = (u64) sg_dma_address(sg);
|
||||||
sge->sg_len = bfa_cb_ioim_get_sglen(ioim->dio, sgeid);
|
sge->sga = *(union bfi_addr_u *) &addr;
|
||||||
|
sge->sg_len = sg_dma_len(sg);
|
||||||
pgcumsz += sge->sg_len;
|
pgcumsz += sge->sg_len;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue