@@ -85,6 +85,8 @@ struct mon_reader_text {
85
85
86
86
wait_queue_head_t wait ;
87
87
int printf_size ;
88
+ size_t printf_offset ;
89
+ size_t printf_togo ;
88
90
char * printf_buf ;
89
91
struct mutex printf_lock ;
90
92
@@ -376,75 +378,103 @@ static int mon_text_open(struct inode *inode, struct file *file)
376
378
return rc ;
377
379
}
378
380
379
- /*
380
- * For simplicity, we read one record in one system call and throw out
381
- * what does not fit. This means that the following does not work:
382
- * dd if=/dbg/usbmon/0t bs=10
383
- * Also, we do not allow seeks and do not bother advancing the offset.
384
- */
381
+ static ssize_t mon_text_copy_to_user (struct mon_reader_text * rp ,
382
+ char __user * const buf , const size_t nbytes )
383
+ {
384
+ const size_t togo = min (nbytes , rp -> printf_togo );
385
+
386
+ if (copy_to_user (buf , & rp -> printf_buf [rp -> printf_offset ], togo ))
387
+ return - EFAULT ;
388
+ rp -> printf_togo -= togo ;
389
+ rp -> printf_offset += togo ;
390
+ return togo ;
391
+ }
392
+
393
+ /* ppos is not advanced since the llseek operation is not permitted. */
385
394
static ssize_t mon_text_read_t (struct file * file , char __user * buf ,
386
- size_t nbytes , loff_t * ppos )
395
+ size_t nbytes , loff_t * ppos )
387
396
{
388
397
struct mon_reader_text * rp = file -> private_data ;
389
398
struct mon_event_text * ep ;
390
399
struct mon_text_ptr ptr ;
400
+ ssize_t ret ;
391
401
392
- ep = mon_text_read_wait (rp , file );
393
- if (IS_ERR (ep ))
394
- return PTR_ERR (ep );
395
402
mutex_lock (& rp -> printf_lock );
396
- ptr .cnt = 0 ;
397
- ptr .pbuf = rp -> printf_buf ;
398
- ptr .limit = rp -> printf_size ;
399
-
400
- mon_text_read_head_t (rp , & ptr , ep );
401
- mon_text_read_statset (rp , & ptr , ep );
402
- ptr .cnt += snprintf (ptr .pbuf + ptr .cnt , ptr .limit - ptr .cnt ,
403
- " %d" , ep -> length );
404
- mon_text_read_data (rp , & ptr , ep );
405
-
406
- if (copy_to_user (buf , rp -> printf_buf , ptr .cnt ))
407
- ptr .cnt = - EFAULT ;
403
+
404
+ if (rp -> printf_togo == 0 ) {
405
+
406
+ ep = mon_text_read_wait (rp , file );
407
+ if (IS_ERR (ep )) {
408
+ mutex_unlock (& rp -> printf_lock );
409
+ return PTR_ERR (ep );
410
+ }
411
+ ptr .cnt = 0 ;
412
+ ptr .pbuf = rp -> printf_buf ;
413
+ ptr .limit = rp -> printf_size ;
414
+
415
+ mon_text_read_head_t (rp , & ptr , ep );
416
+ mon_text_read_statset (rp , & ptr , ep );
417
+ ptr .cnt += snprintf (ptr .pbuf + ptr .cnt , ptr .limit - ptr .cnt ,
418
+ " %d" , ep -> length );
419
+ mon_text_read_data (rp , & ptr , ep );
420
+
421
+ rp -> printf_togo = ptr .cnt ;
422
+ rp -> printf_offset = 0 ;
423
+
424
+ kmem_cache_free (rp -> e_slab , ep );
425
+ }
426
+
427
+ ret = mon_text_copy_to_user (rp , buf , nbytes );
408
428
mutex_unlock (& rp -> printf_lock );
409
- kmem_cache_free (rp -> e_slab , ep );
410
- return ptr .cnt ;
429
+ return ret ;
411
430
}
412
431
432
+ /* ppos is not advanced since the llseek operation is not permitted. */
413
433
static ssize_t mon_text_read_u (struct file * file , char __user * buf ,
414
- size_t nbytes , loff_t * ppos )
434
+ size_t nbytes , loff_t * ppos )
415
435
{
416
436
struct mon_reader_text * rp = file -> private_data ;
417
437
struct mon_event_text * ep ;
418
438
struct mon_text_ptr ptr ;
439
+ ssize_t ret ;
419
440
420
- ep = mon_text_read_wait (rp , file );
421
- if (IS_ERR (ep ))
422
- return PTR_ERR (ep );
423
441
mutex_lock (& rp -> printf_lock );
424
- ptr .cnt = 0 ;
425
- ptr .pbuf = rp -> printf_buf ;
426
- ptr .limit = rp -> printf_size ;
427
442
428
- mon_text_read_head_u (rp , & ptr , ep );
429
- if (ep -> type == 'E' ) {
430
- mon_text_read_statset (rp , & ptr , ep );
431
- } else if (ep -> xfertype == USB_ENDPOINT_XFER_ISOC ) {
432
- mon_text_read_isostat (rp , & ptr , ep );
433
- mon_text_read_isodesc (rp , & ptr , ep );
434
- } else if (ep -> xfertype == USB_ENDPOINT_XFER_INT ) {
435
- mon_text_read_intstat (rp , & ptr , ep );
436
- } else {
437
- mon_text_read_statset (rp , & ptr , ep );
443
+ if (rp -> printf_togo == 0 ) {
444
+
445
+ ep = mon_text_read_wait (rp , file );
446
+ if (IS_ERR (ep )) {
447
+ mutex_unlock (& rp -> printf_lock );
448
+ return PTR_ERR (ep );
449
+ }
450
+ ptr .cnt = 0 ;
451
+ ptr .pbuf = rp -> printf_buf ;
452
+ ptr .limit = rp -> printf_size ;
453
+
454
+ mon_text_read_head_u (rp , & ptr , ep );
455
+ if (ep -> type == 'E' ) {
456
+ mon_text_read_statset (rp , & ptr , ep );
457
+ } else if (ep -> xfertype == USB_ENDPOINT_XFER_ISOC ) {
458
+ mon_text_read_isostat (rp , & ptr , ep );
459
+ mon_text_read_isodesc (rp , & ptr , ep );
460
+ } else if (ep -> xfertype == USB_ENDPOINT_XFER_INT ) {
461
+ mon_text_read_intstat (rp , & ptr , ep );
462
+ } else {
463
+ mon_text_read_statset (rp , & ptr , ep );
464
+ }
465
+ ptr .cnt += snprintf (ptr .pbuf + ptr .cnt , ptr .limit - ptr .cnt ,
466
+ " %d" , ep -> length );
467
+ mon_text_read_data (rp , & ptr , ep );
468
+
469
+ rp -> printf_togo = ptr .cnt ;
470
+ rp -> printf_offset = 0 ;
471
+
472
+ kmem_cache_free (rp -> e_slab , ep );
438
473
}
439
- ptr .cnt += snprintf (ptr .pbuf + ptr .cnt , ptr .limit - ptr .cnt ,
440
- " %d" , ep -> length );
441
- mon_text_read_data (rp , & ptr , ep );
442
474
443
- if (copy_to_user (buf , rp -> printf_buf , ptr .cnt ))
444
- ptr .cnt = - EFAULT ;
475
+ ret = mon_text_copy_to_user (rp , buf , nbytes );
445
476
mutex_unlock (& rp -> printf_lock );
446
- kmem_cache_free (rp -> e_slab , ep );
447
- return ptr .cnt ;
477
+ return ret ;
448
478
}
449
479
450
480
static struct mon_event_text * mon_text_read_wait (struct mon_reader_text * rp ,
0 commit comments