xref: /illumos-gate/usr/src/lib/libnvme/common/libnvme_vendor.c (revision 5b080c3aadfabef156c72cedee796d7b3bac5180)
1533affcbSRobert Mustacchi /*
2533affcbSRobert Mustacchi  * This file and its contents are supplied under the terms of the
3533affcbSRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4533affcbSRobert Mustacchi  * You may only use this file in accordance with the terms of version
5533affcbSRobert Mustacchi  * 1.0 of the CDDL.
6533affcbSRobert Mustacchi  *
7533affcbSRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8533affcbSRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9533affcbSRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10533affcbSRobert Mustacchi  */
11533affcbSRobert Mustacchi 
12533affcbSRobert Mustacchi /*
13533affcbSRobert Mustacchi  * Copyright 2024 Oxide Computer Company
14533affcbSRobert Mustacchi  */
15533affcbSRobert Mustacchi 
16533affcbSRobert Mustacchi /*
17533affcbSRobert Mustacchi  * Implements logic to map a device to a vendor-specific entity.
18533affcbSRobert Mustacchi  */
19533affcbSRobert Mustacchi 
20533affcbSRobert Mustacchi #include <libdevinfo.h>
21533affcbSRobert Mustacchi #include <sys/sysmacros.h>
22533affcbSRobert Mustacchi #include <string.h>
23533affcbSRobert Mustacchi 
24533affcbSRobert Mustacchi #include "libnvme_impl.h"
25533affcbSRobert Mustacchi 
26533affcbSRobert Mustacchi const nvme_vsd_t *const nvme_vsd_devices[] = {
27533affcbSRobert Mustacchi 	&wdc_sn840,
287655c6d5SRobert Mustacchi 	&wdc_sn65x,
297655c6d5SRobert Mustacchi 	&micron_7300,
307655c6d5SRobert Mustacchi 	&micron_74x0,
317655c6d5SRobert Mustacchi 	&micron_x500,
327655c6d5SRobert Mustacchi 	&intel_p5510,
337655c6d5SRobert Mustacchi 	&solidigm_p5x20,
34*5b080c3aSRobert Mustacchi 	&solidigm_ps10x0,
35*5b080c3aSRobert Mustacchi 	&kioxia_cd8
36533affcbSRobert Mustacchi };
37533affcbSRobert Mustacchi 
38533affcbSRobert Mustacchi /*
39533affcbSRobert Mustacchi  * Our job is to attempt to map a given device to vendor specific information,
40533affcbSRobert Mustacchi  * if it exists. It may not.
41533affcbSRobert Mustacchi  */
42533affcbSRobert Mustacchi void
nvme_vendor_map_ctrl(nvme_ctrl_t * ctrl)43533affcbSRobert Mustacchi nvme_vendor_map_ctrl(nvme_ctrl_t *ctrl)
44533affcbSRobert Mustacchi {
457655c6d5SRobert Mustacchi 	int *vid, *did, *svidp, *sdidp;
467655c6d5SRobert Mustacchi 	uint16_t svid = UINT16_MAX, sdid = UINT16_MAX;
47533affcbSRobert Mustacchi 
48533affcbSRobert Mustacchi 	if (di_prop_lookup_ints(DDI_DEV_T_ANY, ctrl->nc_devi, "vendor-id",
49533affcbSRobert Mustacchi 	    &vid) != 1 || di_prop_lookup_ints(DDI_DEV_T_ANY, ctrl->nc_devi,
50533affcbSRobert Mustacchi 	    "device-id", &did) != 1) {
51533affcbSRobert Mustacchi 		return;
52533affcbSRobert Mustacchi 	}
53533affcbSRobert Mustacchi 
547655c6d5SRobert Mustacchi 	if (di_prop_lookup_ints(DDI_DEV_T_ANY, ctrl->nc_devi,
557655c6d5SRobert Mustacchi 	    "subsystem-vendor-id", &svidp) == 1) {
567655c6d5SRobert Mustacchi 		svid = (uint16_t)*svidp;
577655c6d5SRobert Mustacchi 	}
587655c6d5SRobert Mustacchi 
597655c6d5SRobert Mustacchi 	if (di_prop_lookup_ints(DDI_DEV_T_ANY, ctrl->nc_devi, "subsystem-id",
607655c6d5SRobert Mustacchi 	    &sdidp) == 1) {
617655c6d5SRobert Mustacchi 		sdid = (uint16_t)*sdidp;
627655c6d5SRobert Mustacchi 	}
637655c6d5SRobert Mustacchi 
647655c6d5SRobert Mustacchi 	for (size_t dev = 0; dev < ARRAY_SIZE(nvme_vsd_devices); dev++) {
657655c6d5SRobert Mustacchi 		const nvme_vsd_t *vsd = nvme_vsd_devices[dev];
667655c6d5SRobert Mustacchi 
677655c6d5SRobert Mustacchi 		for (size_t i = 0; i < vsd->nvd_nident; i++) {
687655c6d5SRobert Mustacchi 			const nvme_vsd_ident_t *ident = &vsd->nvd_ident[i];
697655c6d5SRobert Mustacchi 			if (ident->nvdi_vid != (uint16_t)vid[0] ||
707655c6d5SRobert Mustacchi 			    ident->nvdi_did != (uint16_t)did[0]) {
717655c6d5SRobert Mustacchi 				continue;
727655c6d5SRobert Mustacchi 			}
737655c6d5SRobert Mustacchi 
747655c6d5SRobert Mustacchi 			if (ident->nvdi_subsys && (ident->nvdi_svid != svid ||
757655c6d5SRobert Mustacchi 			    ident->nvdi_sdid != sdid)) {
767655c6d5SRobert Mustacchi 				continue;
777655c6d5SRobert Mustacchi 			}
787655c6d5SRobert Mustacchi 
797655c6d5SRobert Mustacchi 			ctrl->nc_vsd = nvme_vsd_devices[dev];
80533affcbSRobert Mustacchi 			return;
81533affcbSRobert Mustacchi 		}
82533affcbSRobert Mustacchi 	}
83533affcbSRobert Mustacchi }
84533affcbSRobert Mustacchi 
85533affcbSRobert Mustacchi bool
nvme_vendor_vuc_supported(nvme_ctrl_t * ctrl,const char * name)86533affcbSRobert Mustacchi nvme_vendor_vuc_supported(nvme_ctrl_t *ctrl, const char *name)
87533affcbSRobert Mustacchi {
88533affcbSRobert Mustacchi 	if (ctrl->nc_vsd != NULL) {
89533affcbSRobert Mustacchi 		for (size_t i = 0; i < ctrl->nc_vsd->nvd_nvuc; i++) {
90533affcbSRobert Mustacchi 			if (strcmp(name, ctrl->nc_vsd->nvd_vuc[i].nvd_short) ==
91533affcbSRobert Mustacchi 			    0) {
92533affcbSRobert Mustacchi 				return (true);
93533affcbSRobert Mustacchi 			}
94533affcbSRobert Mustacchi 		}
95533affcbSRobert Mustacchi 	}
96533affcbSRobert Mustacchi 
97533affcbSRobert Mustacchi 	return (nvme_ctrl_error(ctrl, NVME_ERR_VU_FUNC_UNSUP_BY_DEV, 0,
98533affcbSRobert Mustacchi 	    "device missing support for vendor unique command %s", name));
99533affcbSRobert Mustacchi }
100