drivers/scsi/iscsi_boot_sysfs.c

Source file repositories/reference/linux-study-clean/drivers/scsi/iscsi_boot_sysfs.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/iscsi_boot_sysfs.c
Extension
.c
Size
18655 bytes
Lines
555
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct iscsi_boot_attr {
	struct attribute attr;
	int type;
	ssize_t (*show) (void *data, int type, char *buf);
};

/*
 * The routine called for all sysfs attributes.
 */
static ssize_t iscsi_boot_show_attribute(struct kobject *kobj,
					 struct attribute *attr, char *buf)
{
	struct iscsi_boot_kobj *boot_kobj =
			container_of(kobj, struct iscsi_boot_kobj, kobj);
	struct iscsi_boot_attr *boot_attr =
			container_of(attr, struct iscsi_boot_attr, attr);
	ssize_t ret = -EIO;
	char *str = buf;

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;

	if (boot_kobj->show)
		ret = boot_kobj->show(boot_kobj->data, boot_attr->type, str);
	return ret;
}

static const struct sysfs_ops iscsi_boot_attr_ops = {
	.show = iscsi_boot_show_attribute,
};

static void iscsi_boot_kobj_release(struct kobject *kobj)
{
	struct iscsi_boot_kobj *boot_kobj =
			container_of(kobj, struct iscsi_boot_kobj, kobj);

	if (boot_kobj->release)
		boot_kobj->release(boot_kobj->data);
	kfree(boot_kobj);
}

static struct kobj_type iscsi_boot_ktype = {
	.release = iscsi_boot_kobj_release,
	.sysfs_ops = &iscsi_boot_attr_ops,
};

#define iscsi_boot_rd_attr(fnname, sysfs_name, attr_type)		\
static struct iscsi_boot_attr iscsi_boot_attr_##fnname = {	\
	.attr	= { .name = __stringify(sysfs_name), .mode = 0444 },	\
	.type	= attr_type,						\
}

/* Target attrs */
iscsi_boot_rd_attr(tgt_index, index, ISCSI_BOOT_TGT_INDEX);
iscsi_boot_rd_attr(tgt_flags, flags, ISCSI_BOOT_TGT_FLAGS);
iscsi_boot_rd_attr(tgt_ip, ip-addr, ISCSI_BOOT_TGT_IP_ADDR);
iscsi_boot_rd_attr(tgt_port, port, ISCSI_BOOT_TGT_PORT);
iscsi_boot_rd_attr(tgt_lun, lun, ISCSI_BOOT_TGT_LUN);
iscsi_boot_rd_attr(tgt_chap, chap-type, ISCSI_BOOT_TGT_CHAP_TYPE);
iscsi_boot_rd_attr(tgt_nic, nic-assoc, ISCSI_BOOT_TGT_NIC_ASSOC);
iscsi_boot_rd_attr(tgt_name, target-name, ISCSI_BOOT_TGT_NAME);
iscsi_boot_rd_attr(tgt_chap_name, chap-name, ISCSI_BOOT_TGT_CHAP_NAME);
iscsi_boot_rd_attr(tgt_chap_secret, chap-secret, ISCSI_BOOT_TGT_CHAP_SECRET);
iscsi_boot_rd_attr(tgt_chap_rev_name, rev-chap-name,
		   ISCSI_BOOT_TGT_REV_CHAP_NAME);
iscsi_boot_rd_attr(tgt_chap_rev_secret, rev-chap-name-secret,
		   ISCSI_BOOT_TGT_REV_CHAP_SECRET);

static struct attribute *target_attrs[] = {
	&iscsi_boot_attr_tgt_index.attr,
	&iscsi_boot_attr_tgt_flags.attr,
	&iscsi_boot_attr_tgt_ip.attr,
	&iscsi_boot_attr_tgt_port.attr,
	&iscsi_boot_attr_tgt_lun.attr,
	&iscsi_boot_attr_tgt_chap.attr,
	&iscsi_boot_attr_tgt_nic.attr,
	&iscsi_boot_attr_tgt_name.attr,
	&iscsi_boot_attr_tgt_chap_name.attr,
	&iscsi_boot_attr_tgt_chap_secret.attr,
	&iscsi_boot_attr_tgt_chap_rev_name.attr,
	&iscsi_boot_attr_tgt_chap_rev_secret.attr,
	NULL
};

static umode_t iscsi_boot_tgt_attr_is_visible(struct kobject *kobj,
					     struct attribute *attr, int i)
{
	struct iscsi_boot_kobj *boot_kobj =
			container_of(kobj, struct iscsi_boot_kobj, kobj);

Annotation

Implementation Notes