mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 07:31:29 +00:00
Merge patch series "qla2xxx misc. bug fixes"
Nilesh Javali <njavali@marvell.com> says: Martin, Please apply the qla2xxx driver miscellaneous bug fixes to the scsi tree at your earliest convenience. Link: https://lore.kernel.org/r/20240710171057.35066-1-njavali@marvell.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
commit
22b8d89b9d
@ -324,7 +324,7 @@ qla2x00_process_els(struct bsg_job *bsg_job)
|
||||
"request_sg_cnt=%x reply_sg_cnt=%x.\n",
|
||||
bsg_job->request_payload.sg_cnt,
|
||||
bsg_job->reply_payload.sg_cnt);
|
||||
rval = -EPERM;
|
||||
rval = -ENOBUFS;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -3059,16 +3059,60 @@ skip_chip_chk:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool qla_bsg_found(struct qla_qpair *qpair, struct bsg_job *bsg_job)
|
||||
{
|
||||
bool found = false;
|
||||
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
|
||||
scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
srb_t *sp = NULL;
|
||||
int cnt;
|
||||
unsigned long flags;
|
||||
struct req_que *req;
|
||||
|
||||
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
|
||||
req = qpair->req;
|
||||
|
||||
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
|
||||
sp = req->outstanding_cmds[cnt];
|
||||
if (sp &&
|
||||
(sp->type == SRB_CT_CMD ||
|
||||
sp->type == SRB_ELS_CMD_HST ||
|
||||
sp->type == SRB_ELS_CMD_HST_NOLOGIN) &&
|
||||
sp->u.bsg_job == bsg_job) {
|
||||
req->outstanding_cmds[cnt] = NULL;
|
||||
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
|
||||
|
||||
if (!ha->flags.eeh_busy && ha->isp_ops->abort_command(sp)) {
|
||||
ql_log(ql_log_warn, vha, 0x7089,
|
||||
"mbx abort_command failed.\n");
|
||||
bsg_reply->result = -EIO;
|
||||
} else {
|
||||
ql_dbg(ql_dbg_user, vha, 0x708a,
|
||||
"mbx abort_command success.\n");
|
||||
bsg_reply->result = 0;
|
||||
}
|
||||
/* ref: INIT */
|
||||
kref_put(&sp->cmd_kref, qla2x00_sp_release);
|
||||
|
||||
found = true;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
|
||||
|
||||
done:
|
||||
return found;
|
||||
}
|
||||
|
||||
int
|
||||
qla24xx_bsg_timeout(struct bsg_job *bsg_job)
|
||||
{
|
||||
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
|
||||
scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
srb_t *sp;
|
||||
int cnt, que;
|
||||
unsigned long flags;
|
||||
struct req_que *req;
|
||||
int i;
|
||||
struct qla_qpair *qpair;
|
||||
|
||||
ql_log(ql_log_info, vha, 0x708b, "%s CMD timeout. bsg ptr %p.\n",
|
||||
__func__, bsg_job);
|
||||
@ -3079,48 +3123,22 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_job)
|
||||
qla_pci_set_eeh_busy(vha);
|
||||
}
|
||||
|
||||
if (qla_bsg_found(ha->base_qpair, bsg_job))
|
||||
goto done;
|
||||
|
||||
/* find the bsg job from the active list of commands */
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
for (que = 0; que < ha->max_req_queues; que++) {
|
||||
req = ha->req_q_map[que];
|
||||
if (!req)
|
||||
for (i = 0; i < ha->max_qpairs; i++) {
|
||||
qpair = vha->hw->queue_pair_map[i];
|
||||
if (!qpair)
|
||||
continue;
|
||||
|
||||
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
|
||||
sp = req->outstanding_cmds[cnt];
|
||||
if (sp &&
|
||||
(sp->type == SRB_CT_CMD ||
|
||||
sp->type == SRB_ELS_CMD_HST ||
|
||||
sp->type == SRB_ELS_CMD_HST_NOLOGIN ||
|
||||
sp->type == SRB_FXIOCB_BCMD) &&
|
||||
sp->u.bsg_job == bsg_job) {
|
||||
req->outstanding_cmds[cnt] = NULL;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
if (!ha->flags.eeh_busy && ha->isp_ops->abort_command(sp)) {
|
||||
ql_log(ql_log_warn, vha, 0x7089,
|
||||
"mbx abort_command failed.\n");
|
||||
bsg_reply->result = -EIO;
|
||||
} else {
|
||||
ql_dbg(ql_dbg_user, vha, 0x708a,
|
||||
"mbx abort_command success.\n");
|
||||
bsg_reply->result = 0;
|
||||
}
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
goto done;
|
||||
|
||||
}
|
||||
}
|
||||
if (qla_bsg_found(qpair, bsg_job))
|
||||
goto done;
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n");
|
||||
bsg_reply->result = -ENXIO;
|
||||
return 0;
|
||||
|
||||
done:
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
/* ref: INIT */
|
||||
kref_put(&sp->cmd_kref, qla2x00_sp_release);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3309,9 +3309,20 @@ struct fab_scan_rp {
|
||||
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_rp *l;
|
||||
u32 size;
|
||||
u32 rscn_gen_start;
|
||||
u32 rscn_gen_end;
|
||||
enum scan_step step;
|
||||
u16 scan_retry;
|
||||
#define MAX_SCAN_RETRIES 5
|
||||
enum scan_flags_t scan_flags;
|
||||
@ -3537,9 +3548,8 @@ enum qla_work_type {
|
||||
QLA_EVT_RELOGIN,
|
||||
QLA_EVT_ASYNC_PRLO,
|
||||
QLA_EVT_ASYNC_PRLO_DONE,
|
||||
QLA_EVT_GPNFT,
|
||||
QLA_EVT_GPNFT_DONE,
|
||||
QLA_EVT_GNNFT_DONE,
|
||||
QLA_EVT_SCAN_CMD,
|
||||
QLA_EVT_SCAN_FINISH,
|
||||
QLA_EVT_GFPNID,
|
||||
QLA_EVT_SP_RETRY,
|
||||
QLA_EVT_IIDMA,
|
||||
@ -5030,6 +5040,7 @@ typedef struct scsi_qla_host {
|
||||
|
||||
/* Counter to detect races between ELS and RSCN events */
|
||||
atomic_t generation_tick;
|
||||
atomic_t rscn_gen;
|
||||
/* Time when global fcport update has been scheduled */
|
||||
int total_fcport_update_gen;
|
||||
/* List of pending LOGOs, protected by tgt_mutex */
|
||||
|
@ -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 *);
|
||||
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_gpnft(scsi_qla_host_t *, u8, srb_t *);
|
||||
void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *);
|
||||
void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *);
|
||||
int qla_fab_async_scan(scsi_qla_host_t *, srb_t *);
|
||||
void qla_fab_scan_start(struct scsi_qla_host *);
|
||||
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_async_gfpnid(scsi_qla_host_t *, fc_port_t *);
|
||||
void qla24xx_handle_gfpnid_event(scsi_qla_host_t *, struct event_arg *);
|
||||
|
@ -1710,7 +1710,7 @@ qla2x00_hba_attributes(scsi_qla_host_t *vha, void *entries,
|
||||
eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
|
||||
alen = scnprintf(
|
||||
eiter->a.orom_version, sizeof(eiter->a.orom_version),
|
||||
"%d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
|
||||
"%d.%02d", ha->efi_revision[1], ha->efi_revision[0]);
|
||||
alen += FDMI_ATTR_ALIGNMENT(alen);
|
||||
alen += FDMI_ATTR_TYPELEN(eiter);
|
||||
eiter->len = cpu_to_be16(alen);
|
||||
@ -3168,7 +3168,30 @@ static int qla2x00_is_a_vp(scsi_qla_host_t *vha, u64 wwn)
|
||||
return rc;
|
||||
}
|
||||
|
||||
void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
|
||||
static bool qla_ok_to_clear_rscn(scsi_qla_host_t *vha, fc_port_t *fcport)
|
||||
{
|
||||
u32 rscn_gen;
|
||||
|
||||
rscn_gen = atomic_read(&vha->rscn_gen);
|
||||
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2017,
|
||||
"%s %d %8phC rscn_gen %x start %x end %x current %x\n",
|
||||
__func__, __LINE__, fcport->port_name, fcport->rscn_gen,
|
||||
vha->scan.rscn_gen_start, vha->scan.rscn_gen_end, rscn_gen);
|
||||
|
||||
if (val_is_in_range(fcport->rscn_gen, vha->scan.rscn_gen_start,
|
||||
vha->scan.rscn_gen_end))
|
||||
/* rscn came in before fabric scan */
|
||||
return true;
|
||||
|
||||
if (val_is_in_range(fcport->rscn_gen, vha->scan.rscn_gen_end, rscn_gen))
|
||||
/* rscn came in after fabric scan */
|
||||
return false;
|
||||
|
||||
/* rare: fcport's scan_needed + rscn_gen must be stale */
|
||||
return true;
|
||||
}
|
||||
|
||||
void qla_fab_scan_finish(scsi_qla_host_t *vha, srb_t *sp)
|
||||
{
|
||||
fc_port_t *fcport;
|
||||
u32 i, rc;
|
||||
@ -3281,10 +3304,10 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
|
||||
(fcport->scan_needed &&
|
||||
fcport->port_type != FCT_INITIATOR &&
|
||||
fcport->port_type != FCT_NVME_INITIATOR)) {
|
||||
fcport->scan_needed = 0;
|
||||
qlt_schedule_sess_for_deletion(fcport);
|
||||
}
|
||||
fcport->d_id.b24 = rp->id.b24;
|
||||
fcport->scan_needed = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3325,7 +3348,9 @@ login_logout:
|
||||
do_delete = true;
|
||||
}
|
||||
|
||||
fcport->scan_needed = 0;
|
||||
if (qla_ok_to_clear_rscn(vha, fcport))
|
||||
fcport->scan_needed = 0;
|
||||
|
||||
if (((qla_dual_mode_enabled(vha) ||
|
||||
qla_ini_mode_enabled(vha)) &&
|
||||
atomic_read(&fcport->state) == FCS_ONLINE) ||
|
||||
@ -3355,7 +3380,9 @@ login_logout:
|
||||
fcport->port_name, fcport->loop_id,
|
||||
fcport->login_retry);
|
||||
}
|
||||
fcport->scan_needed = 0;
|
||||
|
||||
if (qla_ok_to_clear_rscn(vha, fcport))
|
||||
fcport->scan_needed = 0;
|
||||
qla24xx_fcport_handle_login(vha, fcport);
|
||||
}
|
||||
}
|
||||
@ -3379,14 +3406,11 @@ out:
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if (!e)
|
||||
return QLA_FUNCTION_FAILED;
|
||||
@ -3396,37 +3420,15 @@ static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha,
|
||||
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,
|
||||
struct srb *sp)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
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 *)sp->u.iocb_cmd.u.ctarg.rsp;
|
||||
struct ct_sns_gpn_ft_data *d;
|
||||
struct fab_scan_rp *rp;
|
||||
u16 cmd = be16_to_cpu(ct_req->command);
|
||||
u8 fc4_type = sp->gen2;
|
||||
int i, j, k;
|
||||
port_id_t id;
|
||||
u8 found;
|
||||
@ -3445,85 +3447,83 @@ static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
|
||||
if (id.b24 == 0 || wwn == 0)
|
||||
continue;
|
||||
|
||||
if (fc4_type == FC4_TYPE_FCP_SCSI) {
|
||||
if (cmd == GPN_FT_CMD) {
|
||||
rp = &vha->scan.l[j];
|
||||
rp->id = id;
|
||||
memcpy(rp->port_name, d->port_name, 8);
|
||||
j++;
|
||||
rp->fc4type = FS_FC4TYPE_FCP;
|
||||
} else {
|
||||
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2025,
|
||||
"%s %06x %8ph \n",
|
||||
__func__, id.b24, d->port_name);
|
||||
|
||||
switch (vha->scan.step) {
|
||||
case FAB_SCAN_GPNFT_FCP:
|
||||
rp = &vha->scan.l[j];
|
||||
rp->id = id;
|
||||
memcpy(rp->port_name, d->port_name, 8);
|
||||
j++;
|
||||
rp->fc4type = FS_FC4TYPE_FCP;
|
||||
break;
|
||||
case FAB_SCAN_GNNFT_FCP:
|
||||
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;
|
||||
case FAB_SCAN_GPNFT_NVME:
|
||||
found = 0;
|
||||
|
||||
for (k = 0; k < num_fibre_dev; k++) {
|
||||
rp = &vha->scan.l[k];
|
||||
if (!memcmp(rp->port_name, d->port_name, 8)) {
|
||||
/*
|
||||
* Supports FC-NVMe & FCP
|
||||
*/
|
||||
rp->fc4type |= FS_FC4TYPE_NVME;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We found new FC-NVMe only port */
|
||||
if (!found) {
|
||||
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);
|
||||
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 {
|
||||
/* Search if the fibre device supports FC4_TYPE_NVME */
|
||||
if (cmd == GPN_FT_CMD) {
|
||||
found = 0;
|
||||
|
||||
for (k = 0; k < num_fibre_dev; k++) {
|
||||
rp = &vha->scan.l[k];
|
||||
if (!memcmp(rp->port_name,
|
||||
d->port_name, 8)) {
|
||||
/*
|
||||
* Supports FC-NVMe & FCP
|
||||
*/
|
||||
rp->fc4type |= FS_FC4TYPE_NVME;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We found new FC-NVMe only port */
|
||||
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++) {
|
||||
rp = &vha->scan.l[k];
|
||||
if (id.b24 == rp->id.b24) {
|
||||
memcpy(rp->node_name,
|
||||
d->port_name, 8);
|
||||
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 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;
|
||||
int rc;
|
||||
|
||||
/* gen2 field is holding the fc4type */
|
||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||
"Async done-%s res %x FC4Type %x\n",
|
||||
sp->name, res, sp->gen2);
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2026,
|
||||
"Async done-%s res %x step %x\n",
|
||||
sp->name, res, vha->scan.step);
|
||||
|
||||
sp->rc = res;
|
||||
if (res) {
|
||||
@ -3547,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
|
||||
* the resource to get freed up.
|
||||
*/
|
||||
rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
|
||||
QLA_EVT_GNNFT_DONE);
|
||||
rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH);
|
||||
if (rc) {
|
||||
/* Cleanup here to prevent memory leak */
|
||||
qla24xx_sp_unmap(vha, sp);
|
||||
@ -3573,28 +3572,30 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res)
|
||||
|
||||
qla2x00_find_free_fcp_nvme_slot(vha, sp);
|
||||
|
||||
if ((fc4_type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled &&
|
||||
cmd == GNN_FT_CMD) {
|
||||
spin_lock_irqsave(&vha->work_lock, flags);
|
||||
vha->scan.scan_flags &= ~SF_SCANNING;
|
||||
spin_unlock_irqrestore(&vha->work_lock, flags);
|
||||
spin_lock_irqsave(&vha->work_lock, flags);
|
||||
vha->scan.scan_flags &= ~SF_SCANNING;
|
||||
spin_unlock_irqrestore(&vha->work_lock, flags);
|
||||
|
||||
sp->rc = res;
|
||||
rc = qla2x00_post_nvme_gpnft_work(vha, sp, QLA_EVT_GPNFT);
|
||||
if (rc) {
|
||||
qla24xx_sp_unmap(vha, sp);
|
||||
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
|
||||
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (vha->scan.step) {
|
||||
case FAB_SCAN_GPNFT_FCP:
|
||||
case FAB_SCAN_GPNFT_NVME:
|
||||
rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_CMD);
|
||||
break;
|
||||
case FAB_SCAN_GNNFT_FCP:
|
||||
if (vha->flags.nvme_enabled)
|
||||
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) {
|
||||
rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
|
||||
QLA_EVT_GPNFT_DONE);
|
||||
} else {
|
||||
rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
|
||||
QLA_EVT_GNNFT_DONE);
|
||||
break;
|
||||
case FAB_SCAN_GNNFT_NVME:
|
||||
rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH);
|
||||
break;
|
||||
default:
|
||||
/* should not be here */
|
||||
WARN_ON(1);
|
||||
rc = QLA_FUNCTION_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
@ -3605,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 */
|
||||
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;
|
||||
struct ct_sns_req *ct_req;
|
||||
struct ct_sns_pkt *ct_sns;
|
||||
u32 rspsz;
|
||||
u32 rspsz = 0;
|
||||
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__);
|
||||
|
||||
if (!vha->flags.online)
|
||||
@ -3734,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);
|
||||
if (vha->scan.scan_flags & SF_SCANNING) {
|
||||
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__);
|
||||
return rval;
|
||||
}
|
||||
vha->scan.scan_flags |= SF_SCANNING;
|
||||
if (!sp)
|
||||
vha->scan.step = FAB_SCAN_START;
|
||||
|
||||
spin_unlock_irqrestore(&vha->work_lock, flags);
|
||||
|
||||
if (fc4_type == FC4_TYPE_FCP_SCSI) {
|
||||
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
|
||||
switch (vha->scan.step) {
|
||||
case FAB_SCAN_START:
|
||||
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2018,
|
||||
"%s: Performing FCP Scan\n", __func__);
|
||||
|
||||
if (sp) {
|
||||
/* ref: INIT */
|
||||
kref_put(&sp->cmd_kref, qla2x00_sp_release);
|
||||
}
|
||||
|
||||
/* ref: INIT */
|
||||
sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
|
||||
if (!sp) {
|
||||
@ -3765,7 +3654,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
|
||||
GFP_KERNEL);
|
||||
sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
|
||||
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");
|
||||
spin_lock_irqsave(&vha->work_lock, flags);
|
||||
vha->scan.scan_flags &= ~SF_SCANNING;
|
||||
@ -3773,7 +3662,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
|
||||
qla2x00_rel_sp(sp);
|
||||
return rval;
|
||||
}
|
||||
sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE;
|
||||
|
||||
rspsz = sizeof(struct ct_sns_gpnft_rsp) +
|
||||
vha->hw->max_fibre_devices *
|
||||
@ -3785,7 +3673,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
|
||||
GFP_KERNEL);
|
||||
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz;
|
||||
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");
|
||||
spin_lock_irqsave(&vha->work_lock, flags);
|
||||
vha->scan.scan_flags &= ~SF_SCANNING;
|
||||
@ -3805,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);
|
||||
|
||||
memset(vha->scan.l, 0, vha->scan.size);
|
||||
} else if (!sp) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||
"NVME scan did not provide SP\n");
|
||||
return rval;
|
||||
|
||||
vha->scan.step = FAB_SCAN_GPNFT_FCP;
|
||||
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;
|
||||
}
|
||||
|
||||
sp->type = SRB_CT_PTHRU_CMD;
|
||||
sp->name = "gpnft";
|
||||
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);
|
||||
if (!sp) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x201c,
|
||||
"scan did not provide SP\n");
|
||||
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.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);
|
||||
memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
|
||||
|
||||
|
||||
sp->type = SRB_CT_PTHRU_CMD;
|
||||
sp->gen1 = vha->hw->base_qpair->chip_reset;
|
||||
qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
|
||||
qla_async_scan_sp_done);
|
||||
|
||||
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_req->req.gpn_ft.port_type = fc4_type;
|
||||
/* CT_IU preamble */
|
||||
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;
|
||||
|
||||
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);
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2003,
|
||||
"%s: step %d, rsp size %d, req size %d hdl %x %s FC4TYPE %x \n",
|
||||
__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);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
@ -3864,7 +3812,7 @@ done_free_sp:
|
||||
spin_lock_irqsave(&vha->work_lock, flags);
|
||||
vha->scan.scan_flags &= ~SF_SCANNING;
|
||||
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__);
|
||||
vha->scan.scan_flags |= SF_QUEUED;
|
||||
schedule_delayed_work(&vha->scan.scan_work, 5);
|
||||
@ -3875,6 +3823,15 @@ done_free_sp:
|
||||
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)
|
||||
{
|
||||
struct fab_scan *s = container_of(to_delayed_work(work),
|
||||
|
@ -1842,10 +1842,18 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id,
|
||||
return qla2x00_post_work(vha, e);
|
||||
}
|
||||
|
||||
static void qla_rscn_gen_tick(scsi_qla_host_t *vha, u32 *ret_rscn_gen)
|
||||
{
|
||||
*ret_rscn_gen = atomic_inc_return(&vha->rscn_gen);
|
||||
/* memory barrier */
|
||||
wmb();
|
||||
}
|
||||
|
||||
void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
{
|
||||
fc_port_t *fcport;
|
||||
unsigned long flags;
|
||||
u32 rscn_gen;
|
||||
|
||||
switch (ea->id.b.rsvd_1) {
|
||||
case RSCN_PORT_ADDR:
|
||||
@ -1875,15 +1883,16 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
* Otherwise we're already in the middle of a relogin
|
||||
*/
|
||||
fcport->scan_needed = 1;
|
||||
fcport->rscn_gen++;
|
||||
qla_rscn_gen_tick(vha, &fcport->rscn_gen);
|
||||
}
|
||||
} else {
|
||||
fcport->scan_needed = 1;
|
||||
fcport->rscn_gen++;
|
||||
qla_rscn_gen_tick(vha, &fcport->rscn_gen);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RSCN_AREA_ADDR:
|
||||
qla_rscn_gen_tick(vha, &rscn_gen);
|
||||
list_for_each_entry(fcport, &vha->vp_fcports, list) {
|
||||
if (fcport->flags & FCF_FCP2_DEVICE &&
|
||||
atomic_read(&fcport->state) == FCS_ONLINE)
|
||||
@ -1891,11 +1900,12 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
|
||||
if ((ea->id.b24 & 0xffff00) == (fcport->d_id.b24 & 0xffff00)) {
|
||||
fcport->scan_needed = 1;
|
||||
fcport->rscn_gen++;
|
||||
fcport->rscn_gen = rscn_gen;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RSCN_DOM_ADDR:
|
||||
qla_rscn_gen_tick(vha, &rscn_gen);
|
||||
list_for_each_entry(fcport, &vha->vp_fcports, list) {
|
||||
if (fcport->flags & FCF_FCP2_DEVICE &&
|
||||
atomic_read(&fcport->state) == FCS_ONLINE)
|
||||
@ -1903,19 +1913,20 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
|
||||
if ((ea->id.b24 & 0xff0000) == (fcport->d_id.b24 & 0xff0000)) {
|
||||
fcport->scan_needed = 1;
|
||||
fcport->rscn_gen++;
|
||||
fcport->rscn_gen = rscn_gen;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RSCN_FAB_ADDR:
|
||||
default:
|
||||
qla_rscn_gen_tick(vha, &rscn_gen);
|
||||
list_for_each_entry(fcport, &vha->vp_fcports, list) {
|
||||
if (fcport->flags & FCF_FCP2_DEVICE &&
|
||||
atomic_read(&fcport->state) == FCS_ONLINE)
|
||||
continue;
|
||||
|
||||
fcport->scan_needed = 1;
|
||||
fcport->rscn_gen++;
|
||||
fcport->rscn_gen = rscn_gen;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1924,6 +1935,7 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
if (vha->scan.scan_flags == 0) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0xffff, "%s: schedule\n", __func__);
|
||||
vha->scan.scan_flags |= SF_QUEUED;
|
||||
vha->scan.rscn_gen_start = atomic_read(&vha->rscn_gen);
|
||||
schedule_delayed_work(&vha->scan.scan_work, 5);
|
||||
}
|
||||
spin_unlock_irqrestore(&vha->work_lock, flags);
|
||||
@ -6393,10 +6405,9 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
|
||||
qlt_do_generation_tick(vha, &discovery_gen);
|
||||
|
||||
if (USE_ASYNC_SCAN(ha)) {
|
||||
rval = qla24xx_async_gpnft(vha, FC4_TYPE_FCP_SCSI,
|
||||
NULL);
|
||||
if (rval)
|
||||
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
|
||||
/* start of scan begins here */
|
||||
vha->scan.rscn_gen_end = atomic_read(&vha->rscn_gen);
|
||||
qla_fab_scan_start(vha);
|
||||
} else {
|
||||
list_for_each_entry(fcport, &vha->vp_fcports, list)
|
||||
fcport->scan_state = QLA_FCPORT_SCAN;
|
||||
@ -8207,15 +8218,21 @@ qla28xx_get_aux_images(
|
||||
struct qla27xx_image_status pri_aux_image_status, sec_aux_image_status;
|
||||
bool valid_pri_image = false, valid_sec_image = false;
|
||||
bool active_pri_image = false, active_sec_image = false;
|
||||
int rc;
|
||||
|
||||
if (!ha->flt_region_aux_img_status_pri) {
|
||||
ql_dbg(ql_dbg_init, vha, 0x018a, "Primary aux image not addressed\n");
|
||||
goto check_sec_image;
|
||||
}
|
||||
|
||||
qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status,
|
||||
rc = qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status,
|
||||
ha->flt_region_aux_img_status_pri,
|
||||
sizeof(pri_aux_image_status) >> 2);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x01a1,
|
||||
"Unable to read Primary aux image(%x).\n", rc);
|
||||
goto check_sec_image;
|
||||
}
|
||||
qla27xx_print_image(vha, "Primary aux image", &pri_aux_image_status);
|
||||
|
||||
if (qla28xx_check_aux_image_status_signature(&pri_aux_image_status)) {
|
||||
@ -8246,9 +8263,15 @@ check_sec_image:
|
||||
goto check_valid_image;
|
||||
}
|
||||
|
||||
qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status,
|
||||
rc = qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status,
|
||||
ha->flt_region_aux_img_status_sec,
|
||||
sizeof(sec_aux_image_status) >> 2);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x01a2,
|
||||
"Unable to read Secondary aux image(%x).\n", rc);
|
||||
goto check_valid_image;
|
||||
}
|
||||
|
||||
qla27xx_print_image(vha, "Secondary aux image", &sec_aux_image_status);
|
||||
|
||||
if (qla28xx_check_aux_image_status_signature(&sec_aux_image_status)) {
|
||||
@ -8306,6 +8329,7 @@ qla27xx_get_active_image(struct scsi_qla_host *vha,
|
||||
struct qla27xx_image_status pri_image_status, sec_image_status;
|
||||
bool valid_pri_image = false, valid_sec_image = false;
|
||||
bool active_pri_image = false, active_sec_image = false;
|
||||
int rc;
|
||||
|
||||
if (!ha->flt_region_img_status_pri) {
|
||||
ql_dbg(ql_dbg_init, vha, 0x018a, "Primary image not addressed\n");
|
||||
@ -8347,8 +8371,14 @@ check_sec_image:
|
||||
goto check_valid_image;
|
||||
}
|
||||
|
||||
qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status),
|
||||
rc = qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status),
|
||||
ha->flt_region_img_status_sec, sizeof(sec_image_status) >> 2);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x01a3,
|
||||
"Unable to read Secondary image status(%x).\n", rc);
|
||||
goto check_valid_image;
|
||||
}
|
||||
|
||||
qla27xx_print_image(vha, "Secondary image", &sec_image_status);
|
||||
|
||||
if (qla27xx_check_image_status_signature(&sec_image_status)) {
|
||||
@ -8420,11 +8450,10 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
|
||||
"FW: Loading firmware from flash (%x).\n", faddr);
|
||||
|
||||
dcode = (uint32_t *)req->ring;
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, 8);
|
||||
if (qla24xx_risc_firmware_invalid(dcode)) {
|
||||
rval = qla24xx_read_flash_data(vha, dcode, faddr, 8);
|
||||
if (rval || qla24xx_risc_firmware_invalid(dcode)) {
|
||||
ql_log(ql_log_fatal, vha, 0x008c,
|
||||
"Unable to verify the integrity of flash firmware "
|
||||
"image.\n");
|
||||
"Unable to verify the integrity of flash firmware image (rval %x).\n", rval);
|
||||
ql_log(ql_log_fatal, vha, 0x008d,
|
||||
"Firmware data: %08x %08x %08x %08x.\n",
|
||||
dcode[0], dcode[1], dcode[2], dcode[3]);
|
||||
@ -8438,7 +8467,12 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
|
||||
for (j = 0; j < segments; j++) {
|
||||
ql_dbg(ql_dbg_init, vha, 0x008d,
|
||||
"-> Loading segment %u...\n", j);
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, 10);
|
||||
rval = qla24xx_read_flash_data(vha, dcode, faddr, 10);
|
||||
if (rval) {
|
||||
ql_log(ql_log_fatal, vha, 0x016a,
|
||||
"-> Unable to read segment addr + size .\n");
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
risc_addr = be32_to_cpu((__force __be32)dcode[2]);
|
||||
risc_size = be32_to_cpu((__force __be32)dcode[3]);
|
||||
if (!*srisc_addr) {
|
||||
@ -8454,7 +8488,13 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
|
||||
ql_dbg(ql_dbg_init, vha, 0x008e,
|
||||
"-> Loading fragment %u: %#x <- %#x (%#lx dwords)...\n",
|
||||
fragment, risc_addr, faddr, dlen);
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, dlen);
|
||||
rval = qla24xx_read_flash_data(vha, dcode, faddr, dlen);
|
||||
if (rval) {
|
||||
ql_log(ql_log_fatal, vha, 0x016b,
|
||||
"-> Unable to read fragment(faddr %#x dlen %#lx).\n",
|
||||
faddr, dlen);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
for (i = 0; i < dlen; i++)
|
||||
dcode[i] = swab32(dcode[i]);
|
||||
|
||||
@ -8483,7 +8523,14 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
|
||||
fwdt->length = 0;
|
||||
|
||||
dcode = (uint32_t *)req->ring;
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, 7);
|
||||
|
||||
rval = qla24xx_read_flash_data(vha, dcode, faddr, 7);
|
||||
if (rval) {
|
||||
ql_log(ql_log_fatal, vha, 0x016c,
|
||||
"-> Unable to read template size.\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
risc_size = be32_to_cpu((__force __be32)dcode[2]);
|
||||
ql_dbg(ql_dbg_init, vha, 0x0161,
|
||||
"-> fwdt%u template array at %#x (%#x dwords)\n",
|
||||
@ -8509,11 +8556,12 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
|
||||
}
|
||||
|
||||
dcode = fwdt->template;
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, risc_size);
|
||||
rval = qla24xx_read_flash_data(vha, dcode, faddr, risc_size);
|
||||
|
||||
if (!qla27xx_fwdt_template_valid(dcode)) {
|
||||
if (rval || !qla27xx_fwdt_template_valid(dcode)) {
|
||||
ql_log(ql_log_warn, vha, 0x0165,
|
||||
"-> fwdt%u failed template validate\n", j);
|
||||
"-> fwdt%u failed template validate (rval %x)\n",
|
||||
j, rval);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -631,3 +631,11 @@ static inline int qla_mapq_alloc_qp_cpu_map(struct qla_hw_data *ha)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool val_is_in_range(u32 val, u32 start, u32 end)
|
||||
{
|
||||
if (val >= start && val <= end)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ qla24xx_disable_vp(scsi_qla_host_t *vha)
|
||||
atomic_set(&vha->loop_state, LOOP_DOWN);
|
||||
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
|
||||
list_for_each_entry(fcport, &vha->vp_fcports, list)
|
||||
fcport->logout_on_delete = 0;
|
||||
fcport->logout_on_delete = 1;
|
||||
|
||||
if (!vha->hw->flags.edif_enabled)
|
||||
qla2x00_wait_for_sess_deletion(vha);
|
||||
|
@ -49,7 +49,10 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!vha->nvme_local_port && qla_nvme_register_hba(vha))
|
||||
if (qla_nvme_register_hba(vha))
|
||||
return 0;
|
||||
|
||||
if (!vha->nvme_local_port)
|
||||
return 0;
|
||||
|
||||
if (!(fcport->nvme_prli_service_param &
|
||||
|
@ -1875,14 +1875,9 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
|
||||
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
|
||||
sp = req->outstanding_cmds[cnt];
|
||||
if (sp) {
|
||||
/*
|
||||
* perform lockless completion during driver unload
|
||||
*/
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
req->outstanding_cmds[cnt] = NULL;
|
||||
spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
|
||||
sp->done(sp, res);
|
||||
spin_lock_irqsave(qp->qp_lock_ptr, flags);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -4689,7 +4684,7 @@ static void
|
||||
qla2x00_number_of_exch(scsi_qla_host_t *vha, u32 *ret_cnt, u16 max_cnt)
|
||||
{
|
||||
u32 temp;
|
||||
struct init_cb_81xx *icb = (struct init_cb_81xx *)&vha->hw->init_cb;
|
||||
struct init_cb_81xx *icb = (struct init_cb_81xx *)vha->hw->init_cb;
|
||||
*ret_cnt = FW_DEF_EXCHANGES_CNT;
|
||||
|
||||
if (max_cnt > vha->hw->max_exchg)
|
||||
@ -5563,15 +5558,11 @@ qla2x00_do_work(struct scsi_qla_host *vha)
|
||||
qla2x00_async_prlo_done(vha, e->u.logio.fcport,
|
||||
e->u.logio.data);
|
||||
break;
|
||||
case QLA_EVT_GPNFT:
|
||||
qla24xx_async_gpnft(vha, e->u.gpnft.fc4_type,
|
||||
e->u.gpnft.sp);
|
||||
case QLA_EVT_SCAN_CMD:
|
||||
qla_fab_async_scan(vha, e->u.iosb.sp);
|
||||
break;
|
||||
case QLA_EVT_GPNFT_DONE:
|
||||
qla24xx_async_gpnft_done(vha, e->u.iosb.sp);
|
||||
break;
|
||||
case QLA_EVT_GNNFT_DONE:
|
||||
qla24xx_async_gnnft_done(vha, e->u.iosb.sp);
|
||||
case QLA_EVT_SCAN_FINISH:
|
||||
qla_fab_scan_finish(vha, e->u.iosb.sp);
|
||||
break;
|
||||
case QLA_EVT_GFPNID:
|
||||
qla24xx_async_gfpnid(vha, e->u.fcport.fcport);
|
||||
|
@ -555,6 +555,7 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
|
||||
struct qla_flt_location *fltl = (void *)req->ring;
|
||||
uint32_t *dcode = (uint32_t *)req->ring;
|
||||
uint8_t *buf = (void *)req->ring, *bcode, last_image;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* FLT-location structure resides after the last PCI region.
|
||||
@ -584,14 +585,24 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
|
||||
pcihdr = 0;
|
||||
do {
|
||||
/* Verify PCI expansion ROM header. */
|
||||
qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
|
||||
rc = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x016d,
|
||||
"Unable to read PCI Expansion Rom Header (%x).\n", rc);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
bcode = buf + (pcihdr % 4);
|
||||
if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa)
|
||||
goto end;
|
||||
|
||||
/* Locate PCI data structure. */
|
||||
pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
|
||||
qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
|
||||
rc = qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x0179,
|
||||
"Unable to read PCI Data Structure (%x).\n", rc);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
bcode = buf + (pcihdr % 4);
|
||||
|
||||
/* Validate signature of PCI data structure. */
|
||||
@ -606,7 +617,12 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
|
||||
} while (!last_image);
|
||||
|
||||
/* Now verify FLT-location structure. */
|
||||
qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, sizeof(*fltl) >> 2);
|
||||
rc = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, sizeof(*fltl) >> 2);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x017a,
|
||||
"Unable to read FLT (%x).\n", rc);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
if (memcmp(fltl->sig, "QFLT", 4))
|
||||
goto end;
|
||||
|
||||
@ -2605,13 +2621,18 @@ qla24xx_read_optrom_data(struct scsi_qla_host *vha, void *buf,
|
||||
uint32_t offset, uint32_t length)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
int rc;
|
||||
|
||||
/* Suspend HBA. */
|
||||
scsi_block_requests(vha->host);
|
||||
set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
||||
|
||||
/* Go with read. */
|
||||
qla24xx_read_flash_data(vha, buf, offset >> 2, length >> 2);
|
||||
rc = qla24xx_read_flash_data(vha, buf, offset >> 2, length >> 2);
|
||||
if (rc) {
|
||||
ql_log(ql_log_info, vha, 0x01a0,
|
||||
"Unable to perform optrom read(%x).\n", rc);
|
||||
}
|
||||
|
||||
/* Resume HBA. */
|
||||
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
|
||||
@ -3412,7 +3433,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
struct active_regions active_regions = { };
|
||||
|
||||
if (IS_P3P_TYPE(ha))
|
||||
return ret;
|
||||
return QLA_SUCCESS;
|
||||
|
||||
if (!mbuf)
|
||||
return QLA_FUNCTION_FAILED;
|
||||
@ -3432,20 +3453,31 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
|
||||
do {
|
||||
/* Verify PCI expansion ROM header. */
|
||||
qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
|
||||
ret = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20);
|
||||
if (ret) {
|
||||
ql_log(ql_log_info, vha, 0x017d,
|
||||
"Unable to read PCI EXP Rom Header(%x).\n", ret);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
bcode = mbuf + (pcihdr % 4);
|
||||
if (memcmp(bcode, "\x55\xaa", 2)) {
|
||||
/* No signature */
|
||||
ql_log(ql_log_fatal, vha, 0x0059,
|
||||
"No matching ROM signature.\n");
|
||||
ret = QLA_FUNCTION_FAILED;
|
||||
break;
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
/* Locate PCI data structure. */
|
||||
pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
|
||||
|
||||
qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
|
||||
ret = qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20);
|
||||
if (ret) {
|
||||
ql_log(ql_log_info, vha, 0x018e,
|
||||
"Unable to read PCI Data Structure (%x).\n", ret);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
bcode = mbuf + (pcihdr % 4);
|
||||
|
||||
/* Validate signature of PCI data structure. */
|
||||
@ -3454,8 +3486,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
ql_log(ql_log_fatal, vha, 0x005a,
|
||||
"PCI data struct not found pcir_adr=%x.\n", pcids);
|
||||
ql_dump_buffer(ql_dbg_init, vha, 0x0059, dcode, 32);
|
||||
ret = QLA_FUNCTION_FAILED;
|
||||
break;
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
/* Read version */
|
||||
@ -3507,20 +3538,26 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
faddr = ha->flt_region_fw_sec;
|
||||
}
|
||||
|
||||
qla24xx_read_flash_data(vha, dcode, faddr, 8);
|
||||
if (qla24xx_risc_firmware_invalid(dcode)) {
|
||||
ql_log(ql_log_warn, vha, 0x005f,
|
||||
"Unrecognized fw revision at %x.\n",
|
||||
ha->flt_region_fw * 4);
|
||||
ql_dump_buffer(ql_dbg_init, vha, 0x005f, dcode, 32);
|
||||
ret = qla24xx_read_flash_data(vha, dcode, faddr, 8);
|
||||
if (ret) {
|
||||
ql_log(ql_log_info, vha, 0x019e,
|
||||
"Unable to read FW version (%x).\n", ret);
|
||||
return ret;
|
||||
} else {
|
||||
for (i = 0; i < 4; i++)
|
||||
ha->fw_revision[i] =
|
||||
if (qla24xx_risc_firmware_invalid(dcode)) {
|
||||
ql_log(ql_log_warn, vha, 0x005f,
|
||||
"Unrecognized fw revision at %x.\n",
|
||||
ha->flt_region_fw * 4);
|
||||
ql_dump_buffer(ql_dbg_init, vha, 0x005f, dcode, 32);
|
||||
} else {
|
||||
for (i = 0; i < 4; i++)
|
||||
ha->fw_revision[i] =
|
||||
be32_to_cpu((__force __be32)dcode[4+i]);
|
||||
ql_dbg(ql_dbg_init, vha, 0x0060,
|
||||
"Firmware revision (flash) %u.%u.%u (%x).\n",
|
||||
ha->fw_revision[0], ha->fw_revision[1],
|
||||
ha->fw_revision[2], ha->fw_revision[3]);
|
||||
ql_dbg(ql_dbg_init, vha, 0x0060,
|
||||
"Firmware revision (flash) %u.%u.%u (%x).\n",
|
||||
ha->fw_revision[0], ha->fw_revision[1],
|
||||
ha->fw_revision[2], ha->fw_revision[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for golden firmware and get version if available */
|
||||
@ -3531,18 +3568,23 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
|
||||
|
||||
memset(ha->gold_fw_version, 0, sizeof(ha->gold_fw_version));
|
||||
faddr = ha->flt_region_gold_fw;
|
||||
qla24xx_read_flash_data(vha, dcode, ha->flt_region_gold_fw, 8);
|
||||
if (qla24xx_risc_firmware_invalid(dcode)) {
|
||||
ql_log(ql_log_warn, vha, 0x0056,
|
||||
"Unrecognized golden fw at %#x.\n", faddr);
|
||||
ql_dump_buffer(ql_dbg_init, vha, 0x0056, dcode, 32);
|
||||
ret = qla24xx_read_flash_data(vha, dcode, ha->flt_region_gold_fw, 8);
|
||||
if (ret) {
|
||||
ql_log(ql_log_info, vha, 0x019f,
|
||||
"Unable to read Gold FW version (%x).\n", ret);
|
||||
return ret;
|
||||
} else {
|
||||
if (qla24xx_risc_firmware_invalid(dcode)) {
|
||||
ql_log(ql_log_warn, vha, 0x0056,
|
||||
"Unrecognized golden fw at %#x.\n", faddr);
|
||||
ql_dump_buffer(ql_dbg_init, vha, 0x0056, dcode, 32);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
ha->gold_fw_version[i] =
|
||||
be32_to_cpu((__force __be32)dcode[4+i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
ha->gold_fw_version[i] =
|
||||
be32_to_cpu((__force __be32)dcode[4+i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,9 @@
|
||||
/*
|
||||
* Driver version
|
||||
*/
|
||||
#define QLA2XXX_VERSION "10.02.09.200-k"
|
||||
#define QLA2XXX_VERSION "10.02.09.300-k"
|
||||
|
||||
#define QLA_DRIVER_MAJOR_VER 10
|
||||
#define QLA_DRIVER_MINOR_VER 2
|
||||
#define QLA_DRIVER_PATCH_VER 9
|
||||
#define QLA_DRIVER_BETA_VER 200
|
||||
#define QLA_DRIVER_BETA_VER 300
|
||||
|
Loading…
Reference in New Issue
Block a user