8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / cfgadm_plugins / scsi / common / cfga_rcm.c
blobf65867f4ba21554f36941208b79d02f8f4e326c1
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include "cfga_scsi.h"
28 #define MAX_FORMAT 80
30 static scfga_ret_t scsi_rcm_info_table(rcm_info_t *, char **);
31 static scfga_ret_t scsi_rcm_init(uint_t, char **, rcm_handle_t **);
34 * scsi_rcm_offline()
36 * Offline SCSI resource consumers.
38 scfga_ret_t
39 scsi_rcm_offline(char **rsrclist, char **errstring, cfga_flags_t flags)
41 int rret;
42 uint_t rflags = 0;
43 rcm_info_t *rinfo = NULL;
44 scfga_ret_t ret = SCFGA_OK;
45 rcm_handle_t *rcm_handle;
47 if (rsrclist == NULL)
48 return (ret);
50 if ((ret = scsi_rcm_init(0, errstring, &rcm_handle))
51 != SCFGA_OK)
52 return (ret);
54 if (flags & CFGA_FLAG_FORCE)
55 rflags = RCM_FORCE;
57 if ((rret = rcm_request_offline_list(rcm_handle, rsrclist, rflags,
58 &rinfo)) != RCM_SUCCESS) {
59 if ((flags & FLAG_CLIENT_DEV) == FLAG_CLIENT_DEV) {
60 cfga_err(errstring, 0, ERRARG_RCM_CLIENT_OFFLINE, 0);
61 } else {
62 cfga_err(errstring, 0, ERRARG_RCM_OFFLINE, 0);
64 if (rinfo) {
65 (void) scsi_rcm_info_table(rinfo, errstring);
66 rcm_free_info(rinfo);
68 if (rret == RCM_FAILURE)
69 (void) rcm_notify_online_list(rcm_handle, rsrclist,
70 rflags & ~RCM_FORCE, NULL);
71 ret = SCFGA_BUSY;
73 (void) rcm_free_handle(rcm_handle);
74 return (ret);
78 * scsi_rcm_online()
80 * Online SCSI resource consumers that were previously offlined.
82 /*ARGSUSED2*/
83 scfga_ret_t
84 scsi_rcm_online(char **rsrclist, char **errstring, cfga_flags_t flags)
86 rcm_info_t *rinfo = NULL;
87 scfga_ret_t ret = SCFGA_OK;
88 rcm_handle_t *rcm_handle;
90 if (rsrclist == NULL)
91 return (ret);
93 if ((ret = scsi_rcm_init(0, errstring, &rcm_handle))
94 != SCFGA_OK)
95 return (ret);
97 if (rcm_notify_online_list(rcm_handle, rsrclist, 0, &rinfo)
98 != RCM_SUCCESS) {
99 cfga_err(errstring, 0, ERRARG_RCM_ONLINE, 0);
100 if (rinfo != NULL) {
101 (void) scsi_rcm_info_table(rinfo, errstring);
102 rcm_free_info(rinfo);
104 ret = SCFGA_BUSY;
106 (void) rcm_free_handle(rcm_handle);
107 return (ret);
111 * scsi_rcm_remove()
113 * Remove SCSI resource consumers after their kernel removal.
115 /*ARGSUSED2*/
116 scfga_ret_t
117 scsi_rcm_remove(char **rsrclist, char **errstring, cfga_flags_t flags)
119 rcm_info_t *rinfo = NULL;
120 scfga_ret_t ret = SCFGA_OK;
121 rcm_handle_t *rcm_handle;
123 if (rsrclist == NULL)
124 return (ret);
126 if ((ret = scsi_rcm_init(0, errstring, &rcm_handle))
127 != SCFGA_OK)
128 return (ret);
130 if (rcm_notify_remove_list(rcm_handle, rsrclist, 0, &rinfo)
131 != RCM_SUCCESS) {
132 cfga_err(errstring, 0, ERRARG_RCM_REMOVE, 0);
133 if (rinfo) {
134 (void) scsi_rcm_info_table(rinfo, errstring);
135 rcm_free_info(rinfo);
137 ret = SCFGA_BUSY;
140 (void) rcm_free_handle(rcm_handle);
141 return (ret);
145 * scsi_rcm_suspend()
147 * Suspend SCSI resource consumers before a bus quiesce.
149 scfga_ret_t
150 scsi_rcm_suspend(char **rsrclist, char **errstring, cfga_flags_t flags,
151 int pflag)
153 int rret;
154 uint_t rflags = 0;
155 rcm_info_t *rinfo = NULL;
156 scfga_ret_t ret = SCFGA_OK;
157 rcm_handle_t *rcm_handle;
158 timespec_t zerotime = { 0, 0 };
160 if (rsrclist == NULL)
161 return (ret);
163 pflag = pflag ? RCM_NOPID : 0;
164 if ((ret = scsi_rcm_init(pflag, errstring, &rcm_handle))
165 != SCFGA_OK)
166 return (ret);
168 if (flags & CFGA_FLAG_FORCE)
169 rflags = RCM_FORCE;
172 * attempt a suspension on a list of resources
174 if ((rret = rcm_request_suspend_list(rcm_handle, rsrclist, rflags,
175 &zerotime, &rinfo)) != RCM_SUCCESS) {
176 cfga_err(errstring, 0, ERRARG_RCM_SUSPEND, 0);
177 if (rinfo) {
178 (void) scsi_rcm_info_table(rinfo, errstring);
179 rcm_free_info(rinfo);
181 if (rret == RCM_FAILURE)
182 (void) rcm_notify_resume_list(rcm_handle, rsrclist,
183 (rflags & (~RCM_FORCE)), NULL);
184 ret = SCFGA_BUSY;
186 (void) rcm_free_handle(rcm_handle);
187 return (ret);
191 * scsi_rcm_resume()
193 * Resume SCSI resource consumers after a bus has been unquiesced.
195 /*ARGSUSED2*/
196 scfga_ret_t
197 scsi_rcm_resume(char **rsrclist, char **errstring, cfga_flags_t flags,
198 int pflag)
200 rcm_info_t *rinfo = NULL;
201 scfga_ret_t ret = SCFGA_OK;
202 rcm_handle_t *rcm_handle;
204 if (rsrclist == NULL)
205 return (ret);
207 pflag = pflag ? RCM_NOPID : 0;
208 if ((ret = scsi_rcm_init(pflag, errstring, &rcm_handle))
209 != SCFGA_OK)
210 return (ret);
213 * resume the resource list.
215 if (rcm_notify_resume_list(rcm_handle, rsrclist, 0, &rinfo)
216 != RCM_SUCCESS) {
217 cfga_err(errstring, 0, ERRARG_RCM_RESUME, 0);
218 if (rinfo != NULL) {
219 (void) scsi_rcm_info_table(rinfo, errstring);
220 rcm_free_info(rinfo);
222 ret = SCFGA_BUSY;
224 (void) rcm_free_handle(rcm_handle);
225 return (ret);
229 * scsi_rcm_init()
231 * Contains common initialization code for entering a scsi_rcm_xx()
232 * routine.
234 static scfga_ret_t
235 scsi_rcm_init(uint_t rcm_flag, char **errstring, rcm_handle_t **hdlp)
237 /* Get a handle for the RCM operations */
238 if (rcm_alloc_handle(NULL, rcm_flag, NULL, hdlp) != RCM_SUCCESS) {
239 cfga_err(errstring, 0, ERR_RCM_HANDLE, 0);
240 return (SCFGA_LIB_ERR);
243 return (SCFGA_OK);
247 * scsi_rcm_info_table
249 * Takes an opaque rcm_info_t pointer and a character pointer, and appends
250 * the rcm_info_t data in the form of a table to the given character pointer.
252 static scfga_ret_t
253 scsi_rcm_info_table(rcm_info_t *rinfo, char **table)
255 int i;
256 size_t w;
257 size_t width = 0;
258 size_t w_rsrc = 0;
259 size_t w_info = 0;
260 size_t table_size = 0;
261 uint_t tuples = 0;
262 rcm_info_tuple_t *tuple = NULL;
263 char *rsrc;
264 char *info;
265 char *newtable;
266 static char format[MAX_FORMAT];
267 const char *infostr;
269 /* Protect against invalid arguments */
270 if (rinfo == NULL || table == NULL)
271 return (SCFGA_ERR);
273 /* Set localized table header strings */
274 rsrc = dgettext(TEXT_DOMAIN, "Resource");
275 info = dgettext(TEXT_DOMAIN, "Information");
277 /* A first pass, to size up the RCM information */
278 while (tuple = rcm_info_next(rinfo, tuple)) {
279 if ((infostr = rcm_info_info(tuple)) != NULL) {
280 tuples++;
281 if ((w = strlen(rcm_info_rsrc(tuple))) > w_rsrc)
282 w_rsrc = w;
283 if ((w = strlen(infostr)) > w_info)
284 w_info = w;
288 /* If nothing was sized up above, stop early */
289 if (tuples == 0)
290 return (SCFGA_OK);
292 /* Adjust column widths for column headings */
293 if ((w = strlen(rsrc)) > w_rsrc)
294 w_rsrc = w;
295 else if ((w_rsrc - w) % 2)
296 w_rsrc++;
297 if ((w = strlen(info)) > w_info)
298 w_info = w;
299 else if ((w_info - w) % 2)
300 w_info++;
303 * Compute the total line width of each line,
304 * accounting for intercolumn spacing.
306 width = w_info + w_rsrc + 4;
308 /* Allocate space for the table */
309 table_size = (2 + tuples) * (width + 1) + 2;
310 if (*table == NULL) {
311 /* zero fill for the strcat() call below */
312 *table = calloc(table_size, sizeof (char));
313 if (*table == NULL)
314 return (SCFGA_ERR);
315 } else {
316 newtable = realloc(*table, strlen(*table) + table_size);
317 if (newtable == NULL)
318 return (SCFGA_ERR);
319 else
320 *table = newtable;
323 /* Place a table header into the string */
325 /* The resource header */
326 (void) strcat(*table, "\n");
327 w = strlen(rsrc);
328 for (i = 0; i < ((w_rsrc - w) / 2); i++)
329 (void) strcat(*table, " ");
330 (void) strcat(*table, rsrc);
331 for (i = 0; i < ((w_rsrc - w) / 2); i++)
332 (void) strcat(*table, " ");
334 /* The information header */
335 (void) strcat(*table, " ");
336 w = strlen(info);
337 for (i = 0; i < ((w_info - w) / 2); i++)
338 (void) strcat(*table, " ");
339 (void) strcat(*table, info);
340 for (i = 0; i < ((w_info - w) / 2); i++)
341 (void) strcat(*table, " ");
343 /* Underline the headers */
344 (void) strcat(*table, "\n");
345 for (i = 0; i < w_rsrc; i++)
346 (void) strcat(*table, "-");
347 (void) strcat(*table, " ");
348 for (i = 0; i < w_info; i++)
349 (void) strcat(*table, "-");
351 /* Construct the format string */
352 (void) snprintf(format, MAX_FORMAT, "%%-%ds %%-%ds",
353 (int)w_rsrc, (int)w_info);
355 /* Add the tuples to the table string */
356 tuple = NULL;
357 while ((tuple = rcm_info_next(rinfo, tuple)) != NULL) {
358 if ((infostr = rcm_info_info(tuple)) != NULL) {
359 (void) strcat(*table, "\n");
360 (void) sprintf(&((*table)[strlen(*table)]),
361 format, rcm_info_rsrc(tuple),
362 infostr);
366 return (SCFGA_OK);