1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
14 */
15
16 #include <libnvpair.h>
17 #include <scsi/libses.h>
18 #include <scsi/libses_plugin.h>
19 #include <scsi/plugins/ses/framework/ses2_impl.h>
20
21 /*
22 * This is a plugin, modeled after the DELL-MD3060e plugin, to update
23 * libses's description field for SMC's 60 bay JBOD (2 subenclosures
24 * with 30 bays). When we get the description from the JBOD
25 * subenclosure, it contains the slot number in the form "Slot#",
26 * where # is from 01-30, however, the aes page indicates the device
27 * slot numbering is from 0-29. Therefore, we will replace these
28 * Slot01-Slot30 descriptions using the bay number (Slot00-Slot29).
29 */
30
31 /*ARGSUSED*/
32 static int
33 smc60_parse_node(ses_plugin_t *sp, ses_node_t *np)
34 {
35 uint64_t type, bay;
36 int nverr;
37 nvlist_t *props;
38 char buf[SES2_MIN_DIAGPAGE_ALLOC];
39
40 if (ses_node_type(np) != SES_NODE_ELEMENT)
41 return (0);
42
43 props = ses_node_props(np);
44 VERIFY(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_TYPE, &type) == 0);
45 if (type != SES_ET_ARRAY_DEVICE && type != SES_ET_DEVICE)
46 return (0);
47
48 /* bay will range 0-29 */
49 if (nvlist_lookup_uint64(props, SES_PROP_BAY_NUMBER, &bay) != 0)
50 return (0);
51
52 /* modify the descrition to use the bay number */
53 buf[SES2_MIN_DIAGPAGE_ALLOC - 1] = '\0';
54 if (snprintf(buf, SES2_MIN_DIAGPAGE_ALLOC - 1,
55 "Slot%02" PRIu64, bay) < 0)
56 return (0);
57
58 /*
59 * Replace the ses-description field with the string we created above.
60 * Note: SES_NV_ADD is a nested macro that can return -1 on error.
61 */
62 SES_NV_ADD(string, nverr, props, SES_PROP_DESCRIPTION, buf);
63
64 return (0);
65 }
66
67 int
68 _ses_init(ses_plugin_t *sp)
69 {
70 ses_plugin_config_t config = {
71 .spc_node_parse = smc60_parse_node
72 };
73
74 return (ses_plugin_register(sp, LIBSES_PLUGIN_VERSION, &config) != 0);
75 }