aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h37
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c61
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c35
-rw-r--r--drivers/scsi/lpfc/lpfc_nl.h16
5 files changed, 139 insertions, 11 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 044ef4057d28..a6594857712e 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -22,6 +22,7 @@ typedef 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);
25void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *);
25void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); 26void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
26void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); 27void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
27 28
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 81d1df418e47..4b5c12440b83 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -2362,6 +2362,30 @@ typedef struct {
2362#define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */ 2362#define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */
2363#define DMP_RSP_SIZE 0x6C /* maximum of 27 words of rsp data */ 2363#define DMP_RSP_SIZE 0x6C /* maximum of 27 words of rsp data */
2364 2364
2365#define WAKE_UP_PARMS_REGION_ID 4
2366#define WAKE_UP_PARMS_WORD_SIZE 15
2367
2368/* Option rom version structure */
2369struct prog_id {
2370#ifdef __BIG_ENDIAN_BITFIELD
2371 uint8_t type;
2372 uint8_t id;
2373 uint32_t ver:4; /* Major Version */
2374 uint32_t rev:4; /* Revision */
2375 uint32_t lev:2; /* Level */
2376 uint32_t dist:2; /* Dist Type */
2377 uint32_t num:4; /* number after dist type */
2378#else /* __LITTLE_ENDIAN_BITFIELD */
2379 uint32_t num:4; /* number after dist type */
2380 uint32_t dist:2; /* Dist Type */
2381 uint32_t lev:2; /* Level */
2382 uint32_t rev:4; /* Revision */
2383 uint32_t ver:4; /* Major Version */
2384 uint8_t id;
2385 uint8_t type;
2386#endif
2387};
2388
2365/* Structure for MB Command UPDATE_CFG (0x1B) */ 2389/* Structure for MB Command UPDATE_CFG (0x1B) */
2366 2390
2367struct update_cfg_var { 2391struct update_cfg_var {
@@ -2555,10 +2579,17 @@ typedef struct {
2555 2579
2556 uint32_t pcbLow; /* bit 31:0 of memory based port config block */ 2580 uint32_t pcbLow; /* bit 31:0 of memory based port config block */
2557 uint32_t pcbHigh; /* bit 63:32 of memory based port config block */ 2581 uint32_t pcbHigh; /* bit 63:32 of memory based port config block */
2558 uint32_t hbainit[6]; 2582 uint32_t hbainit[5];
2583#ifdef __BIG_ENDIAN_BITFIELD
2584 uint32_t hps : 1; /* bit 31 word9 Host Pointer in slim */
2585 uint32_t rsvd : 31; /* least significant 31 bits of word 9 */
2586#else /* __LITTLE_ENDIAN */
2587 uint32_t rsvd : 31; /* least significant 31 bits of word 9 */
2588 uint32_t hps : 1; /* bit 31 word9 Host Pointer in slim */
2589#endif
2559 2590
2560#ifdef __BIG_ENDIAN_BITFIELD 2591#ifdef __BIG_ENDIAN_BITFIELD
2561 uint32_t rsvd : 24; /* Reserved */ 2592 uint32_t rsvd1 : 24; /* Reserved */
2562 uint32_t cmv : 1; /* Configure Max VPIs */ 2593 uint32_t cmv : 1; /* Configure Max VPIs */
2563 uint32_t ccrp : 1; /* Config Command Ring Polling */ 2594 uint32_t ccrp : 1; /* Config Command Ring Polling */
2564 uint32_t csah : 1; /* Configure Synchronous Abort Handling */ 2595 uint32_t csah : 1; /* Configure Synchronous Abort Handling */
@@ -2576,7 +2607,7 @@ typedef struct {
2576 uint32_t csah : 1; /* Configure Synchronous Abort Handling */ 2607 uint32_t csah : 1; /* Configure Synchronous Abort Handling */
2577 uint32_t ccrp : 1; /* Config Command Ring Polling */ 2608 uint32_t ccrp : 1; /* Config Command Ring Polling */
2578 uint32_t cmv : 1; /* Configure Max VPIs */ 2609 uint32_t cmv : 1; /* Configure Max VPIs */
2579 uint32_t rsvd : 24; /* Reserved */ 2610 uint32_t rsvd1 : 24; /* Reserved */
2580#endif 2611#endif
2581#ifdef __BIG_ENDIAN_BITFIELD 2612#ifdef __BIG_ENDIAN_BITFIELD
2582 uint32_t rsvd2 : 24; /* Reserved */ 2613 uint32_t rsvd2 : 24; /* Reserved */
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 56ed5282117c..64e3d344f4dd 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -236,6 +236,48 @@ lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
236} 236}
237 237
238/** 238/**
239 * lpfc_dump_wakeup_param_cmpl: Completion handler for dump memory mailbox
240 * command used for getting wake up parameters.
241 * @phba: pointer to lpfc hba data structure.
242 * @pmboxq: pointer to the driver internal queue element for mailbox command.
243 *
244 * This is the completion handler for dump mailbox command for getting
245 * wake up parameters. When this command complete, the response contain
246 * Option rom version of the HBA. This function translate the version number
247 * into a human readable string and store it in OptionROMVersion.
248 **/
249static void
250lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
251{
252 struct prog_id *prg;
253 uint32_t prog_id_word;
254 char dist = ' ';
255 /* character array used for decoding dist type. */
256 char dist_char[] = "nabx";
257
258 if (pmboxq->mb.mbxStatus != MBX_SUCCESS)
259 return;
260
261 prg = (struct prog_id *) &prog_id_word;
262
263 /* word 7 contain option rom version */
264 prog_id_word = pmboxq->mb.un.varWords[7];
265
266 /* Decode the Option rom version word to a readable string */
267 if (prg->dist < 4)
268 dist = dist_char[prg->dist];
269
270 if ((prg->dist == 3) && (prg->num == 0))
271 sprintf(phba->OptionROMVersion, "%d.%d%d",
272 prg->ver, prg->rev, prg->lev);
273 else
274 sprintf(phba->OptionROMVersion, "%d.%d%d%c%d",
275 prg->ver, prg->rev, prg->lev,
276 dist, prg->num);
277 return;
278}
279
280/**
239 * lpfc_config_port_post: Perform lpfc initialization after config port. 281 * lpfc_config_port_post: Perform lpfc initialization after config port.
240 * @phba: pointer to lpfc hba data structure. 282 * @phba: pointer to lpfc hba data structure.
241 * 283 *
@@ -482,6 +524,20 @@ lpfc_config_port_post(struct lpfc_hba *phba)
482 rc); 524 rc);
483 mempool_free(pmb, phba->mbox_mem_pool); 525 mempool_free(pmb, phba->mbox_mem_pool);
484 } 526 }
527
528 /* Get Option rom version */
529 pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
530 lpfc_dump_wakeup_param(phba, pmb);
531 pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl;
532 pmb->vport = phba->pport;
533 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
534
535 if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
536 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0435 Adapter failed "
537 "to get Option ROM version status x%x\n.", rc);
538 mempool_free(pmb, phba->mbox_mem_pool);
539 }
540
485 return 0; 541 return 0;
486} 542}
487 543
@@ -2406,6 +2462,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
2406 phba->eratt_poll.data = (unsigned long) phba; 2462 phba->eratt_poll.data = (unsigned long) phba;
2407 2463
2408 pci_set_master(pdev); 2464 pci_set_master(pdev);
2465 pci_save_state(pdev);
2409 pci_try_set_mwi(pdev); 2466 pci_try_set_mwi(pdev);
2410 2467
2411 if (pci_set_dma_mask(phba->pcidev, DMA_64BIT_MASK) != 0) 2468 if (pci_set_dma_mask(phba->pcidev, DMA_64BIT_MASK) != 0)
@@ -2982,7 +3039,9 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
2982 return PCI_ERS_RESULT_DISCONNECT; 3039 return PCI_ERS_RESULT_DISCONNECT;
2983 } 3040 }
2984 3041
2985 pci_set_master(pdev); 3042 pci_restore_state(pdev);
3043 if (pdev->is_busmaster)
3044 pci_set_master(pdev);
2986 3045
2987 spin_lock_irq(&phba->hbalock); 3046 spin_lock_irq(&phba->hbalock);
2988 psli->sli_flag &= ~LPFC_SLI2_ACTIVE; 3047 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 7465fe746fe9..dcdb7c939520 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -77,6 +77,38 @@ lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset)
77} 77}
78 78
79/** 79/**
80 * lpfc_dump_mem: Prepare a mailbox command for retrieving wakeup params.
81 * @phba: pointer to lpfc hba data structure.
82 * @pmb: pointer to the driver internal queue element for mailbox command.
83 * This function create a dump memory mailbox command to dump wake up
84 * parameters.
85 */
86void
87lpfc_dump_wakeup_param(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
88{
89 MAILBOX_t *mb;
90 void *ctx;
91
92 mb = &pmb->mb;
93 /* Save context so that we can restore after memset */
94 ctx = pmb->context2;
95
96 /* Setup to dump VPD region */
97 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
98 mb->mbxCommand = MBX_DUMP_MEMORY;
99 mb->mbxOwner = OWN_HOST;
100 mb->un.varDmp.cv = 1;
101 mb->un.varDmp.type = DMP_NV_PARAMS;
102 mb->un.varDmp.entry_index = 0;
103 mb->un.varDmp.region_id = WAKE_UP_PARMS_REGION_ID;
104 mb->un.varDmp.word_cnt = WAKE_UP_PARMS_WORD_SIZE;
105 mb->un.varDmp.co = 0;
106 mb->un.varDmp.resp_offset = 0;
107 pmb->context2 = ctx;
108 return;
109}
110
111/**
80 * lpfc_read_nv: Prepare a mailbox command for reading HBA's NVRAM param. 112 * lpfc_read_nv: Prepare a mailbox command for reading HBA's NVRAM param.
81 * @phba: pointer to lpfc hba data structure. 113 * @phba: pointer to lpfc hba data structure.
82 * @pmb: pointer to the driver internal queue element for mailbox command. 114 * @pmb: pointer to the driver internal queue element for mailbox command.
@@ -1061,6 +1093,9 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1061 mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr); 1093 mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
1062 mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr); 1094 mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
1063 1095
1096 /* Always Host Group Pointer is in SLIM */
1097 mb->un.varCfgPort.hps = 1;
1098
1064 /* If HBA supports SLI=3 ask for it */ 1099 /* If HBA supports SLI=3 ask for it */
1065 1100
1066 if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) { 1101 if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) {
diff --git a/drivers/scsi/lpfc/lpfc_nl.h b/drivers/scsi/lpfc/lpfc_nl.h
index 991ad53bd3ce..27d1a88a98fe 100644
--- a/drivers/scsi/lpfc/lpfc_nl.h
+++ b/drivers/scsi/lpfc/lpfc_nl.h
@@ -22,18 +22,20 @@
22#define FC_REG_LINK_EVENT 0x0001 /* link up / down events */ 22#define FC_REG_LINK_EVENT 0x0001 /* link up / down events */
23#define FC_REG_RSCN_EVENT 0x0002 /* RSCN events */ 23#define FC_REG_RSCN_EVENT 0x0002 /* RSCN events */
24#define FC_REG_CT_EVENT 0x0004 /* CT request events */ 24#define FC_REG_CT_EVENT 0x0004 /* CT request events */
25#define FC_REG_DUMP_EVENT 0x0008 /* Dump events */ 25#define FC_REG_DUMP_EVENT 0x0010 /* Dump events */
26#define FC_REG_TEMPERATURE_EVENT 0x0010 /* temperature events */ 26#define FC_REG_TEMPERATURE_EVENT 0x0020 /* temperature events */
27#define FC_REG_ELS_EVENT 0x0020 /* lpfc els events */ 27#define FC_REG_VPORTRSCN_EVENT 0x0040 /* Vport RSCN events */
28#define FC_REG_FABRIC_EVENT 0x0040 /* lpfc fabric events */ 28#define FC_REG_ELS_EVENT 0x0080 /* lpfc els events */
29#define FC_REG_SCSI_EVENT 0x0080 /* lpfc scsi events */ 29#define FC_REG_FABRIC_EVENT 0x0100 /* lpfc fabric events */
30#define FC_REG_BOARD_EVENT 0x0100 /* lpfc board events */ 30#define FC_REG_SCSI_EVENT 0x0200 /* lpfc scsi events */
31#define FC_REG_ADAPTER_EVENT 0x0200 /* lpfc adapter events */ 31#define FC_REG_BOARD_EVENT 0x0400 /* lpfc board events */
32#define FC_REG_ADAPTER_EVENT 0x0800 /* lpfc adapter events */
32#define FC_REG_EVENT_MASK (FC_REG_LINK_EVENT | \ 33#define FC_REG_EVENT_MASK (FC_REG_LINK_EVENT | \
33 FC_REG_RSCN_EVENT | \ 34 FC_REG_RSCN_EVENT | \
34 FC_REG_CT_EVENT | \ 35 FC_REG_CT_EVENT | \
35 FC_REG_DUMP_EVENT | \ 36 FC_REG_DUMP_EVENT | \
36 FC_REG_TEMPERATURE_EVENT | \ 37 FC_REG_TEMPERATURE_EVENT | \
38 FC_REG_VPORTRSCN_EVENT | \
37 FC_REG_ELS_EVENT | \ 39 FC_REG_ELS_EVENT | \
38 FC_REG_FABRIC_EVENT | \ 40 FC_REG_FABRIC_EVENT | \
39 FC_REG_SCSI_EVENT | \ 41 FC_REG_SCSI_EVENT | \