xref: /illumos-gate/usr/src/cmd/picl/plugins/sun4u/lw8/fruaccess/libfruaccess.c (revision ada2da53edc6b7d3afbdff4975c5c32c01a7c72d)
103831d35Sstevel /*
203831d35Sstevel  * CDDL HEADER START
303831d35Sstevel  *
403831d35Sstevel  * The contents of this file are subject to the terms of the
503831d35Sstevel  * Common Development and Distribution License (the "License").
603831d35Sstevel  * You may not use this file except in compliance with the License.
703831d35Sstevel  *
803831d35Sstevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
903831d35Sstevel  * or http://www.opensolaris.org/os/licensing.
1003831d35Sstevel  * See the License for the specific language governing permissions
1103831d35Sstevel  * and limitations under the License.
1203831d35Sstevel  *
1303831d35Sstevel  * When distributing Covered Code, include this CDDL HEADER in each
1403831d35Sstevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1503831d35Sstevel  * If applicable, add the following below this CDDL HEADER, with the
1603831d35Sstevel  * fields enclosed by brackets "[]" replaced with your own identifying
1703831d35Sstevel  * information: Portions Copyright [yyyy] [name of copyright owner]
1803831d35Sstevel  *
1903831d35Sstevel  * CDDL HEADER END
2003831d35Sstevel  */
2103831d35Sstevel 
2203831d35Sstevel /*
2303831d35Sstevel  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
2403831d35Sstevel  * Use is subject to license terms.
2503831d35Sstevel  */
2603831d35Sstevel 
2703831d35Sstevel #include <stdio.h>
2803831d35Sstevel #include <errno.h>
2903831d35Sstevel #include <fcntl.h>
3003831d35Sstevel #include <unistd.h>
3103831d35Sstevel #include <stdlib.h>
3203831d35Sstevel #include <stdarg.h>
3303831d35Sstevel #include <strings.h>
3403831d35Sstevel #include <limits.h>
3503831d35Sstevel #include <syslog.h>
3603831d35Sstevel #include <sys/open.h>
3703831d35Sstevel #include <string.h>
3803831d35Sstevel #include <alloca.h>
3903831d35Sstevel #include <libintl.h>
4003831d35Sstevel #include <sys/stat.h>
4103831d35Sstevel #include <sys/systeminfo.h>
4203831d35Sstevel #include <picl.h>
4303831d35Sstevel #include <picltree.h>
4403831d35Sstevel #include <fru_access.h>
4503831d35Sstevel #include <sys/sgfrutree.h>
4603831d35Sstevel 
4703831d35Sstevel /*
4803831d35Sstevel  * these functions will overlay the symbol table of libfruaccess
4903831d35Sstevel  * at runtime
5003831d35Sstevel  */
5103831d35Sstevel container_hdl_t	fru_open_container(picl_nodehdl_t fru);
5203831d35Sstevel int		fru_close_container(container_hdl_t fru);
5303831d35Sstevel int		fru_get_num_sections(container_hdl_t container,
5403831d35Sstevel 		    door_cred_t *cred);
5503831d35Sstevel int		fru_get_sections(container_hdl_t container, section_t *section,
5603831d35Sstevel 		    int max_sections, door_cred_t *cred);
5703831d35Sstevel int		fru_get_num_segments(section_hdl_t section, door_cred_t *cred);
5803831d35Sstevel int		fru_get_segments(section_hdl_t section, segment_t *segment,
5903831d35Sstevel 		    int max_segments, door_cred_t *cred);
6003831d35Sstevel int		fru_add_segment(section_hdl_t section, segment_t *segment,
6103831d35Sstevel 		    section_hdl_t *newsection, door_cred_t *cred);
6203831d35Sstevel int		fru_delete_segment(segment_hdl_t segment,
6303831d35Sstevel 		    section_hdl_t *newsection, door_cred_t *cred);
6403831d35Sstevel ssize_t		fru_read_segment(segment_hdl_t segment, void *buffer,
6503831d35Sstevel 		    size_t nbytes, door_cred_t *cred);
6603831d35Sstevel ssize_t		fru_write_segment(segment_hdl_t segment, const void *data,
6703831d35Sstevel 		    size_t nbytes, segment_hdl_t *newsegment,
6803831d35Sstevel 		    door_cred_t *cred);
6903831d35Sstevel int		fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred);
7003831d35Sstevel int		fru_get_packets(segment_hdl_t segment, packet_t *packet,
7103831d35Sstevel 		    int max_packets, door_cred_t *cred);
7203831d35Sstevel int		fru_update_payload(packet_hdl_t packet, const void *data,
7303831d35Sstevel 		    size_t nbytes, packet_hdl_t *newpacket, door_cred_t *cred);
7403831d35Sstevel int		fru_append_packet(segment_hdl_t segment, packet_t *packet,
7503831d35Sstevel 		    const void *payload, size_t nbytes,
7603831d35Sstevel 		    segment_hdl_t *newsegment, door_cred_t *cred);
7703831d35Sstevel int		fru_delete_packet(packet_hdl_t packet,
7803831d35Sstevel 		    segment_hdl_t *newsegment, door_cred_t *cred);
7903831d35Sstevel int		fru_is_data_available(picl_nodehdl_t fru);
8003831d35Sstevel 
8103831d35Sstevel #define	PICL_PROP_SC_HANDLE	"SC_handle"
8203831d35Sstevel #define	PICL_PROP_DATA_AVAIL	"FRUDataAvailable"
8303831d35Sstevel #define	MAX_LINE_SIZE		1024
8403831d35Sstevel 
8503831d35Sstevel #define	OPENDEVFRU gettext("fru_open_dev: open of %s failed %s")
8603831d35Sstevel #define	GETPV gettext("fru_open_container: ptree_get_propval_by_name failed %s")
8703831d35Sstevel 
8803831d35Sstevel static int
fru_open_dev(void)8903831d35Sstevel fru_open_dev(void)
9003831d35Sstevel {
9103831d35Sstevel 	static int opendevfru = 0;
9203831d35Sstevel 	static int frufd = 0;
9303831d35Sstevel 
9403831d35Sstevel 	if ((opendevfru == 0) && (frufd == 0)) {
9503831d35Sstevel 		if ((frufd = open(FRU_PSEUDO_DEV, O_RDWR, access)) == -1) {
9603831d35Sstevel 			syslog(LOG_ERR, OPENDEVFRU, FRU_PSEUDO_DEV,
9703831d35Sstevel 			    strerror(errno));
9803831d35Sstevel 			return (-1);
9903831d35Sstevel 		}
10003831d35Sstevel 		opendevfru = 1;
10103831d35Sstevel 	}
10203831d35Sstevel 	return (frufd);
10303831d35Sstevel }
10403831d35Sstevel 
10503831d35Sstevel /*
10603831d35Sstevel  * Look up the container_hdl in the PICL tree.
10703831d35Sstevel  */
10803831d35Sstevel container_hdl_t
fru_open_container(picl_nodehdl_t fruh)10903831d35Sstevel fru_open_container(picl_nodehdl_t fruh)
11003831d35Sstevel {
11103831d35Sstevel 	int err;
11203831d35Sstevel 	container_hdl_t container_hdl;
11303831d35Sstevel 
11403831d35Sstevel 	if (fru_open_dev() == -1) {
115*ada2da53SToomas Soome 		return (0);
11603831d35Sstevel 	}
11703831d35Sstevel 
118*ada2da53SToomas Soome 	err = ptree_get_propval_by_name(fruh, PICL_PROP_DATA_AVAIL, NULL, 0);
11903831d35Sstevel 	if (err != PICL_SUCCESS) {
12003831d35Sstevel 		syslog(LOG_ERR, GETPV, PICL_PROP_DATA_AVAIL, err);
121*ada2da53SToomas Soome 		return (0);
12203831d35Sstevel 	}
12303831d35Sstevel 	err = ptree_get_propval_by_name(fruh, PICL_PROP_SC_HANDLE,
12403831d35Sstevel 	    &container_hdl, sizeof (container_hdl_t));
12503831d35Sstevel 	if (err != PICL_SUCCESS) {
12603831d35Sstevel 		syslog(LOG_ERR, GETPV, PICL_PROP_SC_HANDLE, err);
127*ada2da53SToomas Soome 		return (0);
12803831d35Sstevel 	}
12903831d35Sstevel 	return (container_hdl);
13003831d35Sstevel }
13103831d35Sstevel 
13203831d35Sstevel /*
13303831d35Sstevel  * Note : fru_open_container and fru_close_container do not map onto the opens
13403831d35Sstevel  * and closes of the sgfru device on lw8. There is one sgfru device which
13503831d35Sstevel  * handles all containers.
13603831d35Sstevel  */
13703831d35Sstevel /*ARGSUSED*/
13803831d35Sstevel int
fru_close_container(container_hdl_t fru)13903831d35Sstevel fru_close_container(container_hdl_t fru)
14003831d35Sstevel {
14103831d35Sstevel 	if (fru_open_dev() == -1) {
14203831d35Sstevel 		return (-1);
14303831d35Sstevel 	}
14403831d35Sstevel 	return (0);
14503831d35Sstevel }
14603831d35Sstevel 
14703831d35Sstevel /*ARGSUSED*/
14803831d35Sstevel int
fru_get_num_sections(container_hdl_t container,door_cred_t * cred)14903831d35Sstevel fru_get_num_sections(container_hdl_t container, door_cred_t *cred)
15003831d35Sstevel {
15103831d35Sstevel 	section_info_t numsections;
15203831d35Sstevel 	int fd;
15303831d35Sstevel 
15403831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
15503831d35Sstevel 		return (-1);
15603831d35Sstevel 	}
15703831d35Sstevel 	numsections.hdl = container;
15803831d35Sstevel 	numsections.cnt = 0;
15903831d35Sstevel 	if (ioctl(fd, SGFRU_GETNUMSECTIONS, &numsections) != 0) {
16003831d35Sstevel 		return (-1);
16103831d35Sstevel 	}
16203831d35Sstevel 	return (numsections.cnt);
16303831d35Sstevel }
16403831d35Sstevel 
16503831d35Sstevel /*ARGSUSED*/
16603831d35Sstevel int
fru_get_sections(container_hdl_t container,section_t * section,int max_sections,door_cred_t * cred)16703831d35Sstevel fru_get_sections(container_hdl_t container, section_t *section,
16803831d35Sstevel     int max_sections, door_cred_t *cred)
16903831d35Sstevel {
17003831d35Sstevel 	sections_t sections;
17103831d35Sstevel 	int fd;
17203831d35Sstevel 
17303831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
17403831d35Sstevel 		return (-1);
17503831d35Sstevel 	}
17603831d35Sstevel 	sections.fru_hdl = container;
17703831d35Sstevel 	sections.fru_cnt = max_sections;
17803831d35Sstevel 	sections.frus = section;
17903831d35Sstevel 	if (ioctl(fd, SGFRU_GETSECTIONS, &sections) != 0) {
18003831d35Sstevel 		return (-1);
18103831d35Sstevel 	}
18203831d35Sstevel 	return (sections.fru_cnt);
18303831d35Sstevel }
18403831d35Sstevel 
18503831d35Sstevel /*ARGSUSED*/
18603831d35Sstevel int
fru_get_num_segments(section_hdl_t section,door_cred_t * cred)18703831d35Sstevel fru_get_num_segments(section_hdl_t section, door_cred_t *cred)
18803831d35Sstevel {
18903831d35Sstevel 	segment_info_t numsegments;
19003831d35Sstevel 	int fd;
19103831d35Sstevel 
19203831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
19303831d35Sstevel 		return (-1);
19403831d35Sstevel 	}
19503831d35Sstevel 	numsegments.hdl = section;
19603831d35Sstevel 	numsegments.cnt = 0;
19703831d35Sstevel 	if (ioctl(fd, SGFRU_GETNUMSEGMENTS, &numsegments) != 0) {
19803831d35Sstevel 		return (-1);
19903831d35Sstevel 	}
20003831d35Sstevel 	return (numsegments.cnt);
20103831d35Sstevel }
20203831d35Sstevel 
20303831d35Sstevel /*ARGSUSED*/
20403831d35Sstevel int
fru_get_segments(section_hdl_t section,segment_t * segment,int max_segments,door_cred_t * cred)20503831d35Sstevel fru_get_segments(section_hdl_t section, segment_t *segment, int max_segments,
20603831d35Sstevel     door_cred_t *cred)
20703831d35Sstevel {
20803831d35Sstevel 	segments_t segments;
20903831d35Sstevel 	int fd;
21003831d35Sstevel 
21103831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
21203831d35Sstevel 		return (-1);
21303831d35Sstevel 	}
21403831d35Sstevel 	segments.fru_hdl = section;
21503831d35Sstevel 	segments.fru_cnt = max_segments;
21603831d35Sstevel 	segments.frus = segment;
21703831d35Sstevel 	if (ioctl(fd, SGFRU_GETSEGMENTS, &segments) != 0) {
21803831d35Sstevel 		return (-1);
21903831d35Sstevel 	}
22003831d35Sstevel 	return (segments.fru_cnt);
22103831d35Sstevel }
22203831d35Sstevel 
22303831d35Sstevel /*ARGSUSED*/
22403831d35Sstevel int
fru_add_segment(section_hdl_t section,segment_t * segment,section_hdl_t * newsection,door_cred_t * cred)22503831d35Sstevel fru_add_segment(section_hdl_t section, segment_t *segment,
22603831d35Sstevel     section_hdl_t *newsection, door_cred_t *cred)
22703831d35Sstevel {
22803831d35Sstevel 	segments_t newsegment;
22903831d35Sstevel 	int fd;
23003831d35Sstevel 
23103831d35Sstevel 	/* check the effective uid of the client */
23203831d35Sstevel 	if (cred->dc_euid != 0) {
23303831d35Sstevel 		errno = EPERM;
23403831d35Sstevel 		return (-1);	/* not a root */
23503831d35Sstevel 	}
23603831d35Sstevel 
23703831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
23803831d35Sstevel 		return (-1);
23903831d35Sstevel 	}
24003831d35Sstevel 	newsegment.fru_hdl = section;
24103831d35Sstevel 	newsegment.fru_cnt = 1;
24203831d35Sstevel 	newsegment.frus = segment;
24303831d35Sstevel 	if (ioctl(fd, SGFRU_ADDSEGMENT, &newsegment) != 0) {
24403831d35Sstevel 		return (-1);
24503831d35Sstevel 	}
24603831d35Sstevel 	/*
24703831d35Sstevel 	 * The new segment handle is returned in segment,
24803831d35Sstevel 	 * return the updated section handle in newsection.
24903831d35Sstevel 	 */
25003831d35Sstevel 	*newsection = newsegment.fru_hdl;
25103831d35Sstevel 	return (0);
25203831d35Sstevel }
25303831d35Sstevel 
25403831d35Sstevel int
fru_delete_segment(segment_hdl_t segment,section_hdl_t * newsection,door_cred_t * cred)25503831d35Sstevel fru_delete_segment(segment_hdl_t segment, section_hdl_t *newsection,
25603831d35Sstevel     door_cred_t *cred)
25703831d35Sstevel {
25803831d35Sstevel 	segment_info_t delsegment;
25903831d35Sstevel 	int fd;
26003831d35Sstevel 
26103831d35Sstevel 	/* check the effective uid of the client */
26203831d35Sstevel 	if (cred->dc_euid != 0) {
26303831d35Sstevel 		errno = EPERM;
26403831d35Sstevel 		return (-1);	/* not a root */
26503831d35Sstevel 	}
26603831d35Sstevel 
26703831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
26803831d35Sstevel 		return (-1);
26903831d35Sstevel 	}
27003831d35Sstevel 	delsegment.hdl = segment;
27103831d35Sstevel 	if (ioctl(fd, SGFRU_DELETESEGMENT, &delsegment) != 0) {
27203831d35Sstevel 		return (-1);
27303831d35Sstevel 	}
27403831d35Sstevel 	/* Return the updated section handle in newsection. */
27503831d35Sstevel 	*newsection = delsegment.hdl;
27603831d35Sstevel 	return (0);
27703831d35Sstevel }
27803831d35Sstevel 
27903831d35Sstevel /*ARGSUSED*/
28003831d35Sstevel ssize_t
fru_read_segment(segment_hdl_t segment,void * buffer,size_t nbytes,door_cred_t * cred)28103831d35Sstevel fru_read_segment(segment_hdl_t segment, void *buffer, size_t nbytes,
28203831d35Sstevel     door_cred_t *cred)
28303831d35Sstevel {
28403831d35Sstevel 	segments_t readsegment;
28503831d35Sstevel 	int fd;
28603831d35Sstevel 
28703831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
28803831d35Sstevel 		return (-1);
28903831d35Sstevel 	}
29003831d35Sstevel 	readsegment.fru_hdl = segment;
29103831d35Sstevel 	readsegment.fru_cnt = nbytes;
29203831d35Sstevel 	readsegment.frus = buffer;
29303831d35Sstevel 	if (ioctl(fd, SGFRU_READRAWSEGMENT, &readsegment) != 0) {
29403831d35Sstevel 		return (-1);
29503831d35Sstevel 	}
29603831d35Sstevel 	return ((ssize_t)readsegment.fru_cnt);
29703831d35Sstevel }
29803831d35Sstevel 
29903831d35Sstevel /*ARGSUSED*/
30003831d35Sstevel ssize_t
fru_write_segment(segment_hdl_t segment,const void * buffer,size_t nbytes,segment_hdl_t * newsegment,door_cred_t * cred)30103831d35Sstevel fru_write_segment(segment_hdl_t segment, const void *buffer, size_t nbytes,
30203831d35Sstevel     segment_hdl_t *newsegment, door_cred_t *cred)
30303831d35Sstevel {
30403831d35Sstevel 	segments_t writesegment;
30503831d35Sstevel 	int fd;
30603831d35Sstevel 
30703831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
30803831d35Sstevel 		return (-1);
30903831d35Sstevel 	}
31003831d35Sstevel 	writesegment.fru_hdl = segment;
31103831d35Sstevel 	writesegment.fru_cnt = nbytes;
31203831d35Sstevel 	writesegment.frus = (void *)buffer;
31303831d35Sstevel 	if (ioctl(fd, SGFRU_WRITERAWSEGMENT, &writesegment) != 0) {
31403831d35Sstevel 		return (-1);
31503831d35Sstevel 	}
31603831d35Sstevel 	/* Return the updated segment handle in newsegment. */
31703831d35Sstevel 	*newsegment = writesegment.fru_hdl;
31803831d35Sstevel 	return ((ssize_t)writesegment.fru_cnt);
31903831d35Sstevel }
32003831d35Sstevel 
32103831d35Sstevel /*ARGSUSED*/
32203831d35Sstevel int
fru_get_num_packets(segment_hdl_t segment,door_cred_t * cred)32303831d35Sstevel fru_get_num_packets(segment_hdl_t segment, door_cred_t *cred)
32403831d35Sstevel {
32503831d35Sstevel 	packet_info_t numpackets;
32603831d35Sstevel 	int fd;
32703831d35Sstevel 
32803831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
32903831d35Sstevel 		return (-1);
33003831d35Sstevel 	}
33103831d35Sstevel 	numpackets.hdl = segment;
33203831d35Sstevel 	numpackets.cnt = 0;
33303831d35Sstevel 	if (ioctl(fd, SGFRU_GETNUMPACKETS, &numpackets) != 0) {
33403831d35Sstevel 		return (-1);
33503831d35Sstevel 	}
33603831d35Sstevel 	return (numpackets.cnt);
33703831d35Sstevel }
33803831d35Sstevel 
33903831d35Sstevel /*ARGSUSED*/
34003831d35Sstevel int
fru_get_packets(segment_hdl_t segment,packet_t * packet,int max_packets,door_cred_t * cred)34103831d35Sstevel fru_get_packets(segment_hdl_t segment, packet_t *packet, int max_packets,
34203831d35Sstevel     door_cred_t *cred)
34303831d35Sstevel {
34403831d35Sstevel 	packets_t packets;
34503831d35Sstevel 	int fd;
34603831d35Sstevel 
34703831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
34803831d35Sstevel 		return (-1);
34903831d35Sstevel 	}
35003831d35Sstevel 	packets.fru_hdl = segment;
35103831d35Sstevel 	packets.fru_cnt = max_packets;
35203831d35Sstevel 	packets.frus = packet;
35303831d35Sstevel 	if (ioctl(fd, SGFRU_GETPACKETS, &packets) != 0) {
35403831d35Sstevel 		return (-1);
35503831d35Sstevel 	}
35603831d35Sstevel 	return (packets.fru_cnt);
35703831d35Sstevel }
35803831d35Sstevel 
35903831d35Sstevel /*ARGSUSED*/
36003831d35Sstevel ssize_t
fru_get_payload(packet_hdl_t packet,void * buffer,size_t nbytes,door_cred_t * cred)36103831d35Sstevel fru_get_payload(packet_hdl_t packet, void *buffer, size_t nbytes,
36203831d35Sstevel     door_cred_t *cred)
36303831d35Sstevel {
36403831d35Sstevel 	payload_t payload;
36503831d35Sstevel 	int fd;
36603831d35Sstevel 
36703831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
36803831d35Sstevel 		return (-1);
36903831d35Sstevel 	}
37003831d35Sstevel 	payload.fru_hdl = packet;
37103831d35Sstevel 	payload.fru_cnt = nbytes;
37203831d35Sstevel 	payload.frus = buffer;
37303831d35Sstevel 	if (ioctl(fd, SGFRU_GETPAYLOAD, &payload) != 0) {
37403831d35Sstevel 		return (-1);
37503831d35Sstevel 	}
37603831d35Sstevel 	return ((ssize_t)payload.fru_cnt);
37703831d35Sstevel }
37803831d35Sstevel 
37903831d35Sstevel int
fru_update_payload(packet_hdl_t packet,const void * data,size_t nbytes,packet_hdl_t * newpacket,door_cred_t * cred)38003831d35Sstevel fru_update_payload(packet_hdl_t packet, const void *data, size_t nbytes,
38103831d35Sstevel     packet_hdl_t *newpacket, door_cred_t *cred)
38203831d35Sstevel {
38303831d35Sstevel 	payload_t payload;
38403831d35Sstevel 	int fd;
38503831d35Sstevel 
38603831d35Sstevel 	/* check the effective uid of the client */
38703831d35Sstevel 	if (cred->dc_euid != 0) {
38803831d35Sstevel 		errno = EPERM;
38903831d35Sstevel 		return (-1);	/* not a root */
39003831d35Sstevel 	}
39103831d35Sstevel 
39203831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
39303831d35Sstevel 		return (-1);
39403831d35Sstevel 	}
39503831d35Sstevel 	payload.fru_hdl = packet;
39603831d35Sstevel 	payload.fru_cnt = nbytes;
39703831d35Sstevel 	payload.frus = (void *)data;
39803831d35Sstevel 	if (ioctl(fd, SGFRU_UPDATEPAYLOAD, &payload) != 0) {
39903831d35Sstevel 		return (-1);
40003831d35Sstevel 	}
40103831d35Sstevel 	/* Return the updated packet handle in newpacket. */
40203831d35Sstevel 	*newpacket = payload.fru_hdl;
40303831d35Sstevel 	return (0);
40403831d35Sstevel }
40503831d35Sstevel 
40603831d35Sstevel 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)40703831d35Sstevel fru_append_packet(segment_hdl_t segment, packet_t *packet, const void *payload,
40803831d35Sstevel     size_t nbytes, segment_hdl_t *newsegment, door_cred_t *cred)
40903831d35Sstevel {
41003831d35Sstevel 	append_info_t appendpkt;
41103831d35Sstevel 	int fd;
41203831d35Sstevel 
41303831d35Sstevel 	/* check the effective uid of the client */
41403831d35Sstevel 	if (cred->dc_euid != 0) {
41503831d35Sstevel 		errno = EPERM;
41603831d35Sstevel 		return (-1);	/* not a root */
41703831d35Sstevel 	}
41803831d35Sstevel 
41903831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
42003831d35Sstevel 		return (-1);
42103831d35Sstevel 	}
42203831d35Sstevel 	appendpkt.packet = *packet;
42303831d35Sstevel 	appendpkt.payload_hdl = segment;
42403831d35Sstevel 	appendpkt.payload_cnt = nbytes;
42503831d35Sstevel 	appendpkt.payload_data = (void *)payload;
42603831d35Sstevel 	if (ioctl(fd, SGFRU_APPENDPACKET, &appendpkt) != 0) {
42703831d35Sstevel 		return (-1);
42803831d35Sstevel 	}
42903831d35Sstevel 	/*
43003831d35Sstevel 	 * The new packet handle is returned in packet,
43103831d35Sstevel 	 * return the updated segment handle in newsegment.
43203831d35Sstevel 	 */
43303831d35Sstevel 	packet->handle = appendpkt.packet.handle;
43403831d35Sstevel 	*newsegment = appendpkt.payload_hdl;
43503831d35Sstevel 	return (0);
43603831d35Sstevel }
43703831d35Sstevel 
43803831d35Sstevel int
fru_delete_packet(packet_hdl_t packet,segment_hdl_t * newsegment,door_cred_t * cred)43903831d35Sstevel fru_delete_packet(packet_hdl_t packet, segment_hdl_t *newsegment,
44003831d35Sstevel     door_cred_t *cred)
44103831d35Sstevel {
44203831d35Sstevel 	packet_info_t delpacket;
44303831d35Sstevel 	int fd;
44403831d35Sstevel 
44503831d35Sstevel 	/* check the effective uid of the client */
44603831d35Sstevel 	if (cred->dc_euid != 0) {
44703831d35Sstevel 		errno = EPERM;
44803831d35Sstevel 		return (-1);	/* not a root */
44903831d35Sstevel 	}
45003831d35Sstevel 
45103831d35Sstevel 	if ((fd = fru_open_dev()) == -1) {
45203831d35Sstevel 		return (-1);
45303831d35Sstevel 	}
45403831d35Sstevel 	delpacket.hdl = packet;
45503831d35Sstevel 	if (ioctl(fd, SGFRU_DELETEPACKET, &delpacket) != 0) {
45603831d35Sstevel 		return (-1);
45703831d35Sstevel 	}
45803831d35Sstevel 	/* Return the updated segment handle in newsegment. */
45903831d35Sstevel 	*newsegment = delpacket.hdl;
46003831d35Sstevel 	return (0);
46103831d35Sstevel }
46203831d35Sstevel 
46303831d35Sstevel /*
46403831d35Sstevel  * Description :
46503831d35Sstevel  *		fru_is_data_available() checks to see if the frudata
46603831d35Sstevel  *		is available on a fru.
46703831d35Sstevel  *
46803831d35Sstevel  * Arguments   :
46903831d35Sstevel  *		picl_nodehdl_t holds the picl node handle of the fru.
47003831d35Sstevel  *
47103831d35Sstevel  * Return      :
47203831d35Sstevel  *		int
47303831d35Sstevel  *		return 1: if FRUID information is available
47403831d35Sstevel  *		return 0: if FRUID information is not present
47503831d35Sstevel  *
47603831d35Sstevel  */
47703831d35Sstevel 
47803831d35Sstevel /* ARGSUSED */
47903831d35Sstevel int
fru_is_data_available(picl_nodehdl_t fru)48003831d35Sstevel fru_is_data_available(picl_nodehdl_t fru)
48103831d35Sstevel {
48203831d35Sstevel 	return (0);
48303831d35Sstevel }
484