1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <scsi/libses.h> 28 #include <scsi/libses_plugin.h> 29 #include <string.h> 30 #include <strings.h> 31 32 #include "ses2_impl.h" 33 34 /* 35 * Given an nvlist of properties and an array of property handlers, invoke the 36 * appropriate handler for all supported properties. 37 */ 38 int 39 ses2_setprop(ses_plugin_t *sp, ses_node_t *np, 40 const ses2_ctl_prop_t *ctlprops, nvlist_t *props) 41 { 42 const ses2_ctl_prop_t *cpp; 43 nvpair_t *nvp, *next; 44 45 for (nvp = nvlist_next_nvpair(props, NULL); nvp != NULL; 46 nvp = next) { 47 next = nvlist_next_nvpair(props, nvp); 48 for (cpp = ctlprops; cpp->scp_name != NULL; cpp++) 49 if (strcmp(cpp->scp_name, nvpair_name(nvp)) == 0) 50 break; 51 if (cpp->scp_name == NULL) 52 continue; 53 54 if (cpp->scp_setprop(sp, np, cpp->scp_num, nvp) != 0) 55 return (-1); 56 57 (void) nvlist_remove(props, nvpair_name(nvp), 58 nvpair_type(nvp)); 59 } 60 61 return (0); 62 } 63 64 int 65 ses2_ctl_common_setprop(ses_plugin_t *sp, ses_node_t *np, ses2_diag_page_t page, 66 nvpair_t *nvp) 67 { 68 ses2_cmn_elem_ctl_impl_t *eip; 69 const char *name; 70 boolean_t v; 71 72 ASSERT(page == SES2_DIAGPAGE_ENCLOSURE_CTL_STATUS); 73 74 if ((eip = ses_plugin_ctlpage_lookup(sp, ses_node_snapshot(np), 75 page, 0, np, B_FALSE)) == NULL) 76 return (-1); 77 78 name = nvpair_name(nvp); 79 (void) nvpair_value_boolean_value(nvp, &v); 80 81 if (strcmp(name, SES_PROP_SWAP) == 0) 82 eip->seci_rst_swap = !v; 83 else if (strcmp(name, SES_PROP_DISABLED) == 0) 84 eip->seci_disable = v; 85 else if (strcmp(name, SES_PROP_PRDFAIL) == 0) 86 eip->seci_prdfail = v; 87 else 88 ses_panic("Bad property %s", name); 89 90 return (0); 91 } 92 93 static int 94 ses2_node_parse(ses_plugin_t *sp, ses_node_t *np) 95 { 96 switch (ses_node_type(np)) { 97 case SES_NODE_ENCLOSURE: 98 return (ses2_fill_enclosure_node(sp, np)); 99 100 case SES_NODE_AGGREGATE: 101 case SES_NODE_ELEMENT: 102 return (ses2_fill_element_node(sp, np)); 103 104 default: 105 return (0); 106 } 107 } 108 109 static int 110 ses2_node_ctl(ses_plugin_t *sp, ses_node_t *np, const char *op, 111 nvlist_t *nvl) 112 { 113 switch (ses_node_type(np)) { 114 case SES_NODE_ENCLOSURE: 115 return (ses2_enclosure_ctl(sp, np, op, nvl)); 116 117 case SES_NODE_AGGREGATE: 118 case SES_NODE_ELEMENT: 119 return (ses2_element_ctl(sp, np, op, nvl)); 120 } 121 122 return (0); 123 } 124 125 int 126 _ses_init(ses_plugin_t *sp) 127 { 128 ses_plugin_config_t config = { 129 .spc_pages = ses2_pages, 130 .spc_node_parse = ses2_node_parse, 131 .spc_node_ctl = ses2_node_ctl 132 }; 133 134 return (ses_plugin_register(sp, LIBSES_PLUGIN_VERSION, 135 &config) != 0); 136 } 137