Skip to contentSkip to conversation

lpfc 8.2.8 : Add MSI-X support

PATCH In review James Smart 1 participant 1 message Aug 25, 2008

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 13/15 lpfc 8.2.8 : Add MSI-X support

Add support for MSI-X Multi-Message interrupts. We use different vectors for fast-path interrupts (i/o) and slow-patch interrupts (discovery, etc).

---

 lpfc.h         |   35 ++++
 lpfc_attr.c    |    8 -
 lpfc_crtn.h    |   41 ++---
 lpfc_hbadisc.c |    2 
 lpfc_hw.h      |   63 ++++++++
 lpfc_init.c    |  230 ++++++++++++++++++++++++++------
 lpfc_mbox.c    |   80 +++++++++++
 lpfc_sli.c     |  401 +++++++++++++++++++++++++++++++++++++++++++--------------
 lpfc_version.h |    4 
 9 files changed, 698 insertions(+), 166 deletions(-)
drivers/scsi/lpfc/lpfc_attr.c +4 -4
diff -upNr a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
@@ -2414,12 +2414,12 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
 /*
 # lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
 #		support this feature
-#       0  = MSI disabled (default)
+#       0  = MSI disabled
 #       1  = MSI enabled
-#	2  = MSI-X enabled
-# Value range is [0,2]. Default value is 0.
+#       2  = MSI-X enabled (default)
+# Value range is [0,2]. Default value is 2.
 */
-LPFC_ATTR_R(use_msi, 0, 0, 2, "Use Message Signaled Interrupts (1) or "
+LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
 	    "MSI-X (2), if possible");
 
 /*
drivers/scsi/lpfc/lpfc_crtn.h +21 -20

98 lines not on this page · raw message

drivers/scsi/lpfc/lpfc.h +34 -1
diff -upNr a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
@@ -54,6 +54,9 @@ struct lpfc_sli2_slim;
 #define LPFC_HB_MBOX_INTERVAL   5	/* Heart beat interval in seconds. */
 #define LPFC_HB_MBOX_TIMEOUT    30	/* Heart beat timeout  in seconds. */
 
+/* Error Attention event polling interval */
+#define LPFC_ERATT_POLL_INTERVAL	5 /* EATT poll interval in seconds */
+
 /* Define macros for 64 bit support */
 #define putPaddrLow(addr)    ((uint32_t) (0xffffffff & (u64)(addr)))
 #define putPaddrHigh(addr)   ((uint32_t) (0xffffffff & (((u64)(addr))>>32)))
@@ -65,6 +68,9 @@ struct lpfc_sli2_slim;
 
 #define MAX_HBAEVT	32
 
+/* Number of MSI-X vectors the driver uses */
+#define LPFC_MSIX_VECTORS	2
+
 /* lpfc wait event data ready flag */
 #define LPFC_DATA_READY		(1<<0)
 
@@ -429,12 +435,16 @@ struct lpfc_hba {
 #define LS_NPIV_FAB_SUPPORTED 0x2	/* Fabric supports NPIV */
 #define LS_IGNORE_ERATT       0x4	/* intr handler should ignore ERATT */
 
+	uint32_t hba_flag;	/* hba generic flags */
+#define HBA_ERATT_HANDLED	0x1 /* This flag is set when eratt handled */
+
 	struct lpfc_dmabuf slim2p;
 
 	MAILBOX_t *mbox;
 	uint32_t *inb_ha_copy;
 	uint32_t *inb_counter;
 	uint32_t inb_last_counter;
+	uint32_t ha_copy;
 	struct _PCB *pcb;
 	struct _IOCB *IOCBs;
 
@@ -550,6 +560,7 @@ struct lpfc_hba {
 	uint8_t soft_wwn_enable;
 
 	struct timer_list fcp_poll_timer;
+	struct timer_list eratt_poll;
 
 	/*
 	 * stat  counters
@@ -579,7 +590,7 @@ struct lpfc_hba {
 
 	struct fc_host_statistics link_stats;
 	enum intr_type_t intr_type;
-	struct msix_entry msix_entries[1];
+	struct msix_entry msix_entries[LPFC_MSIX_VECTORS];
 
 	struct list_head port_list;
 	struct lpfc_vport *pport;	/* physical lpfc_vport pointer */
@@ -666,6 +677,28 @@ lpfc_worker_wake_up(struct lpfc_hba *phb
 	return;
 }
 
+static inline void
+lpfc_sli_read_hs(struct lpfc_hba *phba)
+{
+	/*
+	 * There was a link/board error. Read the status register to retrieve
+	 * the error event and process it.
+	 */
+	phba->sli.slistat.err_attn_event++;
+
+	/* Save status info */
+	phba->work_hs = readl(phba->HSregaddr);
+	phba->work_status[0] = readl(phba->MBslimaddr + 0xa8);
+	phba->work_status[1] = readl(phba->MBslimaddr + 0xac);
+
+	/* Clear chip Host Attention error bit */
+	writel(HA_ERATT, phba->HAregaddr);
+	readl(phba->HAregaddr); /* flush */
+	phba->pport->stopped = 1;
+
+	return;
+}
+
 #define FC_REG_DUMP_EVENT		0x10	/* Register for Dump events */
 #define FC_REG_TEMPERATURE_EVENT	0x20    /* Register for temperature
 						   event */
drivers/scsi/lpfc/lpfc_hbadisc.c +2 -0
diff -upNr a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -377,6 +377,7 @@ lpfc_work_done(struct lpfc_hba *phba)
 	spin_unlock_irq(&phba->hbalock);
 
 	if (ha_copy & HA_ERATT)
+		/* Handle the error attention event */
 		lpfc_handle_eratt(phba);
 
 	if (ha_copy & HA_MBATT)
@@ -384,6 +385,7 @@ lpfc_work_done(struct lpfc_hba *phba)
 
 	if (ha_copy & HA_LATT)
 		lpfc_handle_latt(phba);
+
 	vports = lpfc_create_vport_work_array(phba);
 	if (vports != NULL)
 		for(i = 0; i <= phba->max_vpi; i++) {
drivers/scsi/lpfc/lpfc_hw.h +62 -1

99 lines not on this page · raw message

drivers/scsi/lpfc/lpfc_init.c +185 -45

371 lines not on this page · raw message

drivers/scsi/lpfc/lpfc_mbox.c +79 -1

92 lines not on this page · raw message

drivers/scsi/lpfc/lpfc_sli.c +308 -93

504 lines not on this page · raw message

drivers/scsi/lpfc/lpfc_version.h +3 -1
diff -upNr a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,9 @@
 
 #define LPFC_DRIVER_VERSION "8.2.7"
 
-#define LPFC_DRIVER_NAME "lpfc"
+#define LPFC_DRIVER_NAME		"lpfc"
+#define LPFC_SP_DRIVER_HANDLER_NAME	"lpfc:sp"
+#define LPFC_FP_DRIVER_HANDLER_NAME	"lpfc:fp"
 
 #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \
 		LPFC_DRIVER_VERSION