Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2019-12-25 16:44:46 -08:00
25 changed files with 830 additions and 447 deletions
@@ -392,7 +392,6 @@ static struct qla_tgt_cmd *sqa_qla2xxx_get_cmd(struct fc_port *sess)
#endif
cmd->sess = sess;
cmd->vha = sess->vha;
cmd->rel_cmd = sqa_qla2xxx_rel_cmd;
return cmd;
}
@@ -870,6 +869,8 @@ static int sqa_close_session(struct scst_session *scst_sess)
unsigned long flags;
struct qla_hw_data *ha = fcport->vha->hw;
fcport->explicit_logout = 1;
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
sqa_qla2xxx_put_sess(fcport);
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
@@ -1890,6 +1891,7 @@ static struct qla_tgt_func_tmpl sqa_qla2xxx_template = {
.handle_data = sqa_qla2xxx_handle_data,
.handle_tmr = sqa_qla2xxx_handle_tmr,
.get_cmd = sqa_qla2xxx_get_cmd,
.rel_cmd = sqa_qla2xxx_rel_cmd,
.free_cmd = sqa_qla2xxx_free_cmd,
.free_mcmd = sqa_qla2xxx_free_mcmd,
.free_session = sqa_qla2xxx_free_session,
+4 -1
View File
@@ -102,8 +102,10 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
qla8044_idc_lock(ha);
qla82xx_set_reset_owner(vha);
qla8044_idc_unlock(ha);
} else
} else {
ha->fw_dump_mpi = 1;
qla2x00_system_error(vha);
}
break;
case 4:
if (IS_P3P_TYPE(ha)) {
@@ -176,6 +178,7 @@ qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj,
faddr = ha->flt_region_nvram;
if (IS_QLA28XX(ha)) {
qla28xx_get_aux_images(vha, &active_regions);
if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
faddr = ha->flt_region_nvram_sec;
}
+6 -5
View File
@@ -83,7 +83,8 @@ void qla2x00_bsg_sp_free(srb_t *sp)
if (sp->type == SRB_CT_CMD ||
sp->type == SRB_FXIOCB_BCMD ||
sp->type == SRB_ELS_CMD_HST)
kfree(sp->fcport);
qla2x00_free_fcport(sp->fcport);
qla2x00_rel_sp(sp);
}
@@ -444,7 +445,7 @@ done_unmap_sg:
done_free_fcport:
if (bsg_request->msgcode == FC_BSG_RPT_ELS)
kfree(fcport);
qla2x00_free_fcport(fcport);
done:
return rval;
}
@@ -589,7 +590,7 @@ qla2x00_process_ct(struct bsg_job *bsg_job)
return rval;
done_free_fcport:
kfree(fcport);
qla2x00_free_fcport(fcport);
done_unmap_sg:
dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
@@ -2169,7 +2170,7 @@ qlafx00_mgmt_cmd(struct bsg_job *bsg_job)
return rval;
done_free_fcport:
kfree(fcport);
qla2x00_free_fcport(fcport);
done_unmap_rsp_sg:
if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID)
@@ -2559,7 +2560,7 @@ qla2x00_get_flash_image_status(struct bsg_job *bsg_job)
struct qla_active_regions regions = { };
struct active_regions active_regions = { };
qla28xx_get_aux_images(vha, &active_regions);
qla27xx_get_active_image(vha, &active_regions);
regions.global_image = active_regions.global;
if (IS_QLA28XX(ha)) {
+1 -1
View File
@@ -18,7 +18,7 @@
* | Device Discovery | 0x2134 | 0x210e-0x2116 |
* | | | 0x211a |
* | | | 0x211c-0x2128 |
* | | | 0x212a-0x2130 |
* | | | 0x212a-0x2134 |
* | Queue Command and IO tracing | 0x3074 | 0x300b |
* | | | 0x3027-0x3028 |
* | | | 0x303d-0x3041 |
+51 -4
View File
@@ -613,19 +613,23 @@ typedef struct srb {
*/
uint8_t cmd_type;
uint8_t pad[3];
atomic_t ref_count;
struct kref cmd_kref; /* need to migrate ref_count over to this */
void *priv;
wait_queue_head_t nvme_ls_waitq;
struct fc_port *fcport;
struct scsi_qla_host *vha;
unsigned int start_timer:1;
unsigned int abort:1;
unsigned int aborted:1;
unsigned int completed:1;
uint32_t handle;
uint16_t flags;
uint16_t type;
const char *name;
int iocbs;
struct qla_qpair *qpair;
struct srb *cmd_sp;
struct list_head elem;
u32 gen1; /* scratch */
u32 gen2; /* scratch */
@@ -2303,7 +2307,7 @@ typedef struct {
uint8_t fabric_port_name[WWN_SIZE];
uint16_t fp_speed;
uint8_t fc4_type;
uint8_t fc4f_nvme; /* nvme fc4 feature bits */
uint8_t fc4_features;
} sw_info_t;
/* FCP-4 types */
@@ -2423,6 +2427,8 @@ typedef struct fc_port {
unsigned int id_changed:1;
unsigned int scan_needed:1;
unsigned int n2n_flag:1;
unsigned int explicit_logout:1;
unsigned int prli_pend_timer:1;
struct completion nvme_del_done;
uint32_t nvme_prli_service_param;
@@ -2449,6 +2455,7 @@ typedef struct fc_port {
struct work_struct free_work;
struct work_struct reg_work;
uint64_t jiffies_at_registration;
unsigned long prli_expired;
struct qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX];
struct completion *unreg_done;
@@ -2472,7 +2479,7 @@ typedef struct fc_port {
u32 supported_classes;
uint8_t fc4_type;
uint8_t fc4f_nvme;
uint8_t fc4_features;
uint8_t scan_state;
unsigned long last_queue_full;
@@ -2486,6 +2493,7 @@ typedef struct fc_port {
struct qla_tgt_sess *tgt_session;
struct ct_sns_desc ct_desc;
enum discovery_state disc_state;
atomic_t shadow_disc_state;
enum discovery_state next_disc_state;
enum login_state fw_login_state;
unsigned long dm_login_expire;
@@ -2503,6 +2511,11 @@ typedef struct fc_port {
u16 n2n_chip_reset;
} fc_port_t;
enum {
FC4_PRIORITY_NVME = 1,
FC4_PRIORITY_FCP = 2,
};
#define QLA_FCPORT_SCAN 1
#define QLA_FCPORT_FOUND 2
@@ -2527,6 +2540,19 @@ struct event_arg {
extern const char *const port_state_str[5];
static const char * const port_dstate_str[] = {
"DELETED",
"GNN_ID",
"GNL",
"LOGIN_PEND",
"LOGIN_FAILED",
"GPDB",
"UPD_FCPORT",
"LOGIN_COMPLETE",
"ADISC",
"DELETE_PEND"
};
/*
* FC port flags.
*/
@@ -3280,7 +3306,6 @@ enum qla_work_type {
QLA_EVT_IDC_ACK,
QLA_EVT_ASYNC_LOGIN,
QLA_EVT_ASYNC_LOGOUT,
QLA_EVT_ASYNC_LOGOUT_DONE,
QLA_EVT_ASYNC_ADISC,
QLA_EVT_UEVENT,
QLA_EVT_AENFX,
@@ -4318,6 +4343,8 @@ struct qla_hw_data {
atomic_t nvme_active_aen_cnt;
uint16_t nvme_last_rptd_aen; /* Last recorded aen count */
uint8_t fc4_type_priority;
atomic_t zio_threshold;
uint16_t last_zio_threshold;
@@ -4843,6 +4870,26 @@ struct sff_8247_a0 {
ha->current_topology == ISP_CFG_N || \
!ha->current_topology)
#define NVME_TYPE(fcport) \
(fcport->fc4_type & FS_FC4TYPE_NVME) \
#define FCP_TYPE(fcport) \
(fcport->fc4_type & FS_FC4TYPE_FCP) \
#define NVME_ONLY_TARGET(fcport) \
(NVME_TYPE(fcport) && !FCP_TYPE(fcport)) \
#define NVME_FCP_TARGET(fcport) \
(FCP_TYPE(fcport) && NVME_TYPE(fcport)) \
#define NVME_TARGET(ha, fcport) \
((NVME_FCP_TARGET(fcport) && \
(ha->fc4_type_priority == FC4_PRIORITY_NVME)) || \
NVME_ONLY_TARGET(fcport)) \
#define PRLI_PHASE(_cls) \
((_cls == DSC_LS_PRLI_PEND) || (_cls == DSC_LS_PRLI_COMP))
#include "qla_target.h"
#include "qla_gbl.h"
#include "qla_dbg.h"
+22 -15
View File
@@ -1366,12 +1366,12 @@ struct vp_rpt_id_entry_24xx {
uint8_t port_id[3];
uint8_t format;
union {
struct {
struct _f0 {
/* format 0 loop */
uint8_t vp_idx_map[16];
uint8_t reserved_4[32];
} f0;
struct {
struct _f1 {
/* format 1 fabric */
uint8_t vpstat1_subcode; /* vp_status=1 subcode */
uint8_t flags;
@@ -1393,21 +1393,22 @@ struct vp_rpt_id_entry_24xx {
uint16_t bbcr;
uint8_t reserved_5[6];
} f1;
struct { /* format 2: N2N direct connect */
uint8_t vpstat1_subcode;
uint8_t flags;
uint16_t rsv6;
uint8_t rsv2[12];
struct _f2 { /* format 2: N2N direct connect */
uint8_t vpstat1_subcode;
uint8_t flags;
uint16_t fip_flags;
uint8_t rsv2[12];
uint8_t ls_rjt_vendor;
uint8_t ls_rjt_explanation;
uint8_t ls_rjt_reason;
uint8_t rsv3[5];
uint8_t ls_rjt_vendor;
uint8_t ls_rjt_explanation;
uint8_t ls_rjt_reason;
uint8_t rsv3[5];
uint8_t port_name[8];
uint8_t node_name[8];
uint8_t remote_nport_id[4];
uint32_t reserved_5;
uint8_t port_name[8];
uint8_t node_name[8];
uint16_t bbcr;
uint8_t reserved_5[2];
uint8_t remote_nport_id[4];
} f2;
} u;
};
@@ -1535,6 +1536,10 @@ struct qla_flt_header {
#define FLT_REG_NVRAM_SEC_28XX_1 0x10F
#define FLT_REG_NVRAM_SEC_28XX_2 0x111
#define FLT_REG_NVRAM_SEC_28XX_3 0x113
#define FLT_REG_MPI_PRI_28XX 0xD3
#define FLT_REG_MPI_SEC_28XX 0xF0
#define FLT_REG_PEP_PRI_28XX 0xD1
#define FLT_REG_PEP_SEC_28XX 0xF1
struct qla_flt_region {
uint16_t code;
@@ -2113,4 +2118,6 @@ struct qla_fcp_prio_cfg {
#define FA_FLASH_LAYOUT_ADDR_83 (0x3F1000/4)
#define FA_FLASH_LAYOUT_ADDR_28 (0x11000/4)
#define NVRAM_DUAL_FCP_NVME_FLAG_OFFSET 0x196
#endif
+6 -6
View File
@@ -72,14 +72,13 @@ extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *,
extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t);
extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host *,
enum qla_work_type);
extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *);
int qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e);
extern void *qla2x00_alloc_iocbs_ready(struct qla_qpair *, srb_t *);
extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);
extern int qla24xx_async_abort_cmd(srb_t *, bool);
extern void qla2x00_set_fcport_state(fc_port_t *fcport, int state);
extern fc_port_t *
@@ -186,8 +185,6 @@ extern int qla2x00_post_async_login_work(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *,
fc_port_t *, uint16_t *);
extern int qla2x00_post_async_adisc_work(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
extern int qla2x00_post_async_adisc_done_work(struct scsi_qla_host *,
@@ -205,6 +202,7 @@ extern void qla2x00_free_host(struct scsi_qla_host *);
extern void qla2x00_relogin(struct scsi_qla_host *);
extern void qla2x00_do_work(struct scsi_qla_host *);
extern void qla2x00_free_fcports(struct scsi_qla_host *);
extern void qla2x00_free_fcport(fc_port_t *);
extern void qla83xx_schedule_work(scsi_qla_host_t *, int);
extern void qla83xx_service_idc_aen(struct work_struct *);
@@ -257,8 +255,9 @@ extern scsi_qla_host_t *qla24xx_create_vhost(struct fc_vport *);
extern void qla2x00_sp_free_dma(srb_t *sp);
extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);
extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int);
extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int);
extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *);
extern int qla24xx_async_abort_cmd(srb_t *, bool);
extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
@@ -926,4 +925,5 @@ int qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode);
/* nvme.c */
void qla_nvme_unregister_remote_port(struct fc_port *fcport);
void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea);
#endif /* _QLA_GBL_H */
+51 -33
View File
@@ -248,7 +248,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
WWN_SIZE);
fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ?
FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER;
FS_FC4TYPE_FCP : FC4_TYPE_OTHER;
if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
@@ -2887,7 +2887,7 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
struct ct_sns_req *ct_req;
struct ct_sns_rsp *ct_rsp;
struct qla_hw_data *ha = vha->hw;
uint8_t fcp_scsi_features = 0;
uint8_t fcp_scsi_features = 0, nvme_features = 0;
struct ct_arg arg;
for (i = 0; i < ha->max_fibre_devices; i++) {
@@ -2933,14 +2933,19 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
fcp_scsi_features &= 0x0f;
if (fcp_scsi_features)
list[i].fc4_type = FC4_TYPE_FCP_SCSI;
else
list[i].fc4_type = FC4_TYPE_OTHER;
if (fcp_scsi_features) {
list[i].fc4_type = FS_FC4TYPE_FCP;
list[i].fc4_features = fcp_scsi_features;
}
list[i].fc4f_nvme =
nvme_features =
ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
list[i].fc4f_nvme &= 0xf;
nvme_features &= 0xf;
if (nvme_features) {
list[i].fc4_type |= FS_FC4TYPE_NVME;
list[i].fc4_features = nvme_features;
}
}
/* Last device exit. */
@@ -2958,7 +2963,6 @@ int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport)
return QLA_FUNCTION_FAILED;
e->u.fcport.fcport = fcport;
fcport->flags |= FCF_ASYNC_ACTIVE;
return qla2x00_post_work(vha, e);
}
@@ -3005,7 +3009,7 @@ static void qla24xx_async_gpsc_sp_done(srb_t *sp, int res)
fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
if (res == QLA_FUNCTION_TIMEOUT)
return;
goto done;
if (res == (DID_ERROR << 16)) {
/* entry status error */
@@ -3092,9 +3096,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport)
done_free_sp:
sp->free(sp);
fcport->flags &= ~FCF_ASYNC_SENT;
done:
fcport->flags &= ~FCF_ASYNC_ACTIVE;
return rval;
}
@@ -3435,6 +3437,8 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
fc_port_t *fcport = sp->fcport;
struct ct_sns_rsp *ct_rsp;
struct event_arg ea;
uint8_t fc4_scsi_feat;
uint8_t fc4_nvme_feat;
ql_dbg(ql_dbg_disc, vha, 0x2133,
"Async done-%s res %x ID %x. %8phC\n",
@@ -3442,24 +3446,25 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
fcport->flags &= ~FCF_ASYNC_SENT;
ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
/*
* FC-GS-7, 5.2.3.12 FC-4 Features - format
* The format of the FC-4 Features object, as defined by the FC-4,
* Shall be an array of 4-bit values, one for each type code value
*/
if (!res) {
if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) {
if (fc4_scsi_feat & 0xf) {
/* w1 b00:03 */
fcport->fc4_type =
ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
fcport->fc4_type &= 0xf;
}
fcport->fc4_type = FS_FC4TYPE_FCP;
fcport->fc4_features = fc4_scsi_feat & 0xf;
}
if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) {
if (fc4_nvme_feat & 0xf) {
/* w5 [00:03]/28h */
fcport->fc4f_nvme =
ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
fcport->fc4f_nvme &= 0xf;
fcport->fc4_type |= FS_FC4TYPE_NVME;
fcport->fc4_features = fc4_nvme_feat & 0xf;
}
}
@@ -3563,7 +3568,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
u8 recheck = 0;
u16 dup = 0, dup_cnt = 0;
ql_dbg(ql_dbg_disc, vha, 0xffff,
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
"%s enter\n", __func__);
if (sp->gen1 != vha->hw->base_qpair->chip_reset) {
@@ -3579,11 +3584,23 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
goto out;
} else {
ql_dbg(ql_dbg_disc, vha, 0xffff,
"Fabric scan failed on all retries.\n");
"%s: Fabric scan failed for %d retries.\n",
__func__, vha->scan.scan_retry);
/*
* Unable to scan any rports. logout loop below
* will unregister all sessions.
*/
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if ((fcport->flags & FCF_FABRIC_DEVICE) != 0) {
fcport->scan_state = QLA_FCPORT_SCAN;
fcport->logout_on_delete = 0;
}
}
goto login_logout;
}
goto out;
}
vha->scan.scan_retry = 0;
@@ -3661,6 +3678,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
dup_cnt);
}
login_logout:
/*
* Logout all previous fabric dev marked lost, except FCP2 devices.
*/
@@ -4047,7 +4065,7 @@ done_free_sp:
void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp)
{
ql_dbg(ql_dbg_disc, vha, 0xffff,
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
"%s enter\n", __func__);
qla24xx_async_gnnft(vha, sp, sp->gen2);
}
@@ -4061,7 +4079,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
u32 rspsz;
unsigned long flags;
ql_dbg(ql_dbg_disc, vha, 0xffff,
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
"%s enter\n", __func__);
if (!vha->flags.online)
@@ -4070,14 +4088,15 @@ 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, vha, 0xffff, "scan active\n");
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
"%s: scan active\n", __func__);
return rval;
}
vha->scan.scan_flags |= SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);
if (fc4_type == FC4_TYPE_FCP_SCSI) {
ql_dbg(ql_dbg_disc, vha, 0xffff,
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
"%s: Performing FCP Scan\n", __func__);
if (sp)
@@ -4132,7 +4151,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
}
sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz;
ql_dbg(ql_dbg_disc, vha, 0xffff,
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
"%s scan list size %d\n", __func__, vha->scan.size);
memset(vha->scan.l, 0, vha->scan.size);
@@ -4197,8 +4216,8 @@ 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, vha, 0xffff,
"%s: schedule\n", __func__);
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
"%s: Scan scheduled.\n", __func__);
vha->scan.scan_flags |= SF_QUEUED;
schedule_delayed_work(&vha->scan.scan_work, 5);
}
@@ -4268,7 +4287,7 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport)
if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
return rval;
fcport->disc_state = DSC_GNN_ID;
qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID);
sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
if (!sp)
goto done;
@@ -4442,7 +4461,6 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport)
done_free_sp:
sp->free(sp);
fcport->flags &= ~FCF_ASYNC_SENT;
done:
return rval;
}
+181 -137
View File
@@ -49,16 +49,9 @@ qla2x00_sp_timeout(struct timer_list *t)
{
srb_t *sp = from_timer(sp, t, u.iocb_cmd.timer);
struct srb_iocb *iocb;
struct req_que *req;
unsigned long flags;
struct qla_hw_data *ha = sp->vha->hw;
WARN_ON_ONCE(irqs_disabled());
spin_lock_irqsave(&ha->hardware_lock, flags);
req = sp->qpair->req;
req->outstanding_cmds[sp->handle] = NULL;
WARN_ON(irqs_disabled());
iocb = &sp->u.iocb_cmd;
spin_unlock_irqrestore(&ha->hardware_lock, flags);
iocb->timeout(sp);
}
@@ -100,8 +93,22 @@ static void qla24xx_abort_iocb_timeout(void *data)
u32 handle;
unsigned long flags;
if (sp->cmd_sp)
ql_dbg(ql_dbg_async, sp->vha, 0x507c,
"Abort timeout - cmd hdl=%x, cmd type=%x hdl=%x, type=%x\n",
sp->cmd_sp->handle, sp->cmd_sp->type,
sp->handle, sp->type);
else
ql_dbg(ql_dbg_async, sp->vha, 0x507c,
"Abort timeout 2 - hdl=%x, type=%x\n",
sp->handle, sp->type);
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] ==
sp->cmd_sp))
qpair->req->outstanding_cmds[handle] = NULL;
/* removing the abort */
if (qpair->req->outstanding_cmds[handle] == sp) {
qpair->req->outstanding_cmds[handle] = NULL;
@@ -110,6 +117,9 @@ static void qla24xx_abort_iocb_timeout(void *data)
}
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
if (sp->cmd_sp)
sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
abt->u.abt.comp_status = CS_TIMEOUT;
sp->done(sp, QLA_OS_TIMER_EXPIRED);
}
@@ -125,7 +135,7 @@ static void qla24xx_abort_sp_done(srb_t *sp, int res)
sp->free(sp);
}
static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
{
scsi_qla_host_t *vha = cmd_sp->vha;
struct srb_iocb *abt_iocb;
@@ -141,6 +151,7 @@ static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
sp->type = SRB_ABT_CMD;
sp->name = "abort";
sp->qpair = cmd_sp->qpair;
sp->cmd_sp = cmd_sp;
if (wait)
sp->flags = SRB_WAKEUP_ON_COMP;
@@ -224,6 +235,7 @@ qla2x00_async_iocb_timeout(void *data)
case SRB_NACK_PRLI:
case SRB_NACK_LOGO:
case SRB_CTRL_VP:
default:
rc = qla24xx_async_abort_cmd(sp, false);
if (rc) {
spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
@@ -240,10 +252,6 @@ qla2x00_async_iocb_timeout(void *data)
sp->done(sp, QLA_FUNCTION_TIMEOUT);
}
break;
default:
WARN_ON_ONCE(true);
sp->done(sp, QLA_FUNCTION_TIMEOUT);
break;
}
}
@@ -308,10 +316,10 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
if (!sp)
goto done;
qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
fcport->flags |= FCF_ASYNC_SENT;
fcport->logout_completed = 0;
fcport->disc_state = DSC_LOGIN_PEND;
sp->type = SRB_LOGIN_CMD;
sp->name = "login";
sp->gen1 = fcport->rscn_gen;
@@ -327,7 +335,7 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
else
lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
if (fcport->fc4f_nvme)
if (NVME_TARGET(vha->hw, fcport))
lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI;
ql_dbg(ql_dbg_disc, vha, 0x2072,
@@ -407,7 +415,7 @@ qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport,
fcport->flags &= ~FCF_ASYNC_ACTIVE;
/* Don't re-login in target mode */
if (!fcport->tgt_session)
qla2x00_mark_device_lost(vha, fcport, 1, 0);
qla2x00_mark_device_lost(vha, fcport, 1);
qlt_logo_completion_handler(fcport, data[0]);
}
@@ -515,6 +523,7 @@ static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport)
e->u.fcport.fcport = fcport;
fcport->flags |= FCF_ASYNC_ACTIVE;
qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
return qla2x00_post_work(vha, e);
}
@@ -666,7 +675,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
port_id_t id;
u64 wwn;
u16 data[2];
u8 current_login_state;
u8 current_login_state, nvme_cls;
fcport = ea->fcport;
ql_dbg(ql_dbg_disc, vha, 0xffff,
@@ -725,19 +734,24 @@ 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);
if (fcport->fc4f_nvme)
current_login_state = e->current_login_state >> 4;
else
current_login_state = e->current_login_state & 0xf;
nvme_cls = e->current_login_state >> 4;
current_login_state = e->current_login_state & 0xf;
if (PRLI_PHASE(nvme_cls)) {
current_login_state = nvme_cls;
fcport->fc4_type &= ~FS_FC4TYPE_FCP;
fcport->fc4_type |= FS_FC4TYPE_NVME;
} else if (PRLI_PHASE(current_login_state)) {
fcport->fc4_type |= FS_FC4TYPE_FCP;
fcport->fc4_type &= ~FS_FC4TYPE_NVME;
}
ql_dbg(ql_dbg_disc, vha, 0x20e2,
"%s found %8phC CLS [%x|%x] nvme %d ID[%02x%02x%02x|%02x%02x%02x] lid[%d|%d]\n",
"%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] lid[%d|%d]\n",
__func__, fcport->port_name,
e->current_login_state, fcport->fw_login_state,
fcport->fc4f_nvme, 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);
fcport->fc4_type, id.b24, fcport->d_id.b24,
loop_id, fcport->loop_id);
switch (fcport->disc_state) {
case DSC_DELETE_PEND:
@@ -819,7 +833,8 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
* with GNL. Push disc_state back to DELETED
* so GNL can go out again
*/
fcport->disc_state = DSC_DELETED;
qla2x00_set_fcport_disc_state(fcport,
DSC_DELETED);
break;
case DSC_LS_PRLI_COMP:
if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
@@ -895,7 +910,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
qla24xx_fcport_handle_login(vha, fcport);
break;
case ISP_CFG_N:
fcport->disc_state = DSC_DELETED;
qla2x00_set_fcport_disc_state(fcport, DSC_DELETED);
if (time_after_eq(jiffies, fcport->dm_login_expire)) {
if (fcport->n2n_link_reset_cnt < 2) {
fcport->n2n_link_reset_cnt++;
@@ -975,7 +990,7 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, 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, 0x20e8,
ql_dbg(ql_dbg_disc, vha, 0x20e8,
"%s %8phC %02x:%02x:%02x CLS %x/%x 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,
@@ -1034,6 +1049,16 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res)
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
vha->gnl.sent = 0;
if (!list_empty(&vha->gnl.fcports)) {
/* retrigger gnl */
list_for_each_entry_safe(fcport, tf, &vha->gnl.fcports,
gnl_entry) {
list_del_init(&fcport->gnl_entry);
fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
if (qla24xx_post_gnl_work(vha, fcport) == QLA_SUCCESS)
break;
}
}
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
sp->free(sp);
@@ -1055,7 +1080,7 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
fcport->flags |= FCF_ASYNC_SENT;
fcport->disc_state = DSC_GNL;
qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
fcport->last_rscn_gen = fcport->rscn_gen;
fcport->last_login_gen = fcport->login_gen;
@@ -1104,8 +1129,8 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
done_free_sp:
sp->free(sp);
fcport->flags &= ~FCF_ASYNC_SENT;
done:
fcport->flags &= ~(FCF_ASYNC_ACTIVE | FCF_ASYNC_SENT);
return rval;
}
@@ -1134,19 +1159,18 @@ static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res)
"Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n",
sp->name, res, fcport->port_name, mb[1], mb[2]);
if (res == QLA_FUNCTION_TIMEOUT) {
dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
sp->u.iocb_cmd.u.mbx.in_dma);
return;
}
fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
if (res == QLA_FUNCTION_TIMEOUT)
goto done;
memset(&ea, 0, sizeof(ea));
ea.fcport = fcport;
ea.sp = sp;
qla24xx_handle_gpdb_event(vha, &ea);
done:
dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
sp->u.iocb_cmd.u.mbx.in_dma);
@@ -1200,12 +1224,19 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
struct srb_iocb *lio;
int rval = QLA_FUNCTION_FAILED;
if (!vha->flags.online)
if (!vha->flags.online) {
ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n",
__func__, __LINE__, fcport->port_name);
return rval;
}
if (fcport->fw_login_state == DSC_LS_PLOGI_PEND ||
fcport->fw_login_state == DSC_LS_PRLI_PEND)
if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND ||
fcport->fw_login_state == DSC_LS_PRLI_PEND) &&
qla_dual_mode_enabled(vha)) {
ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n",
__func__, __LINE__, fcport->port_name);
return rval;
}
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
@@ -1224,13 +1255,13 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
sp->done = qla2x00_async_prli_sp_done;
lio->u.logio.flags = 0;
if (fcport->fc4f_nvme)
if (NVME_TARGET(vha->hw, fcport))
lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI;
ql_dbg(ql_dbg_disc, vha, 0x211b,
"Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n",
fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24,
fcport->login_retry, fcport->fc4f_nvme ? "nvme" : "fc");
fcport->login_retry, NVME_TARGET(vha->hw, fcport) ? "nvme" : "fc");
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
@@ -1279,12 +1310,12 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
return rval;
}
fcport->disc_state = DSC_GPDB;
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
goto done;
qla2x00_set_fcport_disc_state(fcport, DSC_GPDB);
fcport->flags |= FCF_ASYNC_SENT;
sp->type = SRB_MB_IOCB;
sp->name = "gpdb";
@@ -1333,6 +1364,7 @@ done_free_sp:
sp->free(sp);
fcport->flags &= ~FCF_ASYNC_SENT;
done:
fcport->flags &= ~FCF_ASYNC_ACTIVE;
qla24xx_post_gpdb_work(vha, fcport, opt);
return rval;
}
@@ -1363,7 +1395,7 @@ void __qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
ql_dbg(ql_dbg_disc, vha, 0x20d6,
"%s %d %8phC session revalidate success\n",
__func__, __LINE__, ea->fcport->port_name);
ea->fcport->disc_state = DSC_LOGIN_COMPLETE;
qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_COMPLETE);
}
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
}
@@ -1381,14 +1413,14 @@ 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, 0x20d2,
"%s %8phC DS %d LS %d nvme %x rc %d\n", __func__, fcport->port_name,
fcport->disc_state, pd->current_login_state, fcport->fc4f_nvme,
ea->rc);
"%s %8phC DS %d LS %d fc4_type %x rc %d\n", __func__,
fcport->port_name, fcport->disc_state, pd->current_login_state,
fcport->fc4_type, ea->rc);
if (fcport->disc_state == DSC_DELETE_PEND)
return;
if (fcport->fc4f_nvme)
if (NVME_TARGET(vha->hw, fcport))
ls = pd->current_login_state >> 4;
else
ls = pd->current_login_state & 0xf;
@@ -1417,7 +1449,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
/* Set discovery state back to GNL to Relogin attempt */
if (qla_dual_mode_enabled(vha) ||
qla_ini_mode_enabled(vha)) {
fcport->disc_state = DSC_GNL;
qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
}
return;
@@ -1511,8 +1543,8 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
}
}
/* for pure Target Mode. Login will not be initiated */
if (vha->host->active_mode == MODE_TARGET)
/* Target won't initiate port login if fabric is present */
if (vha->host->active_mode == MODE_TARGET && !N2N_TOPO(vha->hw))
return 0;
if (fcport->flags & FCF_ASYNC_SENT) {
@@ -1577,12 +1609,17 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
ql_dbg(ql_dbg_disc, vha, 0x2118,
"%s %d %8phC post %s PRLI\n",
__func__, __LINE__, fcport->port_name,
fcport->fc4f_nvme ? "NVME" : "FC");
NVME_TARGET(vha->hw, fcport) ? "NVME" :
"FC");
qla24xx_post_prli_work(vha, fcport);
}
break;
default:
if (fcport->login_pause) {
ql_dbg(ql_dbg_disc, vha, 0x20d8,
"%s %d %8phC exit\n",
__func__, __LINE__,
fcport->port_name);
fcport->last_rscn_gen = fcport->rscn_gen;
fcport->last_login_gen = fcport->login_gen;
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
@@ -1700,6 +1737,19 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
qla24xx_fcport_handle_login(vha, fcport);
}
void qla_handle_els_plogi_done(scsi_qla_host_t *vha,
struct event_arg *ea)
{
/* for pure Target Mode, PRLI will not be initiated */
if (vha->host->active_mode == MODE_TARGET)
return;
ql_dbg(ql_dbg_disc, vha, 0x2118,
"%s %d %8phC post PRLI\n",
__func__, __LINE__, ea->fcport->port_name);
qla24xx_post_prli_work(vha, ea->fcport);
}
/*
* RSCN(s) came in for this fcport, but the RSCN(s) was not able
* to be consumed by the fcport
@@ -1728,9 +1778,23 @@ qla2x00_tmf_iocb_timeout(void *data)
{
srb_t *sp = data;
struct srb_iocb *tmf = &sp->u.iocb_cmd;
int rc, h;
unsigned long flags;
tmf->u.tmf.comp_status = CS_TIMEOUT;
complete(&tmf->u.tmf.comp);
rc = qla24xx_async_abort_cmd(sp, false);
if (rc) {
spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
if (sp->qpair->req->outstanding_cmds[h] == sp) {
sp->qpair->req->outstanding_cmds[h] = NULL;
break;
}
}
spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
tmf->u.tmf.comp_status = CS_TIMEOUT;
tmf->u.tmf.data = QLA_FUNCTION_FAILED;
complete(&tmf->u.tmf.comp);
}
}
static void qla2x00_tmf_sp_done(srb_t *sp, int res)
@@ -1859,38 +1923,26 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
break;
}
if (ea->fcport->fc4f_nvme) {
/*
* Retry PRLI with other FC-4 type if failure occurred on dual
* FCP/NVMe port
*/
if (NVME_FCP_TARGET(ea->fcport)) {
ql_dbg(ql_dbg_disc, vha, 0x2118,
"%s %d %8phC post fc4 prli\n",
__func__, __LINE__, ea->fcport->port_name);
ea->fcport->fc4f_nvme = 0;
qla24xx_post_prli_work(vha, ea->fcport);
return;
"%s %d %8phC post %s prli\n",
__func__, __LINE__, ea->fcport->port_name,
(ea->fcport->fc4_type & FS_FC4TYPE_NVME) ?
"NVMe" : "FCP");
if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
else
ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
}
/* at this point both PRLI NVME & PRLI FCP failed */
if (N2N_TOPO(vha->hw)) {
if (ea->fcport->n2n_link_reset_cnt < 3) {
ea->fcport->n2n_link_reset_cnt++;
/*
* remote port is not sending Plogi. Reset
* link to kick start his state machine
*/
set_bit(N2N_LINK_RESET, &vha->dpc_flags);
} else {
ql_log(ql_log_warn, vha, 0x2119,
"%s %d %8phC Unable to reconnect\n",
__func__, __LINE__, ea->fcport->port_name);
}
} else {
/*
* switch connect. login failed. Take connection
* down and allow relogin to retrigger
*/
ea->fcport->flags &= ~FCF_ASYNC_SENT;
ea->fcport->keep_nport_handle = 0;
qlt_schedule_sess_for_deletion(ea->fcport);
}
ea->fcport->flags &= ~FCF_ASYNC_SENT;
ea->fcport->keep_nport_handle = 0;
ea->fcport->logout_on_delete = 1;
qlt_schedule_sess_for_deletion(ea->fcport);
break;
}
}
@@ -1951,14 +2003,14 @@ 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.
*/
if (ea->fcport->fc4f_nvme) {
if (NVME_TARGET(vha->hw, ea->fcport)) {
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 LoopID 0x%x in use with %06x. post gnl\n",
"%s %d %8phC LoopID 0x%x in use with %06x. post gpdb\n",
__func__, __LINE__, ea->fcport->port_name,
ea->fcport->loop_id, ea->fcport->d_id.b24);
@@ -1978,11 +2030,11 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
__func__, __LINE__, ea->fcport->port_name, ea->data[1]);
ea->fcport->flags &= ~FCF_ASYNC_SENT;
ea->fcport->disc_state = DSC_LOGIN_FAILED;
qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_FAILED);
if (ea->data[1] & QLA_LOGIO_LOGIN_RETRIED)
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
else
qla2x00_mark_device_lost(vha, ea->fcport, 1, 0);
qla2x00_mark_device_lost(vha, ea->fcport, 1);
break;
case MBS_LOOP_ID_USED:
/* data[1] = IO PARAM 1 = nport ID */
@@ -2029,6 +2081,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
set_bit(lid, vha->hw->loop_id_map);
ea->fcport->loop_id = lid;
ea->fcport->keep_nport_handle = 0;
ea->fcport->logout_on_delete = 1;
qlt_schedule_sess_for_deletion(ea->fcport);
}
break;
@@ -2036,16 +2089,6 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
return;
}
void
qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport,
uint16_t *data)
{
qlt_logo_completion_handler(fcport, data[0]);
fcport->login_gen++;
fcport->flags &= ~FCF_ASYNC_ACTIVE;
return;
}
/****************************************************************************/
/* QLogic ISP2x00 Hardware Support Functions. */
/****************************************************************************/
@@ -2205,8 +2248,18 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
ql_dbg(ql_dbg_init, vha, 0x0061,
"Configure NVRAM parameters...\n");
/* Let priority default to FCP, can be overridden by nvram_config */
ha->fc4_type_priority = FC4_PRIORITY_FCP;
ha->isp_ops->nvram_config(vha);
if (ha->fc4_type_priority != FC4_PRIORITY_FCP &&
ha->fc4_type_priority != FC4_PRIORITY_NVME)
ha->fc4_type_priority = FC4_PRIORITY_FCP;
ql_log(ql_log_info, vha, 0xffff, "FC4 priority set to %s\n",
ha->fc4_type_priority == FC4_PRIORITY_FCP ? "FCP" : "NVMe");
if (ha->flags.disable_serdes) {
/* Mask HBA via NVRAM settings? */
ql_log(ql_log_info, vha, 0x0077,
@@ -4829,6 +4882,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
}
INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn);
INIT_WORK(&fcport->free_work, qlt_free_session_done);
INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
INIT_LIST_HEAD(&fcport->gnl_entry);
INIT_LIST_HEAD(&fcport->list);
@@ -4896,25 +4950,15 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
qla2x00_get_data_rate(vha);
/* Determine what we need to do */
if (ha->current_topology == ISP_CFG_FL &&
(test_bit(LOCAL_LOOP_UPDATE, &flags))) {
set_bit(RSCN_UPDATE, &flags);
} else if (ha->current_topology == ISP_CFG_F &&
if ((ha->current_topology == ISP_CFG_FL ||
ha->current_topology == ISP_CFG_F) &&
(test_bit(LOCAL_LOOP_UPDATE, &flags))) {
set_bit(RSCN_UPDATE, &flags);
clear_bit(LOCAL_LOOP_UPDATE, &flags);
} else if (ha->current_topology == ISP_CFG_N) {
clear_bit(RSCN_UPDATE, &flags);
if (qla_tgt_mode_enabled(vha)) {
/* allow the other side to start the login */
clear_bit(LOCAL_LOOP_UPDATE, &flags);
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
}
} else if (ha->current_topology == ISP_CFG_NL) {
} else if (ha->current_topology == ISP_CFG_NL ||
ha->current_topology == ISP_CFG_N) {
clear_bit(RSCN_UPDATE, &flags);
set_bit(LOCAL_LOOP_UPDATE, &flags);
} else if (!vha->flags.online ||
@@ -5031,7 +5075,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
memcpy(&ha->plogi_els_payld.data,
(void *)ha->init_cb,
sizeof(ha->plogi_els_payld.data));
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
} else {
ql_dbg(ql_dbg_init, vha, 0x00d1,
"PLOGI ELS param read fail.\n");
@@ -5208,7 +5251,7 @@ skip_login:
qla_ini_mode_enabled(vha)) &&
atomic_read(&fcport->state) == FCS_ONLINE) {
qla2x00_mark_device_lost(vha, fcport,
ql2xplogiabsentdevice, 0);
ql2xplogiabsentdevice);
if (fcport->loop_id != FC_NO_LOOP_ID &&
(fcport->flags & FCF_FCP2_DEVICE) == 0 &&
fcport->port_type != FCT_INITIATOR &&
@@ -5229,7 +5272,7 @@ skip_login:
}
cleanup_allocation:
kfree(new_fcport);
qla2x00_free_fcport(new_fcport);
if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_disc, vha, 0x2098,
@@ -5363,11 +5406,14 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
ql_dbg(ql_dbg_disc, vha, 0x20ef, "%s %8phC\n",
__func__, fcport->port_name);
fcport->disc_state = DSC_UPD_FCPORT;
qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT);
fcport->login_retry = vha->hw->login_retry_count;
fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
fcport->deleted = 0;
fcport->logout_on_delete = 1;
if (vha->hw->current_topology == ISP_CFG_NL)
fcport->logout_on_delete = 0;
else
fcport->logout_on_delete = 1;
fcport->n2n_chip_reset = fcport->n2n_link_reset_cnt = 0;
switch (vha->hw->current_topology) {
@@ -5381,9 +5427,9 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
qla2x00_iidma_fcport(vha, fcport);
if (fcport->fc4f_nvme) {
if (NVME_TARGET(vha->hw, fcport)) {
qla_nvme_register_remote(vha, fcport);
fcport->disc_state = DSC_LOGIN_COMPLETE;
qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
qla2x00_set_fcport_state(fcport, FCS_ONLINE);
return;
}
@@ -5428,7 +5474,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
}
}
fcport->disc_state = DSC_LOGIN_COMPLETE;
qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
}
void qla_register_fcport_fn(struct work_struct *work)
@@ -5709,11 +5755,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
new_fcport->fc4_type = swl[swl_idx].fc4_type;
new_fcport->nvme_flag = 0;
new_fcport->fc4f_nvme = 0;
if (vha->flags.nvme_enabled &&
swl[swl_idx].fc4f_nvme) {
new_fcport->fc4f_nvme =
swl[swl_idx].fc4f_nvme;
swl[swl_idx].fc4_type & FS_FC4TYPE_NVME) {
ql_log(ql_log_info, vha, 0x2131,
"FOUND: NVME port %8phC as FC Type 28h\n",
new_fcport->port_name);
@@ -5769,7 +5812,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
/* Bypass ports whose FCP-4 type is not FCP_SCSI */
if (ql2xgffidenable &&
(new_fcport->fc4_type != FC4_TYPE_FCP_SCSI &&
(!(new_fcport->fc4_type & FS_FC4TYPE_FCP) &&
new_fcport->fc4_type != FC4_TYPE_UNKNOWN))
continue;
@@ -5838,9 +5881,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
break;
}
if (fcport->fc4f_nvme) {
if (NVME_TARGET(vha->hw, fcport)) {
if (fcport->disc_state == DSC_DELETE_PEND) {
fcport->disc_state = DSC_GNL;
qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
vha->fcport_count--;
fcport->login_succ = 0;
}
@@ -5878,8 +5921,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
break;
if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 ||
(fcport->flags & FCF_LOGIN_NEEDED) == 0)
if ((fcport->flags & FCF_FABRIC_DEVICE) == 0)
continue;
if (fcport->scan_state == QLA_FCPORT_SCAN) {
@@ -5887,7 +5929,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
qla_ini_mode_enabled(vha)) &&
atomic_read(&fcport->state) == FCS_ONLINE) {
qla2x00_mark_device_lost(vha, fcport,
ql2xplogiabsentdevice, 0);
ql2xplogiabsentdevice);
if (fcport->loop_id != FC_NO_LOOP_ID &&
(fcport->flags & FCF_FCP2_DEVICE) == 0 &&
fcport->port_type != FCT_INITIATOR &&
@@ -5902,7 +5944,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
}
}
if (fcport->scan_state == QLA_FCPORT_FOUND)
if (fcport->scan_state == QLA_FCPORT_FOUND &&
(fcport->flags & FCF_LOGIN_NEEDED) != 0)
qla24xx_fcport_handle_login(vha, fcport);
}
return (rval);
@@ -6052,7 +6095,7 @@ qla2x00_fabric_login(scsi_qla_host_t *vha, fc_port_t *fcport,
ha->isp_ops->fabric_logout(vha, fcport->loop_id,
fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa);
qla2x00_mark_device_lost(vha, fcport, 1, 0);
qla2x00_mark_device_lost(vha, fcport, 1);
rval = 1;
break;
@@ -6566,9 +6609,9 @@ qla2x00_quiesce_io(scsi_qla_host_t *vha)
atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
atomic_set(&vha->loop_state, LOOP_DOWN);
qla2x00_mark_all_devices_lost(vha, 0);
qla2x00_mark_all_devices_lost(vha);
list_for_each_entry(vp, &ha->vp_list, list)
qla2x00_mark_all_devices_lost(vp, 0);
qla2x00_mark_all_devices_lost(vp);
} else {
if (!atomic_read(&vha->loop_down_timer))
atomic_set(&vha->loop_down_timer,
@@ -6644,14 +6687,14 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
atomic_set(&vha->loop_state, LOOP_DOWN);
qla2x00_mark_all_devices_lost(vha, 0);
qla2x00_mark_all_devices_lost(vha);
spin_lock_irqsave(&ha->vport_slock, flags);
list_for_each_entry(vp, &ha->vp_list, list) {
atomic_inc(&vp->vref_count);
spin_unlock_irqrestore(&ha->vport_slock, flags);
qla2x00_mark_all_devices_lost(vp, 0);
qla2x00_mark_all_devices_lost(vp);
spin_lock_irqsave(&ha->vport_slock, flags);
atomic_dec(&vp->vref_count);
@@ -8513,6 +8556,9 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
/* N2N: driver will initiate Login instead of FW */
icb->firmware_options_3 |= BIT_8;
/* Determine NVMe/FCP priority for target ports */
ha->fc4_type_priority = qla2xxx_get_fc4_priority(vha);
if (rval) {
ql_log(ql_log_warn, vha, 0x0076,
"NVRAM configuration failed.\n");
@@ -9002,8 +9048,6 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)
struct qla_hw_data *ha = qpair->hw;
qpair->delete_in_progress = 1;
while (atomic_read(&qpair->ref_count))
msleep(500);
ret = qla25xx_delete_req_que(vha, qpair->req);
if (ret != QLA_SUCCESS)
+36
View File
@@ -113,6 +113,30 @@ qla2x00_clean_dsd_pool(struct qla_hw_data *ha, struct crc_context *ctx)
INIT_LIST_HEAD(&ctx->dsd_list);
}
static inline void
qla2x00_set_fcport_disc_state(fc_port_t *fcport, int state)
{
int old_val;
uint8_t shiftbits, mask;
/* This will have to change when the max no. of states > 16 */
shiftbits = 4;
mask = (1 << shiftbits) - 1;
fcport->disc_state = state;
while (1) {
old_val = atomic_read(&fcport->shadow_disc_state);
if (old_val == atomic_cmpxchg(&fcport->shadow_disc_state,
old_val, (old_val << shiftbits) | state)) {
ql_dbg(ql_dbg_disc, fcport->vha, 0x2134,
"FCPort %8phC disc_state transition: %s to %s - portid=%06x.\n",
fcport->port_name, port_dstate_str[old_val & mask],
port_dstate_str[state], fcport->d_id.b24);
return;
}
}
}
static inline int
qla2x00_hba_err_chk_enabled(srb_t *sp)
{
@@ -315,3 +339,15 @@ qla_83xx_start_iocbs(struct qla_qpair *qpair)
WRT_REG_DWORD(req->req_q_in, req->ring_index);
}
static inline int
qla2xxx_get_fc4_priority(struct scsi_qla_host *vha)
{
uint32_t data;
data =
((uint8_t *)vha->hw->nvram)[NVRAM_DUAL_FCP_NVME_FLAG_OFFSET];
return (data >> 6) & BIT_0 ? FC4_PRIORITY_FCP : FC4_PRIORITY_NVME;
}
+160 -22
View File
@@ -2411,11 +2411,19 @@ qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx)
static void
qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio)
{
u16 control_flags = LCF_COMMAND_LOGO;
logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
logio->control_flags =
cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
if (!sp->fcport->keep_nport_handle)
logio->control_flags |= cpu_to_le16(LCF_FREE_NPORT);
if (sp->fcport->explicit_logout) {
control_flags |= LCF_EXPL_LOGO|LCF_FREE_NPORT;
} else {
control_flags |= LCF_IMPL_LOGO;
if (!sp->fcport->keep_nport_handle)
control_flags |= LCF_FREE_NPORT;
}
logio->control_flags = cpu_to_le16(control_flags);
logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
logio->port_id[0] = sp->fcport->d_id.b.al_pa;
logio->port_id[1] = sp->fcport->d_id.b.area;
@@ -2535,13 +2543,32 @@ qla2x00_els_dcmd_iocb_timeout(void *data)
fc_port_t *fcport = sp->fcport;
struct scsi_qla_host *vha = sp->vha;
struct srb_iocb *lio = &sp->u.iocb_cmd;
unsigned long flags = 0;
int res, h;
ql_dbg(ql_dbg_io, vha, 0x3069,
"%s Timeout, hdl=%x, portid=%02x%02x%02x\n",
sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa);
complete(&lio->u.els_logo.comp);
/* Abort the exchange */
res = qla24xx_async_abort_cmd(sp, false);
if (res) {
ql_dbg(ql_dbg_io, vha, 0x3070,
"mbx abort_command failed.\n");
spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
if (sp->qpair->req->outstanding_cmds[h] == sp) {
sp->qpair->req->outstanding_cmds[h] = NULL;
break;
}
}
spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
complete(&lio->u.els_logo.comp);
} else {
ql_dbg(ql_dbg_io, vha, 0x3071,
"mbx abort_command success.\n");
}
}
static void qla2x00_els_dcmd_sp_done(srb_t *sp, int res)
@@ -2623,6 +2650,10 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
memcpy(elsio->u.els_logo.els_logo_pyld, &logo_pyld,
sizeof(struct els_logo_payload));
ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3075, "LOGO buffer:");
ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x010a,
elsio->u.els_logo.els_logo_pyld,
sizeof(*elsio->u.els_logo.els_logo_pyld));
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
@@ -2682,7 +2713,8 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073,
"PLOGI ELS IOCB:\n");
ql_dump_buffer(ql_log_info, vha, 0x0109,
(uint8_t *)els_iocb, 0x70);
(uint8_t *)els_iocb,
sizeof(*els_iocb));
} else {
els_iocb->control_flags = 1 << 13;
els_iocb->tx_byte_count =
@@ -2694,6 +2726,11 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
els_iocb->rx_byte_count = 0;
els_iocb->rx_address = 0;
els_iocb->rx_len = 0;
ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3076,
"LOGO ELS IOCB:");
ql_dump_buffer(ql_log_info, vha, 0x010b,
els_iocb,
sizeof(*els_iocb));
}
sp->vha->qla_stats.control_requests++;
@@ -2705,23 +2742,29 @@ qla2x00_els_dcmd2_iocb_timeout(void *data)
srb_t *sp = data;
fc_port_t *fcport = sp->fcport;
struct scsi_qla_host *vha = sp->vha;
struct qla_hw_data *ha = vha->hw;
unsigned long flags = 0;
int res;
int res, h;
ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3069,
"%s hdl=%x ELS Timeout, %8phC portid=%06x\n",
sp->name, sp->handle, fcport->port_name, fcport->d_id.b24);
/* Abort the exchange */
spin_lock_irqsave(&ha->hardware_lock, flags);
res = ha->isp_ops->abort_command(sp);
res = qla24xx_async_abort_cmd(sp, false);
ql_dbg(ql_dbg_io, vha, 0x3070,
"mbx abort_command %s\n",
(res == QLA_SUCCESS) ? "successful" : "failed");
spin_unlock_irqrestore(&ha->hardware_lock, flags);
sp->done(sp, QLA_FUNCTION_TIMEOUT);
if (res) {
spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
if (sp->qpair->req->outstanding_cmds[h] == sp) {
sp->qpair->req->outstanding_cmds[h] = NULL;
break;
}
}
spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
sp->done(sp, QLA_FUNCTION_TIMEOUT);
}
}
void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha, struct els_plogi *els_plogi)
@@ -2746,6 +2789,10 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
struct scsi_qla_host *vha = sp->vha;
struct event_arg ea;
struct qla_work_evt *e;
struct fc_port *conflict_fcport;
port_id_t cid; /* conflict Nport id */
u32 *fw_status = sp->u.iocb_cmd.u.els_plogi.fw_status;
u16 lid;
ql_dbg(ql_dbg_disc, vha, 0x3072,
"%s ELS done rc %d hdl=%x, portid=%06x %8phC\n",
@@ -2757,14 +2804,102 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
if (sp->flags & SRB_WAKEUP_ON_COMP)
complete(&lio->u.els_plogi.comp);
else {
if (res) {
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
} else {
switch (fw_status[0]) {
case CS_DATA_UNDERRUN:
case CS_COMPLETE:
memset(&ea, 0, sizeof(ea));
ea.fcport = fcport;
ea.data[0] = MBS_COMMAND_COMPLETE;
ea.sp = sp;
qla24xx_handle_plogi_done_event(vha, &ea);
ea.rc = res;
qla_handle_els_plogi_done(vha, &ea);
break;
case CS_IOCB_ERROR:
switch (fw_status[1]) {
case LSC_SCODE_PORTID_USED:
lid = fw_status[2] & 0xffff;
qlt_find_sess_invalidate_other(vha,
wwn_to_u64(fcport->port_name),
fcport->d_id, lid, &conflict_fcport);
if (conflict_fcport) {
/*
* Another fcport shares the same
* loop_id & nport id; conflict
* fcport needs to finish cleanup
* before this fcport can proceed
* to login.
*/
conflict_fcport->conflict = fcport;
fcport->login_pause = 1;
ql_dbg(ql_dbg_disc, vha, 0x20ed,
"%s %d %8phC pid %06x inuse with lid %#x post gidpn\n",
__func__, __LINE__,
fcport->port_name,
fcport->d_id.b24, lid);
} else {
ql_dbg(ql_dbg_disc, vha, 0x20ed,
"%s %d %8phC pid %06x inuse with lid %#x sched del\n",
__func__, __LINE__,
fcport->port_name,
fcport->d_id.b24, lid);
qla2x00_clear_loop_id(fcport);
set_bit(lid, vha->hw->loop_id_map);
fcport->loop_id = lid;
fcport->keep_nport_handle = 0;
qlt_schedule_sess_for_deletion(fcport);
}
break;
case LSC_SCODE_NPORT_USED:
cid.b.domain = (fw_status[2] >> 16) & 0xff;
cid.b.area = (fw_status[2] >> 8) & 0xff;
cid.b.al_pa = fw_status[2] & 0xff;
cid.b.rsvd_1 = 0;
ql_dbg(ql_dbg_disc, vha, 0x20ec,
"%s %d %8phC lid %#x in use with pid %06x post gnl\n",
__func__, __LINE__, fcport->port_name,
fcport->loop_id, cid.b24);
set_bit(fcport->loop_id,
vha->hw->loop_id_map);
fcport->loop_id = FC_NO_LOOP_ID;
qla24xx_post_gnl_work(vha, fcport);
break;
case LSC_SCODE_NOXCB:
vha->hw->exch_starvation++;
if (vha->hw->exch_starvation > 5) {
ql_log(ql_log_warn, vha, 0xd046,
"Exchange starvation. Resetting RISC\n");
vha->hw->exch_starvation = 0;
set_bit(ISP_ABORT_NEEDED,
&vha->dpc_flags);
qla2xxx_wake_dpc(vha);
}
/* fall through */
default:
ql_dbg(ql_dbg_disc, vha, 0x20eb,
"%s %8phC cmd error fw_status 0x%x 0x%x 0x%x\n",
__func__, sp->fcport->port_name,
fw_status[0], fw_status[1], fw_status[2]);
fcport->flags &= ~FCF_ASYNC_SENT;
qla2x00_set_fcport_disc_state(fcport,
DSC_LOGIN_FAILED);
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
break;
}
break;
default:
ql_dbg(ql_dbg_disc, vha, 0x20eb,
"%s %8phC cmd error 2 fw_status 0x%x 0x%x 0x%x\n",
__func__, sp->fcport->port_name,
fw_status[0], fw_status[1], fw_status[2]);
sp->fcport->flags &= ~FCF_ASYNC_SENT;
qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_FAILED);
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
break;
}
e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
@@ -2795,14 +2930,16 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
if (!sp) {
ql_log(ql_log_info, vha, 0x70e6,
"SRB allocation failed\n");
fcport->flags &= ~FCF_ASYNC_ACTIVE;
return -ENOMEM;
}
fcport->flags |= FCF_ASYNC_SENT;
qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
elsio = &sp->u.iocb_cmd;
ql_dbg(ql_dbg_io, vha, 0x3073,
"Enter: PLOGI portid=%06x\n", fcport->d_id.b24);
fcport->flags |= FCF_ASYNC_SENT;
sp->type = SRB_ELS_DCMD;
sp->name = "ELS_DCMD";
sp->fcport = fcport;
@@ -2848,7 +2985,8 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n");
ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x0109,
(uint8_t *)elsio->u.els_plogi.els_plogi_pyld, 0x70);
(uint8_t *)elsio->u.els_plogi.els_plogi_pyld,
sizeof(*elsio->u.els_plogi.els_plogi_pyld));
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
@@ -2870,7 +3008,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
}
out:
fcport->flags &= ~(FCF_ASYNC_SENT);
fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi);
sp->free(sp);
done:
+68 -26
View File
@@ -800,7 +800,7 @@ skip_rio:
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
atomic_set(&vha->loop_state, LOOP_DOWN);
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
qla2x00_mark_all_devices_lost(vha, 1);
qla2x00_mark_all_devices_lost(vha);
}
if (vha->vp_idx) {
@@ -873,7 +873,7 @@ skip_rio:
}
vha->device_flags |= DFLG_NO_CABLE;
qla2x00_mark_all_devices_lost(vha, 1);
qla2x00_mark_all_devices_lost(vha);
}
if (vha->vp_idx) {
@@ -893,7 +893,7 @@ skip_rio:
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
atomic_set(&vha->loop_state, LOOP_DOWN);
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
qla2x00_mark_all_devices_lost(vha, 1);
qla2x00_mark_all_devices_lost(vha);
}
if (vha->vp_idx) {
@@ -936,7 +936,7 @@ skip_rio:
atomic_set(&vha->loop_down_timer,
LOOP_DOWN_TIME);
if (!N2N_TOPO(ha))
qla2x00_mark_all_devices_lost(vha, 1);
qla2x00_mark_all_devices_lost(vha);
}
if (vha->vp_idx) {
@@ -965,7 +965,7 @@ skip_rio:
if (!atomic_read(&vha->loop_down_timer))
atomic_set(&vha->loop_down_timer,
LOOP_DOWN_TIME);
qla2x00_mark_all_devices_lost(vha, 1);
qla2x00_mark_all_devices_lost(vha);
}
if (vha->vp_idx) {
@@ -1034,7 +1034,6 @@ skip_rio:
"Marking port lost loopid=%04x portid=%06x.\n",
fcport->loop_id, fcport->d_id.b24);
if (qla_ini_mode_enabled(vha)) {
qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
fcport->logout_on_delete = 0;
qlt_schedule_sess_for_deletion(fcport);
}
@@ -1046,14 +1045,14 @@ global_port_update:
atomic_set(&vha->loop_down_timer,
LOOP_DOWN_TIME);
vha->device_flags |= DFLG_NO_CABLE;
qla2x00_mark_all_devices_lost(vha, 1);
qla2x00_mark_all_devices_lost(vha);
}
if (vha->vp_idx) {
atomic_set(&vha->vp_state, VP_FAILED);
fc_vport_set_state(vha->fc_vport,
FC_VPORT_FAILED);
qla2x00_mark_all_devices_lost(vha, 1);
qla2x00_mark_all_devices_lost(vha);
}
vha->flags.management_server_logged_in = 0;
@@ -1073,8 +1072,6 @@ global_port_update:
ql_dbg(ql_dbg_async, vha, 0x5011,
"Asynchronous PORT UPDATE ignored %04x/%04x/%04x.\n",
mb[1], mb[2], mb[3]);
qlt_async_event(mb[0], vha, mb);
break;
}
@@ -1091,8 +1088,6 @@ global_port_update:
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
set_bit(VP_CONFIG_OK, &vha->vp_flags);
qlt_async_event(mb[0], vha, mb);
break;
case MBA_RSCN_UPDATE: /* State Change Registration */
@@ -1239,20 +1234,63 @@ global_port_update:
break;
case MBA_IDC_AEN:
mb[4] = RD_REG_WORD(&reg24->mailbox4);
mb[5] = RD_REG_WORD(&reg24->mailbox5);
mb[6] = RD_REG_WORD(&reg24->mailbox6);
mb[7] = RD_REG_WORD(&reg24->mailbox7);
qla83xx_handle_8200_aen(vha, mb);
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
ha->flags.fw_init_done = 0;
ql_log(ql_log_warn, vha, 0xffff,
"MPI Heartbeat stop. Chip reset needed. MB0[%xh] MB1[%xh] MB2[%xh] MB3[%xh]\n",
mb[0], mb[1], mb[2], mb[3]);
if ((mb[1] & BIT_8) ||
(mb[2] & BIT_8)) {
ql_log(ql_log_warn, vha, 0xd013,
"MPI Heartbeat stop. FW dump needed\n");
ha->fw_dump_mpi = 1;
ha->isp_ops->fw_dump(vha, 1);
}
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
} else if (IS_QLA83XX(ha)) {
mb[4] = RD_REG_WORD(&reg24->mailbox4);
mb[5] = RD_REG_WORD(&reg24->mailbox5);
mb[6] = RD_REG_WORD(&reg24->mailbox6);
mb[7] = RD_REG_WORD(&reg24->mailbox7);
qla83xx_handle_8200_aen(vha, mb);
} else {
ql_dbg(ql_dbg_async, vha, 0x5052,
"skip Heartbeat processing mb0-3=[0x%04x] [0x%04x] [0x%04x] [0x%04x]\n",
mb[0], mb[1], mb[2], mb[3]);
}
break;
case MBA_DPORT_DIAGNOSTICS:
ql_dbg(ql_dbg_async, vha, 0x5052,
"D-Port Diagnostics: %04x result=%s\n",
mb[0],
mb[1] == 0 ? "start" :
mb[1] == 1 ? "done (pass)" :
mb[1] == 2 ? "done (error)" : "other");
"D-Port Diagnostics: %04x %04x %04x %04x\n",
mb[0], mb[1], mb[2], mb[3]);
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
static char *results[] = {
"start", "done(pass)", "done(error)", "undefined" };
static char *types[] = {
"none", "dynamic", "static", "other" };
uint result = mb[1] >> 0 & 0x3;
uint type = mb[1] >> 6 & 0x3;
uint sw = mb[1] >> 15 & 0x1;
ql_dbg(ql_dbg_async, vha, 0x5052,
"D-Port Diagnostics: result=%s type=%s [sw=%u]\n",
results[result], types[type], sw);
if (result == 2) {
static char *reasons[] = {
"reserved", "unexpected reject",
"unexpected phase", "retry exceeded",
"timed out", "not supported",
"user stopped" };
uint reason = mb[2] >> 0 & 0xf;
uint phase = mb[2] >> 12 & 0xf;
ql_dbg(ql_dbg_async, vha, 0x5052,
"D-Port Diagnostics: reason=%s phase=%u \n",
reason < 7 ? reasons[reason] : "other",
phase >> 1);
}
}
break;
case MBA_TEMPERATURE_ALERT:
@@ -2490,6 +2528,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
return;
}
if (sp->abort)
sp->aborted = 1;
else
sp->completed = 1;
if (sp->cmd_type != TYPE_SRB) {
req->outstanding_cmds[handle] = NULL;
ql_dbg(ql_dbg_io, vha, 0x3015,
@@ -2747,7 +2790,6 @@ check_scsi_status:
port_state_str[FCS_ONLINE],
comp_status);
qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
qlt_schedule_sess_for_deletion(fcport);
}
@@ -3737,7 +3779,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
skip_msix:
ql_log(ql_log_info, vha, 0x0037,
"Falling back-to MSI mode -%d.\n", ret);
"Falling back-to MSI mode -- ret=%d.\n", ret);
if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) &&
!IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha) &&
@@ -3749,13 +3791,13 @@ skip_msix:
#else
ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI);
#endif
if (!ret) {
if (ret > 0) {
ql_dbg(ql_dbg_init, vha, 0x0038,
"MSI: Enabled.\n");
ha->flags.msi_enabled = 1;
} else
ql_log(ql_log_warn, vha, 0x0039,
"Falling back-to INTa mode -- %d.\n", ret);
"Falling back-to INTa mode -- ret=%d.\n", ret);
skip_msi:
/* Skip INTx on ISP82xx. */
+9 -12
View File
@@ -1932,7 +1932,7 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
pd24 = (struct port_database_24xx *) pd;
/* Check for logged in state. */
if (fcport->fc4f_nvme) {
if (NVME_TARGET(ha, fcport)) {
current_login_state = pd24->current_login_state >> 4;
last_login_state = pd24->last_login_state >> 4;
} else {
@@ -3899,8 +3899,9 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
fcport->scan_state = QLA_FCPORT_FOUND;
fcport->n2n_flag = 1;
fcport->keep_nport_handle = 1;
fcport->fc4_type = FS_FC4TYPE_FCP;
if (vha->flags.nvme_enabled)
fcport->fc4f_nvme = 1;
fcport->fc4_type |= FS_FC4TYPE_NVME;
switch (fcport->disc_state) {
case DSC_DELETED:
@@ -3920,6 +3921,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
vha->d_id.b24 = 0;
vha->d_id.b.al_pa = 1;
ha->flags.n2n_bigger = 1;
ha->flags.n2n_ae = 0;
id.b.al_pa = 2;
ql_dbg(ql_dbg_async, vha, 0x5075,
@@ -3930,6 +3932,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
"Format 1: Remote login - Waiting for WWPN %8phC.\n",
rptid_entry->u.f1.port_name);
ha->flags.n2n_bigger = 0;
ha->flags.n2n_ae = 1;
}
qla24xx_post_newsess_work(vha, &id,
rptid_entry->u.f1.port_name,
@@ -3941,7 +3944,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
/* if our portname is higher then initiate N2N login */
set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
ha->flags.n2n_ae = 1;
return;
break;
case TOPO_FL:
@@ -6150,9 +6152,8 @@ qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
mcp->mb[7] = LSW(MSD(req_dma));
mcp->mb[8] = MSW(addr);
/* Setting RAM ID to valid */
mcp->mb[10] |= BIT_7;
/* For MCTP RAM ID is 0x40 */
mcp->mb[10] |= 0x40;
mcp->mb[10] = BIT_7 | 0x40;
mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
MBX_0;
@@ -6287,17 +6288,13 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)
case QLA_SUCCESS:
ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n",
__func__, sp->name);
sp->free(sp);
break;
default:
ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n",
__func__, sp->name, rval);
sp->free(sp);
break;
}
return rval;
done_free_sp:
sp->free(sp);
done:
@@ -6362,7 +6359,7 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
uint64_t zero = 0;
u8 current_login_state, last_login_state;
if (fcport->fc4f_nvme) {
if (NVME_TARGET(vha->hw, fcport)) {
current_login_state = pd->current_login_state >> 4;
last_login_state = pd->last_login_state >> 4;
} else {
@@ -6397,8 +6394,8 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
fcport->d_id.b.al_pa = pd->port_id[2];
fcport->d_id.b.rsvd_1 = 0;
if (fcport->fc4f_nvme) {
fcport->port_type = 0;
if (NVME_TARGET(vha->hw, fcport)) {
fcport->port_type = FCT_NVME;
if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0)
fcport->port_type |= FCT_NVME_INITIATOR;
if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
+7 -10
View File
@@ -147,7 +147,7 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha)
"Marking port dead, loop_id=0x%04x : %x.\n",
fcport->loop_id, fcport->vha->vp_idx);
qla2x00_mark_device_lost(vha, fcport, 0, 0);
qla2x00_mark_device_lost(vha, fcport, 0);
qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED);
}
}
@@ -167,7 +167,7 @@ qla24xx_disable_vp(scsi_qla_host_t *vha)
list_for_each_entry(fcport, &vha->vp_fcports, list)
fcport->logout_on_delete = 0;
qla2x00_mark_all_devices_lost(vha, 0);
qla2x00_mark_all_devices_lost(vha);
/* Remove port id from vp target map */
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
@@ -327,7 +327,7 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
*/
if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
atomic_set(&vha->loop_state, LOOP_DOWN);
qla2x00_mark_all_devices_lost(vha, 0);
qla2x00_mark_all_devices_lost(vha);
} else {
if (!atomic_read(&vha->loop_down_timer))
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
@@ -946,7 +946,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL);
if (!sp)
goto done;
return rval;
sp->type = SRB_CTRL_VP;
sp->name = "ctrl_vp";
@@ -962,7 +962,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
ql_dbg(ql_dbg_async, vha, 0xffff,
"%s: %s Failed submission. %x.\n",
__func__, sp->name, rval);
goto done_free_sp;
goto done;
}
ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n",
@@ -980,16 +980,13 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
case QLA_SUCCESS:
ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s done.\n",
__func__, sp->name);
goto done_free_sp;
break;
default:
ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s Failed. %x.\n",
__func__, sp->name, rval);
goto done_free_sp;
break;
}
done:
return rval;
done_free_sp:
sp->free(sp);
return rval;
}
+8 -8
View File
@@ -1210,9 +1210,9 @@ qlafx00_find_all_targets(scsi_qla_host_t *vha,
" Existing TGT-ID %x did not get "
" offline event from firmware.\n",
fcport->old_tgt_id);
qla2x00_mark_device_lost(vha, fcport, 0, 0);
qla2x00_mark_device_lost(vha, fcport, 0);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
kfree(new_fcport);
qla2x00_free_fcport(new_fcport);
return rval;
}
break;
@@ -1230,7 +1230,7 @@ qlafx00_find_all_targets(scsi_qla_host_t *vha,
return QLA_MEMORY_ALLOC_FAILED;
}
kfree(new_fcport);
qla2x00_free_fcport(new_fcport);
return rval;
}
@@ -1274,7 +1274,7 @@ qlafx00_configure_all_targets(scsi_qla_host_t *vha)
if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
if (fcport->port_type != FCT_INITIATOR)
qla2x00_mark_device_lost(vha, fcport, 0, 0);
qla2x00_mark_device_lost(vha, fcport, 0);
}
}
@@ -1298,7 +1298,7 @@ qlafx00_configure_all_targets(scsi_qla_host_t *vha)
/* Free all new device structures not processed. */
list_for_each_entry_safe(fcport, rmptemp, &new_fcports, list) {
list_del(&fcport->list);
kfree(fcport);
qla2x00_free_fcport(fcport);
}
return rval;
@@ -1706,7 +1706,7 @@ qlafx00_tgt_detach(struct scsi_qla_host *vha, int tgt_id)
if (!fcport)
return;
qla2x00_mark_device_lost(vha, fcport, 0, 0);
qla2x00_mark_device_lost(vha, fcport, 0);
return;
}
@@ -1740,7 +1740,7 @@ qlafx00_process_aen(struct scsi_qla_host *vha, struct qla_work_evt *evt)
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
} else if (evt->u.aenfx.mbx[2] == 2) {
vha->device_flags |= DFLG_NO_CABLE;
qla2x00_mark_all_devices_lost(vha, 1);
qla2x00_mark_all_devices_lost(vha);
}
}
break;
@@ -2528,7 +2528,7 @@ check_scsi_status:
atomic_read(&fcport->state));
if (atomic_read(&fcport->state) == FCS_ONLINE)
qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
qla2x00_mark_device_lost(fcport->vha, fcport, 1);
break;
case CS_ABORTED:
+9 -2
View File
@@ -235,8 +235,8 @@ static void qla_nvme_abort_work(struct work_struct *work)
if (ha->flags.host_shutting_down) {
ql_log(ql_log_info, sp->fcport->vha, 0xffff,
"%s Calling done on sp: %p, type: 0x%x, sp->ref_count: 0x%x\n",
__func__, sp, sp->type, atomic_read(&sp->ref_count));
"%s Calling done on sp: %p, type: 0x%x\n",
__func__, sp, sp->type);
sp->done(sp, 0);
goto out;
}
@@ -621,6 +621,13 @@ static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
}
static struct nvme_fc_port_template qla_nvme_fc_transport = {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)
/*
* See also commit 863fbae929c7 ("nvme_fc: add module to ops template
* to allow module references").
*/
.module = THIS_MODULE,
#endif
.localport_delete = qla_nvme_localport_delete,
.remoteport_delete = qla_nvme_remoteport_delete,
.create_queue = qla_nvme_alloc_queue,
+1 -1
View File
@@ -3029,7 +3029,7 @@ qla8xxx_dev_failed_handler(scsi_qla_host_t *vha)
/* Set DEV_FAILED flag to disable timer */
vha->device_flags |= DFLG_DEV_FAILED;
qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
qla2x00_mark_all_devices_lost(vha, 0);
qla2x00_mark_all_devices_lost(vha);
vha->flags.online = 0;
vha->flags.init_done = 0;
}
+122 -127
View File
@@ -718,11 +718,6 @@ void qla2x00_sp_compl(srb_t *sp, int res)
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
struct completion *comp = sp->comp;
if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0))
return;
atomic_dec(&sp->ref_count);
sp->free(sp);
cmd->result = res;
CMD_SP(cmd) = NULL;
@@ -814,11 +809,6 @@ void qla2xxx_qpair_sp_compl(srb_t *sp, int res)
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
struct completion *comp = sp->comp;
if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0))
return;
atomic_dec(&sp->ref_count);
sp->free(sp);
cmd->result = res;
CMD_SP(cmd) = NULL;
@@ -940,7 +930,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
sp->u.scmd.cmd = cmd;
sp->type = SRB_SCSI_CMD;
atomic_set(&sp->ref_count, 1);
CMD_SP(cmd) = (void *)sp;
sp->free = qla2x00_sp_free_dma;
sp->done = qla2x00_sp_compl;
@@ -1022,18 +1012,16 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
sp->u.scmd.cmd = cmd;
sp->type = SRB_SCSI_CMD;
atomic_set(&sp->ref_count, 1);
CMD_SP(cmd) = (void *)sp;
sp->free = qla2xxx_qpair_sp_free_dma;
sp->done = qla2xxx_qpair_sp_compl;
sp->qpair = qpair;
rval = ha->isp_ops->start_scsi_mq(sp);
if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078,
"Start scsi failed rval=%d for cmd=%p.\n", rval, cmd);
if (rval == QLA_INTERFACE_ERROR)
goto qc24_fail_command;
goto qc24_free_sp_fail_command;
goto qc24_host_busy_free_sp;
}
@@ -1045,6 +1033,11 @@ qc24_host_busy_free_sp:
qc24_target_busy:
return SCSI_MLQUEUE_TARGET_BUSY;
qc24_free_sp_fail_command:
sp->free(sp);
CMD_SP(cmd) = NULL;
qla2xxx_rel_qpair_sp(sp->qpair, sp);
qc24_fail_command:
cmd->scsi_done(cmd);
@@ -1154,7 +1147,7 @@ qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha)
{
u8 i;
qla2x00_mark_all_devices_lost(vha, 0);
qla2x00_mark_all_devices_lost(vha);
for (i = 0; i < 10; i++) {
if (wait_event_timeout(vha->fcport_waitQ,
@@ -1221,23 +1214,6 @@ qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
return return_status;
}
static int
sp_get(struct srb *sp)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
if (!atomic_inc_not_zero(&sp->ref_count))
return ENXIO;
else
return 0;
#else
if (!refcount_inc_not_zero((refcount_t *)&sp->ref_count))
/* kref get fail */
return ENXIO;
else
return 0;
#endif
}
#define ISP_REG_DISCONNECT 0xffffffffU
/**************************************************************************
* qla2x00_isp_reg_stat
@@ -1293,6 +1269,9 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
uint64_t lun;
int rval;
struct qla_hw_data *ha = vha->hw;
uint32_t ratov_j;
struct qla_qpair *qpair;
unsigned long flags;
if (qla2x00_isp_reg_stat(ha)) {
ql_log(ql_log_info, vha, 0x8042,
@@ -1305,13 +1284,26 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
return ret;
sp = scsi_cmd_priv(cmd);
qpair = sp->qpair;
if (sp->fcport && sp->fcport->deleted)
if ((sp->fcport && sp->fcport->deleted) || !qpair)
return SUCCESS;
/* Return if the command has already finished. */
if (sp_get(sp))
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
if (sp->completed) {
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return SUCCESS;
}
if (sp->abort || sp->aborted) {
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return FAILED;
}
sp->abort = 1;
sp->comp = &comp;
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
id = cmd->device->id;
lun = cmd->device->lun;
@@ -1320,47 +1312,37 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
"Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n",
vha->host_no, id, lun, sp, cmd, sp->handle);
/*
* Abort will release the original Command/sp from FW. Let the
* original command call scsi_done. In return, he will wakeup
* this sleeping thread.
*/
rval = ha->isp_ops->abort_command(sp);
ql_dbg(ql_dbg_taskm, vha, 0x8003,
"Abort command mbx cmd=%p, rval=%x.\n", cmd, rval);
/* Wait for the command completion. */
ratov_j = ha->r_a_tov/10 * 4 * 1000;
ratov_j = msecs_to_jiffies(ratov_j);
switch (rval) {
case QLA_SUCCESS:
/*
* The command has been aborted. That means that the firmware
* won't report a completion.
*/
sp->done(sp, DID_ABORT << 16);
ret = SUCCESS;
break;
case QLA_FUNCTION_PARAMETER_ERROR: {
/* Wait for the command completion. */
uint32_t ratov = ha->r_a_tov/10;
uint32_t ratov_j = msecs_to_jiffies(4 * ratov * 1000);
WARN_ON_ONCE(sp->comp);
sp->comp = &comp;
if (!wait_for_completion_timeout(&comp, ratov_j)) {
ql_dbg(ql_dbg_taskm, vha, 0xffff,
"%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n",
__func__, ha->r_a_tov);
__func__, ha->r_a_tov/10);
ret = FAILED;
} else {
ret = SUCCESS;
}
break;
}
default:
/*
* Either abort failed or abort and completion raced. Let
* the SCSI core retry the abort in the former case.
*/
ret = FAILED;
break;
}
sp->comp = NULL;
atomic_dec(&sp->ref_count);
ql_log(ql_log_info, vha, 0x801c,
"Abort command issued nexus=%ld:%d:%llu -- %x.\n",
vha->host_no, id, lun, ret);
@@ -1722,7 +1704,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
if (ha->flags.enable_lip_full_login && !IS_CNA_CAPABLE(ha)) {
atomic_set(&vha->loop_state, LOOP_DOWN);
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
qla2x00_mark_all_devices_lost(vha, 0);
qla2x00_mark_all_devices_lost(vha);
ret = qla2x00_full_login_lip(vha);
if (ret != QLA_SUCCESS) {
ql_dbg(ql_dbg_taskm, vha, 0x802d,
@@ -1752,32 +1734,53 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
scsi_qla_host_t *vha = qp->vha;
struct qla_hw_data *ha = vha->hw;
int rval;
bool ret_cmd;
uint32_t ratov_j;
if (sp_get(sp))
if (qla2x00_chip_is_down(vha)) {
sp->done(sp, res);
return;
}
if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS ||
(sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy &&
!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
!qla2x00_isp_reg_stat(ha))) {
sp->comp = &comp;
spin_unlock_irqrestore(qp->qp_lock_ptr, *flags);
rval = ha->isp_ops->abort_command(sp);
if (sp->comp) {
sp->done(sp, res);
return;
}
sp->comp = &comp;
sp->abort = 1;
spin_unlock_irqrestore(qp->qp_lock_ptr, *flags);
rval = ha->isp_ops->abort_command(sp);
/* Wait for command completion. */
ret_cmd = false;
ratov_j = ha->r_a_tov/10 * 4 * 1000;
ratov_j = msecs_to_jiffies(ratov_j);
switch (rval) {
case QLA_SUCCESS:
sp->done(sp, res);
if (wait_for_completion_timeout(&comp, ratov_j)) {
ql_dbg(ql_dbg_taskm, vha, 0xffff,
"%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n",
__func__, ha->r_a_tov/10);
ret_cmd = true;
}
/* else FW return SP to driver */
break;
case QLA_FUNCTION_PARAMETER_ERROR:
wait_for_completion(&comp);
default:
ret_cmd = true;
break;
}
spin_lock_irqsave(qp->qp_lock_ptr, *flags);
sp->comp = NULL;
if (ret_cmd && (!sp->completed || !sp->aborted))
sp->done(sp, res);
} else {
sp->done(sp, res);
}
atomic_dec(&sp->ref_count);
}
static void
@@ -1799,7 +1802,6 @@ __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) {
req->outstanding_cmds[cnt] = NULL;
switch (sp->cmd_type) {
case TYPE_SRB:
qla2x00_abort_srb(qp, sp, res, &flags);
@@ -1821,6 +1823,7 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
default:
break;
}
req->outstanding_cmds[cnt] = NULL;
}
}
spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
@@ -3542,6 +3545,29 @@ disable_device:
return ret;
}
static void __qla_set_remove_flag(scsi_qla_host_t *base_vha)
{
scsi_qla_host_t *vp;
unsigned long flags;
struct qla_hw_data *ha;
if (!base_vha)
return;
ha = base_vha->hw;
spin_lock_irqsave(&ha->vport_slock, flags);
list_for_each_entry(vp, &ha->vp_list, list)
set_bit(PFLG_DRIVER_REMOVING, &vp->pci_flags);
/*
* Indicate device removal to prevent future board_disable
* and wait until any pending board_disable has completed.
*/
set_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags);
spin_unlock_irqrestore(&ha->vport_slock, flags);
}
static void
qla2x00_shutdown(struct pci_dev *pdev)
{
@@ -3558,7 +3584,7 @@ qla2x00_shutdown(struct pci_dev *pdev)
* Prevent future board_disable and wait
* until any pending board_disable has completed.
*/
set_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags);
__qla_set_remove_flag(vha);
cancel_work_sync(&ha->board_disable);
if (!atomic_read(&pdev->enable_cnt))
@@ -3718,10 +3744,7 @@ qla2x00_remove_one(struct pci_dev *pdev)
ha = base_vha->hw;
ql_log(ql_log_info, base_vha, 0xb079,
"Removing driver\n");
/* Indicate device removal to prevent future board_disable and wait
* until any pending board_disable has completed. */
set_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags);
__qla_set_remove_flag(base_vha);
cancel_work_sync(&ha->board_disable);
/*
@@ -3874,37 +3897,21 @@ void qla2x00_free_fcports(struct scsi_qla_host *vha)
}
static inline void
qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
int defer)
qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport)
{
struct fc_rport *rport;
scsi_qla_host_t *base_vha;
unsigned long flags;
int now;
if (!fcport->rport)
return;
rport = fcport->rport;
if (defer) {
base_vha = pci_get_drvdata(vha->hw->pdev);
spin_lock_irqsave(vha->host->host_lock, flags);
fcport->drport = rport;
spin_unlock_irqrestore(vha->host->host_lock, flags);
qlt_do_generation_tick(vha, &base_vha->total_fcport_update_gen);
set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
qla2xxx_wake_dpc(base_vha);
} else {
int now;
if (rport) {
ql_dbg(ql_dbg_disc, fcport->vha, 0x2109,
"%s %8phN. rport %p roles %x\n",
__func__, fcport->port_name, rport,
rport->roles);
fc_remote_port_delete(rport);
}
qlt_do_generation_tick(vha, &now);
if (fcport->rport) {
ql_dbg(ql_dbg_disc, fcport->vha, 0x2109,
"%s %8phN. rport %p roles %x\n",
__func__, fcport->port_name, fcport->rport,
fcport->rport->roles);
fc_remote_port_delete(fcport->rport);
}
qlt_do_generation_tick(vha, &now);
}
/*
@@ -3917,18 +3924,18 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
* Context:
*/
void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
int do_login, int defer)
int do_login)
{
if (IS_QLAFX00(vha->hw)) {
qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
qla2x00_schedule_rport_del(vha, fcport, defer);
qla2x00_schedule_rport_del(vha, fcport);
return;
}
if (atomic_read(&fcport->state) == FCS_ONLINE &&
vha->vp_idx == fcport->vha->vp_idx) {
qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
qla2x00_schedule_rport_del(vha, fcport, defer);
qla2x00_schedule_rport_del(vha, fcport);
}
/*
* We may need to retry the login, so don't change the state of the
@@ -3957,7 +3964,7 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
* Context:
*/
void
qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha)
{
fc_port_t *fcport;
@@ -3977,13 +3984,6 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
*/
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
continue;
if (atomic_read(&fcport->state) == FCS_ONLINE) {
qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
if (defer)
qla2x00_schedule_rport_del(vha, fcport, defer);
else if (vha->vp_idx == fcport->vha->vp_idx)
qla2x00_schedule_rport_del(vha, fcport, defer);
}
}
}
@@ -4716,7 +4716,8 @@ qla2x00_mem_free(struct qla_hw_data *ha)
ha->sfp_data = NULL;
if (ha->flt)
dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE,
dma_free_coherent(&ha->pdev->dev,
sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE,
ha->flt, ha->flt_dma);
ha->flt = NULL;
ha->flt_dma = 0;
@@ -4984,7 +4985,6 @@ int qla2x00_post_async_##name##_work( \
qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN);
qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
qla2x00_post_async_work(adisc, QLA_EVT_ASYNC_ADISC);
qla2x00_post_async_work(prlo, QLA_EVT_ASYNC_PRLO);
qla2x00_post_async_work(prlo_done, QLA_EVT_ASYNC_PRLO_DONE);
@@ -5051,7 +5051,7 @@ void qla24xx_sched_upd_fcport(fc_port_t *fcport)
fcport->jiffies_at_registration = jiffies;
fcport->sec_since_registration = 0;
fcport->next_disc_state = DSC_DELETED;
fcport->disc_state = DSC_UPD_FCPORT;
qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT);
spin_unlock_irqrestore(&fcport->vha->work_lock, flags);
#if defined(RHEL_MAJOR) && RHEL_MAJOR -0 <= 6
@@ -5096,19 +5096,17 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
fcport->d_id = e->u.new_sess.id;
fcport->flags |= FCF_FABRIC_DEVICE;
fcport->fw_login_state = DSC_LS_PLOGI_PEND;
if (e->u.new_sess.fc4_type == FS_FC4TYPE_FCP)
fcport->fc4_type = FC4_TYPE_FCP_SCSI;
if (e->u.new_sess.fc4_type == FS_FC4TYPE_NVME) {
fcport->fc4_type = FC4_TYPE_OTHER;
fcport->fc4f_nvme = FC4_TYPE_NVME;
}
memcpy(fcport->port_name, e->u.new_sess.port_name,
WWN_SIZE);
if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N)
fcport->fc4_type = e->u.new_sess.fc4_type;
if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) {
fcport->fc4_type = FS_FC4TYPE_FCP;
fcport->n2n_flag = 1;
if (vha->flags.nvme_enabled)
fcport->fc4_type |= FS_FC4TYPE_NVME;
}
} else {
ql_dbg(ql_dbg_disc, vha, 0xffff,
@@ -5212,7 +5210,8 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
fcport->flags &= ~FCF_FABRIC_DEVICE;
fcport->keep_nport_handle = 1;
if (vha->flags.nvme_enabled) {
fcport->fc4f_nvme = 1;
fcport->fc4_type =
(FS_FC4TYPE_NVME | FS_FC4TYPE_FCP);
fcport->n2n_flag = 1;
}
fcport->fw_login_state = 0;
@@ -5277,10 +5276,6 @@ qla2x00_do_work(struct scsi_qla_host *vha)
case QLA_EVT_ASYNC_LOGOUT:
rc = qla2x00_async_logout(vha, e->u.logio.fcport);
break;
case QLA_EVT_ASYNC_LOGOUT_DONE:
qla2x00_async_logout_done(vha, e->u.logio.fcport,
e->u.logio.data);
break;
case QLA_EVT_ASYNC_ADISC:
qla2x00_async_adisc(vha, e->u.logio.fcport,
e->u.logio.data);
@@ -6923,13 +6918,13 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha)
qpair->online = 0;
mutex_unlock(&ha->mq_lock);
qla2x00_mark_all_devices_lost(vha, 0);
qla2x00_mark_all_devices_lost(vha);
spin_lock_irqsave(&ha->vport_slock, flags);
list_for_each_entry(vp, &ha->vp_list, list) {
atomic_inc(&vp->vref_count);
spin_unlock_irqrestore(&ha->vport_slock, flags);
qla2x00_mark_all_devices_lost(vp, 0);
qla2x00_mark_all_devices_lost(vp);
spin_lock_irqsave(&ha->vport_slock, flags);
atomic_dec(&vp->vref_count);
}
+26 -9
View File
@@ -847,15 +847,15 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
ha->flt_region_img_status_pri = start;
break;
case FLT_REG_IMG_SEC_27XX:
if (IS_QLA27XX(ha) && !IS_QLA28XX(ha))
if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
ha->flt_region_img_status_sec = start;
break;
case FLT_REG_FW_SEC_27XX:
if (IS_QLA27XX(ha) && !IS_QLA28XX(ha))
if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
ha->flt_region_fw_sec = start;
break;
case FLT_REG_BOOTLOAD_SEC_27XX:
if (IS_QLA27XX(ha) && !IS_QLA28XX(ha))
if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
ha->flt_region_boot_sec = start;
break;
case FLT_REG_AUX_IMG_PRI_28XX:
@@ -2725,8 +2725,11 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff,
"Region %x is secure\n", region.code);
if (region.code == FLT_REG_FW ||
region.code == FLT_REG_FW_SEC_27XX) {
switch (region.code) {
case FLT_REG_FW:
case FLT_REG_FW_SEC_27XX:
case FLT_REG_MPI_PRI_28XX:
case FLT_REG_MPI_SEC_28XX:
fw_array = dwptr;
/* 1st fw array */
@@ -2757,9 +2760,23 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
buf_size_without_sfub += risc_size;
fw_array += risc_size;
}
} else {
ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff,
"Secure region %x not supported\n",
break;
case FLT_REG_PEP_PRI_28XX:
case FLT_REG_PEP_SEC_28XX:
fw_array = dwptr;
/* 1st fw array */
risc_size = be32_to_cpu(fw_array[3]);
risc_attr = be32_to_cpu(fw_array[9]);
buf_size_without_sfub = risc_size;
fw_array += risc_size;
break;
default:
ql_log(ql_log_warn + ql_dbg_verbose, vha,
0xffff, "Secure region %x not supported\n",
region.code);
rval = QLA_COMMAND_ERROR;
goto done;
@@ -2880,7 +2897,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
"Sending Secure Flash MB Cmd\n");
rval = qla28xx_secure_flash_update(vha, 0, region.code,
buf_size_without_sfub, sfub_dma,
sizeof(struct secure_flash_update_block));
sizeof(struct secure_flash_update_block) >> 2);
if (rval != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0xffff,
"Secure Flash MB Cmd failed %x.", rval);
+28 -20
View File
@@ -476,7 +476,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha,
case IMMED_NOTIFY_TYPE:
{
struct scsi_qla_host *host = vha;
struct scsi_qla_host *host;
struct imm_ntfy_from_isp *entry =
(struct imm_ntfy_from_isp *)pkt;
@@ -609,7 +609,8 @@ static void qla2x00_async_nack_sp_done(srb_t *sp, int res)
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
} else {
sp->fcport->login_retry = 0;
sp->fcport->disc_state = DSC_LOGIN_COMPLETE;
qla2x00_set_fcport_disc_state(sp->fcport,
DSC_LOGIN_COMPLETE);
sp->fcport->deleted = 0;
sp->fcport->logout_on_delete = 1;
}
@@ -970,7 +971,7 @@ void qlt_free_session_done(struct work_struct *work)
struct qlt_plogi_ack_t *own =
sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN];
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf084,
ql_dbg(ql_dbg_disc, vha, 0xf084,
"%s: se_sess %p / sess %p from port %8phC loop_id %#04x"
" s_id %02x:%02x:%02x logout %d keep %d els_logo %d\n",
__func__, sess->se_sess, sess, sess->port_name, sess->loop_id,
@@ -979,7 +980,7 @@ void qlt_free_session_done(struct work_struct *work)
sess->send_els_logo);
if (!IS_SW_RESV_ADDR(sess->d_id)) {
qla2x00_mark_device_lost(vha, sess, 0, 0);
qla2x00_mark_device_lost(vha, sess, 0);
if (sess->send_els_logo) {
qlt_port_logo_t logo;
@@ -1037,7 +1038,7 @@ void qlt_free_session_done(struct work_struct *work)
while (!READ_ONCE(sess->logout_completed)) {
if (!traced) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf086,
ql_dbg(ql_dbg_disc, vha, 0xf086,
"%s: waiting for sess %p logout\n",
__func__, sess);
traced = true;
@@ -1058,6 +1059,10 @@ void qlt_free_session_done(struct work_struct *work)
(struct imm_ntfy_from_isp *)sess->iocb, SRB_NACK_LOGO);
}
spin_lock_irqsave(&vha->work_lock, flags);
sess->flags &= ~FCF_ASYNC_SENT;
spin_unlock_irqrestore(&vha->work_lock, flags);
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
if (sess->se_sess) {
sess->se_sess = NULL;
@@ -1065,7 +1070,7 @@ void qlt_free_session_done(struct work_struct *work)
tgt->sess_count--;
}
sess->disc_state = DSC_DELETED;
qla2x00_set_fcport_disc_state(sess, DSC_DELETED);
sess->fw_login_state = DSC_LS_PORT_UNAVAIL;
sess->deleted = QLA_SESS_DELETED;
@@ -1117,10 +1122,11 @@ void qlt_free_session_done(struct work_struct *work)
}
}
sess->explicit_logout = 0;
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
sess->free_pending = 0;
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001,
ql_dbg(ql_dbg_disc, vha, 0xf001,
"Unregistration of sess %p %8phC finished fcp_cnt %d\n",
sess, sess->port_name, vha->fcport_count);
@@ -1163,13 +1169,18 @@ void qlt_unreg_sess(struct fc_port *sess)
return;
}
sess->free_pending = 1;
/*
* Use FCF_ASYNC_SENT flag to block other cmds used in sess
* management from being sent.
*/
sess->flags |= FCF_ASYNC_SENT;
spin_unlock_irqrestore(&sess->vha->work_lock, flags);
if (sess->se_sess)
vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess);
sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
sess->disc_state = DSC_DELETE_PEND;
qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND);
sess->last_rscn_gen = sess->rscn_gen;
sess->last_login_gen = sess->login_gen;
@@ -1269,7 +1280,8 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
spin_unlock_irqrestore(&sess->vha->work_lock, flags);
sess->disc_state = DSC_DELETE_PEND;
sess->prli_pend_timer = 0;
qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND);
qla24xx_chk_fcp_state(sess);
@@ -1397,9 +1409,6 @@ static struct fc_port *qlt_create_sess(
return NULL;
}
INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn);
INIT_WORK(&sess->free_work, qlt_free_session_done);
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
if (!IS_SW_RESV_ADDR(sess->d_id))
vha->vha_tgt.qla_tgt->sess_count++;
@@ -3852,7 +3861,7 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
return;
}
cmd->jiffies_at_free = get_jiffies_64();
cmd->rel_cmd(cmd);
cmd->vha->hw->tgt.tgt_ops->rel_cmd(cmd);
}
EXPORT_SYMBOL(qlt_free_cmd);
@@ -4189,7 +4198,7 @@ out_term:
qlt_send_term_exchange(qpair, NULL, &cmd->atio, 1, 0);
qlt_decr_num_pend_cmds(vha);
cmd->rel_cmd(cmd);
cmd->vha->hw->tgt.tgt_ops->rel_cmd(cmd);
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
ha->tgt.tgt_ops->put_sess(sess);
@@ -4641,7 +4650,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn,
/* find other sess with nport_id collision */
if (port_id.b24 == other_sess->d_id.b24) {
if (loop_id != other_sess->loop_id) {
ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000c,
ql_dbg(ql_dbg_disc, vha, 0x1000c,
"Invalidating sess %p loop_id %d wwn %llx.\n",
other_sess, other_sess->loop_id, other_wwn);
@@ -4657,7 +4666,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn,
* Another wwn used to have our s_id/loop_id
* kill the session, but don't free the loop_id
*/
ql_dbg(ql_dbg_tgt_tmr, vha, 0xf01b,
ql_dbg(ql_dbg_disc, vha, 0xf01b,
"Invalidating sess %p loop_id %d wwn %llx.\n",
other_sess, other_sess->loop_id, other_wwn);
@@ -4672,7 +4681,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn,
/* find other sess with nport handle collision */
if ((loop_id == other_sess->loop_id) &&
(loop_id != FC_NO_LOOP_ID)) {
ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000d,
ql_dbg(ql_dbg_disc, vha, 0x1000d,
"Invalidating sess %p loop_id %d wwn %llx.\n",
other_sess, other_sess->loop_id, other_wwn);
@@ -4865,6 +4874,7 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
switch (sess->disc_state) {
case DSC_DELETED:
case DSC_LOGIN_PEND:
qlt_plogi_ack_unref(vha, pla);
break;
@@ -5448,8 +5458,6 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
return;
}
memset(cmd, 0, sizeof(struct qla_tgt_cmd));
qlt_incr_num_pend_cmds(vha);
INIT_LIST_HEAD(&cmd->cmd_list);
memcpy(&cmd->atio, atio, sizeof(*atio));
@@ -6108,7 +6116,7 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha,
if (!IS_SW_RESV_ADDR(fcport->d_id))
vha->fcport_count++;
fcport->login_gen++;
fcport->disc_state = DSC_LOGIN_COMPLETE;
qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
fcport->login_succ = 1;
newfcport = 1;
}
+2 -1
View File
@@ -700,6 +700,7 @@ struct qla_tgt_func_tmpl {
int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, u64, uint16_t,
uint32_t);
struct qla_tgt_cmd *(*get_cmd)(struct fc_port *);
void (*rel_cmd)(struct qla_tgt_cmd *);
void (*free_cmd)(struct qla_tgt_cmd *);
void (*free_mcmd)(struct qla_tgt_mgmt_cmd *);
void (*free_session)(struct fc_port *);
@@ -968,7 +969,7 @@ struct qla_tgt_cmd {
uint64_t jiffies_at_alloc;
uint64_t jiffies_at_free;
void (*rel_cmd)(struct qla_tgt_cmd *);
enum trace_flags trc_flags;
};
+26 -3
View File
@@ -10,6 +10,7 @@
#define ISPREG(vha) (&(vha)->hw->iobase->isp24)
#define IOBAR(reg) offsetof(typeof(*(reg)), iobase_addr)
#define IOBASE(vha) IOBAR(ISPREG(vha))
#define INVALID_ENTRY ((struct qla27xx_fwdt_entry *)0xffffffffffffffffUL)
static inline void
qla27xx_insert16(uint16_t value, void *buf, ulong *len)
@@ -261,6 +262,7 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
ulong start = le32_to_cpu(ent->t262.start_addr);
ulong end = le32_to_cpu(ent->t262.end_addr);
ulong dwords;
int rc;
ql_dbg(ql_dbg_misc, vha, 0xd206,
"%s: rdram(%x) [%lx]\n", __func__, ent->t262.ram_area, *len);
@@ -308,7 +310,13 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
dwords = end - start + 1;
if (buf) {
buf += *len;
qla24xx_dump_ram(vha->hw, start, buf, dwords, &buf);
rc = qla24xx_dump_ram(vha->hw, start, buf, dwords, &buf);
if (rc != QLA_SUCCESS) {
ql_dbg(ql_dbg_async, vha, 0xffff,
"%s: dump ram MB failed. Area %xh start %lxh end %lxh\n",
__func__, area, start, end);
return INVALID_ENTRY;
}
}
*len += dwords * sizeof(uint32_t);
done:
@@ -838,6 +846,13 @@ qla27xx_walk_template(struct scsi_qla_host *vha,
ent = qla27xx_find_entry(type)(vha, ent, buf, len);
if (!ent)
break;
if (ent == INVALID_ENTRY) {
*len = 0;
ql_dbg(ql_dbg_async, vha, 0xffff,
"Unable to capture FW dump");
goto bailout;
}
}
if (tmp->count)
@@ -847,6 +862,9 @@ qla27xx_walk_template(struct scsi_qla_host *vha,
if (ent)
ql_dbg(ql_dbg_misc, vha, 0xd019,
"%s: missing end entry\n", __func__);
bailout:
cpu_to_le32s(&tmp->count); /* endianize residual count */
}
static void
@@ -999,8 +1017,9 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked)
uint j;
ulong len;
void *buf = vha->hw->fw_dump;
uint count = vha->hw->fw_dump_mpi ? 2 : 1;
for (j = 0; j < 2; j++, fwdt++, buf += len) {
for (j = 0; j < count; j++, fwdt++, buf += len) {
ql_log(ql_log_warn, vha, 0xd011,
"-> fwdt%u running...\n", j);
if (!fwdt->template) {
@@ -1010,7 +1029,9 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked)
}
len = qla27xx_execute_fwdt_template(vha,
fwdt->template, buf);
if (len != fwdt->dump_size) {
if (len == 0) {
goto bailout;
} else if (len != fwdt->dump_size) {
ql_log(ql_log_warn, vha, 0xd013,
"-> fwdt%u fwdump residual=%+ld\n",
j, fwdt->dump_size - len);
@@ -1025,6 +1046,8 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked)
qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
}
bailout:
vha->hw->fw_dump_mpi = 0;
#ifndef __CHECKER__
if (!hardware_locked)
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+1 -1
View File
@@ -7,7 +7,7 @@
/*
* Driver version
*/
#define QLA2XXX_VERSION "10.01.00.19-k"
#define QLA2XXX_VERSION "10.01.00.22-k"
#define QLA_DRIVER_MAJOR_VER 10
#define QLA_DRIVER_MINOR_VER 1
+1 -1
View File
@@ -10,4 +10,4 @@ ignore=(
SPDX_LICENSE_TAG
SYMBOLIC_PERMS
)
../linux-kernel/scripts/checkpatch.pl -f --show-types --ignore="$(echo "${ignore[@]}" | sed 's/ /,/g')" $(list-source-files | grep -vE 'fcst/linux-patches|patch$|pdf$|png$|^ibmvstgt/|^mpt/|^qla_isp/|^mvsas_tgt/') | sed 's/^#[0-9]*: FILE: \(.*\):/\1:1:/'
../linux-kernel/scripts/checkpatch.pl -f --show-types --ignore="$(echo "${ignore[@]}" | sed 's/ /,/g')" $(list-source-files | grep -vE 'fcst/linux-patches|patch$|pdf$|png$|^ibmvstgt/|^iscsi-scst/usr|^mpt/|^qla_isp/|^mvsas_tgt/') | sed 's/^#[0-9]*: FILE: \(.*\):/\1:1:/'
+1 -1
View File
@@ -10134,7 +10134,7 @@ static const struct attribute *vcdrom_attrs[] = {
NULL,
};
static const char *cdrom_add_dev_params[] = {
static const char *const cdrom_add_dev_params[] = {
"tst",
NULL,
};