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 }