Browse Source

[hermon] Reset device during probe()

Some systems will retry their boot sequence in the event of a boot
failure.  On these systems, the second and subsequent boot attempts
will fail to initialise the Hermon HCA.

Fix by resetting the HCA during probe().  This incurs a one-second
cost, but there seems to be no viable alternative.

Originally-fixed-by: Itay Gazit <itaygazit@gmail.com>
tags/v0.9.8
Michael Brown 15 years ago
parent
commit
9f7141a1ce
2 changed files with 28 additions and 0 deletions
  1. 23
    0
      src/drivers/infiniband/hermon.c
  2. 5
    0
      src/drivers/infiniband/hermon.h

+ 23
- 0
src/drivers/infiniband/hermon.c View File

29
 #include <byteswap.h>
29
 #include <byteswap.h>
30
 #include <gpxe/io.h>
30
 #include <gpxe/io.h>
31
 #include <gpxe/pci.h>
31
 #include <gpxe/pci.h>
32
+#include <gpxe/pcibackup.h>
32
 #include <gpxe/malloc.h>
33
 #include <gpxe/malloc.h>
33
 #include <gpxe/umalloc.h>
34
 #include <gpxe/umalloc.h>
34
 #include <gpxe/iobuf.h>
35
 #include <gpxe/iobuf.h>
2550
 	return 0;
2551
 	return 0;
2551
 }
2552
 }
2552
 
2553
 
2554
+/**
2555
+ * Reset device
2556
+ *
2557
+ * @v hermon		Hermon device
2558
+ * @v pci		PCI device
2559
+ */
2560
+static void hermon_reset ( struct hermon *hermon,
2561
+			   struct pci_device *pci ) {
2562
+	struct pci_config_backup backup;
2563
+	static const uint8_t backup_exclude[] =
2564
+		PCI_CONFIG_BACKUP_EXCLUDE ( 0x58, 0x5c );
2565
+
2566
+	pci_backup ( pci, &backup, backup_exclude );
2567
+	writel ( HERMON_RESET_MAGIC,
2568
+		 ( hermon->config + HERMON_RESET_OFFSET ) );
2569
+	mdelay ( HERMON_RESET_WAIT_TIME_MS );
2570
+	pci_restore ( pci, &backup, backup_exclude );
2571
+}
2572
+
2553
 /**
2573
 /**
2554
  * Probe PCI device
2574
  * Probe PCI device
2555
  *
2575
  *
2582
 	hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
2602
 	hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
2583
 				HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
2603
 				HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
2584
 
2604
 
2605
+	/* Reset device */
2606
+	hermon_reset ( hermon, pci );
2607
+
2585
 	/* Allocate space for mailboxes */
2608
 	/* Allocate space for mailboxes */
2586
 	hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
2609
 	hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
2587
 					  HERMON_MBOX_ALIGN );
2610
 					  HERMON_MBOX_ALIGN );

+ 5
- 0
src/drivers/infiniband/hermon.h View File

29
 #define HERMON_PCI_CONFIG_BAR_SIZE	0x100000
29
 #define HERMON_PCI_CONFIG_BAR_SIZE	0x100000
30
 #define HERMON_PCI_UAR_BAR		PCI_BASE_ADDRESS_2
30
 #define HERMON_PCI_UAR_BAR		PCI_BASE_ADDRESS_2
31
 
31
 
32
+/* Device reset */
33
+#define HERMON_RESET_OFFSET		0x0f0010
34
+#define HERMON_RESET_MAGIC		0x01000000UL
35
+#define HERMON_RESET_WAIT_TIME_MS	1000
36
+
32
 /* Work queue entry and completion queue entry opcodes */
37
 /* Work queue entry and completion queue entry opcodes */
33
 #define HERMON_OPCODE_NOP		0x00
38
 #define HERMON_OPCODE_NOP		0x00
34
 #define HERMON_OPCODE_SEND		0x0a
39
 #define HERMON_OPCODE_SEND		0x0a

Loading…
Cancel
Save