aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-08-24 21:50:30 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-10-13 09:28:55 -0400
commit9399627f340794baebf7e4581470ccb92f019acc (patch)
treec30e656a1c353e2f025bb5ca3daf142128434a34
parent0f1f53a7efd60d7cdd8e82925f0c62dcf64ba092 (diff)
[SCSI] 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). Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/lpfc/lpfc.h35
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c8
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h43
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h63
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c230
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c80
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c401
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h4
9 files changed, 699 insertions, 167 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index aee5444b63d9..181538466117 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -49,6 +49,9 @@ struct lpfc_sli2_slim;
49#define LPFC_HB_MBOX_INTERVAL 5 /* Heart beat interval in seconds. */ 49#define LPFC_HB_MBOX_INTERVAL 5 /* Heart beat interval in seconds. */
50#define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */ 50#define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */
51 51
52/* Error Attention event polling interval */
53#define LPFC_ERATT_POLL_INTERVAL 5 /* EATT poll interval in seconds */
54
52/* Define macros for 64 bit support */ 55/* Define macros for 64 bit support */
53#define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr))) 56#define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr)))
54#define putPaddrHigh(addr) ((uint32_t) (0xffffffff & (((u64)(addr))>>32))) 57#define putPaddrHigh(addr) ((uint32_t) (0xffffffff & (((u64)(addr))>>32)))
@@ -60,6 +63,9 @@ struct lpfc_sli2_slim;
60 63
61#define MAX_HBAEVT 32 64#define MAX_HBAEVT 32
62 65
66/* Number of MSI-X vectors the driver uses */
67#define LPFC_MSIX_VECTORS 2
68
63/* lpfc wait event data ready flag */ 69/* lpfc wait event data ready flag */
64#define LPFC_DATA_READY (1<<0) 70#define LPFC_DATA_READY (1<<0)
65 71
@@ -423,12 +429,16 @@ struct lpfc_hba {
423#define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */ 429#define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */
424#define LS_IGNORE_ERATT 0x4 /* intr handler should ignore ERATT */ 430#define LS_IGNORE_ERATT 0x4 /* intr handler should ignore ERATT */
425 431
432 uint32_t hba_flag; /* hba generic flags */
433#define HBA_ERATT_HANDLED 0x1 /* This flag is set when eratt handled */
434
426 struct lpfc_dmabuf slim2p; 435 struct lpfc_dmabuf slim2p;
427 436
428 MAILBOX_t *mbox; 437 MAILBOX_t *mbox;
429 uint32_t *inb_ha_copy; 438 uint32_t *inb_ha_copy;
430 uint32_t *inb_counter; 439 uint32_t *inb_counter;
431 uint32_t inb_last_counter; 440 uint32_t inb_last_counter;
441 uint32_t ha_copy;
432 struct _PCB *pcb; 442 struct _PCB *pcb;
433 struct _IOCB *IOCBs; 443 struct _IOCB *IOCBs;
434 444
@@ -544,6 +554,7 @@ struct lpfc_hba {
544 uint8_t soft_wwn_enable; 554 uint8_t soft_wwn_enable;
545 555
546 struct timer_list fcp_poll_timer; 556 struct timer_list fcp_poll_timer;
557 struct timer_list eratt_poll;
547 558
548 /* 559 /*
549 * stat counters 560 * stat counters
@@ -573,7 +584,7 @@ struct lpfc_hba {
573 584
574 struct fc_host_statistics link_stats; 585 struct fc_host_statistics link_stats;
575 enum intr_type_t intr_type; 586 enum intr_type_t intr_type;
576 struct msix_entry msix_entries[1]; 587 struct msix_entry msix_entries[LPFC_MSIX_VECTORS];
577 588
578 struct list_head port_list; 589 struct list_head port_list;
579 struct lpfc_vport *pport; /* physical lpfc_vport pointer */ 590 struct lpfc_vport *pport; /* physical lpfc_vport pointer */
@@ -660,6 +671,28 @@ lpfc_worker_wake_up(struct lpfc_hba *phba)
660 return; 671 return;
661} 672}
662 673
674static inline void
675lpfc_sli_read_hs(struct lpfc_hba *phba)
676{
677 /*
678 * There was a link/board error. Read the status register to retrieve
679 * the error event and process it.
680 */
681 phba->sli.slistat.err_attn_event++;
682
683 /* Save status info */
684 phba->work_hs = readl(phba->HSregaddr);
685 phba->work_status[0] = readl(phba->MBslimaddr + 0xa8);
686 phba->work_status[1] = readl(phba->MBslimaddr + 0xac);
687
688 /* Clear chip Host Attention error bit */
689 writel(HA_ERATT, phba->HAregaddr);
690 readl(phba->HAregaddr); /* flush */
691 phba->pport->stopped = 1;
692
693 return;
694}
695
663#define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */ 696#define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */
664#define FC_REG_TEMPERATURE_EVENT 0x20 /* Register for temperature 697#define FC_REG_TEMPERATURE_EVENT 0x20 /* Register for temperature
665 event */ 698 event */
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index b9acc6eefe62..21397f37010d 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -2372,12 +2372,12 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
2372/* 2372/*
2373# lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that 2373# lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
2374# support this feature 2374# support this feature
2375# 0 = MSI disabled (default) 2375# 0 = MSI disabled
2376# 1 = MSI enabled 2376# 1 = MSI enabled
2377# 2 = MSI-X enabled 2377# 2 = MSI-X enabled (default)
2378# Value range is [0,2]. Default value is 0. 2378# Value range is [0,2]. Default value is 2.
2379*/ 2379*/
2380LPFC_ATTR_R(use_msi, 0, 0, 2, "Use Message Signaled Interrupts (1) or " 2380LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
2381 "MSI-X (2), if possible"); 2381 "MSI-X (2), if possible");
2382 2382
2383/* 2383/*
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 495afd06936b..7d173f4a37f5 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -18,7 +18,7 @@
18 * included with this package. * 18 * included with this package. *
19 *******************************************************************/ 19 *******************************************************************/
20 20
21typedef int (*node_filter)(struct lpfc_nodelist *ndlp, void *param); 21typedef int (*node_filter)(struct lpfc_nodelist *, void *);
22 22
23struct fc_rport; 23struct fc_rport;
24void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); 24void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
@@ -26,11 +26,11 @@ void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
26void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); 26void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
27 27
28void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *); 28void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *);
29int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, 29int lpfc_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *, struct lpfc_dmabuf *);
30 struct lpfc_dmabuf *mp);
31void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *); 30void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
32void lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport); 31void lpfc_issue_clear_la(struct lpfc_hba *, struct lpfc_vport *);
33void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); 32void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
33int lpfc_config_msi(struct lpfc_hba *, LPFC_MBOXQ_t *);
34int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *, int); 34int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *, int);
35void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *); 35void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
36void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *); 36void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -43,7 +43,7 @@ void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
43void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); 43void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
44 44
45struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t); 45struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
46void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove); 46void lpfc_cleanup_rpis(struct lpfc_vport *, int);
47int lpfc_linkdown(struct lpfc_hba *); 47int lpfc_linkdown(struct lpfc_hba *);
48void lpfc_port_link_failure(struct lpfc_vport *); 48void lpfc_port_link_failure(struct lpfc_vport *);
49void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); 49void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -135,7 +135,7 @@ void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
135int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t); 135int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t);
136int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int); 136int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int);
137void lpfc_fdmi_tmo(unsigned long); 137void lpfc_fdmi_tmo(unsigned long);
138void lpfc_fdmi_timeout_handler(struct lpfc_vport *vport); 138void lpfc_fdmi_timeout_handler(struct lpfc_vport *);
139 139
140int lpfc_config_port_prep(struct lpfc_hba *); 140int lpfc_config_port_prep(struct lpfc_hba *);
141int lpfc_config_port_post(struct lpfc_hba *); 141int lpfc_config_port_post(struct lpfc_hba *);
@@ -155,6 +155,8 @@ int lpfc_sli_queue_setup(struct lpfc_hba *);
155void lpfc_handle_eratt(struct lpfc_hba *); 155void lpfc_handle_eratt(struct lpfc_hba *);
156void lpfc_handle_latt(struct lpfc_hba *); 156void lpfc_handle_latt(struct lpfc_hba *);
157irqreturn_t lpfc_intr_handler(int, void *); 157irqreturn_t lpfc_intr_handler(int, void *);
158irqreturn_t lpfc_sp_intr_handler(int, void *);
159irqreturn_t lpfc_fp_intr_handler(int, void *);
158 160
159void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *); 161void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *);
160void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *); 162void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *);
@@ -175,11 +177,12 @@ void lpfc_mem_free(struct lpfc_hba *);
175void lpfc_stop_vport_timers(struct lpfc_vport *); 177void lpfc_stop_vport_timers(struct lpfc_vport *);
176 178
177void lpfc_poll_timeout(unsigned long ptr); 179void lpfc_poll_timeout(unsigned long ptr);
178void lpfc_poll_start_timer(struct lpfc_hba * phba); 180void lpfc_poll_start_timer(struct lpfc_hba *);
179void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba); 181void lpfc_poll_eratt(unsigned long);
182void lpfc_sli_poll_fcp_ring(struct lpfc_hba *);
180struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *); 183struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
181void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); 184void lpfc_sli_release_iocbq(struct lpfc_hba *, struct lpfc_iocbq *);
182uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb); 185uint16_t lpfc_sli_next_iotag(struct lpfc_hba *, struct lpfc_iocbq *);
183 186
184void lpfc_reset_barrier(struct lpfc_hba * phba); 187void lpfc_reset_barrier(struct lpfc_hba * phba);
185int lpfc_sli_brdready(struct lpfc_hba *, uint32_t); 188int lpfc_sli_brdready(struct lpfc_hba *, uint32_t);
@@ -187,11 +190,13 @@ int lpfc_sli_brdkill(struct lpfc_hba *);
187int lpfc_sli_brdreset(struct lpfc_hba *); 190int lpfc_sli_brdreset(struct lpfc_hba *);
188int lpfc_sli_brdrestart(struct lpfc_hba *); 191int lpfc_sli_brdrestart(struct lpfc_hba *);
189int lpfc_sli_hba_setup(struct lpfc_hba *); 192int lpfc_sli_hba_setup(struct lpfc_hba *);
193int lpfc_sli_config_port(struct lpfc_hba *, int);
190int lpfc_sli_host_down(struct lpfc_vport *); 194int lpfc_sli_host_down(struct lpfc_vport *);
191int lpfc_sli_hba_down(struct lpfc_hba *); 195int lpfc_sli_hba_down(struct lpfc_hba *);
192int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); 196int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
193int lpfc_sli_handle_mb_event(struct lpfc_hba *); 197int lpfc_sli_handle_mb_event(struct lpfc_hba *);
194int lpfc_sli_flush_mbox_queue(struct lpfc_hba *); 198int lpfc_sli_flush_mbox_queue(struct lpfc_hba *);
199int lpfc_sli_check_eratt(struct lpfc_hba *);
195int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *, 200int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *,
196 struct lpfc_sli_ring *, uint32_t); 201 struct lpfc_sli_ring *, uint32_t);
197void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); 202void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -227,17 +232,13 @@ struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t);
227struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *, 232struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *,
228 struct lpfc_name *); 233 struct lpfc_name *);
229 234
230int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, 235int lpfc_sli_issue_mbox_wait(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
231 uint32_t timeout); 236
232 237int lpfc_sli_issue_iocb_wait(struct lpfc_hba *, struct lpfc_sli_ring *,
233int lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, 238 struct lpfc_iocbq *, struct lpfc_iocbq *,
234 struct lpfc_sli_ring * pring, 239 uint32_t);
235 struct lpfc_iocbq * piocb, 240void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *, struct lpfc_iocbq *,
236 struct lpfc_iocbq * prspiocbq, 241 struct lpfc_iocbq *);
237 uint32_t timeout);
238void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba,
239 struct lpfc_iocbq * cmdiocb,
240 struct lpfc_iocbq * rspiocb);
241 242
242void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *); 243void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *);
243 244
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 897ef7d7a8e9..3b00d9b86c7b 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -369,6 +369,7 @@ lpfc_work_done(struct lpfc_hba *phba)
369 spin_unlock_irq(&phba->hbalock); 369 spin_unlock_irq(&phba->hbalock);
370 370
371 if (ha_copy & HA_ERATT) 371 if (ha_copy & HA_ERATT)
372 /* Handle the error attention event */
372 lpfc_handle_eratt(phba); 373 lpfc_handle_eratt(phba);
373 374
374 if (ha_copy & HA_MBATT) 375 if (ha_copy & HA_MBATT)
@@ -376,6 +377,7 @@ lpfc_work_done(struct lpfc_hba *phba)
376 377
377 if (ha_copy & HA_LATT) 378 if (ha_copy & HA_LATT)
378 lpfc_handle_latt(phba); 379 lpfc_handle_latt(phba);
380
379 vports = lpfc_create_vport_work_array(phba); 381 vports = lpfc_create_vport_work_array(phba);
380 if (vports != NULL) 382 if (vports != NULL)
381 for(i = 0; i <= phba->max_vpi; i++) { 383 for(i = 0; i <= phba->max_vpi; i++) {
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index ee4e50175ca8..5de5dabbbee6 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1203,6 +1203,18 @@ typedef struct { /* FireFly BIU registers */
1203#define HA_RXATT 0x00000008 /* Bit 3 */ 1203#define HA_RXATT 0x00000008 /* Bit 3 */
1204#define HA_RXMASK 0x0000000f 1204#define HA_RXMASK 0x0000000f
1205 1205
1206#define HA_R0_CLR_MSK (HA_R0RE_REQ | HA_R0CE_RSP | HA_R0ATT)
1207#define HA_R1_CLR_MSK (HA_R1RE_REQ | HA_R1CE_RSP | HA_R1ATT)
1208#define HA_R2_CLR_MSK (HA_R2RE_REQ | HA_R2CE_RSP | HA_R2ATT)
1209#define HA_R3_CLR_MSK (HA_R3RE_REQ | HA_R3CE_RSP | HA_R3ATT)
1210
1211#define HA_R0_POS 3
1212#define HA_R1_POS 7
1213#define HA_R2_POS 11
1214#define HA_R3_POS 15
1215#define HA_LE_POS 29
1216#define HA_MB_POS 30
1217#define HA_ER_POS 31
1206/* Chip Attention Register */ 1218/* Chip Attention Register */
1207 1219
1208#define CA_REG_OFFSET 4 /* Byte offset from register base address */ 1220#define CA_REG_OFFSET 4 /* Byte offset from register base address */
@@ -1240,7 +1252,7 @@ typedef struct { /* FireFly BIU registers */
1240 1252
1241/* Host Control Register */ 1253/* Host Control Register */
1242 1254
1243#define HC_REG_OFFSET 12 /* Word offset from register base address */ 1255#define HC_REG_OFFSET 12 /* Byte offset from register base address */
1244 1256
1245#define HC_MBINT_ENA 0x00000001 /* Bit 0 */ 1257#define HC_MBINT_ENA 0x00000001 /* Bit 0 */
1246#define HC_R0INT_ENA 0x00000002 /* Bit 1 */ 1258#define HC_R0INT_ENA 0x00000002 /* Bit 1 */
@@ -1253,6 +1265,19 @@ typedef struct { /* FireFly BIU registers */
1253#define HC_LAINT_ENA 0x20000000 /* Bit 29 */ 1265#define HC_LAINT_ENA 0x20000000 /* Bit 29 */
1254#define HC_ERINT_ENA 0x80000000 /* Bit 31 */ 1266#define HC_ERINT_ENA 0x80000000 /* Bit 31 */
1255 1267
1268/* Message Signaled Interrupt eXtension (MSI-X) message identifiers */
1269#define MSIX_DFLT_ID 0
1270#define MSIX_RNG0_ID 0
1271#define MSIX_RNG1_ID 1
1272#define MSIX_RNG2_ID 2
1273#define MSIX_RNG3_ID 3
1274
1275#define MSIX_LINK_ID 4
1276#define MSIX_MBOX_ID 5
1277
1278#define MSIX_SPARE0_ID 6
1279#define MSIX_SPARE1_ID 7
1280
1256/* Mailbox Commands */ 1281/* Mailbox Commands */
1257#define MBX_SHUTDOWN 0x00 /* terminate testing */ 1282#define MBX_SHUTDOWN 0x00 /* terminate testing */
1258#define MBX_LOAD_SM 0x01 1283#define MBX_LOAD_SM 0x01
@@ -1290,6 +1315,7 @@ typedef struct { /* FireFly BIU registers */
1290#define MBX_KILL_BOARD 0x24 1315#define MBX_KILL_BOARD 0x24
1291#define MBX_CONFIG_FARP 0x25 1316#define MBX_CONFIG_FARP 0x25
1292#define MBX_BEACON 0x2A 1317#define MBX_BEACON 0x2A
1318#define MBX_CONFIG_MSI 0x30
1293#define MBX_HEARTBEAT 0x31 1319#define MBX_HEARTBEAT 0x31
1294#define MBX_WRITE_VPARMS 0x32 1320#define MBX_WRITE_VPARMS 0x32
1295#define MBX_ASYNCEVT_ENABLE 0x33 1321#define MBX_ASYNCEVT_ENABLE 0x33
@@ -2599,6 +2625,40 @@ typedef struct {
2599 2625
2600} CONFIG_PORT_VAR; 2626} CONFIG_PORT_VAR;
2601 2627
2628/* Structure for MB Command CONFIG_MSI (0x30) */
2629struct config_msi_var {
2630#ifdef __BIG_ENDIAN_BITFIELD
2631 uint32_t dfltMsgNum:8; /* Default message number */
2632 uint32_t rsvd1:11; /* Reserved */
2633 uint32_t NID:5; /* Number of secondary attention IDs */
2634 uint32_t rsvd2:5; /* Reserved */
2635 uint32_t dfltPresent:1; /* Default message number present */
2636 uint32_t addFlag:1; /* Add association flag */
2637 uint32_t reportFlag:1; /* Report association flag */
2638#else /* __LITTLE_ENDIAN_BITFIELD */
2639 uint32_t reportFlag:1; /* Report association flag */
2640 uint32_t addFlag:1; /* Add association flag */
2641 uint32_t dfltPresent:1; /* Default message number present */
2642 uint32_t rsvd2:5; /* Reserved */
2643 uint32_t NID:5; /* Number of secondary attention IDs */
2644 uint32_t rsvd1:11; /* Reserved */
2645 uint32_t dfltMsgNum:8; /* Default message number */
2646#endif
2647 uint32_t attentionConditions[2];
2648 uint8_t attentionId[16];
2649 uint8_t messageNumberByHA[64];
2650 uint8_t messageNumberByID[16];
2651 uint32_t autoClearHA[2];
2652#ifdef __BIG_ENDIAN_BITFIELD
2653 uint32_t rsvd3:16;
2654 uint32_t autoClearID:16;
2655#else /* __LITTLE_ENDIAN_BITFIELD */
2656 uint32_t autoClearID:16;
2657 uint32_t rsvd3:16;
2658#endif
2659 uint32_t rsvd4;
2660};
2661
2602/* SLI-2 Port Control Block */ 2662/* SLI-2 Port Control Block */
2603 2663
2604/* SLIM POINTER */ 2664/* SLIM POINTER */
@@ -2722,6 +2782,7 @@ typedef union {
2722 REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */ 2782 REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */
2723 UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */ 2783 UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */
2724 ASYNCEVT_ENABLE_VAR varCfgAsyncEvent; /*cmd = x33 (CONFIG_ASYNC) */ 2784 ASYNCEVT_ENABLE_VAR varCfgAsyncEvent; /*cmd = x33 (CONFIG_ASYNC) */
2785 struct config_msi_var varCfgMSI;/* cmd = x30 (CONFIG_MSI) */
2725} MAILVARIANTS; 2786} MAILVARIANTS;
2726 2787
2727/* 2788/*
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 333166b17908..49577d5f130f 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -389,6 +389,29 @@ lpfc_config_port_post(struct lpfc_hba *phba)
389 if (phba->sli_rev != 3) 389 if (phba->sli_rev != 3)
390 lpfc_post_rcv_buf(phba); 390 lpfc_post_rcv_buf(phba);
391 391
392 /*
393 * Configure HBA MSI-X attention conditions to messages if MSI-X mode
394 */
395 if (phba->intr_type == MSIX) {
396 rc = lpfc_config_msi(phba, pmb);
397 if (rc) {
398 mempool_free(pmb, phba->mbox_mem_pool);
399 return -EIO;
400 }
401 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
402 if (rc != MBX_SUCCESS) {
403 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
404 "0352 Config MSI mailbox command "
405 "failed, mbxCmd x%x, mbxStatus x%x\n",
406 pmb->mb.mbxCommand, pmb->mb.mbxStatus);
407 mempool_free(pmb, phba->mbox_mem_pool);
408 return -EIO;
409 }
410 }
411
412 /* Initialize ERATT handling flag */
413 phba->hba_flag &= ~HBA_ERATT_HANDLED;
414
392 /* Enable appropriate host interrupts */ 415 /* Enable appropriate host interrupts */
393 spin_lock_irq(&phba->hbalock); 416 spin_lock_irq(&phba->hbalock);
394 status = readl(phba->HCregaddr); 417 status = readl(phba->HCregaddr);
@@ -404,20 +427,21 @@ lpfc_config_port_post(struct lpfc_hba *phba)
404 427
405 if ((phba->cfg_poll & ENABLE_FCP_RING_POLLING) && 428 if ((phba->cfg_poll & ENABLE_FCP_RING_POLLING) &&
406 (phba->cfg_poll & DISABLE_FCP_RING_INT)) 429 (phba->cfg_poll & DISABLE_FCP_RING_INT))
407 status &= ~(HC_R0INT_ENA << LPFC_FCP_RING); 430 status &= ~(HC_R0INT_ENA);
408 431
409 writel(status, phba->HCregaddr); 432 writel(status, phba->HCregaddr);
410 readl(phba->HCregaddr); /* flush */ 433 readl(phba->HCregaddr); /* flush */
411 spin_unlock_irq(&phba->hbalock); 434 spin_unlock_irq(&phba->hbalock);
412 435
413 /* 436 /* Set up ring-0 (ELS) timer */
414 * Setup the ring 0 (els) timeout handler 437 timeout = phba->fc_ratov * 2;
415 */
416 timeout = phba->fc_ratov << 1;
417 mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); 438 mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout);
439 /* Set up heart beat (HB) timer */
418 mod_timer(&phba->hb_tmofunc, jiffies + HZ * LPFC_HB_MBOX_INTERVAL); 440 mod_timer(&phba->hb_tmofunc, jiffies + HZ * LPFC_HB_MBOX_INTERVAL);
419 phba->hb_outstanding = 0; 441 phba->hb_outstanding = 0;
420 phba->last_completion_time = jiffies; 442 phba->last_completion_time = jiffies;
443 /* Set up error attention (ERATT) polling timer */
444 mod_timer(&phba->eratt_poll, jiffies + HZ * LPFC_ERATT_POLL_INTERVAL);
421 445
422 lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); 446 lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
423 pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; 447 pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
@@ -581,12 +605,15 @@ lpfc_hb_timeout(unsigned long ptr)
581 unsigned long iflag; 605 unsigned long iflag;
582 606
583 phba = (struct lpfc_hba *)ptr; 607 phba = (struct lpfc_hba *)ptr;
608
609 /* Check for heart beat timeout conditions */
584 spin_lock_irqsave(&phba->pport->work_port_lock, iflag); 610 spin_lock_irqsave(&phba->pport->work_port_lock, iflag);
585 tmo_posted = phba->pport->work_port_events & WORKER_HB_TMO; 611 tmo_posted = phba->pport->work_port_events & WORKER_HB_TMO;
586 if (!tmo_posted) 612 if (!tmo_posted)
587 phba->pport->work_port_events |= WORKER_HB_TMO; 613 phba->pport->work_port_events |= WORKER_HB_TMO;
588 spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); 614 spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);
589 615
616 /* Tell the worker thread there is work to do */
590 if (!tmo_posted) 617 if (!tmo_posted)
591 lpfc_worker_wake_up(phba); 618 lpfc_worker_wake_up(phba);
592 return; 619 return;
@@ -617,6 +644,7 @@ lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
617 phba->hb_outstanding = 0; 644 phba->hb_outstanding = 0;
618 spin_unlock_irqrestore(&phba->hbalock, drvr_flag); 645 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
619 646
647 /* Check and reset heart-beat timer is necessary */
620 mempool_free(pmboxq, phba->mbox_mem_pool); 648 mempool_free(pmboxq, phba->mbox_mem_pool);
621 if (!(phba->pport->fc_flag & FC_OFFLINE_MODE) && 649 if (!(phba->pport->fc_flag & FC_OFFLINE_MODE) &&
622 !(phba->link_state == LPFC_HBA_ERROR) && 650 !(phba->link_state == LPFC_HBA_ERROR) &&
@@ -856,8 +884,8 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
856 884
857 } else { 885 } else {
858 /* The if clause above forces this code path when the status 886 /* The if clause above forces this code path when the status
859 * failure is a value other than FFER6. Do not call the offline 887 * failure is a value other than FFER6. Do not call the offline
860 * twice. This is the adapter hardware error path. 888 * twice. This is the adapter hardware error path.
861 */ 889 */
862 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 890 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
863 "0457 Adapter Hardware Error " 891 "0457 Adapter Hardware Error "
@@ -873,6 +901,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
873 901
874 lpfc_offline_eratt(phba); 902 lpfc_offline_eratt(phba);
875 } 903 }
904 return;
876} 905}
877 906
878/** 907/**
@@ -1656,6 +1685,7 @@ lpfc_stop_phba_timers(struct lpfc_hba *phba)
1656 del_timer_sync(&phba->fabric_block_timer); 1685 del_timer_sync(&phba->fabric_block_timer);
1657 phba->hb_outstanding = 0; 1686 phba->hb_outstanding = 0;
1658 del_timer_sync(&phba->hb_tmofunc); 1687 del_timer_sync(&phba->hb_tmofunc);
1688 del_timer_sync(&phba->eratt_poll);
1659 return; 1689 return;
1660} 1690}
1661 1691
@@ -2172,30 +2202,97 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost)
2172static int 2202static int
2173lpfc_enable_msix(struct lpfc_hba *phba) 2203lpfc_enable_msix(struct lpfc_hba *phba)
2174{ 2204{
2175 int error; 2205 int rc, i;
2206 LPFC_MBOXQ_t *pmb;
2176 2207
2177 phba->msix_entries[0].entry = 0; 2208 /* Set up MSI-X multi-message vectors */
2178 phba->msix_entries[0].vector = 0; 2209 for (i = 0; i < LPFC_MSIX_VECTORS; i++)
2210 phba->msix_entries[i].entry = i;
2179 2211
2180 error = pci_enable_msix(phba->pcidev, phba->msix_entries, 2212 /* Configure MSI-X capability structure */
2213 rc = pci_enable_msix(phba->pcidev, phba->msix_entries,
2181 ARRAY_SIZE(phba->msix_entries)); 2214 ARRAY_SIZE(phba->msix_entries));
2182 if (error) { 2215 if (rc) {
2183 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, 2216 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2184 "0420 Enable MSI-X failed (%d), continuing " 2217 "0420 Enable MSI-X failed (%d), continuing "
2185 "with MSI\n", error); 2218 "with MSI\n", rc);
2186 pci_disable_msix(phba->pcidev); 2219 goto msi_fail_out;
2187 return error; 2220 } else
2221 for (i = 0; i < LPFC_MSIX_VECTORS; i++)
2222 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2223 "0477 MSI-X entry[%d]: vector=x%x "
2224 "message=%d\n", i,
2225 phba->msix_entries[i].vector,
2226 phba->msix_entries[i].entry);
2227 /*
2228 * Assign MSI-X vectors to interrupt handlers
2229 */
2230
2231 /* vector-0 is associated to slow-path handler */
2232 rc = request_irq(phba->msix_entries[0].vector, &lpfc_sp_intr_handler,
2233 IRQF_SHARED, LPFC_SP_DRIVER_HANDLER_NAME, phba);
2234 if (rc) {
2235 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2236 "0421 MSI-X slow-path request_irq failed "
2237 "(%d), continuing with MSI\n", rc);
2238 goto msi_fail_out;
2188 } 2239 }
2189 2240
2190 error = request_irq(phba->msix_entries[0].vector, lpfc_intr_handler, 0, 2241 /* vector-1 is associated to fast-path handler */
2191 LPFC_DRIVER_NAME, phba); 2242 rc = request_irq(phba->msix_entries[1].vector, &lpfc_fp_intr_handler,
2192 if (error) { 2243 IRQF_SHARED, LPFC_FP_DRIVER_HANDLER_NAME, phba);
2244
2245 if (rc) {
2193 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 2246 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2194 "0421 MSI-X request_irq failed (%d), " 2247 "0429 MSI-X fast-path request_irq failed "
2195 "continuing with MSI\n", error); 2248 "(%d), continuing with MSI\n", rc);
2196 pci_disable_msix(phba->pcidev); 2249 goto irq_fail_out;
2197 } 2250 }
2198 return error; 2251
2252 /*
2253 * Configure HBA MSI-X attention conditions to messages
2254 */
2255 pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2256
2257 if (!pmb) {
2258 rc = -ENOMEM;
2259 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2260 "0474 Unable to allocate memory for issuing "
2261 "MBOX_CONFIG_MSI command\n");
2262 goto mem_fail_out;
2263 }
2264 rc = lpfc_config_msi(phba, pmb);
2265 if (rc)
2266 goto mbx_fail_out;
2267 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
2268 if (rc != MBX_SUCCESS) {
2269 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
2270 "0351 Config MSI mailbox command failed, "
2271 "mbxCmd x%x, mbxStatus x%x\n",
2272 pmb->mb.mbxCommand, pmb->mb.mbxStatus);
2273 goto mbx_fail_out;
2274 }
2275
2276 /* Free memory allocated for mailbox command */
2277 mempool_free(pmb, phba->mbox_mem_pool);
2278 return rc;
2279
2280mbx_fail_out:
2281 /* Free memory allocated for mailbox command */
2282 mempool_free(pmb, phba->mbox_mem_pool);
2283
2284mem_fail_out:
2285 /* free the irq already requested */
2286 free_irq(phba->msix_entries[1].vector, phba);
2287
2288irq_fail_out:
2289 /* free the irq already requested */
2290 free_irq(phba->msix_entries[0].vector, phba);
2291
2292msi_fail_out:
2293 /* Unconfigure MSI-X capability structure */
2294 pci_disable_msix(phba->pcidev);
2295 return rc;
2199} 2296}
2200 2297
2201/** 2298/**
@@ -2208,7 +2305,12 @@ lpfc_enable_msix(struct lpfc_hba *phba)
2208static void 2305static void
2209lpfc_disable_msix(struct lpfc_hba *phba) 2306lpfc_disable_msix(struct lpfc_hba *phba)
2210{ 2307{
2211 free_irq(phba->msix_entries[0].vector, phba); 2308 int i;
2309
2310 /* Free up MSI-X multi-message vectors */
2311 for (i = 0; i < LPFC_MSIX_VECTORS; i++)
2312 free_irq(phba->msix_entries[i].vector, phba);
2313 /* Disable MSI-X */
2212 pci_disable_msix(phba->pcidev); 2314 pci_disable_msix(phba->pcidev);
2213} 2315}
2214 2316
@@ -2288,6 +2390,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
2288 init_timer(&phba->fabric_block_timer); 2390 init_timer(&phba->fabric_block_timer);
2289 phba->fabric_block_timer.function = lpfc_fabric_block_timeout; 2391 phba->fabric_block_timer.function = lpfc_fabric_block_timeout;
2290 phba->fabric_block_timer.data = (unsigned long) phba; 2392 phba->fabric_block_timer.data = (unsigned long) phba;
2393 init_timer(&phba->eratt_poll);
2394 phba->eratt_poll.function = lpfc_poll_eratt;
2395 phba->eratt_poll.data = (unsigned long) phba;
2291 2396
2292 pci_set_master(pdev); 2397 pci_set_master(pdev);
2293 pci_try_set_mwi(pdev); 2398 pci_try_set_mwi(pdev);
@@ -2307,7 +2412,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
2307 bar2map_len = pci_resource_len(phba->pcidev, 2); 2412 bar2map_len = pci_resource_len(phba->pcidev, 2);
2308 2413
2309 /* Map HBA SLIM to a kernel virtual address. */ 2414 /* Map HBA SLIM to a kernel virtual address. */
2310 phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len); 2415 phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len);
2311 if (!phba->slim_memmap_p) { 2416 if (!phba->slim_memmap_p) {
2312 error = -ENODEV; 2417 error = -ENODEV;
2313 dev_printk(KERN_ERR, &pdev->dev, 2418 dev_printk(KERN_ERR, &pdev->dev,
@@ -2405,7 +2510,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
2405 phba->fc_arbtov = FF_DEF_ARBTOV; 2510 phba->fc_arbtov = FF_DEF_ARBTOV;
2406 2511
2407 INIT_LIST_HEAD(&phba->work_list); 2512 INIT_LIST_HEAD(&phba->work_list);
2408 phba->work_ha_mask = (HA_ERATT|HA_MBATT|HA_LATT); 2513 phba->work_ha_mask = (HA_ERATT | HA_MBATT | HA_LATT);
2409 phba->work_ha_mask |= (HA_RXMASK << (LPFC_ELS_RING * 4)); 2514 phba->work_ha_mask |= (HA_RXMASK << (LPFC_ELS_RING * 4));
2410 2515
2411 /* Initialize the wait queue head for the kernel thread */ 2516 /* Initialize the wait queue head for the kernel thread */
@@ -2440,21 +2545,42 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
2440 pci_set_drvdata(pdev, shost); 2545 pci_set_drvdata(pdev, shost);
2441 phba->intr_type = NONE; 2546 phba->intr_type = NONE;
2442 2547
2548 phba->MBslimaddr = phba->slim_memmap_p;
2549 phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
2550 phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
2551 phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
2552 phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
2553
2554 /* Configure and enable interrupt */
2443 if (phba->cfg_use_msi == 2) { 2555 if (phba->cfg_use_msi == 2) {
2444 error = lpfc_enable_msix(phba); 2556 /* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
2445 if (!error) 2557 error = lpfc_sli_config_port(phba, 3);
2446 phba->intr_type = MSIX; 2558 if (error)
2559 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2560 "0427 Firmware not capable of SLI 3 mode.\n");
2561 else {
2562 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2563 "0426 Firmware capable of SLI 3 mode.\n");
2564 /* Now, try to enable MSI-X interrupt mode */
2565 error = lpfc_enable_msix(phba);
2566 if (!error) {
2567 phba->intr_type = MSIX;
2568 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2569 "0430 enable MSI-X mode.\n");
2570 }
2571 }
2447 } 2572 }
2448 2573
2449 /* Fallback to MSI if MSI-X initialization failed */ 2574 /* Fallback to MSI if MSI-X initialization failed */
2450 if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { 2575 if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) {
2451 retval = pci_enable_msi(phba->pcidev); 2576 retval = pci_enable_msi(phba->pcidev);
2452 if (!retval) 2577 if (!retval) {
2453 phba->intr_type = MSI; 2578 phba->intr_type = MSI;
2454 else
2455 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, 2579 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2456 "0452 Enable MSI failed, continuing " 2580 "0473 enable MSI mode.\n");
2457 "with IRQ\n"); 2581 } else
2582 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2583 "0452 enable IRQ mode.\n");
2458 } 2584 }
2459 2585
2460 /* MSI-X is the only case the doesn't need to call request_irq */ 2586 /* MSI-X is the only case the doesn't need to call request_irq */
@@ -2470,18 +2596,16 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
2470 phba->intr_type = INTx; 2596 phba->intr_type = INTx;
2471 } 2597 }
2472 2598
2473 phba->MBslimaddr = phba->slim_memmap_p;
2474 phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
2475 phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
2476 phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
2477 phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
2478
2479 if (lpfc_alloc_sysfs_attr(vport)) { 2599 if (lpfc_alloc_sysfs_attr(vport)) {
2600 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2601 "1476 Failed to allocate sysfs attr\n");
2480 error = -ENOMEM; 2602 error = -ENOMEM;
2481 goto out_free_irq; 2603 goto out_free_irq;
2482 } 2604 }
2483 2605
2484 if (lpfc_sli_hba_setup(phba)) { 2606 if (lpfc_sli_hba_setup(phba)) {
2607 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2608 "1477 Failed to set up hba\n");
2485 error = -ENODEV; 2609 error = -ENODEV;
2486 goto out_remove_device; 2610 goto out_remove_device;
2487 } 2611 }
@@ -2500,6 +2624,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
2500 spin_unlock_irq(shost->host_lock); 2624 spin_unlock_irq(shost->host_lock);
2501 } 2625 }
2502 2626
2627 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2628 "0428 Perform SCSI scan\n");
2503 scsi_scan_host(shost); 2629 scsi_scan_host(shost);
2504 2630
2505 return 0; 2631 return 0;
@@ -2732,20 +2858,34 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
2732 /* Enable configured interrupt method */ 2858 /* Enable configured interrupt method */
2733 phba->intr_type = NONE; 2859 phba->intr_type = NONE;
2734 if (phba->cfg_use_msi == 2) { 2860 if (phba->cfg_use_msi == 2) {
2735 error = lpfc_enable_msix(phba); 2861 /* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
2736 if (!error) 2862 error = lpfc_sli_config_port(phba, 3);
2737 phba->intr_type = MSIX; 2863 if (error)
2864 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2865 "0478 Firmware not capable of SLI 3 mode.\n");
2866 else {
2867 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2868 "0479 Firmware capable of SLI 3 mode.\n");
2869 /* Now, try to enable MSI-X interrupt mode */
2870 error = lpfc_enable_msix(phba);
2871 if (!error) {
2872 phba->intr_type = MSIX;
2873 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2874 "0480 enable MSI-X mode.\n");
2875 }
2876 }
2738 } 2877 }
2739 2878
2740 /* Fallback to MSI if MSI-X initialization failed */ 2879 /* Fallback to MSI if MSI-X initialization failed */
2741 if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { 2880 if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) {
2742 retval = pci_enable_msi(phba->pcidev); 2881 retval = pci_enable_msi(phba->pcidev);
2743 if (!retval) 2882 if (!retval) {
2744 phba->intr_type = MSI; 2883 phba->intr_type = MSI;
2745 else
2746 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, 2884 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2747 "0470 Enable MSI failed, continuing " 2885 "0481 enable MSI mode.\n");
2748 "with IRQ\n"); 2886 } else
2887 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2888 "0470 enable IRQ mode.\n");
2749 } 2889 }
2750 2890
2751 /* MSI-X is the only case the doesn't need to call request_irq */ 2891 /* MSI-X is the only case the doesn't need to call request_irq */
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index ca358355ec9b..65bc8e1a5f7d 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2007 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * Portions Copyright (C) 2004-2005 Christoph Hellwig * 7 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -272,6 +272,84 @@ lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
272} 272}
273 273
274/** 274/**
275 * lpfc_config_msi: Prepare a mailbox command for configuring msi-x.
276 * @phba: pointer to lpfc hba data structure.
277 * @pmb: pointer to the driver internal queue element for mailbox command.
278 *
279 * The configure MSI-X mailbox command is used to configure the HBA's SLI-3
280 * MSI-X multi-message interrupt vector association to interrupt attention
281 * conditions.
282 *
283 * Return codes
284 * 0 - Success
285 * -EINVAL - Failure
286 **/
287int
288lpfc_config_msi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
289{
290 MAILBOX_t *mb = &pmb->mb;
291 uint32_t attentionConditions[2];
292
293 /* Sanity check */
294 if (phba->cfg_use_msi != 2) {
295 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
296 "0475 Not configured for supporting MSI-X "
297 "cfg_use_msi: 0x%x\n", phba->cfg_use_msi);
298 return -EINVAL;
299 }
300
301 if (phba->sli_rev < 3) {
302 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
303 "0476 HBA not supporting SLI-3 or later "
304 "SLI Revision: 0x%x\n", phba->sli_rev);
305 return -EINVAL;
306 }
307
308 /* Clear mailbox command fields */
309 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
310
311 /*
312 * SLI-3, Message Signaled Interrupt Fearure.
313 */
314
315 /* Multi-message attention configuration */
316 attentionConditions[0] = (HA_R0ATT | HA_R1ATT | HA_R2ATT | HA_ERATT |
317 HA_LATT | HA_MBATT);
318 attentionConditions[1] = 0;
319
320 mb->un.varCfgMSI.attentionConditions[0] = attentionConditions[0];
321 mb->un.varCfgMSI.attentionConditions[1] = attentionConditions[1];
322
323 /*
324 * Set up message number to HA bit association
325 */
326#ifdef __BIG_ENDIAN_BITFIELD
327 /* RA0 (FCP Ring) */
328 mb->un.varCfgMSI.messageNumberByHA[HA_R0_POS] = 1;
329 /* RA1 (Other Protocol Extra Ring) */
330 mb->un.varCfgMSI.messageNumberByHA[HA_R1_POS] = 1;
331#else /* __LITTLE_ENDIAN_BITFIELD */
332 /* RA0 (FCP Ring) */
333 mb->un.varCfgMSI.messageNumberByHA[HA_R0_POS^3] = 1;
334 /* RA1 (Other Protocol Extra Ring) */
335 mb->un.varCfgMSI.messageNumberByHA[HA_R1_POS^3] = 1;
336#endif
337 /* Multi-message interrupt autoclear configuration*/
338 mb->un.varCfgMSI.autoClearHA[0] = attentionConditions[0];
339 mb->un.varCfgMSI.autoClearHA[1] = attentionConditions[1];
340
341 /* For now, HBA autoclear does not work reliably, disable it */
342 mb->un.varCfgMSI.autoClearHA[0] = 0;
343 mb->un.varCfgMSI.autoClearHA[1] = 0;
344
345 /* Set command and owner bit */
346 mb->mbxCommand = MBX_CONFIG_MSI;
347 mb->mbxOwner = OWN_HOST;
348
349 return 0;
350}
351
352/**
275 * lpfc_init_link: Prepare a mailbox command for initialize link on a HBA. 353 * lpfc_init_link: Prepare a mailbox command for initialize link on a HBA.
276 * @phba: pointer to lpfc hba data structure. 354 * @phba: pointer to lpfc hba data structure.
277 * @pmb: pointer to the driver internal queue element for mailbox command. 355 * @pmb: pointer to the driver internal queue element for mailbox command.
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 1812e18246d5..2cca39e9b93d 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1699,6 +1699,36 @@ lpfc_sli_rsp_pointers_error(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
1699} 1699}
1700 1700
1701/** 1701/**
1702 * lpfc_poll_eratt: Error attention polling timer timeout handler.
1703 * @ptr: Pointer to address of HBA context object.
1704 *
1705 * This function is invoked by the Error Attention polling timer when the
1706 * timer times out. It will check the SLI Error Attention register for
1707 * possible attention events. If so, it will post an Error Attention event
1708 * and wake up worker thread to process it. Otherwise, it will set up the
1709 * Error Attention polling timer for the next poll.
1710 **/
1711void lpfc_poll_eratt(unsigned long ptr)
1712{
1713 struct lpfc_hba *phba;
1714 uint32_t eratt = 0;
1715
1716 phba = (struct lpfc_hba *)ptr;
1717
1718 /* Check chip HA register for error event */
1719 eratt = lpfc_sli_check_eratt(phba);
1720
1721 if (eratt)
1722 /* Tell the worker thread there is work to do */
1723 lpfc_worker_wake_up(phba);
1724 else
1725 /* Restart the timer for next eratt poll */
1726 mod_timer(&phba->eratt_poll, jiffies +
1727 HZ * LPFC_ERATT_POLL_INTERVAL);
1728 return;
1729}
1730
1731/**
1702 * lpfc_sli_poll_fcp_ring: Handle FCP ring completion in polling mode. 1732 * lpfc_sli_poll_fcp_ring: Handle FCP ring completion in polling mode.
1703 * @phba: Pointer to HBA context object. 1733 * @phba: Pointer to HBA context object.
1704 * 1734 *
@@ -3011,7 +3041,7 @@ lpfc_sli_hbq_setup(struct lpfc_hba *phba)
3011} 3041}
3012 3042
3013/** 3043/**
3014 * lpfc_do_config_port: Issue config port mailbox command. 3044 * lpfc_sli_config_port: Issue config port mailbox command.
3015 * @phba: Pointer to HBA context object. 3045 * @phba: Pointer to HBA context object.
3016 * @sli_mode: sli mode - 2/3 3046 * @sli_mode: sli mode - 2/3
3017 * 3047 *
@@ -3023,8 +3053,8 @@ lpfc_sli_hbq_setup(struct lpfc_hba *phba)
3023 * The function returns 0 if successful, else returns negative error 3053 * The function returns 0 if successful, else returns negative error
3024 * code. 3054 * code.
3025 **/ 3055 **/
3026static int 3056int
3027lpfc_do_config_port(struct lpfc_hba *phba, int sli_mode) 3057lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode)
3028{ 3058{
3029 LPFC_MBOXQ_t *pmb; 3059 LPFC_MBOXQ_t *pmb;
3030 uint32_t resetcount = 0, rc = 0, done = 0; 3060 uint32_t resetcount = 0, rc = 0, done = 0;
@@ -3165,13 +3195,14 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
3165 break; 3195 break;
3166 } 3196 }
3167 3197
3168 rc = lpfc_do_config_port(phba, mode); 3198 rc = lpfc_sli_config_port(phba, mode);
3199
3169 if (rc && lpfc_sli_mode == 3) 3200 if (rc && lpfc_sli_mode == 3)
3170 lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT, 3201 lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT,
3171 "1820 Unable to select SLI-3. " 3202 "1820 Unable to select SLI-3. "
3172 "Not supported by adapter.\n"); 3203 "Not supported by adapter.\n");
3173 if (rc && mode != 2) 3204 if (rc && mode != 2)
3174 rc = lpfc_do_config_port(phba, 2); 3205 rc = lpfc_sli_config_port(phba, 2);
3175 if (rc) 3206 if (rc)
3176 goto lpfc_sli_hba_setup_error; 3207 goto lpfc_sli_hba_setup_error;
3177 3208
@@ -3192,8 +3223,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
3192 if (rc) 3223 if (rc)
3193 goto lpfc_sli_hba_setup_error; 3224 goto lpfc_sli_hba_setup_error;
3194 3225
3195 /* Init HBQs */ 3226 /* Init HBQs */
3196
3197 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { 3227 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
3198 rc = lpfc_sli_hbq_setup(phba); 3228 rc = lpfc_sli_hbq_setup(phba);
3199 if (rc) 3229 if (rc)
@@ -5128,28 +5158,73 @@ lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba)
5128} 5158}
5129 5159
5130/** 5160/**
5131 * lpfc_intr_handler: The interrupt handler of lpfc driver. 5161 * lpfc_sli_check_eratt: check error attention events
5162 * @phba: Pointer to HBA context.
5163 *
5164 * This function is called form timer soft interrupt context to check HBA's
5165 * error attention register bit for error attention events.
5166 *
5167 * This fucntion returns 1 when there is Error Attention in the Host Attention
5168 * Register and returns 0 otherwise.
5169 **/
5170int
5171lpfc_sli_check_eratt(struct lpfc_hba *phba)
5172{
5173 uint32_t ha_copy;
5174
5175 /* If somebody is waiting to handle an eratt, don't process it
5176 * here. The brdkill function will do this.
5177 */
5178 if (phba->link_flag & LS_IGNORE_ERATT)
5179 return 0;
5180
5181 /* Check if interrupt handler handles this ERATT */
5182 spin_lock_irq(&phba->hbalock);
5183 if (phba->hba_flag & HBA_ERATT_HANDLED) {
5184 /* Interrupt handler has handled ERATT */
5185 spin_unlock_irq(&phba->hbalock);
5186 return 0;
5187 }
5188
5189 /* Read chip Host Attention (HA) register */
5190 ha_copy = readl(phba->HAregaddr);
5191 if (ha_copy & HA_ERATT) {
5192 /* Read host status register to retrieve error event */
5193 lpfc_sli_read_hs(phba);
5194 /* Set the driver HA work bitmap */
5195 phba->work_ha |= HA_ERATT;
5196 /* Indicate polling handles this ERATT */
5197 phba->hba_flag |= HBA_ERATT_HANDLED;
5198 spin_unlock_irq(&phba->hbalock);
5199 return 1;
5200 }
5201 spin_unlock_irq(&phba->hbalock);
5202 return 0;
5203}
5204
5205/**
5206 * lpfc_sp_intr_handler: The slow-path interrupt handler of lpfc driver.
5132 * @irq: Interrupt number. 5207 * @irq: Interrupt number.
5133 * @dev_id: The device context pointer. 5208 * @dev_id: The device context pointer.
5134 * 5209 *
5135 * This function is called from the PCI layer when there is 5210 * This function is directly called from the PCI layer as an interrupt
5136 * an event in the HBA which requires driver attention. When 5211 * service routine when the device is enabled with MSI-X multi-message
5137 * the PCI slot is in error recovery or the HBA is undergoing 5212 * interrupt mode and there are slow-path events in the HBA. However,
5138 * initialization the interrupt handler will not process the 5213 * when the device is enabled with either MSI or Pin-IRQ interrupt mode,
5139 * interrupt. 5214 * this function is called as part of the device-level interrupt handler.
5140 * The error attention, link attention and els ring attention 5215 * When the PCI slot is in error recovery or the HBA is undergoing
5141 * events are handled by the worker thread. The interrupt 5216 * initialization, the interrupt handler will not process the interrupt.
5142 * handler signals the worker thread and returns for these 5217 * The link attention and ELS ring attention events are handled by the
5143 * events. 5218 * worker thread. The interrupt handler signals the worker thread and
5144 * The SCSI ring event and mailbox events are handled in the 5219 * and returns for these events. This function is called without any
5145 * interrupt context. 5220 * lock held. It gets the hbalock to access and update SLI data
5146 * This function is called without any lock held. It gets the 5221 * structures.
5147 * hbalock to access and update SLI data structures. 5222 *
5148 * This function returns IRQ_HANDLED when interrupt is handled 5223 * This function returns IRQ_HANDLED when interrupt is handled else it
5149 * else it returns IRQ_NONE. 5224 * returns IRQ_NONE.
5150 **/ 5225 **/
5151irqreturn_t 5226irqreturn_t
5152lpfc_intr_handler(int irq, void *dev_id) 5227lpfc_sp_intr_handler(int irq, void *dev_id)
5153{ 5228{
5154 struct lpfc_hba *phba; 5229 struct lpfc_hba *phba;
5155 uint32_t ha_copy; 5230 uint32_t ha_copy;
@@ -5168,54 +5243,52 @@ lpfc_intr_handler(int irq, void *dev_id)
5168 * Get the driver's phba structure from the dev_id and 5243 * Get the driver's phba structure from the dev_id and
5169 * assume the HBA is not interrupting. 5244 * assume the HBA is not interrupting.
5170 */ 5245 */
5171 phba = (struct lpfc_hba *) dev_id; 5246 phba = (struct lpfc_hba *)dev_id;
5172 5247
5173 if (unlikely(!phba)) 5248 if (unlikely(!phba))
5174 return IRQ_NONE; 5249 return IRQ_NONE;
5175 5250
5176 /* If the pci channel is offline, ignore all the interrupts. */
5177 if (unlikely(pci_channel_offline(phba->pcidev)))
5178 return IRQ_NONE;
5179
5180 phba->sli.slistat.sli_intr++;
5181
5182 /* 5251 /*
5183 * Call the HBA to see if it is interrupting. If not, don't claim 5252 * Stuff needs to be attented to when this function is invoked as an
5184 * the interrupt 5253 * individual interrupt handler in MSI-X multi-message interrupt mode
5185 */ 5254 */
5186 5255 if (phba->intr_type == MSIX) {
5187 /* Ignore all interrupts during initialization. */ 5256 /* If the pci channel is offline, ignore all the interrupts */
5188 if (unlikely(phba->link_state < LPFC_LINK_DOWN)) 5257 if (unlikely(pci_channel_offline(phba->pcidev)))
5189 return IRQ_NONE; 5258 return IRQ_NONE;
5190 5259 /* Update device-level interrupt statistics */
5191 /* 5260 phba->sli.slistat.sli_intr++;
5192 * Read host attention register to determine interrupt source 5261 /* Ignore all interrupts during initialization. */
5193 * Clear Attention Sources, except Error Attention (to 5262 if (unlikely(phba->link_state < LPFC_LINK_DOWN))
5194 * preserve status) and Link Attention 5263 return IRQ_NONE;
5195 */ 5264 /* Need to read HA REG for slow-path events */
5196 spin_lock(&phba->hbalock); 5265 spin_lock(&phba->hbalock);
5197 if (phba->sli3_options & LPFC_SLI3_INB_ENABLED &&
5198 (phba->inb_last_counter != *phba->inb_counter)) {
5199 phba->inb_last_counter = *phba->inb_counter;
5200 ha_copy = le32_to_cpu(*phba->inb_ha_copy);
5201 } else
5202 ha_copy = readl(phba->HAregaddr); 5266 ha_copy = readl(phba->HAregaddr);
5203 if (unlikely(!ha_copy)) { 5267 /* If somebody is waiting to handle an eratt don't process it
5268 * here. The brdkill function will do this.
5269 */
5270 if (phba->link_flag & LS_IGNORE_ERATT)
5271 ha_copy &= ~HA_ERATT;
5272 /* Check the need for handling ERATT in interrupt handler */
5273 if (ha_copy & HA_ERATT) {
5274 if (phba->hba_flag & HBA_ERATT_HANDLED)
5275 /* ERATT polling has handled ERATT */
5276 ha_copy &= ~HA_ERATT;
5277 else
5278 /* Indicate interrupt handler handles ERATT */
5279 phba->hba_flag |= HBA_ERATT_HANDLED;
5280 }
5281 /* Clear up only attention source related to slow-path */
5282 writel((ha_copy & (HA_MBATT | HA_R2_CLR_MSK)),
5283 phba->HAregaddr);
5284 readl(phba->HAregaddr); /* flush */
5204 spin_unlock(&phba->hbalock); 5285 spin_unlock(&phba->hbalock);
5205 return IRQ_NONE; 5286 } else
5206 } 5287 ha_copy = phba->ha_copy;
5207 /* If somebody is waiting to handle an eratt don't process it
5208 * here. The brdkill function will do this.
5209 */
5210 if (phba->link_flag & LS_IGNORE_ERATT)
5211 ha_copy &= ~HA_ERATT;
5212 writel((ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr);
5213 readl(phba->HAregaddr); /* flush */
5214 spin_unlock(&phba->hbalock);
5215 5288
5216 work_ha_copy = ha_copy & phba->work_ha_mask; 5289 work_ha_copy = ha_copy & phba->work_ha_mask;
5217 5290
5218 if (unlikely(work_ha_copy)) { 5291 if (work_ha_copy) {
5219 if (work_ha_copy & HA_LATT) { 5292 if (work_ha_copy & HA_LATT) {
5220 if (phba->sli.sli_flag & LPFC_PROCESS_LA) { 5293 if (phba->sli.sli_flag & LPFC_PROCESS_LA) {
5221 /* 5294 /*
@@ -5234,7 +5307,7 @@ lpfc_intr_handler(int irq, void *dev_id)
5234 work_ha_copy &= ~HA_LATT; 5307 work_ha_copy &= ~HA_LATT;
5235 } 5308 }
5236 5309
5237 if (work_ha_copy & ~(HA_ERATT|HA_MBATT|HA_LATT)) { 5310 if (work_ha_copy & ~(HA_ERATT | HA_MBATT | HA_LATT)) {
5238 /* 5311 /*
5239 * Turn off Slow Rings interrupts, LPFC_ELS_RING is 5312 * Turn off Slow Rings interrupts, LPFC_ELS_RING is
5240 * the only slow ring. 5313 * the only slow ring.
@@ -5275,28 +5348,10 @@ lpfc_intr_handler(int irq, void *dev_id)
5275 spin_unlock(&phba->hbalock); 5348 spin_unlock(&phba->hbalock);
5276 } 5349 }
5277 } 5350 }
5278
5279 if (work_ha_copy & HA_ERATT) {
5280 /*
5281 * There was a link/board error. Read the
5282 * status register to retrieve the error event
5283 * and process it.
5284 */
5285 phba->sli.slistat.err_attn_event++;
5286 /* Save status info */
5287 phba->work_hs = readl(phba->HSregaddr);
5288 phba->work_status[0] = readl(phba->MBslimaddr + 0xa8);
5289 phba->work_status[1] = readl(phba->MBslimaddr + 0xac);
5290
5291 /* Clear Chip error bit */
5292 writel(HA_ERATT, phba->HAregaddr);
5293 readl(phba->HAregaddr); /* flush */
5294 phba->pport->stopped = 1;
5295 }
5296
5297 spin_lock(&phba->hbalock); 5351 spin_lock(&phba->hbalock);
5298 if ((work_ha_copy & HA_MBATT) && 5352 if (work_ha_copy & HA_ERATT)
5299 (phba->sli.mbox_active)) { 5353 lpfc_sli_read_hs(phba);
5354 if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active)) {
5300 pmb = phba->sli.mbox_active; 5355 pmb = phba->sli.mbox_active;
5301 pmbox = &pmb->mb; 5356 pmbox = &pmb->mb;
5302 mbox = phba->mbox; 5357 mbox = phba->mbox;
@@ -5379,6 +5434,7 @@ lpfc_intr_handler(int irq, void *dev_id)
5379 } 5434 }
5380 } else 5435 } else
5381 spin_unlock(&phba->hbalock); 5436 spin_unlock(&phba->hbalock);
5437
5382 if ((work_ha_copy & HA_MBATT) && 5438 if ((work_ha_copy & HA_MBATT) &&
5383 (phba->sli.mbox_active == NULL)) { 5439 (phba->sli.mbox_active == NULL)) {
5384send_current_mbox: 5440send_current_mbox:
@@ -5398,15 +5454,74 @@ send_current_mbox:
5398 spin_unlock(&phba->hbalock); 5454 spin_unlock(&phba->hbalock);
5399 lpfc_worker_wake_up(phba); 5455 lpfc_worker_wake_up(phba);
5400 } 5456 }
5457 return IRQ_HANDLED;
5401 5458
5402 ha_copy &= ~(phba->work_ha_mask); 5459} /* lpfc_sp_intr_handler */
5460
5461/**
5462 * lpfc_fp_intr_handler: The fast-path interrupt handler of lpfc driver.
5463 * @irq: Interrupt number.
5464 * @dev_id: The device context pointer.
5465 *
5466 * This function is directly called from the PCI layer as an interrupt
5467 * service routine when the device is enabled with MSI-X multi-message
5468 * interrupt mode and there is a fast-path FCP IOCB ring event in the
5469 * HBA. However, when the device is enabled with either MSI or Pin-IRQ
5470 * interrupt mode, this function is called as part of the device-level
5471 * interrupt handler. When the PCI slot is in error recovery or the HBA
5472 * is undergoing initialization, the interrupt handler will not process
5473 * the interrupt. The SCSI FCP fast-path ring event are handled in the
5474 * intrrupt context. This function is called without any lock held. It
5475 * gets the hbalock to access and update SLI data structures.
5476 *
5477 * This function returns IRQ_HANDLED when interrupt is handled else it
5478 * returns IRQ_NONE.
5479 **/
5480irqreturn_t
5481lpfc_fp_intr_handler(int irq, void *dev_id)
5482{
5483 struct lpfc_hba *phba;
5484 uint32_t ha_copy;
5485 unsigned long status;
5486
5487 /* Get the driver's phba structure from the dev_id and
5488 * assume the HBA is not interrupting.
5489 */
5490 phba = (struct lpfc_hba *) dev_id;
5491
5492 if (unlikely(!phba))
5493 return IRQ_NONE;
5494
5495 /*
5496 * Stuff needs to be attented to when this function is invoked as an
5497 * individual interrupt handler in MSI-X multi-message interrupt mode
5498 */
5499 if (phba->intr_type == MSIX) {
5500 /* If pci channel is offline, ignore all the interrupts */
5501 if (unlikely(pci_channel_offline(phba->pcidev)))
5502 return IRQ_NONE;
5503 /* Update device-level interrupt statistics */
5504 phba->sli.slistat.sli_intr++;
5505 /* Ignore all interrupts during initialization. */
5506 if (unlikely(phba->link_state < LPFC_LINK_DOWN))
5507 return IRQ_NONE;
5508 /* Need to read HA REG for FCP ring and other ring events */
5509 ha_copy = readl(phba->HAregaddr);
5510 /* Clear up only attention source related to fast-path */
5511 spin_lock(&phba->hbalock);
5512 writel((ha_copy & (HA_R0_CLR_MSK | HA_R1_CLR_MSK)),
5513 phba->HAregaddr);
5514 readl(phba->HAregaddr); /* flush */
5515 spin_unlock(&phba->hbalock);
5516 } else
5517 ha_copy = phba->ha_copy;
5403 5518
5404 /* 5519 /*
5405 * Process all events on FCP ring. Take the optimized path for 5520 * Process all events on FCP ring. Take the optimized path for FCP IO.
5406 * FCP IO. Any other IO is slow path and is handled by
5407 * the worker thread.
5408 */ 5521 */
5409 status = (ha_copy & (HA_RXMASK << (4*LPFC_FCP_RING))); 5522 ha_copy &= ~(phba->work_ha_mask);
5523
5524 status = (ha_copy & (HA_RXMASK << (4*LPFC_FCP_RING)));
5410 status >>= (4*LPFC_FCP_RING); 5525 status >>= (4*LPFC_FCP_RING);
5411 if (status & HA_RXMASK) 5526 if (status & HA_RXMASK)
5412 lpfc_sli_handle_fast_ring_event(phba, 5527 lpfc_sli_handle_fast_ring_event(phba,
@@ -5415,11 +5530,10 @@ send_current_mbox:
5415 5530
5416 if (phba->cfg_multi_ring_support == 2) { 5531 if (phba->cfg_multi_ring_support == 2) {
5417 /* 5532 /*
5418 * Process all events on extra ring. Take the optimized path 5533 * Process all events on extra ring. Take the optimized path
5419 * for extra ring IO. Any other IO is slow path and is handled 5534 * for extra ring IO.
5420 * by the worker thread.
5421 */ 5535 */
5422 status = (ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING))); 5536 status = (ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING)));
5423 status >>= (4*LPFC_EXTRA_RING); 5537 status >>= (4*LPFC_EXTRA_RING);
5424 if (status & HA_RXMASK) { 5538 if (status & HA_RXMASK) {
5425 lpfc_sli_handle_fast_ring_event(phba, 5539 lpfc_sli_handle_fast_ring_event(phba,
@@ -5428,5 +5542,106 @@ send_current_mbox:
5428 } 5542 }
5429 } 5543 }
5430 return IRQ_HANDLED; 5544 return IRQ_HANDLED;
5545} /* lpfc_fp_intr_handler */
5546
5547/**
5548 * lpfc_intr_handler: The device-level interrupt handler of lpfc driver.
5549 * @irq: Interrupt number.
5550 * @dev_id: The device context pointer.
5551 *
5552 * This function is the device-level interrupt handler called from the PCI
5553 * layer when either MSI or Pin-IRQ interrupt mode is enabled and there is
5554 * an event in the HBA which requires driver attention. This function
5555 * invokes the slow-path interrupt attention handling function and fast-path
5556 * interrupt attention handling function in turn to process the relevant
5557 * HBA attention events. This function is called without any lock held. It
5558 * gets the hbalock to access and update SLI data structures.
5559 *
5560 * This function returns IRQ_HANDLED when interrupt is handled, else it
5561 * returns IRQ_NONE.
5562 **/
5563irqreturn_t
5564lpfc_intr_handler(int irq, void *dev_id)
5565{
5566 struct lpfc_hba *phba;
5567 irqreturn_t sp_irq_rc, fp_irq_rc;
5568 unsigned long status1, status2;
5569
5570 /*
5571 * Get the driver's phba structure from the dev_id and
5572 * assume the HBA is not interrupting.
5573 */
5574 phba = (struct lpfc_hba *) dev_id;
5575
5576 if (unlikely(!phba))
5577 return IRQ_NONE;
5578
5579 /* If the pci channel is offline, ignore all the interrupts. */
5580 if (unlikely(pci_channel_offline(phba->pcidev)))
5581 return IRQ_NONE;
5582
5583 /* Update device level interrupt statistics */
5584 phba->sli.slistat.sli_intr++;
5585
5586 /* Ignore all interrupts during initialization. */
5587 if (unlikely(phba->link_state < LPFC_LINK_DOWN))
5588 return IRQ_NONE;
5589
5590 spin_lock(&phba->hbalock);
5591 phba->ha_copy = readl(phba->HAregaddr);
5592 if (unlikely(!phba->ha_copy)) {
5593 spin_unlock(&phba->hbalock);
5594 return IRQ_NONE;
5595 } else if (phba->ha_copy & HA_ERATT) {
5596 if (phba->hba_flag & HBA_ERATT_HANDLED)
5597 /* ERATT polling has handled ERATT */
5598 phba->ha_copy &= ~HA_ERATT;
5599 else
5600 /* Indicate interrupt handler handles ERATT */
5601 phba->hba_flag |= HBA_ERATT_HANDLED;
5602 }
5603
5604 /* Clear attention sources except link and error attentions */
5605 writel((phba->ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr);
5606 readl(phba->HAregaddr); /* flush */
5607 spin_unlock(&phba->hbalock);
5608
5609 /*
5610 * Invokes slow-path host attention interrupt handling as appropriate.
5611 */
5612
5613 /* status of events with mailbox and link attention */
5614 status1 = phba->ha_copy & (HA_MBATT | HA_LATT | HA_ERATT);
5615
5616 /* status of events with ELS ring */
5617 status2 = (phba->ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING)));
5618 status2 >>= (4*LPFC_ELS_RING);
5619
5620 if (status1 || (status2 & HA_RXMASK))
5621 sp_irq_rc = lpfc_sp_intr_handler(irq, dev_id);
5622 else
5623 sp_irq_rc = IRQ_NONE;
5624
5625 /*
5626 * Invoke fast-path host attention interrupt handling as appropriate.
5627 */
5628
5629 /* status of events with FCP ring */
5630 status1 = (phba->ha_copy & (HA_RXMASK << (4*LPFC_FCP_RING)));
5631 status1 >>= (4*LPFC_FCP_RING);
5632
5633 /* status of events with extra ring */
5634 if (phba->cfg_multi_ring_support == 2) {
5635 status2 = (phba->ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING)));
5636 status2 >>= (4*LPFC_EXTRA_RING);
5637 } else
5638 status2 = 0;
5639
5640 if ((status1 & HA_RXMASK) || (status2 & HA_RXMASK))
5641 fp_irq_rc = lpfc_fp_intr_handler(irq, dev_id);
5642 else
5643 fp_irq_rc = IRQ_NONE;
5431 5644
5432} /* lpfc_intr_handler */ 5645 /* Return device-level interrupt handling status */
5646 return (sp_irq_rc == IRQ_HANDLED) ? sp_irq_rc : fp_irq_rc;
5647} /* lpfc_intr_handler */
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index ad24cacfbe10..1a62e57a6a2d 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,9 @@
20 20
21#define LPFC_DRIVER_VERSION "8.2.7" 21#define LPFC_DRIVER_VERSION "8.2.7"
22 22
23#define LPFC_DRIVER_NAME "lpfc" 23#define LPFC_DRIVER_NAME "lpfc"
24#define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp"
25#define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp"
24 26
25#define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ 27#define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \
26 LPFC_DRIVER_VERSION 28 LPFC_DRIVER_VERSION