Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2eba0d4c authored by Jing Huang's avatar Jing Huang Committed by James Bottomley
Browse files

[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: default avatarJing Huang <huangj@brocade.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent b504293f
Loading
Loading
Loading
Loading
+0 −29
Original line number Diff line number Diff line
@@ -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.
 */
+17 −5
Original line number Diff line number Diff line
@@ -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;

			/**