Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Browse files Browse the repository at this point in the history
Pull SCSI target fixes from Nicholas Bellinger:
 "The bulk of the changes are in qla2xxx target driver code to address
  various issues found during Cavium/QLogic's internal testing (stable
  CC's included), along with a few other stability and smaller
  miscellaneous improvements.

  There are also a couple of different patch sets from Mike Christie,
  which have been a result of his work to use target-core ALUA logic
  together with tcm-user backend driver.

  Finally, a patch to address some long standing issues with
  pass-through SCSI export of TYPE_TAPE + TYPE_MEDIUM_CHANGER devices,
  which will make folks using physical (or virtual) magnetic tape happy"

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (28 commits)
  qla2xxx: Update driver version to 9.00.00.00-k
  qla2xxx: Fix delayed response to command for loop mode/direct connect.
  qla2xxx: Change scsi host lookup method.
  qla2xxx: Add DebugFS node to display Port Database
  qla2xxx: Use IOCB interface to submit non-critical MBX.
  qla2xxx: Add async new target notification
  qla2xxx: Export DIF stats via debugfs
  qla2xxx: Improve T10-DIF/PI handling in driver.
  qla2xxx: Allow relogin to proceed if remote login did not finish
  qla2xxx: Fix sess_lock & hardware_lock lock order problem.
  qla2xxx: Fix inadequate lock protection for ABTS.
  qla2xxx: Fix request queue corruption.
  qla2xxx: Fix memory leak for abts processing
  qla2xxx: Allow vref count to timeout on vport delete.
  tcmu: Convert cmd_time_out into backend device attribute
  tcmu: make cmd timeout configurable
  tcmu: add helper to check if dev was configured
  target: fix race during implicit transition work flushes
  target: allow userspace to set state to transitioning
  target: fix ALUA transition timeout handling
  ...
  • Loading branch information
torvalds committed Mar 20, 2017
2 parents 1b8df61 + 6c611d1 commit 8aa3417
Show file tree
Hide file tree
Showing 25 changed files with 1,274 additions and 548 deletions.
1 change: 1 addition & 0 deletions drivers/scsi/qla2xxx/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ config SCSI_QLA_FC
depends on PCI && SCSI
depends on SCSI_FC_ATTRS
select FW_LOADER
select BTREE
---help---
This qla2xxx driver supports all QLogic Fibre Channel
PCI and PCIe host adapters.
Expand Down
4 changes: 1 addition & 3 deletions drivers/scsi/qla2xxx/qla_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2154,8 +2154,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
"Timer for the VP[%d] has stopped\n", vha->vp_idx);
}

BUG_ON(atomic_read(&vha->vref_count));

qla2x00_free_fcports(vha);

mutex_lock(&ha->vport_lock);
Expand All @@ -2166,7 +2164,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l,
vha->gnl.ldma);

if (vha->qpair->vp_idx == vha->vp_idx) {
if (vha->qpair && vha->qpair->vp_idx == vha->vp_idx) {
if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS)
ql_log(ql_log_warn, vha, 0x7087,
"Queue Pair delete failed.\n");
Expand Down
1 change: 1 addition & 0 deletions drivers/scsi/qla2xxx/qla_dbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...);
#define ql_dbg_tgt 0x00004000 /* Target mode */
#define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */
#define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */
#define ql_dbg_tgt_dif 0x00000800 /* Target mode dif */

extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *,
uint32_t, void **);
Expand Down
56 changes: 50 additions & 6 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/firmware.h>
#include <linux/aer.h>
#include <linux/mutex.h>
#include <linux/btree.h>

#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
Expand Down Expand Up @@ -395,11 +396,15 @@ struct srb_iocb {
struct completion comp;
} abt;
struct ct_arg ctarg;
#define MAX_IOCB_MB_REG 28
#define SIZEOF_IOCB_MB_REG (MAX_IOCB_MB_REG * sizeof(uint16_t))
struct {
__le16 in_mb[28]; /* fr fw */
__le16 out_mb[28]; /* to fw */
__le16 in_mb[MAX_IOCB_MB_REG]; /* from FW */
__le16 out_mb[MAX_IOCB_MB_REG]; /* to FW */
void *out, *in;
dma_addr_t out_dma, in_dma;
struct completion comp;
int rc;
} mbx;
struct {
struct imm_ntfy_from_isp *ntfy;
Expand Down Expand Up @@ -437,7 +442,7 @@ typedef struct srb {
uint32_t handle;
uint16_t flags;
uint16_t type;
char *name;
const char *name;
int iocbs;
struct qla_qpair *qpair;
u32 gen1; /* scratch */
Expand Down Expand Up @@ -2300,6 +2305,8 @@ typedef struct fc_port {
struct ct_sns_desc ct_desc;
enum discovery_state disc_state;
enum login_state fw_login_state;
unsigned long plogi_nack_done_deadline;

u32 login_gen, last_login_gen;
u32 rscn_gen, last_rscn_gen;
u32 chip_reset;
Expand Down Expand Up @@ -3106,6 +3113,16 @@ struct qla_chip_state_84xx {
uint32_t gold_fw_version;
};

struct qla_dif_statistics {
uint64_t dif_input_bytes;
uint64_t dif_output_bytes;
uint64_t dif_input_requests;
uint64_t dif_output_requests;
uint32_t dif_guard_err;
uint32_t dif_ref_tag_err;
uint32_t dif_app_tag_err;
};

struct qla_statistics {
uint32_t total_isp_aborts;
uint64_t input_bytes;
Expand All @@ -3118,13 +3135,25 @@ struct qla_statistics {
uint32_t stat_max_pend_cmds;
uint32_t stat_max_qfull_cmds_alloc;
uint32_t stat_max_qfull_cmds_dropped;

struct qla_dif_statistics qla_dif_stats;
};

struct bidi_statistics {
unsigned long long io_count;
unsigned long long transfer_bytes;
};

struct qla_tc_param {
struct scsi_qla_host *vha;
uint32_t blk_sz;
uint32_t bufflen;
struct scatterlist *sg;
struct scatterlist *prot_sg;
struct crc_context *ctx;
uint8_t *ctx_dsd_alloced;
};

/* Multi queue support */
#define MBC_INITIALIZE_MULTIQ 0x1f
#define QLA_QUE_PAGE 0X1000
Expand Down Expand Up @@ -3272,6 +3301,8 @@ struct qlt_hw_data {
uint8_t tgt_node_name[WWN_SIZE];

struct dentry *dfs_tgt_sess;
struct dentry *dfs_tgt_port_database;

struct list_head q_full_list;
uint32_t num_pend_cmds;
uint32_t num_qfull_cmds_alloc;
Expand All @@ -3281,6 +3312,7 @@ struct qlt_hw_data {
spinlock_t sess_lock;
int rspq_vector_cpuid;
spinlock_t atio_lock ____cacheline_aligned;
struct btree_head32 host_map;
};

#define MAX_QFULL_CMDS_ALLOC 8192
Expand All @@ -3290,6 +3322,10 @@ struct qlt_hw_data {

#define LEAK_EXCHG_THRESH_HOLD_PERCENT 75 /* 75 percent */

#define QLA_EARLY_LINKUP(_ha) \
((_ha->flags.n2n_ae || _ha->flags.lip_ae) && \
_ha->flags.fw_started && !_ha->flags.fw_init_done)

/*
* Qlogic host adapter specific data structure.
*/
Expand Down Expand Up @@ -3339,7 +3375,11 @@ struct qla_hw_data {
uint32_t fawwpn_enabled:1;
uint32_t exlogins_enabled:1;
uint32_t exchoffld_enabled:1;
/* 35 bits */

uint32_t lip_ae:1;
uint32_t n2n_ae:1;
uint32_t fw_started:1;
uint32_t fw_init_done:1;
} flags;

/* This spinlock is used to protect "io transactions", you must
Expand Down Expand Up @@ -3432,7 +3472,6 @@ struct qla_hw_data {
#define P2P_LOOP 3
uint8_t interrupts_on;
uint32_t isp_abort_cnt;

#define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532
#define PCI_DEVICE_ID_QLOGIC_ISP8432 0x8432
#define PCI_DEVICE_ID_QLOGIC_ISP8001 0x8001
Expand Down Expand Up @@ -3913,6 +3952,7 @@ typedef struct scsi_qla_host {
struct list_head vp_fcports; /* list of fcports */
struct list_head work_list;
spinlock_t work_lock;
struct work_struct iocb_work;

/* Commonly used flags and state information. */
struct Scsi_Host *host;
Expand Down Expand Up @@ -4076,6 +4116,7 @@ typedef struct scsi_qla_host {
/* Count of active session/fcport */
int fcport_count;
wait_queue_head_t fcport_waitQ;
wait_queue_head_t vref_waitq;
} scsi_qla_host_t;

struct qla27xx_image_status {
Expand Down Expand Up @@ -4131,14 +4172,17 @@ struct qla2_sgx {
mb(); \
if (__vha->flags.delete_progress) { \
atomic_dec(&__vha->vref_count); \
wake_up(&__vha->vref_waitq); \
__bail = 1; \
} else { \
__bail = 0; \
} \
} while (0)

#define QLA_VHA_MARK_NOT_BUSY(__vha) \
#define QLA_VHA_MARK_NOT_BUSY(__vha) do { \
atomic_dec(&__vha->vref_count); \
wake_up(&__vha->vref_waitq); \
} while (0) \

#define QLA_QPAIR_MARK_BUSY(__qpair, __bail) do { \
atomic_inc(&__qpair->ref_count); \
Expand Down
107 changes: 103 additions & 4 deletions drivers/scsi/qla2xxx/qla_dfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ qla2x00_dfs_tgt_sess_show(struct seq_file *s, void *unused)
struct qla_hw_data *ha = vha->hw;
unsigned long flags;
struct fc_port *sess = NULL;
struct qla_tgt *tgt= vha->vha_tgt.qla_tgt;
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;

seq_printf(s, "%s\n",vha->host_str);
seq_printf(s, "%s\n", vha->host_str);
if (tgt) {
seq_printf(s, "Port ID Port Name Handle\n");
seq_puts(s, "Port ID Port Name Handle\n");

spin_lock_irqsave(&ha->tgt.sess_lock, flags);
list_for_each_entry(sess, &vha->vp_fcports, list)
Expand All @@ -44,14 +44,85 @@ qla2x00_dfs_tgt_sess_open(struct inode *inode, struct file *file)
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,
};

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;
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, 0x705c,
"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,
};

static int
qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
{
Expand Down Expand Up @@ -114,6 +185,21 @@ qla_dfs_tgt_counters_show(struct seq_file *s, void *unused)
seq_printf(s, "num Q full sent = %lld\n",
vha->tgt_counters.num_q_full_sent);

/* DIF stats */
seq_printf(s, "DIF Inp Bytes = %lld\n",
vha->qla_stats.qla_dif_stats.dif_input_bytes);
seq_printf(s, "DIF Outp Bytes = %lld\n",
vha->qla_stats.qla_dif_stats.dif_output_bytes);
seq_printf(s, "DIF Inp Req = %lld\n",
vha->qla_stats.qla_dif_stats.dif_input_requests);
seq_printf(s, "DIF Outp Req = %lld\n",
vha->qla_stats.qla_dif_stats.dif_output_requests);
seq_printf(s, "DIF Guard err = %d\n",
vha->qla_stats.qla_dif_stats.dif_guard_err);
seq_printf(s, "DIF Ref tag err = %d\n",
vha->qla_stats.qla_dif_stats.dif_ref_tag_err);
seq_printf(s, "DIF App tag err = %d\n",
vha->qla_stats.qla_dif_stats.dif_app_tag_err);
return 0;
}

Expand Down Expand Up @@ -281,6 +367,14 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
goto out;
}

ha->tgt.dfs_tgt_port_database = debugfs_create_file("tgt_port_database",
S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_port_database_ops);
if (!ha->tgt.dfs_tgt_port_database) {
ql_log(ql_log_warn, vha, 0xffff,
"Unable to create debugFS tgt_port_database node.\n");
goto out;
}

ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
&dfs_fce_ops);
if (!ha->dfs_fce) {
Expand Down Expand Up @@ -311,6 +405,11 @@ qla2x00_dfs_remove(scsi_qla_host_t *vha)
ha->tgt.dfs_tgt_sess = NULL;
}

if (ha->tgt.dfs_tgt_port_database) {
debugfs_remove(ha->tgt.dfs_tgt_port_database);
ha->tgt.dfs_tgt_port_database = NULL;
}

if (ha->dfs_fw_resource_cnt) {
debugfs_remove(ha->dfs_fw_resource_cnt);
ha->dfs_fw_resource_cnt = NULL;
Expand Down
Loading

0 comments on commit 8aa3417

Please sign in to comment.