@@ -96,6 +96,20 @@ enum dmatest_error_type {
96
96
DMATEST_ET_DMA_ERROR ,
97
97
DMATEST_ET_DMA_IN_PROGRESS ,
98
98
DMATEST_ET_VERIFY ,
99
+ DMATEST_ET_VERIFY_BUF ,
100
+ };
101
+
102
+ struct dmatest_verify_buffer {
103
+ unsigned int index ;
104
+ u8 expected ;
105
+ u8 actual ;
106
+ };
107
+
108
+ struct dmatest_verify_result {
109
+ unsigned int error_count ;
110
+ struct dmatest_verify_buffer data [MAX_ERROR_COUNT ];
111
+ u8 pattern ;
112
+ bool is_srcbuf ;
99
113
};
100
114
101
115
struct dmatest_thread_result {
@@ -106,10 +120,11 @@ struct dmatest_thread_result {
106
120
unsigned int len ;
107
121
enum dmatest_error_type type ;
108
122
union {
109
- unsigned long data ;
110
- dma_cookie_t cookie ;
111
- enum dma_status status ;
112
- int error ;
123
+ unsigned long data ;
124
+ dma_cookie_t cookie ;
125
+ enum dma_status status ;
126
+ int error ;
127
+ struct dmatest_verify_result * vr ;
113
128
};
114
129
};
115
130
@@ -246,52 +261,30 @@ static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len,
246
261
}
247
262
}
248
263
249
- static void dmatest_mismatch (u8 actual , u8 pattern , unsigned int index ,
250
- unsigned int counter , bool is_srcbuf )
251
- {
252
- u8 diff = actual ^ pattern ;
253
- u8 expected = pattern | (~counter & PATTERN_COUNT_MASK );
254
- const char * thread_name = current -> comm ;
255
-
256
- if (is_srcbuf )
257
- pr_warning ("%s: srcbuf[0x%x] overwritten!"
258
- " Expected %02x, got %02x\n" ,
259
- thread_name , index , expected , actual );
260
- else if ((pattern & PATTERN_COPY )
261
- && (diff & (PATTERN_COPY | PATTERN_OVERWRITE )))
262
- pr_warning ("%s: dstbuf[0x%x] not copied!"
263
- " Expected %02x, got %02x\n" ,
264
- thread_name , index , expected , actual );
265
- else if (diff & PATTERN_SRC )
266
- pr_warning ("%s: dstbuf[0x%x] was copied!"
267
- " Expected %02x, got %02x\n" ,
268
- thread_name , index , expected , actual );
269
- else
270
- pr_warning ("%s: dstbuf[0x%x] mismatch!"
271
- " Expected %02x, got %02x\n" ,
272
- thread_name , index , expected , actual );
273
- }
274
-
275
- static unsigned int dmatest_verify (u8 * * bufs , unsigned int start ,
276
- unsigned int end , unsigned int counter , u8 pattern ,
277
- bool is_srcbuf )
264
+ static unsigned int dmatest_verify (struct dmatest_verify_result * vr , u8 * * bufs ,
265
+ unsigned int start , unsigned int end , unsigned int counter ,
266
+ u8 pattern , bool is_srcbuf )
278
267
{
279
268
unsigned int i ;
280
269
unsigned int error_count = 0 ;
281
270
u8 actual ;
282
271
u8 expected ;
283
272
u8 * buf ;
284
273
unsigned int counter_orig = counter ;
274
+ struct dmatest_verify_buffer * vb ;
285
275
286
276
for (; (buf = * bufs ); bufs ++ ) {
287
277
counter = counter_orig ;
288
278
for (i = start ; i < end ; i ++ ) {
289
279
actual = buf [i ];
290
280
expected = pattern | (~counter & PATTERN_COUNT_MASK );
291
281
if (actual != expected ) {
292
- if (error_count < MAX_ERROR_COUNT )
293
- dmatest_mismatch (actual , pattern , i ,
294
- counter , is_srcbuf );
282
+ if (error_count < MAX_ERROR_COUNT && vr ) {
283
+ vb = & vr -> data [error_count ];
284
+ vb -> index = i ;
285
+ vb -> expected = expected ;
286
+ vb -> actual = actual ;
287
+ }
295
288
error_count ++ ;
296
289
}
297
290
counter ++ ;
@@ -340,6 +333,30 @@ static unsigned int min_odd(unsigned int x, unsigned int y)
340
333
return val % 2 ? val : val - 1 ;
341
334
}
342
335
336
+ static char * verify_result_get_one (struct dmatest_verify_result * vr ,
337
+ unsigned int i )
338
+ {
339
+ struct dmatest_verify_buffer * vb = & vr -> data [i ];
340
+ u8 diff = vb -> actual ^ vr -> pattern ;
341
+ static char buf [512 ];
342
+ char * msg ;
343
+
344
+ if (vr -> is_srcbuf )
345
+ msg = "srcbuf overwritten!" ;
346
+ else if ((vr -> pattern & PATTERN_COPY )
347
+ && (diff & (PATTERN_COPY | PATTERN_OVERWRITE )))
348
+ msg = "dstbuf not copied!" ;
349
+ else if (diff & PATTERN_SRC )
350
+ msg = "dstbuf was copied!" ;
351
+ else
352
+ msg = "dstbuf mismatch!" ;
353
+
354
+ snprintf (buf , sizeof (buf ) - 1 , "%s [0x%x] Expected %02x, got %02x" , msg ,
355
+ vb -> index , vb -> expected , vb -> actual );
356
+
357
+ return buf ;
358
+ }
359
+
343
360
static char * thread_result_get (const char * name ,
344
361
struct dmatest_thread_result * tr )
345
362
{
@@ -355,6 +372,7 @@ static char *thread_result_get(const char *name,
355
372
[DMATEST_ET_DMA_IN_PROGRESS ] =
356
373
"got completion callback (DMA_IN_PROGRESS)" ,
357
374
[DMATEST_ET_VERIFY ] = "errors" ,
375
+ [DMATEST_ET_VERIFY_BUF ] = "verify errors" ,
358
376
};
359
377
static char buf [512 ];
360
378
@@ -392,6 +410,51 @@ static int thread_result_add(struct dmatest_info *info,
392
410
return 0 ;
393
411
}
394
412
413
+ static unsigned int verify_result_add (struct dmatest_info * info ,
414
+ struct dmatest_result * r , unsigned int n ,
415
+ unsigned int src_off , unsigned int dst_off , unsigned int len ,
416
+ u8 * * bufs , int whence , unsigned int counter , u8 pattern ,
417
+ bool is_srcbuf )
418
+ {
419
+ struct dmatest_verify_result * vr ;
420
+ unsigned int error_count ;
421
+ unsigned int buf_off = is_srcbuf ? src_off : dst_off ;
422
+ unsigned int start , end ;
423
+
424
+ if (whence < 0 ) {
425
+ start = 0 ;
426
+ end = buf_off ;
427
+ } else if (whence > 0 ) {
428
+ start = buf_off + len ;
429
+ end = info -> params .buf_size ;
430
+ } else {
431
+ start = buf_off ;
432
+ end = buf_off + len ;
433
+ }
434
+
435
+ vr = kmalloc (sizeof (* vr ), GFP_KERNEL );
436
+ if (!vr ) {
437
+ pr_warn ("dmatest: No memory to store verify result\n" );
438
+ return dmatest_verify (NULL , bufs , start , end , counter , pattern ,
439
+ is_srcbuf );
440
+ }
441
+
442
+ vr -> pattern = pattern ;
443
+ vr -> is_srcbuf = is_srcbuf ;
444
+
445
+ error_count = dmatest_verify (vr , bufs , start , end , counter , pattern ,
446
+ is_srcbuf );
447
+ if (error_count ) {
448
+ vr -> error_count = error_count ;
449
+ thread_result_add (info , r , DMATEST_ET_VERIFY_BUF , n , src_off ,
450
+ dst_off , len , (unsigned long )vr );
451
+ return error_count ;
452
+ }
453
+
454
+ kfree (vr );
455
+ return 0 ;
456
+ }
457
+
395
458
static void result_free (struct dmatest_info * info , const char * name )
396
459
{
397
460
struct dmatest_result * r , * _r ;
@@ -404,6 +467,8 @@ static void result_free(struct dmatest_info *info, const char *name)
404
467
continue ;
405
468
406
469
list_for_each_entry_safe (tr , _tr , & r -> results , node ) {
470
+ if (tr -> type == DMATEST_ET_VERIFY_BUF )
471
+ kfree (tr -> vr );
407
472
list_del (& tr -> node );
408
473
kfree (tr );
409
474
}
@@ -687,25 +752,26 @@ static int dmatest_func(void *data)
687
752
error_count = 0 ;
688
753
689
754
pr_debug ("%s: verifying source buffer...\n" , thread_name );
690
- error_count += dmatest_verify (thread -> srcs , 0 , src_off ,
755
+ error_count += verify_result_add (info , result , total_tests ,
756
+ src_off , dst_off , len , thread -> srcs , -1 ,
691
757
0 , PATTERN_SRC , true);
692
- error_count += dmatest_verify ( thread -> srcs , src_off ,
693
- src_off + len , src_off ,
694
- PATTERN_SRC | PATTERN_COPY , true);
695
- error_count += dmatest_verify ( thread -> srcs , src_off + len ,
696
- params -> buf_size , src_off + len ,
697
- PATTERN_SRC , true);
698
-
699
- pr_debug ("%s: verifying dest buffer...\n" ,
700
- thread -> task -> comm );
701
- error_count += dmatest_verify ( thread -> dsts , 0 , dst_off ,
758
+ error_count += verify_result_add ( info , result , total_tests ,
759
+ src_off , dst_off , len , thread -> srcs , 0 ,
760
+ src_off , PATTERN_SRC | PATTERN_COPY , true);
761
+ error_count += verify_result_add ( info , result , total_tests ,
762
+ src_off , dst_off , len , thread -> srcs , 1 ,
763
+ src_off + len , PATTERN_SRC , true);
764
+
765
+ pr_debug ("%s: verifying dest buffer...\n" , thread_name );
766
+ error_count += verify_result_add ( info , result , total_tests ,
767
+ src_off , dst_off , len , thread -> dsts , -1 ,
702
768
0 , PATTERN_DST , false);
703
- error_count += dmatest_verify ( thread -> dsts , dst_off ,
704
- dst_off + len , src_off ,
705
- PATTERN_SRC | PATTERN_COPY , false);
706
- error_count += dmatest_verify ( thread -> dsts , dst_off + len ,
707
- params -> buf_size , dst_off + len ,
708
- PATTERN_DST , false);
769
+ error_count += verify_result_add ( info , result , total_tests ,
770
+ src_off , dst_off , len , thread -> dsts , 0 ,
771
+ src_off , PATTERN_SRC | PATTERN_COPY , false);
772
+ error_count += verify_result_add ( info , result , total_tests ,
773
+ src_off , dst_off , len , thread -> dsts , 1 ,
774
+ dst_off + len , PATTERN_DST , false);
709
775
710
776
if (error_count ) {
711
777
thread_result_add (info , result , DMATEST_ET_VERIFY ,
@@ -1085,12 +1151,20 @@ static int dtf_results_show(struct seq_file *sf, void *data)
1085
1151
struct dmatest_info * info = sf -> private ;
1086
1152
struct dmatest_result * result ;
1087
1153
struct dmatest_thread_result * tr ;
1154
+ unsigned int i ;
1088
1155
1089
1156
mutex_lock (& info -> results_lock );
1090
1157
list_for_each_entry (result , & info -> results , node ) {
1091
- list_for_each_entry (tr , & result -> results , node )
1158
+ list_for_each_entry (tr , & result -> results , node ) {
1092
1159
seq_printf (sf , "%s\n" ,
1093
1160
thread_result_get (result -> name , tr ));
1161
+ if (tr -> type == DMATEST_ET_VERIFY_BUF ) {
1162
+ for (i = 0 ; i < tr -> vr -> error_count ; i ++ ) {
1163
+ seq_printf (sf , "\t%s\n" ,
1164
+ verify_result_get_one (tr -> vr , i ));
1165
+ }
1166
+ }
1167
+ }
1094
1168
}
1095
1169
1096
1170
mutex_unlock (& info -> results_lock );
0 commit comments