Re: [PATCH V2 3/3] scsi: esp: make it working on SG_CHAIN

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 5 Jun 2019, Ming Lei wrote:

> The driver expects that SCSI SGL is a simply array of SG, and itereate
> the SGL via integer index. This way is obviously wrong, because of
> SG_CHAIN.
> 
> Fixes it by using sgl helper.
> 
> V2:
> 	- as suggested by Finn Thain, introduce .prv_sg for getting previous
> 	scatterlist pointer
> 

Thanks. I'd forgotten about the consequences for SAVE/RESTORE POINTERS 
until I saw your patch.

I can't test the change to the IGNORE WIDE RESIDUE message handling but I 
did confirm that the patch series works in QEMU/m68k.

Reviewed-by: Finn Thain <fthain@xxxxxxxxxxxxxxxxxxx>

-- 

> Cc: Christoph Hellwig <hch@xxxxxx>
> Cc: Bart Van Assche <bvanassche@xxxxxxx>
> Cc: Ewan D. Milne <emilne@xxxxxxxxxx>
> Cc: Hannes Reinecke <hare@xxxxxxxx>
> Cc: Finn Thain <fthain@xxxxxxxxxxxxxxxxxxx>
> Cc: Guenter Roeck <linux@xxxxxxxxxxxx>
> Reported-by: Guenter Roeck <linux@xxxxxxxxxxxx>
> Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx>
> ---
>  drivers/scsi/esp_scsi.c | 20 +++++++++++++-------
>  drivers/scsi/esp_scsi.h |  2 ++
>  2 files changed, 15 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
> index 76e7ca864d6a..bb88995a12c7 100644
> --- a/drivers/scsi/esp_scsi.c
> +++ b/drivers/scsi/esp_scsi.c
> @@ -371,6 +371,7 @@ static void esp_map_dma(struct esp *esp, struct scsi_cmnd *cmd)
>  	struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd);
>  	struct scatterlist *sg = scsi_sglist(cmd);
>  	int total = 0, i;
> +	struct scatterlist *s;
>  
>  	if (cmd->sc_data_direction == DMA_NONE)
>  		return;
> @@ -381,16 +382,18 @@ static void esp_map_dma(struct esp *esp, struct scsi_cmnd *cmd)
>  		 * a dma address, so perform an identity mapping.
>  		 */
>  		spriv->num_sg = scsi_sg_count(cmd);
> -		for (i = 0; i < spriv->num_sg; i++) {
> -			sg[i].dma_address = (uintptr_t)sg_virt(&sg[i]);
> -			total += sg_dma_len(&sg[i]);
> +
> +		scsi_for_each_sg(cmd, s, spriv->num_sg, i) {
> +			s->dma_address = (uintptr_t)sg_virt(s);
> +			total += sg_dma_len(s);
>  		}
>  	} else {
>  		spriv->num_sg = scsi_dma_map(cmd);
> -		for (i = 0; i < spriv->num_sg; i++)
> -			total += sg_dma_len(&sg[i]);
> +		scsi_for_each_sg(cmd, s, spriv->num_sg, i)
> +			total += sg_dma_len(s);
>  	}
>  	spriv->cur_residue = sg_dma_len(sg);
> +	spriv->prv_sg = NULL;
>  	spriv->cur_sg = sg;
>  	spriv->tot_residue = total;
>  }
> @@ -444,7 +447,8 @@ static void esp_advance_dma(struct esp *esp, struct esp_cmd_entry *ent,
>  		p->tot_residue = 0;
>  	}
>  	if (!p->cur_residue && p->tot_residue) {
> -		p->cur_sg++;
> +		p->prv_sg = p->cur_sg;
> +		p->cur_sg = sg_next(p->cur_sg);
>  		p->cur_residue = sg_dma_len(p->cur_sg);
>  	}
>  }
> @@ -465,6 +469,7 @@ static void esp_save_pointers(struct esp *esp, struct esp_cmd_entry *ent)
>  		return;
>  	}
>  	ent->saved_cur_residue = spriv->cur_residue;
> +	ent->saved_prv_sg = spriv->prv_sg;
>  	ent->saved_cur_sg = spriv->cur_sg;
>  	ent->saved_tot_residue = spriv->tot_residue;
>  }
> @@ -479,6 +484,7 @@ static void esp_restore_pointers(struct esp *esp, struct esp_cmd_entry *ent)
>  		return;
>  	}
>  	spriv->cur_residue = ent->saved_cur_residue;
> +	spriv->prv_sg = ent->saved_prv_sg;
>  	spriv->cur_sg = ent->saved_cur_sg;
>  	spriv->tot_residue = ent->saved_tot_residue;
>  }
> @@ -1647,7 +1653,7 @@ static int esp_msgin_process(struct esp *esp)
>  		spriv = ESP_CMD_PRIV(ent->cmd);
>  
>  		if (spriv->cur_residue == sg_dma_len(spriv->cur_sg)) {
> -			spriv->cur_sg--;
> +			spriv->cur_sg = spriv->prv_sg;
>  			spriv->cur_residue = 1;
>  		} else
>  			spriv->cur_residue++;
> diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h
> index aa87a6b72dcc..91b32f2a1a1b 100644
> --- a/drivers/scsi/esp_scsi.h
> +++ b/drivers/scsi/esp_scsi.h
> @@ -251,6 +251,7 @@
>  struct esp_cmd_priv {
>  	int			num_sg;
>  	int			cur_residue;
> +	struct scatterlist	*prv_sg;
>  	struct scatterlist	*cur_sg;
>  	int			tot_residue;
>  };
> @@ -273,6 +274,7 @@ struct esp_cmd_entry {
>  	struct scsi_cmnd	*cmd;
>  
>  	unsigned int		saved_cur_residue;
> +	struct scatterlist	*saved_prv_sg;
>  	struct scatterlist	*saved_cur_sg;
>  	unsigned int		saved_tot_residue;
>  
> 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux