Commit beafd692 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen

scsi: qla2xxx: Reduce fabric scan duplicate code

For fabric scan, current code uses switch scan opcode and flags as the
method to iterate through different commands to carry out the process.
This makes it hard to read. This patch convert those opcode and flags into
steps. In addition, this help reduce some duplicate code.

Consolidate routines that handle GPNFT & GNNFT.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarQuinn Tran <qutran@marvell.com>
Signed-off-by: default avatarNilesh Javali <njavali@marvell.com>
Link: https://lore.kernel.org/r/20240710171057.35066-10-njavali@marvell.comReviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 348744f2
...@@ -3309,11 +3309,20 @@ struct fab_scan_rp { ...@@ -3309,11 +3309,20 @@ struct fab_scan_rp {
u8 node_name[8]; u8 node_name[8];
}; };
enum scan_step {
FAB_SCAN_START,
FAB_SCAN_GPNFT_FCP,
FAB_SCAN_GNNFT_FCP,
FAB_SCAN_GPNFT_NVME,
FAB_SCAN_GNNFT_NVME,
};
struct fab_scan { struct fab_scan {
struct fab_scan_rp *l; struct fab_scan_rp *l;
u32 size; u32 size;
u32 rscn_gen_start; u32 rscn_gen_start;
u32 rscn_gen_end; u32 rscn_gen_end;
enum scan_step step;
u16 scan_retry; u16 scan_retry;
#define MAX_SCAN_RETRIES 5 #define MAX_SCAN_RETRIES 5
enum scan_flags_t scan_flags; enum scan_flags_t scan_flags;
...@@ -3539,9 +3548,8 @@ enum qla_work_type { ...@@ -3539,9 +3548,8 @@ enum qla_work_type {
QLA_EVT_RELOGIN, QLA_EVT_RELOGIN,
QLA_EVT_ASYNC_PRLO, QLA_EVT_ASYNC_PRLO,
QLA_EVT_ASYNC_PRLO_DONE, QLA_EVT_ASYNC_PRLO_DONE,
QLA_EVT_GPNFT, QLA_EVT_SCAN_CMD,
QLA_EVT_GPNFT_DONE, QLA_EVT_SCAN_FINISH,
QLA_EVT_GNNFT_DONE,
QLA_EVT_GFPNID, QLA_EVT_GFPNID,
QLA_EVT_SP_RETRY, QLA_EVT_SP_RETRY,
QLA_EVT_IIDMA, QLA_EVT_IIDMA,
......
...@@ -728,9 +728,9 @@ int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *); ...@@ -728,9 +728,9 @@ int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *);
void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *); void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *);
int qla2x00_mgmt_svr_login(scsi_qla_host_t *); int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool); int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool);
int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *); int qla_fab_async_scan(scsi_qla_host_t *, srb_t *);
void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *); void qla_fab_scan_start(struct scsi_qla_host *);
void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *); void qla_fab_scan_finish(scsi_qla_host_t *, srb_t *);
int qla24xx_post_gfpnid_work(struct scsi_qla_host *, fc_port_t *); int qla24xx_post_gfpnid_work(struct scsi_qla_host *, fc_port_t *);
int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *); int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *);
void qla24xx_handle_gfpnid_event(scsi_qla_host_t *, struct event_arg *); void qla24xx_handle_gfpnid_event(scsi_qla_host_t *, struct event_arg *);
......
...@@ -3191,7 +3191,7 @@ static bool qla_ok_to_clear_rscn(scsi_qla_host_t *vha, fc_port_t *fcport) ...@@ -3191,7 +3191,7 @@ static bool qla_ok_to_clear_rscn(scsi_qla_host_t *vha, fc_port_t *fcport)
return true; return true;
} }
void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) void qla_fab_scan_finish(scsi_qla_host_t *vha, srb_t *sp)
{ {
fc_port_t *fcport; fc_port_t *fcport;
u32 i, rc; u32 i, rc;
...@@ -3406,14 +3406,11 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) ...@@ -3406,14 +3406,11 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
} }
} }
static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha, static int qla2x00_post_next_scan_work(struct scsi_qla_host *vha,
srb_t *sp, int cmd) srb_t *sp, int cmd)
{ {
struct qla_work_evt *e; struct qla_work_evt *e;
if (cmd != QLA_EVT_GPNFT_DONE && cmd != QLA_EVT_GNNFT_DONE)
return QLA_PARAMETER_ERROR;
e = qla2x00_alloc_work(vha, cmd); e = qla2x00_alloc_work(vha, cmd);
if (!e) if (!e)
return QLA_FUNCTION_FAILED; return QLA_FUNCTION_FAILED;
...@@ -3423,37 +3420,15 @@ static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha, ...@@ -3423,37 +3420,15 @@ static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha,
return qla2x00_post_work(vha, e); return qla2x00_post_work(vha, e);
} }
static int qla2x00_post_nvme_gpnft_work(struct scsi_qla_host *vha,
srb_t *sp, int cmd)
{
struct qla_work_evt *e;
if (cmd != QLA_EVT_GPNFT)
return QLA_PARAMETER_ERROR;
e = qla2x00_alloc_work(vha, cmd);
if (!e)
return QLA_FUNCTION_FAILED;
e->u.gpnft.fc4_type = FC4_TYPE_NVME;
e->u.gpnft.sp = sp;
return qla2x00_post_work(vha, e);
}
static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha, static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
struct srb *sp) struct srb *sp)
{ {
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
int num_fibre_dev = ha->max_fibre_devices; int num_fibre_dev = ha->max_fibre_devices;
struct ct_sns_req *ct_req =
(struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
struct ct_sns_gpnft_rsp *ct_rsp = struct ct_sns_gpnft_rsp *ct_rsp =
(struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
struct ct_sns_gpn_ft_data *d; struct ct_sns_gpn_ft_data *d;
struct fab_scan_rp *rp; struct fab_scan_rp *rp;
u16 cmd = be16_to_cpu(ct_req->command);
u8 fc4_type = sp->gen2;
int i, j, k; int i, j, k;
port_id_t id; port_id_t id;
u8 found; u8 found;
...@@ -3472,85 +3447,83 @@ static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha, ...@@ -3472,85 +3447,83 @@ static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
if (id.b24 == 0 || wwn == 0) if (id.b24 == 0 || wwn == 0)
continue; continue;
if (fc4_type == FC4_TYPE_FCP_SCSI) { ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2025,
if (cmd == GPN_FT_CMD) { "%s %06x %8ph \n",
rp = &vha->scan.l[j]; __func__, id.b24, d->port_name);
rp->id = id;
memcpy(rp->port_name, d->port_name, 8); switch (vha->scan.step) {
j++; case FAB_SCAN_GPNFT_FCP:
rp->fc4type = FS_FC4TYPE_FCP; rp = &vha->scan.l[j];
} else { rp->id = id;
for (k = 0; k < num_fibre_dev; k++) { memcpy(rp->port_name, d->port_name, 8);
rp = &vha->scan.l[k]; j++;
if (id.b24 == rp->id.b24) { rp->fc4type = FS_FC4TYPE_FCP;
memcpy(rp->node_name, break;
d->port_name, 8); case FAB_SCAN_GNNFT_FCP:
break; for (k = 0; k < num_fibre_dev; k++) {
} rp = &vha->scan.l[k];
if (id.b24 == rp->id.b24) {
memcpy(rp->node_name,
d->port_name, 8);
break;
} }
} }
} else { break;
/* Search if the fibre device supports FC4_TYPE_NVME */ case FAB_SCAN_GPNFT_NVME:
if (cmd == GPN_FT_CMD) { found = 0;
found = 0;
for (k = 0; k < num_fibre_dev; k++) {
for (k = 0; k < num_fibre_dev; k++) { rp = &vha->scan.l[k];
rp = &vha->scan.l[k]; if (!memcmp(rp->port_name, d->port_name, 8)) {
if (!memcmp(rp->port_name, /*
d->port_name, 8)) { * Supports FC-NVMe & FCP
/* */
* Supports FC-NVMe & FCP rp->fc4type |= FS_FC4TYPE_NVME;
*/ found = 1;
rp->fc4type |= FS_FC4TYPE_NVME; break;
found = 1;
break;
}
} }
}
/* We found new FC-NVMe only port */ /* We found new FC-NVMe only port */
if (!found) { if (!found) {
for (k = 0; k < num_fibre_dev; k++) {
rp = &vha->scan.l[k];
if (wwn_to_u64(rp->port_name)) {
continue;
} else {
rp->id = id;
memcpy(rp->port_name,
d->port_name, 8);
rp->fc4type =
FS_FC4TYPE_NVME;
break;
}
}
}
} else {
for (k = 0; k < num_fibre_dev; k++) { for (k = 0; k < num_fibre_dev; k++) {
rp = &vha->scan.l[k]; rp = &vha->scan.l[k];
if (id.b24 == rp->id.b24) { if (wwn_to_u64(rp->port_name)) {
memcpy(rp->node_name, continue;
d->port_name, 8); } else {
rp->id = id;
memcpy(rp->port_name, d->port_name, 8);
rp->fc4type = FS_FC4TYPE_NVME;
break; break;
} }
} }
} }
break;
case FAB_SCAN_GNNFT_NVME:
for (k = 0; k < num_fibre_dev; k++) {
rp = &vha->scan.l[k];
if (id.b24 == rp->id.b24) {
memcpy(rp->node_name, d->port_name, 8);
break;
}
}
break;
default:
break;
} }
} }
} }
static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) static void qla_async_scan_sp_done(srb_t *sp, int res)
{ {
struct scsi_qla_host *vha = sp->vha; struct scsi_qla_host *vha = sp->vha;
struct ct_sns_req *ct_req =
(struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
u16 cmd = be16_to_cpu(ct_req->command);
u8 fc4_type = sp->gen2;
unsigned long flags; unsigned long flags;
int rc; int rc;
/* gen2 field is holding the fc4type */ /* gen2 field is holding the fc4type */
ql_dbg(ql_dbg_disc, vha, 0xffff, ql_dbg(ql_dbg_disc, vha, 0x2026,
"Async done-%s res %x FC4Type %x\n", "Async done-%s res %x step %x\n",
sp->name, res, sp->gen2); sp->name, res, vha->scan.step);
sp->rc = res; sp->rc = res;
if (res) { if (res) {
...@@ -3574,8 +3547,7 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) ...@@ -3574,8 +3547,7 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res)
* sp for GNNFT_DONE work. This will allow all * sp for GNNFT_DONE work. This will allow all
* the resource to get freed up. * the resource to get freed up.
*/ */
rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH);
QLA_EVT_GNNFT_DONE);
if (rc) { if (rc) {
/* Cleanup here to prevent memory leak */ /* Cleanup here to prevent memory leak */
qla24xx_sp_unmap(vha, sp); qla24xx_sp_unmap(vha, sp);
...@@ -3600,28 +3572,30 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) ...@@ -3600,28 +3572,30 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res)
qla2x00_find_free_fcp_nvme_slot(vha, sp); qla2x00_find_free_fcp_nvme_slot(vha, sp);
if ((fc4_type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled && spin_lock_irqsave(&vha->work_lock, flags);
cmd == GNN_FT_CMD) { vha->scan.scan_flags &= ~SF_SCANNING;
spin_lock_irqsave(&vha->work_lock, flags); spin_unlock_irqrestore(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);
sp->rc = res; switch (vha->scan.step) {
rc = qla2x00_post_nvme_gpnft_work(vha, sp, QLA_EVT_GPNFT); case FAB_SCAN_GPNFT_FCP:
if (rc) { case FAB_SCAN_GPNFT_NVME:
qla24xx_sp_unmap(vha, sp); rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_CMD);
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); break;
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); case FAB_SCAN_GNNFT_FCP:
} if (vha->flags.nvme_enabled)
return; rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_CMD);
} else
rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH);
if (cmd == GPN_FT_CMD) { break;
rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, case FAB_SCAN_GNNFT_NVME:
QLA_EVT_GPNFT_DONE); rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH);
} else { break;
rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, default:
QLA_EVT_GNNFT_DONE); /* should not be here */
WARN_ON(1);
rc = QLA_FUNCTION_FAILED;
break;
} }
if (rc) { if (rc) {
...@@ -3632,127 +3606,16 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) ...@@ -3632,127 +3606,16 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res)
} }
} }
/*
* Get WWNN list for fc4_type
*
* It is assumed the same SRB is re-used from GPNFT to avoid
* mem free & re-alloc
*/
static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
u8 fc4_type)
{
int rval = QLA_FUNCTION_FAILED;
struct ct_sns_req *ct_req;
struct ct_sns_pkt *ct_sns;
unsigned long flags;
if (!vha->flags.online) {
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);
goto done_free_sp;
}
if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) {
ql_log(ql_log_warn, vha, 0xffff,
"%s: req %p rsp %p are not setup\n",
__func__, sp->u.iocb_cmd.u.ctarg.req,
sp->u.iocb_cmd.u.ctarg.rsp);
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);
WARN_ON(1);
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
goto done_free_sp;
}
ql_dbg(ql_dbg_disc, vha, 0xfffff,
"%s: FC4Type %x, CT-PASSTHRU %s command ctarg rsp size %d, ctarg req size %d\n",
__func__, fc4_type, sp->name, sp->u.iocb_cmd.u.ctarg.rsp_size,
sp->u.iocb_cmd.u.ctarg.req_size);
sp->type = SRB_CT_PTHRU_CMD;
sp->name = "gnnft";
sp->gen1 = vha->hw->base_qpair->chip_reset;
sp->gen2 = fc4_type;
qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
qla2x00_async_gpnft_gnnft_sp_done);
memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
/* CT_IU preamble */
ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD,
sp->u.iocb_cmd.u.ctarg.rsp_size);
/* GPN_FT req */
ct_req->req.gpn_ft.port_type = fc4_type;
sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE;
sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
ql_dbg(ql_dbg_disc, vha, 0xffff,
"Async-%s hdl=%x FC4Type %x.\n", sp->name,
sp->handle, ct_req->req.gpn_ft.port_type);
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
goto done_free_sp;
}
return rval;
done_free_sp:
if (sp->u.iocb_cmd.u.ctarg.req) {
dma_free_coherent(&vha->hw->pdev->dev,
sp->u.iocb_cmd.u.ctarg.req_allocated_size,
sp->u.iocb_cmd.u.ctarg.req,
sp->u.iocb_cmd.u.ctarg.req_dma);
sp->u.iocb_cmd.u.ctarg.req = NULL;
}
if (sp->u.iocb_cmd.u.ctarg.rsp) {
dma_free_coherent(&vha->hw->pdev->dev,
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
sp->u.iocb_cmd.u.ctarg.rsp,
sp->u.iocb_cmd.u.ctarg.rsp_dma);
sp->u.iocb_cmd.u.ctarg.rsp = NULL;
}
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
if (vha->scan.scan_flags == 0) {
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s: schedule\n", __func__);
vha->scan.scan_flags |= SF_QUEUED;
schedule_delayed_work(&vha->scan.scan_work, 5);
}
spin_unlock_irqrestore(&vha->work_lock, flags);
return rval;
} /* GNNFT */
void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp)
{
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
"%s enter\n", __func__);
qla24xx_async_gnnft(vha, sp, sp->gen2);
}
/* Get WWPN list for certain fc4_type */ /* Get WWPN list for certain fc4_type */
int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) int qla_fab_async_scan(scsi_qla_host_t *vha, srb_t *sp)
{ {
int rval = QLA_FUNCTION_FAILED; int rval = QLA_FUNCTION_FAILED;
struct ct_sns_req *ct_req; struct ct_sns_req *ct_req;
struct ct_sns_pkt *ct_sns; struct ct_sns_pkt *ct_sns;
u32 rspsz; u32 rspsz = 0;
unsigned long flags; unsigned long flags;
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x200c,
"%s enter\n", __func__); "%s enter\n", __func__);
if (!vha->flags.online) if (!vha->flags.online)
...@@ -3761,22 +3624,21 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) ...@@ -3761,22 +3624,21 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
spin_lock_irqsave(&vha->work_lock, flags); spin_lock_irqsave(&vha->work_lock, flags);
if (vha->scan.scan_flags & SF_SCANNING) { if (vha->scan.scan_flags & SF_SCANNING) {
spin_unlock_irqrestore(&vha->work_lock, flags); spin_unlock_irqrestore(&vha->work_lock, flags);
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2012,
"%s: scan active\n", __func__); "%s: scan active\n", __func__);
return rval; return rval;
} }
vha->scan.scan_flags |= SF_SCANNING; vha->scan.scan_flags |= SF_SCANNING;
if (!sp)
vha->scan.step = FAB_SCAN_START;
spin_unlock_irqrestore(&vha->work_lock, flags); spin_unlock_irqrestore(&vha->work_lock, flags);
if (fc4_type == FC4_TYPE_FCP_SCSI) { switch (vha->scan.step) {
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, case FAB_SCAN_START:
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2018,
"%s: Performing FCP Scan\n", __func__); "%s: Performing FCP Scan\n", __func__);
if (sp) {
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
}
/* ref: INIT */ /* ref: INIT */
sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
if (!sp) { if (!sp) {
...@@ -3792,7 +3654,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) ...@@ -3792,7 +3654,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
GFP_KERNEL); GFP_KERNEL);
sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt); sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
if (!sp->u.iocb_cmd.u.ctarg.req) { if (!sp->u.iocb_cmd.u.ctarg.req) {
ql_log(ql_log_warn, vha, 0xffff, ql_log(ql_log_warn, vha, 0x201a,
"Failed to allocate ct_sns request.\n"); "Failed to allocate ct_sns request.\n");
spin_lock_irqsave(&vha->work_lock, flags); spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING; vha->scan.scan_flags &= ~SF_SCANNING;
...@@ -3800,7 +3662,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) ...@@ -3800,7 +3662,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
qla2x00_rel_sp(sp); qla2x00_rel_sp(sp);
return rval; return rval;
} }
sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE;
rspsz = sizeof(struct ct_sns_gpnft_rsp) + rspsz = sizeof(struct ct_sns_gpnft_rsp) +
vha->hw->max_fibre_devices * vha->hw->max_fibre_devices *
...@@ -3812,7 +3673,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) ...@@ -3812,7 +3673,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
GFP_KERNEL); GFP_KERNEL);
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz; sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz;
if (!sp->u.iocb_cmd.u.ctarg.rsp) { if (!sp->u.iocb_cmd.u.ctarg.rsp) {
ql_log(ql_log_warn, vha, 0xffff, ql_log(ql_log_warn, vha, 0x201b,
"Failed to allocate ct_sns request.\n"); "Failed to allocate ct_sns request.\n");
spin_lock_irqsave(&vha->work_lock, flags); spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING; vha->scan.scan_flags &= ~SF_SCANNING;
...@@ -3832,35 +3693,95 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) ...@@ -3832,35 +3693,95 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
"%s scan list size %d\n", __func__, vha->scan.size); "%s scan list size %d\n", __func__, vha->scan.size);
memset(vha->scan.l, 0, vha->scan.size); memset(vha->scan.l, 0, vha->scan.size);
} else if (!sp) {
ql_dbg(ql_dbg_disc, vha, 0xffff, vha->scan.step = FAB_SCAN_GPNFT_FCP;
"NVME scan did not provide SP\n"); break;
case FAB_SCAN_GPNFT_FCP:
vha->scan.step = FAB_SCAN_GNNFT_FCP;
break;
case FAB_SCAN_GNNFT_FCP:
vha->scan.step = FAB_SCAN_GPNFT_NVME;
break;
case FAB_SCAN_GPNFT_NVME:
vha->scan.step = FAB_SCAN_GNNFT_NVME;
break;
case FAB_SCAN_GNNFT_NVME:
default:
/* should not be here */
WARN_ON(1);
goto done_free_sp;
}
if (!sp) {
ql_dbg(ql_dbg_disc, vha, 0x201c,
"scan did not provide SP\n");
return rval; return rval;
} }
if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) {
ql_log(ql_log_warn, vha, 0x201d,
"%s: req %p rsp %p are not setup\n",
__func__, sp->u.iocb_cmd.u.ctarg.req,
sp->u.iocb_cmd.u.ctarg.rsp);
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);
WARN_ON(1);
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
goto done_free_sp;
}
rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size;
memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
sp->type = SRB_CT_PTHRU_CMD; sp->type = SRB_CT_PTHRU_CMD;
sp->name = "gpnft";
sp->gen1 = vha->hw->base_qpair->chip_reset; sp->gen1 = vha->hw->base_qpair->chip_reset;
sp->gen2 = fc4_type;
qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2, qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
qla2x00_async_gpnft_gnnft_sp_done); qla_async_scan_sp_done);
rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size;
memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
/* CT_IU preamble */
ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz);
/* GPN_FT req */ /* CT_IU preamble */
ct_req->req.gpn_ft.port_type = fc4_type; switch (vha->scan.step) {
case FAB_SCAN_GPNFT_FCP:
sp->name = "gpnft";
ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz);
ct_req->req.gpn_ft.port_type = FC4_TYPE_FCP_SCSI;
sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE;
break;
case FAB_SCAN_GNNFT_FCP:
sp->name = "gnnft";
ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, rspsz);
ct_req->req.gpn_ft.port_type = FC4_TYPE_FCP_SCSI;
sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE;
break;
case FAB_SCAN_GPNFT_NVME:
sp->name = "gpnft";
ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz);
ct_req->req.gpn_ft.port_type = FC4_TYPE_NVME;
sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE;
break;
case FAB_SCAN_GNNFT_NVME:
sp->name = "gnnft";
ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, rspsz);
ct_req->req.gpn_ft.port_type = FC4_TYPE_NVME;
sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE;
break;
default:
/* should not be here */
WARN_ON(1);
goto done_free_sp;
}
sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
ql_dbg(ql_dbg_disc, vha, 0xffff, ql_dbg(ql_dbg_disc, vha, 0x2003,
"Async-%s hdl=%x FC4Type %x.\n", sp->name, "%s: step %d, rsp size %d, req size %d hdl %x %s FC4TYPE %x \n",
sp->handle, ct_req->req.gpn_ft.port_type); __func__, vha->scan.step, sp->u.iocb_cmd.u.ctarg.rsp_size,
sp->u.iocb_cmd.u.ctarg.req_size, sp->handle, sp->name,
ct_req->req.gpn_ft.port_type);
rval = qla2x00_start_sp(sp); rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
...@@ -3891,7 +3812,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) ...@@ -3891,7 +3812,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
spin_lock_irqsave(&vha->work_lock, flags); spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING; vha->scan.scan_flags &= ~SF_SCANNING;
if (vha->scan.scan_flags == 0) { if (vha->scan.scan_flags == 0) {
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2007,
"%s: Scan scheduled.\n", __func__); "%s: Scan scheduled.\n", __func__);
vha->scan.scan_flags |= SF_QUEUED; vha->scan.scan_flags |= SF_QUEUED;
schedule_delayed_work(&vha->scan.scan_work, 5); schedule_delayed_work(&vha->scan.scan_work, 5);
...@@ -3902,6 +3823,15 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) ...@@ -3902,6 +3823,15 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
return rval; return rval;
} }
void qla_fab_scan_start(struct scsi_qla_host *vha)
{
int rval;
rval = qla_fab_async_scan(vha, NULL);
if (rval)
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
}
void qla_scan_work_fn(struct work_struct *work) void qla_scan_work_fn(struct work_struct *work)
{ {
struct fab_scan *s = container_of(to_delayed_work(work), struct fab_scan *s = container_of(to_delayed_work(work),
......
...@@ -6407,10 +6407,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) ...@@ -6407,10 +6407,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
if (USE_ASYNC_SCAN(ha)) { if (USE_ASYNC_SCAN(ha)) {
/* start of scan begins here */ /* start of scan begins here */
vha->scan.rscn_gen_end = atomic_read(&vha->rscn_gen); vha->scan.rscn_gen_end = atomic_read(&vha->rscn_gen);
rval = qla24xx_async_gpnft(vha, FC4_TYPE_FCP_SCSI, qla_fab_scan_start(vha);
NULL);
if (rval)
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
} else { } else {
list_for_each_entry(fcport, &vha->vp_fcports, list) list_for_each_entry(fcport, &vha->vp_fcports, list)
fcport->scan_state = QLA_FCPORT_SCAN; fcport->scan_state = QLA_FCPORT_SCAN;
......
...@@ -5558,15 +5558,11 @@ qla2x00_do_work(struct scsi_qla_host *vha) ...@@ -5558,15 +5558,11 @@ qla2x00_do_work(struct scsi_qla_host *vha)
qla2x00_async_prlo_done(vha, e->u.logio.fcport, qla2x00_async_prlo_done(vha, e->u.logio.fcport,
e->u.logio.data); e->u.logio.data);
break; break;
case QLA_EVT_GPNFT: case QLA_EVT_SCAN_CMD:
qla24xx_async_gpnft(vha, e->u.gpnft.fc4_type, qla_fab_async_scan(vha, e->u.iosb.sp);
e->u.gpnft.sp);
break; break;
case QLA_EVT_GPNFT_DONE: case QLA_EVT_SCAN_FINISH:
qla24xx_async_gpnft_done(vha, e->u.iosb.sp); qla_fab_scan_finish(vha, e->u.iosb.sp);
break;
case QLA_EVT_GNNFT_DONE:
qla24xx_async_gnnft_done(vha, e->u.iosb.sp);
break; break;
case QLA_EVT_GFPNID: case QLA_EVT_GFPNID:
qla24xx_async_gfpnid(vha, e->u.fcport.fcport); qla24xx_async_gfpnid(vha, e->u.fcport.fcport);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment