On 22-07-18, 23:20, Andreas Färber wrote:
> From: Damien Horsley <damien.hors...@imgtec.com>
> 
> It is possible that mdc_tx_status may be called before the first
> node has been read from memory.
> 
> In this case, the residue value stored in the register is undefined.
> Return the transfer size instead.
> 
> Signed-off-by: Damien Horsley <damien.hors...@imgtec.com>
> Signed-off-by: Andreas Färber <afaer...@suse.de>
> ---
>  drivers/dma/img-mdc-dma.c | 40 ++++++++++++++++++++++++----------------
>  1 file changed, 24 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c
> index 25cec9c243e1..0f2f0f52d83a 100644
> --- a/drivers/dma/img-mdc-dma.c
> +++ b/drivers/dma/img-mdc-dma.c
> @@ -621,25 +621,33 @@ static enum dma_status mdc_tx_status(struct dma_chan 
> *chan,
>                       (MDC_CMDS_PROCESSED_CMDS_DONE_MASK + 1);
>  
>               /*
> -              * If the command loaded event hasn't been processed yet, then
> -              * the difference above includes an extra command.
> +              * If the first node has not yet been read from memory,
> +              * the residue register value is undefined

so is this the case when transfer is not started ?

>                */
> -             if (!mdesc->cmd_loaded)
> -                     cmds--;
> -             else
> -                     cmds += mdesc->list_cmds_done;
> -
> -             bytes = mdesc->list_xfer_size;
> -             ldesc = mdesc->list;
> -             for (i = 0; i < cmds; i++) {
> -                     bytes -= ldesc->xfer_size + 1;
> -                     ldesc = ldesc->next_desc;
> -             }
> -             if (ldesc) {
> -                     if (residue != MDC_TRANSFER_SIZE_MASK)
> -                             bytes -= ldesc->xfer_size - residue;
> +             if (!mdesc->cmd_loaded && !cmds) {
> +                     bytes = mdesc->list_xfer_size;
> +             } else {
> +                     /*
> +                      * If the command loaded event hasn't been processed 
> yet, then
> +                      * the difference above includes an extra command.
> +                      */
> +                     if (!mdesc->cmd_loaded)
> +                             cmds--;
>                       else
> +                             cmds += mdesc->list_cmds_done;
> +
> +                     bytes = mdesc->list_xfer_size;
> +                     ldesc = mdesc->list;
> +                     for (i = 0; i < cmds; i++) {
>                               bytes -= ldesc->xfer_size + 1;
> +                             ldesc = ldesc->next_desc;
> +                     }
> +                     if (ldesc) {
> +                             if (residue != MDC_TRANSFER_SIZE_MASK)
> +                                     bytes -= ldesc->xfer_size - residue;
> +                             else
> +                                     bytes -= ldesc->xfer_size + 1;
> +                     }
>               }
>       }
>       spin_unlock_irqrestore(&mchan->vc.lock, flags);
> -- 
> 2.16.4

-- 
~Vinod

Reply via email to