drivers/nvme/target/configfs.c

Source file repositories/reference/linux-study-clean/drivers/nvme/target/configfs.c

File Facts

System
Linux kernel
Corpus path
drivers/nvme/target/configfs.c
Extension
.c
Size
58958 bytes
Lines
2405
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: implementation source
Status
source implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

struct nvmet_type_name_map {
	u8		type;
	const char	*name;
};

static struct nvmet_type_name_map nvmet_transport[] = {
	{ NVMF_TRTYPE_RDMA,	"rdma" },
	{ NVMF_TRTYPE_FC,	"fc" },
	{ NVMF_TRTYPE_TCP,	"tcp" },
	{ NVMF_TRTYPE_PCI,	"pci" },
	{ NVMF_TRTYPE_LOOP,	"loop" },
};

static const struct nvmet_type_name_map nvmet_addr_family[] = {
	{ NVMF_ADDR_FAMILY_PCI,		"pcie" },
	{ NVMF_ADDR_FAMILY_IP4,		"ipv4" },
	{ NVMF_ADDR_FAMILY_IP6,		"ipv6" },
	{ NVMF_ADDR_FAMILY_IB,		"ib" },
	{ NVMF_ADDR_FAMILY_FC,		"fc" },
	{ NVMF_ADDR_FAMILY_PCI,		"pci" },
	{ NVMF_ADDR_FAMILY_LOOP,	"loop" },
};

static bool nvmet_is_port_enabled(struct nvmet_port *p, const char *caller)
{
	if (p->enabled)
		pr_err("Disable port '%u' before changing attribute in %s\n",
		       le16_to_cpu(p->disc_addr.portid), caller);
	return p->enabled;
}

/*
 * nvmet_port Generic ConfigFS definitions.
 * Used in any place in the ConfigFS tree that refers to an address.
 */
static ssize_t nvmet_addr_adrfam_show(struct config_item *item, char *page)
{
	u8 adrfam = to_nvmet_port(item)->disc_addr.adrfam;
	int i;

	for (i = 1; i < ARRAY_SIZE(nvmet_addr_family); i++) {
		if (nvmet_addr_family[i].type == adrfam)
			return snprintf(page, PAGE_SIZE, "%s\n",
					nvmet_addr_family[i].name);
	}

	return snprintf(page, PAGE_SIZE, "\n");
}

static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
		const char *page, size_t count)
{
	struct nvmet_port *port = to_nvmet_port(item);
	int i;

	if (nvmet_is_port_enabled(port, __func__))
		return -EACCES;

	for (i = 1; i < ARRAY_SIZE(nvmet_addr_family); i++) {
		if (sysfs_streq(page, nvmet_addr_family[i].name))
			goto found;
	}

	pr_err("Invalid value '%s' for adrfam\n", page);
	return -EINVAL;

found:
	port->disc_addr.adrfam = nvmet_addr_family[i].type;
	return count;
}

CONFIGFS_ATTR(nvmet_, addr_adrfam);

static ssize_t nvmet_addr_portid_show(struct config_item *item,
		char *page)
{
	__le16 portid = to_nvmet_port(item)->disc_addr.portid;

	return snprintf(page, PAGE_SIZE, "%d\n", le16_to_cpu(portid));
}

static ssize_t nvmet_addr_portid_store(struct config_item *item,
		const char *page, size_t count)
{
	struct nvmet_port *port = to_nvmet_port(item);
	u16 portid = 0;

	if (kstrtou16(page, 0, &portid)) {
		pr_err("Invalid value '%s' for portid\n", page);
		return -EINVAL;

Annotation

Implementation Notes