mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 14:04:27 -04: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:
3
.mailmap
3
.mailmap
@@ -577,6 +577,9 @@ Mark Brown <broonie@sirena.org.uk>
|
||||
Mark Starovoytov <mstarovo@pm.me> <mstarovoitov@marvell.com>
|
||||
Markus Schneider-Pargmann <msp@baylibre.com> <mpa@pengutronix.de>
|
||||
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>
|
||||
Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.intel.com> <martyna.szapar-mudlaw@intel.com>
|
||||
Mathieu Othacehe <othacehe@gnu.org> <m.othacehe@gmail.com>
|
||||
|
||||
@@ -22,6 +22,7 @@ Supported devices
|
||||
|
||||
Features
|
||||
========
|
||||
|
||||
- PCIe Gen4 x8 host interface
|
||||
- Support for SAS and SATA devices
|
||||
- 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/class/scsi_disk/host:bus:target:lun/device/ncq_cmd_prio_enable
|
||||
/sys/block/<disk>/device/sas_device_handle
|
||||
/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
|
||||
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
|
||||
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
|
||||
==========================
|
||||
@@ -100,6 +105,7 @@ in io_uring poll mode. The default value is 0.
|
||||
|
||||
File Location
|
||||
=============
|
||||
|
||||
The driver source is located at:
|
||||
|
||||
``drivers/scsi/leapraid/``
|
||||
|
||||
@@ -18776,8 +18776,6 @@ L: linux-scsi@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/scsi/g_NCR5380.rst
|
||||
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/dmx3191d.c
|
||||
F: drivers/scsi/g_NCR5380.*
|
||||
@@ -24571,7 +24569,7 @@ F: include/scsi/sg.h
|
||||
|
||||
SCSI SUBSYSTEM
|
||||
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
|
||||
S: Maintained
|
||||
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
|
||||
|
||||
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: target-devel@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
@@ -14,6 +14,29 @@
|
||||
# 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
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#
|
||||
# SCSI Device Handler
|
||||
#
|
||||
|
||||
CONTEXT_ANALYSIS := y
|
||||
|
||||
obj-$(CONFIG_SCSI_DH_RDAC) += scsi_dh_rdac.o
|
||||
obj-$(CONFIG_SCSI_DH_HP_SW) += scsi_dh_hp_sw.o
|
||||
obj-$(CONFIG_SCSI_DH_EMC) += scsi_dh_emc.o
|
||||
|
||||
@@ -73,8 +73,9 @@ static struct class shost_class = {
|
||||
* transition is illegal.
|
||||
**/
|
||||
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)
|
||||
return 0;
|
||||
@@ -145,7 +146,7 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
|
||||
}
|
||||
break;
|
||||
}
|
||||
shost->shost_state = state;
|
||||
WRITE_ONCE(shost->shost_state, state);
|
||||
return 0;
|
||||
|
||||
illegal:
|
||||
@@ -276,7 +277,8 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
|
||||
if (error)
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
struct Scsi_Host *shost = dev_to_shost(dev);
|
||||
enum scsi_host_state state = scsi_get_host_state(shost);
|
||||
struct device *parent = dev->parent;
|
||||
|
||||
/* 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)
|
||||
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
|
||||
* 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);
|
||||
|
||||
if (shost->shost_state != SHOST_CREATED)
|
||||
if (state != SHOST_CREATED)
|
||||
put_device(parent);
|
||||
kfree(shost);
|
||||
}
|
||||
@@ -412,8 +415,8 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
|
||||
return NULL;
|
||||
|
||||
shost->host_lock = &shost->default_lock;
|
||||
spin_lock_init(shost->host_lock);
|
||||
shost->shost_state = SHOST_CREATED;
|
||||
scoped_guard(spinlock_init, shost->host_lock)
|
||||
shost->shost_state = SHOST_CREATED;
|
||||
INIT_LIST_HEAD(&shost->__devices);
|
||||
INIT_LIST_HEAD(&shost->__targets);
|
||||
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)
|
||||
{
|
||||
if ((shost->shost_state == SHOST_DEL) ||
|
||||
if (scsi_get_host_state(shost) == SHOST_DEL ||
|
||||
!get_device(&shost->shost_gendev))
|
||||
return NULL;
|
||||
return shost;
|
||||
|
||||
@@ -6151,7 +6151,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
|
||||
timer_delete_sync(&tgt->timer);
|
||||
kref_put(&tgt->kref, ibmvfc_release_tgt);
|
||||
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");
|
||||
nvme_rport = tgt->nvme_remote_port;
|
||||
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;
|
||||
}
|
||||
|
||||
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 Scsi_Host *shost;
|
||||
@@ -184,6 +185,8 @@ static struct leapraid_adapter *leapraid_ctl_lookup_adapter(int adapter_id)
|
||||
shost = adapter->shost;
|
||||
if (!shost || !scsi_host_get(shost))
|
||||
break;
|
||||
if (track_mmap)
|
||||
atomic_inc(&adapter->fw_log_desc.mmap_refcnt);
|
||||
spin_unlock(&leapraid_adapter_lock);
|
||||
return adapter;
|
||||
}
|
||||
@@ -589,7 +592,7 @@ static int leapraid_ctl_ioctl_main(struct file *file, unsigned int cmd,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
adapter = leapraid_ctl_lookup_adapter(ioctl_header.adapter_id);
|
||||
adapter = leapraid_ctl_lookup_adapter(ioctl_header.adapter_id, false);
|
||||
if (!adapter)
|
||||
return -EFAULT;
|
||||
|
||||
@@ -697,6 +700,7 @@ static void leapraid_fw_mmap_open(struct vm_area_struct *vma)
|
||||
if (!adapter)
|
||||
return;
|
||||
|
||||
get_device(&adapter->shost->shost_gendev);
|
||||
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;
|
||||
|
||||
adapter = leapraid_ctl_lookup_adapter(adapter_id);
|
||||
adapter = leapraid_ctl_lookup_adapter(adapter_id, true);
|
||||
if (!adapter) {
|
||||
pr_err("%s: No adapter found!\n", __func__);
|
||||
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_ops = &leapraid_fw_mmap_vm_ops;
|
||||
leapraid_fw_mmap_open(vma);
|
||||
adapter = NULL;
|
||||
|
||||
rc = 0;
|
||||
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);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ static noinline bool leapraid_shost_in_recovery(struct Scsi_Host *shost)
|
||||
{
|
||||
enum scsi_host_state state;
|
||||
|
||||
state = READ_ONCE(shost->shost_state);
|
||||
state = scsi_get_host_state(shost);
|
||||
return state == SHOST_RECOVERY ||
|
||||
state == SHOST_CANCEL_RECOVERY ||
|
||||
state == SHOST_DEL_RECOVERY ||
|
||||
|
||||
@@ -1064,7 +1064,7 @@ struct leapraid_starget_priv {
|
||||
* @starget_priv: Associated target private data.
|
||||
* @lun: Logical Unit Number.
|
||||
* @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.
|
||||
* @deleted: Deletion flag.
|
||||
* @sep: SEP flag.
|
||||
@@ -1073,7 +1073,7 @@ struct leapraid_sdev_priv {
|
||||
struct leapraid_starget_priv *starget_priv;
|
||||
unsigned int lun;
|
||||
u32 flg;
|
||||
u8 ncq_cmd_prio_enable;
|
||||
u8 ncq_prio_enable;
|
||||
u8 block;
|
||||
u8 deleted;
|
||||
u8 sep;
|
||||
|
||||
@@ -808,7 +808,7 @@ static bool leapraid_should_queuecommand(struct leapraid_adapter *adapter,
|
||||
goto no_connect;
|
||||
|
||||
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) {
|
||||
scsi_build_sense(scmd, 0, UNIT_ATTENTION,
|
||||
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;
|
||||
|
||||
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_CLASS_RT))
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
char *buf)
|
||||
{
|
||||
@@ -1867,19 +1876,16 @@ static ssize_t ncq_cmd_prio_enable_show(struct device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return sysfs_emit(buf, "%d\n",
|
||||
sas_device_priv_data->ncq_cmd_prio_enable);
|
||||
return sysfs_emit(buf, "%d\n", sas_device_priv_data->ncq_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,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
struct leapraid_sdev_priv *sas_device_priv_data = sdev->hostdata;
|
||||
struct scsi_vpd *vpd_pg89;
|
||||
int ncq_cmd_prio_enable;
|
||||
bool ncq_supported;
|
||||
bool enable;
|
||||
|
||||
if (!sas_device_priv_data) {
|
||||
dev_err(&sdev->sdev_gendev,
|
||||
@@ -1887,44 +1893,63 @@ static ssize_t ncq_cmd_prio_enable_store(struct device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (kstrtoint(buf, 0, &ncq_cmd_prio_enable))
|
||||
if (kstrtobool(buf, &enable))
|
||||
return -EINVAL;
|
||||
|
||||
if (ncq_cmd_prio_enable != 0 && ncq_cmd_prio_enable != 1) {
|
||||
dev_err(&sdev->sdev_gendev,
|
||||
"%s: Invalid NCQ cmd prio %d (0/1 only)\n",
|
||||
__func__, ncq_cmd_prio_enable);
|
||||
if (!sas_ata_ncq_prio_supported(sdev))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
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;
|
||||
sas_device_priv_data->ncq_prio_enable = enable;
|
||||
return count;
|
||||
}
|
||||
|
||||
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[] = {
|
||||
&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,
|
||||
};
|
||||
|
||||
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 = {
|
||||
.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);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
/* Return the domain device attached to an expander phy */
|
||||
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 domain_device *dev;
|
||||
struct sas_rphy *rphy;
|
||||
|
||||
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)
|
||||
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))
|
||||
return dev;
|
||||
@@ -1958,6 +1963,72 @@ static bool dev_type_flutter(enum sas_device_type new, enum sas_device_type old)
|
||||
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,
|
||||
bool last, int sibling)
|
||||
{
|
||||
@@ -2011,27 +2082,16 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
|
||||
if (res == 0)
|
||||
sas_set_ex_phy(dev, phy_id, disc_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 */
|
||||
pr_info("ex %016llx phy%02d replace %016llx\n",
|
||||
SAS_ADDR(dev->sas_addr), phy_id,
|
||||
SAS_ADDR(phy->attached_sas_addr));
|
||||
sas_unregister_devs_sas_addr(dev, phy_id, last);
|
||||
|
||||
res = sas_discover_new(dev, phy_id);
|
||||
sas_rediscover_ex_phy(dev, phy_id, last);
|
||||
out_free_resp:
|
||||
kfree(disc_resp);
|
||||
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);
|
||||
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);
|
||||
int sas_ex_phy_discover(struct domain_device *dev, int single);
|
||||
int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
#define LPFC_MIN_DEVLOSS_TMO 1
|
||||
#define LPFC_MAX_DEVLOSS_TMO 255
|
||||
|
||||
#define LPFC_MAX_INFO_TMP_LEN 100
|
||||
#define LPFC_INFO_MORE_STR "\nCould be more info...\n"
|
||||
/*
|
||||
* 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 cpu;
|
||||
u64 rcv, total;
|
||||
char tmp[LPFC_MAX_INFO_TMP_LEN] = {0};
|
||||
|
||||
if (phba->cgn_i)
|
||||
cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"Congestion Mgmt Info: E2Eattr %d Ver %d "
|
||||
"CMF %d cnt %d\n",
|
||||
phba->sli4_hba.pc_sli4_params.mi_cap,
|
||||
cp ? cp->cgn_info_version : 0,
|
||||
phba->sli4_hba.pc_sli4_params.cmf, phba->cmf_timer_cnt);
|
||||
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len = strnlen(buf, PAGE_SIZE);
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Congestion Mgmt Info: E2Eattr %d Ver %d CMF %d cnt %d\n",
|
||||
phba->sli4_hba.pc_sli4_params.mi_cap,
|
||||
cp ? cp->cgn_info_version : 0,
|
||||
phba->sli4_hba.pc_sli4_params.cmf,
|
||||
phba->cmf_timer_cnt);
|
||||
|
||||
if (!phba->sli4_hba.pc_sli4_params.cmf)
|
||||
goto buffer_done;
|
||||
|
||||
switch (phba->cgn_init_reg_signal) {
|
||||
case EDC_CG_SIG_WARN_ONLY:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"Register: Init: Signal:WARN ");
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Register: Init: Signal:WARN ");
|
||||
break;
|
||||
case EDC_CG_SIG_WARN_ALARM:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"Register: Init: Signal:WARN|ALARM ");
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Register: Init: Signal:WARN|ALARM ");
|
||||
break;
|
||||
default:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"Register: Init: Signal:NONE ");
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Register: Init: Signal:NONE ");
|
||||
break;
|
||||
}
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
|
||||
switch (phba->cgn_init_reg_fpin) {
|
||||
case LPFC_CGN_FPIN_WARN:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FPIN:WARN\n");
|
||||
len += sysfs_emit_at(buf, len, "FPIN:WARN\n");
|
||||
break;
|
||||
case LPFC_CGN_FPIN_ALARM:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FPIN:ALARM\n");
|
||||
len += sysfs_emit_at(buf, len, "FPIN:ALARM\n");
|
||||
break;
|
||||
case LPFC_CGN_FPIN_BOTH:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FPIN:WARN|ALARM\n");
|
||||
len += sysfs_emit_at(buf, len, "FPIN:WARN|ALARM\n");
|
||||
break;
|
||||
default:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FPIN:NONE\n");
|
||||
len += sysfs_emit_at(buf, len, "FPIN:NONE\n");
|
||||
break;
|
||||
}
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
|
||||
switch (phba->cgn_reg_signal) {
|
||||
case EDC_CG_SIG_WARN_ONLY:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
" Current: Signal:WARN ");
|
||||
len += sysfs_emit_at(buf, len,
|
||||
" Current: Signal:WARN ");
|
||||
break;
|
||||
case EDC_CG_SIG_WARN_ALARM:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
" Current: Signal:WARN|ALARM ");
|
||||
len += sysfs_emit_at(buf, len,
|
||||
" Current: Signal:WARN|ALARM ");
|
||||
break;
|
||||
default:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
" Current: Signal:NONE ");
|
||||
len += sysfs_emit_at(buf, len,
|
||||
" Current: Signal:NONE ");
|
||||
break;
|
||||
}
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
|
||||
switch (phba->cgn_reg_fpin) {
|
||||
case LPFC_CGN_FPIN_WARN:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FPIN:WARN ACQEcnt:%d\n", phba->cgn_acqe_cnt);
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"FPIN:WARN ACQEcnt:%d\n",
|
||||
phba->cgn_acqe_cnt);
|
||||
break;
|
||||
case LPFC_CGN_FPIN_ALARM:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FPIN:ALARM ACQEcnt:%d\n", phba->cgn_acqe_cnt);
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"FPIN:ALARM ACQEcnt:%d\n",
|
||||
phba->cgn_acqe_cnt);
|
||||
break;
|
||||
case LPFC_CGN_FPIN_BOTH:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FPIN:WARN|ALARM ACQEcnt:%d\n", phba->cgn_acqe_cnt);
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"FPIN:WARN|ALARM ACQEcnt:%d\n",
|
||||
phba->cgn_acqe_cnt);
|
||||
break;
|
||||
default:
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FPIN:NONE ACQEcnt:%d\n", phba->cgn_acqe_cnt);
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"FPIN:NONE ACQEcnt:%d\n",
|
||||
phba->cgn_acqe_cnt);
|
||||
break;
|
||||
}
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
|
||||
if (phba->cmf_active_mode != phba->cgn_p.cgn_param_mode) {
|
||||
switch (phba->cmf_active_mode) {
|
||||
case LPFC_CFG_OFF:
|
||||
scnprintf(tmp, sizeof(tmp), "Active: Mode:Off\n");
|
||||
len += sysfs_emit_at(buf, len, "Active: Mode:Off\n");
|
||||
break;
|
||||
case LPFC_CFG_MANAGED:
|
||||
scnprintf(tmp, sizeof(tmp), "Active: Mode:Managed\n");
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Active: Mode:Managed\n");
|
||||
break;
|
||||
case LPFC_CFG_MONITOR:
|
||||
scnprintf(tmp, sizeof(tmp), "Active: Mode:Monitor\n");
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Active: Mode:Monitor\n");
|
||||
break;
|
||||
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) {
|
||||
case LPFC_CFG_OFF:
|
||||
scnprintf(tmp, sizeof(tmp), "Config: Mode:Off ");
|
||||
len += sysfs_emit_at(buf, len, "Config: Mode:Off ");
|
||||
break;
|
||||
case LPFC_CFG_MANAGED:
|
||||
scnprintf(tmp, sizeof(tmp), "Config: Mode:Managed ");
|
||||
len += sysfs_emit_at(buf, len, "Config: Mode:Managed ");
|
||||
break;
|
||||
case LPFC_CFG_MONITOR:
|
||||
scnprintf(tmp, sizeof(tmp), "Config: Mode:Monitor ");
|
||||
len += sysfs_emit_at(buf, len, "Config: Mode:Monitor ");
|
||||
break;
|
||||
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;
|
||||
rcv = 0;
|
||||
@@ -262,24 +249,18 @@ lpfc_cmf_info_show(struct device *dev, struct device_attribute *attr,
|
||||
rcv += atomic64_read(&cgs->rcv_bytes);
|
||||
}
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"IObusy:%d Info:%d Bytes: Rcv:x%llx Total:x%llx\n",
|
||||
atomic_read(&phba->cmf_busy),
|
||||
phba->cmf_active_info, rcv, total);
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"IObusy:%d Info:%d Bytes: Rcv:x%llx Total:x%llx\n",
|
||||
atomic_read(&phba->cmf_busy),
|
||||
phba->cmf_active_info, rcv, total);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"Port_speed:%d Link_byte_cnt:%ld "
|
||||
"Max_byte_per_interval:%ld\n",
|
||||
lpfc_sli_port_speed_get(phba),
|
||||
(unsigned long)phba->cmf_link_byte_count,
|
||||
(unsigned long)phba->cmf_max_bytes_per_interval);
|
||||
strlcat(buf, tmp, PAGE_SIZE);
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Port_speed:%d Link_byte_cnt:%ld Max_byte_per_interval:%ld\n",
|
||||
lpfc_sli_port_speed_get(phba),
|
||||
(unsigned long)phba->cmf_link_byte_count,
|
||||
(unsigned long)phba->cmf_max_bytes_per_interval);
|
||||
|
||||
buffer_done:
|
||||
len = strnlen(buf, PAGE_SIZE);
|
||||
|
||||
if (unlikely(len >= (PAGE_SIZE - 1))) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
|
||||
"6312 Catching potential buffer "
|
||||
@@ -480,17 +461,19 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
|
||||
char *statep;
|
||||
int i;
|
||||
int len = 0;
|
||||
char tmp[LPFC_MAX_INFO_TMP_LEN] = {0};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
len = strnlen(buf, PAGE_SIZE);
|
||||
|
||||
if (phba->nvmet_support) {
|
||||
if (!phba->targetport) {
|
||||
len = scnprintf(buf, PAGE_SIZE,
|
||||
"NVME Target: x%llx is not allocated\n",
|
||||
wwn_to_u64(vport->fc_portname.u.wwn));
|
||||
len = sysfs_emit(buf,
|
||||
"NVME Target: x%llx is not allocated\n",
|
||||
wwn_to_u64(vport->fc_portname.u.wwn));
|
||||
return len;
|
||||
}
|
||||
/* 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";
|
||||
else
|
||||
statep = "INIT";
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"NVME Target Enabled State %s\n",
|
||||
statep);
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"NVME Target Enabled State %s\n",
|
||||
statep);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"%s%d WWPN x%llx WWNN x%llx DID x%06x\n",
|
||||
"NVME Target: lpfc",
|
||||
phba->brd_no,
|
||||
wwn_to_u64(vport->fc_portname.u.wwn),
|
||||
wwn_to_u64(vport->fc_nodename.u.wwn),
|
||||
phba->targetport->port_id);
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"%s%d WWPN x%llx WWNN x%llx DID x%06x\n",
|
||||
"NVME Target: lpfc",
|
||||
phba->brd_no,
|
||||
wwn_to_u64(vport->fc_portname.u.wwn),
|
||||
wwn_to_u64(vport->fc_nodename.u.wwn),
|
||||
phba->targetport->port_id);
|
||||
|
||||
if (strlcat(buf, "\nNVME Target: Statistics\n", PAGE_SIZE)
|
||||
>= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len, "\nNVME Target: Statistics\n");
|
||||
|
||||
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"LS: Rcv %08x Drop %08x Abort %08x\n",
|
||||
atomic_read(&tgtp->rcv_ls_req_in),
|
||||
atomic_read(&tgtp->rcv_ls_req_drop),
|
||||
atomic_read(&tgtp->xmt_ls_abort));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"LS: Rcv %08x Drop %08x Abort %08x\n",
|
||||
atomic_read(&tgtp->rcv_ls_req_in),
|
||||
atomic_read(&tgtp->rcv_ls_req_drop),
|
||||
atomic_read(&tgtp->xmt_ls_abort));
|
||||
|
||||
if (atomic_read(&tgtp->rcv_ls_req_in) !=
|
||||
atomic_read(&tgtp->rcv_ls_req_out)) {
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"Rcv LS: in %08x != out %08x\n",
|
||||
atomic_read(&tgtp->rcv_ls_req_in),
|
||||
atomic_read(&tgtp->rcv_ls_req_out));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Rcv LS: in %08x != out %08x\n",
|
||||
atomic_read(&tgtp->rcv_ls_req_in),
|
||||
atomic_read(&tgtp->rcv_ls_req_out));
|
||||
}
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"LS: Xmt %08x Drop %08x Cmpl %08x\n",
|
||||
atomic_read(&tgtp->xmt_ls_rsp),
|
||||
atomic_read(&tgtp->xmt_ls_drop),
|
||||
atomic_read(&tgtp->xmt_ls_rsp_cmpl));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"LS: Xmt %08x Drop %08x Cmpl %08x\n",
|
||||
atomic_read(&tgtp->xmt_ls_rsp),
|
||||
atomic_read(&tgtp->xmt_ls_drop),
|
||||
atomic_read(&tgtp->xmt_ls_rsp_cmpl));
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"LS: RSP Abort %08x xb %08x Err %08x\n",
|
||||
atomic_read(&tgtp->xmt_ls_rsp_aborted),
|
||||
atomic_read(&tgtp->xmt_ls_rsp_xb_set),
|
||||
atomic_read(&tgtp->xmt_ls_rsp_error));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"LS: RSP Abort %08x xb %08x Err %08x\n",
|
||||
atomic_read(&tgtp->xmt_ls_rsp_aborted),
|
||||
atomic_read(&tgtp->xmt_ls_rsp_xb_set),
|
||||
atomic_read(&tgtp->xmt_ls_rsp_error));
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FCP: Rcv %08x Defer %08x Release %08x "
|
||||
"Drop %08x\n",
|
||||
atomic_read(&tgtp->rcv_fcp_cmd_in),
|
||||
atomic_read(&tgtp->rcv_fcp_cmd_defer),
|
||||
atomic_read(&tgtp->xmt_fcp_release),
|
||||
atomic_read(&tgtp->rcv_fcp_cmd_drop));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"FCP: Rcv %08x Defer %08x Release %08x Drop %08x\n",
|
||||
atomic_read(&tgtp->rcv_fcp_cmd_in),
|
||||
atomic_read(&tgtp->rcv_fcp_cmd_defer),
|
||||
atomic_read(&tgtp->xmt_fcp_release),
|
||||
atomic_read(&tgtp->rcv_fcp_cmd_drop));
|
||||
|
||||
if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
|
||||
atomic_read(&tgtp->rcv_fcp_cmd_out)) {
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"Rcv FCP: in %08x != out %08x\n",
|
||||
atomic_read(&tgtp->rcv_fcp_cmd_in),
|
||||
atomic_read(&tgtp->rcv_fcp_cmd_out));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Rcv FCP: in %08x != out %08x\n",
|
||||
atomic_read(&tgtp->rcv_fcp_cmd_in),
|
||||
atomic_read(&tgtp->rcv_fcp_cmd_out));
|
||||
}
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x "
|
||||
"drop %08x\n",
|
||||
atomic_read(&tgtp->xmt_fcp_read),
|
||||
atomic_read(&tgtp->xmt_fcp_read_rsp),
|
||||
atomic_read(&tgtp->xmt_fcp_write),
|
||||
atomic_read(&tgtp->xmt_fcp_rsp),
|
||||
atomic_read(&tgtp->xmt_fcp_drop));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x drop %08x\n",
|
||||
atomic_read(&tgtp->xmt_fcp_read),
|
||||
atomic_read(&tgtp->xmt_fcp_read_rsp),
|
||||
atomic_read(&tgtp->xmt_fcp_write),
|
||||
atomic_read(&tgtp->xmt_fcp_rsp),
|
||||
atomic_read(&tgtp->xmt_fcp_drop));
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FCP Rsp Cmpl: %08x err %08x drop %08x\n",
|
||||
atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
|
||||
atomic_read(&tgtp->xmt_fcp_rsp_error),
|
||||
atomic_read(&tgtp->xmt_fcp_rsp_drop));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"FCP Rsp Cmpl: %08x err %08x drop %08x\n",
|
||||
atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
|
||||
atomic_read(&tgtp->xmt_fcp_rsp_error),
|
||||
atomic_read(&tgtp->xmt_fcp_rsp_drop));
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
|
||||
atomic_read(&tgtp->xmt_fcp_rsp_aborted),
|
||||
atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
|
||||
atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
|
||||
atomic_read(&tgtp->xmt_fcp_rsp_aborted),
|
||||
atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
|
||||
atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"ABORT: Xmt %08x Cmpl %08x\n",
|
||||
atomic_read(&tgtp->xmt_fcp_abort),
|
||||
atomic_read(&tgtp->xmt_fcp_abort_cmpl));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"ABORT: Xmt %08x Cmpl %08x\n",
|
||||
atomic_read(&tgtp->xmt_fcp_abort),
|
||||
atomic_read(&tgtp->xmt_fcp_abort_cmpl));
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x\n",
|
||||
atomic_read(&tgtp->xmt_abort_sol),
|
||||
atomic_read(&tgtp->xmt_abort_unsol),
|
||||
atomic_read(&tgtp->xmt_abort_rsp),
|
||||
atomic_read(&tgtp->xmt_abort_rsp_error));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x\n",
|
||||
atomic_read(&tgtp->xmt_abort_sol),
|
||||
atomic_read(&tgtp->xmt_abort_unsol),
|
||||
atomic_read(&tgtp->xmt_abort_rsp),
|
||||
atomic_read(&tgtp->xmt_abort_rsp_error));
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"DELAY: ctx %08x fod %08x wqfull %08x\n",
|
||||
atomic_read(&tgtp->defer_ctx),
|
||||
atomic_read(&tgtp->defer_fod),
|
||||
atomic_read(&tgtp->defer_wqfull));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"DELAY: ctx %08x fod %08x wqfull %08x\n",
|
||||
atomic_read(&tgtp->defer_ctx),
|
||||
atomic_read(&tgtp->defer_fod),
|
||||
atomic_read(&tgtp->defer_wqfull));
|
||||
|
||||
/* Calculate outstanding IOs */
|
||||
tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
|
||||
tot += atomic_read(&tgtp->xmt_fcp_release);
|
||||
tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot;
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"IO_CTX: %08x WAIT: cur %08x tot %08x\n"
|
||||
"CTX Outstanding %08llx\n\n",
|
||||
phba->sli4_hba.nvmet_xri_cnt,
|
||||
phba->sli4_hba.nvmet_io_wait_cnt,
|
||||
phba->sli4_hba.nvmet_io_wait_total,
|
||||
tot);
|
||||
strlcat(buf, tmp, PAGE_SIZE);
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"IO_CTX: %08x WAIT: cur %08x tot %08x\n"
|
||||
"CTX Outstanding %08llx\n\n",
|
||||
phba->sli4_hba.nvmet_xri_cnt,
|
||||
phba->sli4_hba.nvmet_io_wait_cnt,
|
||||
phba->sli4_hba.nvmet_io_wait_total,
|
||||
tot);
|
||||
goto buffer_done;
|
||||
}
|
||||
|
||||
localport = vport->localport;
|
||||
if (!localport) {
|
||||
len = scnprintf(buf, PAGE_SIZE,
|
||||
"NVME Initiator x%llx is not allocated\n",
|
||||
wwn_to_u64(vport->fc_portname.u.wwn));
|
||||
len = sysfs_emit(buf,
|
||||
"NVME Initiator x%llx is not allocated\n",
|
||||
wwn_to_u64(vport->fc_portname.u.wwn));
|
||||
return len;
|
||||
}
|
||||
lport = (struct lpfc_nvme_lport *)localport->private;
|
||||
if (strlcat(buf, "\nNVME Initiator Enabled\n", PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len, "\nNVME Initiator Enabled\n");
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"XRI Dist lpfc%d Total %d IO %d ELS %d\n",
|
||||
phba->brd_no,
|
||||
phba->sli4_hba.max_cfg_param.max_xri,
|
||||
phba->sli4_hba.io_xri_max,
|
||||
lpfc_sli4_get_els_iocb_cnt(phba));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"XRI Dist lpfc%d Total %d IO %d ELS %d\n",
|
||||
phba->brd_no,
|
||||
phba->sli4_hba.max_cfg_param.max_xri,
|
||||
phba->sli4_hba.io_xri_max,
|
||||
lpfc_sli4_get_els_iocb_cnt(phba));
|
||||
|
||||
/* Port state is only one of two values for now. */
|
||||
if (localport->port_id)
|
||||
@@ -666,15 +613,13 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
|
||||
else
|
||||
statep = "UNKNOWN ";
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"%s%d WWPN x%llx WWNN x%llx DID x%06x %s\n",
|
||||
"NVME LPORT lpfc",
|
||||
phba->brd_no,
|
||||
wwn_to_u64(vport->fc_portname.u.wwn),
|
||||
wwn_to_u64(vport->fc_nodename.u.wwn),
|
||||
localport->port_id, statep);
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"%s%d WWPN x%llx WWNN x%llx DID x%06x %s\n",
|
||||
"NVME LPORT lpfc",
|
||||
phba->brd_no,
|
||||
wwn_to_u64(vport->fc_portname.u.wwn),
|
||||
wwn_to_u64(vport->fc_nodename.u.wwn),
|
||||
localport->port_id, statep);
|
||||
|
||||
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. */
|
||||
if (strlcat(buf, "NVME RPORT ", PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto unlock_buf_done;
|
||||
if (phba->brd_no >= 10) {
|
||||
if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto unlock_buf_done;
|
||||
}
|
||||
len += sysfs_emit_at(buf, len, "NVME RPORT ");
|
||||
if (phba->brd_no >= 10)
|
||||
len += sysfs_emit_at(buf, len, " ");
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "WWPN x%llx ",
|
||||
nrport->port_name);
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto unlock_buf_done;
|
||||
len += sysfs_emit_at(buf, len, "WWPN x%llx ",
|
||||
nrport->port_name);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "WWNN x%llx ",
|
||||
nrport->node_name);
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto unlock_buf_done;
|
||||
len += sysfs_emit_at(buf, len, "WWNN x%llx ",
|
||||
nrport->node_name);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "DID x%06x ",
|
||||
nrport->port_id);
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto unlock_buf_done;
|
||||
len += sysfs_emit_at(buf, len, "DID x%06x ",
|
||||
nrport->port_id);
|
||||
|
||||
/* An NVME rport can have multiple roles. */
|
||||
if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) {
|
||||
if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto unlock_buf_done;
|
||||
}
|
||||
if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) {
|
||||
if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE)
|
||||
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)
|
||||
len += sysfs_emit_at(buf, len, "INITIATOR ");
|
||||
if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET)
|
||||
len += sysfs_emit_at(buf, len, "TARGET ");
|
||||
if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY)
|
||||
len += sysfs_emit_at(buf, len, "DISCSRVC ");
|
||||
if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
|
||||
FC_PORT_ROLE_NVME_TARGET |
|
||||
FC_PORT_ROLE_NVME_DISCOVERY)) {
|
||||
scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x",
|
||||
nrport->port_role);
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto unlock_buf_done;
|
||||
}
|
||||
FC_PORT_ROLE_NVME_DISCOVERY))
|
||||
len += sysfs_emit_at(buf, len, "UNKNOWN ROLE x%x",
|
||||
nrport->port_role);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "%s\n", statep);
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto unlock_buf_done;
|
||||
len += sysfs_emit_at(buf, len, "%s\n", statep);
|
||||
|
||||
if (len >= PAGE_SIZE - 1)
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&vport->fc_nodes_list_lock, iflags);
|
||||
|
||||
if (!lport)
|
||||
goto buffer_done;
|
||||
|
||||
if (strlcat(buf, "\nNVME Statistics\n", PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len, "\nNVME Statistics\n");
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"LS: Xmt %010x Cmpl %010x Abort %08x\n",
|
||||
atomic_read(&lport->fc4NvmeLsRequests),
|
||||
atomic_read(&lport->fc4NvmeLsCmpls),
|
||||
atomic_read(&lport->xmt_ls_abort));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"LS: Xmt %010x Cmpl %010x Abort %08x\n",
|
||||
atomic_read(&lport->fc4NvmeLsRequests),
|
||||
atomic_read(&lport->fc4NvmeLsCmpls),
|
||||
atomic_read(&lport->xmt_ls_abort));
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"LS XMIT: Err %08x CMPL: xb %08x Err %08x\n",
|
||||
atomic_read(&lport->xmt_ls_err),
|
||||
atomic_read(&lport->cmpl_ls_xb),
|
||||
atomic_read(&lport->cmpl_ls_err));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"LS XMIT: Err %08x CMPL: xb %08x Err %08x\n",
|
||||
atomic_read(&lport->xmt_ls_err),
|
||||
atomic_read(&lport->cmpl_ls_xb),
|
||||
atomic_read(&lport->cmpl_ls_err));
|
||||
|
||||
totin = 0;
|
||||
totout = 0;
|
||||
@@ -785,40 +708,25 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
|
||||
data3 = cstat->control_requests;
|
||||
totout += (data1 + data2 + data3);
|
||||
}
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"Total FCP Cmpl %016llx Issue %016llx "
|
||||
"OutIO %016llx\n",
|
||||
totin, totout, totout - totin);
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Total FCP Cmpl %016llx Issue %016llx OutIO %016llx\n",
|
||||
totin, totout, totout - totin);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"\tabort %08x noxri %08x nondlp %08x qdepth %08x "
|
||||
"wqerr %08x err %08x\n",
|
||||
atomic_read(&lport->xmt_fcp_abort),
|
||||
atomic_read(&lport->xmt_fcp_noxri),
|
||||
atomic_read(&lport->xmt_fcp_bad_ndlp),
|
||||
atomic_read(&lport->xmt_fcp_qdepth),
|
||||
atomic_read(&lport->xmt_fcp_wqerr),
|
||||
atomic_read(&lport->xmt_fcp_err));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"\tabort %08x noxri %08x nondlp %08x qdepth %08x wqerr %08x err %08x\n",
|
||||
atomic_read(&lport->xmt_fcp_abort),
|
||||
atomic_read(&lport->xmt_fcp_noxri),
|
||||
atomic_read(&lport->xmt_fcp_bad_ndlp),
|
||||
atomic_read(&lport->xmt_fcp_qdepth),
|
||||
atomic_read(&lport->xmt_fcp_wqerr),
|
||||
atomic_read(&lport->xmt_fcp_err));
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"FCP CMPL: xb %08x Err %08x\n",
|
||||
atomic_read(&lport->cmpl_fcp_xb),
|
||||
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);
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"FCP CMPL: xb %08x Err %08x\n",
|
||||
atomic_read(&lport->cmpl_fcp_xb),
|
||||
atomic_read(&lport->cmpl_fcp_err));
|
||||
|
||||
buffer_done:
|
||||
len = strnlen(buf, PAGE_SIZE);
|
||||
|
||||
if (unlikely(len >= (PAGE_SIZE - 1))) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_NVME,
|
||||
"6314 Catching potential buffer "
|
||||
@@ -844,13 +752,12 @@ lpfc_scsi_stat_show(struct device *dev, struct device_attribute *attr,
|
||||
u64 data1, data2, data3;
|
||||
u64 tot, totin, totout;
|
||||
int i;
|
||||
char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
|
||||
|
||||
if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
|
||||
(phba->sli_rev != LPFC_SLI_REV4))
|
||||
return 0;
|
||||
|
||||
scnprintf(buf, PAGE_SIZE, "SCSI HDWQ Statistics\n");
|
||||
len = sysfs_emit(buf, "SCSI HDWQ Statistics\n");
|
||||
|
||||
totin = 0;
|
||||
totout = 0;
|
||||
@@ -863,22 +770,20 @@ lpfc_scsi_stat_show(struct device *dev, struct device_attribute *attr,
|
||||
data3 = cstat->control_requests;
|
||||
totout += (data1 + data2 + data3);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx "
|
||||
"IO %016llx ", i, data1, data2, data3);
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"HDWQ (%d): Rd %016llx Wr %016llx IO %016llx ",
|
||||
i, data1, data2, data3);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n",
|
||||
tot, ((data1 + data2 + data3) - tot));
|
||||
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
|
||||
goto buffer_done;
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Cmpl %016llx OutIO %016llx\n",
|
||||
tot, ((data1 + data2 + data3) - tot));
|
||||
|
||||
if (len >= PAGE_SIZE - 1)
|
||||
break;
|
||||
}
|
||||
scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx "
|
||||
"OutIO %016llx\n", totin, totout, totout - totin);
|
||||
strlcat(buf, tmp, PAGE_SIZE);
|
||||
|
||||
buffer_done:
|
||||
len = strnlen(buf, PAGE_SIZE);
|
||||
len += sysfs_emit_at(buf, len,
|
||||
"Total FCP Cmpl %016llx Issue %016llx OutIO %016llx\n",
|
||||
totin, totout, totout - totin);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -1329,10 +1329,8 @@ lpfc_bsg_hba_get_event(struct bsg_job *job)
|
||||
else
|
||||
bsg_reply->reply_payload_rcv_len = 0;
|
||||
|
||||
if (evt_dat) {
|
||||
kfree(evt_dat->data);
|
||||
kfree(evt_dat);
|
||||
}
|
||||
kfree(evt_dat->data);
|
||||
kfree(evt_dat);
|
||||
|
||||
spin_lock_irqsave(&phba->ct_ev_lock, flags);
|
||||
lpfc_bsg_event_unref(evt);
|
||||
|
||||
@@ -1823,34 +1823,15 @@ lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol,
|
||||
size_t size)
|
||||
{
|
||||
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);
|
||||
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" */
|
||||
scnprintf(tmp, sizeof(tmp), " OS:%s", init_utsname()->sysname);
|
||||
strlcat(symbol, tmp, size);
|
||||
|
||||
buffer_done:
|
||||
return strnlen(symbol, size);
|
||||
|
||||
return scnprintf(symbol, size, "Emulex %s FV%s DV%s HN:%s OS:%s",
|
||||
vport->phba->ModelName, fwrev,
|
||||
lpfc_release_version, vport->phba->os_host_name,
|
||||
init_utsname()->sysname);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <linux/idr.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/seq_buf.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pci.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_pbl_pool *pbl_pool;
|
||||
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)
|
||||
return 0;
|
||||
@@ -475,6 +477,9 @@ lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size)
|
||||
return i;
|
||||
}
|
||||
|
||||
used = strnlen(buf, size);
|
||||
seq_buf_init(&s, buf + used, size - used);
|
||||
|
||||
/*
|
||||
* Pbl: Current number of free XRIs in public 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
|
||||
* IO submission
|
||||
*/
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"HWQ: Pbl Pvt Busy HWM | pvt_empty pbl_empty ");
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
return strnlen(buf, size);
|
||||
seq_buf_printf(&s,
|
||||
"HWQ: Pbl Pvt Busy HWM | pvt_empty pbl_empty ");
|
||||
|
||||
#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
|
||||
* other pbl_pool
|
||||
*/
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"MAXH above_lmt below_lmt locPbl_hit othPbl_hit");
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
return strnlen(buf, size);
|
||||
seq_buf_printf(&s, "MAXH above_lmt below_lmt locPbl_hit othPbl_hit");
|
||||
|
||||
/*
|
||||
* sPbl: snapshot of Pbl 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
|
||||
*/
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
" | sPbl sPvt sBusy");
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
return strnlen(buf, size);
|
||||
seq_buf_printf(&s, " | sPbl sPvt sBusy");
|
||||
#endif
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "\n");
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
return strnlen(buf, size);
|
||||
seq_buf_printf(&s, "\n");
|
||||
|
||||
hwq_count = phba->cfg_hdw_queue;
|
||||
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;
|
||||
txcmplq_cnt = qp->io_wq->pring->txcmplq_cnt;
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"%03d: %4d %4d %4d %4d | %10d %10d ",
|
||||
i, pbl_pool->count, pvt_pool->count,
|
||||
txcmplq_cnt, pvt_pool->high_watermark,
|
||||
qp->empty_io_bufs, multixri_pool->pbl_empty_count);
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
break;
|
||||
seq_buf_printf(&s,
|
||||
"%03d: %4d %4d %4d %4d | %10d %10d ",
|
||||
i, pbl_pool->count, pvt_pool->count,
|
||||
txcmplq_cnt, pvt_pool->high_watermark,
|
||||
qp->empty_io_bufs,
|
||||
multixri_pool->pbl_empty_count);
|
||||
|
||||
#ifdef LPFC_MXP_STAT
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"%4d %10d %10d %10d %10d",
|
||||
multixri_pool->stat_max_hwm,
|
||||
multixri_pool->above_limit_count,
|
||||
multixri_pool->below_limit_count,
|
||||
multixri_pool->local_pbl_hit_count,
|
||||
multixri_pool->other_pbl_hit_count);
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
break;
|
||||
seq_buf_printf(&s,
|
||||
"%4d %10d %10d %10d %10d",
|
||||
multixri_pool->stat_max_hwm,
|
||||
multixri_pool->above_limit_count,
|
||||
multixri_pool->below_limit_count,
|
||||
multixri_pool->local_pbl_hit_count,
|
||||
multixri_pool->other_pbl_hit_count);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
" | %4d %4d %5d",
|
||||
multixri_pool->stat_pbl_count,
|
||||
multixri_pool->stat_pvt_count,
|
||||
multixri_pool->stat_busy_count);
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
break;
|
||||
seq_buf_printf(&s,
|
||||
" | %4d %4d %5d",
|
||||
multixri_pool->stat_pbl_count,
|
||||
multixri_pool->stat_pvt_count,
|
||||
multixri_pool->stat_busy_count);
|
||||
#endif
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "\n");
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
seq_buf_printf(&s, "\n");
|
||||
|
||||
if (seq_buf_has_overflowed(&s))
|
||||
break;
|
||||
}
|
||||
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 tot, totin, totout;
|
||||
int i;
|
||||
char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
|
||||
struct seq_buf s;
|
||||
|
||||
if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
|
||||
(phba->sli_rev != LPFC_SLI_REV4))
|
||||
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;
|
||||
totout = 0;
|
||||
@@ -1280,21 +1272,18 @@ lpfc_debugfs_scsistat_data(struct lpfc_vport *vport, char *buf, int size)
|
||||
data3 = cstat->control_requests;
|
||||
totout += (data1 + data2 + data3);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx "
|
||||
"IO %016llx ", i, data1, data2, data3);
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
seq_buf_printf(&s, "HDWQ (%d): Rd %016llx Wr %016llx IO %016llx ",
|
||||
i, data1, data2, data3);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n",
|
||||
tot, ((data1 + data2 + data3) - tot));
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
seq_buf_printf(&s, "Cmpl %016llx OutIO %016llx\n",
|
||||
tot, ((data1 + data2 + data3) - tot));
|
||||
|
||||
if (seq_buf_has_overflowed(&s))
|
||||
break;
|
||||
}
|
||||
scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx "
|
||||
"OutIO %016llx\n", totin, totout, totout - totin);
|
||||
strlcat(buf, tmp, size);
|
||||
seq_buf_printf(&s, "Total FCP Cmpl %016llx Issue %016llx OutIO %016llx\n",
|
||||
totin, totout, totout - totin);
|
||||
|
||||
buffer_done:
|
||||
len = strnlen(buf, size);
|
||||
|
||||
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_rcv;
|
||||
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");
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
seq_buf_init(&s, buf + used, size - used);
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "(NVME Accounting: %s) ",
|
||||
(phba->hdwqstat_on &
|
||||
(LPFC_CHECK_NVME_IO | LPFC_CHECK_NVMET_IO) ?
|
||||
"Enabled" : "Disabled"));
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
seq_buf_printf(&s, "HDWQ Stats:\n\n");
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "(SCSI Accounting: %s) ",
|
||||
(phba->hdwqstat_on & LPFC_CHECK_SCSI_IO ?
|
||||
"Enabled" : "Disabled"));
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
seq_buf_printf(&s, "(NVME Accounting: %s) ",
|
||||
(phba->hdwqstat_on &
|
||||
(LPFC_CHECK_NVME_IO | LPFC_CHECK_NVMET_IO) ?
|
||||
"Enabled" : "Disabled"));
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "\n\n");
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
seq_buf_printf(&s, "(SCSI Accounting: %s) ",
|
||||
(phba->hdwqstat_on & LPFC_CHECK_SCSI_IO ?
|
||||
"Enabled" : "Disabled"));
|
||||
|
||||
seq_buf_printf(&s, "\n\n");
|
||||
|
||||
for (i = 0; i < phba->cfg_hdw_queue; i++) {
|
||||
tot_rcv = 0;
|
||||
@@ -1744,62 +1728,50 @@ lpfc_debugfs_hdwqstat_data(struct lpfc_vport *vport, char *buf, int size)
|
||||
!c_stat->rcv_io)
|
||||
continue;
|
||||
|
||||
if (!tot_xmt && !tot_cmpl && !tot_rcv) {
|
||||
/* Print HDWQ string only the first time */
|
||||
scnprintf(tmp, sizeof(tmp), "[HDWQ %d]:\t", i);
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
}
|
||||
/* Print HDWQ string only the first time */
|
||||
if (!tot_xmt && !tot_cmpl && !tot_rcv)
|
||||
seq_buf_printf(&s, "[HDWQ %d]:\t", i);
|
||||
|
||||
tot_xmt += c_stat->xmt_io;
|
||||
tot_cmpl += c_stat->cmpl_io;
|
||||
if (phba->nvmet_support)
|
||||
tot_rcv += c_stat->rcv_io;
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "| [CPU %d]: ", j);
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
seq_buf_printf(&s, "| [CPU %d]: ", j);
|
||||
|
||||
if (phba->nvmet_support) {
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"XMT 0x%x CMPL 0x%x RCV 0x%x |",
|
||||
c_stat->xmt_io, c_stat->cmpl_io,
|
||||
c_stat->rcv_io);
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
} else {
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"XMT 0x%x CMPL 0x%x |",
|
||||
c_stat->xmt_io, c_stat->cmpl_io);
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
}
|
||||
if (phba->nvmet_support)
|
||||
seq_buf_printf(&s,
|
||||
"XMT 0x%x CMPL 0x%x RCV 0x%x |",
|
||||
c_stat->xmt_io, c_stat->cmpl_io,
|
||||
c_stat->rcv_io);
|
||||
else
|
||||
seq_buf_printf(&s,
|
||||
"XMT 0x%x CMPL 0x%x |",
|
||||
c_stat->xmt_io, c_stat->cmpl_io);
|
||||
|
||||
if (seq_buf_has_overflowed(&s))
|
||||
break;
|
||||
}
|
||||
|
||||
if (seq_buf_has_overflowed(&s))
|
||||
break;
|
||||
|
||||
/* Check if nothing to display */
|
||||
if (!tot_xmt && !tot_cmpl && !tot_rcv)
|
||||
continue;
|
||||
|
||||
scnprintf(tmp, sizeof(tmp), "\t->\t[HDWQ Total: ");
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
seq_buf_printf(&s, "\t->\t[HDWQ Total: ");
|
||||
|
||||
if (phba->nvmet_support) {
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"XMT 0x%x CMPL 0x%x RCV 0x%x]\n\n",
|
||||
tot_xmt, tot_cmpl, tot_rcv);
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
} else {
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
"XMT 0x%x CMPL 0x%x]\n\n",
|
||||
tot_xmt, tot_cmpl);
|
||||
if (strlcat(buf, tmp, size) >= size)
|
||||
goto buffer_done;
|
||||
}
|
||||
if (phba->nvmet_support)
|
||||
seq_buf_printf(&s,
|
||||
"XMT 0x%x CMPL 0x%x RCV 0x%x]\n\n",
|
||||
tot_xmt, tot_cmpl, tot_rcv);
|
||||
else
|
||||
seq_buf_printf(&s,
|
||||
"XMT 0x%x CMPL 0x%x]\n\n",
|
||||
tot_xmt, tot_cmpl);
|
||||
}
|
||||
|
||||
buffer_done:
|
||||
len = strnlen(buf, size);
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
* included with this package. *
|
||||
*******************************************************************/
|
||||
#include <linux/pci.h>
|
||||
#include <linux/seq_buf.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/export.h>
|
||||
@@ -5103,57 +5104,37 @@ lpfc_info(struct Scsi_Host *host)
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
int link_speed = 0;
|
||||
static char lpfcinfobuf[384];
|
||||
char tmp[384] = {0};
|
||||
struct seq_buf s;
|
||||
|
||||
memset(lpfcinfobuf, 0, sizeof(lpfcinfobuf));
|
||||
seq_buf_init(&s, lpfcinfobuf, sizeof(lpfcinfobuf));
|
||||
if (phba && phba->pcidev){
|
||||
/* Model Description */
|
||||
scnprintf(tmp, sizeof(tmp), phba->ModelDesc);
|
||||
if (strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf)) >=
|
||||
sizeof(lpfcinfobuf))
|
||||
goto buffer_done;
|
||||
seq_buf_printf(&s, "%s", phba->ModelDesc);
|
||||
|
||||
/* PCI Info */
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
" on PCI bus %02x device %02x irq %d",
|
||||
phba->pcidev->bus->number, phba->pcidev->devfn,
|
||||
phba->pcidev->irq);
|
||||
if (strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf)) >=
|
||||
sizeof(lpfcinfobuf))
|
||||
goto buffer_done;
|
||||
seq_buf_printf(&s, " on PCI bus %02x device %02x irq %d",
|
||||
phba->pcidev->bus->number, phba->pcidev->devfn,
|
||||
phba->pcidev->irq);
|
||||
|
||||
/* Port Number */
|
||||
if (phba->Port[0]) {
|
||||
scnprintf(tmp, sizeof(tmp), " port %s", phba->Port);
|
||||
if (strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf)) >=
|
||||
sizeof(lpfcinfobuf))
|
||||
goto buffer_done;
|
||||
}
|
||||
if (phba->Port[0])
|
||||
seq_buf_printf(&s, " port %s", phba->Port);
|
||||
|
||||
/* Link Speed */
|
||||
link_speed = lpfc_sli_port_speed_get(phba);
|
||||
if (link_speed != 0) {
|
||||
scnprintf(tmp, sizeof(tmp),
|
||||
" Logical Link Speed: %d Mbps", link_speed);
|
||||
if (strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf)) >=
|
||||
sizeof(lpfcinfobuf))
|
||||
goto buffer_done;
|
||||
}
|
||||
if (link_speed != 0)
|
||||
seq_buf_printf(&s, " Logical Link Speed: %d Mbps",
|
||||
link_speed);
|
||||
|
||||
/* Support for BSG ioctls */
|
||||
scnprintf(tmp, sizeof(tmp), " BSG");
|
||||
if (strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf)) >=
|
||||
sizeof(lpfcinfobuf))
|
||||
goto buffer_done;
|
||||
seq_buf_printf(&s, " BSG");
|
||||
|
||||
/* PCI resettable */
|
||||
if (!lpfc_check_pci_resettable(phba)) {
|
||||
scnprintf(tmp, sizeof(tmp), " PCI resettable");
|
||||
strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf));
|
||||
}
|
||||
if (!lpfc_check_pci_resettable(phba))
|
||||
seq_buf_printf(&s, " PCI resettable");
|
||||
}
|
||||
|
||||
buffer_done:
|
||||
return lpfcinfobuf;
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +158,3 @@ struct fcp_cmnd32 {
|
||||
|
||||
#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/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/seq_buf.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/dmi.h>
|
||||
@@ -8109,17 +8110,18 @@ u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
|
||||
u32 cnt = 0;
|
||||
char tmp[DBG_LOG_STR_SZ] = {0};
|
||||
bool log_to_kmsg = (!buf || !buf_len) ? true : false;
|
||||
struct seq_buf s;
|
||||
|
||||
if (!log_to_kmsg) {
|
||||
/* clear the buffer to be sure */
|
||||
memset(buf, 0, buf_len);
|
||||
|
||||
scnprintf(buf, buf_len, "\t%-16s%-16s%-16s%-16s%-8s%-8s%-8s"
|
||||
"%-8s%-8s%-8s%-16s\n",
|
||||
"MaxBPI", "Tot_Data_CMF",
|
||||
"Tot_Data_Cmd", "Tot_Data_Cmpl",
|
||||
"Lat(us)", "Avg_IO", "Max_IO", "Bsy",
|
||||
"IO_cnt", "Info", "BWutil(ms)");
|
||||
seq_buf_init(&s, buf, buf_len);
|
||||
seq_buf_printf(&s, "\t%-16s%-16s%-16s%-16s%-8s%-8s%-8s%-8s%-8s%-8s%-16s\n",
|
||||
"MaxBPI", "Tot_Data_CMF",
|
||||
"Tot_Data_Cmd", "Tot_Data_Cmpl",
|
||||
"Lat(us)", "Avg_IO", "Max_IO", "Bsy",
|
||||
"IO_cnt", "Info", "BWutil(ms)");
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
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),
|
||||
"%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu"
|
||||
"%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n",
|
||||
*head_idx, entry->max_bytes_per_interval,
|
||||
entry->cmf_bytes, entry->total_bytes,
|
||||
entry->rcv_bytes, entry->avg_io_latency,
|
||||
entry->avg_io_size, entry->max_read_cnt,
|
||||
"%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n",
|
||||
*head_idx,
|
||||
entry->max_bytes_per_interval,
|
||||
entry->cmf_bytes,
|
||||
entry->total_bytes,
|
||||
entry->rcv_bytes,
|
||||
entry->avg_io_latency,
|
||||
entry->avg_io_size,
|
||||
entry->max_read_cnt,
|
||||
entry->cmf_busy, entry->io_cnt,
|
||||
entry->cmf_info, entry->timer_utilization,
|
||||
entry->cmf_info,
|
||||
entry->timer_utilization,
|
||||
entry->timer_interval);
|
||||
|
||||
/* Check for buffer overflow */
|
||||
if ((strlen(buf) + strlen(tmp)) >= buf_len)
|
||||
if (seq_buf_puts(&s, tmp) < 0)
|
||||
break;
|
||||
|
||||
/* Append entry's data to buffer */
|
||||
strlcat(buf, tmp, buf_len);
|
||||
} else {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
|
||||
"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,
|
||||
"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),
|
||||
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 */
|
||||
|
||||
if (scmd->device->host->shost_state == SHOST_RECOVERY &&
|
||||
if (scsi_get_host_state(scmd->device->host) == SHOST_RECOVERY &&
|
||||
scmd->cmnd[0] == TEST_UNIT_READY &&
|
||||
(stgt_priv_data->dev_removed || (dev_handle == MPI3MR_INVALID_DEV_HANDLE))) {
|
||||
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) {
|
||||
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,
|
||||
ioc->pcie_sg_lookup[i].pcie_sgl,
|
||||
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
|
||||
*/
|
||||
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) {
|
||||
scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07);
|
||||
scsi_done(scmd);
|
||||
|
||||
@@ -2302,7 +2302,7 @@ int qla_get_tmf(struct tmf_arg *arg)
|
||||
if (TMF_NOT_READY(fcport)) {
|
||||
ql_log(ql_log_warn, vha, 0x802c,
|
||||
"Unable to acquire TM resource due to disruption.\n");
|
||||
rc = EIO;
|
||||
rc = -EIO;
|
||||
break;
|
||||
}
|
||||
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_size > req->length * qla_req_entry_size(ha)) {
|
||||
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,
|
||||
req->length * qla_req_entry_size(ha));
|
||||
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);
|
||||
}
|
||||
|
||||
if (!retries)
|
||||
if (retries == -1)
|
||||
ret_val = QLA_FUNCTION_FAILED;
|
||||
|
||||
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
|
||||
* 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 1;
|
||||
return 0;
|
||||
return scsi_get_host_state(shost) == SHOST_RECOVERY;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1663,10 +1663,9 @@ static enum scsi_qc_status scsi_dispatch_cmd(struct scsi_cmnd *cmd)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (unlikely(host->shost_state == SHOST_DEL)) {
|
||||
if (unlikely(scsi_get_host_state(host) == SHOST_DEL)) {
|
||||
cmd->result = (DID_NO_CONNECT << 16);
|
||||
goto done;
|
||||
|
||||
}
|
||||
|
||||
trace_scsi_dispatch_cmd_start(cmd);
|
||||
|
||||
@@ -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
|
||||
* @shost: SCSI host pointer
|
||||
* @starget: pointer to target device structure
|
||||
* @lun: LUN of target device
|
||||
* @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
|
||||
* - 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,
|
||||
struct scsi_device **sdevp,
|
||||
enum scsi_scan_mode rescan,
|
||||
void *hostdata)
|
||||
__must_hold(&shost->scan_mutex)
|
||||
{
|
||||
struct scsi_device *sdev;
|
||||
unsigned char *result;
|
||||
blist_flags_t bflags;
|
||||
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
|
||||
@@ -1334,6 +1336,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
|
||||
|
||||
/**
|
||||
* scsi_sequential_lun_scan - sequentially scan a SCSI target
|
||||
* @shost: SCSI host pointer
|
||||
* @starget: pointer to target structure to scan
|
||||
* @bflags: black/white list flag for LUN 0
|
||||
* @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.
|
||||
**/
|
||||
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,
|
||||
enum scsi_scan_mode rescan)
|
||||
__must_hold(&shost->scan_mutex)
|
||||
{
|
||||
uint max_dev_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 scan: Sequential scan\n"));
|
||||
@@ -1412,14 +1416,15 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
|
||||
* sparse_lun.
|
||||
*/
|
||||
for (lun = 1; lun < max_dev_lun; ++lun)
|
||||
if ((scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan,
|
||||
NULL) != SCSI_SCAN_LUN_PRESENT) &&
|
||||
if (scsi_probe_and_add_lun(shost, starget, lun, NULL, NULL,
|
||||
rescan, NULL) != SCSI_SCAN_LUN_PRESENT &&
|
||||
!sparse_lun)
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* scsi_report_lun_scan - Scan using SCSI REPORT LUN results
|
||||
* @shost: SCSI host pointer
|
||||
* @starget: which target
|
||||
* @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
|
||||
@@ -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)
|
||||
* 1: could not scan with REPORT LUN
|
||||
**/
|
||||
static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflags,
|
||||
enum scsi_scan_mode rescan)
|
||||
static int scsi_report_lun_scan(struct Scsi_Host *shost,
|
||||
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 int length;
|
||||
@@ -1448,7 +1455,6 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
|
||||
int result;
|
||||
struct scsi_lun *lunp, *lun_data;
|
||||
struct scsi_device *sdev;
|
||||
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
|
||||
struct scsi_failure failure_defs[] = {
|
||||
{
|
||||
.sense = UNIT_ATTENTION,
|
||||
@@ -1594,7 +1600,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
|
||||
} else {
|
||||
int res;
|
||||
|
||||
res = scsi_probe_and_add_lun(starget,
|
||||
res = scsi_probe_and_add_lun(shost, starget,
|
||||
lun, NULL, NULL, rescan, NULL);
|
||||
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();
|
||||
|
||||
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_autopm_put_host(shost);
|
||||
}
|
||||
@@ -1763,10 +1769,11 @@ int scsi_rescan_device(struct scsi_device *sdev)
|
||||
}
|
||||
EXPORT_SYMBOL(scsi_rescan_device);
|
||||
|
||||
static void __scsi_scan_target(struct device *parent, unsigned int channel,
|
||||
unsigned int id, u64 lun, enum scsi_scan_mode rescan)
|
||||
static void __scsi_scan_target(struct Scsi_Host *shost, struct device *parent,
|
||||
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;
|
||||
int res;
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
* 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 (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,
|
||||
* do a sequential scan.
|
||||
*/
|
||||
scsi_sequential_lun_scan(starget, bflags,
|
||||
scsi_sequential_lun_scan(shost, starget, bflags,
|
||||
starget->scsi_level, rescan);
|
||||
}
|
||||
|
||||
@@ -1851,7 +1860,7 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
|
||||
scsi_complete_async_scans();
|
||||
|
||||
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);
|
||||
}
|
||||
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,
|
||||
unsigned int id, u64 lun,
|
||||
enum scsi_scan_mode rescan)
|
||||
__must_hold(&shost->scan_mutex)
|
||||
{
|
||||
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;
|
||||
else
|
||||
order_id = id;
|
||||
__scsi_scan_target(&shost->shost_gendev, channel,
|
||||
__scsi_scan_target(shost, &shost->shost_gendev, channel,
|
||||
order_id, lun, rescan);
|
||||
}
|
||||
else
|
||||
__scsi_scan_target(&shost->shost_gendev, channel,
|
||||
__scsi_scan_target(shost, &shost->shost_gendev, channel,
|
||||
id, lun, rescan);
|
||||
}
|
||||
|
||||
|
||||
@@ -214,8 +214,9 @@ store_shost_state(struct device *dev, struct device_attribute *attr,
|
||||
if (!state)
|
||||
return -EINVAL;
|
||||
|
||||
if (scsi_host_set_state(shost, state))
|
||||
return -EINVAL;
|
||||
scoped_guard(spinlock_irq, shost->host_lock)
|
||||
if (scsi_host_set_state(shost, state))
|
||||
return -EINVAL;
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -223,7 +224,7 @@ static ssize_t
|
||||
show_shost_state(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
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)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -305,6 +305,7 @@ snic_add_host(struct Scsi_Host *shost, struct pci_dev *pdev)
|
||||
if (!shost->work_q) {
|
||||
SNIC_HOST_ERR(shost, "Failed to Create ScsiHost wq.\n");
|
||||
|
||||
scsi_remove_host(shost);
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
CONTEXT_ANALYSIS := y
|
||||
|
||||
obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o
|
||||
ufshcd-core-y += ufshcd.o ufs-sysfs.o ufs-mcq.o ufs-txeq.o
|
||||
ufshcd-core-$(CONFIG_RPMB) += ufs-rpmb.o
|
||||
|
||||
@@ -65,8 +65,10 @@ static int ee_usr_mask_get(void *data, u64 *val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
token_context_lock(ufs_debugfs);
|
||||
|
||||
static int ufs_debugfs_get_user_access(struct ufs_hba *hba)
|
||||
__acquires(&hba->host_sem)
|
||||
__cond_acquires(0, ufs_debugfs)
|
||||
{
|
||||
down(&hba->host_sem);
|
||||
if (!ufshcd_is_user_access_allowed(hba)) {
|
||||
@@ -74,14 +76,16 @@ __acquires(&hba->host_sem)
|
||||
return -EBUSY;
|
||||
}
|
||||
ufshcd_rpm_get_sync(hba);
|
||||
__acquire(ufs_debugfs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ufs_debugfs_put_user_access(struct ufs_hba *hba)
|
||||
__releases(&hba->host_sem)
|
||||
__releases(ufs_debugfs)
|
||||
{
|
||||
ufshcd_rpm_put_sync(hba);
|
||||
up(&hba->host_sem);
|
||||
__release(ufs_debugfs);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
__set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
io_schedule_timeout(msecs_to_jiffies(20));
|
||||
if (ktime_to_us(ktime_sub(ktime_get(), start)) >
|
||||
wait_timeout_us) {
|
||||
@@ -1353,6 +1354,8 @@ static int ufshcd_wait_for_pending_cmds(struct ufs_hba *hba,
|
||||
* On failure, all acquired locks are released and the tagset is unquiesced.
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -1377,6 +1380,8 @@ int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us)
|
||||
* This function resumes command submissions.
|
||||
*/
|
||||
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);
|
||||
blk_mq_unquiesce_tagset(&hba->host->tag_set);
|
||||
@@ -1446,6 +1451,9 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, u32 target_gear, bool scale_up
|
||||
* Return: 0 upon success; -EBUSY upon timeout.
|
||||
*/
|
||||
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;
|
||||
/*
|
||||
@@ -1475,6 +1483,9 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us)
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
__acquires(&hba->dev_cmd.lock)
|
||||
__acquires_shared(&hba->clk_scaling_lock)
|
||||
{
|
||||
ufshcd_hold(hba);
|
||||
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)
|
||||
__releases_shared(&hba->clk_scaling_lock)
|
||||
__releases(&hba->dev_cmd.lock)
|
||||
{
|
||||
up_read(&hba->clk_scaling_lock);
|
||||
mutex_unlock(&hba->dev_cmd.lock);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# 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_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o
|
||||
obj-$(CONFIG_SCSI_UFS_CDNS_PLATFORM) += cdns-pltfrm.o
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#ifndef _SCSI_SCSI_HOST_H
|
||||
#define _SCSI_SCSI_HOST_H
|
||||
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/types.h>
|
||||
@@ -727,7 +728,7 @@ struct Scsi_Host {
|
||||
unsigned int irq;
|
||||
|
||||
|
||||
enum scsi_host_state shost_state;
|
||||
enum scsi_host_state shost_state __guarded_by(host_lock);
|
||||
|
||||
/* ldm bits */
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return shost->shost_state == SHOST_RECOVERY ||
|
||||
shost->shost_state == SHOST_CANCEL_RECOVERY ||
|
||||
shost->shost_state == SHOST_DEL_RECOVERY ||
|
||||
enum scsi_host_state state = scsi_get_host_state(shost);
|
||||
|
||||
return state == SHOST_RECOVERY ||
|
||||
state == SHOST_CANCEL_RECOVERY ||
|
||||
state == SHOST_DEL_RECOVERY ||
|
||||
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)
|
||||
{
|
||||
return shost->shost_state == SHOST_RUNNING ||
|
||||
shost->shost_state == SHOST_RECOVERY;
|
||||
enum scsi_host_state state = scsi_get_host_state(shost);
|
||||
|
||||
return state == SHOST_RUNNING || state == SHOST_RECOVERY;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
Reference in New Issue
Block a user