mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-19 22:42:38 +00:00
Merge branch 'svn-trunk'
This commit is contained in:
@@ -4,7 +4,7 @@ ABT_DETAILS="x86_64"
|
||||
ABT_JOBS=5
|
||||
ABT_KERNELS=" \
|
||||
5.14.1 \
|
||||
5.13.14 \
|
||||
5.13.14-nc \
|
||||
5.12.19-nc \
|
||||
5.11.22-nc \
|
||||
5.10.62-nc \
|
||||
|
||||
@@ -9,4 +9,5 @@ obj-m := qla2xxx_scst.o
|
||||
qla2xxx_scst-objs := \
|
||||
qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
|
||||
qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \
|
||||
qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o
|
||||
qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o \
|
||||
qla_edif.o
|
||||
|
||||
@@ -4,7 +4,8 @@ ifeq ($(BUILD_2X_MODULE),)
|
||||
|
||||
qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
|
||||
qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \
|
||||
qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o
|
||||
qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o \
|
||||
qla_edif.o
|
||||
|
||||
obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
|
||||
|
||||
|
||||
@@ -1887,6 +1887,30 @@ qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr,
|
||||
return scnprintf(buf, PAGE_SIZE, "%s\n", spd[ha->link_data_rate]);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla2x00_mpi_pause_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
int rval = 0;
|
||||
|
||||
if (sscanf(buf, "%d", &rval) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
ql_log(ql_log_warn, vha, 0x7089, "Pausing MPI...\n");
|
||||
|
||||
rval = qla83xx_wr_reg(vha, 0x002012d4, 0x30000001);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x708a, "Unable to pause MPI.\n");
|
||||
count = 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(mpi_pause, S_IWUSR, NULL, qla2x00_mpi_pause_store);
|
||||
|
||||
/* ----- */
|
||||
|
||||
static ssize_t
|
||||
@@ -2435,6 +2459,7 @@ static DEVICE_ATTR(port_speed, 0644, qla2x00_port_speed_show,
|
||||
qla2x00_port_speed_store);
|
||||
static DEVICE_ATTR(port_no, 0444, qla2x00_port_no_show, NULL);
|
||||
static DEVICE_ATTR(fw_attr, 0444, qla2x00_fw_attr_show, NULL);
|
||||
static DEVICE_ATTR_RO(edif_doorbell);
|
||||
|
||||
|
||||
struct device_attribute *qla2x00_host_attrs[] = {
|
||||
@@ -2480,6 +2505,8 @@ struct device_attribute *qla2x00_host_attrs[] = {
|
||||
&dev_attr_port_no,
|
||||
&dev_attr_fw_attr,
|
||||
&dev_attr_dport_diagnostics,
|
||||
&dev_attr_edif_doorbell,
|
||||
&dev_attr_mpi_pause,
|
||||
NULL, /* reserve for qlini_mode */
|
||||
NULL, /* reserve for ql2xiniexchg */
|
||||
NULL, /* reserve for ql2xexchoffld */
|
||||
@@ -2706,12 +2733,14 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
|
||||
* final cleanup of firmware resources (PCBs and XCBs).
|
||||
*/
|
||||
if (fcport->loop_id != FC_NO_LOOP_ID) {
|
||||
if (IS_FWI2_CAPABLE(fcport->vha->hw))
|
||||
fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
|
||||
fcport->loop_id, fcport->d_id.b.domain,
|
||||
fcport->d_id.b.area, fcport->d_id.b.al_pa);
|
||||
else
|
||||
if (IS_FWI2_CAPABLE(fcport->vha->hw)) {
|
||||
if (fcport->loop_id != FC_NO_LOOP_ID)
|
||||
fcport->logout_on_delete = 1;
|
||||
|
||||
qlt_schedule_sess_for_deletion(fcport);
|
||||
} else {
|
||||
qla2x00_port_logout(fcport->vha, fcport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3107,6 +3136,9 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
|
||||
qla2x00_wait_for_sess_deletion(vha);
|
||||
|
||||
qla_nvme_delete(vha);
|
||||
qla_enode_stop(vha);
|
||||
qla_edb_stop(vha);
|
||||
|
||||
vha->flags.delete_progress = 1;
|
||||
|
||||
qlt_remove_target(ha, vha);
|
||||
|
||||
+63
-28
@@ -46,6 +46,10 @@ void qla2x00_bsg_job_done(srb_t *sp, int res)
|
||||
BSG_JOB_TYPE *bsg_job = sp->u.bsg_job;
|
||||
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
|
||||
|
||||
ql_dbg(ql_dbg_user, sp->vha, 0x7009,
|
||||
"%s: sp hdl %x, result=%x bsg ptr %p\n",
|
||||
__func__, sp->handle, res, bsg_job);
|
||||
|
||||
sp->free(sp);
|
||||
|
||||
bsg_reply->result = res;
|
||||
@@ -74,11 +78,19 @@ void qla2x00_bsg_sp_free(srb_t *sp)
|
||||
bsg_job->reply_payload.sg_list,
|
||||
bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
|
||||
} else {
|
||||
dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
|
||||
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
|
||||
|
||||
dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
|
||||
bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
|
||||
if (sp->remap.remapped) {
|
||||
dma_pool_free(ha->purex_dma_pool, sp->remap.rsp.buf,
|
||||
sp->remap.rsp.dma);
|
||||
dma_pool_free(ha->purex_dma_pool, sp->remap.req.buf,
|
||||
sp->remap.req.dma);
|
||||
} else {
|
||||
dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
|
||||
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
|
||||
|
||||
dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
|
||||
bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
|
||||
}
|
||||
}
|
||||
|
||||
if (sp->type == SRB_CT_CMD ||
|
||||
@@ -287,6 +299,7 @@ qla2x00_process_els(BSG_JOB_TYPE *bsg_job)
|
||||
int req_sg_cnt, rsp_sg_cnt;
|
||||
int rval = (DID_ERROR << 16);
|
||||
uint16_t nextlid = 0;
|
||||
uint32_t els_cmd = 0;
|
||||
|
||||
if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
|
||||
rport = fc_bsg_to_rport(bsg_job);
|
||||
@@ -300,6 +313,9 @@ qla2x00_process_els(BSG_JOB_TYPE *bsg_job)
|
||||
vha = shost_priv(host);
|
||||
ha = vha->hw;
|
||||
type = "FC_BSG_HST_ELS_NOLOGIN";
|
||||
els_cmd = bsg_request->rqst_data.h_els.command_code;
|
||||
if (els_cmd == ELS_AUTH_ELS)
|
||||
return qla_edif_process_els(vha, bsg_job);
|
||||
}
|
||||
|
||||
if (!vha->flags.online) {
|
||||
@@ -2789,10 +2805,14 @@ qla2x00_manage_host_port(BSG_JOB_TYPE *bsg_job)
|
||||
}
|
||||
|
||||
static int
|
||||
qla2x00_process_vendor_specific(BSG_JOB_TYPE *bsg_job)
|
||||
qla2x00_process_vendor_specific(struct scsi_qla_host *vha,
|
||||
BSG_JOB_TYPE *bsg_job)
|
||||
{
|
||||
struct fc_bsg_request *bsg_request = bsg_job->request;
|
||||
|
||||
ql_dbg(ql_dbg_edif, vha, 0x911b, "%s FC_BSG_HST_VENDOR cmd[0]=0x%x\n",
|
||||
__func__, bsg_request->rqst_data.h_vendor.vendor_cmd[0]);
|
||||
|
||||
switch (bsg_request->rqst_data.h_vendor.vendor_cmd[0]) {
|
||||
case QL_VND_LOOPBACK:
|
||||
return qla2x00_process_loopback(bsg_job);
|
||||
@@ -2861,6 +2881,9 @@ qla2x00_process_vendor_specific(BSG_JOB_TYPE *bsg_job)
|
||||
case QL_VND_DPORT_DIAGNOSTICS:
|
||||
return qla2x00_do_dport_diagnostics(bsg_job);
|
||||
|
||||
case QL_VND_EDIF_MGMT:
|
||||
return qla_edif_app_mgmt(bsg_job);
|
||||
|
||||
case QL_VND_SS_GET_FLASH_IMAGE_STATUS:
|
||||
return qla2x00_get_flash_image_status(bsg_job);
|
||||
|
||||
@@ -2918,12 +2941,19 @@ qla24xx_bsg_request(BSG_JOB_TYPE *bsg_job)
|
||||
ql_dbg(ql_dbg_user, vha, 0x709f,
|
||||
"BSG: ISP abort active/needed -- cmd=%d.\n",
|
||||
bsg_request->msgcode);
|
||||
SET_DID_STATUS(bsg_reply->result, DID_ERROR);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (test_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags)) {
|
||||
SET_DID_STATUS(bsg_reply->result, DID_ERROR);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
skip_chip_chk:
|
||||
ql_dbg(ql_dbg_user, vha, 0x7000,
|
||||
"Entered %s msgcode=0x%x.\n", __func__, bsg_request->msgcode);
|
||||
ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x7000,
|
||||
"Entered %s msgcode=0x%x. bsg ptr %px\n",
|
||||
__func__, bsg_request->msgcode, bsg_job);
|
||||
|
||||
switch (bsg_request->msgcode) {
|
||||
case FC_BSG_RPT_ELS:
|
||||
@@ -2934,7 +2964,7 @@ skip_chip_chk:
|
||||
ret = qla2x00_process_ct(bsg_job);
|
||||
break;
|
||||
case FC_BSG_HST_VENDOR:
|
||||
ret = qla2x00_process_vendor_specific(bsg_job);
|
||||
ret = qla2x00_process_vendor_specific(vha, bsg_job);
|
||||
break;
|
||||
case FC_BSG_HST_ADD_RPORT:
|
||||
case FC_BSG_HST_DEL_RPORT:
|
||||
@@ -2943,6 +2973,10 @@ skip_chip_chk:
|
||||
ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x7000,
|
||||
"%s done with return %x\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2957,6 +2991,8 @@ qla24xx_bsg_timeout(BSG_JOB_TYPE *bsg_job)
|
||||
unsigned long flags;
|
||||
struct req_que *req;
|
||||
|
||||
ql_log(ql_log_info, vha, 0x708b, "%s CMD timeout. bsg ptr %p.\n",
|
||||
__func__, bsg_job);
|
||||
/* find the bsg job from the active list of commands */
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
for (que = 0; que < ha->max_req_queues; que++) {
|
||||
@@ -2966,27 +3002,26 @@ qla24xx_bsg_timeout(BSG_JOB_TYPE *bsg_job)
|
||||
|
||||
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
|
||||
sp = req->outstanding_cmds[cnt];
|
||||
if (sp) {
|
||||
if (((sp->type == SRB_CT_CMD) ||
|
||||
(sp->type == SRB_ELS_CMD_HST) ||
|
||||
(sp->type == SRB_FXIOCB_BCMD))
|
||||
&& (sp->u.bsg_job == bsg_job)) {
|
||||
req->outstanding_cmds[cnt] = NULL;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
if (ha->isp_ops->abort_command(sp)) {
|
||||
ql_log(ql_log_warn, vha, 0x7089,
|
||||
"mbx abort_command "
|
||||
"failed.\n");
|
||||
bsg_reply->result = -EIO;
|
||||
} else {
|
||||
ql_dbg(ql_dbg_user, vha, 0x708a,
|
||||
"mbx abort_command "
|
||||
"success.\n");
|
||||
bsg_reply->result = 0;
|
||||
}
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
goto done;
|
||||
if (sp &&
|
||||
(sp->type == SRB_CT_CMD ||
|
||||
sp->type == SRB_ELS_CMD_HST ||
|
||||
sp->type == SRB_ELS_CMD_HST_NOLOGIN ||
|
||||
sp->type == SRB_FXIOCB_BCMD) &&
|
||||
sp->u.bsg_job == bsg_job) {
|
||||
req->outstanding_cmds[cnt] = NULL;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
if (ha->isp_ops->abort_command(sp)) {
|
||||
ql_log(ql_log_warn, vha, 0x7089,
|
||||
"mbx abort_command failed.\n");
|
||||
bsg_reply->result = -EIO;
|
||||
} else {
|
||||
ql_dbg(ql_dbg_user, vha, 0x708a,
|
||||
"mbx abort_command success.\n");
|
||||
bsg_reply->result = 0;
|
||||
}
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
goto done;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#define QL_VND_DPORT_DIAGNOSTICS 0x19
|
||||
#define QL_VND_GET_PRIV_STATS_EX 0x1A
|
||||
#define QL_VND_SS_GET_FLASH_IMAGE_STATUS 0x1E
|
||||
#define QL_VND_EDIF_MGMT 0X1F
|
||||
#define QL_VND_MANAGE_HOST_STATS 0x23
|
||||
#define QL_VND_GET_HOST_STATS 0x24
|
||||
#define QL_VND_GET_TGT_STATS 0x25
|
||||
@@ -294,4 +295,6 @@ struct qla_active_regions {
|
||||
uint8_t reserved[32];
|
||||
} __packed;
|
||||
|
||||
#include "qla_edif_bsg.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
* ----------------------------------------------------------------------
|
||||
* | Module Init and Probe | 0x0199 | |
|
||||
* | Mailbox commands | 0x1206 | 0x11a5-0x11ff |
|
||||
* | Device Discovery | 0x2134 | 0x210e-0x2116 |
|
||||
* | | | 0x211a |
|
||||
* | Device Discovery | 0x2134 | 0x210e-0x2115 |
|
||||
* | | | 0x211c-0x2128 |
|
||||
* | | | 0x212c-0x2134 |
|
||||
* | Queue Command and IO tracing | 0x3074 | 0x300b |
|
||||
|
||||
@@ -367,6 +367,7 @@ ql_log_qp(uint32_t, struct qla_qpair *, int32_t, const char *fmt, ...);
|
||||
#define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */
|
||||
#define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */
|
||||
#define ql_dbg_tgt_dif 0x00000800 /* Target mode dif */
|
||||
#define ql_dbg_edif 0x00000400 /* edif and purex debug */
|
||||
|
||||
extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *,
|
||||
uint32_t, void **);
|
||||
|
||||
+191
-34
@@ -74,6 +74,28 @@ typedef struct {
|
||||
uint8_t domain;
|
||||
} le_id_t;
|
||||
|
||||
/*
|
||||
* 24 bit port ID type definition.
|
||||
*/
|
||||
typedef union {
|
||||
uint32_t b24 : 24;
|
||||
struct {
|
||||
#ifdef __BIG_ENDIAN
|
||||
uint8_t domain;
|
||||
uint8_t area;
|
||||
uint8_t al_pa;
|
||||
#elif defined(__LITTLE_ENDIAN)
|
||||
uint8_t al_pa;
|
||||
uint8_t area;
|
||||
uint8_t domain;
|
||||
#else
|
||||
#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!"
|
||||
#endif
|
||||
uint8_t rsvd_1;
|
||||
} b;
|
||||
} port_id_t;
|
||||
#define INVALID_PORT_ID 0xFFFFFF
|
||||
|
||||
#include "qla_bsg.h"
|
||||
#include "qla_dsd.h"
|
||||
#include "qla_nx.h"
|
||||
@@ -344,6 +366,13 @@ struct name_list_extended {
|
||||
u32 size;
|
||||
u8 sent;
|
||||
};
|
||||
|
||||
struct els_reject {
|
||||
struct fc_els_ls_rjt *c;
|
||||
dma_addr_t cdma;
|
||||
u16 size;
|
||||
};
|
||||
|
||||
/*
|
||||
* Timeout timer counts in seconds
|
||||
*/
|
||||
@@ -370,6 +399,8 @@ struct name_list_extended {
|
||||
#define FW_MAX_EXCHANGES_CNT (32 * 1024)
|
||||
#define REDUCE_EXCHANGES_CNT (8 * 1024)
|
||||
|
||||
#define SET_DID_STATUS(stat_var, status) (stat_var = status << 16)
|
||||
|
||||
struct req_que;
|
||||
struct qla_tgt_sess;
|
||||
|
||||
@@ -395,32 +426,10 @@ struct srb_cmd {
|
||||
#define SRB_CRC_CTX_DSD_VALID BIT_5 /* DIF: dsd_list valid */
|
||||
#define SRB_WAKEUP_ON_COMP BIT_6
|
||||
#define SRB_DIF_BUNDL_DMA_VALID BIT_7 /* DIF: DMA list valid */
|
||||
#define SRB_EDIF_CLEANUP_DELETE BIT_9
|
||||
|
||||
/* To identify if a srb is of T10-CRC type. @sp => srb_t pointer */
|
||||
#define IS_PROT_IO(sp) (sp->flags & SRB_CRC_CTX_DSD_VALID)
|
||||
|
||||
/*
|
||||
* 24 bit port ID type definition.
|
||||
*/
|
||||
typedef union {
|
||||
uint32_t b24 : 24;
|
||||
|
||||
struct {
|
||||
#ifdef __BIG_ENDIAN
|
||||
uint8_t domain;
|
||||
uint8_t area;
|
||||
uint8_t al_pa;
|
||||
#elif defined(__LITTLE_ENDIAN)
|
||||
uint8_t al_pa;
|
||||
uint8_t area;
|
||||
uint8_t domain;
|
||||
#else
|
||||
#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!"
|
||||
#endif
|
||||
uint8_t rsvd_1;
|
||||
} b;
|
||||
} port_id_t;
|
||||
#define INVALID_PORT_ID 0xFFFFFF
|
||||
#define ISP_REG16_DISCONNECT 0xFFFF
|
||||
|
||||
static inline le_id_t be_id_to_le(be_id_t id)
|
||||
@@ -508,6 +517,7 @@ struct srb_iocb {
|
||||
#define SRB_LOGIN_SKIP_PRLI BIT_2
|
||||
#define SRB_LOGIN_NVME_PRLI BIT_3
|
||||
#define SRB_LOGIN_PRLI_ONLY BIT_4
|
||||
#define SRB_LOGIN_FCSP BIT_5
|
||||
uint16_t data[2];
|
||||
u32 iop[2];
|
||||
} logio;
|
||||
@@ -612,6 +622,10 @@ struct srb_iocb {
|
||||
u16 cmd;
|
||||
u16 vp_index;
|
||||
} ctrlvp;
|
||||
struct {
|
||||
struct edif_sa_ctl *sa_ctl;
|
||||
struct qla_sa_update_frame sa_frame;
|
||||
} sa_update;
|
||||
} u;
|
||||
|
||||
struct timer_list timer;
|
||||
@@ -642,6 +656,21 @@ struct srb_iocb {
|
||||
#define SRB_PRLI_CMD 21
|
||||
#define SRB_CTRL_VP 22
|
||||
#define SRB_PRLO_CMD 23
|
||||
#define SRB_SA_UPDATE 25
|
||||
#define SRB_ELS_CMD_HST_NOLOGIN 26
|
||||
#define SRB_SA_REPLACE 27
|
||||
|
||||
struct qla_els_pt_arg {
|
||||
u8 els_opcode;
|
||||
u8 vp_idx;
|
||||
__le16 nport_handle;
|
||||
u16 control_flags;
|
||||
__le32 rx_xchg_address;
|
||||
port_id_t did;
|
||||
u32 tx_len, tx_byte_count, rx_len, rx_byte_count;
|
||||
dma_addr_t tx_addr, rx_addr;
|
||||
|
||||
};
|
||||
|
||||
enum {
|
||||
TYPE_SRB,
|
||||
@@ -655,6 +684,13 @@ struct iocb_resource {
|
||||
u16 iocb_cnt;
|
||||
};
|
||||
|
||||
struct bsg_cmd {
|
||||
struct bsg_job *bsg_job;
|
||||
union {
|
||||
struct qla_els_pt_arg els_arg;
|
||||
} u;
|
||||
};
|
||||
|
||||
typedef struct srb {
|
||||
/*
|
||||
* Do not move cmd_type field, it needs to
|
||||
@@ -691,7 +727,21 @@ typedef struct srb {
|
||||
struct bsg_job *bsg_job;
|
||||
#endif
|
||||
struct srb_cmd scmd;
|
||||
struct bsg_cmd bsg_cmd;
|
||||
} u;
|
||||
struct {
|
||||
bool remapped;
|
||||
struct {
|
||||
dma_addr_t dma;
|
||||
void *buf;
|
||||
uint len;
|
||||
} req;
|
||||
struct {
|
||||
dma_addr_t dma;
|
||||
void *buf;
|
||||
uint len;
|
||||
} rsp;
|
||||
} remap;
|
||||
/*
|
||||
* Report completion status @res and call sp_put(@sp). @res is
|
||||
* an NVMe status code, a SCSI result (e.g. DID_OK << 16) or a
|
||||
@@ -2323,6 +2373,7 @@ struct imm_ntfy_from_isp {
|
||||
__le16 nport_handle;
|
||||
uint16_t reserved_2;
|
||||
__le16 flags;
|
||||
#define NOTIFY24XX_FLAGS_FCSP BIT_5
|
||||
#define NOTIFY24XX_FLAGS_GLOBAL_TPRLO BIT_1
|
||||
#define NOTIFY24XX_FLAGS_PUREX_IOCB BIT_0
|
||||
__le16 srr_rx_id;
|
||||
@@ -2406,11 +2457,9 @@ struct mbx_24xx_entry {
|
||||
*/
|
||||
typedef enum {
|
||||
FCT_UNKNOWN,
|
||||
FCT_RSCN,
|
||||
FCT_SWITCH,
|
||||
FCT_BROADCAST,
|
||||
FCT_INITIATOR,
|
||||
FCT_TARGET,
|
||||
FCT_BROADCAST = 0x01,
|
||||
FCT_INITIATOR = 0x02,
|
||||
FCT_TARGET = 0x04,
|
||||
FCT_NVME_INITIATOR = 0x10,
|
||||
FCT_NVME_TARGET = 0x20,
|
||||
FCT_NVME_DISCOVERY = 0x40,
|
||||
@@ -2453,6 +2502,7 @@ enum discovery_state {
|
||||
DSC_LOGIN_COMPLETE,
|
||||
DSC_ADISC,
|
||||
DSC_DELETE_PEND,
|
||||
DSC_LOGIN_AUTH_PEND,
|
||||
};
|
||||
|
||||
enum login_state { /* FW control Target side */
|
||||
@@ -2496,6 +2546,8 @@ typedef struct fc_port {
|
||||
unsigned int n2n_flag:1;
|
||||
unsigned int explicit_logout:1;
|
||||
unsigned int prli_pend_timer:1;
|
||||
unsigned int do_prli_nvme:1;
|
||||
|
||||
uint8_t nvme_flag;
|
||||
|
||||
uint8_t node_name[WWN_SIZE];
|
||||
@@ -2593,6 +2645,33 @@ typedef struct fc_port {
|
||||
u64 tgt_short_link_down_cnt;
|
||||
u64 tgt_link_down_time;
|
||||
u64 dev_loss_tmo;
|
||||
/*
|
||||
* EDIF parameters for encryption.
|
||||
*/
|
||||
struct {
|
||||
uint32_t enable:1; /* device is edif enabled/req'd */
|
||||
uint32_t app_stop:2;
|
||||
uint32_t app_started:1;
|
||||
uint32_t aes_gmac:1;
|
||||
uint32_t app_sess_online:1;
|
||||
uint32_t tx_sa_set:1;
|
||||
uint32_t rx_sa_set:1;
|
||||
uint32_t tx_sa_pending:1;
|
||||
uint32_t rx_sa_pending:1;
|
||||
uint32_t tx_rekey_cnt;
|
||||
uint32_t rx_rekey_cnt;
|
||||
uint64_t tx_bytes;
|
||||
uint64_t rx_bytes;
|
||||
uint8_t auth_state;
|
||||
uint16_t authok:1;
|
||||
uint16_t rekey_cnt;
|
||||
struct list_head edif_indx_list;
|
||||
spinlock_t indx_list_lock;
|
||||
|
||||
struct list_head tx_sa_list;
|
||||
struct list_head rx_sa_list;
|
||||
spinlock_t sa_list_lock;
|
||||
} edif;
|
||||
} fc_port_t;
|
||||
|
||||
enum {
|
||||
@@ -2634,7 +2713,8 @@ static const char * const port_dstate_str[] = {
|
||||
"UPD_FCPORT",
|
||||
"LOGIN_COMPLETE",
|
||||
"ADISC",
|
||||
"DELETE_PEND"
|
||||
"DELETE_PEND",
|
||||
"LOGIN_AUTH_PEND",
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2646,6 +2726,8 @@ static const char * const port_dstate_str[] = {
|
||||
#define FCF_ASYNC_SENT BIT_3
|
||||
#define FCF_CONF_COMP_SUPPORTED BIT_4
|
||||
#define FCF_ASYNC_ACTIVE BIT_5
|
||||
#define FCF_FCSP_DEVICE BIT_6
|
||||
#define FCF_EDIF_DELETE BIT_7
|
||||
|
||||
/* No loop ID flag. */
|
||||
#define FC_NO_LOOP_ID 0x1000
|
||||
@@ -2737,7 +2819,7 @@ static const char * const port_dstate_str[] = {
|
||||
/*
|
||||
* FDMI HBA attribute types.
|
||||
*/
|
||||
#define FDMI1_HBA_ATTR_COUNT 9
|
||||
#define FDMI1_HBA_ATTR_COUNT 10
|
||||
#define FDMI2_HBA_ATTR_COUNT 17
|
||||
|
||||
#define FDMI_HBA_NODE_NAME 0x1
|
||||
@@ -3416,6 +3498,7 @@ enum qla_work_type {
|
||||
QLA_EVT_SP_RETRY,
|
||||
QLA_EVT_IIDMA,
|
||||
QLA_EVT_ELS_PLOGI,
|
||||
QLA_EVT_SA_REPLACE,
|
||||
};
|
||||
|
||||
|
||||
@@ -3474,6 +3557,11 @@ struct qla_work_evt {
|
||||
u8 fc4_type;
|
||||
srb_t *sp;
|
||||
} gpnft;
|
||||
struct {
|
||||
struct edif_sa_ctl *sa_ctl;
|
||||
fc_port_t *fcport;
|
||||
uint16_t nport_handle;
|
||||
} sa_update;
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -3690,6 +3778,8 @@ struct qla_qpair {
|
||||
struct qla_tgt_counters tgt_counters;
|
||||
uint16_t cpuid;
|
||||
struct qla_fw_resources fwres ____cacheline_aligned;
|
||||
u32 cmd_cnt;
|
||||
u32 cmd_completion_cnt;
|
||||
};
|
||||
|
||||
/* Place holder for FW buffer parameters */
|
||||
@@ -3873,7 +3963,6 @@ struct qlt_hw_data {
|
||||
int num_act_qpairs;
|
||||
#define DEFAULT_NAQP 2
|
||||
spinlock_t atio_lock ____cacheline_aligned;
|
||||
struct btree_head32 host_map;
|
||||
};
|
||||
|
||||
#define MAX_QFULL_CMDS_ALLOC 8192
|
||||
@@ -3963,7 +4052,9 @@ struct qla_hw_data {
|
||||
uint32_t scm_supported_f:1;
|
||||
/* Enabled in Driver */
|
||||
uint32_t scm_enabled:1;
|
||||
uint32_t max_req_queue_warned:1;
|
||||
uint32_t edif_hw:1;
|
||||
uint32_t edif_enabled:1;
|
||||
uint32_t n2n_fw_acc_sec:1;
|
||||
uint32_t plogi_template_valid:1;
|
||||
uint32_t port_isolated:1;
|
||||
} flags;
|
||||
@@ -4375,6 +4466,7 @@ struct qla_hw_data {
|
||||
/* Cisco fabric attached */
|
||||
#define FW_ATTR_EXT0_SCM_CISCO 0x00002000
|
||||
#define FW_ATTR_EXT0_NVME2 BIT_13
|
||||
#define FW_ATTR_EXT0_EDIF BIT_5
|
||||
uint16_t fw_attributes_ext[2];
|
||||
uint32_t fw_memory_size;
|
||||
uint32_t fw_transfer_size;
|
||||
@@ -4646,8 +4738,25 @@ struct qla_hw_data {
|
||||
|
||||
struct qla_hw_data_stat stat;
|
||||
pci_error_state_t pci_error_state;
|
||||
u64 prev_cmd_cnt;
|
||||
struct dma_pool *purex_dma_pool;
|
||||
struct btree_head32 host_map;
|
||||
|
||||
#define EDIF_NUM_SA_INDEX 512
|
||||
#define EDIF_TX_SA_INDEX_BASE EDIF_NUM_SA_INDEX
|
||||
void *edif_rx_sa_id_map;
|
||||
void *edif_tx_sa_id_map;
|
||||
spinlock_t sadb_fp_lock;
|
||||
|
||||
struct list_head sadb_tx_index_list;
|
||||
struct list_head sadb_rx_index_list;
|
||||
spinlock_t sadb_lock; /* protects list */
|
||||
struct els_reject elsrej;
|
||||
u8 edif_post_stop_cnt_down;
|
||||
};
|
||||
|
||||
#define RX_ELS_SIZE (roundup(sizeof(struct enode) + ELS_MAX_PAYLOAD, SMP_CACHE_BYTES))
|
||||
|
||||
struct active_regions {
|
||||
uint8_t global;
|
||||
struct {
|
||||
@@ -4686,6 +4795,8 @@ struct purex_item {
|
||||
} iocb;
|
||||
};
|
||||
|
||||
#include "qla_edif.h"
|
||||
|
||||
#define SCM_FLAG_RDF_REJECT 0x00
|
||||
#define SCM_FLAG_RDF_COMPLETED 0x01
|
||||
|
||||
@@ -4773,6 +4884,7 @@ typedef struct scsi_qla_host {
|
||||
#define SET_ZIO_THRESHOLD_NEEDED 32
|
||||
#define ISP_ABORT_TO_ROM 33
|
||||
#define VPORT_DELETE 34
|
||||
#define HEARTBEAT_CHK 38
|
||||
|
||||
#define PROCESS_PUREX_IOCB 63
|
||||
|
||||
@@ -4914,6 +5026,8 @@ typedef struct scsi_qla_host {
|
||||
u64 reset_cmd_err_cnt;
|
||||
u64 link_down_time;
|
||||
u64 short_link_down_cnt;
|
||||
struct edif_dbell e_dbell;
|
||||
struct pur_core pur_cinfo;
|
||||
} scsi_qla_host_t;
|
||||
|
||||
struct qla27xx_image_status {
|
||||
@@ -5084,6 +5198,9 @@ struct secure_flash_update_block_pk {
|
||||
#define QLA_BUSY 0x107
|
||||
#define QLA_ALREADY_REGISTERED 0x109
|
||||
#define QLA_OS_TIMER_EXPIRED 0x10a
|
||||
#define QLA_ERR_NO_QPAIR 0x10b
|
||||
#define QLA_ERR_NOT_FOUND 0x10c
|
||||
#define QLA_ERR_FROM_FW 0x10d
|
||||
|
||||
#define NVRAM_DELAY() udelay(10)
|
||||
|
||||
@@ -5114,6 +5231,43 @@ enum nexus_wait_type {
|
||||
WAIT_LUN,
|
||||
};
|
||||
|
||||
#define INVALID_EDIF_SA_INDEX 0xffff
|
||||
#define RX_DELETE_NO_EDIF_SA_INDEX 0xfffe
|
||||
|
||||
#define QLA_SKIP_HANDLE QLA_TGT_SKIP_HANDLE
|
||||
|
||||
/* edif hash element */
|
||||
struct edif_list_entry {
|
||||
uint16_t handle; /* nport_handle */
|
||||
uint32_t update_sa_index;
|
||||
uint32_t delete_sa_index;
|
||||
uint32_t count; /* counter for filtering sa_index */
|
||||
#define EDIF_ENTRY_FLAGS_CLEANUP 0x01 /* this index is being cleaned up */
|
||||
uint32_t flags; /* used by sadb cleanup code */
|
||||
fc_port_t *fcport; /* needed by rx delay timer function */
|
||||
struct timer_list timer; /* rx delay timer */
|
||||
struct list_head next;
|
||||
};
|
||||
|
||||
#define EDIF_TX_INDX_BASE 512
|
||||
#define EDIF_RX_INDX_BASE 0
|
||||
#define EDIF_RX_DELETE_FILTER_COUNT 3 /* delay queuing rx delete until this many */
|
||||
|
||||
/* entry in the sa_index free pool */
|
||||
|
||||
struct sa_index_pair {
|
||||
uint16_t sa_index;
|
||||
uint32_t spi;
|
||||
};
|
||||
|
||||
/* edif sa_index data structure */
|
||||
struct edif_sa_index_entry {
|
||||
struct sa_index_pair sa_pair[2];
|
||||
fc_port_t *fcport;
|
||||
uint16_t handle;
|
||||
struct list_head next;
|
||||
};
|
||||
|
||||
/* Refer to SNIA SFF 8247 */
|
||||
struct sff_8247_a0 {
|
||||
u8 txid; /* transceiver id */
|
||||
@@ -5229,9 +5383,12 @@ struct sff_8247_a0 {
|
||||
#define NVME_FCP_TARGET(fcport) \
|
||||
(FCP_TYPE(fcport) && NVME_TYPE(fcport)) \
|
||||
|
||||
#define NVME_PRIORITY(ha, fcport) \
|
||||
(NVME_FCP_TARGET(fcport) && \
|
||||
(ha->fc4_type_priority == FC4_PRIORITY_NVME))
|
||||
|
||||
#define NVME_TARGET(ha, fcport) \
|
||||
((NVME_FCP_TARGET(fcport) && \
|
||||
(ha->fc4_type_priority == FC4_PRIORITY_NVME)) || \
|
||||
(fcport->do_prli_nvme || \
|
||||
NVME_ONLY_TARGET(fcport)) \
|
||||
|
||||
#define PRLI_PHASE(_cls) \
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,136 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Marvell Fibre Channel HBA Driver
|
||||
* Copyright (c) 2021 Marvell
|
||||
*/
|
||||
#ifndef __QLA_EDIF_H
|
||||
#define __QLA_EDIF_H
|
||||
|
||||
struct qla_scsi_host;
|
||||
#define EDIF_APP_ID 0x73730001
|
||||
|
||||
#define EDIF_MAX_INDEX 2048
|
||||
struct edif_sa_ctl {
|
||||
struct list_head next;
|
||||
uint16_t del_index;
|
||||
uint16_t index;
|
||||
uint16_t slot;
|
||||
uint16_t flags;
|
||||
#define EDIF_SA_CTL_FLG_REPL BIT_0
|
||||
#define EDIF_SA_CTL_FLG_DEL BIT_1
|
||||
#define EDIF_SA_CTL_FLG_CLEANUP_DEL BIT_4
|
||||
// Invalidate Index bit and mirrors QLA_SA_UPDATE_FLAGS_DELETE
|
||||
unsigned long state;
|
||||
#define EDIF_SA_CTL_USED 1 /* Active Sa update */
|
||||
#define EDIF_SA_CTL_PEND 2 /* Waiting for slot */
|
||||
#define EDIF_SA_CTL_REPL 3 /* Active Replace and Delete */
|
||||
#define EDIF_SA_CTL_DEL 4 /* Delete Pending */
|
||||
struct fc_port *fcport;
|
||||
struct bsg_job *bsg_job;
|
||||
struct qla_sa_update_frame sa_frame;
|
||||
};
|
||||
|
||||
enum enode_flags_t {
|
||||
ENODE_ACTIVE = 0x1,
|
||||
};
|
||||
|
||||
struct pur_core {
|
||||
enum enode_flags_t enode_flags;
|
||||
spinlock_t pur_lock;
|
||||
struct list_head head;
|
||||
};
|
||||
|
||||
enum db_flags_t {
|
||||
EDB_ACTIVE = 0x1,
|
||||
};
|
||||
|
||||
struct edif_dbell {
|
||||
enum db_flags_t db_flags;
|
||||
spinlock_t db_lock;
|
||||
struct list_head head;
|
||||
struct completion dbell;
|
||||
};
|
||||
|
||||
#define SA_UPDATE_IOCB_TYPE 0x71 /* Security Association Update IOCB entry */
|
||||
struct sa_update_28xx {
|
||||
uint8_t entry_type; /* Entry type. */
|
||||
uint8_t entry_count; /* Entry count. */
|
||||
uint8_t sys_define; /* System Defined. */
|
||||
uint8_t entry_status; /* Entry Status. */
|
||||
|
||||
uint32_t handle; /* IOCB System handle. */
|
||||
|
||||
union {
|
||||
__le16 nport_handle; /* in: N_PORT handle. */
|
||||
__le16 comp_sts; /* out: completion status */
|
||||
#define CS_PORT_EDIF_UNAVAIL 0x28
|
||||
#define CS_PORT_EDIF_LOGOUT 0x29
|
||||
#define CS_PORT_EDIF_SUPP_NOT_RDY 0x64
|
||||
#define CS_PORT_EDIF_INV_REQ 0x66
|
||||
} u;
|
||||
uint8_t vp_index;
|
||||
uint8_t reserved_1;
|
||||
uint8_t port_id[3];
|
||||
uint8_t flags;
|
||||
#define SA_FLAG_INVALIDATE BIT_0
|
||||
#define SA_FLAG_TX BIT_1 // 1=tx, 0=rx
|
||||
|
||||
uint8_t sa_key[32]; /* 256 bit key */
|
||||
__le32 salt;
|
||||
__le32 spi;
|
||||
uint8_t sa_control;
|
||||
#define SA_CNTL_ENC_FCSP (1 << 3)
|
||||
#define SA_CNTL_ENC_OPD (2 << 3)
|
||||
#define SA_CNTL_ENC_MSK (3 << 3) // mask bits 4,3
|
||||
#define SA_CNTL_AES_GMAC (1 << 2)
|
||||
#define SA_CNTL_KEY256 (2 << 0)
|
||||
#define SA_CNTL_KEY128 0
|
||||
|
||||
uint8_t reserved_2;
|
||||
__le16 sa_index; // reserve: bit 11-15
|
||||
__le16 old_sa_info;
|
||||
__le16 new_sa_info;
|
||||
};
|
||||
|
||||
#define NUM_ENTRIES 256
|
||||
#define MAX_PAYLOAD 1024
|
||||
#define PUR_GET 1
|
||||
|
||||
struct dinfo {
|
||||
int nodecnt;
|
||||
int lstate;
|
||||
};
|
||||
|
||||
struct pur_ninfo {
|
||||
unsigned int pur_pend:1;
|
||||
port_id_t pur_sid;
|
||||
port_id_t pur_did;
|
||||
uint8_t vp_idx;
|
||||
short pur_bytes_rcvd;
|
||||
unsigned short pur_nphdl;
|
||||
unsigned int pur_rx_xchg_address;
|
||||
};
|
||||
|
||||
struct purexevent {
|
||||
struct pur_ninfo pur_info;
|
||||
unsigned char *msgp;
|
||||
u32 msgp_len;
|
||||
};
|
||||
|
||||
#define N_UNDEF 0
|
||||
#define N_PUREX 1
|
||||
struct enode {
|
||||
struct list_head list;
|
||||
struct dinfo dinfo;
|
||||
uint32_t ntype;
|
||||
union {
|
||||
struct purexevent purexinfo;
|
||||
} u;
|
||||
};
|
||||
|
||||
#define EDIF_SESSION_DOWN(_s) \
|
||||
(qla_ini_mode_enabled(_s->vha) && (_s->disc_state == DSC_DELETE_PEND || \
|
||||
_s->disc_state == DSC_DELETED || \
|
||||
!_s->edif.app_sess_online))
|
||||
|
||||
#endif /* __QLA_EDIF_H */
|
||||
@@ -0,0 +1,220 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Marvell Fibre Channel HBA Driver
|
||||
* Copyright (C) 2018- Marvell
|
||||
*
|
||||
*/
|
||||
#ifndef __QLA_EDIF_BSG_H
|
||||
#define __QLA_EDIF_BSG_H
|
||||
|
||||
/* BSG Vendor specific commands */
|
||||
#define ELS_MAX_PAYLOAD 1024
|
||||
#ifndef WWN_SIZE
|
||||
#define WWN_SIZE 8
|
||||
#endif
|
||||
#define VND_CMD_APP_RESERVED_SIZE 32
|
||||
|
||||
enum auth_els_sub_cmd {
|
||||
SEND_ELS = 0,
|
||||
SEND_ELS_REPLY,
|
||||
PULL_ELS,
|
||||
};
|
||||
|
||||
struct extra_auth_els {
|
||||
enum auth_els_sub_cmd sub_cmd;
|
||||
uint32_t extra_rx_xchg_address;
|
||||
uint8_t extra_control_flags;
|
||||
#define BSG_CTL_FLAG_INIT 0
|
||||
#define BSG_CTL_FLAG_LS_ACC 1
|
||||
#define BSG_CTL_FLAG_LS_RJT 2
|
||||
#define BSG_CTL_FLAG_TRM 3
|
||||
uint8_t extra_rsvd[3];
|
||||
} __packed;
|
||||
|
||||
struct qla_bsg_auth_els_request {
|
||||
struct fc_bsg_request r;
|
||||
struct extra_auth_els e;
|
||||
};
|
||||
|
||||
struct qla_bsg_auth_els_reply {
|
||||
struct fc_bsg_reply r;
|
||||
uint32_t rx_xchg_address;
|
||||
};
|
||||
|
||||
struct app_id {
|
||||
int app_vid;
|
||||
uint8_t app_key[32];
|
||||
} __packed;
|
||||
|
||||
struct app_start_reply {
|
||||
uint32_t host_support_edif;
|
||||
uint32_t edif_enode_active;
|
||||
uint32_t edif_edb_active;
|
||||
uint32_t reserved[VND_CMD_APP_RESERVED_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct app_start {
|
||||
struct app_id app_info;
|
||||
uint32_t prli_to;
|
||||
uint32_t key_shred;
|
||||
uint8_t app_start_flags;
|
||||
uint8_t reserved[VND_CMD_APP_RESERVED_SIZE - 1];
|
||||
} __packed;
|
||||
|
||||
struct app_stop {
|
||||
struct app_id app_info;
|
||||
char buf[16];
|
||||
} __packed;
|
||||
|
||||
struct app_plogi_reply {
|
||||
uint32_t prli_status;
|
||||
uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
|
||||
} __packed;
|
||||
|
||||
#define RECFG_TIME 1
|
||||
#define RECFG_BYTES 2
|
||||
|
||||
struct app_rekey_cfg {
|
||||
struct app_id app_info;
|
||||
uint8_t rekey_mode;
|
||||
port_id_t d_id;
|
||||
uint8_t force;
|
||||
union {
|
||||
int64_t bytes;
|
||||
int64_t time;
|
||||
} rky_units;
|
||||
|
||||
uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct app_pinfo_req {
|
||||
struct app_id app_info;
|
||||
uint8_t num_ports;
|
||||
port_id_t remote_pid;
|
||||
uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct app_pinfo {
|
||||
port_id_t remote_pid;
|
||||
uint8_t remote_wwpn[WWN_SIZE];
|
||||
uint8_t remote_type;
|
||||
#define VND_CMD_RTYPE_UNKNOWN 0
|
||||
#define VND_CMD_RTYPE_TARGET 1
|
||||
#define VND_CMD_RTYPE_INITIATOR 2
|
||||
uint8_t remote_state;
|
||||
uint8_t auth_state;
|
||||
uint8_t rekey_mode;
|
||||
int64_t rekey_count;
|
||||
int64_t rekey_config_value;
|
||||
int64_t rekey_consumed_value;
|
||||
|
||||
uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
|
||||
} __packed;
|
||||
|
||||
/* AUTH States */
|
||||
#define VND_CMD_AUTH_STATE_UNDEF 0
|
||||
#define VND_CMD_AUTH_STATE_SESSION_SHUTDOWN 1
|
||||
#define VND_CMD_AUTH_STATE_NEEDED 2
|
||||
#define VND_CMD_AUTH_STATE_ELS_RCVD 3
|
||||
#define VND_CMD_AUTH_STATE_SAUPDATE_COMPL 4
|
||||
|
||||
struct app_pinfo_reply {
|
||||
uint8_t port_count;
|
||||
uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
|
||||
struct app_pinfo ports[0];
|
||||
} __packed;
|
||||
|
||||
struct app_sinfo_req {
|
||||
struct app_id app_info;
|
||||
uint8_t num_ports;
|
||||
uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct app_sinfo {
|
||||
uint8_t remote_wwpn[WWN_SIZE];
|
||||
int64_t rekey_count;
|
||||
uint8_t rekey_mode;
|
||||
int64_t tx_bytes;
|
||||
int64_t rx_bytes;
|
||||
} __packed;
|
||||
|
||||
struct app_stats_reply {
|
||||
uint8_t elem_count;
|
||||
struct app_sinfo elem[0];
|
||||
} __packed;
|
||||
|
||||
struct qla_sa_update_frame {
|
||||
struct app_id app_info;
|
||||
uint16_t flags;
|
||||
#define SAU_FLG_INV 0x01 /* delete key */
|
||||
#define SAU_FLG_TX 0x02 /* 1=tx, 0 = rx */
|
||||
#define SAU_FLG_FORCE_DELETE 0x08
|
||||
#define SAU_FLG_GMAC_MODE 0x20 /*
|
||||
* GMAC mode is cleartext for the IO
|
||||
* (i.e. NULL encryption)
|
||||
*/
|
||||
#define SAU_FLG_KEY128 0x40
|
||||
#define SAU_FLG_KEY256 0x80
|
||||
uint16_t fast_sa_index:10,
|
||||
reserved:6;
|
||||
uint32_t salt;
|
||||
uint32_t spi;
|
||||
uint8_t sa_key[32];
|
||||
uint8_t node_name[WWN_SIZE];
|
||||
uint8_t port_name[WWN_SIZE];
|
||||
port_id_t port_id;
|
||||
} __packed;
|
||||
|
||||
// used for edif mgmt bsg interface
|
||||
#define QL_VND_SC_UNDEF 0
|
||||
#define QL_VND_SC_SA_UPDATE 1
|
||||
#define QL_VND_SC_APP_START 2
|
||||
#define QL_VND_SC_APP_STOP 3
|
||||
#define QL_VND_SC_AUTH_OK 4
|
||||
#define QL_VND_SC_AUTH_FAIL 5
|
||||
#define QL_VND_SC_REKEY_CONFIG 6
|
||||
#define QL_VND_SC_GET_FCINFO 7
|
||||
#define QL_VND_SC_GET_STATS 8
|
||||
|
||||
/* Application interface data structure for rtn data */
|
||||
#define EXT_DEF_EVENT_DATA_SIZE 64
|
||||
struct edif_app_dbell {
|
||||
uint32_t event_code;
|
||||
uint32_t event_data_size;
|
||||
union {
|
||||
port_id_t port_id;
|
||||
uint8_t event_data[EXT_DEF_EVENT_DATA_SIZE];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct edif_sa_update_aen {
|
||||
port_id_t port_id;
|
||||
uint32_t key_type; /* Tx (1) or RX (2) */
|
||||
uint32_t status; /* 0 succes, 1 failed, 2 timeout , 3 error */
|
||||
uint8_t reserved[16];
|
||||
} __packed;
|
||||
|
||||
#define QL_VND_SA_STAT_SUCCESS 0
|
||||
#define QL_VND_SA_STAT_FAILED 1
|
||||
#define QL_VND_SA_STAT_TIMEOUT 2
|
||||
#define QL_VND_SA_STAT_ERROR 3
|
||||
|
||||
#define QL_VND_RX_SA_KEY 1
|
||||
#define QL_VND_TX_SA_KEY 2
|
||||
|
||||
/* App defines for plogi auth'd ok and plogi auth bad requests */
|
||||
struct auth_complete_cmd {
|
||||
struct app_id app_info;
|
||||
#define PL_TYPE_WWPN 1
|
||||
#define PL_TYPE_DID 2
|
||||
uint32_t type;
|
||||
union {
|
||||
uint8_t wwpn[WWN_SIZE];
|
||||
port_id_t d_id;
|
||||
} u;
|
||||
uint32_t reserved[VND_CMD_APP_RESERVED_SIZE];
|
||||
} __packed;
|
||||
|
||||
#define RX_DELAY_DELETE_TIMEOUT 20
|
||||
|
||||
#endif /* QLA_EDIF_BSG_H */
|
||||
@@ -94,10 +94,11 @@ struct port_database_24xx {
|
||||
uint8_t port_name[WWN_SIZE];
|
||||
uint8_t node_name[WWN_SIZE];
|
||||
|
||||
uint8_t reserved_3[4];
|
||||
uint8_t reserved_3[2];
|
||||
uint16_t nvme_first_burst_size;
|
||||
uint16_t prli_nvme_svc_param_word_0; /* Bits 15-0 of word 0 */
|
||||
uint16_t prli_nvme_svc_param_word_3; /* Bits 15-0 of word 3 */
|
||||
uint16_t nvme_first_burst_size;
|
||||
uint8_t secure_login;
|
||||
uint8_t reserved_4[14];
|
||||
};
|
||||
|
||||
@@ -501,6 +502,9 @@ struct cmd_type_6 {
|
||||
struct scsi_lun lun; /* FCP LUN (BE). */
|
||||
|
||||
__le16 control_flags; /* Control flags. */
|
||||
#define CF_NEW_SA BIT_12
|
||||
#define CF_EN_EDIF BIT_9
|
||||
#define CF_ADDITIONAL_PARAM_BLK BIT_8
|
||||
#define CF_DIF_SEG_DESCR_ENABLE BIT_3
|
||||
#define CF_DATA_SEG_DESCR_ENABLE BIT_2
|
||||
#define CF_READ_DATA BIT_1
|
||||
@@ -623,6 +627,7 @@ struct sts_entry_24xx {
|
||||
union {
|
||||
__le16 reserved_1;
|
||||
__le16 nvme_rsp_pyld_len;
|
||||
__le16 edif_sa_index; /* edif sa_index used for initiator read data */
|
||||
};
|
||||
|
||||
__le16 state_flags; /* State flags. */
|
||||
@@ -817,6 +822,7 @@ struct els_entry_24xx {
|
||||
#define EPD_RX_XCHG (3 << 13)
|
||||
#define ECF_CLR_PASSTHRU_PEND BIT_12
|
||||
#define ECF_INCL_FRAME_HDR BIT_11
|
||||
#define ECF_SEC_LOGIN BIT_3
|
||||
|
||||
union {
|
||||
struct {
|
||||
@@ -908,6 +914,7 @@ struct logio_entry_24xx {
|
||||
#define LCF_FCP2_OVERRIDE BIT_9 /* Set/Reset word 3 of PRLI. */
|
||||
#define LCF_CLASS_2 BIT_8 /* Enable class 2 during PLOGI. */
|
||||
#define LCF_FREE_NPORT BIT_7 /* Release NPORT handle after LOGO. */
|
||||
#define LCF_COMMON_FEAT BIT_7 /* PLOGI - Set Common Features Field */
|
||||
#define LCF_EXPL_LOGO BIT_6 /* Perform an explicit LOGO. */
|
||||
#define LCF_NVME_PRLI BIT_6 /* Perform NVME FC4 PRLI */
|
||||
#define LCF_SKIP_PRLI BIT_5 /* Skip PRLI after PLOGI. */
|
||||
@@ -932,6 +939,8 @@ struct logio_entry_24xx {
|
||||
uint8_t rsp_size; /* Response size in 32bit words. */
|
||||
|
||||
__le32 io_parameter[11]; /* General I/O parameters. */
|
||||
#define LIO_COMM_FEAT_FCSP BIT_21
|
||||
#define LIO_COMM_FEAT_CIO BIT_31
|
||||
#define LSC_SCODE_NOLINK 0x01
|
||||
#define LSC_SCODE_NOIOCB 0x02
|
||||
#define LSC_SCODE_NOXCB 0x03
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
* Global Function Prototypes in qla_init.c source file.
|
||||
*/
|
||||
extern int qla2x00_initialize_adapter(scsi_qla_host_t *);
|
||||
extern int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport);
|
||||
|
||||
extern int qla2100_pci_config(struct scsi_qla_host *);
|
||||
extern int qla2300_pci_config(struct scsi_qla_host *);
|
||||
@@ -130,6 +131,18 @@ void qla24xx_free_purex_item(struct purex_item *item);
|
||||
extern bool qla24xx_risc_firmware_invalid(uint32_t *);
|
||||
void qla_init_iocb_limit(scsi_qla_host_t *);
|
||||
|
||||
void qla_edif_list_del(fc_port_t *fcport);
|
||||
void qla_edif_sadb_release(struct qla_hw_data *ha);
|
||||
int qla_edif_sadb_build_free_pool(struct qla_hw_data *ha);
|
||||
void qla_edif_sadb_release_free_pool(struct qla_hw_data *ha);
|
||||
void qla_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha,
|
||||
srb_t *sp, struct sts_entry_24xx *sts24);
|
||||
void qlt_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, fc_port_t *fcport,
|
||||
struct ctio7_from_24xx *ctio);
|
||||
void qla2x00_release_all_sadb(struct scsi_qla_host *vha, struct fc_port *fcport);
|
||||
int qla_edif_process_els(scsi_qla_host_t *vha, BSG_JOB_TYPE *bsgjob);
|
||||
void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess);
|
||||
const char *sc_to_str(uint16_t cmd);
|
||||
|
||||
/*
|
||||
* Global Data in qla_os.c source file.
|
||||
@@ -177,9 +190,9 @@ extern int ql2xnvmeenable;
|
||||
extern int ql2xautodetectsfp;
|
||||
extern int ql2xenablemsix;
|
||||
extern int qla2xuseresexchforels;
|
||||
extern int ql2xexlogins;
|
||||
extern int ql2xdifbundlinginternalbuffers;
|
||||
extern int ql2xfulldump_on_mpifail;
|
||||
extern int ql2xsecenable;
|
||||
extern int ql2xenforce_iocb_limit;
|
||||
extern int ql2xabts_wait_nvme;
|
||||
|
||||
@@ -224,7 +237,6 @@ extern int qla83xx_set_drv_presence(scsi_qla_host_t *vha);
|
||||
extern int __qla83xx_set_drv_presence(scsi_qla_host_t *vha);
|
||||
extern int qla83xx_clear_drv_presence(scsi_qla_host_t *vha);
|
||||
extern int __qla83xx_clear_drv_presence(scsi_qla_host_t *vha);
|
||||
extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
|
||||
|
||||
extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
|
||||
extern void qla2x00_disable_board_on_pci_error(struct work_struct *);
|
||||
@@ -242,6 +254,8 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
|
||||
struct purex_item *pkt);
|
||||
void qla_pci_set_eeh_busy(struct scsi_qla_host *);
|
||||
void qla_schedule_eeh_work(struct scsi_qla_host *);
|
||||
struct edif_sa_ctl *qla_edif_find_sa_ctl_by_index(fc_port_t *fcport,
|
||||
int index, int dir);
|
||||
|
||||
/*
|
||||
* Global Functions in qla_mid.c source file.
|
||||
@@ -286,7 +300,10 @@ extern int qla2x00_vp_abort_isp(scsi_qla_host_t *);
|
||||
/*
|
||||
* Global Function Prototypes in qla_iocb.c source file.
|
||||
*/
|
||||
|
||||
void qla_els_pt_iocb(struct scsi_qla_host *vha,
|
||||
struct els_entry_24xx *pkt, struct qla_els_pt_arg *a);
|
||||
cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha,
|
||||
struct req_que *que);
|
||||
extern uint16_t qla2x00_calc_iocbs_32(uint16_t);
|
||||
extern uint16_t qla2x00_calc_iocbs_64(uint16_t);
|
||||
extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t);
|
||||
@@ -316,6 +333,8 @@ extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *,
|
||||
struct dsd64 *, uint16_t, struct qla_tgt_cmd *);
|
||||
extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *);
|
||||
extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *);
|
||||
extern int qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha,
|
||||
struct qla_work_evt *e);
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_mbx.c source file.
|
||||
@@ -555,6 +574,7 @@ extern int qla2xxx_read_remote_register(scsi_qla_host_t *, uint32_t,
|
||||
uint32_t *);
|
||||
extern int qla2xxx_write_remote_register(scsi_qla_host_t *, uint32_t,
|
||||
uint32_t);
|
||||
void qla_no_op_mb(struct scsi_qla_host *vha);
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_isr.c source file.
|
||||
@@ -583,6 +603,7 @@ qla2xxx_msix_rsp_q_hs(int irq, void *dev_id);
|
||||
fc_port_t *qla2x00_find_fcport_by_loopid(scsi_qla_host_t *, uint16_t);
|
||||
fc_port_t *qla2x00_find_fcport_by_wwpn(scsi_qla_host_t *, u8 *, u8);
|
||||
fc_port_t *qla2x00_find_fcport_by_nportid(scsi_qla_host_t *, port_id_t *, u8);
|
||||
void __qla_consume_iocb(struct scsi_qla_host *vha, void **pkt, struct rsp_que **rsp);
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_sup.c source file.
|
||||
@@ -645,6 +666,8 @@ extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
|
||||
|
||||
extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *);
|
||||
extern int qla24xx_read_fcp_prio_cfg(scsi_qla_host_t *);
|
||||
int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha, void **pkt,
|
||||
struct rsp_que **rsp, u8 *buf, u32 buf_len);
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_dbg.c source file.
|
||||
@@ -691,8 +714,6 @@ extern int qla2x00_chk_ms_status(scsi_qla_host_t *, ms_iocb_entry_t *,
|
||||
struct ct_sns_rsp *, const char *);
|
||||
extern void qla2x00_async_iocb_timeout(void *data);
|
||||
|
||||
extern void qla2x00_free_fcport(fc_port_t *);
|
||||
|
||||
extern int qla24xx_post_gpnid_work(struct scsi_qla_host *, port_id_t *);
|
||||
extern int qla24xx_async_gpnid(scsi_qla_host_t *, port_id_t *);
|
||||
void qla24xx_handle_gpnid_event(scsi_qla_host_t *, struct event_arg *);
|
||||
@@ -886,6 +907,9 @@ extern int qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *,
|
||||
dma_addr_t, size_t, uint32_t);
|
||||
extern int qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t,
|
||||
uint16_t *, uint16_t *);
|
||||
extern int qla24xx_sadb_update(BSG_JOB_TYPE *bsg_job);
|
||||
extern int qla_post_sa_replace_work(struct scsi_qla_host *vha,
|
||||
fc_port_t *fcport, uint16_t nport_handle, struct edif_sa_ctl *sa_ctl);
|
||||
|
||||
/* 83xx related functions */
|
||||
void qla83xx_fw_dump(scsi_qla_host_t *vha);
|
||||
@@ -930,6 +954,7 @@ extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *);
|
||||
extern void qlt_handle_abts_recv(struct scsi_qla_host *, struct rsp_que *,
|
||||
response_t *);
|
||||
|
||||
struct scsi_qla_host *qla_find_host_by_d_id(struct scsi_qla_host *vha, be_id_t d_id);
|
||||
int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *,
|
||||
struct imm_ntfy_from_isp *, int);
|
||||
void qla24xx_do_nack_work(struct scsi_qla_host *, struct qla_work_evt *);
|
||||
@@ -942,7 +967,7 @@ extern struct fc_port *qlt_find_sess_invalidate_other(scsi_qla_host_t *,
|
||||
void qla24xx_delete_sess_fn(struct work_struct *);
|
||||
void qlt_unknown_atio_work_fn(struct work_struct *);
|
||||
void qlt_update_host_map(struct scsi_qla_host *, port_id_t);
|
||||
void qlt_remove_target_resources(struct qla_hw_data *);
|
||||
void qla_remove_hostmap(struct qla_hw_data *ha);
|
||||
void qlt_clr_qp_table(struct scsi_qla_host *vha);
|
||||
void qlt_set_mode(struct scsi_qla_host *);
|
||||
int qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode);
|
||||
@@ -957,6 +982,25 @@ extern void qla_nvme_abort_process_comp_status
|
||||
|
||||
/* nvme.c */
|
||||
void qla_nvme_unregister_remote_port(struct fc_port *fcport);
|
||||
|
||||
/* qla_edif.c */
|
||||
fc_port_t *qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id);
|
||||
void qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype, uint32_t data, uint32_t data2,
|
||||
fc_port_t *fcport);
|
||||
void qla_edb_stop(scsi_qla_host_t *vha);
|
||||
ssize_t edif_doorbell_show(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
int32_t qla_edif_app_mgmt(BSG_JOB_TYPE *bsg_job);
|
||||
void qla_enode_init(scsi_qla_host_t *vha);
|
||||
void qla_enode_stop(scsi_qla_host_t *vha);
|
||||
void qla_edif_flush_sa_ctl_lists(fc_port_t *fcport);
|
||||
void qla_edb_init(scsi_qla_host_t *vha);
|
||||
void qla_edif_timer(scsi_qla_host_t *vha);
|
||||
int qla28xx_start_scsi_edif(srb_t *sp);
|
||||
void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb);
|
||||
void qla24xx_sa_replace_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb);
|
||||
void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp);
|
||||
void qla28xx_sa_update_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
struct sa_update_28xx *pkt);
|
||||
void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea);
|
||||
|
||||
#define QLA2XX_HW_ERROR BIT_0
|
||||
|
||||
@@ -632,7 +632,7 @@ static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id)
|
||||
ct_req->req.rft_id.port_id = port_id_to_be_id(vha->d_id);
|
||||
ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */
|
||||
|
||||
if (vha->flags.nvme_enabled)
|
||||
if (vha->flags.nvme_enabled && qla_ini_mode_enabled(vha))
|
||||
ct_req->req.rft_id.fc4_types[6] = 1; /* NVMe type 28h */
|
||||
|
||||
sp->u.iocb_cmd.u.ctarg.req_size = RFT_ID_REQ_SIZE;
|
||||
@@ -1730,8 +1730,6 @@ qla2x00_hba_attributes(scsi_qla_host_t *vha, void *entries,
|
||||
size += alen;
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20a8,
|
||||
"FIRMWARE VERSION = %s.\n", eiter->a.fw_version);
|
||||
if (callopt == CALLOPT_FDMI1)
|
||||
goto done;
|
||||
/* OS Name and Version */
|
||||
eiter = entries + size;
|
||||
eiter->type = cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION);
|
||||
@@ -1754,6 +1752,8 @@ qla2x00_hba_attributes(scsi_qla_host_t *vha, void *entries,
|
||||
size += alen;
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20a9,
|
||||
"OS VERSION = %s.\n", eiter->a.os_version);
|
||||
if (callopt == CALLOPT_FDMI1)
|
||||
goto done;
|
||||
/* MAX CT Payload Length */
|
||||
eiter = entries + size;
|
||||
eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH);
|
||||
@@ -2826,6 +2826,10 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
if (fcport->disc_state == DSC_DELETE_PEND)
|
||||
return;
|
||||
|
||||
/* We will figure-out what happen after AUTH completes */
|
||||
if (fcport->disc_state == DSC_LOGIN_AUTH_PEND)
|
||||
return;
|
||||
|
||||
if (ea->sp->gen2 != fcport->login_gen) {
|
||||
/* target side must have changed it. */
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20d3,
|
||||
@@ -3498,7 +3502,16 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
|
||||
continue;
|
||||
fcport->scan_state = QLA_FCPORT_FOUND;
|
||||
fcport->last_rscn_gen = fcport->rscn_gen;
|
||||
fcport->fc4_type = rp->fc4type;
|
||||
found = true;
|
||||
|
||||
if (fcport->scan_needed) {
|
||||
if (NVME_PRIORITY(vha->hw, fcport))
|
||||
fcport->do_prli_nvme = 1;
|
||||
else
|
||||
fcport->do_prli_nvme = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If device was not a fabric device before.
|
||||
*/
|
||||
|
||||
+256
-99
@@ -34,7 +34,6 @@ static int qla2x00_restart_isp(scsi_qla_host_t *);
|
||||
static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
|
||||
static int qla84xx_init_chip(scsi_qla_host_t *);
|
||||
static int qla25xx_init_queues(struct qla_hw_data *);
|
||||
static int qla24xx_post_prli_work(struct scsi_qla_host*, fc_port_t *);
|
||||
static void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha,
|
||||
struct event_arg *ea);
|
||||
static void qla24xx_handle_prli_done_event(struct scsi_qla_host *,
|
||||
@@ -158,7 +157,7 @@ int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
|
||||
sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport,
|
||||
GFP_ATOMIC);
|
||||
if (!sp)
|
||||
return rval;
|
||||
return QLA_MEMORY_ALLOC_FAILED;
|
||||
|
||||
abt_iocb = &sp->u.iocb_cmd;
|
||||
sp->type = SRB_ABT_CMD;
|
||||
@@ -191,7 +190,7 @@ int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
|
||||
if (wait) {
|
||||
wait_for_completion(&abt_iocb->u.abt.comp);
|
||||
rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
|
||||
QLA_SUCCESS : QLA_FUNCTION_FAILED;
|
||||
QLA_SUCCESS : QLA_ERR_FROM_FW;
|
||||
sp->free(sp);
|
||||
}
|
||||
|
||||
@@ -293,22 +292,6 @@ static void qla2x00_async_login_sp_done(srb_t *sp, int res)
|
||||
sp->free(sp);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
fcport_is_smaller(fc_port_t *fcport)
|
||||
{
|
||||
if (wwn_to_u64(fcport->port_name) <
|
||||
wwn_to_u64(fcport->vha->port_name))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
fcport_is_bigger(fc_port_t *fcport)
|
||||
{
|
||||
return !fcport_is_smaller(fcport);
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
|
||||
uint16_t *data)
|
||||
@@ -343,19 +326,28 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
|
||||
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
|
||||
|
||||
sp->done = qla2x00_async_login_sp_done;
|
||||
if (N2N_TOPO(fcport->vha->hw) && fcport_is_bigger(fcport))
|
||||
if (N2N_TOPO(fcport->vha->hw) && fcport_is_bigger(fcport)) {
|
||||
lio->u.logio.flags |= SRB_LOGIN_PRLI_ONLY;
|
||||
else
|
||||
lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
|
||||
} else {
|
||||
if (vha->hw->flags.edif_enabled &&
|
||||
vha->e_dbell.db_flags & EDB_ACTIVE) {
|
||||
lio->u.logio.flags |=
|
||||
(SRB_LOGIN_FCSP | SRB_LOGIN_SKIP_PRLI);
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2072,
|
||||
"Async-login: w/ FCSP %8phC hdl=%x, loopid=%x portid=%06x\n",
|
||||
fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24);
|
||||
} else {
|
||||
lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
|
||||
}
|
||||
}
|
||||
|
||||
if (NVME_TARGET(vha->hw, fcport))
|
||||
lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI;
|
||||
|
||||
ql_log(ql_log_warn, vha, 0x2072,
|
||||
"Async-login - %8phC hdl=%x, loopid=%x portid=%02x%02x%02x retries=%d.\n",
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2072,
|
||||
"Async-login - %8phC hdl=%x, loopid=%x portid=%06x retries=%d.\n",
|
||||
fcport->port_name, sp->handle, fcport->loop_id,
|
||||
fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa,
|
||||
fcport->login_retry);
|
||||
fcport->d_id.b24, fcport->login_retry);
|
||||
|
||||
rval = qla2x00_start_sp(sp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
@@ -378,7 +370,7 @@ static void qla2x00_async_logout_sp_done(srb_t *sp, int res)
|
||||
{
|
||||
sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
|
||||
sp->fcport->login_gen++;
|
||||
qlt_logo_completion_handler(sp->fcport, res);
|
||||
qlt_logo_completion_handler(sp->fcport, sp->u.iocb_cmd.u.logio.data[0]);
|
||||
sp->free(sp);
|
||||
}
|
||||
|
||||
@@ -404,10 +396,10 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
|
||||
sp->done = qla2x00_async_logout_sp_done;
|
||||
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2070,
|
||||
"Async-logout - hdl=%x loop-id=%x portid=%02x%02x%02x %8phC.\n",
|
||||
"Async-logout - hdl=%x loop-id=%x portid=%02x%02x%02x %8phC explicit %d.\n",
|
||||
sp->handle, fcport->loop_id, fcport->d_id.b.domain,
|
||||
fcport->d_id.b.area, fcport->d_id.b.al_pa,
|
||||
fcport->port_name);
|
||||
fcport->port_name, fcport->explicit_logout);
|
||||
|
||||
rval = qla2x00_start_sp(sp);
|
||||
if (rval != QLA_SUCCESS)
|
||||
@@ -692,11 +684,11 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
|
||||
|
||||
fcport = ea->fcport;
|
||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||
"%s %8phC DS %d LS rc %d %d login %d|%d rscn %d|%d lid %d\n",
|
||||
"%s %8phC DS %d LS rc %d %d login %d|%d rscn %d|%d lid %d edif %d\n",
|
||||
__func__, fcport->port_name, fcport->disc_state,
|
||||
fcport->fw_login_state, ea->rc,
|
||||
fcport->login_gen, fcport->last_login_gen,
|
||||
fcport->rscn_gen, fcport->last_rscn_gen, vha->loop_id);
|
||||
fcport->rscn_gen, fcport->last_rscn_gen, vha->loop_id, fcport->edif.enable);
|
||||
|
||||
if (fcport->disc_state == DSC_DELETE_PEND)
|
||||
return;
|
||||
@@ -810,7 +802,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
|
||||
default:
|
||||
switch (current_login_state) {
|
||||
case DSC_LS_PRLI_COMP:
|
||||
ql_dbg(ql_dbg_disc + ql_dbg_verbose,
|
||||
ql_dbg(ql_dbg_disc,
|
||||
vha, 0x20e4, "%s %d %8phC post gpdb\n",
|
||||
__func__, __LINE__, fcport->port_name);
|
||||
|
||||
@@ -822,6 +814,13 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
|
||||
qla2x00_post_async_adisc_work(vha, fcport,
|
||||
data);
|
||||
break;
|
||||
case DSC_LS_PLOGI_COMP:
|
||||
if (vha->hw->flags.edif_enabled) {
|
||||
/* check to see if App support Secure */
|
||||
qla24xx_post_gpdb_work(vha, fcport, 0);
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
case DSC_LS_PORT_UNAVAIL:
|
||||
default:
|
||||
if (fcport->loop_id == FC_NO_LOOP_ID) {
|
||||
@@ -849,6 +848,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
|
||||
*/
|
||||
qla2x00_set_fcport_disc_state(fcport,
|
||||
DSC_DELETED);
|
||||
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
|
||||
break;
|
||||
case DSC_LS_PRLI_COMP:
|
||||
if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
|
||||
@@ -861,6 +861,12 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
|
||||
data);
|
||||
break;
|
||||
case DSC_LS_PLOGI_COMP:
|
||||
if (vha->hw->flags.edif_enabled &&
|
||||
vha->e_dbell.db_flags & EDB_ACTIVE) {
|
||||
/* check to see if App support secure or not */
|
||||
qla24xx_post_gpdb_work(vha, fcport, 0);
|
||||
break;
|
||||
}
|
||||
if (fcport_is_bigger(fcport)) {
|
||||
/* local adapter is smaller */
|
||||
if (fcport->loop_id != FC_NO_LOOP_ID)
|
||||
@@ -1191,7 +1197,7 @@ done:
|
||||
sp->free(sp);
|
||||
}
|
||||
|
||||
static int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport)
|
||||
int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport)
|
||||
{
|
||||
struct qla_work_evt *e;
|
||||
|
||||
@@ -1214,7 +1220,7 @@ static void qla2x00_async_prli_sp_done(srb_t *sp, int res)
|
||||
struct event_arg ea;
|
||||
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2129,
|
||||
"%s %8phC res %d \n", __func__,
|
||||
"%s %8phC res %x\n", __func__,
|
||||
sp->fcport->port_name, res);
|
||||
|
||||
sp->fcport->flags &= ~FCF_ASYNC_SENT;
|
||||
@@ -1227,6 +1233,8 @@ static void qla2x00_async_prli_sp_done(srb_t *sp, int res)
|
||||
ea.iop[0] = lio->u.logio.iop[0];
|
||||
ea.iop[1] = lio->u.logio.iop[1];
|
||||
ea.sp = sp;
|
||||
if (res == QLA_OS_TIMER_EXPIRED)
|
||||
ea.data[0] = QLA_OS_TIMER_EXPIRED;
|
||||
|
||||
qla24xx_handle_prli_done_event(vha, &ea);
|
||||
}
|
||||
@@ -1418,6 +1426,57 @@ void __qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
|
||||
}
|
||||
|
||||
static int qla_chk_secure_login(scsi_qla_host_t *vha, fc_port_t *fcport,
|
||||
struct port_database_24xx *pd)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (pd->secure_login) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x104d,
|
||||
"Secure Login established on %8phC\n",
|
||||
fcport->port_name);
|
||||
fcport->flags |= FCF_FCSP_DEVICE;
|
||||
} else {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x104d,
|
||||
"non-Secure Login %8phC",
|
||||
fcport->port_name);
|
||||
fcport->flags &= ~FCF_FCSP_DEVICE;
|
||||
}
|
||||
if (vha->hw->flags.edif_enabled) {
|
||||
if (fcport->flags & FCF_FCSP_DEVICE) {
|
||||
qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_AUTH_PEND);
|
||||
/* Start edif prli timer & ring doorbell for app */
|
||||
fcport->edif.rx_sa_set = 0;
|
||||
fcport->edif.tx_sa_set = 0;
|
||||
fcport->edif.rx_sa_pending = 0;
|
||||
fcport->edif.tx_sa_pending = 0;
|
||||
|
||||
qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE,
|
||||
fcport->d_id.b24);
|
||||
|
||||
if (vha->e_dbell.db_flags == EDB_ACTIVE) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20ef,
|
||||
"%s %d %8phC EDIF: post DB_AUTH: AUTH needed\n",
|
||||
__func__, __LINE__, fcport->port_name);
|
||||
fcport->edif.app_started = 1;
|
||||
fcport->edif.app_sess_online = 1;
|
||||
|
||||
qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED,
|
||||
fcport->d_id.b24, 0, fcport);
|
||||
}
|
||||
|
||||
rc = 1;
|
||||
} else if (qla_ini_mode_enabled(vha) || qla_dual_mode_enabled(vha)) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2117,
|
||||
"%s %d %8phC post prli\n",
|
||||
__func__, __LINE__, fcport->port_name);
|
||||
qla24xx_post_prli_work(vha, fcport);
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static
|
||||
void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
{
|
||||
@@ -1431,12 +1490,15 @@ 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 fc4_type %x rc %d\n", __func__,
|
||||
"%s %8phC DS %d LS %x fc4_type %x rc %x\n", __func__,
|
||||
fcport->port_name, fcport->disc_state, pd->current_login_state,
|
||||
fcport->fc4_type, ea->rc);
|
||||
|
||||
if (fcport->disc_state == DSC_DELETE_PEND)
|
||||
if (fcport->disc_state == DSC_DELETE_PEND) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC\n",
|
||||
__func__, __LINE__, fcport->port_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NVME_TARGET(vha->hw, fcport))
|
||||
ls = pd->current_login_state >> 4;
|
||||
@@ -1453,6 +1515,8 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
} else if (ea->sp->gen1 != fcport->rscn_gen) {
|
||||
qla_rscn_replay(fcport);
|
||||
qlt_schedule_sess_for_deletion(fcport);
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC, ls %x\n",
|
||||
__func__, __LINE__, fcport->port_name, ls);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1460,8 +1524,14 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
case PDS_PRLI_COMPLETE:
|
||||
__qla24xx_parse_gpdb(vha, fcport, pd);
|
||||
break;
|
||||
case PDS_PLOGI_PENDING:
|
||||
case PDS_PLOGI_COMPLETE:
|
||||
if (qla_chk_secure_login(vha, fcport, pd)) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC, ls %x\n",
|
||||
__func__, __LINE__, fcport->port_name, ls);
|
||||
return;
|
||||
}
|
||||
fallthrough;
|
||||
case PDS_PLOGI_PENDING:
|
||||
case PDS_PRLI_PENDING:
|
||||
case PDS_PRLI2_PENDING:
|
||||
/* Set discovery state back to GNL to Relogin attempt */
|
||||
@@ -1470,6 +1540,8 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
|
||||
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
|
||||
}
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC, ls %x\n",
|
||||
__func__, __LINE__, fcport->port_name, ls);
|
||||
return;
|
||||
case PDS_LOGO_PENDING:
|
||||
case PDS_PORT_UNAVAILABLE:
|
||||
@@ -1538,11 +1610,12 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
|
||||
u16 sec;
|
||||
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20d8,
|
||||
"%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d lid %d scan %d\n",
|
||||
"%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d lid %d scan %d fc4type %x\n",
|
||||
__func__, fcport->port_name, fcport->disc_state,
|
||||
fcport->fw_login_state, fcport->login_pause, fcport->flags,
|
||||
fcport->conflict, fcport->last_rscn_gen, fcport->rscn_gen,
|
||||
fcport->login_gen, fcport->loop_id, fcport->scan_state);
|
||||
fcport->login_gen, fcport->loop_id, fcport->scan_state,
|
||||
fcport->fc4_type);
|
||||
|
||||
if (fcport->scan_state != QLA_FCPORT_FOUND)
|
||||
return 0;
|
||||
@@ -1715,6 +1788,12 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
|
||||
fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
|
||||
if (fcport) {
|
||||
if (fcport->flags & FCF_FCP2_DEVICE) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2115,
|
||||
"Delaying session delete for FCP2 portid=%06x %8phC ",
|
||||
fcport->d_id.b24, fcport->port_name);
|
||||
return;
|
||||
}
|
||||
fcport->scan_needed = 1;
|
||||
fcport->rscn_gen++;
|
||||
}
|
||||
@@ -1758,6 +1837,13 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
|
||||
void qla_handle_els_plogi_done(scsi_qla_host_t *vha,
|
||||
struct event_arg *ea)
|
||||
{
|
||||
if (N2N_TOPO(vha->hw) && fcport_is_smaller(ea->fcport) &&
|
||||
vha->hw->flags.edif_enabled) {
|
||||
/* check to see if App support Secure */
|
||||
qla24xx_post_gpdb_work(vha, ea->fcport, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* for pure Target Mode, PRLI will not be initiated */
|
||||
if (vha->host->active_mode == MODE_TARGET)
|
||||
return;
|
||||
@@ -1902,7 +1988,7 @@ qla24xx_async_abort_command(srb_t *sp)
|
||||
|
||||
if (handle == req->num_outstanding_cmds) {
|
||||
/* Command not found. */
|
||||
return QLA_FUNCTION_FAILED;
|
||||
return QLA_ERR_NOT_FOUND;
|
||||
}
|
||||
if (sp->type == SRB_FXIOCB_DCMD)
|
||||
return qlafx00_fx_disc(vha, &vha->hw->mr.fcport,
|
||||
@@ -1914,6 +2000,7 @@ qla24xx_async_abort_command(srb_t *sp)
|
||||
static void
|
||||
qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
|
||||
{
|
||||
struct srb *sp;
|
||||
WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
|
||||
ea->data[0]);
|
||||
|
||||
@@ -1941,22 +2028,27 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
|
||||
break;
|
||||
}
|
||||
|
||||
sp = ea->sp;
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2118,
|
||||
"%s %d %8phC priority %s, fc4type %x\n",
|
||||
"%s %d %8phC priority %s, fc4type %x prev try %s\n",
|
||||
__func__, __LINE__, ea->fcport->port_name,
|
||||
vha->hw->fc4_type_priority == FC4_PRIORITY_FCP ?
|
||||
"FCP" : "NVMe", ea->fcport->fc4_type);
|
||||
"FCP" : "NVMe", ea->fcport->fc4_type,
|
||||
(sp->u.iocb_cmd.u.logio.flags & SRB_LOGIN_NVME_PRLI) ?
|
||||
"NVME" : "FCP");
|
||||
|
||||
if (NVME_FCP_TARGET(ea->fcport)) {
|
||||
if (sp->u.iocb_cmd.u.logio.flags & SRB_LOGIN_NVME_PRLI)
|
||||
ea->fcport->do_prli_nvme = 0;
|
||||
else
|
||||
ea->fcport->do_prli_nvme = 1;
|
||||
} else {
|
||||
ea->fcport->do_prli_nvme = 0;
|
||||
}
|
||||
|
||||
if (N2N_TOPO(vha->hw)) {
|
||||
if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) {
|
||||
ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
|
||||
ea->fcport->fc4_type |= FS_FC4TYPE_FCP;
|
||||
} else {
|
||||
ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
|
||||
ea->fcport->fc4_type |= FS_FC4TYPE_NVME;
|
||||
}
|
||||
|
||||
if (ea->fcport->n2n_link_reset_cnt < 3) {
|
||||
if (ea->fcport->n2n_link_reset_cnt <
|
||||
vha->hw->login_retry_count) {
|
||||
ea->fcport->n2n_link_reset_cnt++;
|
||||
vha->relogin_jif = jiffies + 2 * HZ;
|
||||
/*
|
||||
@@ -1964,6 +2056,7 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
|
||||
* state machine
|
||||
*/
|
||||
set_bit(N2N_LINK_RESET, &vha->dpc_flags);
|
||||
qla2xxx_wake_dpc(vha);
|
||||
} else {
|
||||
ql_log(ql_log_warn, vha, 0x2119,
|
||||
"%s %d %8phC Unable to reconnect\n",
|
||||
@@ -1975,19 +2068,6 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
|
||||
* switch connect. login failed. Take connection down
|
||||
* and allow relogin to retrigger
|
||||
*/
|
||||
if (NVME_FCP_TARGET(ea->fcport)) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2118,
|
||||
"%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;
|
||||
}
|
||||
|
||||
ea->fcport->flags &= ~FCF_ASYNC_SENT;
|
||||
ea->fcport->keep_nport_handle = 0;
|
||||
ea->fcport->logout_on_delete = 1;
|
||||
@@ -2053,26 +2133,38 @@ 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 (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 gpdb\n",
|
||||
__func__, __LINE__, ea->fcport->port_name,
|
||||
ea->fcport->loop_id, ea->fcport->d_id.b24);
|
||||
|
||||
if (vha->hw->flags.edif_enabled) {
|
||||
set_bit(ea->fcport->loop_id, vha->hw->loop_id_map);
|
||||
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
|
||||
ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
|
||||
ea->fcport->logout_on_delete = 1;
|
||||
ea->fcport->send_els_logo = 0;
|
||||
ea->fcport->fw_login_state = DSC_LS_PRLI_COMP;
|
||||
ea->fcport->fw_login_state = DSC_LS_PLOGI_COMP;
|
||||
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
|
||||
|
||||
qla24xx_post_gpdb_work(vha, ea->fcport, 0);
|
||||
} else {
|
||||
if (NVME_TARGET(vha->hw, fcport)) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2117,
|
||||
"%s %d %8phC post prli\n",
|
||||
__func__, __LINE__, fcport->port_name);
|
||||
qla24xx_post_prli_work(vha, fcport);
|
||||
} else {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x20ea,
|
||||
"%s %d %8phC LoopID 0x%x in use with %06x. post gpdb\n",
|
||||
__func__, __LINE__, fcport->port_name,
|
||||
fcport->loop_id, fcport->d_id.b24);
|
||||
|
||||
set_bit(fcport->loop_id, vha->hw->loop_id_map);
|
||||
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
|
||||
fcport->chip_reset = vha->hw->base_qpair->chip_reset;
|
||||
fcport->logout_on_delete = 1;
|
||||
fcport->send_els_logo = 0;
|
||||
fcport->fw_login_state = DSC_LS_PRLI_COMP;
|
||||
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
|
||||
|
||||
qla24xx_post_gpdb_work(vha, fcport, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MBS_COMMAND_ERROR:
|
||||
@@ -3877,7 +3969,8 @@ enable_82xx_npiv:
|
||||
}
|
||||
|
||||
/* Enable PUREX PASSTHRU */
|
||||
if (ql2xrdpenable || ha->flags.scm_supported_f)
|
||||
if (ql2xrdpenable || ha->flags.scm_supported_f ||
|
||||
ha->flags.edif_enabled)
|
||||
qla25xx_set_els_cmds_supported(vha);
|
||||
} else
|
||||
goto failed;
|
||||
@@ -4062,7 +4155,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
|
||||
}
|
||||
|
||||
/* Move PUREX, ABTS RX & RIDA to ATIOQ */
|
||||
if (ql2xmvasynctoatio &&
|
||||
if (ql2xmvasynctoatio && !ha->flags.edif_enabled &&
|
||||
(IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))) {
|
||||
if (qla_tgt_mode_enabled(vha) ||
|
||||
qla_dual_mode_enabled(vha))
|
||||
@@ -4081,16 +4174,30 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
|
||||
qla_dual_mode_enabled(vha))
|
||||
ha->fw_options[2] |= BIT_4;
|
||||
else
|
||||
ha->fw_options[2] &= ~BIT_4;
|
||||
ha->fw_options[2] &= ~(BIT_4);
|
||||
|
||||
/* Reserve 1/2 of emergency exchanges for ELS.*/
|
||||
if (qla2xuseresexchforels)
|
||||
ha->fw_options[2] |= BIT_8;
|
||||
else
|
||||
ha->fw_options[2] &= ~BIT_8;
|
||||
|
||||
/*
|
||||
* N2N: set Secure=1 for PLOGI ACC and
|
||||
* fw shal not send PRLI after PLOGI Acc
|
||||
*/
|
||||
if (ha->flags.edif_enabled &&
|
||||
vha->e_dbell.db_flags & EDB_ACTIVE) {
|
||||
ha->fw_options[3] |= BIT_15;
|
||||
ha->flags.n2n_fw_acc_sec = 1;
|
||||
} else {
|
||||
ha->fw_options[3] &= ~BIT_15;
|
||||
ha->flags.n2n_fw_acc_sec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ql2xrdpenable || ha->flags.scm_supported_f)
|
||||
if (ql2xrdpenable || ha->flags.scm_supported_f ||
|
||||
ha->flags.edif_enabled)
|
||||
ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB;
|
||||
|
||||
/* Enable Async 8130/8131 events -- transceiver insertion/removal */
|
||||
@@ -4289,8 +4396,6 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
|
||||
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
ql_dbg(ql_dbg_init, vha, 0x00d1, "Issue init firmware.\n");
|
||||
|
||||
if (IS_QLAFX00(ha)) {
|
||||
rval = qlafx00_init_firmware(vha, ha->init_cb_size);
|
||||
goto next_check;
|
||||
@@ -4299,6 +4404,12 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
|
||||
/* Update any ISP specific firmware options before initialization. */
|
||||
ha->isp_ops->update_fw_options(vha);
|
||||
|
||||
ql_dbg(ql_dbg_init, vha, 0x00d1,
|
||||
"Issue init firmware FW opt 1-3= %08x %08x %08x.\n",
|
||||
le32_to_cpu(mid_init_cb->init_cb.firmware_options_1),
|
||||
le32_to_cpu(mid_init_cb->init_cb.firmware_options_2),
|
||||
le32_to_cpu(mid_init_cb->init_cb.firmware_options_3));
|
||||
|
||||
if (ha->flags.npiv_supported) {
|
||||
if (ha->operating_mode == LOOP && !IS_CNA_CAPABLE(ha))
|
||||
ha->max_npiv_vports = MIN_MULTI_ID_FABRIC - 1;
|
||||
@@ -4356,8 +4467,6 @@ qla2x00_fw_ready(scsi_qla_host_t *vha)
|
||||
if (IS_QLAFX00(vha->hw))
|
||||
return qlafx00_fw_ready(vha);
|
||||
|
||||
rval = QLA_SUCCESS;
|
||||
|
||||
/* Time to wait for loop down */
|
||||
if (IS_P3P_TYPE(ha))
|
||||
min_wait = 30;
|
||||
@@ -4533,11 +4642,11 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
|
||||
/* initialize */
|
||||
ha->min_external_loopid = SNS_FIRST_LOOP_ID;
|
||||
ha->operating_mode = LOOP;
|
||||
ha->switch_cap = 0;
|
||||
|
||||
switch (topo) {
|
||||
case 0:
|
||||
ql_dbg(ql_dbg_disc, vha, 0x200b, "HBA in NL topology.\n");
|
||||
ha->switch_cap = 0;
|
||||
ha->current_topology = ISP_CFG_NL;
|
||||
strcpy(connect_type, "(Loop)");
|
||||
break;
|
||||
@@ -4551,6 +4660,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
|
||||
|
||||
case 2:
|
||||
ql_dbg(ql_dbg_disc, vha, 0x200d, "HBA in N P2P topology.\n");
|
||||
ha->switch_cap = 0;
|
||||
ha->operating_mode = P2P;
|
||||
ha->current_topology = ISP_CFG_N;
|
||||
strcpy(connect_type, "(N_Port-to-N_Port)");
|
||||
@@ -4567,6 +4677,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
|
||||
default:
|
||||
ql_dbg(ql_dbg_disc, vha, 0x200f,
|
||||
"HBA in unknown topology %x, using NL.\n", topo);
|
||||
ha->switch_cap = 0;
|
||||
ha->current_topology = ISP_CFG_NL;
|
||||
strcpy(connect_type, "(Loop)");
|
||||
break;
|
||||
@@ -4579,7 +4690,10 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
|
||||
id.b.al_pa = al_pa;
|
||||
id.b.rsvd_1 = 0;
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
if (!(topo == 2 && ha->flags.n2n_bigger))
|
||||
if (vha->hw->flags.edif_enabled) {
|
||||
if (topo != 2)
|
||||
qlt_update_host_map(vha, id);
|
||||
} else if (!(topo == 2 && ha->flags.n2n_bigger))
|
||||
qlt_update_host_map(vha, id);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
@@ -5073,6 +5187,16 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
|
||||
INIT_LIST_HEAD(&fcport->sess_cmd_list);
|
||||
spin_lock_init(&fcport->sess_cmd_lock);
|
||||
|
||||
spin_lock_init(&fcport->edif.sa_list_lock);
|
||||
INIT_LIST_HEAD(&fcport->edif.tx_sa_list);
|
||||
INIT_LIST_HEAD(&fcport->edif.rx_sa_list);
|
||||
|
||||
if (vha->e_dbell.db_flags == EDB_ACTIVE)
|
||||
fcport->edif.app_started = 1;
|
||||
|
||||
spin_lock_init(&fcport->edif.indx_list_lock);
|
||||
INIT_LIST_HEAD(&fcport->edif.edif_indx_list);
|
||||
|
||||
return fcport;
|
||||
}
|
||||
|
||||
@@ -5086,8 +5210,13 @@ qla2x00_free_fcport(fc_port_t *fcport)
|
||||
|
||||
fcport->ct_desc.ct_sns = NULL;
|
||||
}
|
||||
|
||||
qla_edif_flush_sa_ctl_lists(fcport);
|
||||
list_del(&fcport->list);
|
||||
qla2x00_clear_loop_id(fcport);
|
||||
|
||||
qla_edif_list_del(fcport);
|
||||
|
||||
kfree(fcport);
|
||||
}
|
||||
|
||||
@@ -5206,6 +5335,16 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
|
||||
"LOOP READY.\n");
|
||||
ha->flags.fw_init_done = 1;
|
||||
|
||||
if (ha->flags.edif_enabled &&
|
||||
!(vha->e_dbell.db_flags & EDB_ACTIVE) &&
|
||||
N2N_TOPO(vha->hw)) {
|
||||
/*
|
||||
* use port online to wake up app to get ready
|
||||
* for authentication
|
||||
*/
|
||||
qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process any ATIO queue entries that came in
|
||||
* while we weren't online.
|
||||
@@ -5225,7 +5364,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
|
||||
"%s *** FAILED ***.\n", __func__);
|
||||
} else {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x206b,
|
||||
"%s: exiting normally.\n", __func__);
|
||||
"%s: exiting normally. local port wwpn %8phN id %06x)\n",
|
||||
__func__, vha->port_name, vha->d_id.b24);
|
||||
}
|
||||
|
||||
/* Restore state if a resync event occurred during processing */
|
||||
@@ -5245,6 +5385,8 @@ static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
|
||||
unsigned long flags;
|
||||
fc_port_t *fcport;
|
||||
|
||||
ql_dbg(ql_dbg_disc, vha, 0x206a, "%s %d.\n", __func__, __LINE__);
|
||||
|
||||
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags))
|
||||
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
|
||||
|
||||
@@ -6461,13 +6603,13 @@ void
|
||||
qla2x00_update_fcports(scsi_qla_host_t *base_vha)
|
||||
{
|
||||
fc_port_t *fcport;
|
||||
struct scsi_qla_host *vha;
|
||||
struct scsi_qla_host *vha, *tvp;
|
||||
struct qla_hw_data *ha = base_vha->hw;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
/* Go with deferred removal of rport references. */
|
||||
list_for_each_entry(vha, &base_vha->hw->vp_list, list) {
|
||||
list_for_each_entry_safe(vha, tvp, &base_vha->hw->vp_list, list) {
|
||||
atomic_inc(&vha->vref_count);
|
||||
list_for_each_entry(fcport, &vha->vp_fcports, list) {
|
||||
if (fcport->drport &&
|
||||
@@ -6812,7 +6954,8 @@ void
|
||||
qla2x00_quiesce_io(scsi_qla_host_t *vha)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct scsi_qla_host *vp;
|
||||
struct scsi_qla_host *vp, *tvp;
|
||||
unsigned long flags;
|
||||
|
||||
ql_dbg(ql_dbg_dpc, vha, 0x401d,
|
||||
"Quiescing I/O - ha=%p.\n", ha);
|
||||
@@ -6821,8 +6964,18 @@ qla2x00_quiesce_io(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);
|
||||
list_for_each_entry(vp, &ha->vp_list, list)
|
||||
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
|
||||
atomic_inc(&vp->vref_count);
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
|
||||
qla2x00_mark_all_devices_lost(vp);
|
||||
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
atomic_dec(&vp->vref_count);
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
} else {
|
||||
if (!atomic_read(&vha->loop_down_timer))
|
||||
atomic_set(&vha->loop_down_timer,
|
||||
@@ -6837,7 +6990,7 @@ void
|
||||
qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct scsi_qla_host *vp;
|
||||
struct scsi_qla_host *vp, *tvp;
|
||||
unsigned long flags;
|
||||
fc_port_t *fcport;
|
||||
u16 i;
|
||||
@@ -6872,10 +7025,14 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
|
||||
ha->flags.fw_init_done = 0;
|
||||
ha->chip_reset++;
|
||||
ha->base_qpair->chip_reset = ha->chip_reset;
|
||||
ha->base_qpair->cmd_cnt = ha->base_qpair->cmd_completion_cnt = 0;
|
||||
for (i = 0; i < ha->max_qpairs; i++) {
|
||||
if (ha->queue_pair_map[i])
|
||||
if (ha->queue_pair_map[i]) {
|
||||
ha->queue_pair_map[i]->chip_reset =
|
||||
ha->base_qpair->chip_reset;
|
||||
ha->queue_pair_map[i]->cmd_cnt =
|
||||
ha->queue_pair_map[i]->cmd_completion_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* purge MBox commands */
|
||||
@@ -6901,7 +7058,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
|
||||
qla2x00_mark_all_devices_lost(vha);
|
||||
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
list_for_each_entry(vp, &ha->vp_list, list) {
|
||||
list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
|
||||
atomic_inc(&vp->vref_count);
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
|
||||
@@ -6923,7 +7080,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
|
||||
fcport->scan_state = 0;
|
||||
}
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
list_for_each_entry(vp, &ha->vp_list, list) {
|
||||
list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
|
||||
atomic_inc(&vp->vref_count);
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
|
||||
@@ -6967,7 +7124,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
|
||||
int rval;
|
||||
uint8_t status = 0;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct scsi_qla_host *vp;
|
||||
struct scsi_qla_host *vp, *tvp;
|
||||
struct req_que *req = ha->req_q_map[0];
|
||||
unsigned long flags;
|
||||
|
||||
@@ -7123,7 +7280,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
|
||||
ql_dbg(ql_dbg_taskm, vha, 0x8022, "%s succeeded.\n", __func__);
|
||||
qla2x00_configure_hba(vha);
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
list_for_each_entry(vp, &ha->vp_list, list) {
|
||||
list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
|
||||
if (vp->vp_idx) {
|
||||
atomic_inc(&vp->vref_count);
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
@@ -8808,7 +8965,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha)
|
||||
{
|
||||
int status, rval;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct scsi_qla_host *vp;
|
||||
struct scsi_qla_host *vp, *tvp;
|
||||
unsigned long flags;
|
||||
|
||||
status = qla2x00_init_rings(vha);
|
||||
@@ -8880,7 +9037,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha)
|
||||
"qla82xx_restart_isp succeeded.\n");
|
||||
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
list_for_each_entry(vp, &ha->vp_list, list) {
|
||||
list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
|
||||
if (vp->vp_idx) {
|
||||
atomic_inc(&vp->vref_count);
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
|
||||
@@ -486,3 +486,19 @@ bool qla_pci_disconnected(struct scsi_qla_host *vha,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
fcport_is_smaller(fc_port_t *fcport)
|
||||
{
|
||||
if (wwn_to_u64(fcport->port_name) <
|
||||
wwn_to_u64(fcport->vha->port_name))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
fcport_is_bigger(fc_port_t *fcport)
|
||||
{
|
||||
return !fcport_is_smaller(fcport);
|
||||
}
|
||||
|
||||
+98
-69
@@ -118,7 +118,7 @@ qla2x00_prep_cont_type0_iocb(struct scsi_qla_host *vha)
|
||||
*
|
||||
* Returns a pointer to the continuation type 1 IOCB packet.
|
||||
*/
|
||||
static inline cont_a64_entry_t *
|
||||
cont_a64_entry_t *
|
||||
qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req)
|
||||
{
|
||||
cont_a64_entry_t *cont_pkt;
|
||||
@@ -145,7 +145,6 @@ inline int
|
||||
qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
|
||||
{
|
||||
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
|
||||
uint8_t guard = scsi_host_get_guard(cmd->device->host);
|
||||
|
||||
/* We always use DIFF Bundling for best performance */
|
||||
*fw_prot_opts = 0;
|
||||
@@ -166,7 +165,7 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
|
||||
break;
|
||||
case SCSI_PROT_READ_PASS:
|
||||
case SCSI_PROT_WRITE_PASS:
|
||||
if (guard & SHOST_DIX_GUARD_IP)
|
||||
if (cmd->prot_flags & SCSI_PROT_IP_CHECKSUM)
|
||||
*fw_prot_opts |= PO_MODE_DIF_TCP_CKSUM;
|
||||
else
|
||||
*fw_prot_opts |= PO_MODE_DIF_PASS;
|
||||
@@ -176,6 +175,9 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(cmd->prot_flags & SCSI_PROT_GUARD_CHECK))
|
||||
*fw_prot_opts |= PO_DISABLE_GUARD_CHECK;
|
||||
|
||||
return scsi_prot_sg_count(cmd);
|
||||
}
|
||||
|
||||
@@ -772,74 +774,19 @@ qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt,
|
||||
{
|
||||
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
|
||||
|
||||
switch (scsi_get_prot_type(cmd)) {
|
||||
case SCSI_PROT_DIF_TYPE0:
|
||||
/*
|
||||
* No check for ql2xenablehba_err_chk, as it would be an
|
||||
* I/O error if hba tag generation is not done.
|
||||
*/
|
||||
pkt->ref_tag = cpu_to_le32((uint32_t)
|
||||
(0xffffffff & scsi_get_lba(cmd)));
|
||||
|
||||
if (!qla2x00_hba_err_chk_enabled(sp))
|
||||
break;
|
||||
pkt->ref_tag = cpu_to_le32(scsi_prot_ref_tag(cmd));
|
||||
|
||||
if (cmd->prot_flags & SCSI_PROT_REF_CHECK &&
|
||||
qla2x00_hba_err_chk_enabled(sp)) {
|
||||
pkt->ref_tag_mask[0] = 0xff;
|
||||
pkt->ref_tag_mask[1] = 0xff;
|
||||
pkt->ref_tag_mask[2] = 0xff;
|
||||
pkt->ref_tag_mask[3] = 0xff;
|
||||
break;
|
||||
|
||||
/*
|
||||
* For TYPE 2 protection: 16 bit GUARD + 32 bit REF tag has to
|
||||
* match LBA in CDB + N
|
||||
*/
|
||||
case SCSI_PROT_DIF_TYPE2:
|
||||
pkt->app_tag = cpu_to_le16(0);
|
||||
pkt->app_tag_mask[0] = 0x0;
|
||||
pkt->app_tag_mask[1] = 0x0;
|
||||
|
||||
pkt->ref_tag = cpu_to_le32((uint32_t)
|
||||
(0xffffffff & scsi_get_lba(cmd)));
|
||||
|
||||
if (!qla2x00_hba_err_chk_enabled(sp))
|
||||
break;
|
||||
|
||||
/* enable ALL bytes of the ref tag */
|
||||
pkt->ref_tag_mask[0] = 0xff;
|
||||
pkt->ref_tag_mask[1] = 0xff;
|
||||
pkt->ref_tag_mask[2] = 0xff;
|
||||
pkt->ref_tag_mask[3] = 0xff;
|
||||
break;
|
||||
|
||||
/* For Type 3 protection: 16 bit GUARD only */
|
||||
case SCSI_PROT_DIF_TYPE3:
|
||||
pkt->ref_tag_mask[0] = pkt->ref_tag_mask[1] =
|
||||
pkt->ref_tag_mask[2] = pkt->ref_tag_mask[3] =
|
||||
0x00;
|
||||
break;
|
||||
|
||||
/*
|
||||
* For TYpe 1 protection: 16 bit GUARD tag, 32 bit REF tag, and
|
||||
* 16 bit app tag.
|
||||
*/
|
||||
case SCSI_PROT_DIF_TYPE1:
|
||||
pkt->ref_tag = cpu_to_le32((uint32_t)
|
||||
(0xffffffff & scsi_get_lba(cmd)));
|
||||
pkt->app_tag = cpu_to_le16(0);
|
||||
pkt->app_tag_mask[0] = 0x0;
|
||||
pkt->app_tag_mask[1] = 0x0;
|
||||
|
||||
if (!qla2x00_hba_err_chk_enabled(sp))
|
||||
break;
|
||||
|
||||
/* enable ALL bytes of the ref tag */
|
||||
pkt->ref_tag_mask[0] = 0xff;
|
||||
pkt->ref_tag_mask[1] = 0xff;
|
||||
pkt->ref_tag_mask[2] = 0xff;
|
||||
pkt->ref_tag_mask[3] = 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
pkt->app_tag = cpu_to_le16(0);
|
||||
pkt->app_tag_mask[0] = 0x0;
|
||||
pkt->app_tag_mask[1] = 0x0;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -905,7 +852,7 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
|
||||
memset(&sgx, 0, sizeof(struct qla2_sgx));
|
||||
if (sp) {
|
||||
cmd = GET_CMD_SP(sp);
|
||||
prot_int = cmd->device->sector_size;
|
||||
prot_int = scsi_prot_interval(cmd);
|
||||
|
||||
sgx.tot_bytes = scsi_bufflen(cmd);
|
||||
sgx.cur_sg = scsi_sglist(cmd);
|
||||
@@ -1611,6 +1558,9 @@ qla24xx_start_scsi(srb_t *sp)
|
||||
struct scsi_qla_host *vha = sp->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
if (sp->fcport->edif.enable && (sp->fcport->flags & FCF_FCSP_DEVICE))
|
||||
return qla28xx_start_scsi_edif(sp);
|
||||
|
||||
/* Setup device pointers. */
|
||||
req = vha->req;
|
||||
rsp = req->rsp;
|
||||
@@ -1716,6 +1666,7 @@ qla24xx_start_scsi(srb_t *sp)
|
||||
} else
|
||||
req->ring_ptr++;
|
||||
|
||||
sp->qpair->cmd_cnt++;
|
||||
sp->flags |= SRB_DMA_VALID;
|
||||
|
||||
/* Set chip new ring index. */
|
||||
@@ -1918,6 +1869,7 @@ qla24xx_dif_start_scsi(srb_t *sp)
|
||||
} else
|
||||
req->ring_ptr++;
|
||||
|
||||
sp->qpair->cmd_cnt++;
|
||||
/* Set chip new ring index. */
|
||||
wrt_reg_dword(req->req_q_in, req->ring_index);
|
||||
|
||||
@@ -1967,6 +1919,9 @@ qla2xxx_start_scsi_mq(srb_t *sp)
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct qla_qpair *qpair = sp->qpair;
|
||||
|
||||
if (sp->fcport->edif.enable && (sp->fcport->flags & FCF_FCSP_DEVICE))
|
||||
return qla28xx_start_scsi_edif(sp);
|
||||
|
||||
/* Acquire qpair specific lock */
|
||||
spin_lock_irqsave(&qpair->qp_lock, flags);
|
||||
|
||||
@@ -2074,6 +2029,7 @@ qla2xxx_start_scsi_mq(srb_t *sp)
|
||||
} else
|
||||
req->ring_ptr++;
|
||||
|
||||
sp->qpair->cmd_cnt++;
|
||||
sp->flags |= SRB_DMA_VALID;
|
||||
|
||||
/* Set chip new ring index. */
|
||||
@@ -2290,6 +2246,7 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp)
|
||||
} else
|
||||
req->ring_ptr++;
|
||||
|
||||
sp->qpair->cmd_cnt++;
|
||||
/* Set chip new ring index. */
|
||||
wrt_reg_dword(req->req_q_in, req->ring_index);
|
||||
|
||||
@@ -2468,6 +2425,12 @@ qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio)
|
||||
logio->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
|
||||
if (lio->u.logio.flags & SRB_LOGIN_SKIP_PRLI)
|
||||
logio->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
|
||||
if (lio->u.logio.flags & SRB_LOGIN_FCSP) {
|
||||
logio->control_flags |=
|
||||
cpu_to_le16(LCF_COMMON_FEAT | LCF_SKIP_PRLI);
|
||||
logio->io_parameter[0] =
|
||||
cpu_to_le32(LIO_COMM_FEAT_FCSP | LIO_COMM_FEAT_CIO);
|
||||
}
|
||||
}
|
||||
logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
|
||||
logio->port_id[0] = sp->fcport->d_id.b.al_pa;
|
||||
@@ -2791,7 +2754,10 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
|
||||
els_iocb->s_id[0] = vha->d_id.b.domain;
|
||||
|
||||
if (elsio->u.els_logo.els_cmd == ELS_DCMD_PLOGI) {
|
||||
els_iocb->control_flags = 0;
|
||||
if (vha->hw->flags.edif_enabled)
|
||||
els_iocb->control_flags = cpu_to_le16(ECF_SEC_LOGIN);
|
||||
else
|
||||
els_iocb->control_flags = 0;
|
||||
els_iocb->tx_byte_count = els_iocb->tx_len =
|
||||
cpu_to_le32(sizeof(struct els_plogi_payload));
|
||||
put_unaligned_le64(elsio->u.els_plogi.els_plogi_pyld_dma,
|
||||
@@ -2808,7 +2774,6 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
|
||||
(uint8_t *)els_iocb,
|
||||
sizeof(*els_iocb));
|
||||
} else {
|
||||
els_iocb->control_flags = cpu_to_le16(1 << 13);
|
||||
els_iocb->tx_byte_count =
|
||||
cpu_to_le32(sizeof(struct els_logo_payload));
|
||||
put_unaligned_le64(elsio->u.els_logo.els_logo_pyld_dma,
|
||||
@@ -3032,7 +2997,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||
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);
|
||||
"%s Enter: PLOGI portid=%06x\n", __func__, fcport->d_id.b24);
|
||||
|
||||
sp->type = SRB_ELS_DCMD;
|
||||
sp->name = "ELS_DCMD";
|
||||
@@ -3075,6 +3040,13 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||
elsio->u.els_plogi.els_cmd = els_opcode;
|
||||
elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode;
|
||||
|
||||
if (els_opcode == ELS_DCMD_PLOGI && vha->hw->flags.edif_enabled &&
|
||||
vha->e_dbell.db_flags & EDB_ACTIVE) {
|
||||
struct fc_els_flogi *p = ptr;
|
||||
|
||||
p->fl_csp.sp_features |= cpu_to_be16(FC_SP_FT_SEC);
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -3108,6 +3080,43 @@ done:
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* it is assume qpair lock is held */
|
||||
void qla_els_pt_iocb(struct scsi_qla_host *vha,
|
||||
struct els_entry_24xx *els_iocb,
|
||||
struct qla_els_pt_arg *a)
|
||||
{
|
||||
els_iocb->entry_type = ELS_IOCB_TYPE;
|
||||
els_iocb->entry_count = 1;
|
||||
els_iocb->sys_define = 0;
|
||||
els_iocb->entry_status = 0;
|
||||
els_iocb->handle = QLA_SKIP_HANDLE;
|
||||
els_iocb->nport_handle = a->nport_handle;
|
||||
els_iocb->rx_xchg_address = a->rx_xchg_address;
|
||||
els_iocb->tx_dsd_count = cpu_to_le16(1);
|
||||
els_iocb->vp_index = a->vp_idx;
|
||||
els_iocb->sof_type = EST_SOFI3;
|
||||
els_iocb->rx_dsd_count = cpu_to_le16(0);
|
||||
els_iocb->opcode = a->els_opcode;
|
||||
|
||||
els_iocb->d_id[0] = a->did.b.al_pa;
|
||||
els_iocb->d_id[1] = a->did.b.area;
|
||||
els_iocb->d_id[2] = a->did.b.domain;
|
||||
/* For SID the byte order is different than DID */
|
||||
els_iocb->s_id[1] = vha->d_id.b.al_pa;
|
||||
els_iocb->s_id[2] = vha->d_id.b.area;
|
||||
els_iocb->s_id[0] = vha->d_id.b.domain;
|
||||
|
||||
els_iocb->control_flags = cpu_to_le16(a->control_flags);
|
||||
|
||||
els_iocb->tx_byte_count = cpu_to_le32(a->tx_byte_count);
|
||||
els_iocb->tx_len = cpu_to_le32(a->tx_len);
|
||||
put_unaligned_le64(a->tx_addr, &els_iocb->tx_address);
|
||||
|
||||
els_iocb->rx_byte_count = cpu_to_le32(a->rx_byte_count);
|
||||
els_iocb->rx_len = cpu_to_le32(a->rx_len);
|
||||
put_unaligned_le64(a->rx_addr, &els_iocb->rx_address);
|
||||
}
|
||||
|
||||
static void
|
||||
qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
|
||||
{
|
||||
@@ -3702,6 +3711,16 @@ static void qla2x00_send_notify_ack_iocb(srb_t *sp,
|
||||
nack->u.isp24.srr_reject_code = 0;
|
||||
nack->u.isp24.srr_reject_code_expl = 0;
|
||||
nack->u.isp24.vp_index = ntfy->u.isp24.vp_index;
|
||||
|
||||
if (ntfy->u.isp24.status_subcode == ELS_PLOGI &&
|
||||
(le16_to_cpu(ntfy->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP) &&
|
||||
sp->vha->hw->flags.edif_enabled) {
|
||||
ql_dbg(ql_dbg_disc, sp->vha, 0x3074,
|
||||
"%s PLOGI NACK sent with FC SECURITY bit, hdl=%x, loopid=%x, to pid %06x\n",
|
||||
sp->name, sp->handle, sp->fcport->loop_id,
|
||||
sp->fcport->d_id.b24);
|
||||
nack->u.isp24.flags |= cpu_to_le16(NOTIFY_ACK_FLAGS_FCSP);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3806,6 +3825,10 @@ qla2x00_start_sp(srb_t *sp)
|
||||
case SRB_ELS_CMD_HST:
|
||||
qla24xx_els_iocb(sp, pkt);
|
||||
break;
|
||||
case SRB_ELS_CMD_HST_NOLOGIN:
|
||||
qla_els_pt_iocb(sp->vha, pkt, &sp->u.bsg_cmd.u.els_arg);
|
||||
((struct els_entry_24xx *)pkt)->handle = sp->handle;
|
||||
break;
|
||||
case SRB_CT_CMD:
|
||||
IS_FWI2_CAPABLE(ha) ?
|
||||
qla24xx_ct_iocb(sp, pkt) :
|
||||
@@ -3853,6 +3876,12 @@ qla2x00_start_sp(srb_t *sp)
|
||||
case SRB_PRLO_CMD:
|
||||
qla24xx_prlo_iocb(sp, pkt);
|
||||
break;
|
||||
case SRB_SA_UPDATE:
|
||||
qla24xx_sa_update_iocb(sp, pkt);
|
||||
break;
|
||||
case SRB_SA_REPLACE:
|
||||
qla24xx_sa_replace_iocb(sp, pkt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
+344
-30
@@ -181,6 +181,149 @@ qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
|
||||
dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_els), rsp_els, dma);
|
||||
}
|
||||
|
||||
/**
|
||||
* __qla_consume_iocb - this routine is used to tell fw driver has processed
|
||||
* or consumed the head IOCB along with the continuation IOCB's from the
|
||||
* provided respond queue.
|
||||
* @vha: host adapter pointer
|
||||
* @pkt: pointer to current packet. On return, this pointer shall move
|
||||
* to the next packet.
|
||||
* @rsp: respond queue pointer.
|
||||
*
|
||||
* it is assumed pkt is the head iocb, not the continuation iocbk
|
||||
*/
|
||||
void __qla_consume_iocb(struct scsi_qla_host *vha,
|
||||
void **pkt, struct rsp_que **rsp)
|
||||
{
|
||||
struct rsp_que *rsp_q = *rsp;
|
||||
response_t *new_pkt;
|
||||
uint16_t entry_count_remaining;
|
||||
struct purex_entry_24xx *purex = *pkt;
|
||||
|
||||
entry_count_remaining = purex->entry_count;
|
||||
while (entry_count_remaining > 0) {
|
||||
new_pkt = rsp_q->ring_ptr;
|
||||
*pkt = new_pkt;
|
||||
|
||||
rsp_q->ring_index++;
|
||||
if (rsp_q->ring_index == rsp_q->length) {
|
||||
rsp_q->ring_index = 0;
|
||||
rsp_q->ring_ptr = rsp_q->ring;
|
||||
} else {
|
||||
rsp_q->ring_ptr++;
|
||||
}
|
||||
|
||||
new_pkt->signature = RESPONSE_PROCESSED;
|
||||
/* flush signature */
|
||||
wmb();
|
||||
--entry_count_remaining;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __qla_copy_purex_to_buffer - extract ELS payload from Purex IOCB
|
||||
* and save to provided buffer
|
||||
* @vha: host adapter pointer
|
||||
* @pkt: pointer Purex IOCB
|
||||
* @rsp: respond queue
|
||||
* @buf: extracted ELS payload copy here
|
||||
* @buf_len: buffer length
|
||||
*/
|
||||
int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha,
|
||||
void **pkt, struct rsp_que **rsp, u8 *buf, u32 buf_len)
|
||||
{
|
||||
struct purex_entry_24xx *purex = *pkt;
|
||||
struct rsp_que *rsp_q = *rsp;
|
||||
sts_cont_entry_t *new_pkt;
|
||||
uint16_t no_bytes = 0, total_bytes = 0, pending_bytes = 0;
|
||||
uint16_t buffer_copy_offset = 0;
|
||||
uint16_t entry_count_remaining;
|
||||
u16 tpad;
|
||||
|
||||
entry_count_remaining = purex->entry_count;
|
||||
total_bytes = (le16_to_cpu(purex->frame_size) & 0x0FFF)
|
||||
- PURX_ELS_HEADER_SIZE;
|
||||
|
||||
/*
|
||||
* end of payload may not end in 4bytes boundary. Need to
|
||||
* round up / pad for room to swap, before saving data
|
||||
*/
|
||||
tpad = roundup(total_bytes, 4);
|
||||
|
||||
if (buf_len < tpad) {
|
||||
ql_dbg(ql_dbg_async, vha, 0x5084,
|
||||
"%s buffer is too small %d < %d\n",
|
||||
__func__, buf_len, tpad);
|
||||
__qla_consume_iocb(vha, pkt, rsp);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
pending_bytes = total_bytes = tpad;
|
||||
no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ?
|
||||
sizeof(purex->els_frame_payload) : pending_bytes;
|
||||
|
||||
memcpy(buf, &purex->els_frame_payload[0], no_bytes);
|
||||
buffer_copy_offset += no_bytes;
|
||||
pending_bytes -= no_bytes;
|
||||
--entry_count_remaining;
|
||||
|
||||
((response_t *)purex)->signature = RESPONSE_PROCESSED;
|
||||
/* flush signature */
|
||||
wmb();
|
||||
|
||||
do {
|
||||
while ((total_bytes > 0) && (entry_count_remaining > 0)) {
|
||||
new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
|
||||
*pkt = new_pkt;
|
||||
|
||||
if (new_pkt->entry_type != STATUS_CONT_TYPE) {
|
||||
ql_log(ql_log_warn, vha, 0x507a,
|
||||
"Unexpected IOCB type, partial data 0x%x\n",
|
||||
buffer_copy_offset);
|
||||
break;
|
||||
}
|
||||
|
||||
rsp_q->ring_index++;
|
||||
if (rsp_q->ring_index == rsp_q->length) {
|
||||
rsp_q->ring_index = 0;
|
||||
rsp_q->ring_ptr = rsp_q->ring;
|
||||
} else {
|
||||
rsp_q->ring_ptr++;
|
||||
}
|
||||
no_bytes = (pending_bytes > sizeof(new_pkt->data)) ?
|
||||
sizeof(new_pkt->data) : pending_bytes;
|
||||
if ((buffer_copy_offset + no_bytes) <= total_bytes) {
|
||||
memcpy((buf + buffer_copy_offset), new_pkt->data,
|
||||
no_bytes);
|
||||
buffer_copy_offset += no_bytes;
|
||||
pending_bytes -= no_bytes;
|
||||
--entry_count_remaining;
|
||||
} else {
|
||||
ql_log(ql_log_warn, vha, 0x5044,
|
||||
"Attempt to copy more that we got, optimizing..%x\n",
|
||||
buffer_copy_offset);
|
||||
memcpy((buf + buffer_copy_offset), new_pkt->data,
|
||||
total_bytes - buffer_copy_offset);
|
||||
}
|
||||
|
||||
((response_t *)new_pkt)->signature = RESPONSE_PROCESSED;
|
||||
/* flush signature */
|
||||
wmb();
|
||||
}
|
||||
|
||||
if (pending_bytes != 0 || entry_count_remaining != 0) {
|
||||
ql_log(ql_log_fatal, vha, 0x508b,
|
||||
"Dropping partial Data, underrun bytes = 0x%x, entry cnts 0x%x\n",
|
||||
total_bytes, entry_count_remaining);
|
||||
return -EIO;
|
||||
}
|
||||
} while (entry_count_remaining > 0);
|
||||
|
||||
be32_to_cpu_array((u32 *)buf, (__be32 *)buf, total_bytes >> 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
|
||||
* @irq: interrupt number
|
||||
@@ -517,7 +660,7 @@ const char *
|
||||
qla2x00_get_link_speed_str(struct qla_hw_data *ha, uint16_t speed)
|
||||
{
|
||||
static const char *const link_speeds[] = {
|
||||
"1", "2", "?", "4", "8", "16", "32", "10"
|
||||
"1", "2", "?", "4", "8", "16", "32", "64", "10"
|
||||
};
|
||||
#define QLA_LAST_SPEED (ARRAY_SIZE(link_speeds) - 1)
|
||||
|
||||
@@ -1739,6 +1882,9 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
|
||||
srb_t *sp;
|
||||
uint16_t index;
|
||||
|
||||
if (pkt->handle == QLA_SKIP_HANDLE)
|
||||
return NULL;
|
||||
|
||||
index = LSW(pkt->handle);
|
||||
if (index >= req->num_outstanding_cmds) {
|
||||
ql_log(ql_log_warn, vha, 0x5031,
|
||||
@@ -1983,7 +2129,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
}
|
||||
|
||||
static void
|
||||
qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
qla24xx_els_ct_entry(scsi_qla_host_t *v, struct req_que *req,
|
||||
struct sts_entry_24xx *pkt, int iocb_type)
|
||||
{
|
||||
struct els_sts_entry_24xx *ese = (struct els_sts_entry_24xx *)pkt;
|
||||
@@ -1994,18 +2140,58 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
struct fc_bsg_reply *bsg_reply;
|
||||
uint16_t comp_status;
|
||||
uint32_t fw_status[3];
|
||||
int res;
|
||||
int res, logit = 1;
|
||||
struct srb_iocb *els;
|
||||
uint n;
|
||||
scsi_qla_host_t *vha;
|
||||
struct els_sts_entry_24xx *e = (struct els_sts_entry_24xx *)pkt;
|
||||
|
||||
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
|
||||
sp = qla2x00_get_sp_from_handle(v, func, req, pkt);
|
||||
if (!sp)
|
||||
return;
|
||||
bsg_job = sp->u.bsg_job;
|
||||
vha = sp->vha;
|
||||
|
||||
type = NULL;
|
||||
|
||||
comp_status = fw_status[0] = le16_to_cpu(pkt->comp_status);
|
||||
fw_status[1] = le32_to_cpu(((struct els_sts_entry_24xx *)pkt)->error_subcode_1);
|
||||
fw_status[2] = le32_to_cpu(((struct els_sts_entry_24xx *)pkt)->error_subcode_2);
|
||||
|
||||
switch (sp->type) {
|
||||
case SRB_ELS_CMD_RPT:
|
||||
case SRB_ELS_CMD_HST:
|
||||
type = "rpt hst";
|
||||
break;
|
||||
case SRB_ELS_CMD_HST_NOLOGIN:
|
||||
type = "els";
|
||||
{
|
||||
struct els_entry_24xx *els = (void *)pkt;
|
||||
struct qla_bsg_auth_els_request *p =
|
||||
(struct qla_bsg_auth_els_request *)bsg_job->request;
|
||||
|
||||
ql_dbg(ql_dbg_user, vha, 0x700f,
|
||||
"%s %s. portid=%02x%02x%02x status %x xchg %x bsg ptr %p\n",
|
||||
__func__, sc_to_str(p->e.sub_cmd),
|
||||
e->d_id[2], e->d_id[1], e->d_id[0],
|
||||
comp_status, p->e.extra_rx_xchg_address, bsg_job);
|
||||
|
||||
if (!(le16_to_cpu(els->control_flags) & ECF_PAYLOAD_DESCR_MASK)) {
|
||||
if (sp->remap.remapped) {
|
||||
n = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
||||
bsg_job->reply_payload.sg_cnt,
|
||||
sp->remap.rsp.buf,
|
||||
sp->remap.rsp.len);
|
||||
ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x700e,
|
||||
"%s: SG copied %x of %x\n",
|
||||
__func__, n, sp->remap.rsp.len);
|
||||
} else {
|
||||
ql_dbg(ql_dbg_user, vha, 0x700f,
|
||||
"%s: NOT REMAPPED (error)...!!!\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SRB_CT_CMD:
|
||||
type = "ct pass-through";
|
||||
@@ -2035,10 +2221,6 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
return;
|
||||
}
|
||||
|
||||
comp_status = fw_status[0] = le16_to_cpu(pkt->comp_status);
|
||||
fw_status[1] = le32_to_cpu(ese->error_subcode_1);
|
||||
fw_status[2] = le32_to_cpu(ese->error_subcode_2);
|
||||
|
||||
if (iocb_type == ELS_IOCB_TYPE) {
|
||||
els = &sp->u.iocb_cmd;
|
||||
els->u.els_plogi.fw_status[0] = cpu_to_le32(fw_status[0]);
|
||||
@@ -2052,15 +2234,53 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
res = DID_OK << 16;
|
||||
els->u.els_plogi.len = cpu_to_le16(le32_to_cpu(
|
||||
ese->total_byte_count));
|
||||
|
||||
if (sp->remap.remapped &&
|
||||
((u8 *)sp->remap.rsp.buf)[0] == ELS_LS_ACC) {
|
||||
ql_dbg(ql_dbg_user, vha, 0x503f,
|
||||
"%s IOCB Done LS_ACC %02x%02x%02x -> %02x%02x%02x",
|
||||
__func__, e->s_id[0], e->s_id[2], e->s_id[1],
|
||||
e->d_id[2], e->d_id[1], e->d_id[0]);
|
||||
logit = 0;
|
||||
}
|
||||
|
||||
} else if (comp_status == CS_PORT_LOGGED_OUT) {
|
||||
els->u.els_plogi.len = 0;
|
||||
res = DID_IMM_RETRY << 16;
|
||||
qlt_schedule_sess_for_deletion(sp->fcport);
|
||||
} else {
|
||||
els->u.els_plogi.len = 0;
|
||||
res = DID_ERROR << 16;
|
||||
}
|
||||
|
||||
if (logit) {
|
||||
if (sp->remap.remapped &&
|
||||
((u8 *)sp->remap.rsp.buf)[0] == ELS_LS_RJT) {
|
||||
ql_dbg(ql_dbg_user, vha, 0x503f,
|
||||
"%s IOCB Done LS_RJT hdl=%x comp_status=0x%x\n",
|
||||
type, sp->handle, comp_status);
|
||||
|
||||
ql_dbg(ql_dbg_user, vha, 0x503f,
|
||||
"subcode 1=0x%x subcode 2=0x%x bytes=0x%x %02x%02x%02x -> %02x%02x%02x\n",
|
||||
fw_status[1], fw_status[2],
|
||||
le32_to_cpu(((struct els_sts_entry_24xx *)
|
||||
pkt)->total_byte_count),
|
||||
e->s_id[0], e->s_id[2], e->s_id[1],
|
||||
e->d_id[2], e->d_id[1], e->d_id[0]);
|
||||
} else {
|
||||
ql_log(ql_log_info, vha, 0x503f,
|
||||
"%s IOCB Done hdl=%x comp_status=0x%x\n",
|
||||
type, sp->handle, comp_status);
|
||||
ql_log(ql_log_info, vha, 0x503f,
|
||||
"subcode 1=0x%x subcode 2=0x%x bytes=0x%x %02x%02x%02x -> %02x%02x%02x\n",
|
||||
fw_status[1], fw_status[2],
|
||||
le32_to_cpu(((struct els_sts_entry_24xx *)
|
||||
pkt)->total_byte_count),
|
||||
e->s_id[0], e->s_id[2], e->s_id[1],
|
||||
e->d_id[2], e->d_id[1], e->d_id[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
ql_dbg(ql_dbg_disc, vha, 0x503f,
|
||||
"ELS IOCB Done -%s hdl=%x comp_status=0x%x error subcode 1=0x%x error subcode 2=0x%x total_byte=0x%x\n",
|
||||
type, sp->handle, comp_status, fw_status[1], fw_status[2],
|
||||
le32_to_cpu(ese->total_byte_count));
|
||||
goto els_ct_done;
|
||||
}
|
||||
|
||||
@@ -2119,6 +2339,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
struct srb_iocb *lio;
|
||||
uint16_t *data;
|
||||
uint32_t iop[2];
|
||||
int logit = 1;
|
||||
|
||||
sp = qla2x00_get_sp_from_handle(vha, func, req, logio);
|
||||
if (!sp)
|
||||
@@ -2165,6 +2386,10 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
if (sp->type != SRB_LOGIN_CMD)
|
||||
goto logio_done;
|
||||
|
||||
lio->u.logio.iop[1] = le32_to_cpu(logio->io_parameter[5]);
|
||||
if (le32_to_cpu(logio->io_parameter[5]) & LIO_COMM_FEAT_FCSP)
|
||||
fcport->flags |= FCF_FCSP_DEVICE;
|
||||
|
||||
iop[0] = le32_to_cpu(logio->io_parameter[0]);
|
||||
if (iop[0] & BIT_4) {
|
||||
fcport->port_type = FCT_TARGET;
|
||||
@@ -2192,9 +2417,11 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
case LSC_SCODE_PORTID_USED:
|
||||
data[0] = MBS_PORT_ID_USED;
|
||||
data[1] = LSW(iop[1]);
|
||||
logit = 0;
|
||||
break;
|
||||
case LSC_SCODE_NPORT_USED:
|
||||
data[0] = MBS_LOOP_ID_USED;
|
||||
logit = 0;
|
||||
break;
|
||||
case LSC_SCODE_CMD_FAILED:
|
||||
if (iop[1] == 0x0606) {
|
||||
@@ -2227,12 +2454,20 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
break;
|
||||
}
|
||||
|
||||
ql_log(ql_log_warn, sp->vha, 0x5037,
|
||||
"Async-%s failed: handle=%x pid=%06x wwpn=%8phC comp_status=%x iop0=%x iop1=%x\n",
|
||||
type, sp->handle, fcport->d_id.b24, fcport->port_name,
|
||||
le16_to_cpu(logio->comp_status),
|
||||
le32_to_cpu(logio->io_parameter[0]),
|
||||
le32_to_cpu(logio->io_parameter[1]));
|
||||
if (logit)
|
||||
ql_log(ql_log_warn, sp->vha, 0x5037, "Async-%s failed: "
|
||||
"handle=%x pid=%06x wwpn=%8phC comp_status=%x iop0=%x iop1=%x\n",
|
||||
type, sp->handle, fcport->d_id.b24, fcport->port_name,
|
||||
le16_to_cpu(logio->comp_status),
|
||||
le32_to_cpu(logio->io_parameter[0]),
|
||||
le32_to_cpu(logio->io_parameter[1]));
|
||||
else
|
||||
ql_dbg(ql_dbg_disc, sp->vha, 0x5037, "Async-%s failed: "
|
||||
"handle=%x pid=%06x wwpn=%8phC comp_status=%x iop0=%x iop1=%x\n",
|
||||
type, sp->handle, fcport->d_id.b24, fcport->port_name,
|
||||
le16_to_cpu(logio->comp_status),
|
||||
le32_to_cpu(logio->io_parameter[0]),
|
||||
le32_to_cpu(logio->io_parameter[1]));
|
||||
|
||||
logio_done:
|
||||
sp->done(sp, 0);
|
||||
@@ -2334,6 +2569,8 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
|
||||
if (unlikely(iocb->u.nvme.aen_op))
|
||||
atomic_dec(&sp->vha->hw->nvme_active_aen_cnt);
|
||||
else
|
||||
sp->qpair->cmd_completion_cnt++;
|
||||
|
||||
if (unlikely(comp_status != CS_COMPLETE))
|
||||
logit = 1;
|
||||
@@ -2438,6 +2675,15 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
case CS_PORT_UNAVAILABLE:
|
||||
case CS_PORT_LOGGED_OUT:
|
||||
fcport->nvme_flag |= NVME_FLAG_RESETTING;
|
||||
if (atomic_read(&fcport->state) == FCS_ONLINE) {
|
||||
ql_dbg(ql_dbg_disc, fcport->vha, 0x3021,
|
||||
"Port to be marked lost on fcport=%06x, current "
|
||||
"port state= %s comp_status %x.\n",
|
||||
fcport->d_id.b24, port_state_str[FCS_ONLINE],
|
||||
comp_status);
|
||||
|
||||
qlt_schedule_sess_for_deletion(fcport);
|
||||
}
|
||||
fallthrough;
|
||||
case CS_ABORTED:
|
||||
case CS_PORT_BUSY:
|
||||
@@ -2717,31 +2963,22 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
|
||||
|
||||
/* check guard */
|
||||
if (e_guard != a_guard) {
|
||||
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
|
||||
0x10, 0x1);
|
||||
set_driver_byte(cmd, DRIVER_SENSE);
|
||||
scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x1);
|
||||
set_host_byte(cmd, DID_ABORT);
|
||||
cmd->result |= SAM_STAT_CHECK_CONDITION;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check ref tag */
|
||||
if (e_ref_tag != a_ref_tag) {
|
||||
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
|
||||
0x10, 0x3);
|
||||
set_driver_byte(cmd, DRIVER_SENSE);
|
||||
scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x3);
|
||||
set_host_byte(cmd, DID_ABORT);
|
||||
cmd->result |= SAM_STAT_CHECK_CONDITION;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check appl tag */
|
||||
if (e_app_tag != a_app_tag) {
|
||||
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
|
||||
0x10, 0x2);
|
||||
set_driver_byte(cmd, DRIVER_SENSE);
|
||||
scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x2);
|
||||
set_host_byte(cmd, DID_ABORT);
|
||||
cmd->result |= SAM_STAT_CHECK_CONDITION;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -3000,6 +3237,9 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
||||
}
|
||||
|
||||
/* Fast path completion. */
|
||||
qla_chk_edif_rx_sa_delete_pending(vha, sp, sts24);
|
||||
sp->qpair->cmd_completion_cnt++;
|
||||
|
||||
if (comp_status == CS_COMPLETE && scsi_status == 0) {
|
||||
qla2x00_process_completed_request(vha, req, handle);
|
||||
|
||||
@@ -3394,6 +3634,7 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
|
||||
}
|
||||
break;
|
||||
|
||||
case SA_UPDATE_IOCB_TYPE:
|
||||
case ABTS_RESP_24XX:
|
||||
case CTIO_TYPE7:
|
||||
case CTIO_CRC2:
|
||||
@@ -3480,6 +3721,63 @@ void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha,
|
||||
sp->done(sp, comp_status);
|
||||
}
|
||||
|
||||
/**
|
||||
* qla_chk_cont_iocb_avail - check for all continuation iocbs are available
|
||||
* before iocb processing can start.
|
||||
* @vha: host adapter pointer
|
||||
* @rsp: respond queue
|
||||
* @pkt: head iocb describing how many continuation iocb
|
||||
* Return: 0 all iocbs has arrived, xx- all iocbs have not arrived.
|
||||
*/
|
||||
static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha,
|
||||
struct rsp_que *rsp, response_t *pkt)
|
||||
{
|
||||
int start_pkt_ring_index, end_pkt_ring_index, n_ring_index;
|
||||
response_t *end_pkt;
|
||||
int rc = 0;
|
||||
u32 rsp_q_in;
|
||||
|
||||
if (pkt->entry_count == 1)
|
||||
return rc;
|
||||
|
||||
/* ring_index was pre-increment. set it back to current pkt */
|
||||
if (rsp->ring_index == 0)
|
||||
start_pkt_ring_index = rsp->length - 1;
|
||||
else
|
||||
start_pkt_ring_index = rsp->ring_index - 1;
|
||||
|
||||
if ((start_pkt_ring_index + pkt->entry_count) >= rsp->length)
|
||||
end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count -
|
||||
rsp->length - 1;
|
||||
else
|
||||
end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count - 1;
|
||||
|
||||
end_pkt = rsp->ring + end_pkt_ring_index;
|
||||
|
||||
/* next pkt = end_pkt + 1 */
|
||||
n_ring_index = end_pkt_ring_index + 1;
|
||||
if (n_ring_index >= rsp->length)
|
||||
n_ring_index = 0;
|
||||
|
||||
rsp_q_in = rsp->qpair->use_shadow_reg ? *rsp->in_ptr :
|
||||
rd_reg_dword(rsp->rsp_q_in);
|
||||
|
||||
/* rsp_q_in is either wrapped or pointing beyond endpkt */
|
||||
if ((rsp_q_in < start_pkt_ring_index && rsp_q_in < n_ring_index) ||
|
||||
rsp_q_in >= n_ring_index)
|
||||
/* all IOCBs arrived. */
|
||||
rc = 0;
|
||||
else
|
||||
rc = -EIO;
|
||||
|
||||
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x5091,
|
||||
"%s - ring %p pkt %p end pkt %p entry count %#x rsp_q_in %d rc %d\n",
|
||||
__func__, rsp->ring, pkt, end_pkt, pkt->entry_count,
|
||||
rsp_q_in, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* qla24xx_process_response_queue() - Process response queue entries.
|
||||
* @vha: SCSI driver HA context
|
||||
@@ -3621,12 +3919,26 @@ process_err:
|
||||
qla27xx_process_purex_fpin);
|
||||
break;
|
||||
|
||||
case ELS_AUTH_ELS:
|
||||
if (qla_chk_cont_iocb_avail(vha, rsp, (response_t *)pkt)) {
|
||||
ql_dbg(ql_dbg_init, vha, 0x5091,
|
||||
"Defer processing ELS opcode %#x...\n",
|
||||
purex_entry->els_frame_payload[3]);
|
||||
return;
|
||||
}
|
||||
qla24xx_auth_els(vha, (void **)&pkt, &rsp);
|
||||
break;
|
||||
default:
|
||||
ql_log(ql_log_warn, vha, 0x509c,
|
||||
"Discarding ELS Request opcode 0x%x\n",
|
||||
purex_entry->els_frame_payload[3]);
|
||||
}
|
||||
break;
|
||||
case SA_UPDATE_IOCB_TYPE:
|
||||
qla28xx_sa_update_iocb_entry(vha, rsp->req,
|
||||
(struct sa_update_28xx *)pkt);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Type Not Supported. */
|
||||
ql_dbg(ql_dbg_async, vha, 0x5042,
|
||||
@@ -4323,6 +4635,8 @@ skip_msi:
|
||||
ql_dbg(ql_dbg_init, vha, 0x0125,
|
||||
"INTa mode: Enabled.\n");
|
||||
ha->flags.mr_intr_valid = 1;
|
||||
/* Set max_qpair to 0, as MSI-X and MSI in not enabled */
|
||||
ha->max_qpairs = 0;
|
||||
}
|
||||
|
||||
clear_risc_ints:
|
||||
|
||||
@@ -663,6 +663,7 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
|
||||
}
|
||||
|
||||
#define NVME_ENABLE_FLAG BIT_3
|
||||
#define EDIF_HW_SUPPORT BIT_10
|
||||
|
||||
/*
|
||||
* qla2x00_execute_fw
|
||||
@@ -739,7 +740,7 @@ again:
|
||||
mcp->mb[11] |= EXE_FW_FORCE_SEMAPHORE;
|
||||
|
||||
mcp->out_mb |= MBX_4 | MBX_3 | MBX_2 | MBX_1 | MBX_11;
|
||||
mcp->in_mb |= MBX_3 | MBX_2 | MBX_1;
|
||||
mcp->in_mb |= MBX_5 | MBX_3 | MBX_2 | MBX_1;
|
||||
} else {
|
||||
mcp->mb[1] = LSW(risc_addr);
|
||||
mcp->out_mb |= MBX_1;
|
||||
@@ -795,6 +796,12 @@ again:
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_QLA28XX(ha) && (mcp->mb[5] & EDIF_HW_SUPPORT)) {
|
||||
ha->flags.edif_hw = 1;
|
||||
ql_log(ql_log_info, vha, 0xffff,
|
||||
"%s: edif HW\n", __func__);
|
||||
}
|
||||
|
||||
done:
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
|
||||
"Done %s.\n", __func__);
|
||||
@@ -1130,6 +1137,13 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
|
||||
ha->fw_attributes_ext[0]);
|
||||
vha->flags.nvme2_enabled = 1;
|
||||
}
|
||||
|
||||
if (IS_QLA28XX(ha) && ha->flags.edif_hw && ql2xsecenable &&
|
||||
(ha->fw_attributes_ext[0] & FW_ATTR_EXT0_EDIF)) {
|
||||
ha->flags.edif_enabled = 1;
|
||||
ql_log(ql_log_info, vha, 0xffff,
|
||||
"%s: edif is enabled\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
|
||||
@@ -3231,7 +3245,7 @@ qla24xx_abort_command(srb_t *sp)
|
||||
if (sp->qpair)
|
||||
req = sp->qpair->req;
|
||||
else
|
||||
return QLA_FUNCTION_FAILED;
|
||||
return QLA_ERR_NO_QPAIR;
|
||||
|
||||
if (ql2xasynctmfenable)
|
||||
return qla24xx_async_abort_command(sp);
|
||||
@@ -3244,7 +3258,7 @@ qla24xx_abort_command(srb_t *sp)
|
||||
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
|
||||
if (handle == req->num_outstanding_cmds) {
|
||||
/* Command not found. */
|
||||
return QLA_FUNCTION_FAILED;
|
||||
return QLA_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
abt = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
|
||||
@@ -4035,6 +4049,10 @@ 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->login_retry = vha->hw->login_retry_count;
|
||||
fcport->fc4_type = FS_FC4TYPE_FCP;
|
||||
if (vha->flags.nvme_enabled)
|
||||
fcport->fc4_type |= FS_FC4TYPE_NVME;
|
||||
|
||||
if (wwn_to_u64(vha->port_name) >
|
||||
wwn_to_u64(fcport->port_name)) {
|
||||
@@ -4172,6 +4190,16 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
|
||||
rptid_entry->u.f2.remote_nport_id[1];
|
||||
fcport->d_id.b.al_pa =
|
||||
rptid_entry->u.f2.remote_nport_id[0];
|
||||
|
||||
/*
|
||||
* For the case where remote port sending PRLO, FW
|
||||
* sends up RIDA Format 2 as an indication of session
|
||||
* loss. In other word, FW state change from PRLI
|
||||
* complete back to PLOGI complete. Delete the
|
||||
* session and let relogin drive the reconnect.
|
||||
*/
|
||||
if (atomic_read(&fcport->state) == FCS_ONLINE)
|
||||
qlt_schedule_sess_for_deletion(fcport);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4946,7 +4974,7 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
|
||||
return rval;
|
||||
}
|
||||
|
||||
#define PUREX_CMD_COUNT 2
|
||||
#define PUREX_CMD_COUNT 4
|
||||
int
|
||||
qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
|
||||
{
|
||||
@@ -4954,6 +4982,7 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
uint8_t *els_cmd_map;
|
||||
uint8_t active_cnt = 0;
|
||||
dma_addr_t els_cmd_map_dma;
|
||||
uint8_t cmd_opcode[PUREX_CMD_COUNT];
|
||||
uint8_t i, index, purex_bit;
|
||||
@@ -4975,10 +5004,20 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
|
||||
}
|
||||
|
||||
/* List of Purex ELS */
|
||||
cmd_opcode[0] = ELS_FPIN;
|
||||
cmd_opcode[1] = ELS_RDP;
|
||||
if (ql2xrdpenable) {
|
||||
cmd_opcode[active_cnt] = ELS_RDP;
|
||||
active_cnt++;
|
||||
}
|
||||
if (ha->flags.scm_supported_f) {
|
||||
cmd_opcode[active_cnt] = ELS_FPIN;
|
||||
active_cnt++;
|
||||
}
|
||||
if (ha->flags.edif_enabled) {
|
||||
cmd_opcode[active_cnt] = ELS_AUTH_ELS;
|
||||
active_cnt++;
|
||||
}
|
||||
|
||||
for (i = 0; i < PUREX_CMD_COUNT; i++) {
|
||||
for (i = 0; i < active_cnt; i++) {
|
||||
index = cmd_opcode[i] / 8;
|
||||
purex_bit = cmd_opcode[i] % 8;
|
||||
els_cmd_map[index] |= 1 << purex_bit;
|
||||
@@ -6588,6 +6627,12 @@ 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;
|
||||
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2062,
|
||||
"%8phC SVC Param w3 %02x%02x",
|
||||
fcport->port_name,
|
||||
pd->prli_svc_param_word_3[1],
|
||||
pd->prli_svc_param_word_3[0]);
|
||||
|
||||
if (NVME_TARGET(vha->hw, fcport)) {
|
||||
fcport->port_type = FCT_NVME;
|
||||
if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0)
|
||||
@@ -6939,3 +6984,30 @@ ql26xx_led_config(scsi_qla_host_t *vha, uint16_t options, uint16_t *led)
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* qla_no_op_mb(): This MB is used to check if FW is still alive and
|
||||
* able to generate an interrupt. Otherwise, a timeout will trigger
|
||||
* FW dump + reset
|
||||
* @vha: host adapter pointer
|
||||
* Return: None
|
||||
*/
|
||||
void qla_no_op_mb(struct scsi_qla_host *vha)
|
||||
{
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
int rval;
|
||||
|
||||
memset(&mc, 0, sizeof(mc));
|
||||
mcp->mb[0] = 0; // noop cmd= 0
|
||||
mcp->out_mb = MBX_0;
|
||||
mcp->in_mb = MBX_0;
|
||||
mcp->tov = 5;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
|
||||
if (rval) {
|
||||
ql_dbg(ql_dbg_async, vha, 0x7071,
|
||||
"Failed %s %x\n", __func__, rval);
|
||||
}
|
||||
}
|
||||
|
||||
+32
-19
@@ -65,7 +65,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
|
||||
uint16_t vp_id;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
unsigned long flags = 0;
|
||||
u8 i;
|
||||
u32 i, bailout;
|
||||
|
||||
mutex_lock(&ha->vport_lock);
|
||||
/*
|
||||
@@ -75,21 +75,29 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
|
||||
* ensures no active vp_list traversal while the vport is removed
|
||||
* from the queue)
|
||||
*/
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (wait_event_timeout(vha->vref_waitq,
|
||||
!atomic_read(&vha->vref_count), HZ) > 0)
|
||||
break;
|
||||
}
|
||||
bailout = 0;
|
||||
for (i = 0; i < 500; i++) {
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
if (atomic_read(&vha->vref_count) == 0) {
|
||||
list_del(&vha->list);
|
||||
qlt_update_vp_map(vha, RESET_VP_IDX);
|
||||
bailout = 1;
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
if (atomic_read(&vha->vref_count)) {
|
||||
ql_dbg(ql_dbg_vport, vha, 0xfffa,
|
||||
"vha->vref_count=%u timeout\n", vha->vref_count.counter);
|
||||
vha->vref_count = (atomic_t)ATOMIC_INIT(0);
|
||||
if (bailout)
|
||||
break;
|
||||
else
|
||||
msleep(20);
|
||||
}
|
||||
if (!bailout) {
|
||||
ql_log(ql_log_info, vha, 0xfffa,
|
||||
"vha->vref_count=%u timeout\n", vha->vref_count.counter);
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
list_del(&vha->list);
|
||||
qlt_update_vp_map(vha, RESET_VP_IDX);
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
}
|
||||
list_del(&vha->list);
|
||||
qlt_update_vp_map(vha, RESET_VP_IDX);
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
|
||||
vp_id = vha->vp_idx;
|
||||
ha->num_vhosts--;
|
||||
@@ -158,6 +166,10 @@ qla24xx_disable_vp(scsi_qla_host_t *vha)
|
||||
int ret = QLA_SUCCESS;
|
||||
fc_port_t *fcport;
|
||||
|
||||
if (vha->hw->flags.edif_enabled)
|
||||
/* delete sessions and flush sa_indexes */
|
||||
qla2x00_wait_for_sess_deletion(vha);
|
||||
|
||||
if (vha->hw->flags.fw_started)
|
||||
ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
|
||||
|
||||
@@ -166,7 +178,8 @@ 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);
|
||||
if (!vha->hw->flags.edif_enabled)
|
||||
qla2x00_wait_for_sess_deletion(vha);
|
||||
|
||||
/* Remove port id from vp target map */
|
||||
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
|
||||
@@ -257,13 +270,13 @@ qla24xx_configure_vp(scsi_qla_host_t *vha)
|
||||
void
|
||||
qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
|
||||
{
|
||||
scsi_qla_host_t *vha;
|
||||
scsi_qla_host_t *vha, *tvp;
|
||||
struct qla_hw_data *ha = rsp->hw;
|
||||
int i = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
list_for_each_entry(vha, &ha->vp_list, list) {
|
||||
list_for_each_entry_safe(vha, tvp, &ha->vp_list, list) {
|
||||
if (vha->vp_idx) {
|
||||
if (test_bit(VPORT_DELETE, &vha->dpc_flags))
|
||||
continue;
|
||||
@@ -416,7 +429,7 @@ void
|
||||
qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
scsi_qla_host_t *vp;
|
||||
scsi_qla_host_t *vp, *tvp;
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (vha->vp_idx)
|
||||
@@ -430,7 +443,7 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
list_for_each_entry(vp, &ha->vp_list, list) {
|
||||
list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
|
||||
if (vp->vp_idx) {
|
||||
atomic_inc(&vp->vref_count);
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
|
||||
+48
-35
@@ -104,8 +104,9 @@ static int qla_nvme_alloc_queue(struct nvme_fc_local_port *lport,
|
||||
struct qla_hw_data *ha;
|
||||
struct qla_qpair *qpair;
|
||||
|
||||
if (!qidx)
|
||||
qidx++;
|
||||
/* Map admin queue and 1st IO queue to index 0 */
|
||||
if (qidx)
|
||||
qidx--;
|
||||
|
||||
vha = (struct scsi_qla_host *)lport->private;
|
||||
ha = vha->hw;
|
||||
@@ -121,19 +122,24 @@ static int qla_nvme_alloc_queue(struct nvme_fc_local_port *lport,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ha->queue_pair_map[qidx]) {
|
||||
*handle = ha->queue_pair_map[qidx];
|
||||
ql_log(ql_log_info, vha, 0x2121,
|
||||
"Returning existing qpair of %p for idx=%x\n",
|
||||
*handle, qidx);
|
||||
return 0;
|
||||
}
|
||||
/* Use base qpair if max_qpairs is 0 */
|
||||
if (!ha->max_qpairs) {
|
||||
qpair = ha->base_qpair;
|
||||
} else {
|
||||
if (ha->queue_pair_map[qidx]) {
|
||||
*handle = ha->queue_pair_map[qidx];
|
||||
ql_log(ql_log_info, vha, 0x2121,
|
||||
"Returning existing qpair of %p for idx=%x\n",
|
||||
*handle, qidx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
qpair = qla2xxx_create_qpair(vha, 5, vha->vp_idx, true);
|
||||
if (qpair == NULL) {
|
||||
ql_log(ql_log_warn, vha, 0x2122,
|
||||
"Failed to allocate qpair\n");
|
||||
return -EINVAL;
|
||||
qpair = qla2xxx_create_qpair(vha, 5, vha->vp_idx, true);
|
||||
if (!qpair) {
|
||||
ql_log(ql_log_warn, vha, 0x2122,
|
||||
"Failed to allocate qpair\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
*handle = qpair;
|
||||
|
||||
@@ -234,13 +240,13 @@ static void qla_nvme_abort_work(struct work_struct *work)
|
||||
srb_t *sp = priv->sp;
|
||||
fc_port_t *fcport = sp->fcport;
|
||||
struct qla_hw_data *ha = fcport->vha->hw;
|
||||
int rval;
|
||||
int rval, abts_done_called = 1;
|
||||
|
||||
ql_dbg(ql_dbg_io, fcport->vha, 0xffff,
|
||||
"%s called for sp=%p, hndl=%x on fcport=%p deleted=%d\n",
|
||||
__func__, sp, sp->handle, fcport, fcport->deleted);
|
||||
"%s called for sp=%p, hndl=%x on fcport=%p desc=%p deleted=%d\n",
|
||||
__func__, sp, sp->handle, fcport, sp->u.iocb_cmd.u.nvme.desc, fcport->deleted);
|
||||
|
||||
if (!ha->flags.fw_started || fcport->deleted)
|
||||
if (!ha->flags.fw_started || fcport->deleted == QLA_SESS_DELETED)
|
||||
goto out;
|
||||
|
||||
if (ha->flags.host_shutting_down) {
|
||||
@@ -258,12 +264,20 @@ static void qla_nvme_abort_work(struct work_struct *work)
|
||||
__func__, (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted",
|
||||
sp, sp->handle, fcport, rval);
|
||||
|
||||
/*
|
||||
* If async tmf is enabled, the abort callback is called only on
|
||||
* return codes QLA_SUCCESS and QLA_ERR_FROM_FW.
|
||||
*/
|
||||
if (ql2xasynctmfenable &&
|
||||
rval != QLA_SUCCESS && rval != QLA_ERR_FROM_FW)
|
||||
abts_done_called = 0;
|
||||
|
||||
/*
|
||||
* Returned before decreasing kref so that I/O requests
|
||||
* are waited until ABTS complete. This kref is decreased
|
||||
* at qla24xx_abort_sp_done function.
|
||||
*/
|
||||
if (ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(sp))
|
||||
if (abts_done_called && ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(sp))
|
||||
return;
|
||||
out:
|
||||
/* kref_get was done before work was schedule. */
|
||||
@@ -476,6 +490,10 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
|
||||
} else if (fd->io_dir == 0) {
|
||||
cmd_pkt->control_flags = 0;
|
||||
}
|
||||
|
||||
if (sp->fcport->edif.enable && fd->io_dir != 0)
|
||||
cmd_pkt->control_flags |= cpu_to_le16(CF_EN_EDIF);
|
||||
|
||||
/* Set BIT_13 of control flags for Async event */
|
||||
if (vha->flags.nvme2_enabled &&
|
||||
cmd->sqe.common.opcode == nvme_admin_async_event) {
|
||||
@@ -549,6 +567,10 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
|
||||
req->ring_ptr++;
|
||||
}
|
||||
|
||||
/* ignore nvme async cmd due to long timeout */
|
||||
if (!nvme->u.nvme.aen_op)
|
||||
sp->qpair->cmd_cnt++;
|
||||
|
||||
/* Set chip new ring index. */
|
||||
wrt_reg_dword(req->req_q_in, req->ring_index);
|
||||
|
||||
@@ -684,7 +706,7 @@ void qla_nvme_unregister_remote_port(struct fc_port *fcport)
|
||||
if (!IS_ENABLED(CONFIG_NVME_FC))
|
||||
return;
|
||||
|
||||
ql_log(ql_log_warn, NULL, 0x2112,
|
||||
ql_log(ql_log_warn, fcport->vha, 0x2112,
|
||||
"%s: unregister remoteport on %p %8phN\n",
|
||||
__func__, fcport, fcport->port_name);
|
||||
|
||||
@@ -737,18 +759,9 @@ int qla_nvme_register_hba(struct scsi_qla_host *vha)
|
||||
|
||||
WARN_ON(vha->nvme_local_port);
|
||||
|
||||
if (ha->max_req_queues < 3) {
|
||||
if (!ha->flags.max_req_queue_warned)
|
||||
ql_log(ql_log_info, vha, 0x2120,
|
||||
"%s: Disabling FC-NVME due to lack of free queue pairs (%d).\n",
|
||||
__func__, ha->max_req_queues);
|
||||
ha->flags.max_req_queue_warned = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
qla_nvme_fc_transport.max_hw_queues =
|
||||
min((uint8_t)(qla_nvme_fc_transport.max_hw_queues),
|
||||
(uint8_t)(ha->max_req_queues - 2));
|
||||
(uint8_t)(ha->max_qpairs ? ha->max_qpairs : 1));
|
||||
|
||||
pinfo.node_name = wwn_to_u64(vha->node_name);
|
||||
pinfo.port_name = wwn_to_u64(vha->port_name);
|
||||
@@ -821,14 +834,14 @@ void qla_nvme_abort_process_comp_status(struct abort_entry_24xx *abt, srb_t *ori
|
||||
case CS_PORT_LOGGED_OUT:
|
||||
/* BA_RJT was received for the ABTS */
|
||||
case CS_PORT_CONFIG_CHG:
|
||||
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf09d,
|
||||
ql_dbg(ql_dbg_async, vha, 0xf09d,
|
||||
"Abort I/O IOCB completed with error, comp_status=%x\n",
|
||||
comp_status);
|
||||
break;
|
||||
|
||||
/* BA_RJT was received for the ABTS */
|
||||
case CS_REJECT_RECEIVED:
|
||||
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf09e,
|
||||
ql_dbg(ql_dbg_async, vha, 0xf09e,
|
||||
"BA_RJT was received for the ABTS rjt_vendorUnique = %u",
|
||||
abt->fw.ba_rjt_vendorUnique);
|
||||
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf09e,
|
||||
@@ -837,18 +850,18 @@ void qla_nvme_abort_process_comp_status(struct abort_entry_24xx *abt, srb_t *ori
|
||||
break;
|
||||
|
||||
case CS_COMPLETE:
|
||||
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf09f,
|
||||
ql_dbg(ql_dbg_async + ql_dbg_verbose, vha, 0xf09f,
|
||||
"IOCB request is completed successfully comp_status=%x\n",
|
||||
comp_status);
|
||||
break;
|
||||
|
||||
case CS_IOCB_ERROR:
|
||||
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf0a0,
|
||||
ql_dbg(ql_dbg_async, vha, 0xf0a0,
|
||||
"IOCB request is failed, comp_status=%x\n", comp_status);
|
||||
break;
|
||||
|
||||
default:
|
||||
ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf0a1,
|
||||
ql_dbg(ql_dbg_async, vha, 0xf0a1,
|
||||
"Invalid Abort IO IOCB Completion Status %x\n",
|
||||
comp_status);
|
||||
break;
|
||||
|
||||
@@ -1070,7 +1070,8 @@ qla82xx_write_flash_dword(struct qla_hw_data *ha, uint32_t flashaddr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (qla82xx_flash_set_write_enable(ha))
|
||||
ret = qla82xx_flash_set_write_enable(ha);
|
||||
if (ret < 0)
|
||||
goto done_write;
|
||||
|
||||
qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_WDATA, data);
|
||||
@@ -2172,7 +2173,6 @@ qla82xx_poll(int irq, void *dev_id)
|
||||
struct qla_hw_data *ha;
|
||||
struct rsp_que *rsp;
|
||||
struct device_reg_82xx __iomem *reg;
|
||||
int status = 0;
|
||||
uint32_t stat;
|
||||
uint32_t host_int = 0;
|
||||
uint16_t mb[8];
|
||||
@@ -2201,7 +2201,6 @@ qla82xx_poll(int irq, void *dev_id)
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
qla82xx_mbx_completion(vha, MSW(stat));
|
||||
status |= MBX_INTERRUPT;
|
||||
break;
|
||||
case 0x12:
|
||||
mb[0] = MSW(stat);
|
||||
|
||||
+304
-87
@@ -20,6 +20,7 @@
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||
#include <linux/refcount.h>
|
||||
#endif
|
||||
#include <linux/crash_dump.h>
|
||||
|
||||
#include <scsi/scsi_tcq.h>
|
||||
#include <scsi/scsicam.h>
|
||||
@@ -66,6 +67,11 @@ static struct kmem_cache *ctx_cachep;
|
||||
*/
|
||||
uint ql_errlev = 0x8001;
|
||||
|
||||
int ql2xsecenable;
|
||||
module_param(ql2xsecenable, int, S_IRUGO);
|
||||
MODULE_PARM_DESC(ql2xsecenable,
|
||||
"Enable/disable security. 0(Default) - Security disabled. 1 - Security enabled.");
|
||||
|
||||
static int ql2xenableclass2;
|
||||
module_param(ql2xenableclass2, int, S_IRUGO|S_IRUSR);
|
||||
MODULE_PARM_DESC(ql2xenableclass2,
|
||||
@@ -885,7 +891,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
|
||||
uint16_t hwq;
|
||||
struct qla_qpair *qpair = NULL;
|
||||
|
||||
tag = blk_mq_unique_tag(cmd->request);
|
||||
tag = blk_mq_unique_tag(scsi_cmd_to_rq(cmd));
|
||||
hwq = blk_mq_unique_tag_to_hwq(tag);
|
||||
qpair = ha->queue_pair_map[hwq];
|
||||
|
||||
@@ -1157,12 +1163,28 @@ static inline int test_fcport_count(scsi_qla_host_t *vha)
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
unsigned long flags;
|
||||
int res;
|
||||
/* Return 0 = sleep, x=wake */
|
||||
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
ql_dbg(ql_dbg_init, vha, 0x00ec,
|
||||
"tgt %p, fcport_count=%d\n",
|
||||
vha, vha->fcport_count);
|
||||
res = (vha->fcport_count == 0);
|
||||
if (res) {
|
||||
struct fc_port *fcport;
|
||||
|
||||
list_for_each_entry(fcport, &vha->vp_fcports, list) {
|
||||
if (fcport->deleted != QLA_SESS_DELETED) {
|
||||
/* session(s) may not be fully logged in
|
||||
* (ie fcport_count=0), but session
|
||||
* deletion thread(s) may be inflight.
|
||||
*/
|
||||
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
|
||||
return res;
|
||||
@@ -1403,70 +1425,15 @@ static char *reset_errors[] = {
|
||||
"Waiting for command completions",
|
||||
};
|
||||
|
||||
static int
|
||||
__qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
|
||||
struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, uint64_t, int))
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
|
||||
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
|
||||
int err;
|
||||
|
||||
if (!fcport) {
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
err = fc_block_scsi_eh(cmd);
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
if (fcport->deleted)
|
||||
return SUCCESS;
|
||||
|
||||
ql_log(ql_log_info, vha, 0x8009,
|
||||
"%s RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", name, vha->host_no,
|
||||
cmd->device->id, (u64)cmd->device->lun, cmd);
|
||||
|
||||
err = 0;
|
||||
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x800a,
|
||||
"Wait for hba online failed for cmd=%p.\n", cmd);
|
||||
goto eh_reset_failed;
|
||||
}
|
||||
err = 2;
|
||||
if (do_reset(fcport, cmd->device->lun, 1)
|
||||
!= QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x800c,
|
||||
"do_reset failed for cmd=%p.\n", cmd);
|
||||
goto eh_reset_failed;
|
||||
}
|
||||
err = 3;
|
||||
if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id,
|
||||
cmd->device->lun, type) != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x800d,
|
||||
"wait for pending cmds failed for cmd=%p.\n", cmd);
|
||||
goto eh_reset_failed;
|
||||
}
|
||||
|
||||
ql_log(ql_log_info, vha, 0x800e,
|
||||
"%s RESET SUCCEEDED nexus:%ld:%d:%llu cmd=%p.\n", name,
|
||||
vha->host_no, cmd->device->id, (u64)cmd->device->lun, cmd);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
eh_reset_failed:
|
||||
ql_log(ql_log_info, vha, 0x800f,
|
||||
"%s RESET FAILED: %s nexus=%ld:%d:%llu cmd=%p.\n", name,
|
||||
reset_errors[err], vha->host_no, cmd->device->id, (u64)cmd->device->lun,
|
||||
cmd);
|
||||
vha->reset_cmd_err_cnt++;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
static int
|
||||
qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
|
||||
struct scsi_device *sdev = cmd->device;
|
||||
scsi_qla_host_t *vha = shost_priv(sdev->host);
|
||||
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
|
||||
fc_port_t *fcport = (struct fc_port *) sdev->hostdata;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
int err;
|
||||
|
||||
if (qla2x00_isp_reg_stat(ha)) {
|
||||
ql_log(ql_log_info, vha, 0x803e,
|
||||
@@ -1475,15 +1442,66 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd,
|
||||
ha->isp_ops->lun_reset);
|
||||
if (!fcport) {
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
err = fc_block_rport(rport);
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
if (fcport->deleted)
|
||||
return SUCCESS;
|
||||
|
||||
ql_log(ql_log_info, vha, 0x8009,
|
||||
"DEVICE RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", vha->host_no,
|
||||
sdev->id, (u64)sdev->lun, cmd);
|
||||
|
||||
err = 0;
|
||||
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x800a,
|
||||
"Wait for hba online failed for cmd=%p.\n", cmd);
|
||||
goto eh_reset_failed;
|
||||
}
|
||||
err = 2;
|
||||
if (ha->isp_ops->lun_reset(fcport, sdev->lun, 1)
|
||||
!= QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x800c,
|
||||
"do_reset failed for cmd=%p.\n", cmd);
|
||||
goto eh_reset_failed;
|
||||
}
|
||||
err = 3;
|
||||
if (qla2x00_eh_wait_for_pending_commands(vha, sdev->id,
|
||||
sdev->lun, WAIT_LUN) != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x800d,
|
||||
"wait for pending cmds failed for cmd=%p.\n", cmd);
|
||||
goto eh_reset_failed;
|
||||
}
|
||||
|
||||
ql_log(ql_log_info, vha, 0x800e,
|
||||
"DEVICE RESET SUCCEEDED nexus:%ld:%d:%llu cmd=%p.\n",
|
||||
vha->host_no, sdev->id, (u64)sdev->lun, cmd);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
eh_reset_failed:
|
||||
ql_log(ql_log_info, vha, 0x800f,
|
||||
"DEVICE RESET FAILED: %s nexus=%ld:%d:%llu cmd=%p.\n",
|
||||
reset_errors[err], vha->host_no, sdev->id, (u64)sdev->lun,
|
||||
cmd);
|
||||
vha->reset_cmd_err_cnt++;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
static int
|
||||
qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
|
||||
struct scsi_device *sdev = cmd->device;
|
||||
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
|
||||
scsi_qla_host_t *vha = shost_priv(rport_to_shost(rport));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
|
||||
int err;
|
||||
|
||||
if (qla2x00_isp_reg_stat(ha)) {
|
||||
ql_log(ql_log_info, vha, 0x803f,
|
||||
@@ -1492,8 +1510,54 @@ qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd,
|
||||
ha->isp_ops->target_reset);
|
||||
if (!fcport) {
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
err = fc_block_rport(rport);
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
if (fcport->deleted)
|
||||
return SUCCESS;
|
||||
|
||||
ql_log(ql_log_info, vha, 0x8009,
|
||||
"TARGET RESET ISSUED nexus=%ld:%d cmd=%p.\n", vha->host_no,
|
||||
sdev->id, cmd);
|
||||
|
||||
err = 0;
|
||||
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x800a,
|
||||
"Wait for hba online failed for cmd=%p.\n", cmd);
|
||||
goto eh_reset_failed;
|
||||
}
|
||||
err = 2;
|
||||
if (ha->isp_ops->target_reset(fcport, 0, 0) != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x800c,
|
||||
"target_reset failed for cmd=%p.\n", cmd);
|
||||
goto eh_reset_failed;
|
||||
}
|
||||
err = 3;
|
||||
if (qla2x00_eh_wait_for_pending_commands(vha, sdev->id,
|
||||
0, WAIT_TARGET) != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x800d,
|
||||
"wait for pending cmds failed for cmd=%p.\n", cmd);
|
||||
goto eh_reset_failed;
|
||||
}
|
||||
|
||||
ql_log(ql_log_info, vha, 0x800e,
|
||||
"TARGET RESET SUCCEEDED nexus:%ld:%d cmd=%p.\n",
|
||||
vha->host_no, sdev->id, cmd);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
eh_reset_failed:
|
||||
ql_log(ql_log_info, vha, 0x800f,
|
||||
"TARGET RESET FAILED: %s nexus=%ld:%d:%llu cmd=%p.\n",
|
||||
reset_errors[err], vha->host_no, cmd->device->id, (u64)cmd->device->lun,
|
||||
cmd);
|
||||
vha->reset_cmd_err_cnt++;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
@@ -1515,7 +1579,6 @@ static int
|
||||
qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
|
||||
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
|
||||
int ret = FAILED;
|
||||
unsigned int id;
|
||||
uint64_t lun;
|
||||
@@ -1531,15 +1594,6 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
|
||||
id = cmd->device->id;
|
||||
lun = cmd->device->lun;
|
||||
|
||||
if (!fcport) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = fc_block_scsi_eh(cmd);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = FAILED;
|
||||
|
||||
if (qla2x00_chip_is_down(vha))
|
||||
return ret;
|
||||
|
||||
@@ -1780,7 +1834,7 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
|
||||
|
||||
spin_lock_irqsave(qp->qp_lock_ptr, *flags);
|
||||
#if HAVE_SCSI_MQ
|
||||
if (ret_cmd && blk_mq_request_started(cmd->request))
|
||||
if (ret_cmd && blk_mq_request_started(scsi_cmd_to_rq(cmd)))
|
||||
sp->done(sp, res);
|
||||
#else
|
||||
if (ret_cmd && list_empty(&cmd->request->queuelist))
|
||||
@@ -2864,6 +2918,11 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (is_kdump_kernel()) {
|
||||
ql2xmqsupport = 0;
|
||||
ql2xallocfwdump = 0;
|
||||
}
|
||||
|
||||
/* This may fail but that's ok */
|
||||
pci_enable_pcie_error_reporting(pdev);
|
||||
|
||||
@@ -2881,6 +2940,17 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
spin_lock_init(&ha->tgt.sess_lock);
|
||||
spin_lock_init(&ha->tgt.atio_lock);
|
||||
|
||||
spin_lock_init(&ha->sadb_lock);
|
||||
INIT_LIST_HEAD(&ha->sadb_tx_index_list);
|
||||
INIT_LIST_HEAD(&ha->sadb_rx_index_list);
|
||||
|
||||
spin_lock_init(&ha->sadb_fp_lock);
|
||||
|
||||
if (qla_edif_sadb_build_free_pool(ha)) {
|
||||
kfree(ha);
|
||||
goto disable_device;
|
||||
}
|
||||
|
||||
atomic_set(&ha->nvme_active_aen_cnt, 0);
|
||||
|
||||
/* Clear our data area */
|
||||
@@ -3079,8 +3149,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
ha->portnum = PCI_FUNC(ha->pdev->devfn);
|
||||
ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
|
||||
ha->mbx_count = MAILBOX_REGISTER_COUNT;
|
||||
req_length = REQUEST_ENTRY_CNT_24XX;
|
||||
rsp_length = RESPONSE_ENTRY_CNT_2300;
|
||||
req_length = REQUEST_ENTRY_CNT_83XX;
|
||||
rsp_length = RESPONSE_ENTRY_CNT_83XX;
|
||||
ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
|
||||
ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
|
||||
ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
|
||||
@@ -3508,6 +3578,8 @@ skip_dpc:
|
||||
return 0;
|
||||
|
||||
probe_failed:
|
||||
qla_enode_stop(base_vha);
|
||||
qla_edb_stop(base_vha);
|
||||
if (base_vha->gnl.l) {
|
||||
dma_free_coherent(&ha->pdev->dev, base_vha->gnl.size,
|
||||
base_vha->gnl.l, base_vha->gnl.ldma);
|
||||
@@ -3810,6 +3882,8 @@ qla2x00_remove_one(struct pci_dev *pdev)
|
||||
base_vha->gnl.size, base_vha->gnl.l, base_vha->gnl.ldma);
|
||||
|
||||
base_vha->gnl.l = NULL;
|
||||
qla_enode_stop(base_vha);
|
||||
qla_edb_stop(base_vha);
|
||||
|
||||
vfree(base_vha->scan.l);
|
||||
|
||||
@@ -3843,7 +3917,6 @@ qla2x00_remove_one(struct pci_dev *pdev)
|
||||
qla2x00_free_sysfs_attr(base_vha, true);
|
||||
|
||||
fc_remove_host(base_vha->host);
|
||||
qlt_remove_target_resources(ha);
|
||||
|
||||
scsi_remove_host(base_vha->host);
|
||||
|
||||
@@ -3915,6 +3988,9 @@ qla2x00_free_device(scsi_qla_host_t *vha)
|
||||
|
||||
qla82xx_md_free(vha);
|
||||
|
||||
qla_edif_sadb_release_free_pool(ha);
|
||||
qla_edif_sadb_release(ha);
|
||||
|
||||
qla2x00_free_queues(ha);
|
||||
}
|
||||
|
||||
@@ -3967,6 +4043,7 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
|
||||
qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
|
||||
qla2x00_schedule_rport_del(vha, fcport);
|
||||
}
|
||||
|
||||
/*
|
||||
* We may need to retry the login, so don't change the state of the
|
||||
* port but do the retries.
|
||||
@@ -3989,6 +4066,16 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha)
|
||||
"Mark all dev lost\n");
|
||||
|
||||
list_for_each_entry(fcport, &vha->vp_fcports, list) {
|
||||
if (fcport->loop_id != FC_NO_LOOP_ID &&
|
||||
(fcport->flags & FCF_FCP2_DEVICE) &&
|
||||
fcport->port_type == FCT_TARGET &&
|
||||
!qla2x00_reset_active(vha)) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x211a,
|
||||
"Delaying session delete for FCP2 flags 0x%x port_type = 0x%x port_id=%06x %phC",
|
||||
fcport->flags, fcport->port_type,
|
||||
fcport->d_id.b24, fcport->port_name);
|
||||
continue;
|
||||
}
|
||||
fcport->scan_state = 0;
|
||||
qlt_schedule_sess_for_deletion(fcport);
|
||||
}
|
||||
@@ -4020,15 +4107,20 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
|
||||
struct req_que **req, struct rsp_que **rsp)
|
||||
{
|
||||
char name[16];
|
||||
int rc;
|
||||
|
||||
ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size,
|
||||
&ha->init_cb_dma, GFP_KERNEL);
|
||||
if (!ha->init_cb)
|
||||
goto fail;
|
||||
|
||||
if (qlt_mem_alloc(ha) < 0)
|
||||
rc = btree_init32(&ha->host_map);
|
||||
if (rc)
|
||||
goto fail_free_init_cb;
|
||||
|
||||
if (qlt_mem_alloc(ha) < 0)
|
||||
goto fail_free_btree;
|
||||
|
||||
ha->gid_list = dma_alloc_coherent(&ha->pdev->dev,
|
||||
qla2x00_gid_list_size(ha), &ha->gid_list_dma, GFP_KERNEL);
|
||||
if (!ha->gid_list)
|
||||
@@ -4038,7 +4130,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
|
||||
if (!ha->srb_mempool)
|
||||
goto fail_free_gid_list;
|
||||
|
||||
if (IS_P3P_TYPE(ha)) {
|
||||
if (IS_P3P_TYPE(ha) || IS_QLA27XX(ha) || (ql2xsecenable && IS_QLA28XX(ha))) {
|
||||
/* Allocate cache for CT6 Ctx. */
|
||||
if (!ctx_cachep) {
|
||||
ctx_cachep = kmem_cache_create("qla2xxx_ctx",
|
||||
@@ -4072,7 +4164,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
|
||||
"init_cb=%p gid_list=%p, srb_mempool=%p s_dma_pool=%p.\n",
|
||||
ha->init_cb, ha->gid_list, ha->srb_mempool, ha->s_dma_pool);
|
||||
|
||||
if (IS_P3P_TYPE(ha) || ql2xenabledif) {
|
||||
if (IS_P3P_TYPE(ha) || ql2xenabledif || (IS_QLA28XX(ha) && ql2xsecenable)) {
|
||||
ha->dl_dma_pool = dma_pool_create(name, &ha->pdev->dev,
|
||||
DSD_LIST_DMA_POOL_SIZE, 8, 0);
|
||||
if (!ha->dl_dma_pool) {
|
||||
@@ -4312,8 +4404,36 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
|
||||
goto fail_flt_buffer;
|
||||
}
|
||||
|
||||
/* allocate the purex dma pool */
|
||||
ha->purex_dma_pool = dma_pool_create(name, &ha->pdev->dev,
|
||||
MAX_PAYLOAD, 8, 0);
|
||||
|
||||
if (!ha->purex_dma_pool) {
|
||||
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x011b,
|
||||
"Unable to allocate purex_dma_pool.\n");
|
||||
goto fail_flt;
|
||||
}
|
||||
|
||||
ha->elsrej.size = sizeof(struct fc_els_ls_rjt) + 16;
|
||||
ha->elsrej.c = dma_alloc_coherent(&ha->pdev->dev,
|
||||
ha->elsrej.size, &ha->elsrej.cdma, GFP_KERNEL);
|
||||
|
||||
if (!ha->elsrej.c) {
|
||||
ql_dbg_pci(ql_dbg_init, ha->pdev, 0xffff,
|
||||
"Alloc failed for els reject cmd.\n");
|
||||
goto fail_elsrej;
|
||||
}
|
||||
ha->elsrej.c->er_cmd = ELS_LS_RJT;
|
||||
ha->elsrej.c->er_reason = ELS_RJT_LOGIC;
|
||||
ha->elsrej.c->er_explan = ELS_EXPL_UNAB_DATA;
|
||||
return 0;
|
||||
|
||||
fail_elsrej:
|
||||
dma_pool_destroy(ha->purex_dma_pool);
|
||||
fail_flt:
|
||||
dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE,
|
||||
ha->flt, ha->flt_dma);
|
||||
|
||||
fail_flt_buffer:
|
||||
dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE,
|
||||
ha->sfp_data, ha->sfp_data_dma);
|
||||
@@ -4404,6 +4524,8 @@ fail_free_gid_list:
|
||||
ha->gid_list_dma = 0;
|
||||
fail_free_tgt_mem:
|
||||
qlt_mem_free(ha);
|
||||
fail_free_btree:
|
||||
btree_destroy32(&ha->host_map);
|
||||
fail_free_init_cb:
|
||||
dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb,
|
||||
ha->init_cb_dma);
|
||||
@@ -4820,10 +4942,21 @@ qla2x00_mem_free(struct qla_hw_data *ha)
|
||||
ha->dif_bundl_pool = NULL;
|
||||
|
||||
qlt_mem_free(ha);
|
||||
qla_remove_hostmap(ha);
|
||||
|
||||
if (ha->init_cb)
|
||||
dma_free_coherent(&ha->pdev->dev, ha->init_cb_size,
|
||||
ha->init_cb, ha->init_cb_dma);
|
||||
|
||||
dma_pool_destroy(ha->purex_dma_pool);
|
||||
ha->purex_dma_pool = NULL;
|
||||
|
||||
if (ha->elsrej.c) {
|
||||
dma_free_coherent(&ha->pdev->dev, ha->elsrej.size,
|
||||
ha->elsrej.c, ha->elsrej.cdma);
|
||||
ha->elsrej.c = NULL;
|
||||
}
|
||||
|
||||
ha->init_cb = NULL;
|
||||
ha->init_cb_dma = 0;
|
||||
|
||||
@@ -4885,6 +5018,9 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
|
||||
spin_lock_init(&vha->cmd_list_lock);
|
||||
init_waitqueue_head(&vha->fcport_waitQ);
|
||||
init_waitqueue_head(&vha->vref_waitq);
|
||||
qla_enode_init(vha);
|
||||
qla_edb_init(vha);
|
||||
|
||||
|
||||
vha->gnl.size = sizeof(struct get_name_list_extended) *
|
||||
(ha->max_loop_id + 1);
|
||||
@@ -5132,6 +5268,11 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
|
||||
WWN_SIZE);
|
||||
|
||||
fcport->fc4_type = e->u.new_sess.fc4_type;
|
||||
if (NVME_PRIORITY(vha->hw, fcport))
|
||||
fcport->do_prli_nvme = 1;
|
||||
else
|
||||
fcport->do_prli_nvme = 0;
|
||||
|
||||
if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) {
|
||||
fcport->dm_login_expire = jiffies +
|
||||
QLA_N2N_WAIT_TIME * HZ;
|
||||
@@ -5379,6 +5520,9 @@ qla2x00_do_work(struct scsi_qla_host *vha)
|
||||
qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI,
|
||||
e->u.fcport.fcport, false);
|
||||
break;
|
||||
case QLA_EVT_SA_REPLACE:
|
||||
qla24xx_issue_sa_replace_iocb(vha, e);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc == EAGAIN) {
|
||||
@@ -5428,6 +5572,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
|
||||
if (atomic_read(&fcport->state) != FCS_ONLINE &&
|
||||
fcport->login_retry) {
|
||||
if (fcport->scan_state != QLA_FCPORT_FOUND ||
|
||||
fcport->disc_state == DSC_LOGIN_AUTH_PEND ||
|
||||
fcport->disc_state == DSC_LOGIN_COMPLETE)
|
||||
continue;
|
||||
|
||||
@@ -7021,6 +7166,17 @@ intr_on_check:
|
||||
qla2x00_lip_reset(base_vha);
|
||||
}
|
||||
|
||||
if (test_bit(HEARTBEAT_CHK, &base_vha->dpc_flags)) {
|
||||
/*
|
||||
* if there is a mb in progress then that's
|
||||
* enough of a check to see if fw is still ticking.
|
||||
*/
|
||||
if (!ha->flags.mbox_busy && base_vha->flags.init_done)
|
||||
qla_no_op_mb(base_vha);
|
||||
|
||||
clear_bit(HEARTBEAT_CHK, &base_vha->dpc_flags);
|
||||
}
|
||||
|
||||
ha->dpc_active = 0;
|
||||
end_loop:
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
@@ -7077,6 +7233,61 @@ qla2x00_rst_aen(scsi_qla_host_t *vha)
|
||||
}
|
||||
}
|
||||
|
||||
static bool qla_do_heartbeat(struct scsi_qla_host *vha)
|
||||
{
|
||||
u64 cmd_cnt, prev_cmd_cnt;
|
||||
bool do_hb = false;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
int i;
|
||||
|
||||
/* if cmds are still pending down in fw, then do hb */
|
||||
if (ha->base_qpair->cmd_cnt != ha->base_qpair->cmd_completion_cnt) {
|
||||
do_hb = true;
|
||||
goto skip;
|
||||
}
|
||||
|
||||
for (i = 0; i < ha->max_qpairs; i++) {
|
||||
if (ha->queue_pair_map[i] &&
|
||||
ha->queue_pair_map[i]->cmd_cnt !=
|
||||
ha->queue_pair_map[i]->cmd_completion_cnt) {
|
||||
do_hb = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
skip:
|
||||
prev_cmd_cnt = ha->prev_cmd_cnt;
|
||||
cmd_cnt = ha->base_qpair->cmd_cnt;
|
||||
for (i = 0; i < ha->max_qpairs; i++) {
|
||||
if (ha->queue_pair_map[i])
|
||||
cmd_cnt += ha->queue_pair_map[i]->cmd_cnt;
|
||||
}
|
||||
ha->prev_cmd_cnt = cmd_cnt;
|
||||
|
||||
if (!do_hb && ((cmd_cnt - prev_cmd_cnt) > 50))
|
||||
/*
|
||||
* IOs are completing before periodic hb check.
|
||||
* IOs seems to be running, do hb for sanity check.
|
||||
*/
|
||||
do_hb = true;
|
||||
|
||||
return do_hb;
|
||||
}
|
||||
|
||||
static void qla_heart_beat(struct scsi_qla_host *vha)
|
||||
{
|
||||
if (vha->vp_idx)
|
||||
return;
|
||||
|
||||
if (vha->hw->flags.eeh_busy || qla2x00_chip_is_down(vha))
|
||||
return;
|
||||
|
||||
if (qla_do_heartbeat(vha)) {
|
||||
set_bit(HEARTBEAT_CHK, &vha->dpc_flags);
|
||||
qla2xxx_wake_dpc(vha);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* qla2x00_timer
|
||||
*
|
||||
@@ -7220,6 +7431,10 @@ qla2x00_timer(struct timer_list *t)
|
||||
}
|
||||
}
|
||||
|
||||
/* check if edif running */
|
||||
if (vha->hw->flags.edif_enabled)
|
||||
qla_edif_timer(vha);
|
||||
|
||||
/* Process any deferred work. */
|
||||
if (!list_empty(&vha->work_list)) {
|
||||
unsigned long flags;
|
||||
@@ -7295,6 +7510,8 @@ qla2x00_timer(struct timer_list *t)
|
||||
qla2xxx_wake_dpc(vha);
|
||||
}
|
||||
|
||||
qla_heart_beat(vha);
|
||||
|
||||
qla2x00_restart_timer(vha, WATCH_INTERVAL);
|
||||
}
|
||||
|
||||
@@ -7414,7 +7631,7 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha)
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
|
||||
struct qla_qpair *qpair = NULL;
|
||||
struct scsi_qla_host *vp;
|
||||
struct scsi_qla_host *vp, *tvp;
|
||||
fc_port_t *fcport;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
@@ -7445,7 +7662,7 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha)
|
||||
qla2x00_mark_all_devices_lost(vha);
|
||||
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
list_for_each_entry(vp, &ha->vp_list, list) {
|
||||
list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
|
||||
atomic_inc(&vp->vref_count);
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
qla2x00_mark_all_devices_lost(vp);
|
||||
@@ -7459,7 +7676,7 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha)
|
||||
fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
|
||||
|
||||
spin_lock_irqsave(&ha->vport_slock, flags);
|
||||
list_for_each_entry(vp, &ha->vp_list, list) {
|
||||
list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
|
||||
atomic_inc(&vp->vref_count);
|
||||
spin_unlock_irqrestore(&ha->vport_slock, flags);
|
||||
list_for_each_entry(fcport, &vp->vp_fcports, list)
|
||||
@@ -7940,7 +8157,7 @@ qla2x00_module_init(void)
|
||||
BUILD_BUG_ON(sizeof(struct cmd_type_7_fx00) != 64);
|
||||
BUILD_BUG_ON(sizeof(struct cmd_type_crc_2) != 64);
|
||||
BUILD_BUG_ON(sizeof(struct ct_entry_24xx) != 64);
|
||||
BUILD_BUG_ON(sizeof(struct ct_fdmi1_hba_attributes) != 2344);
|
||||
BUILD_BUG_ON(sizeof(struct ct_fdmi1_hba_attributes) != 2604);
|
||||
BUILD_BUG_ON(sizeof(struct ct_fdmi2_hba_attributes) != 4424);
|
||||
BUILD_BUG_ON(sizeof(struct ct_fdmi2_port_attributes) != 4164);
|
||||
BUILD_BUG_ON(sizeof(struct ct_fdmi_hba_attr) != 260);
|
||||
|
||||
@@ -2936,7 +2936,6 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
|
||||
liter += dburst - 1;
|
||||
faddr += dburst - 1;
|
||||
dwptr += dburst - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
write_protect:
|
||||
|
||||
+168
-33
@@ -199,8 +199,7 @@ static inline int qlt_issue_marker(struct scsi_qla_host *vha, int vha_locked)
|
||||
return QLA_SUCCESS;
|
||||
}
|
||||
|
||||
static inline
|
||||
struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha,
|
||||
struct scsi_qla_host *qla_find_host_by_d_id(struct scsi_qla_host *vha,
|
||||
be_id_t d_id)
|
||||
{
|
||||
struct scsi_qla_host *host;
|
||||
@@ -213,7 +212,7 @@ struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha,
|
||||
|
||||
key = be_to_port_id(d_id).b24;
|
||||
|
||||
host = btree_lookup32(&vha->hw->tgt.host_map, key);
|
||||
host = btree_lookup32(&vha->hw->host_map, key);
|
||||
if (!host)
|
||||
ql_dbg(ql_dbg_tgt_mgt + ql_dbg_verbose, vha, 0xf005,
|
||||
"Unable to find host %06x\n", key);
|
||||
@@ -314,7 +313,7 @@ static void qlt_try_to_dequeue_unknown_atios(struct scsi_qla_host *vha,
|
||||
goto abort;
|
||||
}
|
||||
|
||||
host = qlt_find_host_by_d_id(vha, u->atio.u.isp24.fcp_hdr.d_id);
|
||||
host = qla_find_host_by_d_id(vha, u->atio.u.isp24.fcp_hdr.d_id);
|
||||
if (host != NULL) {
|
||||
ql_dbg(ql_dbg_async + ql_dbg_verbose, vha, 0x502f,
|
||||
"Requeuing unknown ATIO_TYPE7 %p\n", u);
|
||||
@@ -363,7 +362,7 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
|
||||
switch (atio->u.raw.entry_type) {
|
||||
case ATIO_TYPE7:
|
||||
{
|
||||
struct scsi_qla_host *host = qlt_find_host_by_d_id(vha,
|
||||
struct scsi_qla_host *host = qla_find_host_by_d_id(vha,
|
||||
atio->u.isp24.fcp_hdr.d_id);
|
||||
if (unlikely(NULL == host)) {
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe03e,
|
||||
@@ -592,6 +591,18 @@ static void qla2x00_async_nack_sp_done(srb_t *sp, int res)
|
||||
sp->fcport->logout_on_delete = 1;
|
||||
sp->fcport->plogi_nack_done_deadline = jiffies + HZ;
|
||||
sp->fcport->send_els_logo = 0;
|
||||
|
||||
if (sp->fcport->flags & FCF_FCSP_DEVICE) {
|
||||
ql_dbg(ql_dbg_edif, vha, 0x20ef,
|
||||
"%s %8phC edif: PLOGI- AUTH WAIT\n", __func__,
|
||||
sp->fcport->port_name);
|
||||
qla2x00_set_fcport_disc_state(sp->fcport,
|
||||
DSC_LOGIN_AUTH_PEND);
|
||||
qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE,
|
||||
sp->fcport->d_id.b24);
|
||||
qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED, sp->fcport->d_id.b24,
|
||||
0, sp->fcport);
|
||||
}
|
||||
break;
|
||||
|
||||
case SRB_NACK_PRLI:
|
||||
@@ -639,6 +650,9 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport,
|
||||
case SRB_NACK_PLOGI:
|
||||
fcport->fw_login_state = DSC_LS_PLOGI_PEND;
|
||||
c = "PLOGI";
|
||||
if (vha->hw->flags.edif_enabled &&
|
||||
(le16_to_cpu(ntfy->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP))
|
||||
fcport->flags |= FCF_FCSP_DEVICE;
|
||||
break;
|
||||
case SRB_NACK_PRLI:
|
||||
fcport->fw_login_state = DSC_LS_PRLI_PEND;
|
||||
@@ -708,7 +722,12 @@ void qla24xx_do_nack_work(struct scsi_qla_host *vha, struct qla_work_evt *e)
|
||||
void qla24xx_delete_sess_fn(struct work_struct *work)
|
||||
{
|
||||
fc_port_t *fcport = container_of(work, struct fc_port, del_work);
|
||||
struct qla_hw_data *ha = fcport->vha->hw;
|
||||
struct qla_hw_data *ha = NULL;
|
||||
|
||||
if (!fcport || !fcport->vha || !fcport->vha->hw)
|
||||
return;
|
||||
|
||||
ha = fcport->vha->hw;
|
||||
|
||||
if (fcport->se_sess) {
|
||||
ha->tgt.tgt_ops->shutdown_sess(fcport);
|
||||
@@ -932,6 +951,11 @@ qlt_send_first_logo(struct scsi_qla_host *vha, qlt_port_logo_t *logo)
|
||||
qlt_port_logo_t *tmp;
|
||||
int res;
|
||||
|
||||
if (test_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags)) {
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mutex_lock(&vha->vha_tgt.tgt_mutex);
|
||||
|
||||
list_for_each_entry(tmp, &vha->logo_list, list) {
|
||||
@@ -952,6 +976,7 @@ qlt_send_first_logo(struct scsi_qla_host *vha, qlt_port_logo_t *logo)
|
||||
list_del(&logo->list);
|
||||
mutex_unlock(&vha->vha_tgt.tgt_mutex);
|
||||
|
||||
out:
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf098,
|
||||
"Finished LOGO to %02x:%02x:%02x, dropped %d cmds, res = %#x\n",
|
||||
logo->id.b.domain, logo->id.b.area, logo->id.b.al_pa,
|
||||
@@ -980,6 +1005,21 @@ void qlt_free_session_done(struct work_struct *work)
|
||||
sess->send_els_logo);
|
||||
|
||||
if (!IS_SW_RESV_ADDR(sess->d_id)) {
|
||||
if (ha->flags.edif_enabled &&
|
||||
(!own || own->iocb.u.isp24.status_subcode == ELS_PLOGI)) {
|
||||
sess->edif.authok = 0;
|
||||
if (!ha->flags.host_shutting_down) {
|
||||
ql_dbg(ql_dbg_edif, vha, 0x911e,
|
||||
"%s wwpn %8phC calling qla2x00_release_all_sadb\n",
|
||||
__func__, sess->port_name);
|
||||
qla2x00_release_all_sadb(vha, sess);
|
||||
} else {
|
||||
ql_dbg(ql_dbg_edif, vha, 0x911e,
|
||||
"%s bypassing release_all_sadb\n",
|
||||
__func__);
|
||||
}
|
||||
qla_edif_sess_down(vha, sess);
|
||||
}
|
||||
qla2x00_mark_device_lost(vha, sess, 0);
|
||||
|
||||
if (sess->send_els_logo) {
|
||||
@@ -987,6 +1027,7 @@ void qlt_free_session_done(struct work_struct *work)
|
||||
|
||||
logo.id = sess->d_id;
|
||||
logo.cmd_count = 0;
|
||||
INIT_LIST_HEAD(&logo.list);
|
||||
if (!own)
|
||||
qlt_send_first_logo(vha, &logo);
|
||||
sess->send_els_logo = 0;
|
||||
@@ -997,6 +1038,7 @@ void qlt_free_session_done(struct work_struct *work)
|
||||
|
||||
if (!own ||
|
||||
(own->iocb.u.isp24.status_subcode == ELS_PLOGI)) {
|
||||
sess->logout_completed = 0;
|
||||
rc = qla2x00_post_async_logout_work(vha, sess,
|
||||
NULL);
|
||||
if (rc != QLA_SUCCESS)
|
||||
@@ -1293,8 +1335,8 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
|
||||
qla24xx_chk_fcp_state(sess);
|
||||
|
||||
ql_dbg(ql_log_warn, sess->vha, 0xe001,
|
||||
"Scheduling sess %p for deletion %8phC\n",
|
||||
sess, sess->port_name);
|
||||
"Scheduling sess %p for deletion %8phC fc4_type %x\n",
|
||||
sess, sess->port_name, sess->fc4_type);
|
||||
|
||||
WARN_ON(!queue_work(sess->vha->hw->wq, &sess->del_work));
|
||||
}
|
||||
@@ -1578,10 +1620,12 @@ void qlt_stop_phase2(struct qla_tgt *tgt)
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&tgt->ha->optrom_mutex);
|
||||
mutex_lock(&vha->vha_tgt.tgt_mutex);
|
||||
tgt->tgt_stop = 0;
|
||||
tgt->tgt_stopped = 1;
|
||||
mutex_unlock(&vha->vha_tgt.tgt_mutex);
|
||||
mutex_unlock(&tgt->ha->optrom_mutex);
|
||||
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished\n",
|
||||
tgt);
|
||||
@@ -1733,6 +1777,12 @@ static void qlt_send_notify_ack(struct qla_qpair *qpair,
|
||||
nack->u.isp24.srr_reject_code_expl = srr_explan;
|
||||
nack->u.isp24.vp_index = ntfy->u.isp24.vp_index;
|
||||
|
||||
/* TODO qualify this with EDIF enable */
|
||||
if (ntfy->u.isp24.status_subcode == ELS_PLOGI &&
|
||||
(le16_to_cpu(ntfy->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP)) {
|
||||
nack->u.isp24.flags |= cpu_to_le16(NOTIFY_ACK_FLAGS_FCSP);
|
||||
}
|
||||
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe005,
|
||||
"qla_target(%d): Sending 24xx Notify Ack %d\n",
|
||||
vha->vp_idx, nack->u.isp24.status);
|
||||
@@ -2599,6 +2649,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair,
|
||||
struct ctio7_to_24xx *pkt;
|
||||
struct atio_from_isp *atio = &prm->cmd->atio;
|
||||
uint16_t temp;
|
||||
struct qla_tgt_cmd *cmd = prm->cmd;
|
||||
|
||||
pkt = (struct ctio7_to_24xx *)qpair->req->ring_ptr;
|
||||
prm->pkt = pkt;
|
||||
@@ -2631,6 +2682,15 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair,
|
||||
pkt->u.status0.ox_id = cpu_to_le16(temp);
|
||||
pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset);
|
||||
|
||||
if (cmd->edif) {
|
||||
if (cmd->dma_data_direction == DMA_TO_DEVICE)
|
||||
prm->cmd->sess->edif.rx_bytes += cmd->bufflen;
|
||||
if (cmd->dma_data_direction == DMA_FROM_DEVICE)
|
||||
prm->cmd->sess->edif.tx_bytes += cmd->bufflen;
|
||||
|
||||
pkt->u.status0.edif_flags |= EF_EN_EDIF;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3327,8 +3387,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
|
||||
if (xmit_type & QLA_TGT_XMIT_STATUS) {
|
||||
pkt->u.status0.scsi_status =
|
||||
cpu_to_le16(prm.rq_result);
|
||||
pkt->u.status0.residual =
|
||||
cpu_to_le32(prm.residual);
|
||||
if (!cmd->edif)
|
||||
pkt->u.status0.residual =
|
||||
cpu_to_le32(prm.residual);
|
||||
|
||||
pkt->u.status0.flags |= cpu_to_le16(
|
||||
CTIO7_FLAGS_SEND_STATUS);
|
||||
if (qlt_need_explicit_conf(cmd, 0)) {
|
||||
@@ -3988,6 +4050,12 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha,
|
||||
if (cmd == NULL)
|
||||
return;
|
||||
|
||||
if ((le16_to_cpu(((struct ctio7_from_24xx *)ctio)->flags) & CTIO7_FLAGS_DATA_OUT) &&
|
||||
cmd->sess) {
|
||||
qlt_chk_edif_rx_sa_delete_pending(vha, cmd->sess,
|
||||
(struct ctio7_from_24xx *)ctio);
|
||||
}
|
||||
|
||||
se_cmd = &cmd->se_cmd;
|
||||
cmd->cmd_sent_to_fw = 0;
|
||||
|
||||
@@ -4058,6 +4126,16 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha,
|
||||
qlt_handle_dif_error(qpair, cmd, ctio);
|
||||
return;
|
||||
}
|
||||
|
||||
case CTIO_FAST_AUTH_ERR:
|
||||
case CTIO_FAST_INCOMP_PAD_LEN:
|
||||
case CTIO_FAST_INVALID_REQ:
|
||||
case CTIO_FAST_SPI_ERR:
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b,
|
||||
"qla_target(%d): CTIO with EDIF error status 0x%x received (state %x, se_cmd %p\n",
|
||||
vha->vp_idx, status, cmd->state, se_cmd);
|
||||
break;
|
||||
|
||||
default:
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b,
|
||||
"qla_target(%d): CTIO with error status 0x%x received (state %x, se_cmd %p\n",
|
||||
@@ -4362,6 +4440,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
|
||||
qlt_assign_qpair(vha, cmd);
|
||||
cmd->reset_count = vha->hw->base_qpair->chip_reset;
|
||||
cmd->vp_idx = vha->vp_idx;
|
||||
cmd->edif = sess->edif.enable;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
@@ -4793,6 +4872,34 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (vha->hw->flags.edif_enabled &&
|
||||
!(vha->e_dbell.db_flags & EDB_ACTIVE) &&
|
||||
iocb->u.isp24.status_subcode == ELS_PLOGI &&
|
||||
!(le16_to_cpu(iocb->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP)) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||
"%s %d Term INOT due to app not available lid=%d, NportID %06X ",
|
||||
__func__, __LINE__, loop_id, port_id.b24);
|
||||
qlt_send_term_imm_notif(vha, iocb, 1);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (vha->hw->flags.edif_enabled) {
|
||||
if (!(vha->e_dbell.db_flags & EDB_ACTIVE)) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||
"%s %d Term INOT due to app not started lid=%d, NportID %06X ",
|
||||
__func__, __LINE__, loop_id, port_id.b24);
|
||||
qlt_send_term_imm_notif(vha, iocb, 1);
|
||||
goto out;
|
||||
} else if (iocb->u.isp24.status_subcode == ELS_PLOGI &&
|
||||
!(le16_to_cpu(iocb->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP)) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||
"%s %d Term INOT due to unsecure lid=%d, NportID %06X ",
|
||||
__func__, __LINE__, loop_id, port_id.b24);
|
||||
qlt_send_term_imm_notif(vha, iocb, 1);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
pla = qlt_plogi_ack_find_add(vha, &port_id, iocb);
|
||||
if (!pla) {
|
||||
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
|
||||
@@ -4858,6 +4965,20 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
|
||||
qlt_plogi_ack_link(vha, pla, sess, QLT_PLOGI_LINK_SAME_WWN);
|
||||
sess->d_id = port_id;
|
||||
sess->login_gen++;
|
||||
sess->loop_id = loop_id;
|
||||
|
||||
if (iocb->u.isp24.status_subcode == ELS_PLOGI) {
|
||||
/* remote port has assigned Port ID */
|
||||
if (N2N_TOPO(vha->hw) && fcport_is_bigger(sess))
|
||||
vha->d_id = sess->d_id;
|
||||
|
||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||
"%s %8phC - send port online\n",
|
||||
__func__, sess->port_name);
|
||||
|
||||
qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE,
|
||||
sess->d_id.b24);
|
||||
}
|
||||
|
||||
if (iocb->u.isp24.status_subcode == ELS_PRLI) {
|
||||
sess->fw_login_state = DSC_LS_PRLI_PEND;
|
||||
@@ -4970,6 +5091,16 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
|
||||
sess = qla2x00_find_fcport_by_wwpn(vha,
|
||||
iocb->u.isp24.port_name, 1);
|
||||
|
||||
if (vha->hw->flags.edif_enabled && sess &&
|
||||
(!(sess->flags & FCF_FCSP_DEVICE) ||
|
||||
!sess->edif.authok)) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||
"%s %d %8phC Term PRLI due to unauthorize PRLI\n",
|
||||
__func__, __LINE__, iocb->u.isp24.port_name);
|
||||
qlt_send_term_imm_notif(vha, iocb, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (sess && sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN]) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||
"%s %d %8phC Term PRLI due to PLOGI ACK not completed\n",
|
||||
@@ -5018,6 +5149,16 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
|
||||
bool delete = false;
|
||||
int sec;
|
||||
|
||||
if (vha->hw->flags.edif_enabled && sess &&
|
||||
(!(sess->flags & FCF_FCSP_DEVICE) ||
|
||||
!sess->edif.authok)) {
|
||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||
"%s %d %8phC Term PRLI due to unauthorize prli\n",
|
||||
__func__, __LINE__, iocb->u.isp24.port_name);
|
||||
qlt_send_term_imm_notif(vha, iocb, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&tgt->ha->tgt.sess_lock, flags);
|
||||
switch (sess->fw_login_state) {
|
||||
case DSC_LS_PLOGI_PEND:
|
||||
@@ -5207,7 +5348,8 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
|
||||
}
|
||||
|
||||
/*
|
||||
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
|
||||
* ha->hardware_lock supposed to be held on entry.
|
||||
* Might drop it, then reacquire.
|
||||
*/
|
||||
static void qlt_handle_imm_notify(struct scsi_qla_host *vha,
|
||||
struct imm_ntfy_from_isp *iocb)
|
||||
@@ -5547,8 +5689,7 @@ qlt_free_qfull_cmds(struct qla_qpair *qpair)
|
||||
"%s: Unexpected cmd in QFull list %p\n", __func__,
|
||||
cmd);
|
||||
|
||||
list_del(&cmd->cmd_list);
|
||||
list_add_tail(&cmd->cmd_list, &free_list);
|
||||
list_move_tail(&cmd->cmd_list, &free_list);
|
||||
|
||||
/* piggy back on hardware_lock for protection */
|
||||
vha->hw->tgt.num_qfull_cmds_alloc--;
|
||||
@@ -6511,15 +6652,15 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qlt_remove_target_resources(struct qla_hw_data *ha)
|
||||
void qla_remove_hostmap(struct qla_hw_data *ha)
|
||||
{
|
||||
struct scsi_qla_host *node;
|
||||
u32 key = 0;
|
||||
|
||||
btree_for_each_safe32(&ha->tgt.host_map, key, node)
|
||||
btree_remove32(&ha->tgt.host_map, key);
|
||||
btree_for_each_safe32(&ha->host_map, key, node)
|
||||
btree_remove32(&ha->host_map, key);
|
||||
|
||||
btree_destroy32(&ha->tgt.host_map);
|
||||
btree_destroy32(&ha->host_map);
|
||||
}
|
||||
|
||||
static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn,
|
||||
@@ -7147,8 +7288,7 @@ qlt_modify_vp_config(struct scsi_qla_host *vha,
|
||||
void
|
||||
qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha)
|
||||
{
|
||||
int rc;
|
||||
|
||||
mutex_init(&base_vha->vha_tgt.tgt_mutex);
|
||||
if (!QLA_TGT_MODE_ENABLED())
|
||||
return;
|
||||
|
||||
@@ -7161,7 +7301,6 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha)
|
||||
ISP_ATIO_Q_OUT(base_vha) = &ha->iobase->isp24.atio_q_out;
|
||||
}
|
||||
|
||||
mutex_init(&base_vha->vha_tgt.tgt_mutex);
|
||||
mutex_init(&base_vha->vha_tgt.tgt_host_action_mutex);
|
||||
|
||||
INIT_LIST_HEAD(&base_vha->unknown_atio_list);
|
||||
@@ -7170,11 +7309,6 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha)
|
||||
|
||||
qlt_clear_mode(base_vha);
|
||||
|
||||
rc = btree_init32(&ha->tgt.host_map);
|
||||
if (rc)
|
||||
ql_log(ql_log_info, base_vha, 0xd03d,
|
||||
"Unable to initialize ha->host_map btree\n");
|
||||
|
||||
qlt_update_vp_map(base_vha, SET_VP_IDX);
|
||||
}
|
||||
|
||||
@@ -7295,21 +7429,20 @@ qlt_update_vp_map(struct scsi_qla_host *vha, int cmd)
|
||||
u32 key;
|
||||
int rc;
|
||||
|
||||
if (!QLA_TGT_MODE_ENABLED())
|
||||
return;
|
||||
|
||||
key = vha->d_id.b24;
|
||||
|
||||
switch (cmd) {
|
||||
case SET_VP_IDX:
|
||||
if (!QLA_TGT_MODE_ENABLED())
|
||||
return;
|
||||
vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = vha;
|
||||
break;
|
||||
case SET_AL_PA:
|
||||
slot = btree_lookup32(&vha->hw->tgt.host_map, key);
|
||||
slot = btree_lookup32(&vha->hw->host_map, key);
|
||||
if (!slot) {
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf018,
|
||||
"Save vha in host_map %p %06x\n", vha, key);
|
||||
rc = btree_insert32(&vha->hw->tgt.host_map,
|
||||
rc = btree_insert32(&vha->hw->host_map,
|
||||
key, vha, GFP_ATOMIC);
|
||||
if (rc)
|
||||
ql_log(ql_log_info, vha, 0xd03e,
|
||||
@@ -7319,17 +7452,19 @@ qlt_update_vp_map(struct scsi_qla_host *vha, int cmd)
|
||||
}
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf019,
|
||||
"replace existing vha in host_map %p %06x\n", vha, key);
|
||||
btree_update32(&vha->hw->tgt.host_map, key, vha);
|
||||
btree_update32(&vha->hw->host_map, key, vha);
|
||||
break;
|
||||
case RESET_VP_IDX:
|
||||
if (!QLA_TGT_MODE_ENABLED())
|
||||
return;
|
||||
vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL;
|
||||
break;
|
||||
case RESET_AL_PA:
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01a,
|
||||
"clear vha in host_map %p %06x\n", vha, key);
|
||||
slot = btree_lookup32(&vha->hw->tgt.host_map, key);
|
||||
slot = btree_lookup32(&vha->hw->host_map, key);
|
||||
if (slot)
|
||||
btree_remove32(&vha->hw->tgt.host_map, key);
|
||||
btree_remove32(&vha->hw->host_map, key);
|
||||
vha->d_id.b24 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -203,6 +203,7 @@ struct nack_to_isp {
|
||||
uint8_t reserved[2];
|
||||
__le16 ox_id;
|
||||
} __packed;
|
||||
#define NOTIFY_ACK_FLAGS_FCSP BIT_5
|
||||
#define NOTIFY_ACK_FLAGS_TERMINATE BIT_3
|
||||
#define NOTIFY_ACK_SRR_FLAGS_ACCEPT 0
|
||||
#define NOTIFY_ACK_SRR_FLAGS_REJECT 1
|
||||
@@ -265,6 +266,10 @@ struct ctio_to_2xxx {
|
||||
#define CTIO_PORT_LOGGED_OUT 0x29
|
||||
#define CTIO_PORT_CONF_CHANGED 0x2A
|
||||
#define CTIO_SRR_RECEIVED 0x45
|
||||
#define CTIO_FAST_AUTH_ERR 0x63
|
||||
#define CTIO_FAST_INCOMP_PAD_LEN 0x65
|
||||
#define CTIO_FAST_INVALID_REQ 0x66
|
||||
#define CTIO_FAST_SPI_ERR 0x67
|
||||
#endif
|
||||
|
||||
#ifndef CTIO_RET_TYPE
|
||||
@@ -435,7 +440,16 @@ struct ctio7_to_24xx {
|
||||
struct {
|
||||
__le16 reserved1;
|
||||
__le16 flags;
|
||||
__le32 residual;
|
||||
union {
|
||||
__le32 residual;
|
||||
struct {
|
||||
uint8_t rsvd1;
|
||||
uint8_t edif_flags;
|
||||
#define EF_EN_EDIF BIT_0
|
||||
#define EF_NEW_SA BIT_1
|
||||
uint16_t rsvd2;
|
||||
};
|
||||
};
|
||||
__le16 ox_id;
|
||||
__le16 scsi_status;
|
||||
__le32 relative_offset;
|
||||
@@ -473,7 +487,7 @@ struct ctio7_from_24xx {
|
||||
uint8_t vp_index;
|
||||
uint8_t reserved1[5];
|
||||
__le32 exchange_address;
|
||||
__le16 reserved2;
|
||||
__le16 edif_sa_index;
|
||||
__le16 flags;
|
||||
__le32 residual;
|
||||
__le16 ox_id;
|
||||
@@ -921,6 +935,7 @@ struct qla_tgt_cmd {
|
||||
unsigned int term_exchg:1;
|
||||
unsigned int cmd_sent_to_fw:1;
|
||||
unsigned int cmd_in_wq:1;
|
||||
unsigned int edif:1;
|
||||
|
||||
/*
|
||||
* This variable may be set from outside the LIO and I/O completion
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
/*
|
||||
* Driver version
|
||||
*/
|
||||
#define QLA2XXX_VERSION "10.02.00.106-k"
|
||||
#define QLA2XXX_VERSION "10.02.06.200-k"
|
||||
|
||||
#define QLA_DRIVER_MAJOR_VER 10
|
||||
#define QLA_DRIVER_MINOR_VER 2
|
||||
#define QLA_DRIVER_PATCH_VER 0
|
||||
#define QLA_DRIVER_BETA_VER 106
|
||||
#define QLA_DRIVER_PATCH_VER 6
|
||||
#define QLA_DRIVER_BETA_VER 200
|
||||
|
||||
Reference in New Issue
Block a user