Lines Matching +full:ctrl +full:- +full:module
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (c) 2017-2018 Western Digital Corporation or its
7 * Copyright (c) 2019-2020, Eideticom Inc.
11 #include <linux/module.h>
23 void nvmet_passthrough_override_cap(struct nvmet_ctrl *ctrl) in nvmet_passthrough_override_cap() argument
29 if (!nvme_multi_css(ctrl->subsys->passthru_ctrl)) in nvmet_passthrough_override_cap()
30 ctrl->cap &= ~(1ULL << 43); in nvmet_passthrough_override_cap()
35 struct nvmet_ctrl *ctrl = req->sq->ctrl; in nvmet_passthru_override_id_descs() local
42 if (!ctrl->subsys->clear_ids) in nvmet_passthru_override_id_descs()
56 if (cur->nidl == 0) in nvmet_passthru_override_id_descs()
58 if (cur->nidt == NVME_NIDT_CSI) { in nvmet_passthru_override_id_descs()
63 len = sizeof(struct nvme_ns_id_desc) + cur->nidl; in nvmet_passthru_override_id_descs()
70 cur->nidt = NVME_NIDT_CSI; in nvmet_passthru_override_id_descs()
71 cur->nidl = NVME_NIDT_CSI_LEN; in nvmet_passthru_override_id_descs()
82 struct nvmet_ctrl *ctrl = req->sq->ctrl; in nvmet_passthru_override_id_ctrl() local
83 struct nvme_ctrl *pctrl = ctrl->subsys->passthru_ctrl; in nvmet_passthru_override_id_ctrl()
97 id->cntlid = cpu_to_le16(ctrl->cntlid); in nvmet_passthru_override_id_ctrl()
98 id->ver = cpu_to_le32(ctrl->subsys->ver); in nvmet_passthru_override_id_ctrl()
105 max_hw_sectors = min_not_zero(pctrl->max_segments << (PAGE_SHIFT - 9), in nvmet_passthru_override_id_ctrl()
106 pctrl->max_hw_sectors); in nvmet_passthru_override_id_ctrl()
112 max_hw_sectors = min_not_zero(BIO_MAX_VECS << (PAGE_SHIFT - 9), in nvmet_passthru_override_id_ctrl()
115 page_shift = NVME_CAP_MPSMIN(ctrl->cap) + 12; in nvmet_passthru_override_id_ctrl()
117 id->mdts = ilog2(max_hw_sectors) + 9 - page_shift; in nvmet_passthru_override_id_ctrl()
119 id->acl = 3; in nvmet_passthru_override_id_ctrl()
124 id->aerl = NVMET_ASYNC_EVENTS - 1; in nvmet_passthru_override_id_ctrl()
126 /* emulate kas as most of the PCIe ctrl don't have a support for kas */ in nvmet_passthru_override_id_ctrl()
127 id->kas = cpu_to_le16(NVMET_KAS); in nvmet_passthru_override_id_ctrl()
130 id->hmpre = 0; in nvmet_passthru_override_id_ctrl()
131 id->hmmin = 0; in nvmet_passthru_override_id_ctrl()
133 id->sqes = min_t(__u8, ((0x6 << 4) | 0x6), id->sqes); in nvmet_passthru_override_id_ctrl()
134 id->cqes = min_t(__u8, ((0x4 << 4) | 0x4), id->cqes); in nvmet_passthru_override_id_ctrl()
135 id->maxcmd = cpu_to_le16(NVMET_MAX_CMD); in nvmet_passthru_override_id_ctrl()
138 id->fuses = 0; in nvmet_passthru_override_id_ctrl()
140 id->sgls = cpu_to_le32(1 << 0); /* we always support SGLs */ in nvmet_passthru_override_id_ctrl()
141 if (ctrl->ops->flags & NVMF_KEYED_SGLS) in nvmet_passthru_override_id_ctrl()
142 id->sgls |= cpu_to_le32(1 << 2); in nvmet_passthru_override_id_ctrl()
143 if (req->port->inline_data_size) in nvmet_passthru_override_id_ctrl()
144 id->sgls |= cpu_to_le32(1 << 20); in nvmet_passthru_override_id_ctrl()
147 * When passthru controller is setup using nvme-loop transport it will in nvmet_passthru_override_id_ctrl()
148 * export the passthru ctrl subsysnqn (PCIe NVMe ctrl) and will fail in in nvmet_passthru_override_id_ctrl()
149 * the nvme/host/core.c in the nvme_init_subsystem()->nvme_active_ctrl() in nvmet_passthru_override_id_ctrl()
151 * mask the passthru-ctrl subsysnqn with the target ctrl subsysnqn. in nvmet_passthru_override_id_ctrl()
153 memcpy(id->subnqn, ctrl->subsysnqn, sizeof(id->subnqn)); in nvmet_passthru_override_id_ctrl()
155 /* use fabric id-ctrl values */ in nvmet_passthru_override_id_ctrl()
156 id->ioccsz = cpu_to_le32((sizeof(struct nvme_command) + in nvmet_passthru_override_id_ctrl()
157 req->port->inline_data_size) / 16); in nvmet_passthru_override_id_ctrl()
158 id->iorcsz = cpu_to_le32(sizeof(struct nvme_completion) / 16); in nvmet_passthru_override_id_ctrl()
160 id->msdbd = ctrl->ops->msdbd; in nvmet_passthru_override_id_ctrl()
163 id->cmic |= 1 << 1; in nvmet_passthru_override_id_ctrl()
166 id->oncs &= cpu_to_le16(~NVME_CTRL_ONCS_RESERVATIONS); in nvmet_passthru_override_id_ctrl()
189 for (i = 0; i < (id->nlbaf + 1); i++) in nvmet_passthru_override_id_ns()
190 if (id->lbaf[i].ms) in nvmet_passthru_override_id_ns()
191 memset(&id->lbaf[i], 0, sizeof(id->lbaf[i])); in nvmet_passthru_override_id_ns()
193 id->flbas = id->flbas & ~(1 << 4); in nvmet_passthru_override_id_ns()
200 id->mc = 0; in nvmet_passthru_override_id_ns()
202 if (req->sq->ctrl->subsys->clear_ids) { in nvmet_passthru_override_id_ns()
203 memset(id->nguid, 0, NVME_NIDT_NGUID_LEN); in nvmet_passthru_override_id_ns()
204 memset(id->eui64, 0, NVME_NIDT_EUI64_LEN); in nvmet_passthru_override_id_ns()
217 struct request *rq = req->p.rq; in nvmet_passthru_execute_cmd_work()
218 struct nvme_ctrl *ctrl = nvme_req(rq)->ctrl; in nvmet_passthru_execute_cmd_work() local
225 req->cmd->common.opcode == nvme_admin_identify) { in nvmet_passthru_execute_cmd_work()
226 switch (req->cmd->identify.cns) { in nvmet_passthru_execute_cmd_work()
240 req->cqe->result = nvme_req(rq)->result; in nvmet_passthru_execute_cmd_work()
245 nvme_passthru_end(ctrl, effects, req->cmd, status); in nvmet_passthru_execute_cmd_work()
251 struct nvmet_req *req = rq->end_io_data; in nvmet_passthru_req_done()
253 req->cqe->result = nvme_req(rq)->result; in nvmet_passthru_req_done()
254 nvmet_req_complete(req, nvme_req(rq)->status); in nvmet_passthru_req_done()
265 if (req->sg_cnt > BIO_MAX_VECS) in nvmet_passthru_map_sg()
266 return -EINVAL; in nvmet_passthru_map_sg()
269 bio = &req->p.inline_bio; in nvmet_passthru_map_sg()
270 bio_init(bio, NULL, req->inline_bvec, in nvmet_passthru_map_sg()
271 ARRAY_SIZE(req->inline_bvec), req_op(rq)); in nvmet_passthru_map_sg()
273 bio = bio_alloc(NULL, bio_max_segs(req->sg_cnt), req_op(rq), in nvmet_passthru_map_sg()
275 bio->bi_end_io = bio_put; in nvmet_passthru_map_sg()
278 for_each_sg(req->sg, sg, req->sg_cnt, i) { in nvmet_passthru_map_sg()
279 if (bio_add_pc_page(rq->q, bio, sg_page(sg), sg->length, in nvmet_passthru_map_sg()
280 sg->offset) < sg->length) { in nvmet_passthru_map_sg()
282 return -EINVAL; in nvmet_passthru_map_sg()
286 blk_rq_bio_prep(rq, bio, req->sg_cnt); in nvmet_passthru_map_sg()
293 struct nvme_ctrl *ctrl = nvmet_req_subsys(req)->passthru_ctrl; in nvmet_passthru_execute_cmd() local
294 struct request_queue *q = ctrl->admin_q; in nvmet_passthru_execute_cmd()
302 if (likely(req->sq->qid != 0)) { in nvmet_passthru_execute_cmd()
303 u32 nsid = le32_to_cpu(req->cmd->common.nsid); in nvmet_passthru_execute_cmd()
305 ns = nvme_find_get_ns(ctrl, nsid); in nvmet_passthru_execute_cmd()
312 q = ns->queue; in nvmet_passthru_execute_cmd()
313 timeout = nvmet_req_subsys(req)->io_timeout; in nvmet_passthru_execute_cmd()
315 timeout = nvmet_req_subsys(req)->admin_timeout; in nvmet_passthru_execute_cmd()
318 rq = blk_mq_alloc_request(q, nvme_req_op(req->cmd), 0); in nvmet_passthru_execute_cmd()
323 nvme_init_request(rq, req->cmd); in nvmet_passthru_execute_cmd()
326 rq->timeout = timeout; in nvmet_passthru_execute_cmd()
328 if (req->sg_cnt) { in nvmet_passthru_execute_cmd()
343 effects = nvme_command_effects(ctrl, ns, req->cmd->common.opcode); in nvmet_passthru_execute_cmd()
344 if (req->p.use_workqueue || effects) { in nvmet_passthru_execute_cmd()
345 INIT_WORK(&req->p.work, nvmet_passthru_execute_cmd_work); in nvmet_passthru_execute_cmd()
346 req->p.rq = rq; in nvmet_passthru_execute_cmd()
347 queue_work(nvmet_wq, &req->p.work); in nvmet_passthru_execute_cmd()
349 rq->end_io = nvmet_passthru_req_done; in nvmet_passthru_execute_cmd()
350 rq->end_io_data = req; in nvmet_passthru_execute_cmd()
375 struct nvme_ctrl *ctrl = nvmet_req_subsys(req)->passthru_ctrl; in nvmet_passthru_set_host_behaviour() local
384 ret = nvme_get_features(ctrl, NVME_FEAT_HOST_BEHAVIOR, 0, in nvmet_passthru_set_host_behaviour()
406 req->p.use_workqueue = false; in nvmet_setup_passthru_command()
407 req->execute = nvmet_passthru_execute_cmd; in nvmet_setup_passthru_command()
413 /* Reject any commands with non-sgl flags set (ie. fused commands) */ in nvmet_parse_passthru_io_cmd()
414 if (req->cmd->common.flags & ~NVME_CMD_SGL_ALL) in nvmet_parse_passthru_io_cmd()
417 switch (req->cmd->common.opcode) { in nvmet_parse_passthru_io_cmd()
442 switch (le32_to_cpu(req->cmd->features.fid)) { in nvmet_passthru_get_set_features()
474 * The Pre-Boot Software Load Count doesn't make much in nvmet_passthru_get_set_features()
487 /* Reject any commands with non-sgl flags set (ie. fused commands) */ in nvmet_parse_passthru_admin_cmd()
488 if (req->cmd->common.flags & ~NVME_CMD_SGL_ALL) in nvmet_parse_passthru_admin_cmd()
494 if (req->cmd->common.opcode >= nvme_admin_vendor_start) in nvmet_parse_passthru_admin_cmd()
497 switch (req->cmd->common.opcode) { in nvmet_parse_passthru_admin_cmd()
499 req->execute = nvmet_execute_async_event; in nvmet_parse_passthru_admin_cmd()
504 * alive to the non-passthru mode. In future please change this in nvmet_parse_passthru_admin_cmd()
507 req->execute = nvmet_execute_keep_alive; in nvmet_parse_passthru_admin_cmd()
510 switch (le32_to_cpu(req->cmd->features.fid)) { in nvmet_parse_passthru_admin_cmd()
515 req->execute = nvmet_execute_set_features; in nvmet_parse_passthru_admin_cmd()
518 req->execute = nvmet_passthru_set_host_behaviour; in nvmet_parse_passthru_admin_cmd()
525 switch (le32_to_cpu(req->cmd->features.fid)) { in nvmet_parse_passthru_admin_cmd()
530 req->execute = nvmet_execute_get_features; in nvmet_parse_passthru_admin_cmd()
537 switch (req->cmd->identify.cns) { in nvmet_parse_passthru_admin_cmd()
539 req->execute = nvmet_passthru_execute_cmd; in nvmet_parse_passthru_admin_cmd()
540 req->p.use_workqueue = true; in nvmet_parse_passthru_admin_cmd()
543 switch (req->cmd->identify.csi) { in nvmet_parse_passthru_admin_cmd()
545 req->execute = nvmet_passthru_execute_cmd; in nvmet_parse_passthru_admin_cmd()
546 req->p.use_workqueue = true; in nvmet_parse_passthru_admin_cmd()
551 req->execute = nvmet_passthru_execute_cmd; in nvmet_parse_passthru_admin_cmd()
552 req->p.use_workqueue = true; in nvmet_parse_passthru_admin_cmd()
555 switch (req->cmd->identify.csi) { in nvmet_parse_passthru_admin_cmd()
557 req->execute = nvmet_passthru_execute_cmd; in nvmet_parse_passthru_admin_cmd()
558 req->p.use_workqueue = true; in nvmet_parse_passthru_admin_cmd()
575 struct nvme_ctrl *ctrl; in nvmet_passthru_ctrl_enable() local
577 int ret = -EINVAL; in nvmet_passthru_ctrl_enable()
580 mutex_lock(&subsys->lock); in nvmet_passthru_ctrl_enable()
581 if (!subsys->passthru_ctrl_path) in nvmet_passthru_ctrl_enable()
583 if (subsys->passthru_ctrl) in nvmet_passthru_ctrl_enable()
586 if (subsys->nr_namespaces) { in nvmet_passthru_ctrl_enable()
591 file = filp_open(subsys->passthru_ctrl_path, O_RDWR, 0); in nvmet_passthru_ctrl_enable()
597 ctrl = nvme_ctrl_from_file(file); in nvmet_passthru_ctrl_enable()
598 if (!ctrl) { in nvmet_passthru_ctrl_enable()
600 subsys->passthru_ctrl_path); in nvmet_passthru_ctrl_enable()
605 old = xa_cmpxchg(&passthru_subsystems, ctrl->cntlid, NULL, in nvmet_passthru_ctrl_enable()
615 subsys->passthru_ctrl = ctrl; in nvmet_passthru_ctrl_enable()
616 subsys->ver = ctrl->vs; in nvmet_passthru_ctrl_enable()
618 if (subsys->ver < NVME_VS(1, 2, 1)) { in nvmet_passthru_ctrl_enable()
620 NVME_MAJOR(subsys->ver), NVME_MINOR(subsys->ver), in nvmet_passthru_ctrl_enable()
621 NVME_TERTIARY(subsys->ver)); in nvmet_passthru_ctrl_enable()
622 subsys->ver = NVME_VS(1, 2, 1); in nvmet_passthru_ctrl_enable()
624 nvme_get_ctrl(ctrl); in nvmet_passthru_ctrl_enable()
625 __module_get(subsys->passthru_ctrl->ops->module); in nvmet_passthru_ctrl_enable()
631 mutex_unlock(&subsys->lock); in nvmet_passthru_ctrl_enable()
637 if (subsys->passthru_ctrl) { in __nvmet_passthru_ctrl_disable()
638 xa_erase(&passthru_subsystems, subsys->passthru_ctrl->cntlid); in __nvmet_passthru_ctrl_disable()
639 module_put(subsys->passthru_ctrl->ops->module); in __nvmet_passthru_ctrl_disable()
640 nvme_put_ctrl(subsys->passthru_ctrl); in __nvmet_passthru_ctrl_disable()
642 subsys->passthru_ctrl = NULL; in __nvmet_passthru_ctrl_disable()
643 subsys->ver = NVMET_DEFAULT_VS; in __nvmet_passthru_ctrl_disable()
648 mutex_lock(&subsys->lock); in nvmet_passthru_ctrl_disable()
650 mutex_unlock(&subsys->lock); in nvmet_passthru_ctrl_disable()
655 mutex_lock(&subsys->lock); in nvmet_passthru_subsys_free()
657 mutex_unlock(&subsys->lock); in nvmet_passthru_subsys_free()
658 kfree(subsys->passthru_ctrl_path); in nvmet_passthru_subsys_free()