Le 14/06/2019 à 13:32, Horia Geanta a écrit :
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.

Ok.


/* 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?

Thanks for pointing this, I wasn't aware of that function. Looking at it it seems to do the same. Unfortunately, some tests fails with 'wrong result' when using it instead.

Comparing the results of scatterwalk_ffwd() with what I get with my open codying, I see the following difference:

scatterwalk_ffwd() uses sg_page(sg) + sg->offset + len

while my open codying results in virt_to_page(sg_virt(sg) + len)

When sg->offset + len is greater than PAGE_SIZE, the resulting SG entry is different allthough valid in both cases. I think this difference results in sg_copy_to_buffer() failing. I'm still investigating. Any idea ?

Christophe


Horia

Reply via email to