|
@@ -394,8 +394,9 @@ static inline void phantom_write_hilo ( struct phantom_nic *phantom,
|
394
|
394
|
* @v buf 8-byte buffer to fill
|
395
|
395
|
* @ret rc Return status code
|
396
|
396
|
*/
|
397
|
|
-static int phantom_read_test_mem ( struct phantom_nic *phantom,
|
398
|
|
- uint64_t offset, uint32_t buf[2] ) {
|
|
397
|
+static int phantom_read_test_mem_block ( struct phantom_nic *phantom,
|
|
398
|
+ unsigned long offset,
|
|
399
|
+ uint32_t buf[2] ) {
|
399
|
400
|
unsigned int retries;
|
400
|
401
|
uint32_t test_control;
|
401
|
402
|
|
|
@@ -421,29 +422,58 @@ static int phantom_read_test_mem ( struct phantom_nic *phantom,
|
421
|
422
|
return -ETIMEDOUT;
|
422
|
423
|
}
|
423
|
424
|
|
|
425
|
+/**
|
|
426
|
+ * Read single byte from Phantom test memory
|
|
427
|
+ *
|
|
428
|
+ * @v phantom Phantom NIC
|
|
429
|
+ * @v offset Offset within test memory
|
|
430
|
+ * @ret byte Byte read, or negative error
|
|
431
|
+ */
|
|
432
|
+static int phantom_read_test_mem ( struct phantom_nic *phantom,
|
|
433
|
+ unsigned long offset ) {
|
|
434
|
+ static union {
|
|
435
|
+ uint8_t bytes[8];
|
|
436
|
+ uint32_t dwords[2];
|
|
437
|
+ } cache;
|
|
438
|
+ static unsigned long cache_offset = -1UL;
|
|
439
|
+ unsigned long sub_offset;
|
|
440
|
+ int rc;
|
|
441
|
+
|
|
442
|
+ sub_offset = ( offset & ( sizeof ( cache ) - 1 ) );
|
|
443
|
+ offset = ( offset & ~( sizeof ( cache ) - 1 ) );
|
|
444
|
+
|
|
445
|
+ if ( cache_offset != offset ) {
|
|
446
|
+ if ( ( rc = phantom_read_test_mem_block ( phantom, offset,
|
|
447
|
+ cache.dwords )) !=0 )
|
|
448
|
+ return rc;
|
|
449
|
+ cache_offset = offset;
|
|
450
|
+ }
|
|
451
|
+
|
|
452
|
+ return cache.bytes[sub_offset];
|
|
453
|
+}
|
|
454
|
+
|
424
|
455
|
/**
|
425
|
456
|
* Dump Phantom firmware dmesg log
|
426
|
457
|
*
|
427
|
458
|
* @v phantom Phantom NIC
|
428
|
459
|
* @v log Log number
|
|
460
|
+ * @v max_lines Maximum number of lines to show, or -1 to show all
|
|
461
|
+ * @ret rc Return status code
|
429
|
462
|
*/
|
430
|
|
-static void phantom_dmesg ( struct phantom_nic *phantom, unsigned int log ) {
|
|
463
|
+static int phantom_dmesg ( struct phantom_nic *phantom, unsigned int log,
|
|
464
|
+ unsigned int max_lines ) {
|
431
|
465
|
uint32_t head;
|
432
|
466
|
uint32_t tail;
|
433
|
467
|
uint32_t len;
|
434
|
468
|
uint32_t sig;
|
435
|
469
|
uint32_t offset;
|
436
|
|
- union {
|
437
|
|
- uint8_t bytes[8];
|
438
|
|
- uint32_t dwords[2];
|
439
|
|
- } buf;
|
440
|
|
- unsigned int i;
|
441
|
|
- int rc;
|
|
470
|
+ int byte;
|
442
|
471
|
|
443
|
472
|
/* Optimise out for non-debug builds */
|
444
|
473
|
if ( ! DBG_LOG )
|
445
|
|
- return;
|
|
474
|
+ return 0;
|
446
|
475
|
|
|
476
|
+ /* Locate log */
|
447
|
477
|
head = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_HEAD ( log ) );
|
448
|
478
|
len = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_LEN ( log ) );
|
449
|
479
|
tail = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_TAIL ( log ) );
|
|
@@ -456,32 +486,37 @@ static void phantom_dmesg ( struct phantom_nic *phantom, unsigned int log ) {
|
456
|
486
|
sig, UNM_CAM_RAM_DMESG_SIG_MAGIC );
|
457
|
487
|
}
|
458
|
488
|
|
459
|
|
- for ( offset = head ; offset < tail ; offset += 8 ) {
|
460
|
|
- if ( ( rc = phantom_read_test_mem ( phantom, offset,
|
461
|
|
- buf.dwords ) ) != 0 ) {
|
462
|
|
- DBGC ( phantom, "Phantom %p could not read from test "
|
463
|
|
- "memory: %s\n", phantom, strerror ( rc ) );
|
|
489
|
+ /* Locate start of last (max_lines) lines */
|
|
490
|
+ for ( offset = tail ; offset > head ; offset-- ) {
|
|
491
|
+ if ( ( byte = phantom_read_test_mem ( phantom,
|
|
492
|
+ ( offset - 1 ) ) ) < 0 )
|
|
493
|
+ return byte;
|
|
494
|
+ if ( ( byte == '\n' ) && ( max_lines-- == 0 ) )
|
464
|
495
|
break;
|
465
|
|
- }
|
466
|
|
- for ( i = 0 ; ( ( i < sizeof ( buf ) ) &&
|
467
|
|
- ( offset + i ) < tail ) ; i++ ) {
|
468
|
|
- DBG ( "%c", buf.bytes[i] );
|
469
|
|
- }
|
|
496
|
+ }
|
|
497
|
+
|
|
498
|
+ /* Print lines */
|
|
499
|
+ for ( ; offset < tail ; offset++ ) {
|
|
500
|
+ if ( ( byte = phantom_read_test_mem ( phantom, offset ) ) < 0 )
|
|
501
|
+ return byte;
|
|
502
|
+ DBG ( "%c", byte );
|
470
|
503
|
}
|
471
|
504
|
DBG ( "\n" );
|
|
505
|
+ return 0;
|
472
|
506
|
}
|
473
|
507
|
|
474
|
508
|
/**
|
475
|
509
|
* Dump Phantom firmware dmesg logs
|
476
|
510
|
*
|
477
|
511
|
* @v phantom Phantom NIC
|
|
512
|
+ * @v max_lines Maximum number of lines to show, or -1 to show all
|
478
|
513
|
*/
|
479
|
514
|
static void __attribute__ (( unused ))
|
480
|
|
-phantom_dmesg_all ( struct phantom_nic *phantom ) {
|
|
515
|
+phantom_dmesg_all ( struct phantom_nic *phantom, unsigned int max_lines ) {
|
481
|
516
|
unsigned int i;
|
482
|
517
|
|
483
|
518
|
for ( i = 0 ; i < UNM_CAM_RAM_NUM_DMESG_BUFFERS ; i++ )
|
484
|
|
- phantom_dmesg ( phantom, i );
|
|
519
|
+ phantom_dmesg ( phantom, i, max_lines );
|
485
|
520
|
}
|
486
|
521
|
|
487
|
522
|
/***************************************************************************
|