On 6/13/2019 3:48 PM, Christophe Leroy wrote: > @@ -336,15 +336,18 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch) > tail = priv->chan[ch].tail; > while (priv->chan[ch].fifo[tail].desc) { > __be32 hdr; > + struct talitos_edesc *edesc; > > request = &priv->chan[ch].fifo[tail]; > + edesc = container_of(request->desc, struct talitos_edesc, desc); Not needed for all cases, should be moved to the block that uses it. > > /* descriptors with their done bits set don't get the error */ > rmb(); > if (!is_sec1) > hdr = request->desc->hdr; > else if (request->desc->next_desc) > - hdr = (request->desc + 1)->hdr1; > + hdr = ((struct talitos_desc *) > + (edesc->buf + edesc->dma_len))->hdr1; > else > hdr = request->desc->hdr1; > [snip] > @@ -2058,7 +2065,18 @@ static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes) > sg_copy_to_buffer(areq->src, nents, > ctx_buf + req_ctx->nbuf, offset); > req_ctx->nbuf += offset; > - req_ctx->psrc = areq->src; > + for (sg = areq->src; sg && offset >= sg->length; > + offset -= sg->length, sg = sg_next(sg)) > + ; > + if (offset) { > + sg_init_table(req_ctx->bufsl, 2); > + sg_set_buf(req_ctx->bufsl, sg_virt(sg) + offset, > + sg->length - offset); > + sg_chain(req_ctx->bufsl, 2, sg_next(sg)); > + req_ctx->psrc = req_ctx->bufsl; Isn't this what scatterwalk_ffwd() does? Horia