mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-23 16:42:45 +00:00
Merge branch 'svn-trunk'
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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(®24->mailbox4);
|
||||
mb[5] = RD_REG_WORD(®24->mailbox5);
|
||||
mb[6] = RD_REG_WORD(®24->mailbox6);
|
||||
mb[7] = RD_REG_WORD(®24->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(®24->mailbox4);
|
||||
mb[5] = RD_REG_WORD(®24->mailbox5);
|
||||
mb[6] = RD_REG_WORD(®24->mailbox6);
|
||||
mb[7] = RD_REG_WORD(®24->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. */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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 = ∁
|
||||
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 = ∁
|
||||
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 = ∁
|
||||
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 = ∁
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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:/'
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user