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:
Linus Torvalds
2026-08-29 11:55:36 -07:00
36 changed files with 642 additions and 631 deletions

View File

@@ -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>

View File

@@ -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/``

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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 ||

View File

@@ -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;

View File

@@ -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,

View File

@@ -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;

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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 "

View File

@@ -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));
/*

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}
/**

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */