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