diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 9 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 30 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 13 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 168 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 21 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 33 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 4 |
9 files changed, 256 insertions, 27 deletions
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index f91ee717202d..c8057c798125 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -15,9 +15,10 @@ * | | | 0x015b-0x0160 | * | | | 0x016e | * | Mailbox commands | 0x1199 | 0x1193 | - * | Device Discovery | 0x2004 | 0x2016 | - * | | | 0x2011-0x2012, | - * | | | 0x2099-0x20a4 | + * | Device Discovery | 0x2131 | 0x210e-0x2116 | + * | | | 0x211a | + * | | | 0x211c-0x2128 | + * | | | 0x212a-0x2130 | * | Queue Command and IO tracing | 0x3074 | 0x300b | * | | | 0x3027-0x3028 | * | | | 0x303d-0x3041 | @@ -59,7 +60,7 @@ * | | | 0xb13c-0xb140 | * | | | 0xb149 | * | MultiQ | 0xc010 | | - * | Misc | 0xd301 | 0xd031-0xd0ff | + * | Misc | 0xd302 | 0xd031-0xd0ff | * | | | 0xd101-0xd1fe | * | | | 0xd214-0xd2fe | * | Target Mode | 0xe081 | | diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index e1af9db3691d..6f8df9cea8ff 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -343,6 +343,7 @@ struct srb_iocb { #define SRB_LOGIN_RETRIED BIT_0 #define SRB_LOGIN_COND_PLOGI BIT_1 #define SRB_LOGIN_SKIP_PRLI BIT_2 +#define SRB_LOGIN_NVME_PRLI BIT_3 uint16_t data[2]; u32 iop[2]; } logio; @@ -436,6 +437,7 @@ struct srb_iocb { #define SRB_NACK_PLOGI 16 #define SRB_NACK_PRLI 17 #define SRB_NACK_LOGO 18 +#define SRB_PRLI_CMD 21 enum { TYPE_SRB, @@ -1088,6 +1090,7 @@ struct mbx_cmd_32 { #define MBX_1 BIT_1 #define MBX_0 BIT_0 +#define RNID_TYPE_PORT_LOGIN 0x7 #define RNID_TYPE_SET_VERSION 0x9 #define RNID_TYPE_ASIC_TEMP 0xC @@ -2152,6 +2155,7 @@ typedef struct { uint8_t fabric_port_name[WWN_SIZE]; uint16_t fp_speed; uint8_t fc4_type; + uint8_t fc4f_nvme; /* nvme fc4 feature bits */ } sw_info_t; /* FCP-4 types */ @@ -2180,7 +2184,8 @@ typedef enum { FCT_SWITCH, FCT_BROADCAST, FCT_INITIATOR, - FCT_TARGET + FCT_TARGET, + FCT_NVME } fc_port_type_t; enum qla_sess_deletion { @@ -2237,10 +2242,12 @@ enum fcport_mgt_event { FCME_RSCN, FCME_GIDPN_DONE, FCME_PLOGI_DONE, /* Initiator side sent LLIOCB */ + FCME_PRLI_DONE, FCME_GNL_DONE, FCME_GPSC_DONE, FCME_GPDB_DONE, FCME_GPNID_DONE, + FCME_GFFID_DONE, FCME_DELETE_DONE, }; @@ -2274,6 +2281,16 @@ typedef struct fc_port { unsigned int login_pause:1; unsigned int login_succ:1; + struct work_struct nvme_del_work; + atomic_t nvme_ref_count; + uint32_t nvme_prli_service_param; +#define NVME_PRLI_SP_CONF BIT_7 +#define NVME_PRLI_SP_INITIATOR BIT_5 +#define NVME_PRLI_SP_TARGET BIT_4 +#define NVME_PRLI_SP_DISCOVERY BIT_3 + uint8_t nvme_flag; +#define NVME_FLAG_REGISTERED 4 + struct fc_port *conflict; unsigned char logout_completed; int generation; @@ -2306,6 +2323,7 @@ typedef struct fc_port { u32 supported_classes; uint8_t fc4_type; + uint8_t fc4f_nvme; uint8_t scan_state; unsigned long last_queue_full; @@ -2313,6 +2331,8 @@ typedef struct fc_port { uint16_t port_id; + struct nvme_fc_remote_port *nvme_remote_port; + unsigned long retry_delay_timestamp; struct qla_tgt_sess *tgt_session; struct ct_sns_desc ct_desc; @@ -2745,7 +2765,7 @@ struct ct_sns_req { struct { uint8_t reserved; - uint8_t port_name[3]; + uint8_t port_id[3]; } gff_id; struct { @@ -3052,6 +3072,7 @@ enum qla_work_type { QLA_EVT_GPNID_DONE, QLA_EVT_NEW_SESS, QLA_EVT_GPDB, + QLA_EVT_PRLI, QLA_EVT_GPSC, QLA_EVT_UPD_FCPORT, QLA_EVT_GNL, @@ -4007,6 +4028,7 @@ typedef struct scsi_qla_host { uint32_t qpairs_available:1; uint32_t qpairs_req_created:1; uint32_t qpairs_rsp_created:1; + uint32_t nvme_enabled:1; } flags; atomic_t loop_state; @@ -4085,6 +4107,10 @@ typedef struct scsi_qla_host { uint8_t port_name[WWN_SIZE]; uint8_t fabric_node_name[WWN_SIZE]; + struct nvme_fc_local_port *nvme_local_port; + atomic_t nvme_ref_count; + struct list_head nvme_rport_list; + uint16_t fcoe_vlan_id; uint16_t fcoe_fcf_idx; uint8_t fcoe_vn_port_mac[6]; diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 1f808928763b..dcae62d4cbeb 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -37,6 +37,12 @@ struct port_database_24xx { #define PDF_CLASS_2 BIT_4 #define PDF_HARD_ADDR BIT_1 + /* + * for NVMe, the login_state field has been + * split into nibbles. + * The lower nibble is for FCP. + * The upper nibble is for NVMe. + */ uint8_t current_login_state; uint8_t last_login_state; #define PDS_PLOGI_PENDING 0x03 @@ -69,7 +75,11 @@ struct port_database_24xx { uint8_t port_name[WWN_SIZE]; uint8_t node_name[WWN_SIZE]; - uint8_t reserved_3[24]; + uint8_t reserved_3[4]; + uint16_t prli_nvme_svc_param_word_0; /* Bits 15-0 of word 0 */ + uint16_t prli_nvme_svc_param_word_3; /* Bits 15-0 of word 3 */ + uint16_t nvme_first_burst_size; + uint8_t reserved_4[14]; }; /* @@ -819,6 +829,7 @@ struct logio_entry_24xx { #define LCF_CLASS_2 BIT_8 /* Enable class 2 during PLOGI. */ #define LCF_FREE_NPORT BIT_7 /* Release NPORT handle after LOGO. */ #define LCF_EXPL_LOGO BIT_6 /* Perform an explicit LOGO. */ +#define LCF_NVME_PRLI BIT_6 /* Perform NVME FC4 PRLI */ #define LCF_SKIP_PRLI BIT_5 /* Skip PRLI after PLOGI. */ #define LCF_IMPL_LOGO_ALL BIT_5 /* Implicit LOGO to all ports. */ #define LCF_COND_PLOGI BIT_4 /* PLOGI only if not logged-in. */ diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index beebf96c23d4..6fbee11c1a18 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -99,6 +99,7 @@ extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *, extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *); void qla2x00_fcport_event_handler(scsi_qla_host_t *, struct event_arg *); int qla24xx_async_gpdb(struct scsi_qla_host *, fc_port_t *, u8); +int qla24xx_async_prli(struct scsi_qla_host *, fc_port_t *); int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *, struct imm_ntfy_from_isp *, int); int qla24xx_post_newsess_work(struct scsi_qla_host *, port_id_t *, u8 *, diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 1d815ab779ea..ed898b7a32c8 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -37,8 +37,11 @@ static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *); static int qla84xx_init_chip(scsi_qla_host_t *); static int qla25xx_init_queues(struct qla_hw_data *); static int qla24xx_post_gpdb_work(struct scsi_qla_host *, fc_port_t *, u8); +static int qla24xx_post_prli_work(struct scsi_qla_host*, fc_port_t *); static void qla24xx_handle_plogi_done_event(struct scsi_qla_host *, struct event_arg *); +static void qla24xx_handle_prli_done_event(struct scsi_qla_host *, + struct event_arg *); /* SRB Extensions ---------------------------------------------------------- */ @@ -191,6 +194,10 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, lio->timeout = qla2x00_async_iocb_timeout; sp->done = qla2x00_async_login_sp_done; lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; + + if (fcport->fc4f_nvme) + lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI; + if (data[1] & QLA_LOGIO_LOGIN_RETRIED) lio->u.logio.flags |= SRB_LOGIN_RETRIED; rval = qla2x00_start_sp(sp); @@ -327,7 +334,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, u16 i, n, found = 0, loop_id; port_id_t id; u64 wwn; - u8 opt = 0; + u8 opt = 0, current_login_state; fcport = ea->fcport; @@ -414,7 +421,12 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, fcport->login_pause = 1; } - switch (e->current_login_state) { + if (fcport->fc4f_nvme) + current_login_state = e->current_login_state >> 4; + else + current_login_state = e->current_login_state & 0xf; + + switch (current_login_state) { case DSC_LS_PRLI_COMP: ql_dbg(ql_dbg_disc, vha, 0x20e4, "%s %d %8phC post gpdb\n", @@ -422,7 +434,6 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, opt = PDO_FORCE_ADISC; qla24xx_post_gpdb_work(vha, fcport, opt); break; - case DSC_LS_PORT_UNAVAIL: default: if (fcport->loop_id == FC_NO_LOOP_ID) { @@ -665,6 +676,104 @@ gpd_error_out: sp->free(sp); } +static int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport) +{ + struct qla_work_evt *e; + + e = qla2x00_alloc_work(vha, QLA_EVT_PRLI); + if (!e) + return QLA_FUNCTION_FAILED; + + e->u.fcport.fcport = fcport; + + return qla2x00_post_work(vha, e); +} + +static void +qla2x00_async_prli_sp_done(void *ptr, int res) +{ + srb_t *sp = ptr; + struct scsi_qla_host *vha = sp->vha; + struct srb_iocb *lio = &sp->u.iocb_cmd; + struct event_arg ea; + + ql_dbg(ql_dbg_disc, vha, 0x2129, + "%s %8phC res %d \n", __func__, + sp->fcport->port_name, res); + + sp->fcport->flags &= ~FCF_ASYNC_SENT; + + if (!test_bit(UNLOADING, &vha->dpc_flags)) { + memset(&ea, 0, sizeof(ea)); + ea.event = FCME_PRLI_DONE; + ea.fcport = sp->fcport; + ea.data[0] = lio->u.logio.data[0]; + ea.data[1] = lio->u.logio.data[1]; + ea.iop[0] = lio->u.logio.iop[0]; + ea.iop[1] = lio->u.logio.iop[1]; + ea.sp = sp; + + qla2x00_fcport_event_handler(vha, &ea); + } + + sp->free(sp); +} + +int +qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport) +{ + srb_t *sp; + struct srb_iocb *lio; + int rval = QLA_FUNCTION_FAILED; + + if (!vha->flags.online) + return rval; + + if (fcport->fw_login_state == DSC_LS_PLOGI_PEND || + fcport->fw_login_state == DSC_LS_PLOGI_COMP || + fcport->fw_login_state == DSC_LS_PRLI_PEND) + return rval; + + sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); + if (!sp) + return rval; + + fcport->flags |= FCF_ASYNC_SENT; + fcport->logout_completed = 0; + + sp->type = SRB_PRLI_CMD; + sp->name = "prli"; + qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); + + lio = &sp->u.iocb_cmd; + lio->timeout = qla2x00_async_iocb_timeout; + sp->done = qla2x00_async_prli_sp_done; + lio->u.logio.flags = 0; + + if (fcport->fc4f_nvme) + lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI; + + rval = qla2x00_start_sp(sp); + if (rval != QLA_SUCCESS) { + fcport->flags &= ~FCF_ASYNC_SENT; + fcport->flags |= FCF_LOGIN_NEEDED; + set_bit(RELOGIN_NEEDED, &vha->dpc_flags); + goto done_free_sp; + } + + ql_dbg(ql_dbg_disc, vha, 0x211b, + "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d.\n", + fcport->port_name, sp->handle, fcport->loop_id, + fcport->d_id.b24, fcport->login_retry); + + return rval; + +done_free_sp: + sp->free(sp); + fcport->flags &= ~FCF_ASYNC_SENT; + return rval; +} + static int qla24xx_post_gpdb_work(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt) { @@ -1126,6 +1235,9 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea) case FCME_PLOGI_DONE: /* Initiator side sent LLIOCB */ qla24xx_handle_plogi_done_event(vha, ea); break; + case FCME_PRLI_DONE: + qla24xx_handle_prli_done_event(vha, ea); + break; case FCME_GPDB_DONE: qla24xx_handle_gpdb_event(vha, ea); break; @@ -1308,6 +1420,27 @@ qla24xx_async_abort_command(srb_t *sp) } static void +qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) +{ + switch (ea->data[0]) { + case MBS_COMMAND_COMPLETE: + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC post gpdb\n", + __func__, __LINE__, ea->fcport->port_name); + + ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset; + ea->fcport->logout_on_delete = 1; + qla24xx_post_gpdb_work(vha, ea->fcport, 0); + break; + default: + ql_dbg(ql_dbg_disc, vha, 0x2119, + "%s %d %8phC unhandle event of %x\n", + __func__, __LINE__, ea->fcport->port_name, ea->data[0]); + break; + } +} + +static void qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) { port_id_t cid; /* conflict Nport id */ @@ -1319,12 +1452,19 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) * force a relogin attempt via implicit LOGO, PLOGI, and PRLI * requests. */ - ql_dbg(ql_dbg_disc, vha, 0x20ea, - "%s %d %8phC post gpdb\n", - __func__, __LINE__, ea->fcport->port_name); - ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset; - ea->fcport->logout_on_delete = 1; - qla24xx_post_gpdb_work(vha, ea->fcport, 0); + if (ea->fcport->fc4f_nvme) { + ql_dbg(ql_dbg_disc, vha, 0x2117, + "%s %d %8phC post prli\n", + __func__, __LINE__, ea->fcport->port_name); + qla24xx_post_prli_work(vha, ea->fcport); + } else { + ql_dbg(ql_dbg_disc, vha, 0x20ea, + "%s %d %8phC post gpdb\n", + __func__, __LINE__, ea->fcport->port_name); + ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset; + ea->fcport->logout_on_delete = 1; + qla24xx_post_gpdb_work(vha, ea->fcport, 0); + } break; case MBS_COMMAND_ERROR: ql_dbg(ql_dbg_disc, vha, 0x20eb, "%s %d %8phC cmd error %x\n", @@ -4646,6 +4786,16 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) new_fcport->fp_speed = swl[swl_idx].fp_speed; new_fcport->fc4_type = swl[swl_idx].fc4_type; + new_fcport->nvme_flag = 0; + if (vha->flags.nvme_enabled && + swl[swl_idx].fc4f_nvme) { + new_fcport->fc4f_nvme = + swl[swl_idx].fc4f_nvme; + ql_log(ql_log_info, vha, 0x2131, + "FOUND: NVME port %8phC as FC Type 28h\n", + new_fcport->port_name); + } + if (swl[swl_idx].d_id.b.rsvd_1 != 0) { last_dev = 1; } diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index ac49febbac76..daa53235a28a 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2211,12 +2211,30 @@ qla2x00_alloc_iocbs(struct scsi_qla_host *vha, srb_t *sp) } static void +qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio) +{ + struct srb_iocb *lio = &sp->u.iocb_cmd; + + logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; + logio->control_flags = cpu_to_le16(LCF_COMMAND_PRLI); + if (lio->u.logio.flags & SRB_LOGIN_NVME_PRLI) + logio->control_flags |= LCF_NVME_PRLI; + + logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); + logio->port_id[0] = sp->fcport->d_id.b.al_pa; + logio->port_id[1] = sp->fcport->d_id.b.area; + logio->port_id[2] = sp->fcport->d_id.b.domain; + logio->vp_index = sp->vha->vp_idx; +} + +static void qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio) { struct srb_iocb *lio = &sp->u.iocb_cmd; logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI); + if (lio->u.logio.flags & SRB_LOGIN_COND_PLOGI) logio->control_flags |= cpu_to_le16(LCF_COND_PLOGI); if (lio->u.logio.flags & SRB_LOGIN_SKIP_PRLI) @@ -3162,6 +3180,9 @@ qla2x00_start_sp(srb_t *sp) qla24xx_login_iocb(sp, pkt) : qla2x00_login_iocb(sp, pkt); break; + case SRB_PRLI_CMD: + qla24xx_prli_iocb(sp, pkt); + break; case SRB_LOGOUT_CMD: IS_FWI2_CAPABLE(ha) ? qla24xx_logout_iocb(sp, pkt) : diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index f02a2baffb5b..1eac67e8fdfd 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -5968,14 +5968,22 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, { int rval = QLA_SUCCESS; uint64_t zero = 0; + u8 current_login_state, last_login_state; + + if (fcport->fc4f_nvme) { + current_login_state = pd->current_login_state >> 4; + last_login_state = pd->last_login_state >> 4; + } else { + current_login_state = pd->current_login_state & 0xf; + last_login_state = pd->last_login_state & 0xf; + } /* Check for logged in state. */ - if (pd->current_login_state != PDS_PRLI_COMPLETE && - pd->last_login_state != PDS_PRLI_COMPLETE) { + if (current_login_state != PDS_PRLI_COMPLETE && + last_login_state != PDS_PRLI_COMPLETE) { ql_dbg(ql_dbg_mbx, vha, 0x119a, "Unable to verify login-state (%x/%x) for loop_id %x.\n", - pd->current_login_state, pd->last_login_state, - fcport->loop_id); + current_login_state, last_login_state, fcport->loop_id); rval = QLA_FUNCTION_FAILED; goto gpd_error_out; } @@ -5998,12 +6006,17 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, fcport->d_id.b.al_pa = pd->port_id[2]; fcport->d_id.b.rsvd_1 = 0; - /* If not target must be initiator or unknown type. */ - if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) - fcport->port_type = FCT_INITIATOR; - else - fcport->port_type = FCT_TARGET; - + if (fcport->fc4f_nvme) { + fcport->nvme_prli_service_param = + pd->prli_nvme_svc_param_word_3; + fcport->port_type = FCT_NVME; + } else { + /* If not target must be initiator or unknown type. */ + if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) + fcport->port_type = FCT_INITIATOR; + else + fcport->port_type = FCT_TARGET; + } /* Passback COS information. */ fcport->supported_classes = (pd->flags & PDF_CLASS_2) ? FC_COS_CLASS2 : FC_COS_CLASS3; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index f7c4f723c405..aee884d63e55 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4428,6 +4428,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, INIT_LIST_HEAD(&vha->plogi_ack_list); INIT_LIST_HEAD(&vha->qp_list); INIT_LIST_HEAD(&vha->gnl.fcports); + INIT_LIST_HEAD(&vha->nvme_rport_list); spin_lock_init(&vha->work_lock); spin_lock_init(&vha->cmd_list_lock); @@ -4717,6 +4718,9 @@ qla2x00_do_work(struct scsi_qla_host *vha) qla24xx_async_gpdb(vha, e->u.fcport.fcport, e->u.fcport.opt); break; + case QLA_EVT_PRLI: + qla24xx_async_prli(vha, e->u.fcport.fcport); + break; case QLA_EVT_GPSC: qla24xx_async_gpsc(vha, e->u.fcport.fcport); break; diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 12e76cc37fb0..2a0173e5d10e 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -963,7 +963,6 @@ static void qlt_free_session_done(struct work_struct *work) sess->logout_on_delete, sess->keep_nport_handle, sess->send_els_logo); - if (!IS_SW_RESV_ADDR(sess->d_id)) { if (sess->send_els_logo) { qlt_port_logo_t logo; @@ -1118,6 +1117,9 @@ void qlt_unreg_sess(struct fc_port *sess) sess->last_rscn_gen = sess->rscn_gen; sess->last_login_gen = sess->login_gen; + if (sess->nvme_flag & NVME_FLAG_REGISTERED) + schedule_work(&sess->nvme_del_work); + INIT_WORK(&sess->free_work, qlt_free_session_done); schedule_work(&sess->free_work); } |