17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51ae08745Sheppo  * Common Development and Distribution License (the "License").
61ae08745Sheppo  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
211ae08745Sheppo 
227c478bd9Sstevel@tonic-gate /*
23*0d63ce2bSvenki  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include <stdio.h>
287c478bd9Sstevel@tonic-gate #include <unistd.h>
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <alloca.h>
327c478bd9Sstevel@tonic-gate #include <sys/stat.h>
337c478bd9Sstevel@tonic-gate #include <malloc.h>
347c478bd9Sstevel@tonic-gate #include <fcntl.h>
357c478bd9Sstevel@tonic-gate #include <syslog.h>
367c478bd9Sstevel@tonic-gate #include <mdesc.h>
377c478bd9Sstevel@tonic-gate #include <string.h>
387c478bd9Sstevel@tonic-gate #include <errno.h>
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #define	MDESC_PATH	"/devices/pseudo/mdesc@0:mdesc"
417c478bd9Sstevel@tonic-gate 
4226cf27f0Sla static void mdesc_free(void *bufp, size_t size);
43*0d63ce2bSvenki uint64_t *md_bufp;
4426cf27f0Sla 
457c478bd9Sstevel@tonic-gate md_t *
mdesc_devinit(void)467c478bd9Sstevel@tonic-gate mdesc_devinit(void)
477c478bd9Sstevel@tonic-gate {
48*0d63ce2bSvenki 	int fd;
497c478bd9Sstevel@tonic-gate 	md_t *mdp;
50*0d63ce2bSvenki 	size_t size;
517c478bd9Sstevel@tonic-gate 
52*0d63ce2bSvenki 	/*
53*0d63ce2bSvenki 	 * We haven't finished using the previous MD/PRI info.
54*0d63ce2bSvenki 	 */
551ae08745Sheppo 	if (md_bufp != NULL)
561ae08745Sheppo 		return (NULL);
571ae08745Sheppo 
587c478bd9Sstevel@tonic-gate 	do {
59*0d63ce2bSvenki 		if ((fd = open(MDESC_PATH, O_RDONLY, 0)) < 0)
60*0d63ce2bSvenki 			break;
61*0d63ce2bSvenki 
62*0d63ce2bSvenki 		if (ioctl(fd, MDESCIOCGSZ, &size) < 0)
63*0d63ce2bSvenki 			break;
64*0d63ce2bSvenki 		if ((md_bufp = (uint64_t *)malloc(size)) == NULL) {
65*0d63ce2bSvenki 			(void) close(fd);
66*0d63ce2bSvenki 			break;
677c478bd9Sstevel@tonic-gate 		}
687c478bd9Sstevel@tonic-gate 
69*0d63ce2bSvenki 		/*
70*0d63ce2bSvenki 		 * A partial read is as bad as a failed read.
71*0d63ce2bSvenki 		 */
72*0d63ce2bSvenki 		if (read(fd, md_bufp, size) != size) {
731ae08745Sheppo 			free(md_bufp);
74*0d63ce2bSvenki 			md_bufp = NULL;
757c478bd9Sstevel@tonic-gate 		}
767c478bd9Sstevel@tonic-gate 
77*0d63ce2bSvenki 		(void) close(fd);
78*0d63ce2bSvenki 	/*LINTED: E_CONSTANT_CONDITION */
79*0d63ce2bSvenki 	} while (0);
807c478bd9Sstevel@tonic-gate 
81*0d63ce2bSvenki 	if (md_bufp) {
82*0d63ce2bSvenki 		mdp = md_init_intern(md_bufp, malloc, mdesc_free);
83*0d63ce2bSvenki 		if (mdp == NULL) {
84*0d63ce2bSvenki 			free(md_bufp);
85*0d63ce2bSvenki 			md_bufp = NULL;
86*0d63ce2bSvenki 		}
87*0d63ce2bSvenki 	} else
88*0d63ce2bSvenki 		mdp = NULL;
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	return (mdp);
917c478bd9Sstevel@tonic-gate }
9226cf27f0Sla 
9326cf27f0Sla /*ARGSUSED*/
9426cf27f0Sla void
mdesc_free(void * bufp,size_t size)9526cf27f0Sla mdesc_free(void *bufp, size_t size)
9626cf27f0Sla {
971ae08745Sheppo 	if (bufp)
981ae08745Sheppo 		free(bufp);
991ae08745Sheppo }
1001ae08745Sheppo 
1011ae08745Sheppo void
mdesc_devfini(md_t * mdp)1021ae08745Sheppo mdesc_devfini(md_t *mdp)
1031ae08745Sheppo {
1041ae08745Sheppo 	if (mdp)
1051ae08745Sheppo 		(void) md_fini(mdp);
1061ae08745Sheppo 
1071ae08745Sheppo 	if (md_bufp)
1081ae08745Sheppo 		free(md_bufp);
1091ae08745Sheppo 	md_bufp = NULL;
11026cf27f0Sla }
111