On Thu, 11 Oct 2018, Christoph Hellwig wrote:

> index 90604bff8dd2..73fcbd65b9fe 100644
> --- a/drivers/scsi/esp_scsi.c
> +++ b/drivers/scsi/esp_scsi.c
> @@ -369,19 +369,25 @@ 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 dir = cmd->sc_data_direction;
> -     int total, i;
> +     int total = 0, i;
>  
> -     if (dir == DMA_NONE)
> -             return;
> -
> -     spriv->u.num_sg = esp->ops->map_sg(esp, sg, scsi_sg_count(cmd), dir);
> +     if (esp->flags & ESP_FLAG_NO_DMA_MAP) {
> +             /*
> +              * For pseudo DMA and PIO we need the virtual address instead of
> +              * a dma address, so perform an identity mapping.
> +              */
> +             spriv->u.num_sg = scsi_sg_count(cmd);
> +             for (i = 0; i < spriv->u.num_sg; i++) {
> +                     sg[i].dma_address = (uintptr_t)sg_virt(&sg[i]);
> +                     total += sg_dma_len(&sg[i]);
> +             }
> +     } else {
> +             spriv->u.num_sg = scsi_dma_map(cmd);
> +             for (i = 0; i < spriv->u.num_sg; i++)
> +                     total += sg_dma_len(&sg[i]);
> +     }
>       spriv->cur_residue = sg_dma_len(sg);
>       spriv->cur_sg = sg;
> -
> -     total = 0;
> -     for (i = 0; i < spriv->u.num_sg; i++)
> -             total += sg_dma_len(&sg[i]);
>       spriv->tot_residue = total;
>  }
>  
> @@ -441,13 +447,8 @@ static void esp_advance_dma(struct esp *esp, struct 
> esp_cmd_entry *ent,
>  
>  static void esp_unmap_dma(struct esp *esp, struct scsi_cmnd *cmd)
>  {
> -     struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd);
> -     int dir = cmd->sc_data_direction;
> -
> -     if (dir == DMA_NONE)
> -             return;
> -
> -     esp->ops->unmap_sg(esp, scsi_sglist(cmd), spriv->u.num_sg, dir);
> +     if (!(esp->flags & ESP_FLAG_NO_DMA_MAP))
> +             scsi_dma_unmap(cmd);
>  }
>  
>  static void esp_save_pointers(struct esp *esp, struct esp_cmd_entry *ent)
> @@ -624,6 +625,28 @@ static void esp_free_lun_tag(struct esp_cmd_entry *ent,
>       }
>  }
>  
> +static void esp_map_sense(struct esp *esp, struct esp_cmd_entry *ent)
> +{
> +     ent->sense_ptr = ent->cmd->sense_buffer;
> +     if (esp->flags & ESP_FLAG_NO_DMA_MAP) {
> +             ent->sense_dma = (uintptr_t)ent->sense_ptr;
> +             return;
> +     }
> +
> +     ent->sense_dma = dma_map_single(esp->dev, ent->sense_ptr,
> +                                     SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
> +}
> +
> +static void esp_unmap_sense(struct esp *esp, struct esp_cmd_entry *ent)
> +{
> +     if (esp->flags & ESP_FLAG_NO_DMA_MAP)
> +             return;
> +
> +     dma_unmap_single(esp->dev, ent->sense_dma, SCSI_SENSE_BUFFERSIZE,
> +                      DMA_FROM_DEVICE);
> +     ent->sense_ptr = NULL;
> +}
> +

I think it is better to clear ent->sense_ptr unconditionally, as before.

-- 

>  /* When a contingent allegiance conditon is created, we force feed a
>   * REQUEST_SENSE command to the device to fetch the sense data.  I
>   * tried many other schemes, relying on the scsi error handling layer
> @@ -645,12 +668,7 @@ static void esp_autosense(struct esp *esp, struct 
> esp_cmd_entry *ent)
>       if (!ent->sense_ptr) {
>               esp_log_autosense("Doing auto-sense for tgt[%d] lun[%d]\n",
>                                 tgt, lun);
> -
> -             ent->sense_ptr = cmd->sense_buffer;
> -             ent->sense_dma = esp->ops->map_single(esp,
> -                                                   ent->sense_ptr,
> -                                                   SCSI_SENSE_BUFFERSIZE,
> -                                                   DMA_FROM_DEVICE);
> +             esp_map_sense(esp, ent);
>       }
>       ent->saved_sense_ptr = ent->sense_ptr;
>  
> @@ -902,9 +920,7 @@ static void esp_cmd_is_done(struct esp *esp, struct 
> esp_cmd_entry *ent,
>       }
>  
>       if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
> -             esp->ops->unmap_single(esp, ent->sense_dma,
> -                                    SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
> -             ent->sense_ptr = NULL;
> +             esp_unmap_sense(esp, ent);
>  
>               /* Restore the message/status bytes to what we actually
>                * saw originally.  Also, report that we are providing
> @@ -1256,10 +1272,7 @@ static int esp_finish_select(struct esp *esp)
>                       esp->cmd_bytes_ptr = NULL;
>                       esp->cmd_bytes_left = 0;
>               } else {
> -                     esp->ops->unmap_single(esp, ent->sense_dma,
> -                                            SCSI_SENSE_BUFFERSIZE,
> -                                            DMA_FROM_DEVICE);
> -                     ent->sense_ptr = NULL;
> +                     esp_unmap_sense(esp, ent);
>               }
>  
>               /* Now that the state is unwound properly, put back onto
> @@ -2039,11 +2052,8 @@ static void esp_reset_cleanup_one(struct esp *esp, 
> struct esp_cmd_entry *ent)
>       esp_free_lun_tag(ent, cmd->device->hostdata);
>       cmd->result = DID_RESET << 16;
>  
> -     if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) {
> -             esp->ops->unmap_single(esp, ent->sense_dma,
> -                                    SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
> -             ent->sense_ptr = NULL;
> -     }
> +     if (ent->flags & ESP_CMD_FLAG_AUTOSENSE)
> +             esp_unmap_sense(esp, ent);
>  
>       cmd->scsi_done(cmd);
>       list_del(&ent->list);

Reply via email to