Jelajahi Sumber

[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>
Jing Huang 15 tahun lalu
induk
melakukan
2eba0d4c00
2 mengubah file dengan 17 tambahan dan 34 penghapusan
  1. 0 29
      drivers/scsi/bfa/bfa_cb_ioim_macros.h
  2. 17 5
      drivers/scsi/bfa/bfa_ioim.c

+ 0 - 29
drivers/scsi/bfa/bfa_cb_ioim_macros.h

@@ -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
drivers/scsi/bfa/bfa_ioim.c

@@ -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;
 
 			/**