xref: /spdk/lib/nvme/nvme_ctrlr_ocssd_cmd.c (revision 16d862d0380886f6fc765f68a87e240bb4295595)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2018 Intel Corporation. All rights reserved.
3  *   Copyright (c) 2021 Mellanox Technologies LTD. All rights reserved.
4  */
5 
6 #include "spdk/nvme_ocssd.h"
7 #include "nvme_internal.h"
8 
9 bool
10 spdk_nvme_ctrlr_is_ocssd_supported(struct spdk_nvme_ctrlr *ctrlr)
11 {
12 	if (ctrlr->quirks & NVME_QUIRK_OCSSD) {
13 		/* TODO: There isn't a standardized way to identify Open-Channel SSD
14 		 * different verdors may have different conditions.
15 		 */
16 
17 		/*
18 		 * Current QEMU OpenChannel Device needs to check nsdata->vs[0].
19 		 * Here check nsdata->vs[0] of the first namespace.
20 		 */
21 		if (ctrlr->cdata.vid == SPDK_PCI_VID_CNEXLABS) {
22 			uint32_t nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr);
23 			struct spdk_nvme_ns *ns;
24 
25 			if (nsid == 0) {
26 				return false;
27 			}
28 
29 			ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid);
30 
31 			if (ns && ns->nsdata.vendor_specific[0] == 0x1) {
32 				return true;
33 			}
34 		}
35 	}
36 	return false;
37 }
38 
39 
40 int
41 spdk_nvme_ocssd_ctrlr_cmd_geometry(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
42 				   void *payload, uint32_t payload_size,
43 				   spdk_nvme_cmd_cb cb_fn, void *cb_arg)
44 {
45 	struct nvme_request *req;
46 	struct spdk_nvme_cmd *cmd;
47 	int rc;
48 
49 	if (!payload || (payload_size != sizeof(struct spdk_ocssd_geometry_data))) {
50 		return -EINVAL;
51 	}
52 
53 	nvme_ctrlr_lock(ctrlr);
54 	req = nvme_allocate_request_user_copy(ctrlr->adminq,
55 					      payload, payload_size, cb_fn, cb_arg, false);
56 	if (req == NULL) {
57 		nvme_ctrlr_unlock(ctrlr);
58 		return -ENOMEM;
59 	}
60 
61 	cmd = &req->cmd;
62 	cmd->opc = SPDK_OCSSD_OPC_GEOMETRY;
63 	cmd->nsid = nsid;
64 
65 	rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
66 
67 	nvme_ctrlr_unlock(ctrlr);
68 	return rc;
69 }
70