1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM *
4*7836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM *
8*7836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM * and limitations under the License.
12*7836SJohn.Forte@Sun.COM *
13*7836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM *
19*7836SJohn.Forte@Sun.COM * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM */
21*7836SJohn.Forte@Sun.COM /*
22*7836SJohn.Forte@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23*7836SJohn.Forte@Sun.COM * Use is subject to license terms.
24*7836SJohn.Forte@Sun.COM */
25*7836SJohn.Forte@Sun.COM
26*7836SJohn.Forte@Sun.COM
27*7836SJohn.Forte@Sun.COM
28*7836SJohn.Forte@Sun.COM
29*7836SJohn.Forte@Sun.COM #include "cfga_fp.h"
30*7836SJohn.Forte@Sun.COM
31*7836SJohn.Forte@Sun.COM /*
32*7836SJohn.Forte@Sun.COM * This file contains the entry points to the plug-in as defined in the
33*7836SJohn.Forte@Sun.COM * config_admin(3X) man page.
34*7836SJohn.Forte@Sun.COM */
35*7836SJohn.Forte@Sun.COM
36*7836SJohn.Forte@Sun.COM /*
37*7836SJohn.Forte@Sun.COM * Set the version number
38*7836SJohn.Forte@Sun.COM */
39*7836SJohn.Forte@Sun.COM int cfga_version = CFGA_HSL_V2;
40*7836SJohn.Forte@Sun.COM
41*7836SJohn.Forte@Sun.COM /*ARGSUSED*/
42*7836SJohn.Forte@Sun.COM cfga_err_t
cfga_change_state(cfga_cmd_t state_change_cmd,const char * ap_id,const char * options,struct cfga_confirm * confp,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)43*7836SJohn.Forte@Sun.COM cfga_change_state(
44*7836SJohn.Forte@Sun.COM cfga_cmd_t state_change_cmd,
45*7836SJohn.Forte@Sun.COM const char *ap_id,
46*7836SJohn.Forte@Sun.COM const char *options,
47*7836SJohn.Forte@Sun.COM struct cfga_confirm *confp,
48*7836SJohn.Forte@Sun.COM struct cfga_msg *msgp,
49*7836SJohn.Forte@Sun.COM char **errstring,
50*7836SJohn.Forte@Sun.COM cfga_flags_t flags)
51*7836SJohn.Forte@Sun.COM {
52*7836SJohn.Forte@Sun.COM apid_t apidt = {NULL};
53*7836SJohn.Forte@Sun.COM fpcfga_ret_t ret;
54*7836SJohn.Forte@Sun.COM la_wwn_t pwwn;
55*7836SJohn.Forte@Sun.COM char *value, *hw_option, *hw_option_p;
56*7836SJohn.Forte@Sun.COM char *fp_cs_hw_opts[] = {"disable_rcm", "force_update",
57*7836SJohn.Forte@Sun.COM "no_update", "unusable_SCSI_LUN", "unusable_FCP_dev", NULL};
58*7836SJohn.Forte@Sun.COM HBA_HANDLE handle;
59*7836SJohn.Forte@Sun.COM HBA_PORTATTRIBUTES portAttrs;
60*7836SJohn.Forte@Sun.COM int portIndex;
61*7836SJohn.Forte@Sun.COM
62*7836SJohn.Forte@Sun.COM if (errstring != NULL) {
63*7836SJohn.Forte@Sun.COM *errstring = NULL;
64*7836SJohn.Forte@Sun.COM }
65*7836SJohn.Forte@Sun.COM
66*7836SJohn.Forte@Sun.COM /* Check for super user priveleges */
67*7836SJohn.Forte@Sun.COM if (geteuid() != 0) {
68*7836SJohn.Forte@Sun.COM return (CFGA_PRIV);
69*7836SJohn.Forte@Sun.COM }
70*7836SJohn.Forte@Sun.COM
71*7836SJohn.Forte@Sun.COM /* Only configure and unconfigure operations are supported */
72*7836SJohn.Forte@Sun.COM if (state_change_cmd != CFGA_CMD_CONFIGURE &&
73*7836SJohn.Forte@Sun.COM state_change_cmd != CFGA_CMD_UNCONFIGURE) {
74*7836SJohn.Forte@Sun.COM return (CFGA_OPNOTSUPP);
75*7836SJohn.Forte@Sun.COM }
76*7836SJohn.Forte@Sun.COM
77*7836SJohn.Forte@Sun.COM if ((ret = apidt_create(ap_id, &apidt, errstring)) != CFGA_OK) {
78*7836SJohn.Forte@Sun.COM return (err_cvt(ret));
79*7836SJohn.Forte@Sun.COM }
80*7836SJohn.Forte@Sun.COM
81*7836SJohn.Forte@Sun.COM if (options != NULL) {
82*7836SJohn.Forte@Sun.COM hw_option = calloc(1, strlen(options) + 1);
83*7836SJohn.Forte@Sun.COM (void) snprintf(hw_option, strlen(options) + 1, "%s", options);
84*7836SJohn.Forte@Sun.COM hw_option_p = hw_option;
85*7836SJohn.Forte@Sun.COM /* Use getsubopt() if more options get added */
86*7836SJohn.Forte@Sun.COM while (*hw_option_p != '\0') {
87*7836SJohn.Forte@Sun.COM switch (getsubopt(&hw_option_p, fp_cs_hw_opts, &value)) {
88*7836SJohn.Forte@Sun.COM case OPT_DISABLE_RCM :
89*7836SJohn.Forte@Sun.COM apidt.flags |= FLAG_DISABLE_RCM;
90*7836SJohn.Forte@Sun.COM break;
91*7836SJohn.Forte@Sun.COM case OPT_FORCE_UPDATE_REP :
92*7836SJohn.Forte@Sun.COM apidt.flags |= FLAG_FORCE_UPDATE_REP;
93*7836SJohn.Forte@Sun.COM break;
94*7836SJohn.Forte@Sun.COM case OPT_NO_UPDATE_REP :
95*7836SJohn.Forte@Sun.COM apidt.flags |= FLAG_NO_UPDATE_REP;
96*7836SJohn.Forte@Sun.COM break;
97*7836SJohn.Forte@Sun.COM case OPT_REMOVE_UNUSABLE_FCP_DEV :
98*7836SJohn.Forte@Sun.COM case OPT_REMOVE_UNUSABLE_SCSI_LUN:
99*7836SJohn.Forte@Sun.COM if (state_change_cmd != CFGA_CMD_UNCONFIGURE) {
100*7836SJohn.Forte@Sun.COM cfga_err(errstring, 0, ERRARG_OPT_INVAL,
101*7836SJohn.Forte@Sun.COM options, 0);
102*7836SJohn.Forte@Sun.COM S_FREE(hw_option);
103*7836SJohn.Forte@Sun.COM apidt_free(&apidt);
104*7836SJohn.Forte@Sun.COM return (CFGA_ERROR);
105*7836SJohn.Forte@Sun.COM }
106*7836SJohn.Forte@Sun.COM apidt.flags |= FLAG_REMOVE_UNUSABLE_FCP_DEV;
107*7836SJohn.Forte@Sun.COM break;
108*7836SJohn.Forte@Sun.COM default :
109*7836SJohn.Forte@Sun.COM /* process unknonw option. */
110*7836SJohn.Forte@Sun.COM cfga_err(errstring, 0, ERRARG_OPT_INVAL,
111*7836SJohn.Forte@Sun.COM options, 0);
112*7836SJohn.Forte@Sun.COM S_FREE(hw_option);
113*7836SJohn.Forte@Sun.COM apidt_free(&apidt);
114*7836SJohn.Forte@Sun.COM return (CFGA_ERROR);
115*7836SJohn.Forte@Sun.COM }
116*7836SJohn.Forte@Sun.COM }
117*7836SJohn.Forte@Sun.COM S_FREE(hw_option);
118*7836SJohn.Forte@Sun.COM }
119*7836SJohn.Forte@Sun.COM
120*7836SJohn.Forte@Sun.COM if (options != NULL && apidt.flags == 0) {
121*7836SJohn.Forte@Sun.COM /* invalid option specified. */
122*7836SJohn.Forte@Sun.COM cfga_err(errstring, 0, ERRARG_OPT_INVAL, options, 0);
123*7836SJohn.Forte@Sun.COM apidt_free(&apidt);
124*7836SJohn.Forte@Sun.COM return (CFGA_ERROR);
125*7836SJohn.Forte@Sun.COM }
126*7836SJohn.Forte@Sun.COM
127*7836SJohn.Forte@Sun.COM if (apidt.dyncomp != NULL) { /* Was there a port WWN passed ? */
128*7836SJohn.Forte@Sun.COM /*
129*7836SJohn.Forte@Sun.COM * Yes - so change state of the particular device
130*7836SJohn.Forte@Sun.COM *
131*7836SJohn.Forte@Sun.COM * First Get the WWN in la_wwn_t form
132*7836SJohn.Forte@Sun.COM */
133*7836SJohn.Forte@Sun.COM if (cvt_dyncomp_to_lawwn(apidt.dyncomp, &pwwn)) {
134*7836SJohn.Forte@Sun.COM cfga_err(errstring, 0, ERR_APID_INVAL, 0);
135*7836SJohn.Forte@Sun.COM return (err_cvt(FPCFGA_LIB_ERR));
136*7836SJohn.Forte@Sun.COM }
137*7836SJohn.Forte@Sun.COM
138*7836SJohn.Forte@Sun.COM if ((ret = findMatchingAdapterPort(apidt.xport_phys,
139*7836SJohn.Forte@Sun.COM &handle, &portIndex, &portAttrs, errstring)) ==
140*7836SJohn.Forte@Sun.COM FPCFGA_OK) {
141*7836SJohn.Forte@Sun.COM ret = dev_change_state(state_change_cmd, &apidt, &pwwn,
142*7836SJohn.Forte@Sun.COM flags, errstring, handle, portAttrs);
143*7836SJohn.Forte@Sun.COM HBA_CloseAdapter(handle);
144*7836SJohn.Forte@Sun.COM HBA_FreeLibrary();
145*7836SJohn.Forte@Sun.COM }
146*7836SJohn.Forte@Sun.COM } else {
147*7836SJohn.Forte@Sun.COM /* Change state of all devices on FCA and the FCA itself */
148*7836SJohn.Forte@Sun.COM ret = fca_change_state(state_change_cmd, &apidt,
149*7836SJohn.Forte@Sun.COM flags, errstring);
150*7836SJohn.Forte@Sun.COM }
151*7836SJohn.Forte@Sun.COM
152*7836SJohn.Forte@Sun.COM apidt_free(&apidt);
153*7836SJohn.Forte@Sun.COM return (err_cvt(ret));
154*7836SJohn.Forte@Sun.COM }
155*7836SJohn.Forte@Sun.COM
156*7836SJohn.Forte@Sun.COM
157*7836SJohn.Forte@Sun.COM /*ARGSUSED*/
158*7836SJohn.Forte@Sun.COM cfga_err_t
cfga_private_func(const char * func,const char * ap_id,const char * options,struct cfga_confirm * confp,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)159*7836SJohn.Forte@Sun.COM cfga_private_func(
160*7836SJohn.Forte@Sun.COM const char *func,
161*7836SJohn.Forte@Sun.COM const char *ap_id,
162*7836SJohn.Forte@Sun.COM const char *options,
163*7836SJohn.Forte@Sun.COM struct cfga_confirm *confp,
164*7836SJohn.Forte@Sun.COM struct cfga_msg *msgp,
165*7836SJohn.Forte@Sun.COM char **errstring,
166*7836SJohn.Forte@Sun.COM cfga_flags_t flags)
167*7836SJohn.Forte@Sun.COM {
168*7836SJohn.Forte@Sun.COM if (errstring != NULL) {
169*7836SJohn.Forte@Sun.COM *errstring = NULL;
170*7836SJohn.Forte@Sun.COM }
171*7836SJohn.Forte@Sun.COM
172*7836SJohn.Forte@Sun.COM if (geteuid() != 0) {
173*7836SJohn.Forte@Sun.COM return (CFGA_PRIV);
174*7836SJohn.Forte@Sun.COM }
175*7836SJohn.Forte@Sun.COM
176*7836SJohn.Forte@Sun.COM return (CFGA_OPNOTSUPP);
177*7836SJohn.Forte@Sun.COM }
178*7836SJohn.Forte@Sun.COM
179*7836SJohn.Forte@Sun.COM
180*7836SJohn.Forte@Sun.COM /*ARGSUSED*/
181*7836SJohn.Forte@Sun.COM cfga_err_t
cfga_test(const char * ap_id,const char * options,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)182*7836SJohn.Forte@Sun.COM cfga_test(
183*7836SJohn.Forte@Sun.COM const char *ap_id,
184*7836SJohn.Forte@Sun.COM const char *options,
185*7836SJohn.Forte@Sun.COM struct cfga_msg *msgp,
186*7836SJohn.Forte@Sun.COM char **errstring,
187*7836SJohn.Forte@Sun.COM cfga_flags_t flags)
188*7836SJohn.Forte@Sun.COM {
189*7836SJohn.Forte@Sun.COM if (errstring != NULL) {
190*7836SJohn.Forte@Sun.COM *errstring = NULL;
191*7836SJohn.Forte@Sun.COM }
192*7836SJohn.Forte@Sun.COM
193*7836SJohn.Forte@Sun.COM if (geteuid() != 0) {
194*7836SJohn.Forte@Sun.COM return (CFGA_PRIV);
195*7836SJohn.Forte@Sun.COM }
196*7836SJohn.Forte@Sun.COM
197*7836SJohn.Forte@Sun.COM return (CFGA_OPNOTSUPP);
198*7836SJohn.Forte@Sun.COM }
199*7836SJohn.Forte@Sun.COM
200*7836SJohn.Forte@Sun.COM
201*7836SJohn.Forte@Sun.COM /*ARGSUSED*/
202*7836SJohn.Forte@Sun.COM cfga_err_t
cfga_list_ext(const char * ap_id,cfga_list_data_t ** ap_id_list,int * nlistp,const char * options,const char * listopts,char ** errstring,cfga_flags_t flags)203*7836SJohn.Forte@Sun.COM cfga_list_ext(
204*7836SJohn.Forte@Sun.COM const char *ap_id,
205*7836SJohn.Forte@Sun.COM cfga_list_data_t **ap_id_list,
206*7836SJohn.Forte@Sun.COM int *nlistp,
207*7836SJohn.Forte@Sun.COM const char *options,
208*7836SJohn.Forte@Sun.COM const char *listopts,
209*7836SJohn.Forte@Sun.COM char **errstring,
210*7836SJohn.Forte@Sun.COM cfga_flags_t flags)
211*7836SJohn.Forte@Sun.COM {
212*7836SJohn.Forte@Sun.COM int fca, expand, nelem;
213*7836SJohn.Forte@Sun.COM ldata_list_t *ldatalistp = NULL;
214*7836SJohn.Forte@Sun.COM apid_t apidt = {NULL};
215*7836SJohn.Forte@Sun.COM fpcfga_cmd_t cmd;
216*7836SJohn.Forte@Sun.COM fpcfga_ret_t ret;
217*7836SJohn.Forte@Sun.COM char *value, *hw_option, *hw_option_p;
218*7836SJohn.Forte@Sun.COM uint_t fp_flags = 0;
219*7836SJohn.Forte@Sun.COM char *fp_list_hw_opts[] = {"devinfo_force", "show_SCSI_LUN",
220*7836SJohn.Forte@Sun.COM "show_FCP_dev", NULL};
221*7836SJohn.Forte@Sun.COM
222*7836SJohn.Forte@Sun.COM if (errstring != NULL) {
223*7836SJohn.Forte@Sun.COM *errstring = NULL;
224*7836SJohn.Forte@Sun.COM }
225*7836SJohn.Forte@Sun.COM
226*7836SJohn.Forte@Sun.COM /* Check for super user privileges */
227*7836SJohn.Forte@Sun.COM if (geteuid() != 0) {
228*7836SJohn.Forte@Sun.COM return (CFGA_PRIV);
229*7836SJohn.Forte@Sun.COM }
230*7836SJohn.Forte@Sun.COM
231*7836SJohn.Forte@Sun.COM if (ap_id_list == NULL || nlistp == NULL) {
232*7836SJohn.Forte@Sun.COM return (CFGA_ERROR);
233*7836SJohn.Forte@Sun.COM }
234*7836SJohn.Forte@Sun.COM
235*7836SJohn.Forte@Sun.COM *ap_id_list = NULL;
236*7836SJohn.Forte@Sun.COM *nlistp = 0;
237*7836SJohn.Forte@Sun.COM
238*7836SJohn.Forte@Sun.COM if (options != NULL) {
239*7836SJohn.Forte@Sun.COM hw_option = calloc(1, strlen(options) + 1);
240*7836SJohn.Forte@Sun.COM (void) snprintf(hw_option, strlen(options) + 1, "%s", options);
241*7836SJohn.Forte@Sun.COM hw_option_p = hw_option;
242*7836SJohn.Forte@Sun.COM /* Use getsubopt() if more options get added */
243*7836SJohn.Forte@Sun.COM while (*hw_option_p != '\0') {
244*7836SJohn.Forte@Sun.COM switch (getsubopt(&hw_option_p, fp_list_hw_opts, &value)) {
245*7836SJohn.Forte@Sun.COM case OPT_DEVINFO_FORCE :
246*7836SJohn.Forte@Sun.COM fp_flags |= FLAG_DEVINFO_FORCE;
247*7836SJohn.Forte@Sun.COM break;
248*7836SJohn.Forte@Sun.COM case OPT_FCP_DEV :
249*7836SJohn.Forte@Sun.COM case OPT_SHOW_SCSI_LUN:
250*7836SJohn.Forte@Sun.COM fp_flags |= FLAG_FCP_DEV;
251*7836SJohn.Forte@Sun.COM break;
252*7836SJohn.Forte@Sun.COM default :
253*7836SJohn.Forte@Sun.COM /* process unknonw option. */
254*7836SJohn.Forte@Sun.COM cfga_err(errstring, 0, ERRARG_OPT_INVAL,
255*7836SJohn.Forte@Sun.COM options, 0);
256*7836SJohn.Forte@Sun.COM S_FREE(hw_option);
257*7836SJohn.Forte@Sun.COM return (CFGA_ERROR);
258*7836SJohn.Forte@Sun.COM }
259*7836SJohn.Forte@Sun.COM }
260*7836SJohn.Forte@Sun.COM S_FREE(hw_option);
261*7836SJohn.Forte@Sun.COM }
262*7836SJohn.Forte@Sun.COM
263*7836SJohn.Forte@Sun.COM /* if force_devinfo is specified check uid = 0 or not. */
264*7836SJohn.Forte@Sun.COM if (((fp_flags & FLAG_DEVINFO_FORCE) == FLAG_DEVINFO_FORCE) &&
265*7836SJohn.Forte@Sun.COM (geteuid() != 0)) {
266*7836SJohn.Forte@Sun.COM return (CFGA_PRIV);
267*7836SJohn.Forte@Sun.COM }
268*7836SJohn.Forte@Sun.COM
269*7836SJohn.Forte@Sun.COM fca = 0;
270*7836SJohn.Forte@Sun.COM if (GET_DYN(ap_id) == NULL) {
271*7836SJohn.Forte@Sun.COM fca = 1;
272*7836SJohn.Forte@Sun.COM }
273*7836SJohn.Forte@Sun.COM
274*7836SJohn.Forte@Sun.COM expand = 0;
275*7836SJohn.Forte@Sun.COM if ((flags & CFGA_FLAG_LIST_ALL) == CFGA_FLAG_LIST_ALL) {
276*7836SJohn.Forte@Sun.COM expand = 1;
277*7836SJohn.Forte@Sun.COM }
278*7836SJohn.Forte@Sun.COM
279*7836SJohn.Forte@Sun.COM /*
280*7836SJohn.Forte@Sun.COM * We expand published attachment points but not
281*7836SJohn.Forte@Sun.COM * dynamic attachment points
282*7836SJohn.Forte@Sun.COM */
283*7836SJohn.Forte@Sun.COM
284*7836SJohn.Forte@Sun.COM if (!fca) { /* Stat a single device - no expansion for devices */
285*7836SJohn.Forte@Sun.COM cmd = FPCFGA_STAT_FC_DEV;
286*7836SJohn.Forte@Sun.COM } else if (!expand) { /* Stat only the HBA */
287*7836SJohn.Forte@Sun.COM cmd = FPCFGA_STAT_FCA_PORT;
288*7836SJohn.Forte@Sun.COM } else { /* Expand HBA attachment point */
289*7836SJohn.Forte@Sun.COM cmd = FPCFGA_STAT_ALL;
290*7836SJohn.Forte@Sun.COM }
291*7836SJohn.Forte@Sun.COM
292*7836SJohn.Forte@Sun.COM ldatalistp = NULL;
293*7836SJohn.Forte@Sun.COM nelem = 0;
294*7836SJohn.Forte@Sun.COM
295*7836SJohn.Forte@Sun.COM if ((fp_flags & FLAG_FCP_DEV) == FLAG_FCP_DEV) {
296*7836SJohn.Forte@Sun.COM ret = do_list_FCP_dev(ap_id, fp_flags, cmd, &ldatalistp, &nelem,
297*7836SJohn.Forte@Sun.COM errstring);
298*7836SJohn.Forte@Sun.COM if (ret != FPCFGA_OK) {
299*7836SJohn.Forte@Sun.COM list_free(&ldatalistp);
300*7836SJohn.Forte@Sun.COM return (err_cvt(ret));
301*7836SJohn.Forte@Sun.COM }
302*7836SJohn.Forte@Sun.COM } else {
303*7836SJohn.Forte@Sun.COM if ((ret = apidt_create(ap_id, &apidt, errstring))
304*7836SJohn.Forte@Sun.COM != FPCFGA_OK) {
305*7836SJohn.Forte@Sun.COM return (err_cvt(ret));
306*7836SJohn.Forte@Sun.COM }
307*7836SJohn.Forte@Sun.COM
308*7836SJohn.Forte@Sun.COM if (options != NULL) {
309*7836SJohn.Forte@Sun.COM apidt.flags |= fp_flags;
310*7836SJohn.Forte@Sun.COM }
311*7836SJohn.Forte@Sun.COM
312*7836SJohn.Forte@Sun.COM ret = do_list(&apidt, cmd, &ldatalistp, &nelem, errstring);
313*7836SJohn.Forte@Sun.COM if (ret != FPCFGA_OK) {
314*7836SJohn.Forte@Sun.COM list_free(&ldatalistp);
315*7836SJohn.Forte@Sun.COM apidt_free(&apidt);
316*7836SJohn.Forte@Sun.COM return (err_cvt(ret));
317*7836SJohn.Forte@Sun.COM }
318*7836SJohn.Forte@Sun.COM apidt_free(&apidt);
319*7836SJohn.Forte@Sun.COM }
320*7836SJohn.Forte@Sun.COM
321*7836SJohn.Forte@Sun.COM assert(ldatalistp != NULL);
322*7836SJohn.Forte@Sun.COM
323*7836SJohn.Forte@Sun.COM if (list_ext_postprocess(&ldatalistp, nelem, ap_id_list, nlistp,
324*7836SJohn.Forte@Sun.COM errstring) != FPCFGA_OK) {
325*7836SJohn.Forte@Sun.COM assert(*ap_id_list == NULL && *nlistp == 0);
326*7836SJohn.Forte@Sun.COM ret = FPCFGA_LIB_ERR;
327*7836SJohn.Forte@Sun.COM } else {
328*7836SJohn.Forte@Sun.COM assert(*ap_id_list != NULL && *nlistp == nelem);
329*7836SJohn.Forte@Sun.COM ret = FPCFGA_OK;
330*7836SJohn.Forte@Sun.COM }
331*7836SJohn.Forte@Sun.COM
332*7836SJohn.Forte@Sun.COM list_free(&ldatalistp);
333*7836SJohn.Forte@Sun.COM return (err_cvt(ret));
334*7836SJohn.Forte@Sun.COM }
335*7836SJohn.Forte@Sun.COM
336*7836SJohn.Forte@Sun.COM
337*7836SJohn.Forte@Sun.COM /*ARGSUSED*/
338*7836SJohn.Forte@Sun.COM cfga_err_t
cfga_help(struct cfga_msg * msgp,const char * options,cfga_flags_t flags)339*7836SJohn.Forte@Sun.COM cfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
340*7836SJohn.Forte@Sun.COM {
341*7836SJohn.Forte@Sun.COM cfga_msg(msgp, MSG_HELP_HDR, MSG_HELP_USAGE, 0);
342*7836SJohn.Forte@Sun.COM
343*7836SJohn.Forte@Sun.COM return (CFGA_OK);
344*7836SJohn.Forte@Sun.COM
345*7836SJohn.Forte@Sun.COM }
346*7836SJohn.Forte@Sun.COM
347*7836SJohn.Forte@Sun.COM /*ARGSUSED*/
348*7836SJohn.Forte@Sun.COM int
cfga_ap_id_cmp(const char * ap_id1,const char * ap_id2)349*7836SJohn.Forte@Sun.COM cfga_ap_id_cmp(const char *ap_id1, const char *ap_id2)
350*7836SJohn.Forte@Sun.COM {
351*7836SJohn.Forte@Sun.COM int i = 0;
352*7836SJohn.Forte@Sun.COM long long ret;
353*7836SJohn.Forte@Sun.COM
354*7836SJohn.Forte@Sun.COM if (ap_id1 == ap_id2) {
355*7836SJohn.Forte@Sun.COM return (0);
356*7836SJohn.Forte@Sun.COM }
357*7836SJohn.Forte@Sun.COM
358*7836SJohn.Forte@Sun.COM if (ap_id1 == NULL || ap_id2 == NULL) {
359*7836SJohn.Forte@Sun.COM if (ap_id1 == NULL) {
360*7836SJohn.Forte@Sun.COM /* Return a negative value */
361*7836SJohn.Forte@Sun.COM return (0 - (uchar_t)ap_id2[0]);
362*7836SJohn.Forte@Sun.COM } else {
363*7836SJohn.Forte@Sun.COM return ((uchar_t)ap_id1[0]);
364*7836SJohn.Forte@Sun.COM }
365*7836SJohn.Forte@Sun.COM }
366*7836SJohn.Forte@Sun.COM
367*7836SJohn.Forte@Sun.COM /*
368*7836SJohn.Forte@Sun.COM * Search for first different char
369*7836SJohn.Forte@Sun.COM */
370*7836SJohn.Forte@Sun.COM while (ap_id1[i] == ap_id2[i] && ap_id1[i] != '\0')
371*7836SJohn.Forte@Sun.COM i++;
372*7836SJohn.Forte@Sun.COM
373*7836SJohn.Forte@Sun.COM if ((ap_id1[i] == '\0') &&
374*7836SJohn.Forte@Sun.COM !(strncmp(&ap_id2[i], LUN_COMP_SEP, strlen(LUN_COMP_SEP)))) {
375*7836SJohn.Forte@Sun.COM return (0);
376*7836SJohn.Forte@Sun.COM } else if ((ap_id2[i] == '\0') &&
377*7836SJohn.Forte@Sun.COM !(strncmp(&ap_id1[i], LUN_COMP_SEP, strlen(LUN_COMP_SEP)))) {
378*7836SJohn.Forte@Sun.COM return (0);
379*7836SJohn.Forte@Sun.COM }
380*7836SJohn.Forte@Sun.COM
381*7836SJohn.Forte@Sun.COM /*
382*7836SJohn.Forte@Sun.COM * If one of the char is a digit, back up to where the
383*7836SJohn.Forte@Sun.COM * number started, compare the number.
384*7836SJohn.Forte@Sun.COM */
385*7836SJohn.Forte@Sun.COM if (isxdigit(ap_id1[i]) || isxdigit(ap_id2[i])) {
386*7836SJohn.Forte@Sun.COM while ((i > 0) && isxdigit(ap_id1[i - 1]))
387*7836SJohn.Forte@Sun.COM i--;
388*7836SJohn.Forte@Sun.COM
389*7836SJohn.Forte@Sun.COM if (isxdigit(ap_id1[i]) && isxdigit(ap_id2[i])) {
390*7836SJohn.Forte@Sun.COM ret = (strtoll((ap_id1 + i), NULL, 16)) -
391*7836SJohn.Forte@Sun.COM (strtoll((ap_id2 + i), NULL, 16));
392*7836SJohn.Forte@Sun.COM if (ret > 0) {
393*7836SJohn.Forte@Sun.COM return (1);
394*7836SJohn.Forte@Sun.COM } else if (ret < 0) {
395*7836SJohn.Forte@Sun.COM return (-1);
396*7836SJohn.Forte@Sun.COM } else {
397*7836SJohn.Forte@Sun.COM return (0);
398*7836SJohn.Forte@Sun.COM }
399*7836SJohn.Forte@Sun.COM }
400*7836SJohn.Forte@Sun.COM }
401*7836SJohn.Forte@Sun.COM
402*7836SJohn.Forte@Sun.COM /* One of them isn't a number, compare the char */
403*7836SJohn.Forte@Sun.COM return (ap_id1[i] - ap_id2[i]);
404*7836SJohn.Forte@Sun.COM }
405