Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2020-12-28 15:54:49 -08:00
32 changed files with 894 additions and 641 deletions
+50 -50
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include "qla_target.h"
@@ -157,6 +156,14 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
vha->host_no);
}
break;
case 10:
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
ql_log(ql_log_info, vha, 0x70e9,
"Issuing MPI firmware dump on host#%ld.\n",
vha->host_no);
ha->isp_ops->mpi_fw_dump(vha, 0);
}
break;
}
return count;
}
@@ -744,8 +751,6 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP);
qla83xx_idc_unlock(vha, 0);
break;
} else if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
qla27xx_reset_mpi(vha);
} else {
/* Make sure FC side is not in reset */
WARN_ON_ONCE(qla2x00_wait_for_hba_online(vha) !=
@@ -2726,6 +2731,9 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
struct link_statistics *stats;
dma_addr_t stats_dma;
struct fc_host_statistics *p = &vha->fc_host_stat;
struct qla_qpair *qpair;
int i;
u64 ib = 0, ob = 0, ir = 0, or = 0;
memset(p, -1, sizeof(*p));
@@ -2762,6 +2770,27 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
if (rval != QLA_SUCCESS)
goto done_free;
/* --- */
for (i = 0; i < vha->hw->max_qpairs; i++) {
qpair = vha->hw->queue_pair_map[i];
if (!qpair)
continue;
ir += qpair->counters.input_requests;
or += qpair->counters.output_requests;
ib += qpair->counters.input_bytes;
ob += qpair->counters.output_bytes;
}
ir += ha->base_qpair->counters.input_requests;
or += ha->base_qpair->counters.output_requests;
ib += ha->base_qpair->counters.input_bytes;
ob += ha->base_qpair->counters.output_bytes;
ir += vha->qla_stats.input_requests;
or += vha->qla_stats.output_requests;
ib += vha->qla_stats.input_bytes;
ob += vha->qla_stats.output_bytes;
/* --- */
p->link_failure_count = le32_to_cpu(stats->link_fail_cnt);
p->loss_of_sync_count = le32_to_cpu(stats->loss_sync_cnt);
p->loss_of_signal_count = le32_to_cpu(stats->loss_sig_cnt);
@@ -2781,15 +2810,16 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
p->rx_words = le64_to_cpu(stats->fpm_recv_word_cnt);
p->tx_words = le64_to_cpu(stats->fpm_xmit_word_cnt);
} else {
p->rx_words = vha->qla_stats.input_bytes;
p->tx_words = vha->qla_stats.output_bytes;
p->rx_words = ib >> 2;
p->tx_words = ob >> 2;
}
}
p->fcp_control_requests = vha->qla_stats.control_requests;
p->fcp_input_requests = vha->qla_stats.input_requests;
p->fcp_output_requests = vha->qla_stats.output_requests;
p->fcp_input_megabytes = vha->qla_stats.input_bytes >> 20;
p->fcp_output_megabytes = vha->qla_stats.output_bytes >> 20;
p->fcp_input_requests = ir;
p->fcp_output_requests = or;
p->fcp_input_megabytes = ib >> 20;
p->fcp_output_megabytes = ob >> 20;
p->seconds_since_last_reset =
get_jiffies_64() - vha->qla_stats.jiffies_at_last_reset;
do_div(p->seconds_since_last_reset, HZ);
@@ -2809,9 +2839,18 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost)
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
struct link_statistics *stats;
dma_addr_t stats_dma;
int i;
struct qla_qpair *qpair;
memset(&vha->qla_stats, 0, sizeof(vha->qla_stats));
memset(&vha->fc_host_stat, 0, sizeof(vha->fc_host_stat));
for (i = 0; i < vha->hw->max_qpairs; i++) {
qpair = vha->hw->queue_pair_map[i];
if (!qpair)
continue;
memset(&qpair->counters, 0, sizeof(qpair->counters));
}
memset(&ha->base_qpair->counters, 0, sizeof(qpair->counters));
vha->qla_stats.jiffies_at_last_reset = get_jiffies_64();
@@ -3217,46 +3256,7 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha)
fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports;
fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count;
if (IS_CNA_CAPABLE(ha))
speeds = FC_PORTSPEED_10GBIT;
else if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
if (ha->max_supported_speed == 2) {
if (ha->min_supported_speed <= 6)
speeds |= FC_PORTSPEED_64GBIT;
}
if (ha->max_supported_speed == 2 ||
ha->max_supported_speed == 1) {
if (ha->min_supported_speed <= 5)
speeds |= FC_PORTSPEED_32GBIT;
}
if (ha->max_supported_speed == 2 ||
ha->max_supported_speed == 1 ||
ha->max_supported_speed == 0) {
if (ha->min_supported_speed <= 4)
speeds |= FC_PORTSPEED_16GBIT;
}
if (ha->max_supported_speed == 1 ||
ha->max_supported_speed == 0) {
if (ha->min_supported_speed <= 3)
speeds |= FC_PORTSPEED_8GBIT;
}
if (ha->max_supported_speed == 0) {
if (ha->min_supported_speed <= 2)
speeds |= FC_PORTSPEED_4GBIT;
}
} else if (IS_QLA2031(ha))
speeds = FC_PORTSPEED_16GBIT|FC_PORTSPEED_8GBIT|
FC_PORTSPEED_4GBIT;
else if (IS_QLA25XX(ha) || IS_QLAFX00(ha))
speeds = FC_PORTSPEED_8GBIT|FC_PORTSPEED_4GBIT|
FC_PORTSPEED_2GBIT|FC_PORTSPEED_1GBIT;
else if (IS_QLA24XX_TYPE(ha))
speeds = FC_PORTSPEED_4GBIT|FC_PORTSPEED_2GBIT|
FC_PORTSPEED_1GBIT;
else if (IS_QLA23XX(ha))
speeds = FC_PORTSPEED_2GBIT|FC_PORTSPEED_1GBIT;
else
speeds = FC_PORTSPEED_1GBIT;
speeds = qla25xx_fdmi_port_speed_capability(ha);
fc_host_supported_speeds(vha->host) = speeds;
}
+1 -2
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
+1 -2
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifndef __QLA_BSG_H
#define __QLA_BSG_H
+3 -4
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
/*
@@ -16,7 +15,7 @@
* | Device Discovery | 0x2134 | 0x210e-0x2116 |
* | | | 0x211a |
* | | | 0x211c-0x2128 |
* | | | 0x212a-0x2134 |
* | | | 0x212c-0x2134 |
* | Queue Command and IO tracing | 0x3074 | 0x300b |
* | | | 0x3027-0x3028 |
* | | | 0x303d-0x3041 |
@@ -2449,7 +2448,7 @@ static void ql_dbg_prefix(char *pbuf, int pbuf_size,
const struct pci_dev *pdev = vha->hw->pdev;
/* <module-name> [<dev-name>]-<msg-id>:<host>: */
snprintf(pbuf, pbuf_size, "%s [%s]-%04x:%ld: ", QL_MSGHDR,
snprintf(pbuf, pbuf_size, "%s [%s]-%04x:%lu: ", QL_MSGHDR,
dev_name(&(pdev->dev)), msg_id, vha->host_no);
} else {
/* <module-name> [<dev-name>]-<msg-id>: : */
+1 -2
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
+66 -15
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifndef __QLA_DEF_H
#define __QLA_DEF_H
@@ -646,6 +645,12 @@ enum {
TYPE_TGT_TMCMD, /* task management */
};
struct iocb_resource {
u8 res_type;
u8 pad;
u16 iocb_cnt;
};
typedef struct srb {
/*
* Do not move cmd_type field, it needs to
@@ -653,6 +658,7 @@ typedef struct srb {
*/
uint8_t cmd_type;
uint8_t pad[3];
struct iocb_resource iores;
struct kref cmd_kref; /* need to migrate ref_count over to this */
void *priv;
wait_queue_head_t nvme_ls_waitq;
@@ -1652,7 +1658,7 @@ typedef struct {
*/
uint8_t firmware_options[2];
uint16_t frame_payload_size;
__le16 frame_payload_size;
__le16 max_iocb_allocation;
__le16 execution_throttle;
uint8_t retry_count;
@@ -2469,12 +2475,6 @@ typedef struct fc_port {
struct list_head list;
struct scsi_qla_host *vha;
uint8_t node_name[WWN_SIZE];
uint8_t port_name[WWN_SIZE];
port_id_t d_id;
uint16_t loop_id;
uint16_t old_loop_id;
unsigned int conf_compl_supported:1;
unsigned int deleted:2;
unsigned int free_pending:1;
@@ -2491,15 +2491,24 @@ typedef struct fc_port {
unsigned int n2n_flag:1;
unsigned int explicit_logout:1;
unsigned int prli_pend_timer:1;
uint8_t nvme_flag;
uint8_t node_name[WWN_SIZE];
uint8_t port_name[WWN_SIZE];
port_id_t d_id;
uint16_t loop_id;
uint16_t old_loop_id;
struct completion nvme_del_done;
uint32_t nvme_prli_service_param;
#define NVME_PRLI_SP_PI_CTRL BIT_9
#define NVME_PRLI_SP_SLER BIT_8
#define NVME_PRLI_SP_CONF BIT_7
#define NVME_PRLI_SP_INITIATOR BIT_5
#define NVME_PRLI_SP_TARGET BIT_4
#define NVME_PRLI_SP_DISCOVERY BIT_3
#define NVME_PRLI_SP_FIRST_BURST BIT_0
uint8_t nvme_flag;
uint32_t nvme_first_burst_size;
#define NVME_FLAG_REGISTERED 4
#define NVME_FLAG_DELETING 2
@@ -2510,6 +2519,8 @@ typedef struct fc_port {
int generation;
struct se_session *se_sess;
struct list_head sess_cmd_list;
spinlock_t sess_cmd_lock;
struct kref sess_kref;
struct qla_tgt *tgt;
unsigned long expires;
@@ -2571,6 +2582,8 @@ typedef struct fc_port {
u8 last_login_state;
u16 n2n_link_reset_cnt;
u16 n2n_chip_reset;
struct dentry *dfs_rport_dir;
} fc_port_t;
enum {
@@ -3310,8 +3323,10 @@ struct isp_operations {
void (*fw_dump)(struct scsi_qla_host *vha);
void (*mpi_fw_dump)(struct scsi_qla_host *, int);
/* Context: task, might sleep */
int (*beacon_on) (struct scsi_qla_host *);
int (*beacon_off) (struct scsi_qla_host *);
void (*beacon_blink) (struct scsi_qla_host *);
void *(*read_optrom)(struct scsi_qla_host *, void *,
@@ -3322,7 +3337,10 @@ struct isp_operations {
int (*get_flash_version) (struct scsi_qla_host *, void *);
int (*start_scsi) (srb_t *);
int (*start_scsi_mq) (srb_t *);
/* Context: task, might sleep */
int (*abort_isp) (struct scsi_qla_host *);
int (*iospace_config)(struct qla_hw_data *);
int (*initialize_adapter)(struct scsi_qla_host *);
};
@@ -3535,6 +3553,14 @@ struct qla_tgt_counters {
uint64_t num_term_xchg_sent;
};
struct qla_counters {
uint64_t input_bytes;
uint64_t input_requests;
uint64_t output_bytes;
uint64_t output_requests;
};
struct qla_qpair;
/* Response queue data structure */
@@ -3593,6 +3619,15 @@ struct req_que {
uint8_t req_pkt[REQUEST_ENTRY_SIZE];
};
struct qla_fw_resources {
u16 iocbs_total;
u16 iocbs_limit;
u16 iocbs_qp_limit;
u16 iocbs_used;
};
#define QLA_IOCB_PCT_LIMIT 95
/*Queue pair data structure */
struct qla_qpair {
spinlock_t qp_lock;
@@ -3619,6 +3654,7 @@ struct qla_qpair {
uint32_t enable_class_2:1;
uint32_t enable_explicit_conf:1;
uint32_t use_shadow_reg:1;
uint32_t rcv_intr:1;
uint16_t id; /* qp number used with FW */
uint16_t vp_idx; /* vport ID */
@@ -3634,13 +3670,17 @@ struct qla_qpair {
struct qla_msix_entry *msix; /* point to &ha->msix_entries[x] */
struct qla_hw_data *hw;
struct work_struct q_work;
struct qla_counters counters;
struct list_head qp_list_elem; /* vha->qp_list */
struct list_head hints_list;
uint16_t cpuid;
uint16_t retry_term_cnt;
__le32 retry_term_exchg_addr;
uint64_t retry_term_jiff;
struct qla_tgt_counters tgt_counters;
uint16_t cpuid;
struct qla_fw_resources fwres ____cacheline_aligned;
};
/* Place holder for FW buffer parameters */
@@ -3908,6 +3948,7 @@ struct qla_hw_data {
/* Enabled in Driver */
uint32_t scm_enabled:1;
uint32_t max_req_queue_warned:1;
uint32_t plogi_template_valid:1;
} flags;
uint16_t max_exchg;
@@ -4154,6 +4195,10 @@ struct qla_hw_data {
#define USE_ASYNC_SCAN(ha) (IS_QLA25XX(ha) || IS_QLA81XX(ha) ||\
IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))
#define IS_ZIO_THRESHOLD_CAPABLE(ha) \
((IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) &&\
(ha->zio_mode == QLA_ZIO_MODE_6))
/* HBA serial number */
uint8_t serial0;
uint8_t serial1;
@@ -4241,7 +4286,7 @@ struct qla_hw_data {
/* Extended Logins */
void *exlogin_buf;
dma_addr_t exlogin_buf_dma;
int exlogin_size;
uint32_t exlogin_size;
#define ENABLE_EXCHANGE_OFFLD BIT_2
@@ -4252,7 +4297,8 @@ struct qla_hw_data {
int exchoffld_count;
/* n2n */
struct els_plogi_payload plogi_els_payld;
struct fc_els_flogi plogi_els_payld;
#define LOGIN_TEMPLATE_SIZE (sizeof(struct fc_els_flogi) - 4)
void *swl;
@@ -4300,6 +4346,7 @@ struct qla_hw_data {
#define FW_ATTR_EXT0_SCM_BROCADE 0x00001000
/* Cisco fabric attached */
#define FW_ATTR_EXT0_SCM_CISCO 0x00002000
#define FW_ATTR_EXT0_NVME2 BIT_13
uint16_t fw_attributes_ext[2];
uint32_t fw_memory_size;
uint32_t fw_transfer_size;
@@ -4649,6 +4696,7 @@ typedef struct scsi_qla_host {
uint32_t qpairs_rsp_created:1;
uint32_t nvme_enabled:1;
uint32_t nvme_first_burst:1;
uint32_t nvme2_enabled:1;
} flags;
atomic_t loop_state;
@@ -4807,6 +4855,8 @@ typedef struct scsi_qla_host {
uint16_t ql2xexchoffld;
uint16_t ql2xiniexchg;
struct dentry *dfs_rport_root;
struct purex_list {
struct list_head head;
spinlock_t lock;
@@ -4952,8 +5002,7 @@ struct secure_flash_update_block_pk {
} while (0)
#define QLA_QPAIR_MARK_NOT_BUSY(__qpair) \
atomic_dec(&__qpair->ref_count); \
atomic_dec(&__qpair->ref_count)
#define QLA_ENA_CONF(_ha) {\
int i;\
@@ -5130,6 +5179,8 @@ struct sff_8247_a0 {
ha->current_topology == ISP_CFG_N || \
!ha->current_topology)
#define QLA_N2N_WAIT_TIME 5 /* 2 * ra_tov(n2n) + 1 */
#define NVME_TYPE(fcport) \
(fcport->fc4_type & FS_FC4TYPE_NVME) \
+213 -101
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
@@ -12,6 +11,140 @@
static struct dentry *qla2x00_dfs_root;
static atomic_t qla2x00_dfs_root_count;
#define QLA_DFS_RPORT_DEVLOSS_TMO 1
static int
qla_dfs_rport_get(struct fc_port *fp, int attr_id, u64 *val)
{
switch (attr_id) {
case QLA_DFS_RPORT_DEVLOSS_TMO:
/* Only supported for FC-NVMe devices that are registered. */
if (!(fp->nvme_flag & NVME_FLAG_REGISTERED))
return -EIO;
*val = fp->nvme_remote_port->dev_loss_tmo;
break;
default:
return -EINVAL;
}
return 0;
}
static int
qla_dfs_rport_set(struct fc_port *fp, int attr_id, u64 val)
{
switch (attr_id) {
case QLA_DFS_RPORT_DEVLOSS_TMO:
/* Only supported for FC-NVMe devices that are registered. */
if (!(fp->nvme_flag & NVME_FLAG_REGISTERED))
return -EIO;
#if (IS_ENABLED(CONFIG_NVME_FC))
return nvme_fc_set_remoteport_devloss(fp->nvme_remote_port,
val);
#else /* CONFIG_NVME_FC */
return -EINVAL;
#endif /* CONFIG_NVME_FC */
default:
return -EINVAL;
}
return 0;
}
#define DEFINE_QLA_DFS_RPORT_RW_ATTR(_attr_id, _attr) \
static int qla_dfs_rport_##_attr##_get(void *data, u64 *val) \
{ \
struct fc_port *fp = data; \
return qla_dfs_rport_get(fp, _attr_id, val); \
} \
static int qla_dfs_rport_##_attr##_set(void *data, u64 val) \
{ \
struct fc_port *fp = data; \
return qla_dfs_rport_set(fp, _attr_id, val); \
} \
DEFINE_DEBUGFS_ATTRIBUTE(qla_dfs_rport_##_attr##_fops, \
qla_dfs_rport_##_attr##_get, \
qla_dfs_rport_##_attr##_set, "%llu\n")
/*
* Wrapper for getting fc_port fields.
*
* _attr : Attribute name.
* _get_val : Accessor macro to retrieve the value.
*/
#define DEFINE_QLA_DFS_RPORT_FIELD_GET(_attr, _get_val) \
static int qla_dfs_rport_field_##_attr##_get(void *data, u64 *val) \
{ \
struct fc_port *fp = data; \
*val = _get_val; \
return 0; \
} \
DEFINE_DEBUGFS_ATTRIBUTE(qla_dfs_rport_field_##_attr##_fops, \
qla_dfs_rport_field_##_attr##_get, \
NULL, "%llu\n")
#define DEFINE_QLA_DFS_RPORT_ACCESS(_attr, _get_val) \
DEFINE_QLA_DFS_RPORT_FIELD_GET(_attr, _get_val)
#define DEFINE_QLA_DFS_RPORT_FIELD(_attr) \
DEFINE_QLA_DFS_RPORT_FIELD_GET(_attr, fp->_attr)
DEFINE_QLA_DFS_RPORT_RW_ATTR(QLA_DFS_RPORT_DEVLOSS_TMO, dev_loss_tmo);
DEFINE_QLA_DFS_RPORT_FIELD(disc_state);
DEFINE_QLA_DFS_RPORT_FIELD(scan_state);
DEFINE_QLA_DFS_RPORT_FIELD(fw_login_state);
DEFINE_QLA_DFS_RPORT_FIELD(login_pause);
DEFINE_QLA_DFS_RPORT_FIELD(flags);
DEFINE_QLA_DFS_RPORT_FIELD(nvme_flag);
DEFINE_QLA_DFS_RPORT_FIELD(last_rscn_gen);
DEFINE_QLA_DFS_RPORT_FIELD(rscn_gen);
DEFINE_QLA_DFS_RPORT_FIELD(login_gen);
DEFINE_QLA_DFS_RPORT_FIELD(loop_id);
DEFINE_QLA_DFS_RPORT_FIELD_GET(port_id, fp->d_id.b24);
DEFINE_QLA_DFS_RPORT_FIELD_GET(sess_kref, kref_read(&fp->sess_kref));
void
qla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp)
{
char wwn[32];
#define QLA_CREATE_RPORT_FIELD_ATTR(_attr) \
debugfs_create_file(#_attr, 0400, fp->dfs_rport_dir, \
fp, &qla_dfs_rport_field_##_attr##_fops)
if (!vha->dfs_rport_root || fp->dfs_rport_dir)
return;
sprintf(wwn, "pn-%016llx", wwn_to_u64(fp->port_name));
fp->dfs_rport_dir = debugfs_create_dir(wwn, vha->dfs_rport_root);
if (!fp->dfs_rport_dir)
return;
if (NVME_TARGET(vha->hw, fp))
debugfs_create_file("dev_loss_tmo", 0600, fp->dfs_rport_dir,
fp, &qla_dfs_rport_dev_loss_tmo_fops);
QLA_CREATE_RPORT_FIELD_ATTR(disc_state);
QLA_CREATE_RPORT_FIELD_ATTR(scan_state);
QLA_CREATE_RPORT_FIELD_ATTR(fw_login_state);
QLA_CREATE_RPORT_FIELD_ATTR(login_pause);
QLA_CREATE_RPORT_FIELD_ATTR(flags);
QLA_CREATE_RPORT_FIELD_ATTR(nvme_flag);
QLA_CREATE_RPORT_FIELD_ATTR(last_rscn_gen);
QLA_CREATE_RPORT_FIELD_ATTR(rscn_gen);
QLA_CREATE_RPORT_FIELD_ATTR(login_gen);
QLA_CREATE_RPORT_FIELD_ATTR(loop_id);
QLA_CREATE_RPORT_FIELD_ATTR(port_id);
QLA_CREATE_RPORT_FIELD_ATTR(sess_kref);
}
void
qla2x00_dfs_remove_rport(scsi_qla_host_t *vha, struct fc_port *fp)
{
if (!vha->dfs_rport_root || !fp->dfs_rport_dir)
return;
debugfs_remove_recursive(fp->dfs_rport_dir);
fp->dfs_rport_dir = NULL;
}
static int
qla2x00_dfs_tgt_sess_show(struct seq_file *s, void *unused)
{
@@ -37,89 +170,63 @@ qla2x00_dfs_tgt_sess_show(struct seq_file *s, void *unused)
return 0;
}
static int
qla2x00_dfs_tgt_sess_open(struct inode *inode, struct file *file)
{
scsi_qla_host_t *vha = inode->i_private;
return single_open(file, qla2x00_dfs_tgt_sess_show, vha);
}
static const struct file_operations dfs_tgt_sess_ops = {
.open = qla2x00_dfs_tgt_sess_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
DEFINE_SHOW_ATTRIBUTE(qla2x00_dfs_tgt_sess);
static int
qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused)
{
scsi_qla_host_t *vha = s->private;
struct qla_hw_data *ha = vha->hw;
struct gid_list_info *gid_list, *gid;
struct gid_list_info *gid_list;
dma_addr_t gid_list_dma;
fc_port_t fc_port;
char *id_iter;
int rc, i;
uint16_t entries, loop_id;
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
seq_printf(s, "%s\n", vha->host_str);
if (tgt) {
gid_list = dma_alloc_coherent(&ha->pdev->dev,
qla2x00_gid_list_size(ha),
&gid_list_dma, GFP_KERNEL);
if (!gid_list) {
ql_dbg(ql_dbg_user, vha, 0x7018,
"DMA allocation failed for %u\n",
qla2x00_gid_list_size(ha));
return 0;
}
rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma,
&entries);
if (rc != QLA_SUCCESS)
goto out_free_id_list;
gid = gid_list;
seq_puts(s, "Port Name Port ID Loop ID\n");
for (i = 0; i < entries; i++) {
loop_id = le16_to_cpu(gid->loop_id);
memset(&fc_port, 0, sizeof(fc_port_t));
fc_port.loop_id = loop_id;
rc = qla24xx_gpdb_wait(vha, &fc_port, 0);
seq_printf(s, "%8phC %02x%02x%02x %d\n",
fc_port.port_name, fc_port.d_id.b.domain,
fc_port.d_id.b.area, fc_port.d_id.b.al_pa,
fc_port.loop_id);
gid = (void *)gid + ha->gid_list_info_size;
}
out_free_id_list:
dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha),
gid_list, gid_list_dma);
gid_list = dma_alloc_coherent(&ha->pdev->dev,
qla2x00_gid_list_size(ha),
&gid_list_dma, GFP_KERNEL);
if (!gid_list) {
ql_dbg(ql_dbg_user, vha, 0x7018,
"DMA allocation failed for %u\n",
qla2x00_gid_list_size(ha));
return 0;
}
rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma,
&entries);
if (rc != QLA_SUCCESS)
goto out_free_id_list;
id_iter = (char *)gid_list;
seq_puts(s, "Port Name Port ID Loop ID\n");
for (i = 0; i < entries; i++) {
struct gid_list_info *gid =
(struct gid_list_info *)id_iter;
loop_id = le16_to_cpu(gid->loop_id);
memset(&fc_port, 0, sizeof(fc_port_t));
fc_port.loop_id = loop_id;
rc = qla24xx_gpdb_wait(vha, &fc_port, 0);
seq_printf(s, "%8phC %02x%02x%02x %d\n",
fc_port.port_name, fc_port.d_id.b.domain,
fc_port.d_id.b.area, fc_port.d_id.b.al_pa,
fc_port.loop_id);
id_iter += ha->gid_list_info_size;
}
out_free_id_list:
dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha),
gid_list, gid_list_dma);
return 0;
}
static int
qla2x00_dfs_tgt_port_database_open(struct inode *inode, struct file *file)
{
scsi_qla_host_t *vha = inode->i_private;
return single_open(file, qla2x00_dfs_tgt_port_database_show, vha);
}
static const struct file_operations dfs_tgt_port_database_ops = {
.open = qla2x00_dfs_tgt_port_database_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
DEFINE_SHOW_ATTRIBUTE(qla2x00_dfs_tgt_port_database);
static int
qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
@@ -127,6 +234,8 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
struct scsi_qla_host *vha = s->private;
uint16_t mb[MAX_IOCB_MB_REG];
int rc;
struct qla_hw_data *ha = vha->hw;
u16 iocbs_used, i;
rc = qla24xx_res_count_wait(vha, mb, SIZEOF_IOCB_MB_REG);
if (rc != QLA_SUCCESS) {
@@ -151,23 +260,22 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
mb[23]);
}
if (ql2xenforce_iocb_limit) {
/* lock is not require. It's an estimate. */
iocbs_used = ha->base_qpair->fwres.iocbs_used;
for (i = 0; i < ha->max_qpairs; i++) {
if (ha->queue_pair_map[i])
iocbs_used += ha->queue_pair_map[i]->fwres.iocbs_used;
}
seq_printf(s, "Driver: estimate iocb used [%d] high water limit [%d]\n",
iocbs_used, ha->base_qpair->fwres.iocbs_limit);
}
return 0;
}
static int
qla_dfs_fw_resource_cnt_open(struct inode *inode, struct file *file)
{
struct scsi_qla_host *vha = inode->i_private;
return single_open(file, qla_dfs_fw_resource_cnt_show, vha);
}
static const struct file_operations dfs_fw_resource_cnt_ops = {
.open = qla_dfs_fw_resource_cnt_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
DEFINE_SHOW_ATTRIBUTE(qla_dfs_fw_resource_cnt);
static int
qla_dfs_tgt_counters_show(struct seq_file *s, void *unused)
@@ -244,20 +352,7 @@ qla_dfs_tgt_counters_show(struct seq_file *s, void *unused)
return 0;
}
static int
qla_dfs_tgt_counters_open(struct inode *inode, struct file *file)
{
struct scsi_qla_host *vha = inode->i_private;
return single_open(file, qla_dfs_tgt_counters_show, vha);
}
static const struct file_operations dfs_tgt_counters_ops = {
.open = qla_dfs_tgt_counters_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
DEFINE_SHOW_ATTRIBUTE(qla_dfs_tgt_counters);
static int
qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
@@ -459,23 +554,35 @@ create_dir:
create_nodes:
ha->dfs_fw_resource_cnt = debugfs_create_file("fw_resource_count",
S_IRUSR, ha->dfs_dir, vha, &dfs_fw_resource_cnt_ops);
S_IRUSR, ha->dfs_dir, vha, &qla_dfs_fw_resource_cnt_fops);
ha->dfs_tgt_counters = debugfs_create_file("tgt_counters", S_IRUSR,
ha->dfs_dir, vha, &dfs_tgt_counters_ops);
ha->dfs_dir, vha, &qla_dfs_tgt_counters_fops);
ha->tgt.dfs_tgt_port_database = debugfs_create_file("tgt_port_database",
S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_port_database_ops);
S_IRUSR, ha->dfs_dir, vha, &qla2x00_dfs_tgt_port_database_fops);
ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
&dfs_fce_ops);
ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess",
S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_sess_ops);
S_IRUSR, ha->dfs_dir, vha, &qla2x00_dfs_tgt_sess_fops);
if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha))
if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) {
ha->tgt.dfs_naqp = debugfs_create_file("naqp",
0400, ha->dfs_dir, vha, &dfs_naqp_ops);
if (!ha->tgt.dfs_naqp) {
ql_log(ql_log_warn, vha, 0xd011,
"Unable to create debugFS naqp node.\n");
goto out;
}
}
vha->dfs_rport_root = debugfs_create_dir("rports", ha->dfs_dir);
if (!vha->dfs_rport_root) {
ql_log(ql_log_warn, vha, 0xd012,
"Unable to create debugFS rports node.\n");
goto out;
}
out:
return 0;
}
@@ -515,6 +622,11 @@ qla2x00_dfs_remove(scsi_qla_host_t *vha)
ha->dfs_fce = NULL;
}
if (vha->dfs_rport_root) {
debugfs_remove_recursive(vha->dfs_rport_root);
vha->dfs_rport_root = NULL;
}
if (ha->dfs_dir) {
debugfs_remove(ha->dfs_dir);
ha->dfs_dir = NULL;
+2 -3
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifndef __QLA_FW_H
#define __QLA_FW_H
@@ -631,7 +630,7 @@ struct sts_entry_24xx {
#define SF_NVME_ERSP BIT_6
#define SF_FCP_RSP_DMA BIT_0
__le16 retry_delay;
__le16 status_qualifier;
__le16 scsi_status; /* SCSI status. */
#define SS_CONFIRMATION_REQ BIT_12
+8 -3
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifndef __QLA_GBL_H
#define __QLA_GBL_H
@@ -129,6 +128,8 @@ int qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *);
void qla_rscn_replay(fc_port_t *fcport);
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 *);
/*
* Global Data in qla_os.c source file.
@@ -179,6 +180,7 @@ extern int qla2xuseresexchforels;
extern int ql2xexlogins;
extern int ql2xdifbundlinginternalbuffers;
extern int ql2xfulldump_on_mpifail;
extern int ql2xenforce_iocb_limit;
extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
@@ -708,6 +710,8 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *);
void qla24xx_handle_gfpnid_event(scsi_qla_host_t *, struct event_arg *);
void qla24xx_sp_unmap(scsi_qla_host_t *, srb_t *);
void qla_scan_work_fn(struct work_struct *);
uint qla25xx_fdmi_port_speed_capability(struct qla_hw_data *);
uint qla25xx_fdmi_port_speed_currently(struct qla_hw_data *);
/*
* Global Function Prototypes in qla_attr.c source file.
@@ -944,9 +948,10 @@ 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);
extern void qla24xx_process_purex_list(struct purex_list *);
extern void qla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp);
extern void qla2x00_dfs_remove_rport(scsi_qla_host_t *vha, struct fc_port *fp);
/* nvme.c */
void qla_nvme_unregister_remote_port(struct fc_port *fcport);
void qla27xx_reset_mpi(scsi_qla_host_t *vha);
void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea);
#endif /* _QLA_GBL_H */
+9 -9
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include "qla_target.h"
@@ -1502,7 +1501,7 @@ qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
return &p->p.req;
}
static uint
uint
qla25xx_fdmi_port_speed_capability(struct qla_hw_data *ha)
{
uint speeds = 0;
@@ -1546,7 +1545,7 @@ qla25xx_fdmi_port_speed_capability(struct qla_hw_data *ha)
}
return speeds;
}
if (IS_QLA25XX(ha))
if (IS_QLA25XX(ha) || IS_QLAFX00(ha))
return FDMI_PORT_SPEED_8GB|FDMI_PORT_SPEED_4GB|
FDMI_PORT_SPEED_2GB|FDMI_PORT_SPEED_1GB;
if (IS_QLA24XX_TYPE(ha))
@@ -1556,7 +1555,8 @@ qla25xx_fdmi_port_speed_capability(struct qla_hw_data *ha)
return FDMI_PORT_SPEED_2GB|FDMI_PORT_SPEED_1GB;
return FDMI_PORT_SPEED_1GB;
}
static uint
uint
qla25xx_fdmi_port_speed_currently(struct qla_hw_data *ha)
{
switch (ha->link_data_rate) {
@@ -3558,10 +3558,10 @@ login_logout:
if (fcport->flags & FCF_FCP2_DEVICE)
fcport->logout_on_delete = 0;
ql_dbg(ql_dbg_disc, vha, 0x20f0,
"%s %d %8phC post del sess\n",
__func__, __LINE__,
fcport->port_name);
ql_log(ql_log_warn, vha, 0x20f0,
"%s %d %8phC post del sess\n",
__func__, __LINE__,
fcport->port_name);
qlt_schedule_sess_for_deletion(fcport);
continue;
+133 -56
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include "qla_gbl.h"
@@ -63,6 +62,16 @@ void qla2x00_sp_free(srb_t *sp)
qla2x00_rel_sp(sp);
}
void qla2xxx_rel_done_warning(srb_t *sp, int res)
{
WARN_ONCE(1, "Calling done() of an already freed srb %p object\n", sp);
}
void qla2xxx_rel_free_warning(srb_t *sp)
{
WARN_ONCE(1, "Calling free() of an already freed srb %p object\n", sp);
}
/* Asynchronous Login/Logout Routines -------------------------------------- */
unsigned long
@@ -1259,9 +1268,10 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI;
ql_dbg(ql_dbg_disc, vha, 0x211b,
"Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n",
"Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d fc4type %x priority %x %s.\n",
fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24,
fcport->login_retry, NVME_TARGET(vha->hw, fcport) ? "nvme" : "fc");
fcport->login_retry, fcport->fc4_type, vha->hw->fc4_type_priority,
NVME_TARGET(vha->hw, fcport) ? "nvme" : "fcp");
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
@@ -1923,26 +1933,58 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
break;
}
/*
* Retry PRLI with other FC-4 type if failure occurred on dual
* FCP/NVMe port
*/
if (NVME_FCP_TARGET(ea->fcport)) {
ql_dbg(ql_dbg_disc, vha, 0x2118,
"%s %d %8phC post %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;
}
ql_dbg(ql_dbg_disc, vha, 0x2118,
"%s %d %8phC priority %s, fc4type %x\n",
__func__, __LINE__, ea->fcport->port_name,
vha->hw->fc4_type_priority == FC4_PRIORITY_FCP ?
"FCP" : "NVMe", ea->fcport->fc4_type);
ea->fcport->flags &= ~FCF_ASYNC_SENT;
ea->fcport->keep_nport_handle = 0;
ea->fcport->logout_on_delete = 1;
qlt_schedule_sess_for_deletion(ea->fcport);
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) {
ea->fcport->n2n_link_reset_cnt++;
vha->relogin_jif = jiffies + 2 * HZ;
/*
* PRLI failed. Reset link to kick start
* state machine
*/
set_bit(N2N_LINK_RESET, &vha->dpc_flags);
} else {
ql_log(ql_log_warn, vha, 0x2119,
"%s %d %8phC Unable to reconnect\n",
__func__, __LINE__,
ea->fcport->port_name);
}
} else {
/*
* switch connect. login failed. Take connection down
* and allow relogin to retrigger
*/
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;
qlt_schedule_sess_for_deletion(ea->fcport);
}
break;
}
}
@@ -3288,6 +3330,8 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
j, fwdt->dump_size);
dump_size += fwdt->dump_size;
}
/* Add space for spare MPI fw dump. */
dump_size += ha->fwdt[1].dump_size;
} else {
req_q_size = req->length * sizeof(request_t);
rsp_q_size = rsp->length * sizeof(response_t);
@@ -3622,6 +3666,31 @@ out:
return ha->flags.lr_detected;
}
void qla_init_iocb_limit(scsi_qla_host_t *vha)
{
u16 i, num_qps;
u32 limit;
struct qla_hw_data *ha = vha->hw;
num_qps = ha->num_qpairs + 1;
limit = (ha->orig_fw_iocb_count * QLA_IOCB_PCT_LIMIT) / 100;
ha->base_qpair->fwres.iocbs_total = ha->orig_fw_iocb_count;
ha->base_qpair->fwres.iocbs_limit = limit;
ha->base_qpair->fwres.iocbs_qp_limit = limit / num_qps;
ha->base_qpair->fwres.iocbs_used = 0;
for (i = 0; i < ha->max_qpairs; i++) {
if (ha->queue_pair_map[i]) {
ha->queue_pair_map[i]->fwres.iocbs_total =
ha->orig_fw_iocb_count;
ha->queue_pair_map[i]->fwres.iocbs_limit = limit;
ha->queue_pair_map[i]->fwres.iocbs_qp_limit =
limit / num_qps;
ha->queue_pair_map[i]->fwres.iocbs_used = 0;
}
}
}
/**
* qla2x00_setup_chip() - Load and start RISC firmware.
* @vha: HA context
@@ -3690,9 +3759,7 @@ execute_fw_with_lr:
goto execute_fw_with_lr;
}
if ((IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
IS_QLA28XX(ha)) &&
(ha->zio_mode == QLA_ZIO_MODE_6))
if (IS_ZIO_THRESHOLD_CAPABLE(ha))
qla27xx_set_zio_threshold(vha,
ha->last_zio_threshold);
@@ -3723,6 +3790,7 @@ enable_82xx_npiv:
MIN_MULTI_ID_FABRIC - 1;
}
qla2x00_get_resource_cnts(vha);
qla_init_iocb_limit(vha);
/*
* Allocate the array of outstanding commands
@@ -4603,18 +4671,18 @@ qla2x00_nvram_config(scsi_qla_host_t *vha)
nv->firmware_options[1] = BIT_7 | BIT_5;
nv->add_firmware_options[0] = BIT_5;
nv->add_firmware_options[1] = BIT_5 | BIT_4;
nv->frame_payload_size = 2048;
nv->frame_payload_size = cpu_to_le16(2048);
nv->special_options[1] = BIT_7;
} else if (IS_QLA2200(ha)) {
nv->firmware_options[0] = BIT_2 | BIT_1;
nv->firmware_options[1] = BIT_7 | BIT_5;
nv->add_firmware_options[0] = BIT_5;
nv->add_firmware_options[1] = BIT_5 | BIT_4;
nv->frame_payload_size = 1024;
nv->frame_payload_size = cpu_to_le16(1024);
} else if (IS_QLA2100(ha)) {
nv->firmware_options[0] = BIT_3 | BIT_1;
nv->firmware_options[1] = BIT_5;
nv->frame_payload_size = 1024;
nv->frame_payload_size = cpu_to_le16(1024);
}
nv->max_iocb_allocation = cpu_to_le16(256);
@@ -4939,6 +5007,9 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
INIT_LIST_HEAD(&fcport->gnl_entry);
INIT_LIST_HEAD(&fcport->list);
INIT_LIST_HEAD(&fcport->sess_cmd_list);
spin_lock_init(&fcport->sess_cmd_lock);
return fcport;
}
@@ -4957,6 +5028,29 @@ qla2x00_free_fcport(fc_port_t *fcport)
kfree(fcport);
}
static void qla_get_login_template(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
int rval;
u32 *bp, sz;
__be32 *q;
memset(ha->init_cb, 0, ha->init_cb_size);
sz = min_t(int, sizeof(struct fc_els_flogi), ha->init_cb_size);
rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
ha->init_cb, sz);
if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_init, vha, 0x00d1,
"PLOGI ELS param read fail.\n");
return;
}
q = (__be32 *)&ha->plogi_els_payld.fl_csp;
bp = (uint32_t *)ha->init_cb;
cpu_to_be32_array(q, bp, sz / 4);
ha->flags.plogi_template_valid = 1;
}
/*
* qla2x00_configure_loop
* Updates Fibre Channel Device Database with what is actually on loop.
@@ -5000,6 +5094,7 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
clear_bit(RSCN_UPDATE, &vha->dpc_flags);
qla2x00_get_data_rate(vha);
qla_get_login_template(vha);
/* Determine what we need to do */
if ((ha->current_topology == ISP_CFG_FL ||
@@ -5084,32 +5179,11 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
unsigned long flags;
fc_port_t *fcport;
int rval;
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
/* borrowing */
u32 *bp, sz;
memset(ha->init_cb, 0, ha->init_cb_size);
sz = min_t(int, sizeof(struct els_plogi_payload),
ha->init_cb_size);
rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
ha->init_cb, sz);
if (rval == QLA_SUCCESS) {
__be32 *q = &ha->plogi_els_payld.data[0];
bp = (uint32_t *)ha->init_cb;
cpu_to_be32_array(q, bp, sz / 4);
memcpy(bp, q, sizeof(ha->plogi_els_payld.data));
} else {
ql_dbg(ql_dbg_init, vha, 0x00d1,
"PLOGI ELS param read fail.\n");
goto skip_login;
}
}
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags))
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (fcport->n2n_flag) {
@@ -5118,7 +5192,6 @@ static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
}
}
skip_login:
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_retry++;
spin_unlock_irqrestore(&vha->work_lock, flags);
@@ -5486,6 +5559,8 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
qla2x00_iidma_fcport(vha, fcport);
qla2x00_dfs_create_rport(vha, fcport);
if (NVME_TARGET(vha->hw, fcport)) {
qla_nvme_register_remote(vha, fcport);
qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
@@ -5907,6 +5982,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
break;
}
if (fcport->login_retry == 0)
fcport->login_retry =
vha->hw->login_retry_count;
/*
* If device was not a fabric device before.
*/
@@ -7109,10 +7187,9 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha)
unsigned long flags = 0;
struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
int rval = QLA_SUCCESS;
if (IS_P3P_TYPE(ha))
return rval;
return QLA_SUCCESS;
vha->flags.online = 0;
ha->isp_ops->disable_intrs(ha);
@@ -7127,7 +7204,7 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha)
if (IS_NOPOLLING_TYPE(ha))
ha->isp_ops->enable_intrs(ha);
return rval;
return QLA_SUCCESS;
}
/* On sparc systems, obtain port and node WWN from firmware
+95 -6
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifdef INSIDE_KERNEL_TREE
@@ -215,10 +214,15 @@ qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair,
return sp;
}
void qla2xxx_rel_done_warning(srb_t *sp, int res);
void qla2xxx_rel_free_warning(srb_t *sp);
static inline void
qla2xxx_rel_qpair_sp(struct qla_qpair *qpair, srb_t *sp)
{
sp->qpair = NULL;
sp->done = qla2xxx_rel_done_warning;
sp->free = qla2xxx_rel_free_warning;
mempool_free(sp, qpair->srb_mempool);
QLA_QPAIR_MARK_NOT_BUSY(qpair);
}
@@ -274,11 +278,41 @@ qla2x00_handle_mbx_completion(struct qla_hw_data *ha, int status)
}
static inline void
qla2x00_set_retry_delay_timestamp(fc_port_t *fcport, uint16_t retry_delay)
qla2x00_set_retry_delay_timestamp(fc_port_t *fcport, uint16_t sts_qual)
{
if (retry_delay)
fcport->retry_delay_timestamp = jiffies +
(retry_delay * HZ / 10);
u8 scope;
u16 qual;
#define SQ_SCOPE_MASK 0xc000 /* SAM-6 rev5 5.3.2 */
#define SQ_SCOPE_SHIFT 14
#define SQ_QUAL_MASK 0x3fff
#define SQ_MAX_WAIT_SEC 60 /* Max I/O hold off time in seconds. */
#define SQ_MAX_WAIT_TIME (SQ_MAX_WAIT_SEC * 10) /* in 100ms. */
if (!sts_qual) /* Common case. */
return;
scope = (sts_qual & SQ_SCOPE_MASK) >> SQ_SCOPE_SHIFT;
/* Handle only scope 1 or 2, which is for I-T nexus. */
if (scope != 1 && scope != 2)
return;
/* Skip processing, if retry delay timer is already in effect. */
if (fcport->retry_delay_timestamp &&
time_before(jiffies, fcport->retry_delay_timestamp))
return;
qual = sts_qual & SQ_QUAL_MASK;
if (qual < 1 || qual > 0x3fef)
return;
qual = min(qual, (u16)SQ_MAX_WAIT_TIME);
/* qual is expressed in 100ms increments. */
fcport->retry_delay_timestamp = jiffies + (qual * HZ / 10);
ql_log(ql_log_warn, fcport->vha, 0x5101,
"%8phC: I/O throttling requested (status qualifier = %04xh), holding off I/Os for %ums.\n",
fcport->port_name, sts_qual, qual * 100);
}
static inline bool
@@ -351,3 +385,58 @@ qla2xxx_get_fc4_priority(struct scsi_qla_host *vha)
return (data >> 6) & BIT_0 ? FC4_PRIORITY_FCP : FC4_PRIORITY_NVME;
}
enum {
RESOURCE_NONE,
RESOURCE_INI,
};
static inline int
qla_get_iocbs(struct qla_qpair *qp, struct iocb_resource *iores)
{
u16 iocbs_used, i;
struct qla_hw_data *ha = qp->vha->hw;
if (!ql2xenforce_iocb_limit) {
iores->res_type = RESOURCE_NONE;
return 0;
}
if ((iores->iocb_cnt + qp->fwres.iocbs_used) < qp->fwres.iocbs_qp_limit) {
qp->fwres.iocbs_used += iores->iocb_cnt;
return 0;
} else {
/* no need to acquire qpair lock. It's just rough calculation */
iocbs_used = ha->base_qpair->fwres.iocbs_used;
for (i = 0; i < ha->max_qpairs; i++) {
if (ha->queue_pair_map[i])
iocbs_used += ha->queue_pair_map[i]->fwres.iocbs_used;
}
if ((iores->iocb_cnt + iocbs_used) < qp->fwres.iocbs_limit) {
qp->fwres.iocbs_used += iores->iocb_cnt;
return 0;
} else {
iores->res_type = RESOURCE_NONE;
return -ENOSPC;
}
}
}
static inline void
qla_put_iocbs(struct qla_qpair *qp, struct iocb_resource *iores)
{
switch (iores->res_type) {
case RESOURCE_NONE:
break;
default:
if (qp->fwres.iocbs_used >= iores->iocb_cnt) {
qp->fwres.iocbs_used -= iores->iocb_cnt;
} else {
// should not happen
qp->fwres.iocbs_used = 0;
}
break;
}
iores->res_type = RESOURCE_NONE;
}
+48 -12
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include "qla_target.h"
@@ -594,6 +593,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
uint32_t dsd_list_len;
struct dsd_dma *dsd_ptr;
struct ct6_dsd *ctx;
struct qla_qpair *qpair = sp->qpair;
cmd = GET_CMD_SP(sp);
@@ -612,12 +612,12 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
/* Set transfer direction */
if (cmd->sc_data_direction == DMA_TO_DEVICE) {
cmd_pkt->control_flags = cpu_to_le16(CF_WRITE_DATA);
vha->qla_stats.output_bytes += scsi_bufflen(cmd);
vha->qla_stats.output_requests++;
qpair->counters.output_bytes += scsi_bufflen(cmd);
qpair->counters.output_requests++;
} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
cmd_pkt->control_flags = cpu_to_le16(CF_READ_DATA);
vha->qla_stats.input_bytes += scsi_bufflen(cmd);
vha->qla_stats.input_requests++;
qpair->counters.input_bytes += scsi_bufflen(cmd);
qpair->counters.input_requests++;
}
cur_seg = scsi_sglist(cmd);
@@ -704,6 +704,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
struct scsi_cmnd *cmd;
struct scatterlist *sg;
int i;
struct qla_qpair *qpair = sp->qpair;
cmd = GET_CMD_SP(sp);
@@ -721,12 +722,12 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
/* Set transfer direction */
if (cmd->sc_data_direction == DMA_TO_DEVICE) {
cmd_pkt->task_mgmt_flags = cpu_to_le16(TMF_WRITE_DATA);
vha->qla_stats.output_bytes += scsi_bufflen(cmd);
vha->qla_stats.output_requests++;
qpair->counters.output_bytes += scsi_bufflen(cmd);
qpair->counters.output_requests++;
} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
cmd_pkt->task_mgmt_flags = cpu_to_le16(TMF_READ_DATA);
vha->qla_stats.input_bytes += scsi_bufflen(cmd);
vha->qla_stats.input_requests++;
qpair->counters.input_bytes += scsi_bufflen(cmd);
qpair->counters.input_requests++;
}
/* One DSD is available in the Command Type 3 IOCB */
@@ -1641,6 +1642,12 @@ qla24xx_start_scsi(srb_t *sp)
tot_dsds = nseg;
req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
sp->iores.res_type = RESOURCE_INI;
sp->iores.iocb_cnt = req_cnt;
if (qla_get_iocbs(sp->qpair, &sp->iores))
goto queuing_error;
if (req->cnt < (req_cnt + 2)) {
cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
rd_reg_dword_relaxed(req->req_q_out);
@@ -1713,6 +1720,7 @@ queuing_error:
if (tot_dsds)
scsi_dma_unmap(cmd);
qla_put_iocbs(sp->qpair, &sp->iores);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return QLA_FUNCTION_FAILED;
@@ -1826,6 +1834,12 @@ qla24xx_dif_start_scsi(srb_t *sp)
/* Total Data and protection sg segment(s) */
tot_prot_dsds = nseg;
tot_dsds += nseg;
sp->iores.res_type = RESOURCE_INI;
sp->iores.iocb_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
if (qla_get_iocbs(sp->qpair, &sp->iores))
goto queuing_error;
if (req->cnt < (req_cnt + 2)) {
cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
rd_reg_dword_relaxed(req->req_q_out);
@@ -1900,6 +1914,7 @@ queuing_error:
}
/* Cleanup will be performed by the caller (queuecommand) */
qla_put_iocbs(sp->qpair, &sp->iores);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return QLA_FUNCTION_FAILED;
}
@@ -1961,6 +1976,12 @@ qla2xxx_start_scsi_mq(srb_t *sp)
tot_dsds = nseg;
req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
sp->iores.res_type = RESOURCE_INI;
sp->iores.iocb_cnt = req_cnt;
if (qla_get_iocbs(sp->qpair, &sp->iores))
goto queuing_error;
if (req->cnt < (req_cnt + 2)) {
cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
rd_reg_dword_relaxed(req->req_q_out);
@@ -2033,6 +2054,7 @@ queuing_error:
if (tot_dsds)
scsi_dma_unmap(cmd);
qla_put_iocbs(sp->qpair, &sp->iores);
spin_unlock_irqrestore(&qpair->qp_lock, flags);
return QLA_FUNCTION_FAILED;
@@ -2161,6 +2183,12 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp)
/* Total Data and protection sg segment(s) */
tot_prot_dsds = nseg;
tot_dsds += nseg;
sp->iores.res_type = RESOURCE_INI;
sp->iores.iocb_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
if (qla_get_iocbs(sp->qpair, &sp->iores))
goto queuing_error;
if (req->cnt < (req_cnt + 2)) {
cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
rd_reg_dword_relaxed(req->req_q_out);
@@ -2238,6 +2266,7 @@ queuing_error:
}
/* Cleanup will be performed by the caller (queuecommand) */
qla_put_iocbs(sp->qpair, &sp->iores);
spin_unlock_irqrestore(&qpair->qp_lock, flags);
return QLA_FUNCTION_FAILED;
}
@@ -2354,6 +2383,14 @@ qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio)
if (sp->vha->flags.nvme_first_burst)
logio->io_parameter[0] =
cpu_to_le32(NVME_PRLI_SP_FIRST_BURST);
if (sp->vha->flags.nvme2_enabled) {
/* Set service parameter BIT_8 for SLER support */
logio->io_parameter[0] |=
cpu_to_le32(NVME_PRLI_SP_SLER);
/* Set service parameter BIT_9 for PI control support */
logio->io_parameter[0] |=
cpu_to_le32(NVME_PRLI_SP_PI_CTRL);
}
}
logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
@@ -2981,8 +3018,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
memset(ptr, 0, sizeof(struct els_plogi_payload));
memset(resp_ptr, 0, sizeof(struct els_plogi_payload));
memcpy(elsio->u.els_plogi.els_plogi_pyld->data,
&ha->plogi_els_payld.data,
sizeof(elsio->u.els_plogi.els_plogi_pyld->data));
&ha->plogi_els_payld.fl_csp, LOGIN_TEMPLATE_SIZE);
elsio->u.els_plogi.els_cmd = els_opcode;
elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode;
+68 -31
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include "qla_target.h"
@@ -779,7 +778,7 @@ qla27xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
ql_log(ql_log_warn, vha, 0x02f0,
"MPI Heartbeat stop. MPI reset is%s needed. "
"MB0[%xh] MB1[%xh] MB2[%xh] MB3[%xh]\n",
mb[0] & BIT_8 ? "" : " not",
mb[1] & BIT_8 ? "" : " not",
mb[0], mb[1], mb[2], mb[3]);
if ((mb[1] & BIT_8) == 0)
@@ -1728,35 +1727,35 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
{
struct qla_hw_data *ha = vha->hw;
sts_entry_t *pkt = iocb;
srb_t *sp = NULL;
srb_t *sp;
uint16_t index;
index = LSW(pkt->handle);
if (index >= req->num_outstanding_cmds) {
ql_log(ql_log_warn, vha, 0x5031,
"Invalid command index (%x) type %8ph.\n",
index, iocb);
"%s: Invalid command index (%x) type %8ph.\n",
func, index, iocb);
if (IS_P3P_TYPE(ha))
set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
else
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
goto done;
return NULL;
}
sp = req->outstanding_cmds[index];
if (!sp) {
ql_log(ql_log_warn, vha, 0x5032,
"Invalid completion handle (%x) -- timed-out.\n", index);
return sp;
"%s: Invalid completion handle (%x) -- timed-out.\n",
func, index);
return NULL;
}
if (sp->handle != index) {
ql_log(ql_log_warn, vha, 0x5033,
"SRB handle (%x) mismatch %x.\n", sp->handle, index);
"%s: SRB handle (%x) mismatch %x.\n", func,
sp->handle, index);
return NULL;
}
req->outstanding_cmds[index] = NULL;
done:
return sp;
}
@@ -1851,6 +1850,7 @@ qla24xx_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
struct mbx_24xx_entry *pkt)
{
const char func[] = "MBX-IOCB2";
struct qla_hw_data *ha = vha->hw;
srb_t *sp;
struct srb_iocb *si;
u16 sz, i;
@@ -1860,6 +1860,18 @@ qla24xx_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
if (!sp)
return;
if (sp->type == SRB_SCSI_CMD ||
sp->type == SRB_NVME_CMD ||
sp->type == SRB_TM_CMD) {
ql_log(ql_log_warn, vha, 0x509d,
"Inconsistent event entry type %d\n", sp->type);
if (IS_P3P_TYPE(ha))
set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
else
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
return;
}
si = &sp->u.iocb_cmd;
sz = min(ARRAY_SIZE(pkt->mb), ARRAY_SIZE(sp->u.iocb_cmd.u.mbx.in_mb));
@@ -2234,11 +2246,13 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
srb_t *sp;
struct srb_iocb *iocb;
struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
u16 comp_status;
sp = qla2x00_get_sp_from_handle(vha, func, req, tsk);
if (!sp)
return;
comp_status = le16_to_cpu(sts->comp_status);
iocb = &sp->u.iocb_cmd;
type = sp->name;
fcport = sp->fcport;
@@ -2252,7 +2266,7 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
} else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) {
ql_log(ql_log_warn, fcport->vha, 0x5039,
"Async-%s error - hdl=%x completion status(%x).\n",
type, sp->handle, sts->comp_status);
type, sp->handle, comp_status);
iocb->u.tmf.data = QLA_FUNCTION_FAILED;
} else if ((le16_to_cpu(sts->scsi_status) &
SS_RESPONSE_INFO_LEN_VALID)) {
@@ -2268,6 +2282,30 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
}
}
switch (comp_status) {
case CS_PORT_LOGGED_OUT:
case CS_PORT_CONFIG_CHG:
case CS_PORT_BUSY:
case CS_INCOMPLETE:
case CS_PORT_UNAVAILABLE:
case CS_TIMEOUT:
case CS_RESET:
if (atomic_read(&fcport->state) == FCS_ONLINE) {
ql_dbg(ql_dbg_disc, fcport->vha, 0x3021,
"-Port to be marked lost on fcport=%02x%02x%02x, current port state= %s comp_status %x.\n",
fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa,
port_state_str[FCS_ONLINE],
comp_status);
qlt_schedule_sess_for_deletion(fcport);
}
break;
default:
break;
}
if (iocb->u.tmf.data != QLA_SUCCESS)
ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, sp->vha, 0x5055,
sts, sizeof(*sts));
@@ -2890,7 +2928,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
int logit = 1;
int res = 0;
uint16_t state_flags = 0;
uint16_t retry_delay = 0;
uint16_t sts_qual = 0;
if (IS_FWI2_CAPABLE(ha)) {
comp_status = le16_to_cpu(sts24->comp_status);
@@ -2936,6 +2974,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
}
return;
}
qla_put_iocbs(sp->qpair, &sp->iores);
if (sp->cmd_type != TYPE_SRB) {
req->outstanding_cmds[handle] = NULL;
@@ -2988,8 +3027,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
sense_len = par_sense_len = rsp_info_len = resid_len =
fw_resid_len = 0;
if (IS_FWI2_CAPABLE(ha)) {
u16 sts24_retry_delay = le16_to_cpu(sts24->retry_delay);
if (scsi_status & SS_SENSE_LEN_VALID)
sense_len = le32_to_cpu(sts24->sense_len);
if (scsi_status & SS_RESPONSE_INFO_LEN_VALID)
@@ -3003,13 +3040,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
host_to_fcp_swap(sts24->data, sizeof(sts24->data));
ox_id = le16_to_cpu(sts24->ox_id);
par_sense_len = sizeof(sts24->data);
/* Valid values of the retry delay timer are 0x1-0xffef */
if (sts24_retry_delay > 0 && sts24_retry_delay < 0xfff1) {
retry_delay = sts24_retry_delay & 0x3fff;
ql_dbg(ql_dbg_io, sp->vha, 0x3033,
"%s: scope=%#x retry_delay=%#x\n", __func__,
sts24_retry_delay >> 14, retry_delay);
}
sts_qual = le16_to_cpu(sts24->status_qualifier);
} else {
if (scsi_status & SS_SENSE_LEN_VALID)
sense_len = le16_to_cpu(sts->req_sense_length);
@@ -3047,9 +3078,9 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
* Check retry_delay_timer value if we receive a busy or
* queue full.
*/
if (lscsi_status == SAM_STAT_TASK_SET_FULL ||
lscsi_status == SAM_STAT_BUSY)
qla2x00_set_retry_delay_timestamp(fcport, retry_delay);
if (unlikely(lscsi_status == SAM_STAT_TASK_SET_FULL ||
lscsi_status == SAM_STAT_BUSY))
qla2x00_set_retry_delay_timestamp(fcport, sts_qual);
/*
* Based on Host and scsi status generate status code for Linux
@@ -3356,6 +3387,7 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
default:
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
if (sp) {
qla_put_iocbs(sp->qpair, &sp->iores);
sp->done(sp, res);
return 0;
}
@@ -3457,8 +3489,11 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
if (!ha->flags.fw_started)
return;
if (rsp->qpair->cpuid != raw_smp_processor_id())
if (rsp->qpair->cpuid != raw_smp_processor_id() ||
!rsp->qpair->rcv_intr) {
rsp->qpair->rcv_intr = 1;
qla_cpu_update(rsp->qpair, raw_smp_processor_id());
}
while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
@@ -3908,7 +3943,7 @@ qla2xxx_msix_rsp_q(int irq, void *dev_id)
}
ha = qpair->hw;
queue_work(ha->wq, &qpair->q_work);
queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work);
return IRQ_HANDLED;
}
@@ -3934,7 +3969,7 @@ qla2xxx_msix_rsp_q_hs(int irq, void *dev_id)
wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_INT);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
queue_work(ha->wq, &qpair->q_work);
queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work);
return IRQ_HANDLED;
}
@@ -4047,10 +4082,12 @@ msix_failed:
if (USER_CTRL_IRQ(ha) || !ha->mqiobase) {
/* user wants to control IRQ setting for target mode */
ret = pci_alloc_irq_vectors(ha->pdev, min_vecs,
ha->msix_count, PCI_IRQ_MSIX);
min((u16)ha->msix_count, (u16)num_online_cpus()),
PCI_IRQ_MSIX);
} else
ret = pci_alloc_irq_vectors_affinity(ha->pdev, min_vecs,
ha->msix_count, PCI_IRQ_MSIX | PCI_IRQ_AFFINITY,
min((u16)ha->msix_count, (u16)num_online_cpus()),
PCI_IRQ_MSIX | PCI_IRQ_AFFINITY,
&desc);
#endif
+24 -52
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include "qla_target.h"
@@ -845,7 +844,7 @@ qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
* Context:
* Kernel context.
*/
#define CONFIG_XLOGINS_MEM 0x3
#define CONFIG_XLOGINS_MEM 0x9
int
qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
{
@@ -872,8 +871,9 @@ qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS) {
/*EMPTY*/
ql_dbg(ql_dbg_mbx, vha, 0x111b, "Failed=%x.\n", rval);
ql_dbg(ql_dbg_mbx, vha, 0x111b,
"EXlogin Failed=%x. MB0=%x MB11=%x\n",
rval, mcp->mb[0], mcp->mb[11]);
} else {
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
"Done %s.\n", __func__);
@@ -1092,6 +1092,14 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
"%s: FC-NVMe is Enabled (0x%x)\n",
__func__, ha->fw_attributes_h);
}
/* BIT_13 of Extended FW Attributes informs about NVMe2 support */
if (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_NVME2) {
ql_log(ql_log_info, vha, 0xd302,
"Firmware supports NVMe2 0x%x\n",
ha->fw_attributes_ext[0]);
vha->flags.nvme2_enabled = 1;
}
}
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
@@ -1121,12 +1129,18 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
if (ha->flags.scm_supported_a &&
(ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) {
ha->flags.scm_supported_f = 1;
memset(ha->sf_init_cb, 0, sizeof(struct init_sf_cb));
ha->sf_init_cb->flags |= BIT_13;
ha->sf_init_cb->flags |= cpu_to_le16(BIT_13);
}
ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n",
(ha->flags.scm_supported_f) ? "Supported" :
"Not Supported");
if (vha->flags.nvme2_enabled) {
/* set BIT_15 of special feature control block for SLER */
ha->sf_init_cb->flags |= cpu_to_le16(BIT_15);
/* set BIT_14 of special feature control block for PI CTRL*/
ha->sf_init_cb->flags |= cpu_to_le16(BIT_14);
}
}
failed:
@@ -1822,7 +1836,7 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
}
if (ha->flags.scm_supported_f) {
if (ha->flags.scm_supported_f || vha->flags.nvme2_enabled) {
mcp->mb[1] |= BIT_1;
mcp->mb[16] = MSW(ha->sf_init_cb_dma);
mcp->mb[17] = LSW(ha->sf_init_cb_dma);
@@ -3979,13 +3993,11 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
if (fcport) {
fcport->plogi_nack_done_deadline = jiffies + HZ;
fcport->dm_login_expire = jiffies + 2*HZ;
fcport->dm_login_expire = jiffies +
QLA_N2N_WAIT_TIME * HZ;
fcport->scan_state = QLA_FCPORT_FOUND;
fcport->n2n_flag = 1;
fcport->keep_nport_handle = 1;
fcport->fc4_type = FS_FC4TYPE_FCP;
if (vha->flags.nvme_enabled)
fcport->fc4_type |= FS_FC4TYPE_NVME;
if (wwn_to_u64(vha->port_name) >
wwn_to_u64(fcport->port_name)) {
@@ -4015,7 +4027,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
return;
break;
case TOPO_FL:
ha->current_topology = ISP_CFG_FL;
break;
@@ -4962,45 +4973,6 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
return rval;
}
int
qla24xx_get_buffer_credits(scsi_qla_host_t *vha, struct buffer_credit_24xx *bbc,
dma_addr_t bbc_dma)
{
mbx_cmd_t mc;
mbx_cmd_t *mcp = &mc;
int rval;
if (!IS_FWI2_CAPABLE(vha->hw))
return QLA_FUNCTION_FAILED;
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118e,
"Entered %s.\n", __func__);
mcp->mb[0] = MBC_GET_RNID_PARAMS;
mcp->mb[1] = RNID_BUFFER_CREDITS << 8;
mcp->mb[2] = MSW(LSD(bbc_dma));
mcp->mb[3] = LSW(LSD(bbc_dma));
mcp->mb[6] = MSW(MSD(bbc_dma));
mcp->mb[7] = LSW(MSD(bbc_dma));
mcp->mb[8] = sizeof(*bbc) / sizeof(*bbc->parameter);
mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_1|MBX_0;
mcp->buf_size = sizeof(*bbc);
mcp->flags = MBX_DMA_IN;
mcp->tov = MBX_TOV_SECONDS;
rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_mbx, vha, 0x118f,
"Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
} else {
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1190,
"Done %s.\n", __func__);
}
return rval;
}
static int
qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
{
+2 -5
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include "qla_gbl.h"
@@ -808,11 +807,9 @@ static void qla_do_work(struct work_struct *work)
{
unsigned long flags;
struct qla_qpair *qpair = container_of(work, struct qla_qpair, q_work);
struct scsi_qla_host *vha;
struct qla_hw_data *ha = qpair->hw;
struct scsi_qla_host *vha = qpair->vha;
spin_lock_irqsave(&qpair->qp_lock, flags);
vha = pci_get_drvdata(ha->pdev);
qla24xx_process_response_queue(vha, qpair->rsp);
spin_unlock_irqrestore(&qpair->qp_lock, flags);
+1 -2
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include <linux/delay.h>
+1 -2
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifndef __QLA_MR_H
#define __QLA_MR_H
+35 -16
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2017 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include <linux/version.h>
@@ -50,9 +49,11 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
/*
* See also commit 9dd9686b1419 ("scsi: qla2xxx: Add changes for
* devloss timeout in driver") # v4.17.
* devloss timeout in driver") # v4.17. See also commit dd8d0bf6fb72
* ("scsi: qla2xxx: Fix I/O failures during remote port toggle
* testing") # v5.10.
*/
req.dev_loss_tmo = NVME_FC_DEV_LOSS_TMO;
req.dev_loss_tmo = 0;
#endif
if (fcport->nvme_prli_service_param & NVME_PRLI_SP_INITIATOR)
@@ -80,6 +81,14 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
return ret;
}
if (fcport->nvme_prli_service_param & NVME_PRLI_SP_SLER)
ql_log(ql_log_info, vha, 0x212a,
"PortID:%06x Supports SLER\n", req.port_id);
if (fcport->nvme_prli_service_param & NVME_PRLI_SP_PI_CTRL)
ql_log(ql_log_info, vha, 0x212b,
"PortID:%06x Supports PI control\n", req.port_id);
rport = fcport->nvme_remote_port->private;
rport->fcport = fcport;
@@ -231,7 +240,7 @@ static void qla_nvme_abort_work(struct work_struct *work)
"%s called for sp=%p, hndl=%x on fcport=%p deleted=%d\n",
__func__, sp, sp->handle, fcport, fcport->deleted);
if (!ha->flags.fw_started && fcport->deleted)
if (!ha->flags.fw_started || fcport->deleted)
goto out;
if (ha->flags.host_shutting_down) {
@@ -379,6 +388,7 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
struct srb_iocb *nvme = &sp->u.iocb_cmd;
struct scatterlist *sgl, *sg;
struct nvmefc_fcp_req *fd = nvme->u.nvme.desc;
struct nvme_fc_cmd_iu *cmd = fd->cmdaddr;
uint32_t rval = QLA_SUCCESS;
/* Setup qpair pointers */
@@ -410,8 +420,6 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
}
if (unlikely(!fd->sqid)) {
struct nvme_fc_cmd_iu *cmd = fd->cmdaddr;
if (cmd->sqe.common.opcode == nvme_admin_async_event) {
nvme->u.nvme.aen_op = 1;
atomic_inc(&ha->nvme_active_aen_cnt);
@@ -439,8 +447,8 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
/* No data transfer how do we check buffer len == 0?? */
if (fd->io_dir == NVMEFC_FCP_READ) {
cmd_pkt->control_flags = cpu_to_le16(CF_READ_DATA);
vha->qla_stats.input_bytes += fd->payload_length;
vha->qla_stats.input_requests++;
qpair->counters.input_bytes += fd->payload_length;
qpair->counters.input_requests++;
} else if (fd->io_dir == NVMEFC_FCP_WRITE) {
cmd_pkt->control_flags = cpu_to_le16(CF_WRITE_DATA);
if ((vha->flags.nvme_first_burst) &&
@@ -452,11 +460,16 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
cmd_pkt->control_flags |=
cpu_to_le16(CF_NVME_FIRST_BURST_ENABLE);
}
vha->qla_stats.output_bytes += fd->payload_length;
vha->qla_stats.output_requests++;
qpair->counters.output_bytes += fd->payload_length;
qpair->counters.output_requests++;
} else if (fd->io_dir == 0) {
cmd_pkt->control_flags = 0;
}
/* Set BIT_13 of control flags for Async event */
if (vha->flags.nvme2_enabled &&
cmd->sqe.common.opcode == nvme_admin_async_event) {
cmd_pkt->control_flags |= cpu_to_le16(CF_ADMIN_ASYNC_EVENT);
}
/* Set NPORT-ID */
cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
@@ -541,7 +554,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
fc_port_t *fcport;
struct srb_iocb *nvme;
struct scsi_qla_host *vha;
int rval = -ENODEV;
int rval;
srb_t *sp;
struct qla_qpair *qpair = hw_queue_handle;
struct nvme_private *priv = fd->private;
@@ -549,16 +562,22 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
if (!priv) {
/* nvme association has been torn down */
return rval;
return -ENODEV;
}
fcport = qla_rport->fcport;
if (!qpair || !fcport || (qpair && !qpair->fw_started) ||
(fcport && fcport->deleted))
return rval;
if (unlikely(!qpair || !fcport || fcport->deleted))
return -EBUSY;
if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED))
return -ENODEV;
vha = fcport->vha;
if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
return -EBUSY;
/*
* If we know the dev is going away while the transport is still sending
* IO's return busy back to stall the IO Q. This happens when the
+2 -5
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2017 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifndef __QLA_NVME_H
#define __QLA_NVME_H
@@ -17,9 +16,6 @@
#include "qla_def.h"
#include "qla_dsd.h"
/* default dev loss time (seconds) before transport tears down ctrl */
#define NVME_FC_DEV_LOSS_TMO 30
#define NVME_ATIO_CMD_OFF 32
#define NVME_FIRST_PACKET_CMDLEN (64 - NVME_ATIO_CMD_OFF)
#define Q2T_NVME_NUM_TAGS 2048
@@ -60,6 +56,7 @@ struct cmd_nvme {
uint64_t rsvd;
__le16 control_flags; /* Control Flags */
#define CF_ADMIN_ASYNC_EVENT BIT_13
#define CF_NVME_FIRST_BURST_ENABLE BIT_11
#define CF_DIF_SEG_DESCR_ENABLE BIT_3
#define CF_DATA_SEG_DESCR_ENABLE BIT_2
+13 -17
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include <linux/delay.h>
@@ -489,29 +488,26 @@ qla82xx_rd_32(struct qla_hw_data *ha, ulong off_in)
return data;
}
#define IDC_LOCK_TIMEOUT 100000000
/*
* Context: task, might sleep
*/
int qla82xx_idc_lock(struct qla_hw_data *ha)
{
int i;
int done = 0, timeout = 0;
const int delay_ms = 100, timeout_ms = 2000;
int done, total = 0;
while (!done) {
might_sleep();
while (true) {
/* acquire semaphore5 from PCI HW block */
done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_LOCK));
if (done == 1)
break;
if (timeout >= IDC_LOCK_TIMEOUT)
if (WARN_ON_ONCE(total >= timeout_ms))
return -1;
timeout++;
/* Yield CPU */
if (!in_interrupt())
schedule();
else {
for (i = 0; i < 20; i++)
cpu_relax();
}
total += delay_ms;
msleep(delay_ms);
}
return 0;
@@ -973,7 +969,7 @@ qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val)
static int
qla82xx_flash_wait_write_finish(struct qla_hw_data *ha)
{
uint32_t val;
uint32_t val = 0;
int i, ret;
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
+1 -2
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifndef __QLA_NX_H
#define __QLA_NX_H
+4 -5
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include <linux/vmalloc.h>
@@ -140,7 +139,7 @@ qla8044_poll_wait_for_ready(struct scsi_qla_host *vha, uint32_t addr1,
uint32_t mask)
{
unsigned long timeout;
uint32_t temp;
uint32_t temp = 0;
/* jiffies after 100ms */
timeout = jiffies + msecs_to_jiffies(TIMEOUT_100_MS);
@@ -660,7 +659,7 @@ static int
qla8044_poll_reg(struct scsi_qla_host *vha, uint32_t addr,
int duration, uint32_t test_mask, uint32_t test_result)
{
uint32_t value;
uint32_t value = 0;
int timeout_error;
uint8_t retries;
int ret_val = QLA_SUCCESS;
@@ -2595,7 +2594,7 @@ qla8044_minidump_process_rdmux(struct scsi_qla_host *vha,
struct qla8044_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
{
uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value;
uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value = 0;
struct qla8044_minidump_entry_mux *mux_hdr;
uint32_t *data_ptr = *d_ptr;
+1 -2
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifndef __QLA_NX2_H
+52 -150
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
@@ -53,6 +52,11 @@ module_param(ql2xfulldump_on_mpifail, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(ql2xfulldump_on_mpifail,
"Set this to take full dump on MPI hang.");
int ql2xenforce_iocb_limit = 1;
module_param(ql2xenforce_iocb_limit, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(ql2xenforce_iocb_limit,
"Enforce IOCB throttling, to avoid FW congestion. (default: 0)");
/*
* CT6 CTX allocation cache
*/
@@ -917,8 +921,8 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
goto qc24_fail_command;
}
if (!fcport) {
cmd->result = DID_NO_CONNECT << 16;
if (!fcport || fcport->deleted) {
cmd->result = DID_IMM_RETRY << 16;
goto qc24_fail_command;
}
@@ -999,8 +1003,8 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
goto qc24_fail_command;
}
if (!fcport) {
cmd->result = DID_NO_CONNECT << 16;
if (!fcport || fcport->deleted) {
cmd->result = DID_IMM_RETRY << 16;
goto qc24_fail_command;
}
@@ -3309,7 +3313,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
"req->req_q_in=%p req->req_q_out=%p rsp->rsp_q_in=%p rsp->rsp_q_out=%p.\n",
req->req_q_in, req->req_q_out, rsp->rsp_q_in, rsp->rsp_q_out);
ha->wq = alloc_workqueue("qla2xxx_wq", 0, 0);
ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 0);
if (unlikely(!ha->wq)) {
ret = -ENOMEM;
goto probe_failed;
@@ -3364,6 +3368,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
for (i = 0; i < ha->max_qpairs; i++)
qla2xxx_create_qpair(base_vha, 5, 0, startit);
}
qla_init_iocb_limit(base_vha);
if (ha->flags.running_gold_fw)
goto skip_dpc;
@@ -4273,6 +4278,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
&ha->sf_init_cb_dma);
if (!ha->sf_init_cb)
goto fail_sf_init_cb;
memset(ha->sf_init_cb, 0, sizeof(struct init_sf_cb));
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0199,
"sf_init_cb=%p.\n", ha->sf_init_cb);
}
@@ -4427,11 +4433,12 @@ int
qla2x00_set_exlogins_buffer(scsi_qla_host_t *vha)
{
int rval;
uint16_t size, max_cnt, temp;
uint16_t size, max_cnt;
uint32_t temp;
struct qla_hw_data *ha = vha->hw;
/* Return if we don't need to alloacate any extended logins */
if (!ql2xexlogins)
if (ql2xexlogins <= MAX_FIBRE_DEVICES_2400)
return QLA_SUCCESS;
if (!IS_EXLOGIN_OFFLD_CAPABLE(ha))
@@ -4920,7 +4927,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
}
INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn);
sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no);
sprintf(vha->host_str, "%s_%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
ql_dbg(ql_dbg_init, vha, 0x0041,
"Allocated the host=%p hw=%p vha=%p dev_name=%s",
vha->host, vha->hw, vha,
@@ -5049,7 +5056,7 @@ qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code)
switch (code) {
case QLA_UEVENT_CODE_FW_DUMP:
snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld",
snprintf(event_string, sizeof(event_string), "FW_DUMP=%lu",
vha->host_no);
break;
default:
@@ -5141,6 +5148,8 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
fcport->fc4_type = e->u.new_sess.fc4_type;
if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) {
fcport->dm_login_expire = jiffies +
QLA_N2N_WAIT_TIME * HZ;
fcport->fc4_type = FS_FC4TYPE_FCP;
fcport->n2n_flag = 1;
if (vha->flags.nvme_enabled)
@@ -5662,25 +5671,10 @@ qla83xx_service_idc_aen(struct work_struct *work)
}
}
static void
qla83xx_wait_logic(void)
{
int i;
/* Yield CPU */
if (!in_interrupt()) {
/*
* Wait about 200ms before retrying again.
* This controls the number of retries for single
* lock operation.
*/
msleep(100);
schedule();
} else {
for (i = 0; i < 20; i++)
cpu_relax(); /* This a nop instr on i386 */
}
}
/*
* Control the frequency of IDC lock retries
*/
#define QLA83XX_WAIT_LOGIC_MS 100
static int
qla83xx_force_lock_recovery(scsi_qla_host_t *base_vha)
@@ -5770,7 +5764,7 @@ retry_lockid:
goto exit;
if (o_drv_lockid == n_drv_lockid) {
qla83xx_wait_logic();
msleep(QLA83XX_WAIT_LOGIC_MS);
goto retry_lockid;
} else
return QLA_SUCCESS;
@@ -5779,6 +5773,9 @@ exit:
return rval;
}
/*
* Context: task, can sleep
*/
void
qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id)
{
@@ -5786,6 +5783,8 @@ qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id)
uint32_t lock_owner;
struct qla_hw_data *ha = base_vha->hw;
might_sleep();
/* IDC-lock implementation using driver-lock/lock-id remote registers */
retry_lock:
if (qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCK, &data)
@@ -5804,7 +5803,7 @@ retry_lock:
/* Retry/Perform IDC-Lock recovery */
if (qla83xx_idc_lock_recovery(base_vha)
== QLA_SUCCESS) {
qla83xx_wait_logic();
msleep(QLA83XX_WAIT_LOGIC_MS);
goto retry_lock;
} else
ql_log(ql_log_warn, base_vha, 0xb075,
@@ -5862,98 +5861,6 @@ qla25xx_rdp_rsp_reduce_size(struct scsi_qla_host *vha,
return true;
}
static uint
qla25xx_rdp_port_speed_capability(struct qla_hw_data *ha)
{
if (IS_CNA_CAPABLE(ha))
return RDP_PORT_SPEED_10GB;
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
unsigned int speeds = 0;
if (ha->max_supported_speed == 2) {
if (ha->min_supported_speed <= 6)
speeds |= RDP_PORT_SPEED_64GB;
}
if (ha->max_supported_speed == 2 ||
ha->max_supported_speed == 1) {
if (ha->min_supported_speed <= 5)
speeds |= RDP_PORT_SPEED_32GB;
}
if (ha->max_supported_speed == 2 ||
ha->max_supported_speed == 1 ||
ha->max_supported_speed == 0) {
if (ha->min_supported_speed <= 4)
speeds |= RDP_PORT_SPEED_16GB;
}
if (ha->max_supported_speed == 1 ||
ha->max_supported_speed == 0) {
if (ha->min_supported_speed <= 3)
speeds |= RDP_PORT_SPEED_8GB;
}
if (ha->max_supported_speed == 0) {
if (ha->min_supported_speed <= 2)
speeds |= RDP_PORT_SPEED_4GB;
}
return speeds;
}
if (IS_QLA2031(ha))
return RDP_PORT_SPEED_16GB|RDP_PORT_SPEED_8GB|
RDP_PORT_SPEED_4GB;
if (IS_QLA25XX(ha))
return RDP_PORT_SPEED_8GB|RDP_PORT_SPEED_4GB|
RDP_PORT_SPEED_2GB|RDP_PORT_SPEED_1GB;
if (IS_QLA24XX_TYPE(ha))
return RDP_PORT_SPEED_4GB|RDP_PORT_SPEED_2GB|
RDP_PORT_SPEED_1GB;
if (IS_QLA23XX(ha))
return RDP_PORT_SPEED_2GB|RDP_PORT_SPEED_1GB;
return RDP_PORT_SPEED_1GB;
}
static uint
qla25xx_rdp_port_speed_currently(struct qla_hw_data *ha)
{
switch (ha->link_data_rate) {
case PORT_SPEED_1GB:
return RDP_PORT_SPEED_1GB;
case PORT_SPEED_2GB:
return RDP_PORT_SPEED_2GB;
case PORT_SPEED_4GB:
return RDP_PORT_SPEED_4GB;
case PORT_SPEED_8GB:
return RDP_PORT_SPEED_8GB;
case PORT_SPEED_10GB:
return RDP_PORT_SPEED_10GB;
case PORT_SPEED_16GB:
return RDP_PORT_SPEED_16GB;
case PORT_SPEED_32GB:
return RDP_PORT_SPEED_32GB;
case PORT_SPEED_64GB:
return RDP_PORT_SPEED_64GB;
default:
return RDP_PORT_SPEED_UNKNOWN;
}
}
/*
* Function Name: qla24xx_process_purex_iocb
*
@@ -5973,12 +5880,10 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
dma_addr_t rsp_els_dma;
dma_addr_t rsp_payload_dma;
dma_addr_t stat_dma;
dma_addr_t bbc_dma;
dma_addr_t sfp_dma;
struct els_entry_24xx *rsp_els = NULL;
struct rdp_rsp_payload *rsp_payload = NULL;
struct link_statistics *stat = NULL;
struct buffer_credit_24xx *bbc = NULL;
uint8_t *sfp = NULL;
uint16_t sfp_flags = 0;
uint rsp_payload_length = sizeof(*rsp_payload);
@@ -6022,9 +5927,6 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
stat = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stat),
&stat_dma, GFP_KERNEL);
bbc = dma_alloc_coherent(&ha->pdev->dev, sizeof(*bbc),
&bbc_dma, GFP_KERNEL);
/* Prepare Response IOCB */
rsp_els->entry_type = ELS_IOCB_TYPE;
rsp_els->entry_count = 1;
@@ -6120,9 +6022,9 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
rsp_payload->port_speed_desc.desc_len =
cpu_to_be32(RDP_DESC_LEN(rsp_payload->port_speed_desc));
rsp_payload->port_speed_desc.speed_capab = cpu_to_be16(
qla25xx_rdp_port_speed_capability(ha));
qla25xx_fdmi_port_speed_capability(ha));
rsp_payload->port_speed_desc.operating_speed = cpu_to_be16(
qla25xx_rdp_port_speed_currently(ha));
qla25xx_fdmi_port_speed_currently(ha));
/* Link Error Status Descriptor */
rsp_payload->ls_err_desc.desc_tag = cpu_to_be32(0x10002);
@@ -6178,13 +6080,10 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
rsp_payload->buffer_credit_desc.attached_fcport_b2b = cpu_to_be32(0);
rsp_payload->buffer_credit_desc.fcport_rtt = cpu_to_be32(0);
if (bbc) {
memset(bbc, 0, sizeof(*bbc));
rval = qla24xx_get_buffer_credits(vha, bbc, bbc_dma);
if (!rval) {
rsp_payload->buffer_credit_desc.fcport_b2b =
cpu_to_be32(LSW(bbc->parameter[0]));
}
if (ha->flags.plogi_template_valid) {
uint32_t tmp =
be16_to_cpu(ha->plogi_els_payld.fl_csp.sp_bb_cred);
rsp_payload->buffer_credit_desc.fcport_b2b = cpu_to_be32(tmp);
}
if (rsp_payload_length < sizeof(*rsp_payload))
@@ -6362,9 +6261,6 @@ send:
}
dealloc:
if (bbc)
dma_free_coherent(&ha->pdev->dev, sizeof(*bbc),
bbc, bbc_dma);
if (stat)
dma_free_coherent(&ha->pdev->dev, sizeof(*stat),
stat, stat_dma);
@@ -6379,7 +6275,8 @@ dealloc:
rsp_els, rsp_els_dma);
}
void qla24xx_free_purex_item(struct purex_item *item)
void
qla24xx_free_purex_item(struct purex_item *item)
{
if (item == &item->vha->default_item)
memset(&item->vha->default_item, 0, sizeof(struct purex_item));
@@ -6404,6 +6301,9 @@ void qla24xx_process_purex_list(struct purex_list *list)
}
}
/*
* Context: task, can sleep
*/
void
qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
{
@@ -6414,6 +6314,8 @@ qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
uint32_t data;
struct qla_hw_data *ha = base_vha->hw;
might_sleep();
/* IDC-unlock implementation using driver-unlock/lock-id
* remote registers
*/
@@ -6429,7 +6331,7 @@ retry_unlock:
/* SV: XXX: IDC unlock retrying needed here? */
/* Retry for IDC-unlock */
qla83xx_wait_logic();
msleep(QLA83XX_WAIT_LOGIC_MS);
retry++;
ql_dbg(ql_dbg_p3p, base_vha, 0xb064,
"Failed to release IDC lock, retrying=%d\n", retry);
@@ -6437,7 +6339,7 @@ retry_unlock:
}
} else if (retry < 10) {
/* Retry for IDC-unlock */
qla83xx_wait_logic();
msleep(QLA83XX_WAIT_LOGIC_MS);
retry++;
ql_dbg(ql_dbg_p3p, base_vha, 0xb065,
"Failed to read drv-lockid, retrying=%d\n", retry);
@@ -6453,7 +6355,7 @@ retry_unlock2:
if (qla83xx_access_control(base_vha, options, 0, 0, NULL)) {
if (retry < 10) {
/* Retry for IDC-unlock */
qla83xx_wait_logic();
msleep(QLA83XX_WAIT_LOGIC_MS);
retry++;
ql_dbg(ql_dbg_p3p, base_vha, 0xb066,
"Failed to release IDC lock, retrying=%d\n", retry);
@@ -7340,8 +7242,10 @@ qla2x00_timer(struct timer_list *t)
* FC-NVME
* see if the active AEN count has changed from what was last reported.
*/
index = atomic_read(&ha->nvme_active_aen_cnt);
if (!vha->vp_idx &&
(atomic_read(&ha->nvme_active_aen_cnt) != ha->nvme_last_rptd_aen) &&
(index != ha->nvme_last_rptd_aen) &&
(index >= DEFAULT_ZIO_THRESHOLD) &&
ha->zio_mode == QLA_ZIO_MODE_6 &&
!ha->flags.host_shutting_down) {
ql_log(ql_log_info, vha, 0x3002,
@@ -7353,9 +7257,8 @@ qla2x00_timer(struct timer_list *t)
}
if (!vha->vp_idx &&
(atomic_read(&ha->zio_threshold) != ha->last_zio_threshold) &&
(ha->zio_mode == QLA_ZIO_MODE_6) &&
(IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))) {
atomic_read(&ha->zio_threshold) != ha->last_zio_threshold &&
IS_ZIO_THRESHOLD_CAPABLE(ha)) {
ql_log(ql_log_info, vha, 0x3002,
"Sched: Set ZIO exchange threshold to %d.\n",
ha->last_zio_threshold);
@@ -8160,7 +8063,6 @@ module_exit(qla2x00_module_exit);
MODULE_AUTHOR("QLogic Corporation");
MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(QLA2XXX_VERSION);
MODULE_FIRMWARE(FW_FILE_ISP21XX);
MODULE_FIRMWARE(FW_FILE_ISP22XX);
MODULE_FIRMWARE(FW_FILE_ISP2300);
+1 -2
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#define MAX_RETRIES_OF_ISP_ABORT 5
+6 -7
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
@@ -2635,14 +2634,14 @@ qla28xx_extract_sfub_and_verify(struct scsi_qla_host *vha, uint32_t *buf,
sizeof(struct secure_flash_update_block));
for (i = 0; i < (sizeof(struct secure_flash_update_block) >> 2); i++)
check_sum += p[i];
check_sum += le32_to_cpu(p[i]);
check_sum = (~check_sum) + 1;
if (check_sum != p[i]) {
if (check_sum != le32_to_cpu(p[i])) {
ql_log(ql_log_warn, vha, 0x7097,
"SFUB checksum failed, 0x%x, 0x%x\n",
check_sum, p[i]);
check_sum, le32_to_cpu(p[i]));
return QLA_COMMAND_ERROR;
}
@@ -2722,7 +2721,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
if (ha->flags.secure_adapter && region.attribute) {
ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff,
"Region %x is secure\n", region.code);
"Region %x is secure\n", le16_to_cpu(region.code));
switch (le16_to_cpu(region.code)) {
case FLT_REG_FW:
@@ -2776,7 +2775,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
default:
ql_log(ql_log_warn + ql_dbg_verbose, vha,
0xffff, "Secure region %x not supported\n",
region.code);
le16_to_cpu(region.code));
rval = QLA_COMMAND_ERROR;
goto done;
}
+25 -22
View File
@@ -1126,6 +1126,8 @@ void qlt_free_session_done(struct work_struct *work)
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
sess->free_pending = 0;
qla2x00_dfs_remove_rport(vha, sess);
ql_dbg(ql_dbg_disc, vha, 0xf001,
"Unregistration of sess %p %8phC finished fcp_cnt %d\n",
sess, sess->port_name, vha->fcport_count);
@@ -1244,14 +1246,15 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
case DSC_DELETE_PEND:
return;
case DSC_DELETED:
if (tgt && tgt->tgt_stop && (tgt->sess_count == 0))
wake_up_all(&tgt->waitQ);
if (sess->vha->fcport_count == 0)
wake_up_all(&sess->vha->fcport_waitQ);
if (!sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN] &&
!sess->plogi_link[QLT_PLOGI_LINK_CONFLICT])
!sess->plogi_link[QLT_PLOGI_LINK_CONFLICT]) {
if (tgt && tgt->tgt_stop && tgt->sess_count == 0)
wake_up_all(&tgt->waitQ);
if (sess->vha->fcport_count == 0)
wake_up_all(&sess->vha->fcport_waitQ);
return;
}
break;
case DSC_UPD_FCPORT:
/*
@@ -1285,7 +1288,7 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
qla24xx_chk_fcp_state(sess);
ql_dbg(ql_dbg_disc, sess->vha, 0xe001,
ql_dbg(ql_log_warn, sess->vha, 0xe001,
"Scheduling sess %p for deletion %8phC\n",
sess, sess->port_name);
@@ -2095,6 +2098,7 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
struct qla_hw_data *ha = vha->hw;
struct qla_tgt_mgmt_cmd *mcmd;
struct qla_qpair_hint *h = &vha->vha_tgt.qla_tgt->qphints[0];
struct qla_tgt_cmd *abort_cmd;
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f,
"qla_target(%d): task abort (tag=%d)\n",
@@ -2124,21 +2128,19 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
mcmd->se_cmd.cpuid = h->cpuid;
#endif
if (ha->tgt.tgt_ops->find_cmd_by_tag) {
struct qla_tgt_cmd *abort_cmd;
abort_cmd = ha->tgt.tgt_ops->find_cmd_by_tag(sess,
le32_to_cpu(abts->exchange_addr_to_abort));
if (abort_cmd && abort_cmd->qpair) {
mcmd->qpair = abort_cmd->qpair;
#if HAVE_SE_CMD_CPUID
mcmd->se_cmd.cpuid = abort_cmd->se_cmd.cpuid;
#endif
mcmd->abort_io_attr = abort_cmd->atio.u.isp24.attr;
mcmd->flags = QLA24XX_MGMT_ABORT_IO_ATTR_VALID;
}
}
abort_cmd = ha->tgt.tgt_ops->find_cmd_by_tag(sess,
le32_to_cpu(abts->exchange_addr_to_abort));
if (!abort_cmd)
return -EIO;
mcmd->unpacked_lun = abort_cmd->se_cmd.orig_fe_lun;
if (abort_cmd->qpair) {
mcmd->qpair = abort_cmd->qpair;
mcmd->se_cmd.cpuid = abort_cmd->se_cmd.cpuid;
mcmd->abort_io_attr = abort_cmd->atio.u.isp24.attr;
mcmd->flags = QLA24XX_MGMT_ABORT_IO_ATTR_VALID;
}
INIT_WORK(&mcmd->work, qlt_do_tmr_work);
#if HAVE_SE_CMD_CPUID
queue_work_on(mcmd->se_cmd.cpuid, qla_tgt_wq, &mcmd->work);
@@ -3828,7 +3830,7 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd)
*/
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf016, "multiple abort. %p\n",
cmd);
return EIO;
return -EIO;
}
cmd->aborted = 1;
cmd->trc_flags |= TRC_ABORT;
@@ -4340,6 +4342,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
cmd->cmd_type = TYPE_TGT_CMD;
memcpy(&cmd->atio, atio, sizeof(*atio));
INIT_LIST_HEAD(&cmd->sess_cmd_list);
cmd->state = QLA_TGT_STATE_NEW;
cmd->tgt = vha->vha_tgt.qla_tgt;
qlt_incr_num_pend_cmds(vha);
+1
View File
@@ -891,6 +891,7 @@ struct qla_tgt_cmd {
uint8_t cmd_type;
uint8_t pad[7];
struct se_cmd se_cmd;
struct list_head sess_cmd_list;
struct scst_cmd *scst_cmd;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
/*
+21 -48
View File
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include "qla_tmpl.h"
@@ -12,33 +11,6 @@
#define IOBASE(vha) IOBAR(ISPREG(vha))
#define INVALID_ENTRY ((struct qla27xx_fwdt_entry *)0xffffffffffffffffUL)
/* hardware_lock assumed held. */
static void
qla27xx_write_remote_reg(struct scsi_qla_host *vha,
u32 addr, u32 data)
{
struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24;
ql_dbg(ql_dbg_misc, vha, 0xd300,
"%s: addr/data = %xh/%xh\n", __func__, addr, data);
wrt_reg_dword(&reg->iobase_addr, 0x40);
wrt_reg_dword(&reg->iobase_c4, data);
wrt_reg_dword(&reg->iobase_window, addr);
}
void
qla27xx_reset_mpi(scsi_qla_host_t *vha)
{
ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd301,
"Entered %s.\n", __func__);
qla27xx_write_remote_reg(vha, 0x104050, 0x40004);
qla27xx_write_remote_reg(vha, 0x10405c, 0x4);
vha->hw->stat.num_mpi_reset++;
}
static inline void
qla27xx_insert16(uint16_t value, void *buf, ulong *len)
{
@@ -906,8 +878,8 @@ qla27xx_driver_info(struct qla27xx_fwdt_template *tmp)
uint8_t v[] = { 0, 0, 0, 0, 0, 0 };
WARN_ON_ONCE(sscanf(qla2x00_version_str,
"%hhu.%hhu.%hhu.%hhu.%hhu.%hhu",
v+0, v+1, v+2, v+3, v+4, v+5) != 6);
"%hhu.%hhu.%hhu.%hhu",
v + 0, v + 1, v + 2, v + 3) != 4);
tmp->driver_info[0] = cpu_to_le32(
v[3] << 24 | v[2] << 16 | v[1] << 8 | v[0]);
@@ -956,7 +928,8 @@ qla27xx_template_checksum(void *p, ulong size)
static inline int
qla27xx_verify_template_checksum(struct qla27xx_fwdt_template *tmp)
{
return qla27xx_template_checksum(tmp, tmp->template_size) == 0;
return qla27xx_template_checksum(tmp,
le32_to_cpu(tmp->template_size)) == 0;
}
static inline int
@@ -972,7 +945,7 @@ qla27xx_execute_fwdt_template(struct scsi_qla_host *vha,
ulong len = 0;
if (qla27xx_fwdt_template_valid(tmp)) {
len = tmp->template_size;
len = le32_to_cpu(tmp->template_size);
tmp = memcpy(buf, tmp, len);
ql27xx_edit_template(vha, tmp);
qla27xx_walk_template(vha, tmp, buf, &len);
@@ -988,7 +961,7 @@ qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *vha, void *p)
ulong len = 0;
if (qla27xx_fwdt_template_valid(tmp)) {
len = tmp->template_size;
len = le32_to_cpu(tmp->template_size);
qla27xx_walk_template(vha, tmp, NULL, &len);
}
@@ -1000,7 +973,7 @@ qla27xx_fwdt_template_size(void *p)
{
struct qla27xx_fwdt_template *tmp = p;
return tmp->template_size;
return le32_to_cpu(tmp->template_size);
}
int
@@ -1028,22 +1001,25 @@ void
qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked)
{
ulong flags = 0;
bool need_mpi_reset = true;
#ifndef __CHECKER__
if (!hardware_locked)
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
#endif
if (!vha->hw->mpi_fw_dump) {
ql_log(ql_log_warn, vha, 0x02f3, "-> mpi_fwdump no buffer\n");
} else if (vha->hw->mpi_fw_dumped) {
ql_log(ql_log_warn, vha, 0x02f4,
"-> MPI firmware already dumped (%p) -- ignoring request\n",
vha->hw->mpi_fw_dump);
} else {
struct fwdt *fwdt = &vha->hw->fwdt[1];
ulong len;
void *buf = vha->hw->mpi_fw_dump;
bool walk_template_only = false;
if (vha->hw->mpi_fw_dumped) {
/* Use the spare area for any further dumps. */
buf += fwdt->dump_size;
walk_template_only = true;
ql_log(ql_log_warn, vha, 0x02f4,
"-> MPI firmware already dumped -- dump saving to temporary buffer %p.\n",
buf);
}
ql_log(ql_log_warn, vha, 0x02f5, "-> fwdt1 running...\n");
if (!fwdt->template) {
@@ -1058,9 +1034,10 @@ qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked)
ql_log(ql_log_warn, vha, 0x02f7,
"-> fwdt1 fwdump residual=%+ld\n",
fwdt->dump_size - len);
} else {
need_mpi_reset = false;
}
vha->hw->stat.num_mpi_reset++;
if (walk_template_only)
goto bailout;
vha->hw->mpi_fw_dump_len = len;
vha->hw->mpi_fw_dumped = 1;
@@ -1072,12 +1049,8 @@ qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked)
}
bailout:
if (need_mpi_reset)
qla27xx_reset_mpi(vha);
#ifndef __CHECKER__
if (!hardware_locked)
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
#endif
}
void
+2 -3
View File
@@ -1,8 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#ifndef __QLA_DMP27_H__
@@ -13,7 +12,7 @@
struct __packed qla27xx_fwdt_template {
__le32 template_type;
__le32 entry_offset;
uint32_t template_size;
__le32 template_size;
uint32_t count; /* borrow field for running/residual count */
__le32 entry_count;
+4 -5
View File
@@ -1,15 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
/*
* Driver version
*/
#define QLA2XXX_VERSION "10.01.00.25-k"
#define QLA2XXX_VERSION "10.02.00.104-k"
#define QLA_DRIVER_MAJOR_VER 10
#define QLA_DRIVER_MINOR_VER 1
#define QLA_DRIVER_MINOR_VER 2
#define QLA_DRIVER_PATCH_VER 0
#define QLA_DRIVER_BETA_VER 0
#define QLA_DRIVER_BETA_VER 104