Skip to content

Commit

Permalink
scsi: qla2xxx: Add ability to use GPNFT/GNNFT for RSCN handling
Browse files Browse the repository at this point in the history
add ability to use gpnft/gnnft to handle RSCN.

Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Quinn Tran authored and Martin K. Petersen committed Jan 4, 2018
1 parent 0616e96 commit f352eeb
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 60 deletions.
7 changes: 7 additions & 0 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -2972,6 +2972,11 @@ struct ct_sns_gpnft_pkt {
} p;
};

enum scan_flags_t {
SF_SCANNING = BIT_0,
SF_QUEUED = BIT_1,
};

struct fab_scan_rp {
port_id_t id;
u8 port_name[8];
Expand All @@ -2981,6 +2986,8 @@ struct fab_scan_rp {
struct fab_scan {
struct fab_scan_rp *l;
u32 size;
enum scan_flags_t scan_flags;
struct delayed_work scan_work;
};

/*
Expand Down
1 change: 1 addition & 0 deletions drivers/scsi/qla2xxx/qla_gbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ int qla24xx_post_gfpnid_work(struct scsi_qla_host *, 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_sp_unmap(scsi_qla_host_t *, srb_t *);
void qla_scan_work_fn(struct work_struct *);

/*
* Global Function Prototypes in qla_attr.c source file.
Expand Down
99 changes: 69 additions & 30 deletions drivers/scsi/qla2xxx/qla_gs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2976,18 +2976,20 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea)
fc_port_t *fcport = ea->fcport;

ql_dbg(ql_dbg_disc, vha, 0x201d,
"%s %8phC login state %d\n",
__func__, fcport->port_name, fcport->fw_login_state);
"%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
__func__, fcport->port_name, fcport->disc_state,
fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
fcport->rscn_gen, ea->sp->gen1, fcport->loop_id);

if (fcport->disc_state == DSC_DELETE_PEND)
return;

if (ea->sp->gen2 != fcport->login_gen) {
/* PLOGI/PRLI/LOGO came in while cmd was out.*/
ql_dbg(ql_dbg_disc, vha, 0x201e,
"%s %8phC generation changed rscn %d|%d login %d|%d \n",
"%s %8phC generation changed rscn %d|%d n",
__func__, fcport->port_name, fcport->last_rscn_gen,
fcport->rscn_gen, fcport->last_login_gen, fcport->login_gen);
fcport->rscn_gen);
return;
}

Expand Down Expand Up @@ -3215,22 +3217,19 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea)
struct fc_port *fcport = ea->fcport;

ql_dbg(ql_dbg_disc, vha, 0x20d8,
"%s %8phC DS %d LS %d rscn %d|%d login %d|%d lid %d\n",
"%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
__func__, fcport->port_name, fcport->disc_state,
fcport->fw_login_state, fcport->last_rscn_gen, fcport->rscn_gen,
fcport->last_login_gen, fcport->login_gen,
fcport->loop_id);
fcport->fw_login_state, ea->rc, ea->sp->gen2, fcport->login_gen,
ea->sp->gen2, fcport->rscn_gen|ea->sp->gen1, fcport->loop_id);

if (fcport->disc_state == DSC_DELETE_PEND)
return;

if (ea->sp->gen2 != fcport->login_gen) {
/* target side must have changed it. */
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);
"%s %8phC generation changed\n",
__func__, fcport->port_name);
return;
} else if (ea->sp->gen1 != fcport->rscn_gen) {
ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
Expand Down Expand Up @@ -3862,6 +3861,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
bool found;
u8 fc4type = sp->gen2;
struct fab_scan_rp *rp;
unsigned long flags;

ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s enter\n", __func__);
Expand Down Expand Up @@ -3939,16 +3939,15 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
if ((fcport->flags & FCF_FABRIC_DEVICE) == 0)
continue;

if (fcport->scan_state == QLA_FCPORT_SCAN) {
if (fcport->scan_state != QLA_FCPORT_FOUND) {
if ((qla_dual_mode_enabled(vha) ||
qla_ini_mode_enabled(vha)) &&
atomic_read(&fcport->state) == FCS_ONLINE) {
qla2x00_mark_device_lost(vha, fcport,
ql2xplogiabsentdevice, 0);

if (fcport->loop_id != FC_NO_LOOP_ID &&
(fcport->flags & FCF_FCP2_DEVICE) == 0 &&
fcport->port_type != FCT_INITIATOR &&
fcport->port_type != FCT_BROADCAST) {
(fcport->flags & FCF_FCP2_DEVICE) == 0) {
ql_dbg(ql_dbg_disc, vha, 0x20f0,
"%s %d %8phC post del sess\n",
__func__, __LINE__,
Expand All @@ -3959,14 +3958,16 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
continue;
}
}
}

if (fcport->scan_state == QLA_FCPORT_FOUND)
} else
qla24xx_fcport_handle_login(vha, fcport);
}

out:
qla24xx_sp_unmap(vha, sp);

spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);
}

static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
Expand Down Expand Up @@ -3995,6 +3996,9 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
"Async done-%s timed out.\n",
sp->name);
sp->free(sp);
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
Expand Down Expand Up @@ -4086,14 +4090,17 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
struct ct_sns_req *ct_req;
struct ct_sns_pkt *ct_sns;

if (!vha->flags.online)
if (!vha->flags.online) {
vha->scan.scan_flags &= ~SF_SCANNING;
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);
vha->scan.scan_flags &= ~SF_SCANNING;
WARN_ON(1);
goto done_free_sp;
}
Expand Down Expand Up @@ -4166,14 +4173,25 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type)
srb_t *sp;
struct ct_sns_pkt *ct_sns;
u32 rspsz;
unsigned long flags;

if (!vha->flags.online)
return rval;

sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
if (!sp)
spin_lock_irqsave(&vha->work_lock, flags);
if (vha->scan.scan_flags & SF_SCANNING) {
spin_unlock_irqrestore(&vha->work_lock, flags);
ql_dbg(ql_dbg_disc, vha, 0xffff, "scan active\n");
return rval;
}
vha->scan.scan_flags |= SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);

sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
if (!sp) {
vha->scan.scan_flags &= ~SF_SCANNING;
return rval;
}

sp->type = SRB_CT_PTHRU_CMD;
sp->name = "gpnft";
Expand All @@ -4187,6 +4205,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type)
if (!sp->u.iocb_cmd.u.ctarg.req) {
ql_log(ql_log_warn, vha, 0xffff,
"Failed to allocate ct_sns request.\n");
vha->scan.scan_flags &= ~SF_SCANNING;
goto done_free_sp;
}

Expand All @@ -4199,6 +4218,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type)
if (!sp->u.iocb_cmd.u.ctarg.rsp) {
ql_log(ql_log_warn, vha, 0xffff,
"Failed to allocate ct_sns request.\n");
vha->scan.scan_flags &= ~SF_SCANNING;
goto done_free_sp;
}

Expand All @@ -4219,8 +4239,10 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type)
sp->done = qla2x00_async_gpnft_gnnft_sp_done;

rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS)
if (rval != QLA_SUCCESS) {
vha->scan.scan_flags &= ~SF_SCANNING;
goto done_free_sp;
}

ql_dbg(ql_dbg_disc, vha, 0xffff,
"Async-%s hdl=%x FC4Type %x.\n", sp->name,
Expand Down Expand Up @@ -4248,6 +4270,24 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type)
return rval;
}

void qla_scan_work_fn(struct work_struct *work)
{
struct fab_scan *s = container_of(to_delayed_work(work),
struct fab_scan, scan_work);
struct scsi_qla_host *vha = container_of(s, struct scsi_qla_host,
scan);
unsigned long flags;

ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s: schedule loop resync\n", __func__);
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_QUEUED;
spin_unlock_irqrestore(&vha->work_lock, flags);
}

/* GNN_ID */
void qla24xx_handle_gnnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
{
Expand Down Expand Up @@ -4367,20 +4407,19 @@ void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
fc_port_t *fcport = ea->fcport;

ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s %d %8phC post gpsc fcp_cnt %d\n",
__func__, __LINE__, fcport->port_name,
vha->fcport_count);
"%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d fcpcnt %d\n",
__func__, fcport->port_name, fcport->disc_state,
fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
fcport->rscn_gen, ea->sp->gen1, vha->fcport_count);

if (fcport->disc_state == DSC_DELETE_PEND)
return;

if (ea->sp->gen2 != fcport->login_gen) {
/* target side must have changed it. */
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);
"%s %8phC generation changed\n",
__func__, fcport->port_name);
return;
} else if (ea->sp->gen1 != fcport->rscn_gen) {
ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
Expand Down
Loading

0 comments on commit f352eeb

Please sign in to comment.