Subject: Update lpfc to 8.2.8.4 From: Hannes Reinecke Date: Tue Oct 7 13:50:11 2008 +0200: References: bnc#420767 This patch updates the SLES 11 lpfc driver to 8.2.8.4 which has the following changes: * Changed version number to 8.2.8.4 * Added code to get option ROM version from HBA * Added support for FC_REG_VPORTRSCN_EVENT * Fix the authentication error when the initial authentication is rejected * Add the lpfc_symbolic_name back into the scsi_host attributes * Fix vport failed to create when link was down or in loop (CR 83339) * Fix authentication failures always show up an generic errors (CR 74969) * Fixed statistical data collection for virtual ports * Support changes to vport's symbolic name * Fix Vport created in disabled state doesn't have correct state * Fix vport disable attribute missing * Fix vport attributes by removing physical attributes Signed-off-by: Jamie Wellnitz Signed-off-by: Hannes Reinecke diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 10e1ac6..7508dea 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -328,6 +328,11 @@ enum auth_state { LPFC_AUTH_UNKNOWN = 0, LPFC_AUTH_SUCCESS = 1, LPFC_AUTH_FAIL = 2, + LPFC_AUTH_FAIL_ELS_TMO = 3, + LPFC_AUTH_FAIL_TRANS_TMO = 4, + LPFC_AUTH_FAIL_LS_RJT_GEN = 5, + LPFC_AUTH_FAIL_LS_RJT_BUSY = 6, + LPFC_AUTH_FAIL_AUTH_RJT = 7, }; enum auth_msg_state { LPFC_AUTH_NONE = 0, @@ -463,8 +468,6 @@ struct lpfc_vport { uint8_t load_flag; #define FC_LOADING 0x1 /* HBA in process of loading drvr */ #define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */ - char *vname; /* Application assigned name */ - /* Fields used for accessing auth service */ struct lpfc_auth auth; uint32_t sc_tran_id; diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 8e94902..1069491 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1107,6 +1107,17 @@ lpfc_auth_state_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "Not Authenticated\n"); case LPFC_AUTH_FAIL: return snprintf(buf, PAGE_SIZE, "Failed\n"); + case LPFC_AUTH_FAIL_ELS_TMO: + return snprintf(buf, PAGE_SIZE, "Failed - ELS Timeout\n"); + case LPFC_AUTH_FAIL_TRANS_TMO: + return snprintf(buf, PAGE_SIZE, "Failed - " + "Transaction Timeout\n"); + case LPFC_AUTH_FAIL_LS_RJT_GEN: + return snprintf(buf, PAGE_SIZE, "Failed - LS_RJT\n"); + case LPFC_AUTH_FAIL_LS_RJT_BUSY: + return snprintf(buf, PAGE_SIZE, "Failed - LS_RJT Busy\n"); + case LPFC_AUTH_FAIL_AUTH_RJT: + return snprintf(buf, PAGE_SIZE, "Failed - AUTH RJT\n"); case LPFC_AUTH_SUCCESS: if (vport->auth.auth_msg_state == LPFC_AUTH_NEGOTIATE || vport->auth.auth_msg_state == LPFC_DHCHAP_CHALLENGE || @@ -1665,6 +1676,20 @@ static DEVICE_ATTR(auth_hash, S_IRUGO, lpfc_auth_hash_show, NULL); static DEVICE_ATTR(auth_last, S_IRUGO, lpfc_auth_last_show, NULL); static DEVICE_ATTR(auth_next, S_IRUGO, lpfc_auth_next_show, NULL); +static ssize_t +lpfc_symbolic_name_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + int length; + char symbname[256]; + + length = lpfc_vport_symbolic_port_name(vport, symbname, 256); + return snprintf(buf, PAGE_SIZE, "%s\n", symbname); +} +static DEVICE_ATTR(lpfc_symbolic_name, S_IRUGO, lpfc_symbolic_name_show, NULL); + static int lpfc_parse_wwn(const char *ns, uint8_t *nm) { @@ -3134,6 +3159,7 @@ struct device_attribute *lpfc_hba_attrs[] = { &dev_attr_auth_hash, &dev_attr_auth_last, &dev_attr_auth_next, + &dev_attr_lpfc_symbolic_name, &dev_attr_lpfc_soft_wwnn, &dev_attr_lpfc_soft_wwpn, &dev_attr_lpfc_soft_wwn_enable, @@ -3171,7 +3197,7 @@ struct device_attribute *lpfc_vport_attrs[] = { &dev_attr_auth_hash, &dev_attr_auth_last, &dev_attr_auth_next, - + &dev_attr_lpfc_symbolic_name, &dev_attr_lpfc_max_scsicmpl_time, &dev_attr_lpfc_stat_data_ctrl, NULL, @@ -4134,25 +4160,28 @@ lpfc_alloc_sysfs_attr(struct lpfc_vport *vport) int error; error = sysfs_create_bin_file(&shost->shost_dev.kobj, - &sysfs_ctlreg_attr); - if (error) + &sysfs_drvr_stat_data_attr); + + /* Virtual ports do not need ctrl_reg and mbox */ + if (error || vport->port_type == LPFC_NPIV_PORT) goto out; error = sysfs_create_bin_file(&shost->shost_dev.kobj, - &sysfs_mbox_attr); + &sysfs_ctlreg_attr); if (error) - goto out_remove_ctlreg_attr; + goto out_remove_stat_attr; error = sysfs_create_bin_file(&shost->shost_dev.kobj, - &sysfs_drvr_stat_data_attr); + &sysfs_mbox_attr); if (error) - goto out_remove_mbox_attr; + goto out_remove_ctlreg_attr; return 0; -out_remove_mbox_attr: - sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr); out_remove_ctlreg_attr: sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr); +out_remove_stat_attr: + sysfs_remove_bin_file(&shost->shost_dev.kobj, + &sysfs_drvr_stat_data_attr); out: return error; } @@ -4167,6 +4196,9 @@ lpfc_free_sysfs_attr(struct lpfc_vport *vport) struct Scsi_Host *shost = lpfc_shost_from_vport(vport); sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_drvr_stat_data_attr); + /* Virtual ports do not need ctrl_reg and mbox */ + if (vport->port_type == LPFC_NPIV_PORT) + return; sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr); sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr); sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_menlo_attr); @@ -4645,6 +4677,23 @@ lpfc_show_rport_##field (struct device *dev, \ lpfc_rport_show_function(field, format_string, sz, ) \ static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL) +/** + * lpfc_set_vport_symbolic_name: Set the vport's symbolic name. + * @fc_vport: The fc_vport who's symbolic name has been changed. + * + * Description: + * This function is called by the transport after the @fc_vport's symbolic name + * has been changed. This function re-registers the symbolic name with the + * switch to propogate the change into the fabric if the vport is active. + **/ +static void +lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport) +{ + struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; + + if (vport->port_state == LPFC_VPORT_READY) + lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0); +} struct fc_function_template lpfc_transport_functions = { /* fixed attributes the driver supports */ @@ -4654,6 +4703,7 @@ struct fc_function_template lpfc_transport_functions = { .show_host_supported_fc4s = 1, .show_host_supported_speeds = 1, .show_host_maxframe_size = 1, + .show_host_symbolic_name = 1, /* dynamic attributes the driver supports */ .get_host_port_id = lpfc_get_host_port_id, @@ -4703,6 +4753,10 @@ struct fc_function_template lpfc_transport_functions = { .terminate_rport_io = lpfc_terminate_rport_io, .dd_fcvport_size = sizeof(struct lpfc_vport *), + + .vport_disable = lpfc_vport_disable, + + .set_vport_symbolic_name = lpfc_set_vport_symbolic_name, }; struct fc_function_template lpfc_vport_transport_functions = { @@ -4713,6 +4767,7 @@ struct fc_function_template lpfc_vport_transport_functions = { .show_host_supported_fc4s = 1, .show_host_supported_speeds = 1, .show_host_maxframe_size = 1, + .show_host_symbolic_name = 1, /* dynamic attributes the driver supports */ .get_host_port_id = lpfc_get_host_port_id, @@ -4761,6 +4816,8 @@ struct fc_function_template lpfc_vport_transport_functions = { .terminate_rport_io = lpfc_terminate_rport_io, .vport_disable = lpfc_vport_disable, + + .set_vport_symbolic_name = lpfc_set_vport_symbolic_name, }; /** @@ -4788,6 +4845,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) phba->cfg_soft_wwpn = 0L; lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt); /* Also reinitialize the host templates with new values. */ + lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; /* * Since the sg_tablesize is module parameter, the sg_dma_buf_size diff --git a/drivers/scsi/lpfc/lpfc_auth.c b/drivers/scsi/lpfc/lpfc_auth.c index 6a5da93..7dc3600 100644 --- a/drivers/scsi/lpfc/lpfc_auth.c +++ b/drivers/scsi/lpfc/lpfc_auth.c @@ -179,9 +179,8 @@ lpfc_dhchap_authenticate(struct Scsi_Host *shost, ndlp->nlp_DID); lpfc_issue_els_auth_reject(vport, ndlp, AUTH_ERR, AUTHENTICATION_FAILED); - if (vport->auth.auth_state == LPFC_AUTH_SUCCESS) { - lpfc_port_auth_failed(ndlp); - } + if (vport->auth.auth_state == LPFC_AUTH_SUCCESS) + lpfc_port_auth_failed(ndlp, LPFC_AUTH_FAIL_AUTH_RJT); } kfree(rsp); diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index a93c555..380acef 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -28,6 +28,7 @@ int lpfc_issue_els_auth_reject(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, uint8_t reason, uint8_t explanation); void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); +void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); @@ -89,7 +90,7 @@ struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t); struct lpfc_nodelist *lpfc_findnode_wwnn(struct lpfc_vport *, struct lpfc_name *); -void lpfc_port_auth_failed(struct lpfc_nodelist *); +void lpfc_port_auth_failed(struct lpfc_nodelist *, enum auth_state); void lpfc_worker_wake_up(struct lpfc_hba *); int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); int lpfc_do_work(void *); @@ -272,6 +273,7 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *); extern struct device_attribute *lpfc_hba_attrs[]; extern struct device_attribute *lpfc_vport_attrs[]; extern struct scsi_host_template lpfc_template; +extern struct scsi_host_template lpfc_vport_template; extern struct fc_function_template lpfc_transport_functions; extern struct fc_function_template lpfc_vport_transport_functions; extern int lpfc_sli_mode; diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 26dae8b..7fecdbb 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -1008,8 +1008,10 @@ lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol, if (n < size) n += snprintf(symbol + n, size - n, " VPort-%d", vport->vpi); - if (n < size && vport->vname) - n += snprintf(symbol + n, size - n, " VName-%s", vport->vname); + if (n < size && + strlen(vport->fc_vport->symbolic_name)) + n += snprintf(symbol + n, size - n, " VName-%s", + vport->fc_vport->symbolic_name); return n; } diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index a95815e..3f58a4b 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -5347,7 +5347,7 @@ lpfc_els_rcv_auth_rjt(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, "1036 Authentication transaction reject - " "re-auth request reason 0x%x exp 0x%x\n", rjt->reason, rjt->explanation); - lpfc_port_auth_failed(ndlp); + lpfc_port_auth_failed(ndlp, LPFC_AUTH_FAIL_AUTH_RJT); if (vport->auth.auth_msg_state == LPFC_DHCHAP_SUCCESS) { /* start authentication */ lpfc_start_authentication(vport, ndlp); @@ -5366,6 +5366,7 @@ lpfc_els_rcv_auth_rjt(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, "1057 Authentication transaction " "reject. reason 0x%x exp 0x%x\n", rjt->reason, rjt->explanation); + lpfc_port_auth_failed(ndlp, LPFC_AUTH_FAIL_AUTH_RJT); vport->auth.auth_msg_state = LPFC_AUTH_REJECT; if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && (phba->link_state != LPFC_CLEAR_LA)) { @@ -7040,6 +7041,8 @@ lpfc_cmpl_els_auth(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, IOCB_t *irsp = &rspiocb->iocb; struct lpfc_vport *vport = cmdiocb->vport; struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; + enum auth_state auth_state; + struct ls_rjt stat; /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(vport)) { @@ -7049,9 +7052,19 @@ lpfc_cmpl_els_auth(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } if (irsp->ulpStatus) { + auth_state = LPFC_AUTH_FAIL; if (irsp->ulpStatus == IOSTAT_LS_RJT) { + stat.un.lsRjtError = be32_to_cpu(irsp->un.ulpWord[4]); lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "1043 Authentication LS_RJT\n"); + if (stat.un.b.lsRjtRsnCode == LSRJT_LOGICAL_BSY) + auth_state = LPFC_AUTH_FAIL_LS_RJT_BUSY; + else + auth_state = LPFC_AUTH_FAIL_LS_RJT_GEN; + } else if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT && + (irsp->un.ulpWord[4] & 0xff) == + IOERR_SEQUENCE_TIMEOUT) { + auth_state = LPFC_AUTH_FAIL_ELS_TMO; } /* Check for retry */ if (!lpfc_els_retry(phba, cmdiocb, rspiocb)) { @@ -7063,7 +7076,7 @@ lpfc_cmpl_els_auth(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } if (vport->auth.auth_mode == FC_AUTHMODE_ACTIVE) { lpfc_can_disctmo(vport); - lpfc_port_auth_failed(ndlp); + lpfc_port_auth_failed(ndlp, auth_state); } } if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 502a9a5..358e9de 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -754,17 +754,18 @@ lpfc_linkdown_port(struct lpfc_vport *vport) vport->port_state, vport->fc_ns_retry, vport->fc_flag); lpfc_port_link_failure(vport); - - vport->auth.auth_state = LPFC_AUTH_UNKNOWN; - vport->auth.auth_msg_state = LPFC_AUTH_NONE; + if (vport->auth.auth_state < LPFC_AUTH_FAIL) { + vport->auth.auth_state = LPFC_AUTH_UNKNOWN; + vport->auth.auth_msg_state = LPFC_AUTH_NONE; + } } void -lpfc_port_auth_failed(struct lpfc_nodelist *ndlp) +lpfc_port_auth_failed(struct lpfc_nodelist *ndlp, enum auth_state fail_state) { struct lpfc_vport *vport = ndlp->vport; - vport->auth.auth_state = LPFC_AUTH_FAIL; + vport->auth.auth_state = fail_state; vport->auth.auth_msg_state = LPFC_AUTH_NONE; lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); if (ndlp->nlp_type & NLP_FABRIC) { @@ -886,6 +887,8 @@ lpfc_linkup_port(struct lpfc_vport *vport) if (vport->fc_flag & FC_LBIT) lpfc_linkup_cleanup_nodes(vport); + vport->auth.auth_state = LPFC_AUTH_UNKNOWN; + vport->auth.auth_msg_state = LPFC_AUTH_NONE; } static int diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 90d0c5a..c77d49e 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -2404,6 +2404,30 @@ typedef struct { #define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */ #define DMP_RSP_SIZE 0x6C /* maximum of 27 words of rsp data */ +#define WAKE_UP_PARMS_REGION_ID 4 +#define WAKE_UP_PARMS_WORD_SIZE 15 + +/* Option rom version structure */ +struct prog_id { +#ifdef __BIG_ENDIAN_BITFIELD + uint8_t type; + uint8_t id; + uint32_t ver:4; /* Major Version */ + uint32_t rev:4; /* Revision */ + uint32_t lev:2; /* Level */ + uint32_t dist:2; /* Dist Type */ + uint32_t num:4; /* number after dist type */ +#else /* __LITTLE_ENDIAN_BITFIELD */ + uint32_t num:4; /* number after dist type */ + uint32_t dist:2; /* Dist Type */ + uint32_t lev:2; /* Level */ + uint32_t rev:4; /* Revision */ + uint32_t ver:4; /* Major Version */ + uint8_t id; + uint8_t type; +#endif +}; + /* Structure for MB Command UPDATE_CFG (0x1B) */ struct update_cfg_var { diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index c0ea4fc..c151651 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -271,6 +271,48 @@ lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) } /** + * lpfc_dump_wakeup_param_cmpl: Completion handler for dump memory mailbox + * command used for getting wake up parameters. + * @phba: pointer to lpfc hba data structure. + * @pmboxq: pointer to the driver internal queue element for mailbox command. + * + * This is the completion handler for dump mailbox command for getting + * wake up parameters. When this command complete, the response contain + * Option rom version of the HBA. This function translate the version number + * into a human readable string and store it in OptionROMVersion. + **/ +static void +lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) +{ + struct prog_id *prg; + uint32_t prog_id_word; + char dist = ' '; + /* character array used for decoding dist type. */ + char dist_char[] = "nabx"; + + if (pmboxq->mb.mbxStatus != MBX_SUCCESS) + return; + + prg = (struct prog_id *) &prog_id_word; + + /* word 7 contain option rom version */ + prog_id_word = pmboxq->mb.un.varWords[7]; + + /* Decode the Option rom version word to a readable string */ + if (prg->dist < 4) + dist = dist_char[prg->dist]; + + if ((prg->dist == 3) && (prg->num == 0)) + sprintf(phba->OptionROMVersion, "%d.%d%d", + prg->ver, prg->rev, prg->lev); + else + sprintf(phba->OptionROMVersion, "%d.%d%d%c%d", + prg->ver, prg->rev, prg->lev, + dist, prg->num); + return; +} + +/** * lpfc_config_port_post: Perform lpfc initialization after config port. * @phba: pointer to lpfc hba data structure. * @@ -528,6 +570,20 @@ lpfc_config_port_post(struct lpfc_hba *phba) rc); mempool_free(pmb, phba->mbox_mem_pool); } + + /* Get Option rom version */ + pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + lpfc_dump_wakeup_param(phba, pmb); + pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl; + pmb->vport = phba->pport; + rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); + + if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0435 Adapter failed " + "to get Option ROM version status x%x\n.", rc); + mempool_free(pmb, phba->mbox_mem_pool); + } + return 0; } @@ -2014,7 +2070,12 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) struct Scsi_Host *shost; int error = 0; - shost = scsi_host_alloc(&lpfc_template, sizeof(struct lpfc_vport)); + if (dev != &phba->pcidev->dev) + shost = scsi_host_alloc(&lpfc_vport_template, + sizeof(struct lpfc_vport)); + else + shost = scsi_host_alloc(&lpfc_template, + sizeof(struct lpfc_vport)); if (!shost) goto out; @@ -2097,8 +2158,6 @@ destroy_port(struct lpfc_vport *vport) struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct lpfc_hba *phba = vport->phba; - kfree(vport->vname); - lpfc_debugfs_terminate(vport); fc_remove_host(shost); scsi_remove_host(shost); @@ -2862,7 +2921,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev) vport->load_flag |= FC_UNLOADING; spin_unlock_irq(&phba->hbalock); - kfree(vport->vname); lpfc_free_sysfs_attr(vport); kthread_stop(phba->worker_thread); diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 184fe62..f0ab456 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) } /** + * lpfc_dump_mem: Prepare a mailbox command for retrieving wakeup params. + * @phba: pointer to lpfc hba data structure. + * @pmb: pointer to the driver internal queue element for mailbox command. + * This function create a dump memory mailbox command to dump wake up + * parameters. + */ +void +lpfc_dump_wakeup_param(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) +{ + MAILBOX_t *mb; + void *ctx; + + mb = &pmb->mb; + /* Save context so that we can restore after memset */ + ctx = pmb->context2; + + /* Setup to dump VPD region */ + memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); + mb->mbxCommand = MBX_DUMP_MEMORY; + mb->mbxOwner = OWN_HOST; + mb->un.varDmp.cv = 1; + mb->un.varDmp.type = DMP_NV_PARAMS; + mb->un.varDmp.entry_index = 0; + mb->un.varDmp.region_id = WAKE_UP_PARMS_REGION_ID; + mb->un.varDmp.word_cnt = WAKE_UP_PARMS_WORD_SIZE; + mb->un.varDmp.co = 0; + mb->un.varDmp.resp_offset = 0; + pmb->context2 = ctx; + return; +} + +/** * lpfc_read_nv: Prepare a mailbox command for reading HBA's NVRAM param. * @phba: pointer to lpfc hba data structure. * @pmb: pointer to the driver internal queue element for mailbox command. diff --git a/drivers/scsi/lpfc/lpfc_nl.h b/drivers/scsi/lpfc/lpfc_nl.h index 991ad53..27d1a88 100644 --- a/drivers/scsi/lpfc/lpfc_nl.h +++ b/drivers/scsi/lpfc/lpfc_nl.h @@ -22,18 +22,20 @@ #define FC_REG_LINK_EVENT 0x0001 /* link up / down events */ #define FC_REG_RSCN_EVENT 0x0002 /* RSCN events */ #define FC_REG_CT_EVENT 0x0004 /* CT request events */ -#define FC_REG_DUMP_EVENT 0x0008 /* Dump events */ -#define FC_REG_TEMPERATURE_EVENT 0x0010 /* temperature events */ -#define FC_REG_ELS_EVENT 0x0020 /* lpfc els events */ -#define FC_REG_FABRIC_EVENT 0x0040 /* lpfc fabric events */ -#define FC_REG_SCSI_EVENT 0x0080 /* lpfc scsi events */ -#define FC_REG_BOARD_EVENT 0x0100 /* lpfc board events */ -#define FC_REG_ADAPTER_EVENT 0x0200 /* lpfc adapter events */ +#define FC_REG_DUMP_EVENT 0x0010 /* Dump events */ +#define FC_REG_TEMPERATURE_EVENT 0x0020 /* temperature events */ +#define FC_REG_VPORTRSCN_EVENT 0x0040 /* Vport RSCN events */ +#define FC_REG_ELS_EVENT 0x0080 /* lpfc els events */ +#define FC_REG_FABRIC_EVENT 0x0100 /* lpfc fabric events */ +#define FC_REG_SCSI_EVENT 0x0200 /* lpfc scsi events */ +#define FC_REG_BOARD_EVENT 0x0400 /* lpfc board events */ +#define FC_REG_ADAPTER_EVENT 0x0800 /* lpfc adapter events */ #define FC_REG_EVENT_MASK (FC_REG_LINK_EVENT | \ FC_REG_RSCN_EVENT | \ FC_REG_CT_EVENT | \ FC_REG_DUMP_EVENT | \ FC_REG_TEMPERATURE_EVENT | \ + FC_REG_VPORTRSCN_EVENT | \ FC_REG_ELS_EVENT | \ FC_REG_FABRIC_EVENT | \ FC_REG_SCSI_EVENT | \ diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index a7ea952..fed32ff 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1842,7 +1842,7 @@ struct scsi_host_template lpfc_template = { .info = lpfc_info, .queuecommand = lpfc_queuecommand, .eh_abort_handler = lpfc_abort_handler, - .eh_device_reset_handler= lpfc_device_reset_handler, + .eh_device_reset_handler = lpfc_device_reset_handler, .eh_bus_reset_handler = lpfc_bus_reset_handler, .slave_alloc = lpfc_slave_alloc, .slave_configure = lpfc_slave_configure, @@ -1856,3 +1856,22 @@ struct scsi_host_template lpfc_template = { .max_sectors = 0xFFFF, }; +struct scsi_host_template lpfc_vport_template = { + .module = THIS_MODULE, + .name = LPFC_DRIVER_NAME, + .info = lpfc_info, + .queuecommand = lpfc_queuecommand, + .eh_abort_handler = lpfc_abort_handler, + .eh_device_reset_handler = lpfc_device_reset_handler, + .eh_bus_reset_handler = lpfc_bus_reset_handler, + .slave_alloc = lpfc_slave_alloc, + .slave_configure = lpfc_slave_configure, + .slave_destroy = lpfc_slave_destroy, + .scan_finished = lpfc_scan_finished, + .this_id = -1, + .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, + .cmd_per_lun = LPFC_CMD_PER_LUN, + .use_clustering = ENABLE_CLUSTERING, + .shost_attrs = lpfc_vport_attrs, + .max_sectors = 0xFFFF, +}; diff --git a/drivers/scsi/lpfc/lpfc_security.c b/drivers/scsi/lpfc/lpfc_security.c index d136f67..c0fbe56 100644 --- a/drivers/scsi/lpfc/lpfc_security.c +++ b/drivers/scsi/lpfc/lpfc_security.c @@ -263,7 +263,7 @@ lpfc_reauthentication_handler(struct lpfc_nodelist *ndlp) lpfc_printf_vlog(vport, KERN_ERR, LOG_SECURITY, "1029 Reauthentication Failure\n"); if (vport->auth.auth_state == LPFC_AUTH_SUCCESS) - lpfc_port_auth_failed(ndlp); + lpfc_port_auth_failed(ndlp, LPFC_AUTH_FAIL); } } diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index a42cef2..57b559a 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.2.8.3" +#define LPFC_DRIVER_VERSION "8.2.8.4" #define LPFC_DRIVER_NAME "lpfc" #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index c3a3f6e..ae8256d 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -289,10 +289,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) int vpi; int rc = VPORT_ERROR; int status; - int size; - if ((phba->sli_rev < 3) || - !(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) { + if ((phba->sli_rev < 3) || !(phba->cfg_enable_npiv)) { lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, "1808 Create VPORT failed: " "NPIV is not enabled: SLImode:%d\n", @@ -352,20 +350,6 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) memcpy(vport->fc_portname.u.wwn, vport->fc_sparam.portName.u.wwn, 8); memcpy(vport->fc_nodename.u.wwn, vport->fc_sparam.nodeName.u.wwn, 8); - size = strnlen(fc_vport->symbolic_name, LPFC_VNAME_LEN); - if (size) { - vport->vname = kzalloc(size+1, GFP_KERNEL); - if (!vport->vname) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, - "1814 Create VPORT failed. " - "vname allocation failed.\n"); - rc = VPORT_ERROR; - lpfc_free_vpi(phba, vpi); - destroy_port(vport); - goto error_out; - } - memcpy(vport->vname, fc_vport->symbolic_name, size+1); - } if (fc_vport->node_name != 0) u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn); if (fc_vport->port_name != 0) @@ -410,6 +394,9 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) } } + /* Create binary sysfs attribute for vport */ + lpfc_alloc_sysfs_attr(vport); + *(struct lpfc_vport **)fc_vport->dd_data = vport; vport->fc_vport = fc_vport; @@ -421,6 +408,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) } if (disable) { + lpfc_vport_set_state(vport, FC_VPORT_DISABLED); rc = VPORT_OK; goto out; } @@ -603,7 +591,9 @@ lpfc_vport_delete(struct fc_vport *fc_vport) spin_lock_irq(&phba->hbalock); vport->load_flag |= FC_UNLOADING; spin_unlock_irq(&phba->hbalock); - kfree(vport->vname); + + lpfc_free_sysfs_attr(vport); + lpfc_debugfs_terminate(vport); /* Remove FC host and then SCSI host with the vport */