drivers/nvme/target/passthru.c

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

File Facts

System
Linux kernel
Corpus path
drivers/nvme/target/passthru.c
Extension
.c
Size
17569 bytes
Lines
665
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

if (cur->nidt == NVME_NIDT_CSI) {
			memcpy(&csi, cur + 1, NVME_NIDT_CSI_LEN);
			csi_seen = true;
			break;
		}
		len = sizeof(struct nvme_ns_id_desc) + cur->nidl;
	}

	memset(data, 0, NVME_IDENTIFY_DATA_SIZE);
	if (csi_seen) {
		struct nvme_ns_id_desc *cur = data;

		cur->nidt = NVME_NIDT_CSI;
		cur->nidl = NVME_NIDT_CSI_LEN;
		memcpy(cur + 1, &csi, NVME_NIDT_CSI_LEN);
	}
	status = nvmet_copy_to_sgl(req, 0, data, NVME_IDENTIFY_DATA_SIZE);
out_free:
	kfree(data);
	return status;
}

static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req)
{
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	struct nvme_ctrl *pctrl = ctrl->subsys->passthru_ctrl;
	u16 status = NVME_SC_SUCCESS;
	struct nvme_id_ctrl *id;
	unsigned int max_hw_sectors;
	int page_shift;

	id = kzalloc_obj(*id);
	if (!id)
		return NVME_SC_INTERNAL;

	status = nvmet_copy_from_sgl(req, 0, id, sizeof(*id));
	if (status)
		goto out_free;

	id->cntlid = cpu_to_le16(ctrl->cntlid);
	id->ver = cpu_to_le32(ctrl->subsys->ver);

	/*
	 * The passthru NVMe driver may have a limit on the number of segments
	 * which depends on the host's memory fragmentation. To solve this,
	 * ensure mdts is limited to the pages equal to the number of segments.
	 */
	max_hw_sectors = min_not_zero(pctrl->max_segments << PAGE_SECTORS_SHIFT,
				      pctrl->max_hw_sectors);

	/*
	 * nvmet_passthru_map_sg is limited to using a single bio so limit
	 * the mdts based on BIO_MAX_VECS as well
	 */
	max_hw_sectors = min_not_zero(BIO_MAX_VECS << PAGE_SECTORS_SHIFT,
				      max_hw_sectors);

	page_shift = NVME_CAP_MPSMIN(ctrl->cap) + 12;

	id->mdts = ilog2(max_hw_sectors) + 9 - page_shift;

	id->acl = 3;
	/*
	 * We export aerl limit for the fabrics controller, update this when
	 * passthru based aerl support is added.
	 */
	id->aerl = NVMET_ASYNC_EVENTS - 1;

	/* emulate kas as most of the PCIe ctrl don't have a support for kas */
	id->kas = cpu_to_le16(NVMET_KAS);

	/* don't support host memory buffer */
	id->hmpre = 0;
	id->hmmin = 0;

	id->sqes = min_t(__u8, ((0x6 << 4) | 0x6), id->sqes);
	id->cqes = min_t(__u8, ((0x4 << 4) | 0x4), id->cqes);
	id->maxcmd = cpu_to_le16(NVMET_MAX_CMD(ctrl));

	/* don't support fuse commands */
	id->fuses = 0;

	id->sgls = cpu_to_le32(1 << 0); /* we always support SGLs */
	if (ctrl->ops->flags & NVMF_KEYED_SGLS)
		id->sgls |= cpu_to_le32(1 << 2);
	if (req->port->inline_data_size)
		id->sgls |= cpu_to_le32(1 << 20);

	/*
	 * When passthru controller is setup using nvme-loop transport it will

Annotation

Implementation Notes