mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-25 01:23:14 +00:00
Merge branch 'svn-trunk'
This commit is contained in:
+50
-50
@@ -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,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,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
|
||||
|
||||
@@ -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,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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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(®->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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,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,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
@@ -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
|
||||
|
||||
@@ -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
@@ -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,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
|
||||
|
||||
@@ -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,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
@@ -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,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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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(®->iobase_addr, 0x40);
|
||||
wrt_reg_dword(®->iobase_c4, data);
|
||||
wrt_reg_dword(®->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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user