summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c606
1 files changed, 437 insertions, 169 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 0391fc317003..072ad1aa5505 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 ---------------------------------------------------------- */
@@ -141,7 +144,7 @@ qla2x00_async_login_sp_done(void *ptr, int res)
struct srb_iocb *lio = &sp->u.iocb_cmd;
struct event_arg ea;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20dd,
"%s %8phC res %d \n", __func__, sp->fcport->port_name, res);
sp->fcport->flags &= ~FCF_ASYNC_SENT;
@@ -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,38 +334,38 @@ 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;
if (ea->rc) { /* rval */
if (fcport->login_retry == 0) {
fcport->login_retry = vha->hw->login_retry_count;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "GNL failed Port login retry %8phN, retry cnt=%d.\n",
- fcport->port_name, fcport->login_retry);
+ ql_dbg(ql_dbg_disc, vha, 0x20de,
+ "GNL failed Port login retry %8phN, retry cnt=%d.\n",
+ fcport->port_name, fcport->login_retry);
}
return;
}
if (fcport->last_rscn_gen != fcport->rscn_gen) {
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20df,
"%s %8phC rscn gen changed rscn %d|%d \n",
__func__, fcport->port_name,
fcport->last_rscn_gen, fcport->rscn_gen);
qla24xx_post_gidpn_work(vha, fcport);
return;
} else if (fcport->last_login_gen != fcport->login_gen) {
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %8phC login gen changed login %d|%d \n",
- __func__, fcport->port_name,
- fcport->last_login_gen, fcport->login_gen);
+ ql_dbg(ql_dbg_disc, vha, 0x20e0,
+ "%s %8phC login gen changed login %d|%d\n",
+ __func__, fcport->port_name,
+ fcport->last_login_gen, fcport->login_gen);
return;
}
n = ea->data[0] / sizeof(struct get_name_list_extended);
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20e1,
"%s %d %8phC n %d %02x%02x%02x lid %d \n",
__func__, __LINE__, fcport->port_name, n,
fcport->d_id.b.domain, fcport->d_id.b.area,
@@ -380,20 +387,20 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
loop_id = le16_to_cpu(e->nport_handle);
loop_id = (loop_id & 0x7fff);
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s found %8phC CLS [%d|%d] ID[%02x%02x%02x|%02x%02x%02x] lid[%d|%d]\n",
- __func__, fcport->port_name,
- e->current_login_state, fcport->fw_login_state,
- id.b.domain, id.b.area, id.b.al_pa,
- fcport->d_id.b.domain, fcport->d_id.b.area,
- fcport->d_id.b.al_pa, loop_id, fcport->loop_id);
+ ql_dbg(ql_dbg_disc, vha, 0x20e2,
+ "%s found %8phC CLS [%d|%d] ID[%02x%02x%02x|%02x%02x%02x] lid[%d|%d]\n",
+ __func__, fcport->port_name,
+ e->current_login_state, fcport->fw_login_state,
+ id.b.domain, id.b.area, id.b.al_pa,
+ fcport->d_id.b.domain, fcport->d_id.b.area,
+ fcport->d_id.b.al_pa, loop_id, fcport->loop_id);
if ((id.b24 != fcport->d_id.b24) ||
((fcport->loop_id != FC_NO_LOOP_ID) &&
(fcport->loop_id != loop_id))) {
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %d %8phC post del sess\n",
- __func__, __LINE__, fcport->port_name);
+ ql_dbg(ql_dbg_disc, vha, 0x20e3,
+ "%s %d %8phC post del sess\n",
+ __func__, __LINE__, fcport->port_name);
qlt_schedule_sess_for_deletion(fcport, 1);
return;
}
@@ -414,24 +421,28 @@ 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, 0xffff,
- "%s %d %8phC post gpdb\n",
- __func__, __LINE__, fcport->port_name);
+ ql_dbg(ql_dbg_disc, vha, 0x20e4,
+ "%s %d %8phC post gpdb\n",
+ __func__, __LINE__, fcport->port_name);
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) {
qla2x00_find_new_loop_id(vha, fcport);
fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
}
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %d %8phC \n",
- __func__, __LINE__, fcport->port_name);
+ ql_dbg(ql_dbg_disc, vha, 0x20e5,
+ "%s %d %8phC\n",
+ __func__, __LINE__, fcport->port_name);
qla24xx_fcport_handle_login(vha, fcport);
break;
}
@@ -456,7 +467,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
qla2x00_find_fcport_by_wwpn(vha,
e->port_name, 0);
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20e6,
"%s %d %8phC post del sess\n",
__func__, __LINE__,
conflict_fcport->port_name);
@@ -487,7 +498,7 @@ qla24xx_async_gnl_sp_done(void *s, int res)
u64 wwn;
struct list_head h;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20e7,
"Async done-%s res %x mb[1]=%x mb[2]=%x \n",
sp->name, res, sp->u.iocb_cmd.u.mbx.in_mb[1],
sp->u.iocb_cmd.u.mbx.in_mb[2]);
@@ -512,7 +523,7 @@ qla24xx_async_gnl_sp_done(void *s, int res)
set_bit(loop_id, vha->hw->loop_id_map);
wwn = wwn_to_u64(e->port_name);
- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
+ ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x20e8,
"%s %8phC %02x:%02x:%02x state %d/%d lid %x \n",
__func__, (void *)&wwn, e->port_id[2], e->port_id[1],
e->port_id[0], e->current_login_state, e->last_login_state,
@@ -551,7 +562,7 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
if (!vha->flags.online)
goto done;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20d9,
"Async-gnlist WWPN %8phC \n", fcport->port_name);
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
@@ -598,9 +609,9 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
if (rval != QLA_SUCCESS)
goto done_free_sp;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "Async-%s - OUT WWPN %8phC hndl %x\n",
- sp->name, fcport->port_name, sp->handle);
+ ql_dbg(ql_dbg_disc, vha, 0x20da,
+ "Async-%s - OUT WWPN %8phC hndl %x\n",
+ sp->name, fcport->port_name, sp->handle);
return rval;
@@ -635,7 +646,7 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)
int rval = QLA_SUCCESS;
struct event_arg ea;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20db,
"Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n",
sp->name, res, fcport->port_name, mb[1], mb[2]);
@@ -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)
{
@@ -701,8 +810,8 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
if (pd == NULL) {
- ql_log(ql_log_warn, vha, 0xffff,
- "Failed to allocate port database structure.\n");
+ ql_log(ql_log_warn, vha, 0xd043,
+ "Failed to allocate port database structure.\n");
goto done_free_sp;
}
memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
@@ -734,9 +843,9 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
if (rval != QLA_SUCCESS)
goto done_free_sp;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "Async-%s %8phC hndl %x opt %x\n",
- sp->name, fcport->port_name, sp->handle, opt);
+ ql_dbg(ql_dbg_disc, vha, 0x20dc,
+ "Async-%s %8phC hndl %x opt %x\n",
+ sp->name, fcport->port_name, sp->handle, opt);
return rval;
@@ -760,27 +869,27 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
fcport->flags &= ~FCF_ASYNC_SENT;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20d2,
"%s %8phC DS %d LS %d rval %d\n", __func__, fcport->port_name,
fcport->disc_state, fcport->fw_login_state, rval);
if (ea->sp->gen2 != fcport->login_gen) {
/* target side must have changed it. */
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20d3,
"%s %8phC generation changed rscn %d|%d login %d|%d \n",
__func__, fcport->port_name, fcport->last_rscn_gen,
fcport->rscn_gen, fcport->last_login_gen,
fcport->login_gen);
return;
} else if (ea->sp->gen1 != fcport->rscn_gen) {
- ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC post gidpn\n",
+ ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
__func__, __LINE__, fcport->port_name);
qla24xx_post_gidpn_work(vha, fcport);
return;
}
if (rval != QLA_SUCCESS) {
- ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC post del sess\n",
+ ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC post del sess\n",
__func__, __LINE__, fcport->port_name);
qlt_schedule_sess_for_deletion_lock(fcport);
return;
@@ -797,14 +906,14 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
if (!IS_IIDMA_CAPABLE(vha->hw) ||
!vha->hw->flags.gpsc_supported) {
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20d6,
"%s %d %8phC post upd_fcport fcp_cnt %d\n",
__func__, __LINE__, fcport->port_name,
vha->fcport_count);
qla24xx_post_upd_fcport_work(vha, fcport);
} else {
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20d7,
"%s %d %8phC post gpsc fcp_cnt %d\n",
__func__, __LINE__, fcport->port_name,
vha->fcport_count);
@@ -823,7 +932,7 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
if (fcport->scan_state != QLA_FCPORT_FOUND)
return 0;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20d8,
"%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d|%d retry %d lid %d\n",
__func__, fcport->port_name, fcport->disc_state,
fcport->fw_login_state, fcport->login_pause, fcport->flags,
@@ -854,14 +963,14 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
switch (fcport->disc_state) {
case DSC_DELETED:
if (fcport->loop_id == FC_NO_LOOP_ID) {
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %d %8phC post gnl\n",
- __func__, __LINE__, fcport->port_name);
+ ql_dbg(ql_dbg_disc, vha, 0x20bd,
+ "%s %d %8phC post gnl\n",
+ __func__, __LINE__, fcport->port_name);
qla24xx_async_gnl(vha, fcport);
} else {
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %d %8phC post login\n",
- __func__, __LINE__, fcport->port_name);
+ ql_dbg(ql_dbg_disc, vha, 0x20bf,
+ "%s %d %8phC post login\n",
+ __func__, __LINE__, fcport->port_name);
fcport->disc_state = DSC_LOGIN_PEND;
qla2x00_post_async_login_work(vha, fcport, NULL);
}
@@ -878,16 +987,16 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
if (fcport->flags & FCF_FCP2_DEVICE) {
u8 opt = PDO_FORCE_ADISC;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %d %8phC post gpdb\n",
- __func__, __LINE__, fcport->port_name);
+ ql_dbg(ql_dbg_disc, vha, 0x20c9,
+ "%s %d %8phC post gpdb\n",
+ __func__, __LINE__, fcport->port_name);
fcport->disc_state = DSC_GPDB;
qla24xx_post_gpdb_work(vha, fcport, opt);
} else {
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %d %8phC post login \n",
- __func__, __LINE__, fcport->port_name);
+ ql_dbg(ql_dbg_disc, vha, 0x20cf,
+ "%s %d %8phC post login\n",
+ __func__, __LINE__, fcport->port_name);
fcport->disc_state = DSC_LOGIN_PEND;
qla2x00_post_async_login_work(vha, fcport, NULL);
}
@@ -895,18 +1004,18 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
break;
case DSC_LOGIN_FAILED:
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %d %8phC post gidpn \n",
- __func__, __LINE__, fcport->port_name);
+ ql_dbg(ql_dbg_disc, vha, 0x20d0,
+ "%s %d %8phC post gidpn\n",
+ __func__, __LINE__, fcport->port_name);
qla24xx_post_gidpn_work(vha, fcport);
break;
case DSC_LOGIN_COMPLETE:
/* recheck login state */
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %d %8phC post gpdb \n",
- __func__, __LINE__, fcport->port_name);
+ ql_dbg(ql_dbg_disc, vha, 0x20d1,
+ "%s %d %8phC post gpdb\n",
+ __func__, __LINE__, fcport->port_name);
qla24xx_post_gpdb_work(vha, fcport, PDO_FORCE_ADISC);
break;
@@ -923,10 +1032,10 @@ void qla24xx_handle_rscn_event(fc_port_t *fcport, struct event_arg *ea)
{
fcport->rscn_gen++;
- ql_dbg(ql_dbg_disc, fcport->vha, 0xffff,
- "%s %8phC DS %d LS %d\n",
- __func__, fcport->port_name, fcport->disc_state,
- fcport->fw_login_state);
+ ql_dbg(ql_dbg_disc, fcport->vha, 0x210c,
+ "%s %8phC DS %d LS %d\n",
+ __func__, fcport->port_name, fcport->disc_state,
+ fcport->fw_login_state);
if (fcport->flags & FCF_ASYNC_SENT)
return;
@@ -993,14 +1102,14 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
return;
}
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %8phC DS %d LS %d P %d del %d cnfl %p rscn %d|%d login %d|%d fl %x\n",
- __func__, fcport->port_name, fcport->disc_state,
- fcport->fw_login_state, fcport->login_pause,
- fcport->deleted, fcport->conflict,
- fcport->last_rscn_gen, fcport->rscn_gen,
- fcport->last_login_gen, fcport->login_gen,
- fcport->flags);
+ ql_dbg(ql_dbg_disc, vha, 0x2102,
+ "%s %8phC DS %d LS %d P %d del %d cnfl %p rscn %d|%d login %d|%d fl %x\n",
+ __func__, fcport->port_name, fcport->disc_state,
+ fcport->fw_login_state, fcport->login_pause,
+ fcport->deleted, fcport->conflict,
+ fcport->last_rscn_gen, fcport->rscn_gen,
+ fcport->last_login_gen, fcport->login_gen,
+ fcport->flags);
if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
(fcport->fw_login_state == DSC_LS_PRLI_PEND))
@@ -1023,7 +1132,7 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
}
if (fcport->last_rscn_gen != fcport->rscn_gen) {
- ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC post gidpn\n",
+ ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gidpn\n",
__func__, __LINE__, fcport->port_name);
qla24xx_async_gidpn(vha, fcport);
@@ -1041,6 +1150,20 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
switch (ea->event) {
case FCME_RELOGIN:
+ case FCME_RSCN:
+ case FCME_GIDPN_DONE:
+ case FCME_GPSC_DONE:
+ case FCME_GPNID_DONE:
+ if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) ||
+ test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))
+ return;
+ break;
+ default:
+ break;
+ }
+
+ switch (ea->event) {
+ case FCME_RELOGIN:
if (test_bit(UNLOADING, &vha->dpc_flags))
return;
@@ -1056,10 +1179,10 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
/* cable moved */
rc = qla24xx_post_gpnid_work(vha, &ea->id);
if (rc) {
- ql_log(ql_log_warn, vha, 0xffff,
- "RSCN GPNID work failed %02x%02x%02x\n",
- ea->id.b.domain, ea->id.b.area,
- ea->id.b.al_pa);
+ ql_log(ql_log_warn, vha, 0xd044,
+ "RSCN GPNID work failed %02x%02x%02x\n",
+ ea->id.b.domain, ea->id.b.area,
+ ea->id.b.al_pa);
}
} else {
ea->fcport = fcport;
@@ -1070,14 +1193,14 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
case RSCN_DOM_ADDR:
if (ea->id.b.rsvd_1 == RSCN_AREA_ADDR) {
mask = 0xffff00;
- ql_log(ql_dbg_async, vha, 0xffff,
- "RSCN: Area 0x%06x was affected\n",
- ea->id.b24);
+ ql_dbg(ql_dbg_async, vha, 0x5044,
+ "RSCN: Area 0x%06x was affected\n",
+ ea->id.b24);
} else {
mask = 0xff0000;
- ql_log(ql_dbg_async, vha, 0xffff,
- "RSCN: Domain 0x%06x was affected\n",
- ea->id.b24);
+ ql_dbg(ql_dbg_async, vha, 0x507a,
+ "RSCN: Domain 0x%06x was affected\n",
+ ea->id.b24);
}
rid = ea->id.b24 & mask;
@@ -1092,9 +1215,9 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
break;
case RSCN_FAB_ADDR:
default:
- ql_log(ql_log_warn, vha, 0xffff,
- "RSCN: Fabric was affected. Addr format %d\n",
- ea->id.b.rsvd_1);
+ ql_log(ql_log_warn, vha, 0xd045,
+ "RSCN: Fabric was affected. Addr format %d\n",
+ ea->id.b.rsvd_1);
qla2x00_mark_all_devices_lost(vha, 1);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
@@ -1112,12 +1235,18 @@ 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;
case FCME_GPNID_DONE:
qla24xx_handle_gpnid_event(vha, ea);
break;
+ case FCME_GFFID_DONE:
+ qla24xx_handle_gffid_event(vha, ea);
+ break;
case FCME_DELETE_DONE:
qla24xx_handle_delete_done_event(vha, ea);
break;
@@ -1294,6 +1423,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 */
@@ -1305,15 +1455,22 @@ 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, 0xffff,
- "%s %d %8phC post gpdb\n",
- __func__, __LINE__, ea->fcport->port_name);
- ea->fcport->chip_reset = vha->hw->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, 0xffff, "%s %d %8phC cmd error %x\n",
+ ql_dbg(ql_dbg_disc, vha, 0x20eb, "%s %d %8phC cmd error %x\n",
__func__, __LINE__, ea->fcport->port_name, ea->data[1]);
ea->fcport->flags &= ~FCF_ASYNC_SENT;
@@ -1330,10 +1487,10 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
cid.b.al_pa = ea->iop[1] & 0xff;
cid.b.rsvd_1 = 0;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %d %8phC LoopID 0x%x in use post gnl\n",
- __func__, __LINE__, ea->fcport->port_name,
- ea->fcport->loop_id);
+ ql_dbg(ql_dbg_disc, vha, 0x20ec,
+ "%s %d %8phC LoopID 0x%x in use post gnl\n",
+ __func__, __LINE__, ea->fcport->port_name,
+ ea->fcport->loop_id);
if (IS_SW_RESV_ADDR(cid)) {
set_bit(ea->fcport->loop_id, vha->hw->loop_id_map);
@@ -1344,11 +1501,11 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
qla24xx_post_gnl_work(vha, ea->fcport);
break;
case MBS_PORT_ID_USED:
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %d %8phC NPortId %02x%02x%02x inuse post gidpn\n",
- __func__, __LINE__, ea->fcport->port_name,
- ea->fcport->d_id.b.domain, ea->fcport->d_id.b.area,
- ea->fcport->d_id.b.al_pa);
+ ql_dbg(ql_dbg_disc, vha, 0x20ed,
+ "%s %d %8phC NPortId %02x%02x%02x inuse post gidpn\n",
+ __func__, __LINE__, ea->fcport->port_name,
+ ea->fcport->d_id.b.domain, ea->fcport->d_id.b.area,
+ ea->fcport->d_id.b.al_pa);
qla2x00_clear_loop_id(ea->fcport);
qla24xx_post_gidpn_work(vha, ea->fcport);
@@ -2524,6 +2681,13 @@ cont_alloc:
ha->chain_offset = dump_size;
dump_size += mq_size + fce_size;
+ if (ha->exchoffld_buf)
+ dump_size += sizeof(struct qla2xxx_offld_chain) +
+ ha->exchoffld_size;
+ if (ha->exlogin_buf)
+ dump_size += sizeof(struct qla2xxx_offld_chain) +
+ ha->exlogin_size;
+
allocate:
ha->fw_dump = vmalloc(dump_size);
if (!ha->fw_dump) {
@@ -2709,7 +2873,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
if (ql2xexlogins)
ha->flags.exlogins_enabled = 1;
- if (ql2xexchoffld)
+ if (qla_is_exch_offld_enabled(vha))
ha->flags.exchoffld_enabled = 1;
rval = qla2x00_execute_fw(vha, srisc_address);
@@ -2946,7 +3110,8 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
}
/* Move PUREX, ABTS RX & RIDA to ATIOQ */
- if (ql2xmvasynctoatio) {
+ if (ql2xmvasynctoatio &&
+ (IS_QLA83XX(ha) || IS_QLA27XX(ha))) {
if (qla_tgt_mode_enabled(vha) ||
qla_dual_mode_enabled(vha))
ha->fw_options[2] |= BIT_11;
@@ -2954,11 +3119,25 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
ha->fw_options[2] &= ~BIT_11;
}
- ql_dbg(ql_dbg_init, vha, 0xffff,
- "%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
- __func__, ha->fw_options[1], ha->fw_options[2],
- ha->fw_options[3], vha->host->active_mode);
- qla2x00_set_fw_options(vha, ha->fw_options);
+ if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
+ /*
+ * Tell FW to track each exchange to prevent
+ * driver from using stale exchange.
+ */
+ if (qla_tgt_mode_enabled(vha) ||
+ qla_dual_mode_enabled(vha))
+ ha->fw_options[2] |= BIT_4;
+ else
+ ha->fw_options[2] &= ~BIT_4;
+ }
+
+ ql_dbg(ql_dbg_init, vha, 0x00e8,
+ "%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
+ __func__, ha->fw_options[1], ha->fw_options[2],
+ ha->fw_options[3], vha->host->active_mode);
+
+ if (ha->fw_options[1] || ha->fw_options[2] || ha->fw_options[3])
+ qla2x00_set_fw_options(vha, ha->fw_options);
/* Update Serial Link options. */
if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
@@ -3036,7 +3215,7 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
icb->rid = cpu_to_le16(rid);
if (ha->flags.msix_enabled) {
msix = &ha->msix_entries[1];
- ql_dbg(ql_dbg_init, vha, 0x00fd,
+ ql_dbg(ql_dbg_init, vha, 0x0019,
"Registering vector 0x%x for base que.\n",
msix->entry);
icb->msix = cpu_to_le16(msix->entry);
@@ -3166,7 +3345,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
/* FA-WWPN Status */
ha->flags.fawwpn_enabled =
(mid_init_cb->init_cb.firmware_options_1 & BIT_6) != 0;
- ql_dbg(ql_dbg_init, vha, 0x0141, "FA-WWPN Support: %s.\n",
+ ql_dbg(ql_dbg_init, vha, 0x00bc, "FA-WWPN Support: %s.\n",
(ha->flags.fawwpn_enabled) ? "enabled" : "disabled");
}
@@ -3178,7 +3357,7 @@ next_check:
} else {
ql_dbg(ql_dbg_init, vha, 0x00d3,
"Init Firmware -- success.\n");
- ha->flags.fw_started = 1;
+ QLA_FW_STARTED(ha);
}
return (rval);
@@ -3840,10 +4019,10 @@ qla2x00_rport_del(void *data)
fcport->drport = NULL;
spin_unlock_irqrestore(fcport->vha->host->host_lock, flags);
if (rport) {
- ql_dbg(ql_dbg_disc, fcport->vha, 0xffff,
- "%s %8phN. rport %p roles %x \n",
- __func__, fcport->port_name, rport,
- rport->roles);
+ ql_dbg(ql_dbg_disc, fcport->vha, 0x210b,
+ "%s %8phN. rport %p roles %x\n",
+ __func__, fcport->port_name, rport,
+ rport->roles);
fc_remote_port_delete(rport);
}
@@ -3883,7 +4062,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
fcport->logout_on_delete = 1;
if (!fcport->ct_desc.ct_sns) {
- ql_log(ql_log_warn, vha, 0xffff,
+ ql_log(ql_log_warn, vha, 0xd049,
"Failed to allocate ct_sns request.\n");
kfree(fcport);
fcport = NULL;
@@ -3985,7 +4164,7 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
if (rval == QLA_SUCCESS && test_bit(RSCN_UPDATE, &flags)) {
if (LOOP_TRANSITION(vha)) {
- ql_dbg(ql_dbg_disc, vha, 0x201e,
+ ql_dbg(ql_dbg_disc, vha, 0x2099,
"Needs RSCN update and loop transition.\n");
rval = QLA_FUNCTION_FAILED;
}
@@ -4085,7 +4264,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
if (rval != QLA_SUCCESS)
goto cleanup_allocation;
- ql_dbg(ql_dbg_disc, vha, 0x2017,
+ ql_dbg(ql_dbg_disc, vha, 0x2011,
"Entries in ID list (%d).\n", entries);
ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2075,
(uint8_t *)ha->gid_list,
@@ -4094,7 +4273,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
/* Allocate temporary fcport for any new fcports discovered. */
new_fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
if (new_fcport == NULL) {
- ql_log(ql_log_warn, vha, 0x2018,
+ ql_log(ql_log_warn, vha, 0x2012,
"Memory allocation failed for fcport.\n");
rval = QLA_MEMORY_ALLOC_FAILED;
goto cleanup_allocation;
@@ -4109,7 +4288,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
fcport->port_type != FCT_BROADCAST &&
(fcport->flags & FCF_FABRIC_DEVICE) == 0) {
- ql_dbg(ql_dbg_disc, vha, 0x2019,
+ ql_dbg(ql_dbg_disc, vha, 0x2096,
"Marking port lost loop_id=0x%04x.\n",
fcport->loop_id);
@@ -4154,11 +4333,11 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
rval2 = qla2x00_get_port_database(vha, new_fcport, 0);
if (rval2 != QLA_SUCCESS) {
- ql_dbg(ql_dbg_disc, vha, 0x201a,
+ ql_dbg(ql_dbg_disc, vha, 0x2097,
"Failed to retrieve fcport information "
"-- get_port_database=%x, loop_id=0x%04x.\n",
rval2, new_fcport->loop_id);
- ql_dbg(ql_dbg_disc, vha, 0x201b,
+ ql_dbg(ql_dbg_disc, vha, 0x2105,
"Scheduling resync.\n");
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
continue;
@@ -4207,7 +4386,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
new_fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
if (new_fcport == NULL) {
- ql_log(ql_log_warn, vha, 0x201c,
+ ql_log(ql_log_warn, vha, 0xd031,
"Failed to allocate memory for fcport.\n");
rval = QLA_MEMORY_ALLOC_FAILED;
goto cleanup_allocation;
@@ -4230,7 +4409,7 @@ cleanup_allocation:
kfree(new_fcport);
if (rval != QLA_SUCCESS) {
- ql_dbg(ql_dbg_disc, vha, 0x201d,
+ ql_dbg(ql_dbg_disc, vha, 0x2098,
"Configure local loop error exit: rval=%x.\n", rval);
}
@@ -4300,10 +4479,10 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
if (fcport->port_type == FCT_TARGET)
rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
- ql_dbg(ql_dbg_disc, vha, 0xffff,
- "%s %8phN. rport %p is %s mode \n",
- __func__, fcport->port_name, rport,
- (fcport->port_type == FCT_TARGET) ? "tgt" : "ini");
+ ql_dbg(ql_dbg_disc, vha, 0x20ee,
+ "%s %8phN. rport %p is %s mode\n",
+ __func__, fcport->port_name, rport,
+ (fcport->port_type == FCT_TARGET) ? "tgt" : "ini");
fc_remote_port_rolechg(rport, rport_ids.roles);
}
@@ -4331,7 +4510,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
if (IS_SW_RESV_ADDR(fcport->d_id))
return;
- ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %8phC \n",
+ ql_dbg(ql_dbg_disc, vha, 0x20ef, "%s %8phC\n",
__func__, fcport->port_name);
if (IS_QLAFX00(vha->hw)) {
@@ -4344,6 +4523,11 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
fcport->deleted = 0;
fcport->logout_on_delete = 1;
+ if (fcport->fc4f_nvme) {
+ qla_nvme_register_remote(vha, fcport);
+ return;
+ }
+
qla2x00_set_fcport_state(fcport, FCS_ONLINE);
qla2x00_iidma_fcport(vha, fcport);
qla24xx_update_fcport_fcp_prio(vha, fcport);
@@ -4398,7 +4582,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
loop_id = SNS_FL_PORT;
rval = qla2x00_get_port_name(vha, loop_id, vha->fabric_node_name, 1);
if (rval != QLA_SUCCESS) {
- ql_dbg(ql_dbg_disc, vha, 0x201f,
+ ql_dbg(ql_dbg_disc, vha, 0x20a0,
"MBX_GET_PORT_NAME failed, No FL Port.\n");
vha->device_flags &= ~SWITCH_FOUND;
@@ -4436,7 +4620,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
return rval;
}
if (mb[0] != MBS_COMMAND_COMPLETE) {
- ql_dbg(ql_dbg_disc, vha, 0x2042,
+ ql_dbg(ql_dbg_disc, vha, 0x20a1,
"Failed SNS login: loop_id=%x mb[0]=%x mb[1]=%x mb[2]=%x "
"mb[6]=%x mb[7]=%x.\n", loop_id, mb[0], mb[1],
mb[2], mb[6], mb[7]);
@@ -4446,22 +4630,39 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
if (test_and_clear_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags)) {
if (qla2x00_rft_id(vha)) {
/* EMPTY */
- ql_dbg(ql_dbg_disc, vha, 0x2045,
+ ql_dbg(ql_dbg_disc, vha, 0x20a2,
"Register FC-4 TYPE failed.\n");
+ if (test_bit(LOOP_RESYNC_NEEDED,
+ &vha->dpc_flags))
+ break;
}
- if (qla2x00_rff_id(vha)) {
+ if (qla2x00_rff_id(vha, FC4_TYPE_FCP_SCSI)) {
/* EMPTY */
- ql_dbg(ql_dbg_disc, vha, 0x2049,
+ ql_dbg(ql_dbg_disc, vha, 0x209a,
"Register FC-4 Features failed.\n");
+ if (test_bit(LOOP_RESYNC_NEEDED,
+ &vha->dpc_flags))
+ break;
+ }
+ if (vha->flags.nvme_enabled) {
+ if (qla2x00_rff_id(vha, FC_TYPE_NVME)) {
+ ql_dbg(ql_dbg_disc, vha, 0x2049,
+ "Register NVME FC Type Features failed.\n");
+ }
}
if (qla2x00_rnn_id(vha)) {
/* EMPTY */
- ql_dbg(ql_dbg_disc, vha, 0x204f,
+ ql_dbg(ql_dbg_disc, vha, 0x2104,
"Register Node Name failed.\n");
+ if (test_bit(LOOP_RESYNC_NEEDED,
+ &vha->dpc_flags))
+ break;
} else if (qla2x00_rsnn_nn(vha)) {
/* EMPTY */
- ql_dbg(ql_dbg_disc, vha, 0x2053,
- "Register Symobilic Node Name failed.\n");
+ ql_dbg(ql_dbg_disc, vha, 0x209b,
+ "Register Symbolic Node Name failed.\n");
+ if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
+ break;
}
}
@@ -4482,6 +4683,9 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
break;
} while (0);
+ if (!vha->nvme_local_port && vha->flags.nvme_enabled)
+ qla_nvme_register_hba(vha);
+
if (rval)
ql_dbg(ql_dbg_disc, vha, 0x2068,
"Configure fabric error exit rval=%d.\n", rval);
@@ -4527,30 +4731,41 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
swl = ha->swl;
if (!swl) {
/*EMPTY*/
- ql_dbg(ql_dbg_disc, vha, 0x2054,
+ ql_dbg(ql_dbg_disc, vha, 0x209c,
"GID_PT allocations failed, fallback on GA_NXT.\n");
} else {
memset(swl, 0, ha->max_fibre_devices * sizeof(sw_info_t));
if (qla2x00_gid_pt(vha, swl) != QLA_SUCCESS) {
swl = NULL;
+ if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
+ return rval;
} else if (qla2x00_gpn_id(vha, swl) != QLA_SUCCESS) {
swl = NULL;
+ if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
+ return rval;
} else if (qla2x00_gnn_id(vha, swl) != QLA_SUCCESS) {
swl = NULL;
+ if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
+ return rval;
} else if (qla2x00_gfpn_id(vha, swl) != QLA_SUCCESS) {
swl = NULL;
+ if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
+ return rval;
}
/* If other queries succeeded probe for FC-4 type */
- if (swl)
+ if (swl) {
qla2x00_gff_id(vha, swl);
+ if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
+ return rval;
+ }
}
swl_idx = 0;
/* Allocate temporary fcport for any new fcports discovered. */
new_fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
if (new_fcport == NULL) {
- ql_log(ql_log_warn, vha, 0x205e,
+ ql_log(ql_log_warn, vha, 0x209d,
"Failed to allocate memory for fcport.\n");
return (QLA_MEMORY_ALLOC_FAILED);
}
@@ -4588,6 +4803,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;
}
@@ -4597,7 +4822,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
/* Send GA_NXT to the switch */
rval = qla2x00_ga_nxt(vha, new_fcport);
if (rval != QLA_SUCCESS) {
- ql_log(ql_log_warn, vha, 0x2064,
+ ql_log(ql_log_warn, vha, 0x209e,
"SNS scan failed -- assuming "
"zero-entry result.\n");
rval = QLA_SUCCESS;
@@ -4610,7 +4835,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
wrap.b24 = new_fcport->d_id.b24;
first_dev = 0;
} else if (new_fcport->d_id.b24 == wrap.b24) {
- ql_dbg(ql_dbg_disc, vha, 0x2065,
+ ql_dbg(ql_dbg_disc, vha, 0x209f,
"Device wrap (%02x%02x%02x).\n",
new_fcport->d_id.b.domain,
new_fcport->d_id.b.area,
@@ -4722,7 +4947,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
nxt_d_id.b24 = new_fcport->d_id.b24;
new_fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
if (new_fcport == NULL) {
- ql_log(ql_log_warn, vha, 0x2066,
+ ql_log(ql_log_warn, vha, 0xd032,
"Memory allocation failed for fcport.\n");
return (QLA_MEMORY_ALLOC_FAILED);
}
@@ -4753,7 +4978,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
(fcport->flags & FCF_FCP2_DEVICE) == 0 &&
fcport->port_type != FCT_INITIATOR &&
fcport->port_type != FCT_BROADCAST) {
- ql_dbg(ql_dbg_disc, vha, 0xffff,
+ ql_dbg(ql_dbg_disc, vha, 0x20f0,
"%s %d %8phC post del sess\n",
__func__, __LINE__,
fcport->port_name);
@@ -5473,6 +5698,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
struct scsi_qla_host *vp;
unsigned long flags;
fc_port_t *fcport;
+ u16 i;
/* For ISP82XX, driver waits for completion of the commands.
* online flag should be set.
@@ -5498,7 +5724,12 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
ha->current_topology = 0;
ha->flags.fw_started = 0;
ha->flags.fw_init_done = 0;
- ha->chip_reset++;
+ ha->base_qpair->chip_reset++;
+ for (i = 0; i < ha->max_qpairs; i++) {
+ if (ha->queue_pair_map[i])
+ ha->queue_pair_map[i]->chip_reset =
+ ha->base_qpair->chip_reset;
+ }
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
@@ -6353,8 +6584,8 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
"-> template size %x bytes\n", dlen);
if (dlen > risc_size * sizeof(*dcode)) {
ql_log(ql_log_warn, vha, 0x0167,
- "Failed fwdump template exceeds array by %x bytes\n",
- (uint32_t)(dlen - risc_size * sizeof(*dcode)));
+ "Failed fwdump template exceeds array by %zx bytes\n",
+ (size_t)(dlen - risc_size * sizeof(*dcode)));
goto default_template;
}
ha->fw_dump_template_len = dlen;
@@ -6655,8 +6886,8 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr)
"-> template size %x bytes\n", dlen);
if (dlen > risc_size * sizeof(*fwcode)) {
ql_log(ql_log_warn, vha, 0x0177,
- "Failed fwdump template exceeds array by %x bytes\n",
- (uint32_t)(dlen - risc_size * sizeof(*fwcode)));
+ "Failed fwdump template exceeds array by %zx bytes\n",
+ (size_t)(dlen - risc_size * sizeof(*fwcode)));
goto default_template;
}
ha->fw_dump_template_len = dlen;
@@ -6790,7 +7021,7 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha)
ret = qla2x00_stop_firmware(vha);
}
- ha->flags.fw_started = 0;
+ QLA_FW_STOPPED(ha);
ha->flags.fw_init_done = 0;
}
@@ -7322,16 +7553,31 @@ qla81xx_update_fw_options(scsi_qla_host_t *vha)
ha->fw_options[2] &= ~BIT_11;
}
+ if (qla_tgt_mode_enabled(vha) ||
+ qla_dual_mode_enabled(vha)) {
+ /* FW auto send SCSI status during */
+ ha->fw_options[1] |= BIT_8;
+ ha->fw_options[10] |= (u16)SAM_STAT_BUSY << 8;
+
+ /* FW perform Exchange validation */
+ ha->fw_options[2] |= BIT_4;
+ } else {
+ ha->fw_options[1] &= ~BIT_8;
+ ha->fw_options[10] &= 0x00ff;
+
+ ha->fw_options[2] &= ~BIT_4;
+ }
+
if (ql2xetsenable) {
/* Enable ETS Burst. */
memset(ha->fw_options, 0, sizeof(ha->fw_options));
ha->fw_options[2] |= BIT_9;
}
- ql_dbg(ql_dbg_init, vha, 0xffff,
- "%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
- __func__, ha->fw_options[1], ha->fw_options[2],
- ha->fw_options[3], vha->host->active_mode);
+ ql_dbg(ql_dbg_init, vha, 0x00e9,
+ "%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
+ __func__, ha->fw_options[1], ha->fw_options[2],
+ ha->fw_options[3], vha->host->active_mode);
qla2x00_set_fw_options(vha, ha->fw_options);
}
@@ -7512,7 +7758,8 @@ qla24xx_update_all_fcp_prio(scsi_qla_host_t *vha)
return ret;
}
-struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int vp_idx)
+struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos,
+ int vp_idx, bool startqp)
{
int rsp_id = 0;
int req_id = 0;
@@ -7539,6 +7786,9 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
qpair->hw = vha->hw;
qpair->vha = vha;
+ qpair->qp_lock_ptr = &qpair->qp_lock;
+ spin_lock_init(&qpair->qp_lock);
+ qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0;
/* Assign available que pair id */
mutex_lock(&ha->mq_lock);
@@ -7554,13 +7804,18 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
ha->queue_pair_map[qpair_id] = qpair;
qpair->id = qpair_id;
qpair->vp_idx = vp_idx;
+ INIT_LIST_HEAD(&qpair->hints_list);
+ qpair->chip_reset = ha->base_qpair->chip_reset;
+ qpair->enable_class_2 = ha->base_qpair->enable_class_2;
+ qpair->enable_explicit_conf =
+ ha->base_qpair->enable_explicit_conf;
for (i = 0; i < ha->msix_count; i++) {
msix = &ha->msix_entries[i];
if (msix->in_use)
continue;
qpair->msix = msix;
- ql_log(ql_dbg_multiq, vha, 0xc00f,
+ ql_dbg(ql_dbg_multiq, vha, 0xc00f,
"Vector %x selected for qpair\n", msix->vector);
break;
}
@@ -7572,11 +7827,14 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
qpair->msix->in_use = 1;
list_add_tail(&qpair->qp_list_elem, &vha->qp_list);
+ qpair->pdev = ha->pdev;
+ if (IS_QLA27XX(ha) || IS_QLA83XX(ha))
+ qpair->reqq_start_iocbs = qla_83xx_start_iocbs;
mutex_unlock(&ha->mq_lock);
/* Create response queue first */
- rsp_id = qla25xx_create_rsp_que(ha, 0, 0, 0, qpair);
+ rsp_id = qla25xx_create_rsp_que(ha, 0, 0, 0, qpair, startqp);
if (!rsp_id) {
ql_log(ql_log_warn, vha, 0x0185,
"Failed to create response queue.\n");
@@ -7586,7 +7844,8 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
qpair->rsp = ha->rsp_q_map[rsp_id];
/* Create request queue */
- req_id = qla25xx_create_req_que(ha, 0, vp_idx, 0, rsp_id, qos);
+ req_id = qla25xx_create_req_que(ha, 0, vp_idx, 0, rsp_id, qos,
+ startqp);
if (!req_id) {
ql_log(ql_log_warn, vha, 0x0186,
"Failed to create request queue.\n");
@@ -7595,6 +7854,9 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
qpair->req = ha->req_q_map[req_id];
qpair->rsp->req = qpair->req;
+ qpair->rsp->qpair = qpair;
+ /* init qpair to this cpu. Will adjust at run time. */
+ qla_cpu_update(qpair, smp_processor_id());
if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
if (ha->fw_attributes & BIT_4)
@@ -7603,7 +7865,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
qpair->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep);
if (!qpair->srb_mempool) {
- ql_log(ql_log_warn, vha, 0x0191,
+ ql_log(ql_log_warn, vha, 0xd036,
"Failed to create srb mempool for qpair %d\n",
qpair->id);
goto fail_mempool;
@@ -7645,9 +7907,12 @@ fail_qid_map:
int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)
{
- int ret;
+ int ret = QLA_FUNCTION_FAILED;
struct qla_hw_data *ha = qpair->hw;
+ if (!vha->flags.qpairs_req_created && !vha->flags.qpairs_rsp_created)
+ goto fail;
+
qpair->delete_in_progress = 1;
while (atomic_read(&qpair->ref_count))
msleep(500);
@@ -7664,8 +7929,11 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)
clear_bit(qpair->id, ha->qpair_qid_map);
ha->num_qpairs--;
list_del(&qpair->qp_list_elem);
- if (list_empty(&vha->qp_list))
+ if (list_empty(&vha->qp_list)) {
vha->flags.qpairs_available = 0;
+ vha->flags.qpairs_req_created = 0;
+ vha->flags.qpairs_rsp_created = 0;
+ }
mempool_destroy(qpair->srb_mempool);
kfree(qpair);
mutex_unlock(&ha->mq_lock);