Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] lpfc 8.3.0 : Added 3 small features and improve PCI EEH support

- Added FC_REG_VPORTRSCN_EVENT to lpfc_nl.h

- Added code to provide option ROM version from HBA and via sysfs

- Added support for HPS bit in config port mailbox command to tell HBA
that host group pointers are in host memory.

- Bugfix for Extended Error Handling (EEH) support on IBM PowerPC P6
platform with MSI enabled

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

authored by

James Smart and committed by
James Bottomley
97207482 eada272d

+139 -11
+1
drivers/scsi/lpfc/lpfc_crtn.h
··· 22 22 23 23 struct fc_rport; 24 24 void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); 25 + void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *); 25 26 void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); 26 27 void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); 27 28
+34 -3
drivers/scsi/lpfc/lpfc_hw.h
··· 2362 2362 #define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */ 2363 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 */ 2369 + struct 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 2389 /* Structure for MB Command UPDATE_CFG (0x1B) */ 2366 2390 2367 2391 struct update_cfg_var { ··· 2579 2555 2580 2556 uint32_t pcbLow; /* bit 31:0 of memory based port config block */ 2581 2557 uint32_t pcbHigh; /* bit 63:32 of memory based port config block */ 2582 - uint32_t hbainit[6]; 2558 + uint32_t hbainit[5]; 2559 + #ifdef __BIG_ENDIAN_BITFIELD 2560 + uint32_t hps : 1; /* bit 31 word9 Host Pointer in slim */ 2561 + uint32_t rsvd : 31; /* least significant 31 bits of word 9 */ 2562 + #else /* __LITTLE_ENDIAN */ 2563 + uint32_t rsvd : 31; /* least significant 31 bits of word 9 */ 2564 + uint32_t hps : 1; /* bit 31 word9 Host Pointer in slim */ 2565 + #endif 2583 2566 2584 2567 #ifdef __BIG_ENDIAN_BITFIELD 2585 - uint32_t rsvd : 24; /* Reserved */ 2568 + uint32_t rsvd1 : 24; /* Reserved */ 2586 2569 uint32_t cmv : 1; /* Configure Max VPIs */ 2587 2570 uint32_t ccrp : 1; /* Config Command Ring Polling */ 2588 2571 uint32_t csah : 1; /* Configure Synchronous Abort Handling */ ··· 2607 2576 uint32_t csah : 1; /* Configure Synchronous Abort Handling */ 2608 2577 uint32_t ccrp : 1; /* Config Command Ring Polling */ 2609 2578 uint32_t cmv : 1; /* Configure Max VPIs */ 2610 - uint32_t rsvd : 24; /* Reserved */ 2579 + uint32_t rsvd1 : 24; /* Reserved */ 2611 2580 #endif 2612 2581 #ifdef __BIG_ENDIAN_BITFIELD 2613 2582 uint32_t rsvd2 : 24; /* Reserved */
+60 -1
drivers/scsi/lpfc/lpfc_init.c
··· 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 + **/ 249 + static void 250 + lpfc_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 281 * lpfc_config_port_post: Perform lpfc initialization after config port. 240 282 * @phba: pointer to lpfc hba data structure. 241 283 * ··· 524 482 rc); 525 483 mempool_free(pmb, phba->mbox_mem_pool); 526 484 } 485 + 486 + /* Get Option rom version */ 487 + pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 488 + lpfc_dump_wakeup_param(phba, pmb); 489 + pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl; 490 + pmb->vport = phba->pport; 491 + rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); 492 + 493 + if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 494 + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0435 Adapter failed " 495 + "to get Option ROM version status x%x\n.", rc); 496 + mempool_free(pmb, phba->mbox_mem_pool); 497 + } 498 + 527 499 return 0; 528 500 } 529 501 ··· 2462 2406 phba->eratt_poll.data = (unsigned long) phba; 2463 2407 2464 2408 pci_set_master(pdev); 2409 + pci_save_state(pdev); 2465 2410 pci_try_set_mwi(pdev); 2466 2411 2467 2412 if (pci_set_dma_mask(phba->pcidev, DMA_64BIT_MASK) != 0) ··· 3039 2982 return PCI_ERS_RESULT_DISCONNECT; 3040 2983 } 3041 2984 3042 - pci_set_master(pdev); 2985 + pci_restore_state(pdev); 2986 + if (pdev->is_busmaster) 2987 + pci_set_master(pdev); 3043 2988 3044 2989 spin_lock_irq(&phba->hbalock); 3045 2990 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
+35
drivers/scsi/lpfc/lpfc_mbox.c
··· 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 + */ 86 + void 87 + lpfc_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 112 * lpfc_read_nv: Prepare a mailbox command for reading HBA's NVRAM param. 81 113 * @phba: pointer to lpfc hba data structure. 82 114 * @pmb: pointer to the driver internal queue element for mailbox command. ··· 1092 1060 pdma_addr = phba->slim2p.phys + offset; 1093 1061 mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr); 1094 1062 mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr); 1063 + 1064 + /* Always Host Group Pointer is in SLIM */ 1065 + mb->un.varCfgPort.hps = 1; 1095 1066 1096 1067 /* If HBA supports SLI=3 ask for it */ 1097 1068
+9 -7
drivers/scsi/lpfc/lpfc_nl.h
··· 22 22 #define FC_REG_LINK_EVENT 0x0001 /* link up / down events */ 23 23 #define FC_REG_RSCN_EVENT 0x0002 /* RSCN events */ 24 24 #define FC_REG_CT_EVENT 0x0004 /* CT request events */ 25 - #define FC_REG_DUMP_EVENT 0x0008 /* Dump events */ 26 - #define FC_REG_TEMPERATURE_EVENT 0x0010 /* temperature events */ 27 - #define FC_REG_ELS_EVENT 0x0020 /* lpfc els events */ 28 - #define FC_REG_FABRIC_EVENT 0x0040 /* lpfc fabric events */ 29 - #define FC_REG_SCSI_EVENT 0x0080 /* lpfc scsi events */ 30 - #define FC_REG_BOARD_EVENT 0x0100 /* lpfc board events */ 31 - #define FC_REG_ADAPTER_EVENT 0x0200 /* lpfc adapter events */ 25 + #define FC_REG_DUMP_EVENT 0x0010 /* Dump events */ 26 + #define FC_REG_TEMPERATURE_EVENT 0x0020 /* temperature events */ 27 + #define FC_REG_VPORTRSCN_EVENT 0x0040 /* Vport RSCN events */ 28 + #define FC_REG_ELS_EVENT 0x0080 /* lpfc els events */ 29 + #define FC_REG_FABRIC_EVENT 0x0100 /* lpfc fabric events */ 30 + #define FC_REG_SCSI_EVENT 0x0200 /* lpfc scsi events */ 31 + #define FC_REG_BOARD_EVENT 0x0400 /* lpfc board events */ 32 + #define FC_REG_ADAPTER_EVENT 0x0800 /* lpfc adapter events */ 32 33 #define FC_REG_EVENT_MASK (FC_REG_LINK_EVENT | \ 33 34 FC_REG_RSCN_EVENT | \ 34 35 FC_REG_CT_EVENT | \ 35 36 FC_REG_DUMP_EVENT | \ 36 37 FC_REG_TEMPERATURE_EVENT | \ 38 + FC_REG_VPORTRSCN_EVENT | \ 37 39 FC_REG_ELS_EVENT | \ 38 40 FC_REG_FABRIC_EVENT | \ 39 41 FC_REG_SCSI_EVENT | \