On Tue, Jun 4, 2019 at 5:22 PM Finn Thain <fth...@telegraphics.com.au> wrote:
>
> On Tue, 4 Jun 2019, Ming Lei wrote:
>
> > The driver supporses that there isn't sg chain, and itereate the
> > list one by one. This way is obviously wrong.
> >
> > Fixes it by sgl helper.
> >
> > Cc: Christoph Hellwig <h...@lst.de>
> > Cc: Bart Van Assche <bvanass...@acm.org>
> > Cc: Ewan D. Milne <emi...@redhat.com>
> > Cc: Hannes Reinecke <h...@suse.com>
> > Cc: Guenter Roeck <li...@roeck-us.net>
> > Reported-by: Guenter Roeck <li...@roeck-us.net>
> > Signed-off-by: Ming Lei <ming....@redhat.com>
> > ---
> >  drivers/scsi/esp_scsi.c | 32 +++++++++++++++++++++++++-------
> >  1 file changed, 25 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
> > index 76e7ca864d6a..58b4e059dcfb 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 *sgt;
> >
> >       if (cmd->sc_data_direction == DMA_NONE)
> >               return;
> > @@ -381,14 +382,15 @@ 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, sgt, spriv->num_sg, i) {
> > +                     sgt->dma_address = (uintptr_t)sg_virt(sgt);
> > +                     total += sg_dma_len(sgt);
> >               }
> >       } 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, sgt, spriv->num_sg, i)
> > +                     total += sg_dma_len(sgt);
> >       }
> >       spriv->cur_residue = sg_dma_len(sg);
> >       spriv->cur_sg = sg;
> > @@ -444,7 +446,7 @@ 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->cur_sg = sg_next(p->cur_sg);
> >               p->cur_residue = sg_dma_len(p->cur_sg);
> >       }
> >  }
> > @@ -1610,6 +1612,22 @@ static void esp_msgin_extended(struct esp *esp)
> >       scsi_esp_cmd(esp, ESP_CMD_SATN);
> >  }
> >
> > +static struct scatterlist *esp_sg_prev(struct scsi_cmnd *cmd,
> > +             struct scatterlist *sg)
> > +{
> > +     int i;
> > +     struct scatterlist *tmp;
> > +     struct scatterlist *prev = NULL;
> > +
> > +     scsi_for_each_sg(cmd, tmp, scsi_sg_count(cmd), i) {
> > +             if (tmp == sg)
> > +                     break;
> > +             prev = tmp;
> > +     }
> > +
> > +     return prev;
> > +}
> > +
>
> Did you consider recording the previous scatterlist pointer using an
> additional member in struct esp_cmd_priv, to be assigned in
> esp_advance_dma()? I think it would execute faster and require less code.

Good point, will do it in V2.

Thanks,
Ming Lei

Reply via email to