mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 23:09:29 +02:00
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi
Pull more SCSI updates from Martin Petersen: "Remaining updates for the 7.3 merge window. The only core change is enabling context analysis for the SCSI layer and UFS. The remaining changes are either bug fixes or hardening" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi: (26 commits) scsi: snic: Fix SCSI host leak on workqueue allocation failure scsi: MAINTAINERS: Update my email address scsi: MAINTAINERS: Leave the cumana_1 and oak drivers to the RISCPC maintainers scsi: leapraid: Standardize NCQ priority sysfs attributes scsi: leapraid: Serialize firmware log mmap with teardown scsi: leapraid: Balance host references for firmware log VMAs scsi: lpfc: Remove unnnecessary NULL check scsi: qla2xxx: Fix an loop timeout test scsi: qla2xxx: Fix an error code in qla_get_tmf() scsi: ibmvfc: Fix use of uninitialized rport in ibmvfc_do_work() scsi: core: Enable context analysis for hosts.o scsi: lpfc: Replace strlcat() with sysfs_emit_at() in the sysfs show functions scsi: lpfc: Replace strlcat() with seq_buf in the debugfs dump helpers scsi: lpfc: Replace strlcat() with seq_buf in lpfc_rx_monitor_report() scsi: lpfc: Replace strlcat() with scnprintf() in lpfc_vport_symbolic_node_name() scsi: lpfc: Replace strlcat() with seq_buf in lpfc_info() scsi: core: Enable context analysis scsi: core: Protect host state changes with the host lock scsi: core: Add lock context annotations scsi: core: Pass the SCSI host pointer directly to scanning functions ...
This commit is contained in:
@@ -577,6 +577,9 @@ Mark Brown <broonie@sirena.org.uk>
|
|||||||
Mark Starovoytov <mstarovo@pm.me> <mstarovoitov@marvell.com>
|
Mark Starovoytov <mstarovo@pm.me> <mstarovoitov@marvell.com>
|
||||||
Markus Schneider-Pargmann <msp@baylibre.com> <mpa@pengutronix.de>
|
Markus Schneider-Pargmann <msp@baylibre.com> <mpa@pengutronix.de>
|
||||||
Mark Yao <markyao0591@gmail.com> <mark.yao@rock-chips.com>
|
Mark Yao <markyao0591@gmail.com> <mark.yao@rock-chips.com>
|
||||||
|
Martin K. Petersen <mkp@kernel.org> <martin.petersen@oracle.com>
|
||||||
|
Martin K. Petersen <mkp@kernel.org> <mkp@mkp.net>
|
||||||
|
Martin K. Petersen <mkp@kernel.org> <mkp@linuxcare.com>
|
||||||
Martin Kepplinger-Novakovic <martink@posteo.de> <martin.kepplinger-novakovic@ginzinger.com>
|
Martin Kepplinger-Novakovic <martink@posteo.de> <martin.kepplinger-novakovic@ginzinger.com>
|
||||||
Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.intel.com> <martyna.szapar-mudlaw@intel.com>
|
Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.intel.com> <martyna.szapar-mudlaw@intel.com>
|
||||||
Mathieu Othacehe <othacehe@gnu.org> <m.othacehe@gmail.com>
|
Mathieu Othacehe <othacehe@gnu.org> <m.othacehe@gmail.com>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ Supported devices
|
|||||||
|
|
||||||
Features
|
Features
|
||||||
========
|
========
|
||||||
|
|
||||||
- PCIe Gen4 x8 host interface
|
- PCIe Gen4 x8 host interface
|
||||||
- Support for SAS and SATA devices
|
- Support for SAS and SATA devices
|
||||||
- RAID levels: 0, 1, 10, 5, 50, 6, 60
|
- RAID levels: 0, 1, 10, 5, 50, 6, 60
|
||||||
@@ -50,16 +51,20 @@ LeapRAID specific disk attributes
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
/sys/class/scsi_disk/host:bus:target:lun/device/sas_device_handle
|
/sys/block/<disk>/device/sas_device_handle
|
||||||
/sys/class/scsi_disk/host:bus:target:lun/device/ncq_cmd_prio_enable
|
/sys/block/<disk>/device/sas_ncq_prio_supported
|
||||||
|
/sys/block/<disk>/device/sas_ncq_prio_enable
|
||||||
|
|
||||||
The read-only attribute "sas_device_handle" represents the disk's device
|
The read-only attribute "sas_device_handle" represents the disk's device
|
||||||
handle, which is a unique identifier maintained by the firmware.
|
handle, which is a unique identifier maintained by the firmware.
|
||||||
|
|
||||||
This attribute "ncq_cmd_prio_enable" controls NCQ command priority. A value
|
The read-only attribute "sas_ncq_prio_supported" reports whether a SATA
|
||||||
|
device supports NCQ command priority.
|
||||||
|
|
||||||
|
The attribute "sas_ncq_prio_enable" controls NCQ command priority. A value
|
||||||
of 0 disables NCQ priority handling for RT-priority I/O. Writing 1 enables
|
of 0 disables NCQ priority handling for RT-priority I/O. Writing 1 enables
|
||||||
NCQ priority handling when the device reports support for the feature through
|
NCQ priority handling when the device reports support for the feature through
|
||||||
VPD page 0x89. Unsupported devices keep the effective state at 0.
|
VPD page 0x89. Writes to unsupported devices fail with an error.
|
||||||
|
|
||||||
LeapRAID module parameters
|
LeapRAID module parameters
|
||||||
==========================
|
==========================
|
||||||
@@ -100,6 +105,7 @@ in io_uring poll mode. The default value is 0.
|
|||||||
|
|
||||||
File Location
|
File Location
|
||||||
=============
|
=============
|
||||||
|
|
||||||
The driver source is located at:
|
The driver source is located at:
|
||||||
|
|
||||||
``drivers/scsi/leapraid/``
|
``drivers/scsi/leapraid/``
|
||||||
|
|||||||
+2
-4
@@ -18776,8 +18776,6 @@ L: linux-scsi@vger.kernel.org
|
|||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/scsi/g_NCR5380.rst
|
F: Documentation/scsi/g_NCR5380.rst
|
||||||
F: drivers/scsi/NCR5380.*
|
F: drivers/scsi/NCR5380.*
|
||||||
F: drivers/scsi/arm/cumana_1.c
|
|
||||||
F: drivers/scsi/arm/oak.c
|
|
||||||
F: drivers/scsi/atari_scsi.*
|
F: drivers/scsi/atari_scsi.*
|
||||||
F: drivers/scsi/dmx3191d.c
|
F: drivers/scsi/dmx3191d.c
|
||||||
F: drivers/scsi/g_NCR5380.*
|
F: drivers/scsi/g_NCR5380.*
|
||||||
@@ -24571,7 +24569,7 @@ F: include/scsi/sg.h
|
|||||||
|
|
||||||
SCSI SUBSYSTEM
|
SCSI SUBSYSTEM
|
||||||
M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
|
M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
|
||||||
M: "Martin K. Petersen" <martin.petersen@oracle.com>
|
M: "Martin K. Petersen" <mkp@kernel.org>
|
||||||
L: linux-scsi@vger.kernel.org
|
L: linux-scsi@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
Q: https://patchwork.kernel.org/project/linux-scsi/list/
|
Q: https://patchwork.kernel.org/project/linux-scsi/list/
|
||||||
@@ -24601,7 +24599,7 @@ F: drivers/target/target_core_user.c
|
|||||||
F: include/uapi/linux/target_core_user.h
|
F: include/uapi/linux/target_core_user.h
|
||||||
|
|
||||||
SCSI TARGET SUBSYSTEM
|
SCSI TARGET SUBSYSTEM
|
||||||
M: "Martin K. Petersen" <martin.petersen@oracle.com>
|
M: "Martin K. Petersen" <mkp@kernel.org>
|
||||||
L: linux-scsi@vger.kernel.org
|
L: linux-scsi@vger.kernel.org
|
||||||
L: target-devel@vger.kernel.org
|
L: target-devel@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|||||||
@@ -14,6 +14,29 @@
|
|||||||
# satisfy certain initialization assumptions in the SCSI layer.
|
# satisfy certain initialization assumptions in the SCSI layer.
|
||||||
# *!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!
|
# *!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!
|
||||||
|
|
||||||
|
CONTEXT_ANALYSIS_constants.o := y
|
||||||
|
CONTEXT_ANALYSIS_hosts.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_common.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_devinfo.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_dh.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_error.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_ioctl.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_lib.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_lib_dma.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_logging.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_netlink.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_pm.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_proc.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_scan.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_sysfs.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsi_trace.o := y
|
||||||
|
CONTEXT_ANALYSIS_scsicam.o := y
|
||||||
|
CONTEXT_ANALYSIS_sd.o := y
|
||||||
|
CONTEXT_ANALYSIS_sd_dif.o := y
|
||||||
|
CONTEXT_ANALYSIS_sd_zbc.o := y
|
||||||
|
CONTEXT_ANALYSIS_sr.o := y
|
||||||
|
CONTEXT_ANALYSIS_sr_ioctl.o := y
|
||||||
|
|
||||||
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
|
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
#
|
#
|
||||||
# SCSI Device Handler
|
# SCSI Device Handler
|
||||||
#
|
#
|
||||||
|
|
||||||
|
CONTEXT_ANALYSIS := y
|
||||||
|
|
||||||
obj-$(CONFIG_SCSI_DH_RDAC) += scsi_dh_rdac.o
|
obj-$(CONFIG_SCSI_DH_RDAC) += scsi_dh_rdac.o
|
||||||
obj-$(CONFIG_SCSI_DH_HP_SW) += scsi_dh_hp_sw.o
|
obj-$(CONFIG_SCSI_DH_HP_SW) += scsi_dh_hp_sw.o
|
||||||
obj-$(CONFIG_SCSI_DH_EMC) += scsi_dh_emc.o
|
obj-$(CONFIG_SCSI_DH_EMC) += scsi_dh_emc.o
|
||||||
|
|||||||
+11
-8
@@ -73,8 +73,9 @@ static struct class shost_class = {
|
|||||||
* transition is illegal.
|
* transition is illegal.
|
||||||
**/
|
**/
|
||||||
int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
|
int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
|
||||||
|
__must_hold(shost->host_lock)
|
||||||
{
|
{
|
||||||
enum scsi_host_state oldstate = shost->shost_state;
|
enum scsi_host_state oldstate = READ_ONCE(shost->shost_state);
|
||||||
|
|
||||||
if (state == oldstate)
|
if (state == oldstate)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -145,7 +146,7 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
shost->shost_state = state;
|
WRITE_ONCE(shost->shost_state, state);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
illegal:
|
illegal:
|
||||||
@@ -276,7 +277,8 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
|
|||||||
if (error)
|
if (error)
|
||||||
goto out_disable_runtime_pm;
|
goto out_disable_runtime_pm;
|
||||||
|
|
||||||
scsi_host_set_state(shost, SHOST_RUNNING);
|
scoped_guard(spinlock_irq, shost->host_lock)
|
||||||
|
scsi_host_set_state(shost, SHOST_RUNNING);
|
||||||
get_device(shost->shost_gendev.parent);
|
get_device(shost->shost_gendev.parent);
|
||||||
|
|
||||||
device_enable_async_suspend(&shost->shost_dev);
|
device_enable_async_suspend(&shost->shost_dev);
|
||||||
@@ -350,6 +352,7 @@ EXPORT_SYMBOL(scsi_add_host_with_dma);
|
|||||||
static void scsi_host_dev_release(struct device *dev)
|
static void scsi_host_dev_release(struct device *dev)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = dev_to_shost(dev);
|
struct Scsi_Host *shost = dev_to_shost(dev);
|
||||||
|
enum scsi_host_state state = scsi_get_host_state(shost);
|
||||||
struct device *parent = dev->parent;
|
struct device *parent = dev->parent;
|
||||||
|
|
||||||
/* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
|
/* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
|
||||||
@@ -363,7 +366,7 @@ static void scsi_host_dev_release(struct device *dev)
|
|||||||
if (shost->work_q)
|
if (shost->work_q)
|
||||||
destroy_workqueue(shost->work_q);
|
destroy_workqueue(shost->work_q);
|
||||||
|
|
||||||
if (shost->shost_state == SHOST_CREATED) {
|
if (state == SHOST_CREATED) {
|
||||||
/*
|
/*
|
||||||
* Free the shost_dev device name and remove the proc host dir
|
* Free the shost_dev device name and remove the proc host dir
|
||||||
* here if scsi_host_{alloc,put}() have been called but neither
|
* here if scsi_host_{alloc,put}() have been called but neither
|
||||||
@@ -379,7 +382,7 @@ static void scsi_host_dev_release(struct device *dev)
|
|||||||
|
|
||||||
ida_free(&host_index_ida, shost->host_no);
|
ida_free(&host_index_ida, shost->host_no);
|
||||||
|
|
||||||
if (shost->shost_state != SHOST_CREATED)
|
if (state != SHOST_CREATED)
|
||||||
put_device(parent);
|
put_device(parent);
|
||||||
kfree(shost);
|
kfree(shost);
|
||||||
}
|
}
|
||||||
@@ -412,8 +415,8 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
shost->host_lock = &shost->default_lock;
|
shost->host_lock = &shost->default_lock;
|
||||||
spin_lock_init(shost->host_lock);
|
scoped_guard(spinlock_init, shost->host_lock)
|
||||||
shost->shost_state = SHOST_CREATED;
|
shost->shost_state = SHOST_CREATED;
|
||||||
INIT_LIST_HEAD(&shost->__devices);
|
INIT_LIST_HEAD(&shost->__devices);
|
||||||
INIT_LIST_HEAD(&shost->__targets);
|
INIT_LIST_HEAD(&shost->__targets);
|
||||||
INIT_LIST_HEAD(&shost->eh_abort_list);
|
INIT_LIST_HEAD(&shost->eh_abort_list);
|
||||||
@@ -600,7 +603,7 @@ EXPORT_SYMBOL(scsi_host_lookup);
|
|||||||
**/
|
**/
|
||||||
struct Scsi_Host *scsi_host_get(struct Scsi_Host *shost)
|
struct Scsi_Host *scsi_host_get(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
if ((shost->shost_state == SHOST_DEL) ||
|
if (scsi_get_host_state(shost) == SHOST_DEL ||
|
||||||
!get_device(&shost->shost_gendev))
|
!get_device(&shost->shost_gendev))
|
||||||
return NULL;
|
return NULL;
|
||||||
return shost;
|
return shost;
|
||||||
|
|||||||
@@ -6151,7 +6151,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
|
|||||||
timer_delete_sync(&tgt->timer);
|
timer_delete_sync(&tgt->timer);
|
||||||
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
||||||
return;
|
return;
|
||||||
} else if (rport && tgt->action == IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT) {
|
} else if (tgt->action == IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT) {
|
||||||
tgt_dbg(tgt, "Deleting NVMe rport with outstanding I/O\n");
|
tgt_dbg(tgt, "Deleting NVMe rport with outstanding I/O\n");
|
||||||
nvme_rport = tgt->nvme_remote_port;
|
nvme_rport = tgt->nvme_remote_port;
|
||||||
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT);
|
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT);
|
||||||
|
|||||||
@@ -171,7 +171,8 @@ static int leapraid_ctl_validate_sge_offset(struct leapraid_adapter *adapter,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct leapraid_adapter *leapraid_ctl_lookup_adapter(int adapter_id)
|
static struct leapraid_adapter *leapraid_ctl_lookup_adapter(int adapter_id,
|
||||||
|
bool track_mmap)
|
||||||
{
|
{
|
||||||
struct leapraid_adapter *adapter;
|
struct leapraid_adapter *adapter;
|
||||||
struct Scsi_Host *shost;
|
struct Scsi_Host *shost;
|
||||||
@@ -184,6 +185,8 @@ static struct leapraid_adapter *leapraid_ctl_lookup_adapter(int adapter_id)
|
|||||||
shost = adapter->shost;
|
shost = adapter->shost;
|
||||||
if (!shost || !scsi_host_get(shost))
|
if (!shost || !scsi_host_get(shost))
|
||||||
break;
|
break;
|
||||||
|
if (track_mmap)
|
||||||
|
atomic_inc(&adapter->fw_log_desc.mmap_refcnt);
|
||||||
spin_unlock(&leapraid_adapter_lock);
|
spin_unlock(&leapraid_adapter_lock);
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
@@ -589,7 +592,7 @@ static int leapraid_ctl_ioctl_main(struct file *file, unsigned int cmd,
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter = leapraid_ctl_lookup_adapter(ioctl_header.adapter_id);
|
adapter = leapraid_ctl_lookup_adapter(ioctl_header.adapter_id, false);
|
||||||
if (!adapter)
|
if (!adapter)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
@@ -697,6 +700,7 @@ static void leapraid_fw_mmap_open(struct vm_area_struct *vma)
|
|||||||
if (!adapter)
|
if (!adapter)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
get_device(&adapter->shost->shost_gendev);
|
||||||
atomic_inc(&adapter->fw_log_desc.mmap_refcnt);
|
atomic_inc(&adapter->fw_log_desc.mmap_refcnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -727,7 +731,7 @@ static int leapraid_fw_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||||||
|
|
||||||
length = vma->vm_end - vma->vm_start;
|
length = vma->vm_end - vma->vm_start;
|
||||||
|
|
||||||
adapter = leapraid_ctl_lookup_adapter(adapter_id);
|
adapter = leapraid_ctl_lookup_adapter(adapter_id, true);
|
||||||
if (!adapter) {
|
if (!adapter) {
|
||||||
pr_err("%s: No adapter found!\n", __func__);
|
pr_err("%s: No adapter found!\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -767,10 +771,12 @@ static int leapraid_fw_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||||||
vma->vm_private_data = adapter;
|
vma->vm_private_data = adapter;
|
||||||
vma->vm_ops = &leapraid_fw_mmap_vm_ops;
|
vma->vm_ops = &leapraid_fw_mmap_vm_ops;
|
||||||
leapraid_fw_mmap_open(vma);
|
leapraid_fw_mmap_open(vma);
|
||||||
adapter = NULL;
|
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
out_put:
|
out_put:
|
||||||
|
if (adapter &&
|
||||||
|
atomic_dec_and_test(&adapter->fw_log_desc.mmap_refcnt))
|
||||||
|
wake_up(&adapter->fw_log_desc.mmap_waitq);
|
||||||
leapraid_ctl_put_adapter(adapter);
|
leapraid_ctl_put_adapter(adapter);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ static noinline bool leapraid_shost_in_recovery(struct Scsi_Host *shost)
|
|||||||
{
|
{
|
||||||
enum scsi_host_state state;
|
enum scsi_host_state state;
|
||||||
|
|
||||||
state = READ_ONCE(shost->shost_state);
|
state = scsi_get_host_state(shost);
|
||||||
return state == SHOST_RECOVERY ||
|
return state == SHOST_RECOVERY ||
|
||||||
state == SHOST_CANCEL_RECOVERY ||
|
state == SHOST_CANCEL_RECOVERY ||
|
||||||
state == SHOST_DEL_RECOVERY ||
|
state == SHOST_DEL_RECOVERY ||
|
||||||
|
|||||||
@@ -1064,7 +1064,7 @@ struct leapraid_starget_priv {
|
|||||||
* @starget_priv: Associated target private data.
|
* @starget_priv: Associated target private data.
|
||||||
* @lun: Logical Unit Number.
|
* @lun: Logical Unit Number.
|
||||||
* @flg: Flags.
|
* @flg: Flags.
|
||||||
* @ncq_cmd_prio_enable: Enables NCQ command priority for RT I/O.
|
* @ncq_prio_enable: Enables NCQ command priority for RT I/O.
|
||||||
* @block: Block flag.
|
* @block: Block flag.
|
||||||
* @deleted: Deletion flag.
|
* @deleted: Deletion flag.
|
||||||
* @sep: SEP flag.
|
* @sep: SEP flag.
|
||||||
@@ -1073,7 +1073,7 @@ struct leapraid_sdev_priv {
|
|||||||
struct leapraid_starget_priv *starget_priv;
|
struct leapraid_starget_priv *starget_priv;
|
||||||
unsigned int lun;
|
unsigned int lun;
|
||||||
u32 flg;
|
u32 flg;
|
||||||
u8 ncq_cmd_prio_enable;
|
u8 ncq_prio_enable;
|
||||||
u8 block;
|
u8 block;
|
||||||
u8 deleted;
|
u8 deleted;
|
||||||
u8 sep;
|
u8 sep;
|
||||||
|
|||||||
@@ -808,7 +808,7 @@ static bool leapraid_should_queuecommand(struct leapraid_adapter *adapter,
|
|||||||
goto no_connect;
|
goto no_connect;
|
||||||
|
|
||||||
if (sdev_priv->block &&
|
if (sdev_priv->block &&
|
||||||
scmd->device->host->shost_state == SHOST_RECOVERY &&
|
scsi_get_host_state(scmd->device->host) == SHOST_RECOVERY &&
|
||||||
scmd->cmnd[0] == TEST_UNIT_READY) {
|
scmd->cmnd[0] == TEST_UNIT_READY) {
|
||||||
scsi_build_sense(scmd, 0, UNIT_ATTENTION,
|
scsi_build_sense(scmd, 0, UNIT_ATTENTION,
|
||||||
LEAPRAID_SCSI_ASC_POWER_ON_RESET,
|
LEAPRAID_SCSI_ASC_POWER_ON_RESET,
|
||||||
@@ -859,7 +859,7 @@ static u32 build_scsiio_req_control(struct scsi_cmnd *scmd,
|
|||||||
|
|
||||||
control |= LEAPRAID_SCSIIO_CTRL_SIMPLEQ;
|
control |= LEAPRAID_SCSIIO_CTRL_SIMPLEQ;
|
||||||
|
|
||||||
if (sdev_priv->ncq_cmd_prio_enable &&
|
if (sdev_priv->ncq_prio_enable &&
|
||||||
(IOPRIO_PRIO_CLASS(req_get_ioprio(scsi_cmd_to_rq(scmd))) ==
|
(IOPRIO_PRIO_CLASS(req_get_ioprio(scsi_cmd_to_rq(scmd))) ==
|
||||||
IOPRIO_CLASS_RT))
|
IOPRIO_CLASS_RT))
|
||||||
control |= LEAPRAID_SCSIIO_CTRL_CMDPRI;
|
control |= LEAPRAID_SCSIIO_CTRL_CMDPRI;
|
||||||
@@ -1854,7 +1854,16 @@ static ssize_t sas_device_handle_show(struct device *dev,
|
|||||||
sas_device_priv_data->starget_priv->hdl);
|
sas_device_priv_data->starget_priv->hdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t ncq_cmd_prio_enable_show(struct device *dev,
|
static ssize_t sas_ncq_prio_supported_show(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct scsi_device *sdev = to_scsi_device(dev);
|
||||||
|
|
||||||
|
return sysfs_emit(buf, "%d\n", sas_ata_ncq_prio_supported(sdev));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t sas_ncq_prio_enable_show(struct device *dev,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
@@ -1867,19 +1876,16 @@ static ssize_t ncq_cmd_prio_enable_show(struct device *dev,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sysfs_emit(buf, "%d\n",
|
return sysfs_emit(buf, "%d\n", sas_device_priv_data->ncq_prio_enable);
|
||||||
sas_device_priv_data->ncq_cmd_prio_enable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t ncq_cmd_prio_enable_store(struct device *dev,
|
static ssize_t sas_ncq_prio_enable_store(struct device *dev,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct scsi_device *sdev = to_scsi_device(dev);
|
struct scsi_device *sdev = to_scsi_device(dev);
|
||||||
struct leapraid_sdev_priv *sas_device_priv_data = sdev->hostdata;
|
struct leapraid_sdev_priv *sas_device_priv_data = sdev->hostdata;
|
||||||
struct scsi_vpd *vpd_pg89;
|
bool enable;
|
||||||
int ncq_cmd_prio_enable;
|
|
||||||
bool ncq_supported;
|
|
||||||
|
|
||||||
if (!sas_device_priv_data) {
|
if (!sas_device_priv_data) {
|
||||||
dev_err(&sdev->sdev_gendev,
|
dev_err(&sdev->sdev_gendev,
|
||||||
@@ -1887,44 +1893,63 @@ static ssize_t ncq_cmd_prio_enable_store(struct device *dev,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kstrtoint(buf, 0, &ncq_cmd_prio_enable))
|
if (kstrtobool(buf, &enable))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (ncq_cmd_prio_enable != 0 && ncq_cmd_prio_enable != 1) {
|
if (!sas_ata_ncq_prio_supported(sdev))
|
||||||
dev_err(&sdev->sdev_gendev,
|
|
||||||
"%s: Invalid NCQ cmd prio %d (0/1 only)\n",
|
|
||||||
__func__, ncq_cmd_prio_enable);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
|
||||||
|
|
||||||
rcu_read_lock();
|
sas_device_priv_data->ncq_prio_enable = enable;
|
||||||
vpd_pg89 = rcu_dereference(sdev->vpd_pg89);
|
|
||||||
if (!vpd_pg89 || vpd_pg89->len < LEAPRAID_VPD_PG89_MIN_LEN) {
|
|
||||||
rcu_read_unlock();
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ncq_supported = (vpd_pg89->data[LEAPRAID_VPD_PG89_NCQ_BYTE_IDX] >>
|
|
||||||
LEAPRAID_VPD_PG89_NCQ_BIT_SHIFT) &
|
|
||||||
LEAPRAID_VPD_PG89_NCQ_BIT_MASK;
|
|
||||||
rcu_read_unlock();
|
|
||||||
if (ncq_supported)
|
|
||||||
sas_device_priv_data->ncq_cmd_prio_enable =
|
|
||||||
ncq_cmd_prio_enable;
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR_RO(sas_device_handle);
|
static DEVICE_ATTR_RO(sas_device_handle);
|
||||||
|
static DEVICE_ATTR_RO(sas_ncq_prio_supported);
|
||||||
|
static DEVICE_ATTR_RW(sas_ncq_prio_enable);
|
||||||
|
|
||||||
static DEVICE_ATTR_RW(ncq_cmd_prio_enable);
|
static bool leapraid_sdev_is_sata(struct scsi_device *sdev)
|
||||||
|
{
|
||||||
|
struct scsi_target *starget = sdev->sdev_target;
|
||||||
|
struct leapraid_starget_priv *starget_priv = starget->hostdata;
|
||||||
|
struct leapraid_sas_dev *sas_dev;
|
||||||
|
|
||||||
|
if (!starget_priv)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sas_dev = starget_priv->sas_dev;
|
||||||
|
return sas_dev && (sas_dev->dev_info & LEAPRAID_DEVTYP_SATA_DEV);
|
||||||
|
}
|
||||||
|
|
||||||
static struct attribute *leapraid_sdev_attrs[] = {
|
static struct attribute *leapraid_sdev_attrs[] = {
|
||||||
&dev_attr_sas_device_handle.attr,
|
&dev_attr_sas_device_handle.attr,
|
||||||
&dev_attr_ncq_cmd_prio_enable.attr,
|
&dev_attr_sas_ncq_prio_supported.attr,
|
||||||
|
&dev_attr_sas_ncq_prio_enable.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
ATTRIBUTE_GROUPS(leapraid_sdev);
|
static umode_t leapraid_sdev_attr_is_visible(struct kobject *kobj,
|
||||||
|
struct attribute *attr, int i)
|
||||||
|
{
|
||||||
|
struct device *dev = kobj_to_dev(kobj);
|
||||||
|
struct scsi_device *sdev = to_scsi_device(dev);
|
||||||
|
|
||||||
|
if (attr == &dev_attr_sas_ncq_prio_supported.attr ||
|
||||||
|
attr == &dev_attr_sas_ncq_prio_enable.attr)
|
||||||
|
if (!leapraid_sdev_is_sata(sdev))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return attr->mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct attribute_group leapraid_sdev_attr_group = {
|
||||||
|
.attrs = leapraid_sdev_attrs,
|
||||||
|
.is_visible = leapraid_sdev_attr_is_visible,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group *leapraid_sdev_groups[] = {
|
||||||
|
&leapraid_sdev_attr_group,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
static struct scsi_host_template leapraid_driver_template = {
|
static struct scsi_host_template leapraid_driver_template = {
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
|
|||||||
@@ -345,11 +345,10 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
|
|||||||
SAS_ADDR(phy->attached_sas_addr), type);
|
SAS_ADDR(phy->attached_sas_addr), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if we have an existing attached ata device on this expander phy */
|
/* Return the domain device attached to an expander phy */
|
||||||
struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id)
|
struct domain_device *sas_ex_phy_to_dev(struct domain_device *ex_dev, int phy_id)
|
||||||
{
|
{
|
||||||
struct ex_phy *ex_phy = &ex_dev->ex_dev.ex_phy[phy_id];
|
struct ex_phy *ex_phy = &ex_dev->ex_dev.ex_phy[phy_id];
|
||||||
struct domain_device *dev;
|
|
||||||
struct sas_rphy *rphy;
|
struct sas_rphy *rphy;
|
||||||
|
|
||||||
if (!ex_phy->port)
|
if (!ex_phy->port)
|
||||||
@@ -359,7 +358,13 @@ struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id)
|
|||||||
if (!rphy)
|
if (!rphy)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dev = sas_find_dev_by_rphy(rphy);
|
return sas_find_dev_by_rphy(rphy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we have an existing attached ata device on this expander phy */
|
||||||
|
struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id)
|
||||||
|
{
|
||||||
|
struct domain_device *dev = sas_ex_phy_to_dev(ex_dev, phy_id);
|
||||||
|
|
||||||
if (dev && dev_is_sata(dev))
|
if (dev && dev_is_sata(dev))
|
||||||
return dev;
|
return dev;
|
||||||
@@ -1958,6 +1963,72 @@ static bool dev_type_flutter(enum sas_device_type new, enum sas_device_type old)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sas_rediscover_ex_phy(struct domain_device *dev, int phy_id,
|
||||||
|
bool last)
|
||||||
|
{
|
||||||
|
struct expander_device *ex = &dev->ex_dev;
|
||||||
|
struct ex_phy *phy = &ex->ex_phy[phy_id];
|
||||||
|
|
||||||
|
phy->phy_change_count = -1;
|
||||||
|
ex->ex_change_count = -1;
|
||||||
|
sas_unregister_devs_sas_addr(dev, phy_id, last);
|
||||||
|
sas_discover_event(dev->port, DISCE_REVALIDATE_DOMAIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool sas_dev_is_flutter(struct domain_device *dev, int phy_id,
|
||||||
|
u8 *sas_addr, enum sas_device_type type)
|
||||||
|
{
|
||||||
|
struct expander_device *ex = &dev->ex_dev;
|
||||||
|
struct ex_phy *phy = &ex->ex_phy[phy_id];
|
||||||
|
struct domain_device *child_dev;
|
||||||
|
char *action = "";
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (SAS_ADDR(sas_addr) != SAS_ADDR(phy->attached_sas_addr) ||
|
||||||
|
!dev_type_flutter(type, phy->attached_dev_type))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
res = sas_ex_phy_discover(dev, phy_id);
|
||||||
|
if (res)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
child_dev = sas_ex_phy_to_dev(dev, phy_id);
|
||||||
|
if (!child_dev)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (dev_is_sata(child_dev) &&
|
||||||
|
phy->attached_dev_type == SAS_SATA_PENDING) {
|
||||||
|
action = ", needs recovery";
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SAS_ADDR(child_dev->sas_addr) != SAS_ADDR(phy->attached_sas_addr)) {
|
||||||
|
pr_info("ex %016llx phy%02d sas_addr changed from %016llx to %016llx\n",
|
||||||
|
SAS_ADDR(dev->sas_addr), phy_id,
|
||||||
|
SAS_ADDR(child_dev->sas_addr),
|
||||||
|
SAS_ADDR(phy->attached_sas_addr));
|
||||||
|
/*
|
||||||
|
* Device unregistering relies on address matching. Restore
|
||||||
|
* attached_sas_addr back to the original address so that the old
|
||||||
|
* device can be unregistered later
|
||||||
|
*/
|
||||||
|
memcpy(phy->attached_sas_addr, child_dev->sas_addr, SAS_ADDR_SIZE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child_dev->linkrate != phy->linkrate) {
|
||||||
|
pr_info("ex %016llx phy%02d linkrate changed from %d to %d\n",
|
||||||
|
SAS_ADDR(dev->sas_addr), phy_id,
|
||||||
|
child_dev->linkrate, phy->linkrate);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
pr_debug("ex %016llx phy%02d broadcast flutter%s\n",
|
||||||
|
SAS_ADDR(dev->sas_addr), phy_id, action);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
|
static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
|
||||||
bool last, int sibling)
|
bool last, int sibling)
|
||||||
{
|
{
|
||||||
@@ -2011,27 +2082,16 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
|
|||||||
if (res == 0)
|
if (res == 0)
|
||||||
sas_set_ex_phy(dev, phy_id, disc_resp);
|
sas_set_ex_phy(dev, phy_id, disc_resp);
|
||||||
goto out_free_resp;
|
goto out_free_resp;
|
||||||
} else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) &&
|
|
||||||
dev_type_flutter(type, phy->attached_dev_type)) {
|
|
||||||
struct domain_device *ata_dev = sas_ex_to_ata(dev, phy_id);
|
|
||||||
char *action = "";
|
|
||||||
|
|
||||||
sas_ex_phy_discover(dev, phy_id);
|
|
||||||
|
|
||||||
if (ata_dev && phy->attached_dev_type == SAS_SATA_PENDING)
|
|
||||||
action = ", needs recovery";
|
|
||||||
pr_debug("ex %016llx phy%02d broadcast flutter%s\n",
|
|
||||||
SAS_ADDR(dev->sas_addr), phy_id, action);
|
|
||||||
goto out_free_resp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sas_dev_is_flutter(dev, phy_id, sas_addr, type))
|
||||||
|
goto out_free_resp;
|
||||||
|
|
||||||
/* we always have to delete the old device when we went here */
|
/* we always have to delete the old device when we went here */
|
||||||
pr_info("ex %016llx phy%02d replace %016llx\n",
|
pr_info("ex %016llx phy%02d replace %016llx\n",
|
||||||
SAS_ADDR(dev->sas_addr), phy_id,
|
SAS_ADDR(dev->sas_addr), phy_id,
|
||||||
SAS_ADDR(phy->attached_sas_addr));
|
SAS_ADDR(phy->attached_sas_addr));
|
||||||
sas_unregister_devs_sas_addr(dev, phy_id, last);
|
sas_rediscover_ex_phy(dev, phy_id, last);
|
||||||
|
|
||||||
res = sas_discover_new(dev, phy_id);
|
|
||||||
out_free_resp:
|
out_free_resp:
|
||||||
kfree(disc_resp);
|
kfree(disc_resp);
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy);
|
|||||||
|
|
||||||
void sas_device_set_phy(struct domain_device *dev, struct sas_port *port);
|
void sas_device_set_phy(struct domain_device *dev, struct sas_port *port);
|
||||||
struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy);
|
struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy);
|
||||||
|
struct domain_device *sas_ex_phy_to_dev(struct domain_device *ex_dev, int phy_id);
|
||||||
struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id);
|
struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id);
|
||||||
int sas_ex_phy_discover(struct domain_device *dev, int single);
|
int sas_ex_phy_discover(struct domain_device *dev, int single);
|
||||||
int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
|
int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
|
||||||
|
|||||||
+219
-314
@@ -57,7 +57,6 @@
|
|||||||
#define LPFC_MIN_DEVLOSS_TMO 1
|
#define LPFC_MIN_DEVLOSS_TMO 1
|
||||||
#define LPFC_MAX_DEVLOSS_TMO 255
|
#define LPFC_MAX_DEVLOSS_TMO 255
|
||||||
|
|
||||||
#define LPFC_MAX_INFO_TMP_LEN 100
|
|
||||||
#define LPFC_INFO_MORE_STR "\nCould be more info...\n"
|
#define LPFC_INFO_MORE_STR "\nCould be more info...\n"
|
||||||
/*
|
/*
|
||||||
* Write key size should be multiple of 4. If write key is changed
|
* Write key size should be multiple of 4. If write key is changed
|
||||||
@@ -126,133 +125,121 @@ lpfc_cmf_info_show(struct device *dev, struct device_attribute *attr,
|
|||||||
int len = 0;
|
int len = 0;
|
||||||
int cpu;
|
int cpu;
|
||||||
u64 rcv, total;
|
u64 rcv, total;
|
||||||
char tmp[LPFC_MAX_INFO_TMP_LEN] = {0};
|
|
||||||
|
|
||||||
if (phba->cgn_i)
|
if (phba->cgn_i)
|
||||||
cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;
|
cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len = strnlen(buf, PAGE_SIZE);
|
||||||
"Congestion Mgmt Info: E2Eattr %d Ver %d "
|
len += sysfs_emit_at(buf, len,
|
||||||
"CMF %d cnt %d\n",
|
"Congestion Mgmt Info: E2Eattr %d Ver %d CMF %d cnt %d\n",
|
||||||
phba->sli4_hba.pc_sli4_params.mi_cap,
|
phba->sli4_hba.pc_sli4_params.mi_cap,
|
||||||
cp ? cp->cgn_info_version : 0,
|
cp ? cp->cgn_info_version : 0,
|
||||||
phba->sli4_hba.pc_sli4_params.cmf, phba->cmf_timer_cnt);
|
phba->sli4_hba.pc_sli4_params.cmf,
|
||||||
|
phba->cmf_timer_cnt);
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
if (!phba->sli4_hba.pc_sli4_params.cmf)
|
if (!phba->sli4_hba.pc_sli4_params.cmf)
|
||||||
goto buffer_done;
|
goto buffer_done;
|
||||||
|
|
||||||
switch (phba->cgn_init_reg_signal) {
|
switch (phba->cgn_init_reg_signal) {
|
||||||
case EDC_CG_SIG_WARN_ONLY:
|
case EDC_CG_SIG_WARN_ONLY:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"Register: Init: Signal:WARN ");
|
"Register: Init: Signal:WARN ");
|
||||||
break;
|
break;
|
||||||
case EDC_CG_SIG_WARN_ALARM:
|
case EDC_CG_SIG_WARN_ALARM:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"Register: Init: Signal:WARN|ALARM ");
|
"Register: Init: Signal:WARN|ALARM ");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"Register: Init: Signal:NONE ");
|
"Register: Init: Signal:NONE ");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
switch (phba->cgn_init_reg_fpin) {
|
switch (phba->cgn_init_reg_fpin) {
|
||||||
case LPFC_CGN_FPIN_WARN:
|
case LPFC_CGN_FPIN_WARN:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len, "FPIN:WARN\n");
|
||||||
"FPIN:WARN\n");
|
|
||||||
break;
|
break;
|
||||||
case LPFC_CGN_FPIN_ALARM:
|
case LPFC_CGN_FPIN_ALARM:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len, "FPIN:ALARM\n");
|
||||||
"FPIN:ALARM\n");
|
|
||||||
break;
|
break;
|
||||||
case LPFC_CGN_FPIN_BOTH:
|
case LPFC_CGN_FPIN_BOTH:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len, "FPIN:WARN|ALARM\n");
|
||||||
"FPIN:WARN|ALARM\n");
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len, "FPIN:NONE\n");
|
||||||
"FPIN:NONE\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
switch (phba->cgn_reg_signal) {
|
switch (phba->cgn_reg_signal) {
|
||||||
case EDC_CG_SIG_WARN_ONLY:
|
case EDC_CG_SIG_WARN_ONLY:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
" Current: Signal:WARN ");
|
" Current: Signal:WARN ");
|
||||||
break;
|
break;
|
||||||
case EDC_CG_SIG_WARN_ALARM:
|
case EDC_CG_SIG_WARN_ALARM:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
" Current: Signal:WARN|ALARM ");
|
" Current: Signal:WARN|ALARM ");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
" Current: Signal:NONE ");
|
" Current: Signal:NONE ");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
switch (phba->cgn_reg_fpin) {
|
switch (phba->cgn_reg_fpin) {
|
||||||
case LPFC_CGN_FPIN_WARN:
|
case LPFC_CGN_FPIN_WARN:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"FPIN:WARN ACQEcnt:%d\n", phba->cgn_acqe_cnt);
|
"FPIN:WARN ACQEcnt:%d\n",
|
||||||
|
phba->cgn_acqe_cnt);
|
||||||
break;
|
break;
|
||||||
case LPFC_CGN_FPIN_ALARM:
|
case LPFC_CGN_FPIN_ALARM:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"FPIN:ALARM ACQEcnt:%d\n", phba->cgn_acqe_cnt);
|
"FPIN:ALARM ACQEcnt:%d\n",
|
||||||
|
phba->cgn_acqe_cnt);
|
||||||
break;
|
break;
|
||||||
case LPFC_CGN_FPIN_BOTH:
|
case LPFC_CGN_FPIN_BOTH:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"FPIN:WARN|ALARM ACQEcnt:%d\n", phba->cgn_acqe_cnt);
|
"FPIN:WARN|ALARM ACQEcnt:%d\n",
|
||||||
|
phba->cgn_acqe_cnt);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"FPIN:NONE ACQEcnt:%d\n", phba->cgn_acqe_cnt);
|
"FPIN:NONE ACQEcnt:%d\n",
|
||||||
|
phba->cgn_acqe_cnt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
if (phba->cmf_active_mode != phba->cgn_p.cgn_param_mode) {
|
if (phba->cmf_active_mode != phba->cgn_p.cgn_param_mode) {
|
||||||
switch (phba->cmf_active_mode) {
|
switch (phba->cmf_active_mode) {
|
||||||
case LPFC_CFG_OFF:
|
case LPFC_CFG_OFF:
|
||||||
scnprintf(tmp, sizeof(tmp), "Active: Mode:Off\n");
|
len += sysfs_emit_at(buf, len, "Active: Mode:Off\n");
|
||||||
break;
|
break;
|
||||||
case LPFC_CFG_MANAGED:
|
case LPFC_CFG_MANAGED:
|
||||||
scnprintf(tmp, sizeof(tmp), "Active: Mode:Managed\n");
|
len += sysfs_emit_at(buf, len,
|
||||||
|
"Active: Mode:Managed\n");
|
||||||
break;
|
break;
|
||||||
case LPFC_CFG_MONITOR:
|
case LPFC_CFG_MONITOR:
|
||||||
scnprintf(tmp, sizeof(tmp), "Active: Mode:Monitor\n");
|
len += sysfs_emit_at(buf, len,
|
||||||
|
"Active: Mode:Monitor\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scnprintf(tmp, sizeof(tmp), "Active: Mode:Unknown\n");
|
len += sysfs_emit_at(buf, len,
|
||||||
|
"Active: Mode:Unknown\n");
|
||||||
}
|
}
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (phba->cgn_p.cgn_param_mode) {
|
switch (phba->cgn_p.cgn_param_mode) {
|
||||||
case LPFC_CFG_OFF:
|
case LPFC_CFG_OFF:
|
||||||
scnprintf(tmp, sizeof(tmp), "Config: Mode:Off ");
|
len += sysfs_emit_at(buf, len, "Config: Mode:Off ");
|
||||||
break;
|
break;
|
||||||
case LPFC_CFG_MANAGED:
|
case LPFC_CFG_MANAGED:
|
||||||
scnprintf(tmp, sizeof(tmp), "Config: Mode:Managed ");
|
len += sysfs_emit_at(buf, len, "Config: Mode:Managed ");
|
||||||
break;
|
break;
|
||||||
case LPFC_CFG_MONITOR:
|
case LPFC_CFG_MONITOR:
|
||||||
scnprintf(tmp, sizeof(tmp), "Config: Mode:Monitor ");
|
len += sysfs_emit_at(buf, len, "Config: Mode:Monitor ");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scnprintf(tmp, sizeof(tmp), "Config: Mode:Unknown ");
|
len += sysfs_emit_at(buf, len, "Config: Mode:Unknown ");
|
||||||
}
|
}
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
total = 0;
|
total = 0;
|
||||||
rcv = 0;
|
rcv = 0;
|
||||||
@@ -262,24 +249,18 @@ lpfc_cmf_info_show(struct device *dev, struct device_attribute *attr,
|
|||||||
rcv += atomic64_read(&cgs->rcv_bytes);
|
rcv += atomic64_read(&cgs->rcv_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"IObusy:%d Info:%d Bytes: Rcv:x%llx Total:x%llx\n",
|
"IObusy:%d Info:%d Bytes: Rcv:x%llx Total:x%llx\n",
|
||||||
atomic_read(&phba->cmf_busy),
|
atomic_read(&phba->cmf_busy),
|
||||||
phba->cmf_active_info, rcv, total);
|
phba->cmf_active_info, rcv, total);
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"Port_speed:%d Link_byte_cnt:%ld "
|
"Port_speed:%d Link_byte_cnt:%ld Max_byte_per_interval:%ld\n",
|
||||||
"Max_byte_per_interval:%ld\n",
|
lpfc_sli_port_speed_get(phba),
|
||||||
lpfc_sli_port_speed_get(phba),
|
(unsigned long)phba->cmf_link_byte_count,
|
||||||
(unsigned long)phba->cmf_link_byte_count,
|
(unsigned long)phba->cmf_max_bytes_per_interval);
|
||||||
(unsigned long)phba->cmf_max_bytes_per_interval);
|
|
||||||
strlcat(buf, tmp, PAGE_SIZE);
|
|
||||||
|
|
||||||
buffer_done:
|
buffer_done:
|
||||||
len = strnlen(buf, PAGE_SIZE);
|
|
||||||
|
|
||||||
if (unlikely(len >= (PAGE_SIZE - 1))) {
|
if (unlikely(len >= (PAGE_SIZE - 1))) {
|
||||||
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
|
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
|
||||||
"6312 Catching potential buffer "
|
"6312 Catching potential buffer "
|
||||||
@@ -480,17 +461,19 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
|
|||||||
char *statep;
|
char *statep;
|
||||||
int i;
|
int i;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
char tmp[LPFC_MAX_INFO_TMP_LEN] = {0};
|
|
||||||
|
|
||||||
if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) {
|
if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) {
|
||||||
len = scnprintf(buf, PAGE_SIZE, "NVME Disabled\n");
|
len = sysfs_emit(buf, "NVME Disabled\n");
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
len = strnlen(buf, PAGE_SIZE);
|
||||||
|
|
||||||
if (phba->nvmet_support) {
|
if (phba->nvmet_support) {
|
||||||
if (!phba->targetport) {
|
if (!phba->targetport) {
|
||||||
len = scnprintf(buf, PAGE_SIZE,
|
len = sysfs_emit(buf,
|
||||||
"NVME Target: x%llx is not allocated\n",
|
"NVME Target: x%llx is not allocated\n",
|
||||||
wwn_to_u64(vport->fc_portname.u.wwn));
|
wwn_to_u64(vport->fc_portname.u.wwn));
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
/* Port state is only one of two values for now. */
|
/* Port state is only one of two values for now. */
|
||||||
@@ -498,167 +481,131 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
|
|||||||
statep = "REGISTERED";
|
statep = "REGISTERED";
|
||||||
else
|
else
|
||||||
statep = "INIT";
|
statep = "INIT";
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"NVME Target Enabled State %s\n",
|
"NVME Target Enabled State %s\n",
|
||||||
statep);
|
statep);
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"%s%d WWPN x%llx WWNN x%llx DID x%06x\n",
|
"%s%d WWPN x%llx WWNN x%llx DID x%06x\n",
|
||||||
"NVME Target: lpfc",
|
"NVME Target: lpfc",
|
||||||
phba->brd_no,
|
phba->brd_no,
|
||||||
wwn_to_u64(vport->fc_portname.u.wwn),
|
wwn_to_u64(vport->fc_portname.u.wwn),
|
||||||
wwn_to_u64(vport->fc_nodename.u.wwn),
|
wwn_to_u64(vport->fc_nodename.u.wwn),
|
||||||
phba->targetport->port_id);
|
phba->targetport->port_id);
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
if (strlcat(buf, "\nNVME Target: Statistics\n", PAGE_SIZE)
|
len += sysfs_emit_at(buf, len, "\nNVME Target: Statistics\n");
|
||||||
>= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
|
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"LS: Rcv %08x Drop %08x Abort %08x\n",
|
"LS: Rcv %08x Drop %08x Abort %08x\n",
|
||||||
atomic_read(&tgtp->rcv_ls_req_in),
|
atomic_read(&tgtp->rcv_ls_req_in),
|
||||||
atomic_read(&tgtp->rcv_ls_req_drop),
|
atomic_read(&tgtp->rcv_ls_req_drop),
|
||||||
atomic_read(&tgtp->xmt_ls_abort));
|
atomic_read(&tgtp->xmt_ls_abort));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
if (atomic_read(&tgtp->rcv_ls_req_in) !=
|
if (atomic_read(&tgtp->rcv_ls_req_in) !=
|
||||||
atomic_read(&tgtp->rcv_ls_req_out)) {
|
atomic_read(&tgtp->rcv_ls_req_out)) {
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"Rcv LS: in %08x != out %08x\n",
|
"Rcv LS: in %08x != out %08x\n",
|
||||||
atomic_read(&tgtp->rcv_ls_req_in),
|
atomic_read(&tgtp->rcv_ls_req_in),
|
||||||
atomic_read(&tgtp->rcv_ls_req_out));
|
atomic_read(&tgtp->rcv_ls_req_out));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"LS: Xmt %08x Drop %08x Cmpl %08x\n",
|
"LS: Xmt %08x Drop %08x Cmpl %08x\n",
|
||||||
atomic_read(&tgtp->xmt_ls_rsp),
|
atomic_read(&tgtp->xmt_ls_rsp),
|
||||||
atomic_read(&tgtp->xmt_ls_drop),
|
atomic_read(&tgtp->xmt_ls_drop),
|
||||||
atomic_read(&tgtp->xmt_ls_rsp_cmpl));
|
atomic_read(&tgtp->xmt_ls_rsp_cmpl));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"LS: RSP Abort %08x xb %08x Err %08x\n",
|
"LS: RSP Abort %08x xb %08x Err %08x\n",
|
||||||
atomic_read(&tgtp->xmt_ls_rsp_aborted),
|
atomic_read(&tgtp->xmt_ls_rsp_aborted),
|
||||||
atomic_read(&tgtp->xmt_ls_rsp_xb_set),
|
atomic_read(&tgtp->xmt_ls_rsp_xb_set),
|
||||||
atomic_read(&tgtp->xmt_ls_rsp_error));
|
atomic_read(&tgtp->xmt_ls_rsp_error));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"FCP: Rcv %08x Defer %08x Release %08x "
|
"FCP: Rcv %08x Defer %08x Release %08x Drop %08x\n",
|
||||||
"Drop %08x\n",
|
atomic_read(&tgtp->rcv_fcp_cmd_in),
|
||||||
atomic_read(&tgtp->rcv_fcp_cmd_in),
|
atomic_read(&tgtp->rcv_fcp_cmd_defer),
|
||||||
atomic_read(&tgtp->rcv_fcp_cmd_defer),
|
atomic_read(&tgtp->xmt_fcp_release),
|
||||||
atomic_read(&tgtp->xmt_fcp_release),
|
atomic_read(&tgtp->rcv_fcp_cmd_drop));
|
||||||
atomic_read(&tgtp->rcv_fcp_cmd_drop));
|
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
|
if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
|
||||||
atomic_read(&tgtp->rcv_fcp_cmd_out)) {
|
atomic_read(&tgtp->rcv_fcp_cmd_out)) {
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"Rcv FCP: in %08x != out %08x\n",
|
"Rcv FCP: in %08x != out %08x\n",
|
||||||
atomic_read(&tgtp->rcv_fcp_cmd_in),
|
atomic_read(&tgtp->rcv_fcp_cmd_in),
|
||||||
atomic_read(&tgtp->rcv_fcp_cmd_out));
|
atomic_read(&tgtp->rcv_fcp_cmd_out));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x "
|
"FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x drop %08x\n",
|
||||||
"drop %08x\n",
|
atomic_read(&tgtp->xmt_fcp_read),
|
||||||
atomic_read(&tgtp->xmt_fcp_read),
|
atomic_read(&tgtp->xmt_fcp_read_rsp),
|
||||||
atomic_read(&tgtp->xmt_fcp_read_rsp),
|
atomic_read(&tgtp->xmt_fcp_write),
|
||||||
atomic_read(&tgtp->xmt_fcp_write),
|
atomic_read(&tgtp->xmt_fcp_rsp),
|
||||||
atomic_read(&tgtp->xmt_fcp_rsp),
|
atomic_read(&tgtp->xmt_fcp_drop));
|
||||||
atomic_read(&tgtp->xmt_fcp_drop));
|
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"FCP Rsp Cmpl: %08x err %08x drop %08x\n",
|
"FCP Rsp Cmpl: %08x err %08x drop %08x\n",
|
||||||
atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
|
atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
|
||||||
atomic_read(&tgtp->xmt_fcp_rsp_error),
|
atomic_read(&tgtp->xmt_fcp_rsp_error),
|
||||||
atomic_read(&tgtp->xmt_fcp_rsp_drop));
|
atomic_read(&tgtp->xmt_fcp_rsp_drop));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
|
"FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
|
||||||
atomic_read(&tgtp->xmt_fcp_rsp_aborted),
|
atomic_read(&tgtp->xmt_fcp_rsp_aborted),
|
||||||
atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
|
atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
|
||||||
atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
|
atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"ABORT: Xmt %08x Cmpl %08x\n",
|
"ABORT: Xmt %08x Cmpl %08x\n",
|
||||||
atomic_read(&tgtp->xmt_fcp_abort),
|
atomic_read(&tgtp->xmt_fcp_abort),
|
||||||
atomic_read(&tgtp->xmt_fcp_abort_cmpl));
|
atomic_read(&tgtp->xmt_fcp_abort_cmpl));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x\n",
|
"ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x\n",
|
||||||
atomic_read(&tgtp->xmt_abort_sol),
|
atomic_read(&tgtp->xmt_abort_sol),
|
||||||
atomic_read(&tgtp->xmt_abort_unsol),
|
atomic_read(&tgtp->xmt_abort_unsol),
|
||||||
atomic_read(&tgtp->xmt_abort_rsp),
|
atomic_read(&tgtp->xmt_abort_rsp),
|
||||||
atomic_read(&tgtp->xmt_abort_rsp_error));
|
atomic_read(&tgtp->xmt_abort_rsp_error));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"DELAY: ctx %08x fod %08x wqfull %08x\n",
|
"DELAY: ctx %08x fod %08x wqfull %08x\n",
|
||||||
atomic_read(&tgtp->defer_ctx),
|
atomic_read(&tgtp->defer_ctx),
|
||||||
atomic_read(&tgtp->defer_fod),
|
atomic_read(&tgtp->defer_fod),
|
||||||
atomic_read(&tgtp->defer_wqfull));
|
atomic_read(&tgtp->defer_wqfull));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
/* Calculate outstanding IOs */
|
/* Calculate outstanding IOs */
|
||||||
tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
|
tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
|
||||||
tot += atomic_read(&tgtp->xmt_fcp_release);
|
tot += atomic_read(&tgtp->xmt_fcp_release);
|
||||||
tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot;
|
tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot;
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"IO_CTX: %08x WAIT: cur %08x tot %08x\n"
|
"IO_CTX: %08x WAIT: cur %08x tot %08x\n"
|
||||||
"CTX Outstanding %08llx\n\n",
|
"CTX Outstanding %08llx\n\n",
|
||||||
phba->sli4_hba.nvmet_xri_cnt,
|
phba->sli4_hba.nvmet_xri_cnt,
|
||||||
phba->sli4_hba.nvmet_io_wait_cnt,
|
phba->sli4_hba.nvmet_io_wait_cnt,
|
||||||
phba->sli4_hba.nvmet_io_wait_total,
|
phba->sli4_hba.nvmet_io_wait_total,
|
||||||
tot);
|
tot);
|
||||||
strlcat(buf, tmp, PAGE_SIZE);
|
|
||||||
goto buffer_done;
|
goto buffer_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
localport = vport->localport;
|
localport = vport->localport;
|
||||||
if (!localport) {
|
if (!localport) {
|
||||||
len = scnprintf(buf, PAGE_SIZE,
|
len = sysfs_emit(buf,
|
||||||
"NVME Initiator x%llx is not allocated\n",
|
"NVME Initiator x%llx is not allocated\n",
|
||||||
wwn_to_u64(vport->fc_portname.u.wwn));
|
wwn_to_u64(vport->fc_portname.u.wwn));
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
lport = (struct lpfc_nvme_lport *)localport->private;
|
lport = (struct lpfc_nvme_lport *)localport->private;
|
||||||
if (strlcat(buf, "\nNVME Initiator Enabled\n", PAGE_SIZE) >= PAGE_SIZE)
|
len += sysfs_emit_at(buf, len, "\nNVME Initiator Enabled\n");
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"XRI Dist lpfc%d Total %d IO %d ELS %d\n",
|
"XRI Dist lpfc%d Total %d IO %d ELS %d\n",
|
||||||
phba->brd_no,
|
phba->brd_no,
|
||||||
phba->sli4_hba.max_cfg_param.max_xri,
|
phba->sli4_hba.max_cfg_param.max_xri,
|
||||||
phba->sli4_hba.io_xri_max,
|
phba->sli4_hba.io_xri_max,
|
||||||
lpfc_sli4_get_els_iocb_cnt(phba));
|
lpfc_sli4_get_els_iocb_cnt(phba));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
/* Port state is only one of two values for now. */
|
/* Port state is only one of two values for now. */
|
||||||
if (localport->port_id)
|
if (localport->port_id)
|
||||||
@@ -666,15 +613,13 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
|
|||||||
else
|
else
|
||||||
statep = "UNKNOWN ";
|
statep = "UNKNOWN ";
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"%s%d WWPN x%llx WWNN x%llx DID x%06x %s\n",
|
"%s%d WWPN x%llx WWNN x%llx DID x%06x %s\n",
|
||||||
"NVME LPORT lpfc",
|
"NVME LPORT lpfc",
|
||||||
phba->brd_no,
|
phba->brd_no,
|
||||||
wwn_to_u64(vport->fc_portname.u.wwn),
|
wwn_to_u64(vport->fc_portname.u.wwn),
|
||||||
wwn_to_u64(vport->fc_nodename.u.wwn),
|
wwn_to_u64(vport->fc_nodename.u.wwn),
|
||||||
localport->port_id, statep);
|
localport->port_id, statep);
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&vport->fc_nodes_list_lock, iflags);
|
spin_lock_irqsave(&vport->fc_nodes_list_lock, iflags);
|
||||||
|
|
||||||
@@ -702,77 +647,55 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Tab in to show lport ownership. */
|
/* Tab in to show lport ownership. */
|
||||||
if (strlcat(buf, "NVME RPORT ", PAGE_SIZE) >= PAGE_SIZE)
|
len += sysfs_emit_at(buf, len, "NVME RPORT ");
|
||||||
goto unlock_buf_done;
|
if (phba->brd_no >= 10)
|
||||||
if (phba->brd_no >= 10) {
|
len += sysfs_emit_at(buf, len, " ");
|
||||||
if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto unlock_buf_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "WWPN x%llx ",
|
len += sysfs_emit_at(buf, len, "WWPN x%llx ",
|
||||||
nrport->port_name);
|
nrport->port_name);
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto unlock_buf_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "WWNN x%llx ",
|
len += sysfs_emit_at(buf, len, "WWNN x%llx ",
|
||||||
nrport->node_name);
|
nrport->node_name);
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto unlock_buf_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "DID x%06x ",
|
len += sysfs_emit_at(buf, len, "DID x%06x ",
|
||||||
nrport->port_id);
|
nrport->port_id);
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto unlock_buf_done;
|
|
||||||
|
|
||||||
/* An NVME rport can have multiple roles. */
|
/* An NVME rport can have multiple roles. */
|
||||||
if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) {
|
if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR)
|
||||||
if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE)
|
len += sysfs_emit_at(buf, len, "INITIATOR ");
|
||||||
goto unlock_buf_done;
|
if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET)
|
||||||
}
|
len += sysfs_emit_at(buf, len, "TARGET ");
|
||||||
if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) {
|
if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY)
|
||||||
if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE)
|
len += sysfs_emit_at(buf, len, "DISCSRVC ");
|
||||||
goto unlock_buf_done;
|
|
||||||
}
|
|
||||||
if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) {
|
|
||||||
if (strlcat(buf, "DISCSRVC ", PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto unlock_buf_done;
|
|
||||||
}
|
|
||||||
if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
|
if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
|
||||||
FC_PORT_ROLE_NVME_TARGET |
|
FC_PORT_ROLE_NVME_TARGET |
|
||||||
FC_PORT_ROLE_NVME_DISCOVERY)) {
|
FC_PORT_ROLE_NVME_DISCOVERY))
|
||||||
scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x",
|
len += sysfs_emit_at(buf, len, "UNKNOWN ROLE x%x",
|
||||||
nrport->port_role);
|
nrport->port_role);
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto unlock_buf_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "%s\n", statep);
|
len += sysfs_emit_at(buf, len, "%s\n", statep);
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto unlock_buf_done;
|
if (len >= PAGE_SIZE - 1)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&vport->fc_nodes_list_lock, iflags);
|
spin_unlock_irqrestore(&vport->fc_nodes_list_lock, iflags);
|
||||||
|
|
||||||
if (!lport)
|
if (!lport)
|
||||||
goto buffer_done;
|
goto buffer_done;
|
||||||
|
|
||||||
if (strlcat(buf, "\nNVME Statistics\n", PAGE_SIZE) >= PAGE_SIZE)
|
len += sysfs_emit_at(buf, len, "\nNVME Statistics\n");
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"LS: Xmt %010x Cmpl %010x Abort %08x\n",
|
"LS: Xmt %010x Cmpl %010x Abort %08x\n",
|
||||||
atomic_read(&lport->fc4NvmeLsRequests),
|
atomic_read(&lport->fc4NvmeLsRequests),
|
||||||
atomic_read(&lport->fc4NvmeLsCmpls),
|
atomic_read(&lport->fc4NvmeLsCmpls),
|
||||||
atomic_read(&lport->xmt_ls_abort));
|
atomic_read(&lport->xmt_ls_abort));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"LS XMIT: Err %08x CMPL: xb %08x Err %08x\n",
|
"LS XMIT: Err %08x CMPL: xb %08x Err %08x\n",
|
||||||
atomic_read(&lport->xmt_ls_err),
|
atomic_read(&lport->xmt_ls_err),
|
||||||
atomic_read(&lport->cmpl_ls_xb),
|
atomic_read(&lport->cmpl_ls_xb),
|
||||||
atomic_read(&lport->cmpl_ls_err));
|
atomic_read(&lport->cmpl_ls_err));
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
totin = 0;
|
totin = 0;
|
||||||
totout = 0;
|
totout = 0;
|
||||||
@@ -785,40 +708,25 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
|
|||||||
data3 = cstat->control_requests;
|
data3 = cstat->control_requests;
|
||||||
totout += (data1 + data2 + data3);
|
totout += (data1 + data2 + data3);
|
||||||
}
|
}
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"Total FCP Cmpl %016llx Issue %016llx "
|
"Total FCP Cmpl %016llx Issue %016llx OutIO %016llx\n",
|
||||||
"OutIO %016llx\n",
|
totin, totout, totout - totin);
|
||||||
totin, totout, totout - totin);
|
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"\tabort %08x noxri %08x nondlp %08x qdepth %08x "
|
"\tabort %08x noxri %08x nondlp %08x qdepth %08x wqerr %08x err %08x\n",
|
||||||
"wqerr %08x err %08x\n",
|
atomic_read(&lport->xmt_fcp_abort),
|
||||||
atomic_read(&lport->xmt_fcp_abort),
|
atomic_read(&lport->xmt_fcp_noxri),
|
||||||
atomic_read(&lport->xmt_fcp_noxri),
|
atomic_read(&lport->xmt_fcp_bad_ndlp),
|
||||||
atomic_read(&lport->xmt_fcp_bad_ndlp),
|
atomic_read(&lport->xmt_fcp_qdepth),
|
||||||
atomic_read(&lport->xmt_fcp_qdepth),
|
atomic_read(&lport->xmt_fcp_wqerr),
|
||||||
atomic_read(&lport->xmt_fcp_wqerr),
|
atomic_read(&lport->xmt_fcp_err));
|
||||||
atomic_read(&lport->xmt_fcp_err));
|
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
len += sysfs_emit_at(buf, len,
|
||||||
"FCP CMPL: xb %08x Err %08x\n",
|
"FCP CMPL: xb %08x Err %08x\n",
|
||||||
atomic_read(&lport->cmpl_fcp_xb),
|
atomic_read(&lport->cmpl_fcp_xb),
|
||||||
atomic_read(&lport->cmpl_fcp_err));
|
atomic_read(&lport->cmpl_fcp_err));
|
||||||
strlcat(buf, tmp, PAGE_SIZE);
|
|
||||||
|
|
||||||
/* host_lock is already unlocked. */
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
unlock_buf_done:
|
|
||||||
spin_unlock_irqrestore(&vport->fc_nodes_list_lock, iflags);
|
|
||||||
|
|
||||||
buffer_done:
|
buffer_done:
|
||||||
len = strnlen(buf, PAGE_SIZE);
|
|
||||||
|
|
||||||
if (unlikely(len >= (PAGE_SIZE - 1))) {
|
if (unlikely(len >= (PAGE_SIZE - 1))) {
|
||||||
lpfc_printf_log(phba, KERN_INFO, LOG_NVME,
|
lpfc_printf_log(phba, KERN_INFO, LOG_NVME,
|
||||||
"6314 Catching potential buffer "
|
"6314 Catching potential buffer "
|
||||||
@@ -844,13 +752,12 @@ lpfc_scsi_stat_show(struct device *dev, struct device_attribute *attr,
|
|||||||
u64 data1, data2, data3;
|
u64 data1, data2, data3;
|
||||||
u64 tot, totin, totout;
|
u64 tot, totin, totout;
|
||||||
int i;
|
int i;
|
||||||
char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
|
|
||||||
|
|
||||||
if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
|
if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
|
||||||
(phba->sli_rev != LPFC_SLI_REV4))
|
(phba->sli_rev != LPFC_SLI_REV4))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
scnprintf(buf, PAGE_SIZE, "SCSI HDWQ Statistics\n");
|
len = sysfs_emit(buf, "SCSI HDWQ Statistics\n");
|
||||||
|
|
||||||
totin = 0;
|
totin = 0;
|
||||||
totout = 0;
|
totout = 0;
|
||||||
@@ -863,22 +770,20 @@ lpfc_scsi_stat_show(struct device *dev, struct device_attribute *attr,
|
|||||||
data3 = cstat->control_requests;
|
data3 = cstat->control_requests;
|
||||||
totout += (data1 + data2 + data3);
|
totout += (data1 + data2 + data3);
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx "
|
len += sysfs_emit_at(buf, len,
|
||||||
"IO %016llx ", i, data1, data2, data3);
|
"HDWQ (%d): Rd %016llx Wr %016llx IO %016llx ",
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
i, data1, data2, data3);
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n",
|
len += sysfs_emit_at(buf, len,
|
||||||
tot, ((data1 + data2 + data3) - tot));
|
"Cmpl %016llx OutIO %016llx\n",
|
||||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
tot, ((data1 + data2 + data3) - tot));
|
||||||
goto buffer_done;
|
|
||||||
|
if (len >= PAGE_SIZE - 1)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx "
|
len += sysfs_emit_at(buf, len,
|
||||||
"OutIO %016llx\n", totin, totout, totout - totin);
|
"Total FCP Cmpl %016llx Issue %016llx OutIO %016llx\n",
|
||||||
strlcat(buf, tmp, PAGE_SIZE);
|
totin, totout, totout - totin);
|
||||||
|
|
||||||
buffer_done:
|
|
||||||
len = strnlen(buf, PAGE_SIZE);
|
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1329,10 +1329,8 @@ lpfc_bsg_hba_get_event(struct bsg_job *job)
|
|||||||
else
|
else
|
||||||
bsg_reply->reply_payload_rcv_len = 0;
|
bsg_reply->reply_payload_rcv_len = 0;
|
||||||
|
|
||||||
if (evt_dat) {
|
kfree(evt_dat->data);
|
||||||
kfree(evt_dat->data);
|
kfree(evt_dat);
|
||||||
kfree(evt_dat);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(&phba->ct_ev_lock, flags);
|
spin_lock_irqsave(&phba->ct_ev_lock, flags);
|
||||||
lpfc_bsg_event_unref(evt);
|
lpfc_bsg_event_unref(evt);
|
||||||
|
|||||||
@@ -1823,34 +1823,15 @@ lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol,
|
|||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
char fwrev[FW_REV_STR_SIZE] = {0};
|
char fwrev[FW_REV_STR_SIZE] = {0};
|
||||||
char tmp[MAXHOSTNAMELEN] = {0};
|
|
||||||
|
|
||||||
memset(symbol, 0, size);
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "Emulex %s", vport->phba->ModelName);
|
|
||||||
if (strlcat(symbol, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
lpfc_decode_firmware_rev(vport->phba, fwrev, 0);
|
lpfc_decode_firmware_rev(vport->phba, fwrev, 0);
|
||||||
scnprintf(tmp, sizeof(tmp), " FV%s", fwrev);
|
|
||||||
if (strlcat(symbol, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), " DV%s", lpfc_release_version);
|
|
||||||
if (strlcat(symbol, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), " HN:%s", vport->phba->os_host_name);
|
|
||||||
if (strlcat(symbol, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
|
memset(symbol, 0, size);
|
||||||
/* Note :- OS name is "Linux" */
|
/* Note :- OS name is "Linux" */
|
||||||
scnprintf(tmp, sizeof(tmp), " OS:%s", init_utsname()->sysname);
|
return scnprintf(symbol, size, "Emulex %s FV%s DV%s HN:%s OS:%s",
|
||||||
strlcat(symbol, tmp, size);
|
vport->phba->ModelName, fwrev,
|
||||||
|
lpfc_release_version, vport->phba->os_host_name,
|
||||||
buffer_done:
|
init_utsname()->sysname);
|
||||||
return strnlen(symbol, size);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include <linux/idr.h>
|
#include <linux/idr.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
|
#include <linux/seq_buf.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
@@ -462,7 +463,8 @@ lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size)
|
|||||||
struct lpfc_pvt_pool *pvt_pool;
|
struct lpfc_pvt_pool *pvt_pool;
|
||||||
struct lpfc_pbl_pool *pbl_pool;
|
struct lpfc_pbl_pool *pbl_pool;
|
||||||
u32 txcmplq_cnt;
|
u32 txcmplq_cnt;
|
||||||
char tmp[LPFC_DEBUG_OUT_LINE_SZ] = {0};
|
size_t used;
|
||||||
|
struct seq_buf s;
|
||||||
|
|
||||||
if (phba->sli_rev != LPFC_SLI_REV4)
|
if (phba->sli_rev != LPFC_SLI_REV4)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -475,6 +477,9 @@ lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
used = strnlen(buf, size);
|
||||||
|
seq_buf_init(&s, buf + used, size - used);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pbl: Current number of free XRIs in public pool
|
* Pbl: Current number of free XRIs in public pool
|
||||||
* Pvt: Current number of free XRIs in private pool
|
* Pvt: Current number of free XRIs in private pool
|
||||||
@@ -484,10 +489,8 @@ lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size)
|
|||||||
* pbl_empty: Incremented by 1 when all pbl_pool are empty during
|
* pbl_empty: Incremented by 1 when all pbl_pool are empty during
|
||||||
* IO submission
|
* IO submission
|
||||||
*/
|
*/
|
||||||
scnprintf(tmp, sizeof(tmp),
|
seq_buf_printf(&s,
|
||||||
"HWQ: Pbl Pvt Busy HWM | pvt_empty pbl_empty ");
|
"HWQ: Pbl Pvt Busy HWM | pvt_empty pbl_empty ");
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
return strnlen(buf, size);
|
|
||||||
|
|
||||||
#ifdef LPFC_MXP_STAT
|
#ifdef LPFC_MXP_STAT
|
||||||
/*
|
/*
|
||||||
@@ -501,25 +504,17 @@ lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size)
|
|||||||
* othPbl_hit: Incremented by 1 if successfully get a batch of XRI from
|
* othPbl_hit: Incremented by 1 if successfully get a batch of XRI from
|
||||||
* other pbl_pool
|
* other pbl_pool
|
||||||
*/
|
*/
|
||||||
scnprintf(tmp, sizeof(tmp),
|
seq_buf_printf(&s, "MAXH above_lmt below_lmt locPbl_hit othPbl_hit");
|
||||||
"MAXH above_lmt below_lmt locPbl_hit othPbl_hit");
|
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
return strnlen(buf, size);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sPbl: snapshot of Pbl 15 sec after stat gets cleared
|
* sPbl: snapshot of Pbl 15 sec after stat gets cleared
|
||||||
* sPvt: snapshot of Pvt 15 sec after stat gets cleared
|
* sPvt: snapshot of Pvt 15 sec after stat gets cleared
|
||||||
* sBusy: snapshot of Busy 15 sec after stat gets cleared
|
* sBusy: snapshot of Busy 15 sec after stat gets cleared
|
||||||
*/
|
*/
|
||||||
scnprintf(tmp, sizeof(tmp),
|
seq_buf_printf(&s, " | sPbl sPvt sBusy");
|
||||||
" | sPbl sPvt sBusy");
|
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
return strnlen(buf, size);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "\n");
|
seq_buf_printf(&s, "\n");
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
return strnlen(buf, size);
|
|
||||||
|
|
||||||
hwq_count = phba->cfg_hdw_queue;
|
hwq_count = phba->cfg_hdw_queue;
|
||||||
for (i = 0; i < hwq_count; i++) {
|
for (i = 0; i < hwq_count; i++) {
|
||||||
@@ -531,36 +526,32 @@ lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size)
|
|||||||
pvt_pool = &multixri_pool->pvt_pool;
|
pvt_pool = &multixri_pool->pvt_pool;
|
||||||
txcmplq_cnt = qp->io_wq->pring->txcmplq_cnt;
|
txcmplq_cnt = qp->io_wq->pring->txcmplq_cnt;
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
seq_buf_printf(&s,
|
||||||
"%03d: %4d %4d %4d %4d | %10d %10d ",
|
"%03d: %4d %4d %4d %4d | %10d %10d ",
|
||||||
i, pbl_pool->count, pvt_pool->count,
|
i, pbl_pool->count, pvt_pool->count,
|
||||||
txcmplq_cnt, pvt_pool->high_watermark,
|
txcmplq_cnt, pvt_pool->high_watermark,
|
||||||
qp->empty_io_bufs, multixri_pool->pbl_empty_count);
|
qp->empty_io_bufs,
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
multixri_pool->pbl_empty_count);
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef LPFC_MXP_STAT
|
#ifdef LPFC_MXP_STAT
|
||||||
scnprintf(tmp, sizeof(tmp),
|
seq_buf_printf(&s,
|
||||||
"%4d %10d %10d %10d %10d",
|
"%4d %10d %10d %10d %10d",
|
||||||
multixri_pool->stat_max_hwm,
|
multixri_pool->stat_max_hwm,
|
||||||
multixri_pool->above_limit_count,
|
multixri_pool->above_limit_count,
|
||||||
multixri_pool->below_limit_count,
|
multixri_pool->below_limit_count,
|
||||||
multixri_pool->local_pbl_hit_count,
|
multixri_pool->local_pbl_hit_count,
|
||||||
multixri_pool->other_pbl_hit_count);
|
multixri_pool->other_pbl_hit_count);
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
break;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp),
|
seq_buf_printf(&s,
|
||||||
" | %4d %4d %5d",
|
" | %4d %4d %5d",
|
||||||
multixri_pool->stat_pbl_count,
|
multixri_pool->stat_pbl_count,
|
||||||
multixri_pool->stat_pvt_count,
|
multixri_pool->stat_pvt_count,
|
||||||
multixri_pool->stat_busy_count);
|
multixri_pool->stat_busy_count);
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "\n");
|
seq_buf_printf(&s, "\n");
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
|
if (seq_buf_has_overflowed(&s))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return strnlen(buf, size);
|
return strnlen(buf, size);
|
||||||
@@ -1261,13 +1252,14 @@ lpfc_debugfs_scsistat_data(struct lpfc_vport *vport, char *buf, int size)
|
|||||||
u64 data1, data2, data3;
|
u64 data1, data2, data3;
|
||||||
u64 tot, totin, totout;
|
u64 tot, totin, totout;
|
||||||
int i;
|
int i;
|
||||||
char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
|
struct seq_buf s;
|
||||||
|
|
||||||
if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
|
if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
|
||||||
(phba->sli_rev != LPFC_SLI_REV4))
|
(phba->sli_rev != LPFC_SLI_REV4))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
scnprintf(buf, size, "SCSI HDWQ Statistics\n");
|
seq_buf_init(&s, buf, size);
|
||||||
|
seq_buf_printf(&s, "SCSI HDWQ Statistics\n");
|
||||||
|
|
||||||
totin = 0;
|
totin = 0;
|
||||||
totout = 0;
|
totout = 0;
|
||||||
@@ -1280,21 +1272,18 @@ lpfc_debugfs_scsistat_data(struct lpfc_vport *vport, char *buf, int size)
|
|||||||
data3 = cstat->control_requests;
|
data3 = cstat->control_requests;
|
||||||
totout += (data1 + data2 + data3);
|
totout += (data1 + data2 + data3);
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx "
|
seq_buf_printf(&s, "HDWQ (%d): Rd %016llx Wr %016llx IO %016llx ",
|
||||||
"IO %016llx ", i, data1, data2, data3);
|
i, data1, data2, data3);
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n",
|
seq_buf_printf(&s, "Cmpl %016llx OutIO %016llx\n",
|
||||||
tot, ((data1 + data2 + data3) - tot));
|
tot, ((data1 + data2 + data3) - tot));
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
if (seq_buf_has_overflowed(&s))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx "
|
seq_buf_printf(&s, "Total FCP Cmpl %016llx Issue %016llx OutIO %016llx\n",
|
||||||
"OutIO %016llx\n", totin, totout, totout - totin);
|
totin, totout, totout - totin);
|
||||||
strlcat(buf, tmp, size);
|
|
||||||
|
|
||||||
buffer_done:
|
|
||||||
len = strnlen(buf, size);
|
len = strnlen(buf, size);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
@@ -1704,28 +1693,23 @@ lpfc_debugfs_hdwqstat_data(struct lpfc_vport *vport, char *buf, int size)
|
|||||||
uint32_t tot_xmt;
|
uint32_t tot_xmt;
|
||||||
uint32_t tot_rcv;
|
uint32_t tot_rcv;
|
||||||
uint32_t tot_cmpl;
|
uint32_t tot_cmpl;
|
||||||
char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
|
size_t used = strnlen(buf, size);
|
||||||
|
struct seq_buf s;
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "HDWQ Stats:\n\n");
|
seq_buf_init(&s, buf + used, size - used);
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "(NVME Accounting: %s) ",
|
seq_buf_printf(&s, "HDWQ Stats:\n\n");
|
||||||
(phba->hdwqstat_on &
|
|
||||||
(LPFC_CHECK_NVME_IO | LPFC_CHECK_NVMET_IO) ?
|
|
||||||
"Enabled" : "Disabled"));
|
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "(SCSI Accounting: %s) ",
|
seq_buf_printf(&s, "(NVME Accounting: %s) ",
|
||||||
(phba->hdwqstat_on & LPFC_CHECK_SCSI_IO ?
|
(phba->hdwqstat_on &
|
||||||
"Enabled" : "Disabled"));
|
(LPFC_CHECK_NVME_IO | LPFC_CHECK_NVMET_IO) ?
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
"Enabled" : "Disabled"));
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "\n\n");
|
seq_buf_printf(&s, "(SCSI Accounting: %s) ",
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
(phba->hdwqstat_on & LPFC_CHECK_SCSI_IO ?
|
||||||
goto buffer_done;
|
"Enabled" : "Disabled"));
|
||||||
|
|
||||||
|
seq_buf_printf(&s, "\n\n");
|
||||||
|
|
||||||
for (i = 0; i < phba->cfg_hdw_queue; i++) {
|
for (i = 0; i < phba->cfg_hdw_queue; i++) {
|
||||||
tot_rcv = 0;
|
tot_rcv = 0;
|
||||||
@@ -1744,62 +1728,50 @@ lpfc_debugfs_hdwqstat_data(struct lpfc_vport *vport, char *buf, int size)
|
|||||||
!c_stat->rcv_io)
|
!c_stat->rcv_io)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!tot_xmt && !tot_cmpl && !tot_rcv) {
|
/* Print HDWQ string only the first time */
|
||||||
/* Print HDWQ string only the first time */
|
if (!tot_xmt && !tot_cmpl && !tot_rcv)
|
||||||
scnprintf(tmp, sizeof(tmp), "[HDWQ %d]:\t", i);
|
seq_buf_printf(&s, "[HDWQ %d]:\t", i);
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
tot_xmt += c_stat->xmt_io;
|
tot_xmt += c_stat->xmt_io;
|
||||||
tot_cmpl += c_stat->cmpl_io;
|
tot_cmpl += c_stat->cmpl_io;
|
||||||
if (phba->nvmet_support)
|
if (phba->nvmet_support)
|
||||||
tot_rcv += c_stat->rcv_io;
|
tot_rcv += c_stat->rcv_io;
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "| [CPU %d]: ", j);
|
seq_buf_printf(&s, "| [CPU %d]: ", j);
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
if (phba->nvmet_support) {
|
if (phba->nvmet_support)
|
||||||
scnprintf(tmp, sizeof(tmp),
|
seq_buf_printf(&s,
|
||||||
"XMT 0x%x CMPL 0x%x RCV 0x%x |",
|
"XMT 0x%x CMPL 0x%x RCV 0x%x |",
|
||||||
c_stat->xmt_io, c_stat->cmpl_io,
|
c_stat->xmt_io, c_stat->cmpl_io,
|
||||||
c_stat->rcv_io);
|
c_stat->rcv_io);
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
else
|
||||||
goto buffer_done;
|
seq_buf_printf(&s,
|
||||||
} else {
|
"XMT 0x%x CMPL 0x%x |",
|
||||||
scnprintf(tmp, sizeof(tmp),
|
c_stat->xmt_io, c_stat->cmpl_io);
|
||||||
"XMT 0x%x CMPL 0x%x |",
|
|
||||||
c_stat->xmt_io, c_stat->cmpl_io);
|
if (seq_buf_has_overflowed(&s))
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
break;
|
||||||
goto buffer_done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (seq_buf_has_overflowed(&s))
|
||||||
|
break;
|
||||||
|
|
||||||
/* Check if nothing to display */
|
/* Check if nothing to display */
|
||||||
if (!tot_xmt && !tot_cmpl && !tot_rcv)
|
if (!tot_xmt && !tot_cmpl && !tot_rcv)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
scnprintf(tmp, sizeof(tmp), "\t->\t[HDWQ Total: ");
|
seq_buf_printf(&s, "\t->\t[HDWQ Total: ");
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
if (phba->nvmet_support) {
|
if (phba->nvmet_support)
|
||||||
scnprintf(tmp, sizeof(tmp),
|
seq_buf_printf(&s,
|
||||||
"XMT 0x%x CMPL 0x%x RCV 0x%x]\n\n",
|
"XMT 0x%x CMPL 0x%x RCV 0x%x]\n\n",
|
||||||
tot_xmt, tot_cmpl, tot_rcv);
|
tot_xmt, tot_cmpl, tot_rcv);
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
else
|
||||||
goto buffer_done;
|
seq_buf_printf(&s,
|
||||||
} else {
|
"XMT 0x%x CMPL 0x%x]\n\n",
|
||||||
scnprintf(tmp, sizeof(tmp),
|
tot_xmt, tot_cmpl);
|
||||||
"XMT 0x%x CMPL 0x%x]\n\n",
|
|
||||||
tot_xmt, tot_cmpl);
|
|
||||||
if (strlcat(buf, tmp, size) >= size)
|
|
||||||
goto buffer_done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_done:
|
|
||||||
len = strnlen(buf, size);
|
len = strnlen(buf, size);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
* included with this package. *
|
* included with this package. *
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
|
#include <linux/seq_buf.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
@@ -5103,57 +5104,37 @@ lpfc_info(struct Scsi_Host *host)
|
|||||||
struct lpfc_hba *phba = vport->phba;
|
struct lpfc_hba *phba = vport->phba;
|
||||||
int link_speed = 0;
|
int link_speed = 0;
|
||||||
static char lpfcinfobuf[384];
|
static char lpfcinfobuf[384];
|
||||||
char tmp[384] = {0};
|
struct seq_buf s;
|
||||||
|
|
||||||
memset(lpfcinfobuf, 0, sizeof(lpfcinfobuf));
|
memset(lpfcinfobuf, 0, sizeof(lpfcinfobuf));
|
||||||
|
seq_buf_init(&s, lpfcinfobuf, sizeof(lpfcinfobuf));
|
||||||
if (phba && phba->pcidev){
|
if (phba && phba->pcidev){
|
||||||
/* Model Description */
|
/* Model Description */
|
||||||
scnprintf(tmp, sizeof(tmp), phba->ModelDesc);
|
seq_buf_printf(&s, "%s", phba->ModelDesc);
|
||||||
if (strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf)) >=
|
|
||||||
sizeof(lpfcinfobuf))
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
/* PCI Info */
|
/* PCI Info */
|
||||||
scnprintf(tmp, sizeof(tmp),
|
seq_buf_printf(&s, " on PCI bus %02x device %02x irq %d",
|
||||||
" on PCI bus %02x device %02x irq %d",
|
phba->pcidev->bus->number, phba->pcidev->devfn,
|
||||||
phba->pcidev->bus->number, phba->pcidev->devfn,
|
phba->pcidev->irq);
|
||||||
phba->pcidev->irq);
|
|
||||||
if (strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf)) >=
|
|
||||||
sizeof(lpfcinfobuf))
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
/* Port Number */
|
/* Port Number */
|
||||||
if (phba->Port[0]) {
|
if (phba->Port[0])
|
||||||
scnprintf(tmp, sizeof(tmp), " port %s", phba->Port);
|
seq_buf_printf(&s, " port %s", phba->Port);
|
||||||
if (strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf)) >=
|
|
||||||
sizeof(lpfcinfobuf))
|
|
||||||
goto buffer_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Link Speed */
|
/* Link Speed */
|
||||||
link_speed = lpfc_sli_port_speed_get(phba);
|
link_speed = lpfc_sli_port_speed_get(phba);
|
||||||
if (link_speed != 0) {
|
if (link_speed != 0)
|
||||||
scnprintf(tmp, sizeof(tmp),
|
seq_buf_printf(&s, " Logical Link Speed: %d Mbps",
|
||||||
" Logical Link Speed: %d Mbps", link_speed);
|
link_speed);
|
||||||
if (strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf)) >=
|
|
||||||
sizeof(lpfcinfobuf))
|
|
||||||
goto buffer_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Support for BSG ioctls */
|
/* Support for BSG ioctls */
|
||||||
scnprintf(tmp, sizeof(tmp), " BSG");
|
seq_buf_printf(&s, " BSG");
|
||||||
if (strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf)) >=
|
|
||||||
sizeof(lpfcinfobuf))
|
|
||||||
goto buffer_done;
|
|
||||||
|
|
||||||
/* PCI resettable */
|
/* PCI resettable */
|
||||||
if (!lpfc_check_pci_resettable(phba)) {
|
if (!lpfc_check_pci_resettable(phba))
|
||||||
scnprintf(tmp, sizeof(tmp), " PCI resettable");
|
seq_buf_printf(&s, " PCI resettable");
|
||||||
strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_done:
|
|
||||||
return lpfcinfobuf;
|
return lpfcinfobuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,6 +158,3 @@ struct fcp_cmnd32 {
|
|||||||
|
|
||||||
#define TXRDY_PAYLOAD_LEN 12
|
#define TXRDY_PAYLOAD_LEN 12
|
||||||
|
|
||||||
/* For sysfs/debugfs tmp string max len */
|
|
||||||
#define LPFC_MAX_SCSI_INFO_TMP_LEN 79
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/seq_buf.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/lockdep.h>
|
#include <linux/lockdep.h>
|
||||||
#include <linux/dmi.h>
|
#include <linux/dmi.h>
|
||||||
@@ -8109,17 +8110,18 @@ u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
|
|||||||
u32 cnt = 0;
|
u32 cnt = 0;
|
||||||
char tmp[DBG_LOG_STR_SZ] = {0};
|
char tmp[DBG_LOG_STR_SZ] = {0};
|
||||||
bool log_to_kmsg = (!buf || !buf_len) ? true : false;
|
bool log_to_kmsg = (!buf || !buf_len) ? true : false;
|
||||||
|
struct seq_buf s;
|
||||||
|
|
||||||
if (!log_to_kmsg) {
|
if (!log_to_kmsg) {
|
||||||
/* clear the buffer to be sure */
|
/* clear the buffer to be sure */
|
||||||
memset(buf, 0, buf_len);
|
memset(buf, 0, buf_len);
|
||||||
|
|
||||||
scnprintf(buf, buf_len, "\t%-16s%-16s%-16s%-16s%-8s%-8s%-8s"
|
seq_buf_init(&s, buf, buf_len);
|
||||||
"%-8s%-8s%-8s%-16s\n",
|
seq_buf_printf(&s, "\t%-16s%-16s%-16s%-16s%-8s%-8s%-8s%-8s%-8s%-8s%-16s\n",
|
||||||
"MaxBPI", "Tot_Data_CMF",
|
"MaxBPI", "Tot_Data_CMF",
|
||||||
"Tot_Data_Cmd", "Tot_Data_Cmpl",
|
"Tot_Data_Cmd", "Tot_Data_Cmpl",
|
||||||
"Lat(us)", "Avg_IO", "Max_IO", "Bsy",
|
"Lat(us)", "Avg_IO", "Max_IO", "Bsy",
|
||||||
"IO_cnt", "Info", "BWutil(ms)");
|
"IO_cnt", "Info", "BWutil(ms)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Needs to be _irq because record is called from timer interrupt
|
/* Needs to be _irq because record is called from timer interrupt
|
||||||
@@ -8131,24 +8133,27 @@ u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
|
|||||||
|
|
||||||
/* Read out this entry's data. */
|
/* Read out this entry's data. */
|
||||||
if (!log_to_kmsg) {
|
if (!log_to_kmsg) {
|
||||||
/* If !log_to_kmsg, then store to buf. */
|
/*
|
||||||
|
* Drop a record whole if it does not fit, without
|
||||||
|
* consuming its ring entry.
|
||||||
|
*/
|
||||||
scnprintf(tmp, sizeof(tmp),
|
scnprintf(tmp, sizeof(tmp),
|
||||||
"%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu"
|
"%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n",
|
||||||
"%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n",
|
*head_idx,
|
||||||
*head_idx, entry->max_bytes_per_interval,
|
entry->max_bytes_per_interval,
|
||||||
entry->cmf_bytes, entry->total_bytes,
|
entry->cmf_bytes,
|
||||||
entry->rcv_bytes, entry->avg_io_latency,
|
entry->total_bytes,
|
||||||
entry->avg_io_size, entry->max_read_cnt,
|
entry->rcv_bytes,
|
||||||
|
entry->avg_io_latency,
|
||||||
|
entry->avg_io_size,
|
||||||
|
entry->max_read_cnt,
|
||||||
entry->cmf_busy, entry->io_cnt,
|
entry->cmf_busy, entry->io_cnt,
|
||||||
entry->cmf_info, entry->timer_utilization,
|
entry->cmf_info,
|
||||||
|
entry->timer_utilization,
|
||||||
entry->timer_interval);
|
entry->timer_interval);
|
||||||
|
|
||||||
/* Check for buffer overflow */
|
if (seq_buf_puts(&s, tmp) < 0)
|
||||||
if ((strlen(buf) + strlen(tmp)) >= buf_len)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Append entry's data to buffer */
|
|
||||||
strlcat(buf, tmp, buf_len);
|
|
||||||
} else {
|
} else {
|
||||||
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
|
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
|
||||||
"4410 %02u: MBPI %llu Xmit %llu "
|
"4410 %02u: MBPI %llu Xmit %llu "
|
||||||
|
|||||||
@@ -3072,7 +3072,7 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
|
|||||||
|
|
||||||
scmd_printk(KERN_INFO, scmd,
|
scmd_printk(KERN_INFO, scmd,
|
||||||
"SCSI host state: %d SCSI host busy: %d FW outstanding: %d\n",
|
"SCSI host state: %d SCSI host busy: %d FW outstanding: %d\n",
|
||||||
scmd->device->host->shost_state,
|
scsi_get_host_state(scmd->device->host),
|
||||||
scsi_host_busy(scmd->device->host),
|
scsi_host_busy(scmd->device->host),
|
||||||
atomic_read(&instance->fw_outstanding));
|
atomic_read(&instance->fw_outstanding));
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -5172,7 +5172,7 @@ static enum scsi_qc_status mpi3mr_qcmd(struct Scsi_Host *shost,
|
|||||||
|
|
||||||
/* Avoid error handling escalation when device is removed or blocked */
|
/* Avoid error handling escalation when device is removed or blocked */
|
||||||
|
|
||||||
if (scmd->device->host->shost_state == SHOST_RECOVERY &&
|
if (scsi_get_host_state(scmd->device->host) == SHOST_RECOVERY &&
|
||||||
scmd->cmnd[0] == TEST_UNIT_READY &&
|
scmd->cmnd[0] == TEST_UNIT_READY &&
|
||||||
(stgt_priv_data->dev_removed || (dev_handle == MPI3MR_INVALID_DEV_HANDLE))) {
|
(stgt_priv_data->dev_removed || (dev_handle == MPI3MR_INVALID_DEV_HANDLE))) {
|
||||||
scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07);
|
scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07);
|
||||||
|
|||||||
@@ -5870,6 +5870,8 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
|
|||||||
|
|
||||||
if (ioc->pcie_sgl_dma_pool) {
|
if (ioc->pcie_sgl_dma_pool) {
|
||||||
for (i = 0; i < ioc->scsiio_depth; i++) {
|
for (i = 0; i < ioc->scsiio_depth; i++) {
|
||||||
|
if (!ioc->pcie_sg_lookup[i].pcie_sgl)
|
||||||
|
continue;
|
||||||
dma_pool_free(ioc->pcie_sgl_dma_pool,
|
dma_pool_free(ioc->pcie_sgl_dma_pool,
|
||||||
ioc->pcie_sg_lookup[i].pcie_sgl,
|
ioc->pcie_sg_lookup[i].pcie_sgl,
|
||||||
ioc->pcie_sg_lookup[i].pcie_sgl_dma);
|
ioc->pcie_sg_lookup[i].pcie_sgl_dma);
|
||||||
|
|||||||
@@ -5472,7 +5472,7 @@ static enum scsi_qc_status scsih_qcmd(struct Scsi_Host *shost,
|
|||||||
* Avoid error handling escallation when device is disconnected
|
* Avoid error handling escallation when device is disconnected
|
||||||
*/
|
*/
|
||||||
if (handle == MPT3SAS_INVALID_DEVICE_HANDLE || sas_device_priv_data->block) {
|
if (handle == MPT3SAS_INVALID_DEVICE_HANDLE || sas_device_priv_data->block) {
|
||||||
if (scmd->device->host->shost_state == SHOST_RECOVERY &&
|
if (scsi_get_host_state(scmd->device->host) == SHOST_RECOVERY &&
|
||||||
scmd->cmnd[0] == TEST_UNIT_READY) {
|
scmd->cmnd[0] == TEST_UNIT_READY) {
|
||||||
scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07);
|
scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07);
|
||||||
scsi_done(scmd);
|
scsi_done(scmd);
|
||||||
|
|||||||
@@ -2302,7 +2302,7 @@ int qla_get_tmf(struct tmf_arg *arg)
|
|||||||
if (TMF_NOT_READY(fcport)) {
|
if (TMF_NOT_READY(fcport)) {
|
||||||
ql_log(ql_log_warn, vha, 0x802c,
|
ql_log(ql_log_warn, vha, 0x802c,
|
||||||
"Unable to acquire TM resource due to disruption.\n");
|
"Unable to acquire TM resource due to disruption.\n");
|
||||||
rc = EIO;
|
rc = -EIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ha->active_tmf < MAX_ACTIVE_TMF &&
|
if (ha->active_tmf < MAX_ACTIVE_TMF &&
|
||||||
@@ -9269,7 +9269,7 @@ static int qla29xx_process_rd_image(struct scsi_qla_host *vha,
|
|||||||
if (section == TIM) {
|
if (section == TIM) {
|
||||||
if (section_size > req->length * qla_req_entry_size(ha)) {
|
if (section_size > req->length * qla_req_entry_size(ha)) {
|
||||||
ql_log(ql_log_fatal, vha, 0x0098,
|
ql_log(ql_log_fatal, vha, 0x0098,
|
||||||
"TIM section too large (0x%x bytes, ring 0x%lx bytes).\n",
|
"TIM section too large (0x%x bytes, ring 0x%zx bytes).\n",
|
||||||
section_size,
|
section_size,
|
||||||
req->length * qla_req_entry_size(ha));
|
req->length * qla_req_entry_size(ha));
|
||||||
return QLA_FUNCTION_FAILED;
|
return QLA_FUNCTION_FAILED;
|
||||||
|
|||||||
@@ -3507,7 +3507,7 @@ qla8044_poll_flash_status_reg(struct scsi_qla_host *vha)
|
|||||||
msleep(QLA8044_FLASH_STATUS_REG_POLL_DELAY);
|
msleep(QLA8044_FLASH_STATUS_REG_POLL_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!retries)
|
if (retries == -1)
|
||||||
ret_val = QLA_FUNCTION_FAILED;
|
ret_val = QLA_FUNCTION_FAILED;
|
||||||
|
|
||||||
return ret_val;
|
return ret_val;
|
||||||
|
|||||||
@@ -9411,11 +9411,9 @@ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd)
|
|||||||
* This routine finds that if reset host is called in EH
|
* This routine finds that if reset host is called in EH
|
||||||
* scenario or from some application like sg_reset
|
* scenario or from some application like sg_reset
|
||||||
**/
|
**/
|
||||||
static int qla4xxx_is_eh_active(struct Scsi_Host *shost)
|
static bool qla4xxx_is_eh_active(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
if (shost->shost_state == SHOST_RECOVERY)
|
return scsi_get_host_state(shost) == SHOST_RECOVERY;
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1663,10 +1663,9 @@ static enum scsi_qc_status scsi_dispatch_cmd(struct scsi_cmnd *cmd)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(host->shost_state == SHOST_DEL)) {
|
if (unlikely(scsi_get_host_state(host) == SHOST_DEL)) {
|
||||||
cmd->result = (DID_NO_CONNECT << 16);
|
cmd->result = (DID_NO_CONNECT << 16);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_scsi_dispatch_cmd_start(cmd);
|
trace_scsi_dispatch_cmd_start(cmd);
|
||||||
|
|||||||
+31
-21
@@ -1169,6 +1169,7 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
|
* scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
|
||||||
|
* @shost: SCSI host pointer
|
||||||
* @starget: pointer to target device structure
|
* @starget: pointer to target device structure
|
||||||
* @lun: LUN of target device
|
* @lun: LUN of target device
|
||||||
* @bflagsp: store bflags here if not NULL
|
* @bflagsp: store bflags here if not NULL
|
||||||
@@ -1188,17 +1189,18 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
|
|||||||
* attached at the LUN
|
* attached at the LUN
|
||||||
* - SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
|
* - SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
|
||||||
**/
|
**/
|
||||||
static int scsi_probe_and_add_lun(struct scsi_target *starget,
|
static int scsi_probe_and_add_lun(struct Scsi_Host *shost,
|
||||||
|
struct scsi_target *starget,
|
||||||
u64 lun, blist_flags_t *bflagsp,
|
u64 lun, blist_flags_t *bflagsp,
|
||||||
struct scsi_device **sdevp,
|
struct scsi_device **sdevp,
|
||||||
enum scsi_scan_mode rescan,
|
enum scsi_scan_mode rescan,
|
||||||
void *hostdata)
|
void *hostdata)
|
||||||
|
__must_hold(&shost->scan_mutex)
|
||||||
{
|
{
|
||||||
struct scsi_device *sdev;
|
struct scsi_device *sdev;
|
||||||
unsigned char *result;
|
unsigned char *result;
|
||||||
blist_flags_t bflags;
|
blist_flags_t bflags;
|
||||||
int res = SCSI_SCAN_NO_RESPONSE, result_len = 256;
|
int res = SCSI_SCAN_NO_RESPONSE, result_len = 256;
|
||||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The rescan flag is used as an optimization, the first scan of a
|
* The rescan flag is used as an optimization, the first scan of a
|
||||||
@@ -1334,6 +1336,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* scsi_sequential_lun_scan - sequentially scan a SCSI target
|
* scsi_sequential_lun_scan - sequentially scan a SCSI target
|
||||||
|
* @shost: SCSI host pointer
|
||||||
* @starget: pointer to target structure to scan
|
* @starget: pointer to target structure to scan
|
||||||
* @bflags: black/white list flag for LUN 0
|
* @bflags: black/white list flag for LUN 0
|
||||||
* @scsi_level: Which version of the standard does this device adhere to
|
* @scsi_level: Which version of the standard does this device adhere to
|
||||||
@@ -1346,13 +1349,14 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
|
|||||||
*
|
*
|
||||||
* Modifies sdevscan->lun.
|
* Modifies sdevscan->lun.
|
||||||
**/
|
**/
|
||||||
static void scsi_sequential_lun_scan(struct scsi_target *starget,
|
static void scsi_sequential_lun_scan(struct Scsi_Host *shost,
|
||||||
|
struct scsi_target *starget,
|
||||||
blist_flags_t bflags, int scsi_level,
|
blist_flags_t bflags, int scsi_level,
|
||||||
enum scsi_scan_mode rescan)
|
enum scsi_scan_mode rescan)
|
||||||
|
__must_hold(&shost->scan_mutex)
|
||||||
{
|
{
|
||||||
uint max_dev_lun;
|
uint max_dev_lun;
|
||||||
u64 sparse_lun, lun;
|
u64 sparse_lun, lun;
|
||||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
|
||||||
|
|
||||||
SCSI_LOG_SCAN_BUS(3, starget_printk(KERN_INFO, starget,
|
SCSI_LOG_SCAN_BUS(3, starget_printk(KERN_INFO, starget,
|
||||||
"scsi scan: Sequential scan\n"));
|
"scsi scan: Sequential scan\n"));
|
||||||
@@ -1412,14 +1416,15 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
|
|||||||
* sparse_lun.
|
* sparse_lun.
|
||||||
*/
|
*/
|
||||||
for (lun = 1; lun < max_dev_lun; ++lun)
|
for (lun = 1; lun < max_dev_lun; ++lun)
|
||||||
if ((scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan,
|
if (scsi_probe_and_add_lun(shost, starget, lun, NULL, NULL,
|
||||||
NULL) != SCSI_SCAN_LUN_PRESENT) &&
|
rescan, NULL) != SCSI_SCAN_LUN_PRESENT &&
|
||||||
!sparse_lun)
|
!sparse_lun)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* scsi_report_lun_scan - Scan using SCSI REPORT LUN results
|
* scsi_report_lun_scan - Scan using SCSI REPORT LUN results
|
||||||
|
* @shost: SCSI host pointer
|
||||||
* @starget: which target
|
* @starget: which target
|
||||||
* @bflags: Zero or a mix of BLIST_NOLUN, BLIST_REPORTLUN2, or BLIST_NOREPORTLUN
|
* @bflags: Zero or a mix of BLIST_NOLUN, BLIST_REPORTLUN2, or BLIST_NOREPORTLUN
|
||||||
* @rescan: nonzero if we can skip code only needed on first scan
|
* @rescan: nonzero if we can skip code only needed on first scan
|
||||||
@@ -1438,8 +1443,10 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
|
|||||||
* 0: scan completed (or no memory, so further scanning is futile)
|
* 0: scan completed (or no memory, so further scanning is futile)
|
||||||
* 1: could not scan with REPORT LUN
|
* 1: could not scan with REPORT LUN
|
||||||
**/
|
**/
|
||||||
static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflags,
|
static int scsi_report_lun_scan(struct Scsi_Host *shost,
|
||||||
enum scsi_scan_mode rescan)
|
struct scsi_target *starget, blist_flags_t bflags,
|
||||||
|
enum scsi_scan_mode rescan)
|
||||||
|
__must_hold(&shost->scan_mutex)
|
||||||
{
|
{
|
||||||
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
|
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
@@ -1448,7 +1455,6 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
|
|||||||
int result;
|
int result;
|
||||||
struct scsi_lun *lunp, *lun_data;
|
struct scsi_lun *lunp, *lun_data;
|
||||||
struct scsi_device *sdev;
|
struct scsi_device *sdev;
|
||||||
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
|
|
||||||
struct scsi_failure failure_defs[] = {
|
struct scsi_failure failure_defs[] = {
|
||||||
{
|
{
|
||||||
.sense = UNIT_ATTENTION,
|
.sense = UNIT_ATTENTION,
|
||||||
@@ -1594,7 +1600,7 @@ retry:
|
|||||||
} else {
|
} else {
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
res = scsi_probe_and_add_lun(starget,
|
res = scsi_probe_and_add_lun(shost, starget,
|
||||||
lun, NULL, NULL, rescan, NULL);
|
lun, NULL, NULL, rescan, NULL);
|
||||||
if (res == SCSI_SCAN_NO_RESPONSE) {
|
if (res == SCSI_SCAN_NO_RESPONSE) {
|
||||||
/*
|
/*
|
||||||
@@ -1641,7 +1647,7 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
|
|||||||
scsi_complete_async_scans();
|
scsi_complete_async_scans();
|
||||||
|
|
||||||
if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
|
if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
|
||||||
scsi_probe_and_add_lun(starget, lun, NULL, &sdev,
|
scsi_probe_and_add_lun(shost, starget, lun, NULL, &sdev,
|
||||||
SCSI_SCAN_RESCAN, hostdata);
|
SCSI_SCAN_RESCAN, hostdata);
|
||||||
scsi_autopm_put_host(shost);
|
scsi_autopm_put_host(shost);
|
||||||
}
|
}
|
||||||
@@ -1763,10 +1769,11 @@ unlock:
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(scsi_rescan_device);
|
EXPORT_SYMBOL(scsi_rescan_device);
|
||||||
|
|
||||||
static void __scsi_scan_target(struct device *parent, unsigned int channel,
|
static void __scsi_scan_target(struct Scsi_Host *shost, struct device *parent,
|
||||||
unsigned int id, u64 lun, enum scsi_scan_mode rescan)
|
unsigned int channel, unsigned int id, u64 lun,
|
||||||
|
enum scsi_scan_mode rescan)
|
||||||
|
__must_hold(&shost->scan_mutex)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = dev_to_shost(parent);
|
|
||||||
blist_flags_t bflags = 0;
|
blist_flags_t bflags = 0;
|
||||||
int res;
|
int res;
|
||||||
struct scsi_target *starget;
|
struct scsi_target *starget;
|
||||||
@@ -1786,7 +1793,8 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
|
|||||||
/*
|
/*
|
||||||
* Scan for a specific host/chan/id/lun.
|
* Scan for a specific host/chan/id/lun.
|
||||||
*/
|
*/
|
||||||
scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan, NULL);
|
scsi_probe_and_add_lun(shost, starget, lun, NULL, NULL, rescan,
|
||||||
|
NULL);
|
||||||
goto out_reap;
|
goto out_reap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1794,14 +1802,15 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
|
|||||||
* Scan LUN 0, if there is some response, scan further. Ideally, we
|
* Scan LUN 0, if there is some response, scan further. Ideally, we
|
||||||
* would not configure LUN 0 until all LUNs are scanned.
|
* would not configure LUN 0 until all LUNs are scanned.
|
||||||
*/
|
*/
|
||||||
res = scsi_probe_and_add_lun(starget, 0, &bflags, NULL, rescan, NULL);
|
res = scsi_probe_and_add_lun(shost, starget, 0, &bflags, NULL, rescan,
|
||||||
|
NULL);
|
||||||
if (res == SCSI_SCAN_LUN_PRESENT || res == SCSI_SCAN_TARGET_PRESENT) {
|
if (res == SCSI_SCAN_LUN_PRESENT || res == SCSI_SCAN_TARGET_PRESENT) {
|
||||||
if (scsi_report_lun_scan(starget, bflags, rescan) != 0)
|
if (scsi_report_lun_scan(shost, starget, bflags, rescan) != 0)
|
||||||
/*
|
/*
|
||||||
* The REPORT LUN did not scan the target,
|
* The REPORT LUN did not scan the target,
|
||||||
* do a sequential scan.
|
* do a sequential scan.
|
||||||
*/
|
*/
|
||||||
scsi_sequential_lun_scan(starget, bflags,
|
scsi_sequential_lun_scan(shost, starget, bflags,
|
||||||
starget->scsi_level, rescan);
|
starget->scsi_level, rescan);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1851,7 +1860,7 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
|
|||||||
scsi_complete_async_scans();
|
scsi_complete_async_scans();
|
||||||
|
|
||||||
if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
|
if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
|
||||||
__scsi_scan_target(parent, channel, id, lun, rescan);
|
__scsi_scan_target(shost, parent, channel, id, lun, rescan);
|
||||||
scsi_autopm_put_host(shost);
|
scsi_autopm_put_host(shost);
|
||||||
}
|
}
|
||||||
mutex_unlock(&shost->scan_mutex);
|
mutex_unlock(&shost->scan_mutex);
|
||||||
@@ -1861,6 +1870,7 @@ EXPORT_SYMBOL(scsi_scan_target);
|
|||||||
static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
|
static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
|
||||||
unsigned int id, u64 lun,
|
unsigned int id, u64 lun,
|
||||||
enum scsi_scan_mode rescan)
|
enum scsi_scan_mode rescan)
|
||||||
|
__must_hold(&shost->scan_mutex)
|
||||||
{
|
{
|
||||||
uint order_id;
|
uint order_id;
|
||||||
|
|
||||||
@@ -1882,11 +1892,11 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
|
|||||||
order_id = shost->max_id - id - 1;
|
order_id = shost->max_id - id - 1;
|
||||||
else
|
else
|
||||||
order_id = id;
|
order_id = id;
|
||||||
__scsi_scan_target(&shost->shost_gendev, channel,
|
__scsi_scan_target(shost, &shost->shost_gendev, channel,
|
||||||
order_id, lun, rescan);
|
order_id, lun, rescan);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
__scsi_scan_target(&shost->shost_gendev, channel,
|
__scsi_scan_target(shost, &shost->shost_gendev, channel,
|
||||||
id, lun, rescan);
|
id, lun, rescan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -214,8 +214,9 @@ store_shost_state(struct device *dev, struct device_attribute *attr,
|
|||||||
if (!state)
|
if (!state)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (scsi_host_set_state(shost, state))
|
scoped_guard(spinlock_irq, shost->host_lock)
|
||||||
return -EINVAL;
|
if (scsi_host_set_state(shost, state))
|
||||||
|
return -EINVAL;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,7 +224,7 @@ static ssize_t
|
|||||||
show_shost_state(struct device *dev, struct device_attribute *attr, char *buf)
|
show_shost_state(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct Scsi_Host *shost = class_to_shost(dev);
|
struct Scsi_Host *shost = class_to_shost(dev);
|
||||||
const char *name = scsi_host_state_name(shost->shost_state);
|
const char *name = scsi_host_state_name(scsi_get_host_state(shost));
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|||||||
@@ -305,6 +305,7 @@ snic_add_host(struct Scsi_Host *shost, struct pci_dev *pdev)
|
|||||||
if (!shost->work_q) {
|
if (!shost->work_q) {
|
||||||
SNIC_HOST_ERR(shost, "Failed to Create ScsiHost wq.\n");
|
SNIC_HOST_ERR(shost, "Failed to Create ScsiHost wq.\n");
|
||||||
|
|
||||||
|
scsi_remove_host(shost);
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
CONTEXT_ANALYSIS := y
|
||||||
|
|
||||||
obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o
|
obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o
|
||||||
ufshcd-core-y += ufshcd.o ufs-sysfs.o ufs-mcq.o ufs-txeq.o
|
ufshcd-core-y += ufshcd.o ufs-sysfs.o ufs-mcq.o ufs-txeq.o
|
||||||
ufshcd-core-$(CONFIG_RPMB) += ufs-rpmb.o
|
ufshcd-core-$(CONFIG_RPMB) += ufs-rpmb.o
|
||||||
|
|||||||
@@ -65,8 +65,10 @@ static int ee_usr_mask_get(void *data, u64 *val)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
token_context_lock(ufs_debugfs);
|
||||||
|
|
||||||
static int ufs_debugfs_get_user_access(struct ufs_hba *hba)
|
static int ufs_debugfs_get_user_access(struct ufs_hba *hba)
|
||||||
__acquires(&hba->host_sem)
|
__cond_acquires(0, ufs_debugfs)
|
||||||
{
|
{
|
||||||
down(&hba->host_sem);
|
down(&hba->host_sem);
|
||||||
if (!ufshcd_is_user_access_allowed(hba)) {
|
if (!ufshcd_is_user_access_allowed(hba)) {
|
||||||
@@ -74,14 +76,16 @@ __acquires(&hba->host_sem)
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
ufshcd_rpm_get_sync(hba);
|
ufshcd_rpm_get_sync(hba);
|
||||||
|
__acquire(ufs_debugfs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ufs_debugfs_put_user_access(struct ufs_hba *hba)
|
static void ufs_debugfs_put_user_access(struct ufs_hba *hba)
|
||||||
__releases(&hba->host_sem)
|
__releases(ufs_debugfs)
|
||||||
{
|
{
|
||||||
ufshcd_rpm_put_sync(hba);
|
ufshcd_rpm_put_sync(hba);
|
||||||
up(&hba->host_sem);
|
up(&hba->host_sem);
|
||||||
|
__release(ufs_debugfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ee_usr_mask_set(void *data, u64 val)
|
static int ee_usr_mask_set(void *data, u64 val)
|
||||||
|
|||||||
@@ -1317,6 +1317,7 @@ static int ufshcd_wait_for_pending_cmds(struct ufs_hba *hba,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__set_current_state(TASK_UNINTERRUPTIBLE);
|
||||||
io_schedule_timeout(msecs_to_jiffies(20));
|
io_schedule_timeout(msecs_to_jiffies(20));
|
||||||
if (ktime_to_us(ktime_sub(ktime_get(), start)) >
|
if (ktime_to_us(ktime_sub(ktime_get(), start)) >
|
||||||
wait_timeout_us) {
|
wait_timeout_us) {
|
||||||
@@ -1353,6 +1354,8 @@ out:
|
|||||||
* On failure, all acquired locks are released and the tagset is unquiesced.
|
* On failure, all acquired locks are released and the tagset is unquiesced.
|
||||||
*/
|
*/
|
||||||
int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us)
|
int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us)
|
||||||
|
__cond_acquires(0, &hba->host->scan_mutex)
|
||||||
|
__cond_acquires(0, &hba->clk_scaling_lock)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -1377,6 +1380,8 @@ int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us)
|
|||||||
* This function resumes command submissions.
|
* This function resumes command submissions.
|
||||||
*/
|
*/
|
||||||
void ufshcd_resume_command_processing(struct ufs_hba *hba)
|
void ufshcd_resume_command_processing(struct ufs_hba *hba)
|
||||||
|
__releases(&hba->clk_scaling_lock)
|
||||||
|
__releases(&hba->host->scan_mutex)
|
||||||
{
|
{
|
||||||
up_write(&hba->clk_scaling_lock);
|
up_write(&hba->clk_scaling_lock);
|
||||||
blk_mq_unquiesce_tagset(&hba->host->tag_set);
|
blk_mq_unquiesce_tagset(&hba->host->tag_set);
|
||||||
@@ -1446,6 +1451,9 @@ config_pwr_mode:
|
|||||||
* Return: 0 upon success; -EBUSY upon timeout.
|
* Return: 0 upon success; -EBUSY upon timeout.
|
||||||
*/
|
*/
|
||||||
static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us)
|
static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us)
|
||||||
|
__cond_acquires(0, &hba->host->scan_mutex)
|
||||||
|
__cond_acquires(0, &hba->wb_mutex)
|
||||||
|
__cond_acquires(0, &hba->clk_scaling_lock)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
/*
|
/*
|
||||||
@@ -1475,6 +1483,9 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err)
|
static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err)
|
||||||
|
__releases(&hba->clk_scaling_lock)
|
||||||
|
__releases(&hba->wb_mutex)
|
||||||
|
__releases(&hba->host->scan_mutex)
|
||||||
{
|
{
|
||||||
up_write(&hba->clk_scaling_lock);
|
up_write(&hba->clk_scaling_lock);
|
||||||
mutex_unlock(&hba->wb_mutex);
|
mutex_unlock(&hba->wb_mutex);
|
||||||
@@ -3304,6 +3315,8 @@ ufshcd_dev_cmd_completion(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ufshcd_dev_man_lock(struct ufs_hba *hba)
|
static void ufshcd_dev_man_lock(struct ufs_hba *hba)
|
||||||
|
__acquires(&hba->dev_cmd.lock)
|
||||||
|
__acquires_shared(&hba->clk_scaling_lock)
|
||||||
{
|
{
|
||||||
ufshcd_hold(hba);
|
ufshcd_hold(hba);
|
||||||
mutex_lock(&hba->dev_cmd.lock);
|
mutex_lock(&hba->dev_cmd.lock);
|
||||||
@@ -3311,6 +3324,8 @@ static void ufshcd_dev_man_lock(struct ufs_hba *hba)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ufshcd_dev_man_unlock(struct ufs_hba *hba)
|
static void ufshcd_dev_man_unlock(struct ufs_hba *hba)
|
||||||
|
__releases_shared(&hba->clk_scaling_lock)
|
||||||
|
__releases(&hba->dev_cmd.lock)
|
||||||
{
|
{
|
||||||
up_read(&hba->clk_scaling_lock);
|
up_read(&hba->clk_scaling_lock);
|
||||||
mutex_unlock(&hba->dev_cmd.lock);
|
mutex_unlock(&hba->dev_cmd.lock);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
CONTEXT_ANALYSIS := y
|
||||||
|
|
||||||
obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o
|
obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o
|
||||||
obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o
|
obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o
|
||||||
obj-$(CONFIG_SCSI_UFS_CDNS_PLATFORM) += cdns-pltfrm.o
|
obj-$(CONFIG_SCSI_UFS_CDNS_PLATFORM) += cdns-pltfrm.o
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#ifndef _SCSI_SCSI_HOST_H
|
#ifndef _SCSI_SCSI_HOST_H
|
||||||
#define _SCSI_SCSI_HOST_H
|
#define _SCSI_SCSI_HOST_H
|
||||||
|
|
||||||
|
#include <linux/cleanup.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
@@ -727,7 +728,7 @@ struct Scsi_Host {
|
|||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
|
|
||||||
|
|
||||||
enum scsi_host_state shost_state;
|
enum scsi_host_state shost_state __guarded_by(host_lock);
|
||||||
|
|
||||||
/* ldm bits */
|
/* ldm bits */
|
||||||
struct device shost_gendev, shost_dev;
|
struct device shost_gendev, shost_dev;
|
||||||
@@ -788,11 +789,18 @@ static inline struct Scsi_Host *dev_to_shost(struct device *dev)
|
|||||||
return container_of(dev, struct Scsi_Host, shost_gendev);
|
return container_of(dev, struct Scsi_Host, shost_gendev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline enum scsi_host_state scsi_get_host_state(struct Scsi_Host *shost)
|
||||||
|
{
|
||||||
|
return context_unsafe(READ_ONCE(shost->shost_state));
|
||||||
|
}
|
||||||
|
|
||||||
static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
|
static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
return shost->shost_state == SHOST_RECOVERY ||
|
enum scsi_host_state state = scsi_get_host_state(shost);
|
||||||
shost->shost_state == SHOST_CANCEL_RECOVERY ||
|
|
||||||
shost->shost_state == SHOST_DEL_RECOVERY ||
|
return state == SHOST_RECOVERY ||
|
||||||
|
state == SHOST_CANCEL_RECOVERY ||
|
||||||
|
state == SHOST_DEL_RECOVERY ||
|
||||||
shost->tmf_in_progress;
|
shost->tmf_in_progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,8 +846,9 @@ static inline struct device *scsi_get_device(struct Scsi_Host *shost)
|
|||||||
**/
|
**/
|
||||||
static inline int scsi_host_scan_allowed(struct Scsi_Host *shost)
|
static inline int scsi_host_scan_allowed(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
return shost->shost_state == SHOST_RUNNING ||
|
enum scsi_host_state state = scsi_get_host_state(shost);
|
||||||
shost->shost_state == SHOST_RECOVERY;
|
|
||||||
|
return state == SHOST_RUNNING || state == SHOST_RECOVERY;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void scsi_unblock_requests(struct Scsi_Host *);
|
extern void scsi_unblock_requests(struct Scsi_Host *);
|
||||||
@@ -943,6 +952,7 @@ static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost)
|
|||||||
return shost->prot_guard_type;
|
return shost->prot_guard_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int scsi_host_set_state(struct Scsi_Host *, enum scsi_host_state);
|
int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
|
||||||
|
__must_hold(shost->host_lock);
|
||||||
|
|
||||||
#endif /* _SCSI_SCSI_HOST_H */
|
#endif /* _SCSI_SCSI_HOST_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user