1*1708Sstevel /*
2*1708Sstevel * CDDL HEADER START
3*1708Sstevel *
4*1708Sstevel * The contents of this file are subject to the terms of the
5*1708Sstevel * Common Development and Distribution License (the "License").
6*1708Sstevel * You may not use this file except in compliance with the License.
7*1708Sstevel *
8*1708Sstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*1708Sstevel * or http://www.opensolaris.org/os/licensing.
10*1708Sstevel * See the License for the specific language governing permissions
11*1708Sstevel * and limitations under the License.
12*1708Sstevel *
13*1708Sstevel * When distributing Covered Code, include this CDDL HEADER in each
14*1708Sstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*1708Sstevel * If applicable, add the following below this CDDL HEADER, with the
16*1708Sstevel * fields enclosed by brackets "[]" replaced with your own identifying
17*1708Sstevel * information: Portions Copyright [yyyy] [name of copyright owner]
18*1708Sstevel *
19*1708Sstevel * CDDL HEADER END
20*1708Sstevel */
21*1708Sstevel
22*1708Sstevel /*
23*1708Sstevel * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24*1708Sstevel * Use is subject to license terms.
25*1708Sstevel */
26*1708Sstevel
27*1708Sstevel #pragma ident "%Z%%M% %I% %E% SMI"
28*1708Sstevel
29*1708Sstevel #include <stdio.h>
30*1708Sstevel #include <errno.h>
31*1708Sstevel #include <fcntl.h>
32*1708Sstevel #include <unistd.h>
33*1708Sstevel #include <stdlib.h>
34*1708Sstevel #include <stdarg.h>
35*1708Sstevel #include <strings.h>
36*1708Sstevel #include <limits.h>
37*1708Sstevel #include <syslog.h>
38*1708Sstevel #include <sys/open.h>
39*1708Sstevel #include <string.h>
40*1708Sstevel #include <alloca.h>
41*1708Sstevel #include <libintl.h>
42*1708Sstevel #include <sys/stat.h>
43*1708Sstevel #include <sys/systeminfo.h>
44*1708Sstevel #include <picl.h>
45*1708Sstevel #include <picltree.h>
46*1708Sstevel #include <fru_access.h>
47*1708Sstevel #include <sys/sgfrutree.h>
48*1708Sstevel
49*1708Sstevel /*
50*1708Sstevel * these functions will overlay the symbol table of libfruaccess
51*1708Sstevel * at runtime
52*1708Sstevel */
53*1708Sstevel container_hdl_t fru_open_container(picl_nodehdl_t fru);
54*1708Sstevel int fru_close_container(container_hdl_t fru);
55*1708Sstevel int fru_get_num_sections(container_hdl_t container,
56*1708Sstevel door_cred_t *cred);
57*1708Sstevel int fru_get_sections(container_hdl_t container, section_t *section,
58*1708Sstevel int max_sections, door_cred_t *cred);
59*1708Sstevel int fru_get_num_segments(section_hdl_t section, door_cred_t *cred);
60*1708Sstevel int fru_get_segments(section_hdl_t section, segment_t *segment,
61*1708Sstevel int max_segments, door_cred_t *cred);
62*1708Sstevel int fru_add_segment(section_hdl_t section, segment_t *segment,
63*1708Sstevel section_hdl_t *newsection, door_cred_t *cred);
64*1708Sstevel int fru_delete_segment(segment_hdl_t segment,
65*1708Sstevel section_hdl_t *newsection, door_cred_t *cred);
66*1708Sstevel ssize_t fru_read_segment(segment_hdl_t segment, void *buffer,
67*1708Sstevel size_t nbytes, door_cred_t *cred);
68*1708Sstevel ssize_t fru_write_segment(segment_hdl_t segment, const void *data,
69*1708Sstevel size_t nbytes, segment_hdl_t *newsegment,
70*1708Sstevel door_cred_t *cred);
71*1708Sstevel int fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred);
72*1708Sstevel int fru_get_packets(segment_hdl_t segment, packet_t *packet,
73*1708Sstevel int max_packets, door_cred_t *cred);
74*1708Sstevel int fru_update_payload(packet_hdl_t packet, const void *data,
75*1708Sstevel size_t nbytes, packet_hdl_t *newpacket, door_cred_t *cred);
76*1708Sstevel int fru_append_packet(segment_hdl_t segment, packet_t *packet,
77*1708Sstevel const void *payload, size_t nbytes,
78*1708Sstevel segment_hdl_t *newsegment, door_cred_t *cred);
79*1708Sstevel int fru_delete_packet(packet_hdl_t packet,
80*1708Sstevel segment_hdl_t *newsegment, door_cred_t *cred);
81*1708Sstevel int fru_is_data_available(picl_nodehdl_t fru);
82*1708Sstevel
83*1708Sstevel #define PICL_PROP_SC_HANDLE "SC_handle"
84*1708Sstevel #define PICL_PROP_DATA_AVAIL "FRUDataAvailable"
85*1708Sstevel #define MAX_LINE_SIZE 1024
86*1708Sstevel
87*1708Sstevel #define OPENDEVFRU gettext("fru_open_dev: open of %s failed %s")
88*1708Sstevel #define GETPV gettext("fru_open_container: ptree_get_propval_by_name failed %s")
89*1708Sstevel
90*1708Sstevel static int
fru_open_dev(void)91*1708Sstevel fru_open_dev(void)
92*1708Sstevel {
93*1708Sstevel static int opendevfru = 0;
94*1708Sstevel static int frufd = 0;
95*1708Sstevel
96*1708Sstevel if ((opendevfru == 0) && (frufd == 0)) {
97*1708Sstevel if ((frufd = open(FRU_PSEUDO_DEV, O_RDWR, access)) == -1) {
98*1708Sstevel syslog(LOG_ERR, OPENDEVFRU, FRU_PSEUDO_DEV,
99*1708Sstevel strerror(errno));
100*1708Sstevel return (-1);
101*1708Sstevel }
102*1708Sstevel opendevfru = 1;
103*1708Sstevel }
104*1708Sstevel return (frufd);
105*1708Sstevel }
106*1708Sstevel
107*1708Sstevel /*
108*1708Sstevel * Look up the container_hdl in the PICL tree.
109*1708Sstevel */
110*1708Sstevel container_hdl_t
fru_open_container(picl_nodehdl_t fruh)111*1708Sstevel fru_open_container(picl_nodehdl_t fruh)
112*1708Sstevel {
113*1708Sstevel int err;
114*1708Sstevel container_hdl_t container_hdl;
115*1708Sstevel
116*1708Sstevel if (fru_open_dev() == -1) {
117*1708Sstevel return (NULL);
118*1708Sstevel }
119*1708Sstevel
120*1708Sstevel err = ptree_get_propval_by_name(fruh, PICL_PROP_DATA_AVAIL, NULL, NULL);
121*1708Sstevel if (err != PICL_SUCCESS) {
122*1708Sstevel syslog(LOG_ERR, GETPV, PICL_PROP_DATA_AVAIL, err);
123*1708Sstevel return (NULL);
124*1708Sstevel }
125*1708Sstevel err = ptree_get_propval_by_name(fruh, PICL_PROP_SC_HANDLE,
126*1708Sstevel &container_hdl, sizeof (container_hdl_t));
127*1708Sstevel if (err != PICL_SUCCESS) {
128*1708Sstevel syslog(LOG_ERR, GETPV, PICL_PROP_SC_HANDLE, err);
129*1708Sstevel return (NULL);
130*1708Sstevel }
131*1708Sstevel return (container_hdl);
132*1708Sstevel }
133*1708Sstevel
134*1708Sstevel /*
135*1708Sstevel * Note : fru_open_container and fru_close_container do not map onto the opens
136*1708Sstevel * and closes of the sgfru device on lw8. There is one sgfru device which
137*1708Sstevel * handles all containers.
138*1708Sstevel */
139*1708Sstevel /*ARGSUSED*/
140*1708Sstevel int
fru_close_container(container_hdl_t fru)141*1708Sstevel fru_close_container(container_hdl_t fru)
142*1708Sstevel {
143*1708Sstevel if (fru_open_dev() == -1) {
144*1708Sstevel return (-1);
145*1708Sstevel }
146*1708Sstevel return (0);
147*1708Sstevel }
148*1708Sstevel
149*1708Sstevel /*ARGSUSED*/
150*1708Sstevel int
fru_get_num_sections(container_hdl_t container,door_cred_t * cred)151*1708Sstevel fru_get_num_sections(container_hdl_t container, door_cred_t *cred)
152*1708Sstevel {
153*1708Sstevel section_info_t numsections;
154*1708Sstevel int fd;
155*1708Sstevel
156*1708Sstevel if ((fd = fru_open_dev()) == -1) {
157*1708Sstevel return (-1);
158*1708Sstevel }
159*1708Sstevel numsections.hdl = container;
160*1708Sstevel numsections.cnt = 0;
161*1708Sstevel if (ioctl(fd, SGFRU_GETNUMSECTIONS, &numsections) != 0) {
162*1708Sstevel return (-1);
163*1708Sstevel }
164*1708Sstevel return (numsections.cnt);
165*1708Sstevel }
166*1708Sstevel
167*1708Sstevel /*ARGSUSED*/
168*1708Sstevel int
fru_get_sections(container_hdl_t container,section_t * section,int max_sections,door_cred_t * cred)169*1708Sstevel fru_get_sections(container_hdl_t container, section_t *section,
170*1708Sstevel int max_sections, door_cred_t *cred)
171*1708Sstevel {
172*1708Sstevel sections_t sections;
173*1708Sstevel int fd;
174*1708Sstevel
175*1708Sstevel if ((fd = fru_open_dev()) == -1) {
176*1708Sstevel return (-1);
177*1708Sstevel }
178*1708Sstevel sections.fru_hdl = container;
179*1708Sstevel sections.fru_cnt = max_sections;
180*1708Sstevel sections.frus = section;
181*1708Sstevel if (ioctl(fd, SGFRU_GETSECTIONS, §ions) != 0) {
182*1708Sstevel return (-1);
183*1708Sstevel }
184*1708Sstevel return (sections.fru_cnt);
185*1708Sstevel }
186*1708Sstevel
187*1708Sstevel /*ARGSUSED*/
188*1708Sstevel int
fru_get_num_segments(section_hdl_t section,door_cred_t * cred)189*1708Sstevel fru_get_num_segments(section_hdl_t section, door_cred_t *cred)
190*1708Sstevel {
191*1708Sstevel segment_info_t numsegments;
192*1708Sstevel int fd;
193*1708Sstevel
194*1708Sstevel if ((fd = fru_open_dev()) == -1) {
195*1708Sstevel return (-1);
196*1708Sstevel }
197*1708Sstevel numsegments.hdl = section;
198*1708Sstevel numsegments.cnt = 0;
199*1708Sstevel if (ioctl(fd, SGFRU_GETNUMSEGMENTS, &numsegments) != 0) {
200*1708Sstevel return (-1);
201*1708Sstevel }
202*1708Sstevel return (numsegments.cnt);
203*1708Sstevel }
204*1708Sstevel
205*1708Sstevel /*ARGSUSED*/
206*1708Sstevel int
fru_get_segments(section_hdl_t section,segment_t * segment,int max_segments,door_cred_t * cred)207*1708Sstevel fru_get_segments(section_hdl_t section, segment_t *segment, int max_segments,
208*1708Sstevel door_cred_t *cred)
209*1708Sstevel {
210*1708Sstevel segments_t segments;
211*1708Sstevel int fd;
212*1708Sstevel
213*1708Sstevel if ((fd = fru_open_dev()) == -1) {
214*1708Sstevel return (-1);
215*1708Sstevel }
216*1708Sstevel segments.fru_hdl = section;
217*1708Sstevel segments.fru_cnt = max_segments;
218*1708Sstevel segments.frus = segment;
219*1708Sstevel if (ioctl(fd, SGFRU_GETSEGMENTS, &segments) != 0) {
220*1708Sstevel return (-1);
221*1708Sstevel }
222*1708Sstevel return (segments.fru_cnt);
223*1708Sstevel }
224*1708Sstevel
225*1708Sstevel /*ARGSUSED*/
226*1708Sstevel int
fru_add_segment(section_hdl_t section,segment_t * segment,section_hdl_t * newsection,door_cred_t * cred)227*1708Sstevel fru_add_segment(section_hdl_t section, segment_t *segment,
228*1708Sstevel section_hdl_t *newsection, door_cred_t *cred)
229*1708Sstevel {
230*1708Sstevel segments_t newsegment;
231*1708Sstevel int fd;
232*1708Sstevel
233*1708Sstevel /* check the effective uid of the client */
234*1708Sstevel if (cred->dc_euid != 0) {
235*1708Sstevel errno = EPERM;
236*1708Sstevel return (-1); /* not a root */
237*1708Sstevel }
238*1708Sstevel
239*1708Sstevel if ((fd = fru_open_dev()) == -1) {
240*1708Sstevel return (-1);
241*1708Sstevel }
242*1708Sstevel newsegment.fru_hdl = section;
243*1708Sstevel newsegment.fru_cnt = 1;
244*1708Sstevel newsegment.frus = segment;
245*1708Sstevel if (ioctl(fd, SGFRU_ADDSEGMENT, &newsegment) != 0) {
246*1708Sstevel return (-1);
247*1708Sstevel }
248*1708Sstevel /*
249*1708Sstevel * The new segment handle is returned in segment,
250*1708Sstevel * return the updated section handle in newsection.
251*1708Sstevel */
252*1708Sstevel *newsection = newsegment.fru_hdl;
253*1708Sstevel return (0);
254*1708Sstevel }
255*1708Sstevel
256*1708Sstevel int
fru_delete_segment(segment_hdl_t segment,section_hdl_t * newsection,door_cred_t * cred)257*1708Sstevel fru_delete_segment(segment_hdl_t segment, section_hdl_t *newsection,
258*1708Sstevel door_cred_t *cred)
259*1708Sstevel {
260*1708Sstevel segment_info_t delsegment;
261*1708Sstevel int fd;
262*1708Sstevel
263*1708Sstevel /* check the effective uid of the client */
264*1708Sstevel if (cred->dc_euid != 0) {
265*1708Sstevel errno = EPERM;
266*1708Sstevel return (-1); /* not a root */
267*1708Sstevel }
268*1708Sstevel
269*1708Sstevel if ((fd = fru_open_dev()) == -1) {
270*1708Sstevel return (-1);
271*1708Sstevel }
272*1708Sstevel delsegment.hdl = segment;
273*1708Sstevel if (ioctl(fd, SGFRU_DELETESEGMENT, &delsegment) != 0) {
274*1708Sstevel return (-1);
275*1708Sstevel }
276*1708Sstevel /* Return the updated section handle in newsection. */
277*1708Sstevel *newsection = delsegment.hdl;
278*1708Sstevel return (0);
279*1708Sstevel }
280*1708Sstevel
281*1708Sstevel /*ARGSUSED*/
282*1708Sstevel ssize_t
fru_read_segment(segment_hdl_t segment,void * buffer,size_t nbytes,door_cred_t * cred)283*1708Sstevel fru_read_segment(segment_hdl_t segment, void *buffer, size_t nbytes,
284*1708Sstevel door_cred_t *cred)
285*1708Sstevel {
286*1708Sstevel segments_t readsegment;
287*1708Sstevel int fd;
288*1708Sstevel
289*1708Sstevel if ((fd = fru_open_dev()) == -1) {
290*1708Sstevel return (-1);
291*1708Sstevel }
292*1708Sstevel readsegment.fru_hdl = segment;
293*1708Sstevel readsegment.fru_cnt = nbytes;
294*1708Sstevel readsegment.frus = buffer;
295*1708Sstevel if (ioctl(fd, SGFRU_READRAWSEGMENT, &readsegment) != 0) {
296*1708Sstevel return (-1);
297*1708Sstevel }
298*1708Sstevel return ((ssize_t)readsegment.fru_cnt);
299*1708Sstevel }
300*1708Sstevel
301*1708Sstevel /*ARGSUSED*/
302*1708Sstevel ssize_t
fru_write_segment(segment_hdl_t segment,const void * buffer,size_t nbytes,segment_hdl_t * newsegment,door_cred_t * cred)303*1708Sstevel fru_write_segment(segment_hdl_t segment, const void *buffer, size_t nbytes,
304*1708Sstevel segment_hdl_t *newsegment, door_cred_t *cred)
305*1708Sstevel {
306*1708Sstevel segments_t writesegment;
307*1708Sstevel int fd;
308*1708Sstevel
309*1708Sstevel if ((fd = fru_open_dev()) == -1) {
310*1708Sstevel return (-1);
311*1708Sstevel }
312*1708Sstevel writesegment.fru_hdl = segment;
313*1708Sstevel writesegment.fru_cnt = nbytes;
314*1708Sstevel writesegment.frus = (void *)buffer;
315*1708Sstevel if (ioctl(fd, SGFRU_WRITERAWSEGMENT, &writesegment) != 0) {
316*1708Sstevel return (-1);
317*1708Sstevel }
318*1708Sstevel /* Return the updated segment handle in newsegment. */
319*1708Sstevel *newsegment = writesegment.fru_hdl;
320*1708Sstevel return ((ssize_t)writesegment.fru_cnt);
321*1708Sstevel }
322*1708Sstevel
323*1708Sstevel /*ARGSUSED*/
324*1708Sstevel int
fru_get_num_packets(segment_hdl_t segment,door_cred_t * cred)325*1708Sstevel fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred)
326*1708Sstevel {
327*1708Sstevel packet_info_t numpackets;
328*1708Sstevel int fd;
329*1708Sstevel
330*1708Sstevel if ((fd = fru_open_dev()) == -1) {
331*1708Sstevel return (-1);
332*1708Sstevel }
333*1708Sstevel numpackets.hdl = segment;
334*1708Sstevel numpackets.cnt = 0;
335*1708Sstevel if (ioctl(fd, SGFRU_GETNUMPACKETS, &numpackets) != 0) {
336*1708Sstevel return (-1);
337*1708Sstevel }
338*1708Sstevel return (numpackets.cnt);
339*1708Sstevel }
340*1708Sstevel
341*1708Sstevel /*ARGSUSED*/
342*1708Sstevel int
fru_get_packets(segment_hdl_t segment,packet_t * packet,int max_packets,door_cred_t * cred)343*1708Sstevel fru_get_packets(segment_hdl_t segment, packet_t *packet, int max_packets,
344*1708Sstevel door_cred_t *cred)
345*1708Sstevel {
346*1708Sstevel packets_t packets;
347*1708Sstevel int fd;
348*1708Sstevel
349*1708Sstevel if ((fd = fru_open_dev()) == -1) {
350*1708Sstevel return (-1);
351*1708Sstevel }
352*1708Sstevel packets.fru_hdl = segment;
353*1708Sstevel packets.fru_cnt = max_packets;
354*1708Sstevel packets.frus = packet;
355*1708Sstevel if (ioctl(fd, SGFRU_GETPACKETS, &packets) != 0) {
356*1708Sstevel return (-1);
357*1708Sstevel }
358*1708Sstevel return (packets.fru_cnt);
359*1708Sstevel }
360*1708Sstevel
361*1708Sstevel /*ARGSUSED*/
362*1708Sstevel ssize_t
fru_get_payload(packet_hdl_t packet,void * buffer,size_t nbytes,door_cred_t * cred)363*1708Sstevel fru_get_payload(packet_hdl_t packet, void *buffer, size_t nbytes,
364*1708Sstevel door_cred_t *cred)
365*1708Sstevel {
366*1708Sstevel payload_t payload;
367*1708Sstevel int fd;
368*1708Sstevel
369*1708Sstevel if ((fd = fru_open_dev()) == -1) {
370*1708Sstevel return (-1);
371*1708Sstevel }
372*1708Sstevel payload.fru_hdl = packet;
373*1708Sstevel payload.fru_cnt = nbytes;
374*1708Sstevel payload.frus = buffer;
375*1708Sstevel if (ioctl(fd, SGFRU_GETPAYLOAD, &payload) != 0) {
376*1708Sstevel return (-1);
377*1708Sstevel }
378*1708Sstevel return ((ssize_t)payload.fru_cnt);
379*1708Sstevel }
380*1708Sstevel
381*1708Sstevel int
fru_update_payload(packet_hdl_t packet,const void * data,size_t nbytes,packet_hdl_t * newpacket,door_cred_t * cred)382*1708Sstevel fru_update_payload(packet_hdl_t packet, const void *data, size_t nbytes,
383*1708Sstevel packet_hdl_t *newpacket, door_cred_t *cred)
384*1708Sstevel {
385*1708Sstevel payload_t payload;
386*1708Sstevel int fd;
387*1708Sstevel
388*1708Sstevel /* check the effective uid of the client */
389*1708Sstevel if (cred->dc_euid != 0) {
390*1708Sstevel errno = EPERM;
391*1708Sstevel return (-1); /* not a root */
392*1708Sstevel }
393*1708Sstevel
394*1708Sstevel if ((fd = fru_open_dev()) == -1) {
395*1708Sstevel return (-1);
396*1708Sstevel }
397*1708Sstevel payload.fru_hdl = packet;
398*1708Sstevel payload.fru_cnt = nbytes;
399*1708Sstevel payload.frus = (void *)data;
400*1708Sstevel if (ioctl(fd, SGFRU_UPDATEPAYLOAD, &payload) != 0) {
401*1708Sstevel return (-1);
402*1708Sstevel }
403*1708Sstevel /* Return the updated packet handle in newpacket. */
404*1708Sstevel *newpacket = payload.fru_hdl;
405*1708Sstevel return (0);
406*1708Sstevel }
407*1708Sstevel
408*1708Sstevel int
fru_append_packet(segment_hdl_t segment,packet_t * packet,const void * payload,size_t nbytes,segment_hdl_t * newsegment,door_cred_t * cred)409*1708Sstevel fru_append_packet(segment_hdl_t segment, packet_t *packet, const void *payload,
410*1708Sstevel size_t nbytes, segment_hdl_t *newsegment, door_cred_t *cred)
411*1708Sstevel {
412*1708Sstevel append_info_t appendpkt;
413*1708Sstevel int fd;
414*1708Sstevel
415*1708Sstevel /* check the effective uid of the client */
416*1708Sstevel if (cred->dc_euid != 0) {
417*1708Sstevel errno = EPERM;
418*1708Sstevel return (-1); /* not a root */
419*1708Sstevel }
420*1708Sstevel
421*1708Sstevel if ((fd = fru_open_dev()) == -1) {
422*1708Sstevel return (-1);
423*1708Sstevel }
424*1708Sstevel appendpkt.packet = *packet;
425*1708Sstevel appendpkt.payload_hdl = segment;
426*1708Sstevel appendpkt.payload_cnt = nbytes;
427*1708Sstevel appendpkt.payload_data = (void *)payload;
428*1708Sstevel if (ioctl(fd, SGFRU_APPENDPACKET, &appendpkt) != 0) {
429*1708Sstevel return (-1);
430*1708Sstevel }
431*1708Sstevel /*
432*1708Sstevel * The new packet handle is returned in packet,
433*1708Sstevel * return the updated segment handle in newsegment.
434*1708Sstevel */
435*1708Sstevel packet->handle = appendpkt.packet.handle;
436*1708Sstevel *newsegment = appendpkt.payload_hdl;
437*1708Sstevel return (0);
438*1708Sstevel }
439*1708Sstevel
440*1708Sstevel int
fru_delete_packet(packet_hdl_t packet,segment_hdl_t * newsegment,door_cred_t * cred)441*1708Sstevel fru_delete_packet(packet_hdl_t packet, segment_hdl_t *newsegment,
442*1708Sstevel door_cred_t *cred)
443*1708Sstevel {
444*1708Sstevel packet_info_t delpacket;
445*1708Sstevel int fd;
446*1708Sstevel
447*1708Sstevel /* check the effective uid of the client */
448*1708Sstevel if (cred->dc_euid != 0) {
449*1708Sstevel errno = EPERM;
450*1708Sstevel return (-1); /* not a root */
451*1708Sstevel }
452*1708Sstevel
453*1708Sstevel if ((fd = fru_open_dev()) == -1) {
454*1708Sstevel return (-1);
455*1708Sstevel }
456*1708Sstevel delpacket.hdl = packet;
457*1708Sstevel if (ioctl(fd, SGFRU_DELETEPACKET, &delpacket) != 0) {
458*1708Sstevel return (-1);
459*1708Sstevel }
460*1708Sstevel /* Return the updated segment handle in newsegment. */
461*1708Sstevel *newsegment = delpacket.hdl;
462*1708Sstevel return (0);
463*1708Sstevel }
464*1708Sstevel
465*1708Sstevel /*
466*1708Sstevel * Description :
467*1708Sstevel * fru_is_data_available() checks to see if the frudata
468*1708Sstevel * is available on a fru.
469*1708Sstevel *
470*1708Sstevel * Arguments :
471*1708Sstevel * picl_nodehdl_t holds the picl node handle of the fru.
472*1708Sstevel *
473*1708Sstevel * Return :
474*1708Sstevel * int
475*1708Sstevel * return 1: if FRUID information is available
476*1708Sstevel * return 0: if FRUID information is not present
477*1708Sstevel *
478*1708Sstevel */
479*1708Sstevel
480*1708Sstevel /* ARGSUSED */
481*1708Sstevel int
fru_is_data_available(picl_nodehdl_t fru)482*1708Sstevel fru_is_data_available(picl_nodehdl_t fru)
483*1708Sstevel {
484*1708Sstevel return (0);
485*1708Sstevel }
486