@@ -273,7 +273,10 @@ static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
273273 void * context , int error ),
274274 void * context )
275275{
276+ struct talitos_edesc * edesc = container_of (desc , struct talitos_edesc , desc );
276277 struct talitos_private * priv = dev_get_drvdata (dev );
278+ dma_addr_t dma_desc , prev_dma_desc ;
279+ struct talitos_edesc * prev_edesc = NULL ;
277280 struct talitos_request * request ;
278281 unsigned long flags ;
279282 int head ;
@@ -292,10 +295,31 @@ static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
292295
293296 /* map descriptor and save caller data */
294297 if (is_sec1 ) {
295- desc -> hdr1 = desc -> hdr ;
296- request -> dma_desc = dma_map_single (dev , & desc -> hdr1 ,
298+ while (edesc ) {
299+ edesc -> desc .hdr1 = edesc -> desc .hdr ;
300+
301+ dma_desc = dma_map_single (dev , & edesc -> desc .hdr1 ,
302+ TALITOS_DESC_SIZE ,
303+ DMA_BIDIRECTIONAL );
304+
305+ if (!prev_edesc ) {
306+ request -> dma_desc = dma_desc ;
307+ goto next ;
308+ }
309+
310+ /* Chain in any previous descriptors. */
311+
312+ prev_edesc -> desc .next_desc = cpu_to_be32 (dma_desc );
313+
314+ dma_sync_single_for_device (dev , prev_dma_desc ,
297315 TALITOS_DESC_SIZE ,
298- DMA_BIDIRECTIONAL );
316+ DMA_TO_DEVICE );
317+
318+ next :
319+ prev_edesc = edesc ;
320+ prev_dma_desc = dma_desc ;
321+ edesc = edesc -> next_desc ;
322+ }
299323 } else {
300324 request -> dma_desc = dma_map_single (dev , desc ,
301325 TALITOS_DESC_SIZE ,
@@ -326,6 +350,7 @@ static __be32 get_request_hdr(struct device *dev,
326350 struct talitos_request * request , bool is_sec1 )
327351{
328352 struct talitos_edesc * edesc ;
353+ dma_addr_t dma_desc ;
329354
330355 if (!is_sec1 ) {
331356 dma_sync_single_for_cpu (dev , request -> dma_desc ,
@@ -334,19 +359,17 @@ static __be32 get_request_hdr(struct device *dev,
334359 return request -> desc -> hdr ;
335360 }
336361
337- if (!request -> desc -> next_desc ) {
338- dma_sync_single_for_cpu (dev , request -> dma_desc ,
339- TALITOS_DESC_SIZE , DMA_BIDIRECTIONAL );
340- return request -> desc -> hdr1 ;
341- } else {
342- dma_sync_single_for_cpu (dev ,
343- be32_to_cpu (request -> desc -> next_desc ),
344- TALITOS_DESC_SIZE , DMA_BIDIRECTIONAL );
345- edesc = container_of (request -> desc , struct talitos_edesc , desc );
346-
347- return ((struct talitos_desc * )(edesc -> buf + edesc -> dma_len ))
348- -> hdr1 ;
362+ edesc = container_of (request -> desc , struct talitos_edesc , desc );
363+ dma_desc = request -> dma_desc ;
364+ while (edesc -> next_desc ) {
365+ dma_desc = be32_to_cpu (edesc -> desc .next_desc );
366+ edesc = edesc -> next_desc ;
349367 }
368+
369+ dma_sync_single_for_cpu (dev , dma_desc , TALITOS_DESC_SIZE ,
370+ DMA_BIDIRECTIONAL );
371+
372+ return edesc -> desc .hdr1 ;
350373}
351374
352375/*
@@ -356,6 +379,7 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
356379{
357380 struct talitos_private * priv = dev_get_drvdata (dev );
358381 struct talitos_request * request , saved_req ;
382+ struct talitos_edesc * edesc ;
359383 unsigned long flags ;
360384 int tail , status ;
361385 bool is_sec1 = has_ftr_sec1 (priv );
@@ -380,9 +404,22 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
380404 else
381405 status = error ;
382406
383- dma_unmap_single (dev , request -> dma_desc ,
384- TALITOS_DESC_SIZE ,
385- DMA_BIDIRECTIONAL );
407+ if (is_sec1 ) {
408+ dma_unmap_single (dev , request -> dma_desc ,
409+ TALITOS_DESC_SIZE , DMA_BIDIRECTIONAL );
410+ edesc = container_of (request -> desc ,
411+ struct talitos_edesc , desc );
412+ while (edesc -> next_desc ) {
413+ dma_unmap_single (
414+ dev , be32_to_cpu (edesc -> desc .next_desc ),
415+ TALITOS_DESC_SIZE , DMA_BIDIRECTIONAL );
416+ edesc = edesc -> next_desc ;
417+ }
418+ } else {
419+ dma_unmap_single (dev , request -> dma_desc ,
420+ TALITOS_DESC_SIZE ,
421+ DMA_BIDIRECTIONAL );
422+ }
386423
387424 /* copy entries so we can call callback outside lock */
388425 saved_req .desc = request -> desc ;
@@ -477,8 +514,12 @@ DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
477514static __be32 current_desc_hdr (struct device * dev , int ch )
478515{
479516 struct talitos_private * priv = dev_get_drvdata (dev );
517+ bool is_sec1 = has_ftr_sec1 (priv );
518+ struct talitos_request * request ;
519+ struct talitos_edesc * edesc ;
480520 int tail , iter ;
481521 dma_addr_t cur_desc ;
522+ __be32 hdr = 0 ;
482523
483524 cur_desc = ((u64 )in_be32 (priv -> chan [ch ].reg + TALITOS_CDPR )) << 32 ;
484525 cur_desc |= in_be32 (priv -> chan [ch ].reg + TALITOS_CDPR_LO );
@@ -489,27 +530,35 @@ static __be32 current_desc_hdr(struct device *dev, int ch)
489530 }
490531
491532 tail = priv -> chan [ch ].tail ;
492-
493533 iter = tail ;
494- while (priv -> chan [ch ].fifo [iter ].dma_desc != cur_desc &&
495- priv -> chan [ch ].fifo [iter ].desc -> next_desc != cpu_to_be32 (cur_desc )) {
496- iter = (iter + 1 ) & (priv -> fifo_len - 1 );
497- if (iter == tail ) {
498- dev_err (dev , "couldn't locate current descriptor\n" );
499- return 0 ;
534+ do {
535+ request = & priv -> chan [ch ].fifo [iter ];
536+
537+ if (request -> dma_desc == cur_desc ) {
538+ hdr = request -> desc -> hdr ;
539+ } else if (is_sec1 ) {
540+ edesc = container_of (request -> desc ,
541+ struct talitos_edesc , desc );
542+ while (edesc -> next_desc ) {
543+ if (edesc -> desc .next_desc ==
544+ cpu_to_be32 (cur_desc )) {
545+ hdr = edesc -> next_desc -> desc .hdr1 ;
546+ break ;
547+ }
548+ edesc = edesc -> next_desc ;
549+ }
500550 }
501- }
502551
503- if (priv -> chan [ ch ]. fifo [ iter ]. desc -> next_desc == cpu_to_be32 ( cur_desc )) {
504- struct talitos_edesc * edesc ;
552+ if (hdr )
553+ break ;
505554
506- edesc = container_of ( priv -> chan [ ch ]. fifo [ iter ]. desc ,
507- struct talitos_edesc , desc );
508- return (( struct talitos_desc * )
509- ( edesc -> buf + edesc -> dma_len )) -> hdr ;
510- }
555+ iter = ( iter + 1 ) & ( priv -> fifo_len - 1 );
556+ } while ( iter != tail );
557+
558+ if (! hdr )
559+ dev_err ( dev , "couldn't locate current descriptor\n" );
511560
512- return priv -> chan [ ch ]. fifo [ iter ]. desc -> hdr ;
561+ return hdr ;
513562}
514563
515564/*
@@ -1408,10 +1457,6 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
14081457 dma_len = 0 ;
14091458 }
14101459 alloc_len += icv_stashing ? authsize : 0 ;
1411-
1412- /* if its a ahash, add space for a second desc next to the first one */
1413- if (is_sec1 && !dst )
1414- alloc_len += sizeof (struct talitos_desc );
14151460 alloc_len += ivsize ;
14161461
14171462 edesc = kmalloc (ALIGN (alloc_len , dma_get_cache_alignment ()), flags );
@@ -1427,6 +1472,7 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev,
14271472 edesc -> dst_nents = dst_nents ;
14281473 edesc -> iv_dma = iv_dma ;
14291474 edesc -> dma_len = dma_len ;
1475+ edesc -> next_desc = NULL ;
14301476 if (dma_len )
14311477 edesc -> dma_link_tbl = dma_map_single (dev , & edesc -> link_tbl [0 ],
14321478 edesc -> dma_len ,
@@ -1727,8 +1773,10 @@ static void common_nonsnoop_hash_unmap(struct device *dev,
17271773 struct talitos_private * priv = dev_get_drvdata (dev );
17281774 bool is_sec1 = has_ftr_sec1 (priv );
17291775 struct talitos_desc * desc = & edesc -> desc ;
1730- struct talitos_desc * desc2 = (struct talitos_desc * )
1731- (edesc -> buf + edesc -> dma_len );
1776+ struct talitos_desc * desc2 ;
1777+
1778+ if (desc -> next_desc )
1779+ desc2 = & edesc -> next_desc -> desc ;
17321780
17331781 unmap_single_talitos_ptr (dev , & desc -> ptr [5 ], DMA_FROM_DEVICE );
17341782 if (desc -> next_desc &&
@@ -1756,10 +1804,17 @@ static void common_nonsnoop_hash_unmap(struct device *dev,
17561804 if (edesc -> dma_len )
17571805 dma_unmap_single (dev , edesc -> dma_link_tbl , edesc -> dma_len ,
17581806 DMA_BIDIRECTIONAL );
1807+ }
17591808
1760- if (desc -> next_desc )
1761- dma_unmap_single (dev , be32_to_cpu (desc -> next_desc ),
1762- TALITOS_DESC_SIZE , DMA_BIDIRECTIONAL );
1809+ static void free_edesc_list_from (struct talitos_edesc * edesc )
1810+ {
1811+ struct talitos_edesc * next ;
1812+
1813+ while (edesc ) {
1814+ next = edesc -> next_desc ;
1815+ kfree (edesc );
1816+ edesc = next ;
1817+ }
17631818}
17641819
17651820static void ahash_done (struct device * dev ,
@@ -1778,7 +1833,7 @@ static void ahash_done(struct device *dev,
17781833 }
17791834 common_nonsnoop_hash_unmap (dev , edesc , areq );
17801835
1781- kfree (edesc );
1836+ free_edesc_list_from (edesc );
17821837
17831838 if (err ) {
17841839 ahash_request_complete (areq , err );
@@ -1894,14 +1949,23 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
18941949 talitos_handle_buggy_hash (ctx , edesc , & desc -> ptr [3 ]);
18951950
18961951 if (is_sec1 && req_ctx -> nbuf && length ) {
1897- struct talitos_desc * desc2 = (struct talitos_desc * )
1898- (edesc -> buf + edesc -> dma_len );
1899- dma_addr_t next_desc ;
1952+ struct talitos_edesc * edesc2 ;
1953+ struct talitos_desc * desc2 ;
1954+
1955+ edesc2 = kzalloc (sizeof (* edesc2 ),
1956+ areq -> base .flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
1957+ GFP_KERNEL :
1958+ GFP_ATOMIC );
1959+ if (!edesc2 ) {
1960+ ret = - ENOMEM ;
1961+ goto err ;
1962+ }
1963+ edesc -> next_desc = edesc2 ;
1964+
1965+ desc2 = & edesc2 -> desc ;
19001966
1901- memset (desc2 , 0 , sizeof (* desc2 ));
19021967 desc2 -> hdr = desc -> hdr ;
19031968 desc2 -> hdr &= ~DESC_HDR_MODE0_MDEU_INIT ;
1904- desc2 -> hdr1 = desc2 -> hdr ;
19051969 desc -> hdr &= ~DESC_HDR_MODE0_MDEU_PAD ;
19061970 desc -> hdr |= DESC_HDR_MODE0_MDEU_CONT ;
19071971 desc -> hdr &= ~DESC_HDR_DONE_NOTIFY ;
@@ -1925,21 +1989,21 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
19251989 req_ctx -> hw_context_size ,
19261990 req_ctx -> hw_context ,
19271991 DMA_FROM_DEVICE );
1928-
1929- next_desc = dma_map_single (dev , & desc2 -> hdr1 , TALITOS_DESC_SIZE ,
1930- DMA_BIDIRECTIONAL );
1931- desc -> next_desc = cpu_to_be32 (next_desc );
19321992 }
19331993
19341994 if (sync_needed )
19351995 dma_sync_single_for_device (dev , edesc -> dma_link_tbl ,
19361996 edesc -> dma_len , DMA_BIDIRECTIONAL );
19371997
1938- ret = talitos_submit (dev , ctx -> ch , desc , callback , areq );
1939- if (ret != - EINPROGRESS ) {
1940- common_nonsnoop_hash_unmap (dev , edesc , areq );
1941- kfree (edesc );
1942- }
1998+ ret = talitos_submit (dev , ctx -> ch , desc , callback ,
1999+ areq );
2000+ if (ret != - EINPROGRESS )
2001+ goto err ;
2002+
2003+ return - EINPROGRESS ;
2004+ err :
2005+ common_nonsnoop_hash_unmap (dev , edesc , areq );
2006+ kfree (edesc );
19432007 return ret ;
19442008}
19452009
0 commit comments