dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / picl / plugins / sun4u / lw8 / fruaccess / libfruaccess.c
bloba4fea2bd6114361e7f4a7863d8f49a737cf4f659
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
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <stdarg.h>
35 #include <strings.h>
36 #include <limits.h>
37 #include <syslog.h>
38 #include <sys/open.h>
39 #include <string.h>
40 #include <alloca.h>
41 #include <libintl.h>
42 #include <sys/stat.h>
43 #include <sys/systeminfo.h>
44 #include <picl.h>
45 #include <picltree.h>
46 #include <fru_access.h>
47 #include <sys/sgfrutree.h>
50 * these functions will overlay the symbol table of libfruaccess
51 * at runtime
53 container_hdl_t fru_open_container(picl_nodehdl_t fru);
54 int fru_close_container(container_hdl_t fru);
55 int fru_get_num_sections(container_hdl_t container,
56 door_cred_t *cred);
57 int fru_get_sections(container_hdl_t container, section_t *section,
58 int max_sections, door_cred_t *cred);
59 int fru_get_num_segments(section_hdl_t section, door_cred_t *cred);
60 int fru_get_segments(section_hdl_t section, segment_t *segment,
61 int max_segments, door_cred_t *cred);
62 int fru_add_segment(section_hdl_t section, segment_t *segment,
63 section_hdl_t *newsection, door_cred_t *cred);
64 int fru_delete_segment(segment_hdl_t segment,
65 section_hdl_t *newsection, door_cred_t *cred);
66 ssize_t fru_read_segment(segment_hdl_t segment, void *buffer,
67 size_t nbytes, door_cred_t *cred);
68 ssize_t fru_write_segment(segment_hdl_t segment, const void *data,
69 size_t nbytes, segment_hdl_t *newsegment,
70 door_cred_t *cred);
71 int fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred);
72 int fru_get_packets(segment_hdl_t segment, packet_t *packet,
73 int max_packets, door_cred_t *cred);
74 int fru_update_payload(packet_hdl_t packet, const void *data,
75 size_t nbytes, packet_hdl_t *newpacket, door_cred_t *cred);
76 int fru_append_packet(segment_hdl_t segment, packet_t *packet,
77 const void *payload, size_t nbytes,
78 segment_hdl_t *newsegment, door_cred_t *cred);
79 int fru_delete_packet(packet_hdl_t packet,
80 segment_hdl_t *newsegment, door_cred_t *cred);
81 int fru_is_data_available(picl_nodehdl_t fru);
83 #define PICL_PROP_SC_HANDLE "SC_handle"
84 #define PICL_PROP_DATA_AVAIL "FRUDataAvailable"
85 #define MAX_LINE_SIZE 1024
87 #define OPENDEVFRU gettext("fru_open_dev: open of %s failed %s")
88 #define GETPV gettext("fru_open_container: ptree_get_propval_by_name failed %s")
90 static int
91 fru_open_dev(void)
93 static int opendevfru = 0;
94 static int frufd = 0;
96 if ((opendevfru == 0) && (frufd == 0)) {
97 if ((frufd = open(FRU_PSEUDO_DEV, O_RDWR, access)) == -1) {
98 syslog(LOG_ERR, OPENDEVFRU, FRU_PSEUDO_DEV,
99 strerror(errno));
100 return (-1);
102 opendevfru = 1;
104 return (frufd);
108 * Look up the container_hdl in the PICL tree.
110 container_hdl_t
111 fru_open_container(picl_nodehdl_t fruh)
113 int err;
114 container_hdl_t container_hdl;
116 if (fru_open_dev() == -1) {
117 return (NULL);
120 err = ptree_get_propval_by_name(fruh, PICL_PROP_DATA_AVAIL, NULL, NULL);
121 if (err != PICL_SUCCESS) {
122 syslog(LOG_ERR, GETPV, PICL_PROP_DATA_AVAIL, err);
123 return (NULL);
125 err = ptree_get_propval_by_name(fruh, PICL_PROP_SC_HANDLE,
126 &container_hdl, sizeof (container_hdl_t));
127 if (err != PICL_SUCCESS) {
128 syslog(LOG_ERR, GETPV, PICL_PROP_SC_HANDLE, err);
129 return (NULL);
131 return (container_hdl);
135 * Note : fru_open_container and fru_close_container do not map onto the opens
136 * and closes of the sgfru device on lw8. There is one sgfru device which
137 * handles all containers.
139 /*ARGSUSED*/
141 fru_close_container(container_hdl_t fru)
143 if (fru_open_dev() == -1) {
144 return (-1);
146 return (0);
149 /*ARGSUSED*/
151 fru_get_num_sections(container_hdl_t container, door_cred_t *cred)
153 section_info_t numsections;
154 int fd;
156 if ((fd = fru_open_dev()) == -1) {
157 return (-1);
159 numsections.hdl = container;
160 numsections.cnt = 0;
161 if (ioctl(fd, SGFRU_GETNUMSECTIONS, &numsections) != 0) {
162 return (-1);
164 return (numsections.cnt);
167 /*ARGSUSED*/
169 fru_get_sections(container_hdl_t container, section_t *section,
170 int max_sections, door_cred_t *cred)
172 sections_t sections;
173 int fd;
175 if ((fd = fru_open_dev()) == -1) {
176 return (-1);
178 sections.fru_hdl = container;
179 sections.fru_cnt = max_sections;
180 sections.frus = section;
181 if (ioctl(fd, SGFRU_GETSECTIONS, &sections) != 0) {
182 return (-1);
184 return (sections.fru_cnt);
187 /*ARGSUSED*/
189 fru_get_num_segments(section_hdl_t section, door_cred_t *cred)
191 segment_info_t numsegments;
192 int fd;
194 if ((fd = fru_open_dev()) == -1) {
195 return (-1);
197 numsegments.hdl = section;
198 numsegments.cnt = 0;
199 if (ioctl(fd, SGFRU_GETNUMSEGMENTS, &numsegments) != 0) {
200 return (-1);
202 return (numsegments.cnt);
205 /*ARGSUSED*/
207 fru_get_segments(section_hdl_t section, segment_t *segment, int max_segments,
208 door_cred_t *cred)
210 segments_t segments;
211 int fd;
213 if ((fd = fru_open_dev()) == -1) {
214 return (-1);
216 segments.fru_hdl = section;
217 segments.fru_cnt = max_segments;
218 segments.frus = segment;
219 if (ioctl(fd, SGFRU_GETSEGMENTS, &segments) != 0) {
220 return (-1);
222 return (segments.fru_cnt);
225 /*ARGSUSED*/
227 fru_add_segment(section_hdl_t section, segment_t *segment,
228 section_hdl_t *newsection, door_cred_t *cred)
230 segments_t newsegment;
231 int fd;
233 /* check the effective uid of the client */
234 if (cred->dc_euid != 0) {
235 errno = EPERM;
236 return (-1); /* not a root */
239 if ((fd = fru_open_dev()) == -1) {
240 return (-1);
242 newsegment.fru_hdl = section;
243 newsegment.fru_cnt = 1;
244 newsegment.frus = segment;
245 if (ioctl(fd, SGFRU_ADDSEGMENT, &newsegment) != 0) {
246 return (-1);
249 * The new segment handle is returned in segment,
250 * return the updated section handle in newsection.
252 *newsection = newsegment.fru_hdl;
253 return (0);
257 fru_delete_segment(segment_hdl_t segment, section_hdl_t *newsection,
258 door_cred_t *cred)
260 segment_info_t delsegment;
261 int fd;
263 /* check the effective uid of the client */
264 if (cred->dc_euid != 0) {
265 errno = EPERM;
266 return (-1); /* not a root */
269 if ((fd = fru_open_dev()) == -1) {
270 return (-1);
272 delsegment.hdl = segment;
273 if (ioctl(fd, SGFRU_DELETESEGMENT, &delsegment) != 0) {
274 return (-1);
276 /* Return the updated section handle in newsection. */
277 *newsection = delsegment.hdl;
278 return (0);
281 /*ARGSUSED*/
282 ssize_t
283 fru_read_segment(segment_hdl_t segment, void *buffer, size_t nbytes,
284 door_cred_t *cred)
286 segments_t readsegment;
287 int fd;
289 if ((fd = fru_open_dev()) == -1) {
290 return (-1);
292 readsegment.fru_hdl = segment;
293 readsegment.fru_cnt = nbytes;
294 readsegment.frus = buffer;
295 if (ioctl(fd, SGFRU_READRAWSEGMENT, &readsegment) != 0) {
296 return (-1);
298 return ((ssize_t)readsegment.fru_cnt);
301 /*ARGSUSED*/
302 ssize_t
303 fru_write_segment(segment_hdl_t segment, const void *buffer, size_t nbytes,
304 segment_hdl_t *newsegment, door_cred_t *cred)
306 segments_t writesegment;
307 int fd;
309 if ((fd = fru_open_dev()) == -1) {
310 return (-1);
312 writesegment.fru_hdl = segment;
313 writesegment.fru_cnt = nbytes;
314 writesegment.frus = (void *)buffer;
315 if (ioctl(fd, SGFRU_WRITERAWSEGMENT, &writesegment) != 0) {
316 return (-1);
318 /* Return the updated segment handle in newsegment. */
319 *newsegment = writesegment.fru_hdl;
320 return ((ssize_t)writesegment.fru_cnt);
323 /*ARGSUSED*/
325 fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred)
327 packet_info_t numpackets;
328 int fd;
330 if ((fd = fru_open_dev()) == -1) {
331 return (-1);
333 numpackets.hdl = segment;
334 numpackets.cnt = 0;
335 if (ioctl(fd, SGFRU_GETNUMPACKETS, &numpackets) != 0) {
336 return (-1);
338 return (numpackets.cnt);
341 /*ARGSUSED*/
343 fru_get_packets(segment_hdl_t segment, packet_t *packet, int max_packets,
344 door_cred_t *cred)
346 packets_t packets;
347 int fd;
349 if ((fd = fru_open_dev()) == -1) {
350 return (-1);
352 packets.fru_hdl = segment;
353 packets.fru_cnt = max_packets;
354 packets.frus = packet;
355 if (ioctl(fd, SGFRU_GETPACKETS, &packets) != 0) {
356 return (-1);
358 return (packets.fru_cnt);
361 /*ARGSUSED*/
362 ssize_t
363 fru_get_payload(packet_hdl_t packet, void *buffer, size_t nbytes,
364 door_cred_t *cred)
366 payload_t payload;
367 int fd;
369 if ((fd = fru_open_dev()) == -1) {
370 return (-1);
372 payload.fru_hdl = packet;
373 payload.fru_cnt = nbytes;
374 payload.frus = buffer;
375 if (ioctl(fd, SGFRU_GETPAYLOAD, &payload) != 0) {
376 return (-1);
378 return ((ssize_t)payload.fru_cnt);
382 fru_update_payload(packet_hdl_t packet, const void *data, size_t nbytes,
383 packet_hdl_t *newpacket, door_cred_t *cred)
385 payload_t payload;
386 int fd;
388 /* check the effective uid of the client */
389 if (cred->dc_euid != 0) {
390 errno = EPERM;
391 return (-1); /* not a root */
394 if ((fd = fru_open_dev()) == -1) {
395 return (-1);
397 payload.fru_hdl = packet;
398 payload.fru_cnt = nbytes;
399 payload.frus = (void *)data;
400 if (ioctl(fd, SGFRU_UPDATEPAYLOAD, &payload) != 0) {
401 return (-1);
403 /* Return the updated packet handle in newpacket. */
404 *newpacket = payload.fru_hdl;
405 return (0);
409 fru_append_packet(segment_hdl_t segment, packet_t *packet, const void *payload,
410 size_t nbytes, segment_hdl_t *newsegment, door_cred_t *cred)
412 append_info_t appendpkt;
413 int fd;
415 /* check the effective uid of the client */
416 if (cred->dc_euid != 0) {
417 errno = EPERM;
418 return (-1); /* not a root */
421 if ((fd = fru_open_dev()) == -1) {
422 return (-1);
424 appendpkt.packet = *packet;
425 appendpkt.payload_hdl = segment;
426 appendpkt.payload_cnt = nbytes;
427 appendpkt.payload_data = (void *)payload;
428 if (ioctl(fd, SGFRU_APPENDPACKET, &appendpkt) != 0) {
429 return (-1);
432 * The new packet handle is returned in packet,
433 * return the updated segment handle in newsegment.
435 packet->handle = appendpkt.packet.handle;
436 *newsegment = appendpkt.payload_hdl;
437 return (0);
441 fru_delete_packet(packet_hdl_t packet, segment_hdl_t *newsegment,
442 door_cred_t *cred)
444 packet_info_t delpacket;
445 int fd;
447 /* check the effective uid of the client */
448 if (cred->dc_euid != 0) {
449 errno = EPERM;
450 return (-1); /* not a root */
453 if ((fd = fru_open_dev()) == -1) {
454 return (-1);
456 delpacket.hdl = packet;
457 if (ioctl(fd, SGFRU_DELETEPACKET, &delpacket) != 0) {
458 return (-1);
460 /* Return the updated segment handle in newsegment. */
461 *newsegment = delpacket.hdl;
462 return (0);
466 * Description :
467 * fru_is_data_available() checks to see if the frudata
468 * is available on a fru.
470 * Arguments :
471 * picl_nodehdl_t holds the picl node handle of the fru.
473 * Return :
474 * int
475 * return 1: if FRUID information is available
476 * return 0: if FRUID information is not present
480 /* ARGSUSED */
482 fru_is_data_available(picl_nodehdl_t fru)
484 return (0);