linux/drivers/scsi/scsi_sysfs.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * scsi_sysfs.c
 *
 * SCSI sysfs interface routines.
 *
 * Created to pull SCSI mid layer sysfs routines into one file.
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/device.h>
#include <linux/pm_runtime.h>
#include <linux/bsg.h>

#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_dh.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_devinfo.h>

#include "scsi_priv.h"
#include "scsi_logging.h"

static const struct device_type scsi_dev_type;

static const struct {} sdev_states[] =;

const char *scsi_device_state_name(enum scsi_device_state state)
{}

static const struct {} shost_states[] =;
const char *scsi_host_state_name(enum scsi_host_state state)
{}

#ifdef CONFIG_SCSI_DH
static const struct {} sdev_access_states[] =;

static const char *scsi_access_state_name(unsigned char state)
{}
#endif

static int check_set(unsigned long long *val, char *src)
{}

static int scsi_scan(struct Scsi_Host *shost, const char *str)
{}

/*
 * shost_show_function: macro to create an attr function that can be used to
 * show a non-bit field.
 */
#define shost_show_function(name, field, format_string)

/*
 * shost_rd_attr: macro to create a function and attribute variable for a
 * read only field.
 */
#define shost_rd_attr2(name, field, format_string)

#define shost_rd_attr(field, format_string)

/*
 * Create the actual show/store functions and data structures.
 */

static ssize_t
store_scan(struct device *dev, struct device_attribute *attr,
	   const char *buf, size_t count)
{
	struct Scsi_Host *shost = class_to_shost(dev);
	int res;

	res = scsi_scan(shost, buf);
	if (res == 0)
		res = count;
	return res;
};
static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);

static ssize_t
store_shost_state(struct device *dev, struct device_attribute *attr,
		  const char *buf, size_t count)
{}

static ssize_t
show_shost_state(struct device *dev, struct device_attribute *attr, char *buf)
{}

/* DEVICE_ATTR(state) clashes with dev_attr_state for sdev */
static struct device_attribute dev_attr_hstate =;

static ssize_t
show_shost_mode(unsigned int mode, char *buf)
{}

static ssize_t
show_shost_supported_mode(struct device *dev, struct device_attribute *attr,
			  char *buf)
{}

static DEVICE_ATTR(supported_mode, S_IRUGO | S_IWUSR, show_shost_supported_mode, NULL);

static ssize_t
show_shost_active_mode(struct device *dev,
		       struct device_attribute *attr, char *buf)
{}

static DEVICE_ATTR(active_mode, S_IRUGO | S_IWUSR, show_shost_active_mode, NULL);

static int check_reset_type(const char *str)
{}

static ssize_t
store_host_reset(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{}

static DEVICE_ATTR(host_reset, S_IWUSR, NULL, store_host_reset);

static ssize_t
show_shost_eh_deadline(struct device *dev,
		      struct device_attribute *attr, char *buf)
{}

static ssize_t
store_shost_eh_deadline(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{}

static DEVICE_ATTR(eh_deadline, S_IRUGO | S_IWUSR, show_shost_eh_deadline, store_shost_eh_deadline);

shost_rd_attr(unique_id, "%u\n");
shost_rd_attr(cmd_per_lun, "%hd\n");
shost_rd_attr(can_queue, "%d\n");
shost_rd_attr(sg_tablesize, "%hu\n");
shost_rd_attr(sg_prot_tablesize, "%hu\n");
shost_rd_attr(prot_capabilities, "%u\n");
shost_rd_attr(prot_guard_type, "%hd\n");
shost_rd_attr2(proc_name, hostt->proc_name, "%s\n");

static ssize_t
show_host_busy(struct device *dev, struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR(host_busy, S_IRUGO, show_host_busy, NULL);

static ssize_t
show_use_blk_mq(struct device *dev, struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR(use_blk_mq, S_IRUGO, show_use_blk_mq, NULL);

static ssize_t
show_nr_hw_queues(struct device *dev, struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR(nr_hw_queues, S_IRUGO, show_nr_hw_queues, NULL);

static struct attribute *scsi_sysfs_shost_attrs[] =;

static const struct attribute_group scsi_shost_attr_group =;

const struct attribute_group *scsi_shost_groups[] =;

static void scsi_device_cls_release(struct device *class_dev)
{}

static void scsi_device_dev_release(struct device *dev)
{}

static struct class sdev_class =;

/* all probing is done in the individual ->probe routines */
static int scsi_bus_match(struct device *dev, const struct device_driver *gendrv)
{}

static int scsi_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)
{}

const struct bus_type scsi_bus_type =;

int scsi_sysfs_register(void)
{}

void scsi_sysfs_unregister(void)
{}

/*
 * sdev_show_function: macro to create an attr function that can be used to
 * show a non-bit field.
 */
#define sdev_show_function(field, format_string)									\

/*
 * sdev_rd_attr: macro to create a function and attribute variable for a
 * read only field.
 */
#define sdev_rd_attr(field, format_string)


/*
 * sdev_rw_attr: create a function and attribute variable for a
 * read/write field.
 */
#define sdev_rw_attr(field, format_string)

/* Currently we don't export bit fields, but we might in future,
 * so leave this code in */
#if 0
/*
 * sdev_rd_attr: create a function and attribute variable for a
 * read/write bit field.
 */
#define sdev_rw_attr_bit

/*
 * scsi_sdev_check_buf_bit: return 0 if buf is "0", return 1 if buf is "1",
 * else return -EINVAL.
 */
static int scsi_sdev_check_buf_bit(const char *buf)
{
	if ((buf[1] == '\0') || ((buf[1] == '\n') && (buf[2] == '\0'))) {
		if (buf[0] == '1')
			return 1;
		else if (buf[0] == '0')
			return 0;
		else
			return -EINVAL;
	} else
		return -EINVAL;
}
#endif
/*
 * Create the actual show/store functions and data structures.
 */
sdev_rd_attr (type, "%d\n");
sdev_rd_attr (scsi_level, "%d\n");
sdev_rd_attr (vendor, "%.8s\n");
sdev_rd_attr (model, "%.16s\n");
sdev_rd_attr (rev, "%.4s\n");
sdev_rd_attr (cdl_supported, "%d\n");

static ssize_t
sdev_show_device_busy(struct device *dev, struct device_attribute *attr,
		char *buf)
{}
static DEVICE_ATTR(device_busy, S_IRUGO, sdev_show_device_busy, NULL);

static ssize_t
sdev_show_device_blocked(struct device *dev, struct device_attribute *attr,
		char *buf)
{}
static DEVICE_ATTR(device_blocked, S_IRUGO, sdev_show_device_blocked, NULL);

/*
 * TODO: can we make these symlinks to the block layer ones?
 */
static ssize_t
sdev_show_timeout (struct device *dev, struct device_attribute *attr, char *buf)
{}

static ssize_t
sdev_store_timeout (struct device *dev, struct device_attribute *attr,
		    const char *buf, size_t count)
{}
static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout);

static ssize_t
sdev_show_eh_timeout(struct device *dev, struct device_attribute *attr, char *buf)
{}

static ssize_t
sdev_store_eh_timeout(struct device *dev, struct device_attribute *attr,
		    const char *buf, size_t count)
{}
static DEVICE_ATTR(eh_timeout, S_IRUGO | S_IWUSR, sdev_show_eh_timeout, sdev_store_eh_timeout);

static ssize_t
store_rescan_field (struct device *dev, struct device_attribute *attr,
		    const char *buf, size_t count)
{}
static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field);

static ssize_t
sdev_store_delete(struct device *dev, struct device_attribute *attr,
		  const char *buf, size_t count)
{
	struct kernfs_node *kn;
	struct scsi_device *sdev = to_scsi_device(dev);

	/*
	 * We need to try to get module, avoiding the module been removed
	 * during delete.
	 */
	if (scsi_device_get(sdev))
		return -ENODEV;

	kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
	WARN_ON_ONCE(!kn);
	/*
	 * Concurrent writes into the "delete" sysfs attribute may trigger
	 * concurrent calls to device_remove_file() and scsi_remove_device().
	 * device_remove_file() handles concurrent removal calls by
	 * serializing these and by ignoring the second and later removal
	 * attempts.  Concurrent calls of scsi_remove_device() are
	 * serialized. The second and later calls of scsi_remove_device() are
	 * ignored because the first call of that function changes the device
	 * state into SDEV_DEL.
	 */
	device_remove_file(dev, attr);
	scsi_remove_device(sdev);
	if (kn)
		sysfs_unbreak_active_protection(kn);
	scsi_device_put(sdev);
	return count;
};
static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete);

static ssize_t
store_state_field(struct device *dev, struct device_attribute *attr,
		  const char *buf, size_t count)
{}

static ssize_t
show_state_field(struct device *dev, struct device_attribute *attr, char *buf)
{}

static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_state_field, store_state_field);

static ssize_t
show_queue_type_field(struct device *dev, struct device_attribute *attr,
		      char *buf)
{}

static ssize_t
store_queue_type_field(struct device *dev, struct device_attribute *attr,
		       const char *buf, size_t count)
{}

static DEVICE_ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field,
		   store_queue_type_field);

#define sdev_vpd_pg_attr(_page)

sdev_vpd_pg_attr(pg83);
sdev_vpd_pg_attr(pg80);
sdev_vpd_pg_attr(pg89);
sdev_vpd_pg_attr(pgb0);
sdev_vpd_pg_attr(pgb1);
sdev_vpd_pg_attr(pgb2);
sdev_vpd_pg_attr(pgb7);
sdev_vpd_pg_attr(pg0);

static ssize_t show_inquiry(struct file *filep, struct kobject *kobj,
			    struct bin_attribute *bin_attr,
			    char *buf, loff_t off, size_t count)
{}

static struct bin_attribute dev_attr_inquiry =;

static ssize_t
show_iostat_counterbits(struct device *dev, struct device_attribute *attr,
			char *buf)
{}

static DEVICE_ATTR(iocounterbits, S_IRUGO, show_iostat_counterbits, NULL);

#define show_sdev_iostat(field)

show_sdev_iostat();
show_sdev_iostat();
show_sdev_iostat();
show_sdev_iostat();

static ssize_t
sdev_show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL);

#define DECLARE_EVT_SHOW(name, Cap_name)

#define DECLARE_EVT_STORE(name, Cap_name)

#define DECLARE_EVT(name, Cap_name)
#define REF_EVT(name)

DECLARE_EVT()
DECLARE_EVT()
DECLARE_EVT()
DECLARE_EVT()
DECLARE_EVT()
DECLARE_EVT()

static ssize_t
sdev_store_queue_depth(struct device *dev, struct device_attribute *attr,
		       const char *buf, size_t count)
{}
sdev_show_function(queue_depth, "%d\n");

static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth,
		   sdev_store_queue_depth);

static ssize_t
sdev_show_wwid(struct device *dev, struct device_attribute *attr,
		    char *buf)
{}
static DEVICE_ATTR(wwid, S_IRUGO, sdev_show_wwid, NULL);

#define BLIST_FLAG_NAME
static const char *const sdev_bflags_name[] =;
#undef BLIST_FLAG_NAME

static ssize_t
sdev_show_blacklist(struct device *dev, struct device_attribute *attr,
		    char *buf)
{}
static DEVICE_ATTR(blacklist, S_IRUGO, sdev_show_blacklist, NULL);

#ifdef CONFIG_SCSI_DH
static ssize_t
sdev_show_dh_state(struct device *dev, struct device_attribute *attr,
		   char *buf)
{}

static ssize_t
sdev_store_dh_state(struct device *dev, struct device_attribute *attr,
		    const char *buf, size_t count)
{}

static DEVICE_ATTR(dh_state, S_IRUGO | S_IWUSR, sdev_show_dh_state,
		   sdev_store_dh_state);

static ssize_t
sdev_show_access_state(struct device *dev,
		       struct device_attribute *attr,
		       char *buf)
{}
static DEVICE_ATTR(access_state, S_IRUGO, sdev_show_access_state, NULL);

static ssize_t
sdev_show_preferred_path(struct device *dev,
			 struct device_attribute *attr,
			 char *buf)
{}
static DEVICE_ATTR(preferred_path, S_IRUGO, sdev_show_preferred_path, NULL);
#endif

static ssize_t
sdev_show_queue_ramp_up_period(struct device *dev,
			       struct device_attribute *attr,
			       char *buf)
{}

static ssize_t
sdev_store_queue_ramp_up_period(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{}

static DEVICE_ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR,
		   sdev_show_queue_ramp_up_period,
		   sdev_store_queue_ramp_up_period);

static ssize_t sdev_show_cdl_enable(struct device *dev,
				    struct device_attribute *attr, char *buf)
{}

static ssize_t sdev_store_cdl_enable(struct device *dev,
				     struct device_attribute *attr,
				     const char *buf, size_t count)
{}
static DEVICE_ATTR(cdl_enable, S_IRUGO | S_IWUSR,
		   sdev_show_cdl_enable, sdev_store_cdl_enable);

static umode_t scsi_sdev_attr_is_visible(struct kobject *kobj,
					 struct attribute *attr, int i)
{}

static umode_t scsi_sdev_bin_attr_is_visible(struct kobject *kobj,
					     struct bin_attribute *attr, int i)
{}

/* Default template for device attributes.  May NOT be modified */
static struct attribute *scsi_sdev_attrs[] =;

static struct bin_attribute *scsi_sdev_bin_attrs[] =;
static struct attribute_group scsi_sdev_attr_group =;

static const struct attribute_group *scsi_sdev_attr_groups[] =;

static int scsi_target_add(struct scsi_target *starget)
{}

/**
 * scsi_sysfs_add_sdev - add scsi device to sysfs
 * @sdev:	scsi_device to add
 *
 * Return value:
 * 	0 on Success / non-zero on Failure
 **/
int scsi_sysfs_add_sdev(struct scsi_device *sdev)
{}

void __scsi_remove_device(struct scsi_device *sdev)
{}

/**
 * scsi_remove_device - unregister a device from the scsi bus
 * @sdev:	scsi_device to unregister
 **/
void scsi_remove_device(struct scsi_device *sdev)
{}
EXPORT_SYMBOL();

static void __scsi_remove_target(struct scsi_target *starget)
{}

/**
 * scsi_remove_target - try to remove a target and all its devices
 * @dev: generic starget or parent of generic stargets to be removed
 *
 * Note: This is slightly racy.  It is possible that if the user
 * requests the addition of another device then the target won't be
 * removed.
 */
void scsi_remove_target(struct device *dev)
{}
EXPORT_SYMBOL();

int __scsi_register_driver(struct device_driver *drv, struct module *owner)
{}
EXPORT_SYMBOL();

int scsi_register_interface(struct class_interface *intf)
{}
EXPORT_SYMBOL();

/**
 * scsi_sysfs_add_host - add scsi host to subsystem
 * @shost:     scsi host struct to add to subsystem
 **/
int scsi_sysfs_add_host(struct Scsi_Host *shost)
{}

static const struct device_type scsi_dev_type =;

void scsi_sysfs_device_initialize(struct scsi_device *sdev)
{}

int scsi_is_sdev_device(const struct device *dev)
{}
EXPORT_SYMBOL();

/* A blank transport template that is used in drivers that don't
 * yet implement Transport Attributes */
struct scsi_transport_template blank_transport_template =;