xref: /illumos-gate/usr/src/lib/libsmedia/plugins/blkdev/common/b_generic.c (revision 430062b0bc38ddbe5eda3921705af71cd2c44260)
1*3f7d54a6SGarrett D'Amore /*
2*3f7d54a6SGarrett D'Amore  * CDDL HEADER START
3*3f7d54a6SGarrett D'Amore  *
4*3f7d54a6SGarrett D'Amore  * The contents of this file are subject to the terms of the
5*3f7d54a6SGarrett D'Amore  * Common Development and Distribution License (the "License").
6*3f7d54a6SGarrett D'Amore  * You may not use this file except in compliance with the License.
7*3f7d54a6SGarrett D'Amore  *
8*3f7d54a6SGarrett D'Amore  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*3f7d54a6SGarrett D'Amore  * or http://www.opensolaris.org/os/licensing.
10*3f7d54a6SGarrett D'Amore  * See the License for the specific language governing permissions
11*3f7d54a6SGarrett D'Amore  * and limitations under the License.
12*3f7d54a6SGarrett D'Amore  *
13*3f7d54a6SGarrett D'Amore  * When distributing Covered Code, include this CDDL HEADER in each
14*3f7d54a6SGarrett D'Amore  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*3f7d54a6SGarrett D'Amore  * If applicable, add the following below this CDDL HEADER, with the
16*3f7d54a6SGarrett D'Amore  * fields enclosed by brackets "[]" replaced with your own identifying
17*3f7d54a6SGarrett D'Amore  * information: Portions Copyright [yyyy] [name of copyright owner]
18*3f7d54a6SGarrett D'Amore  *
19*3f7d54a6SGarrett D'Amore  * CDDL HEADER END
20*3f7d54a6SGarrett D'Amore  */
21*3f7d54a6SGarrett D'Amore /*
22*3f7d54a6SGarrett D'Amore  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23*3f7d54a6SGarrett D'Amore  */
24*3f7d54a6SGarrett D'Amore 
25*3f7d54a6SGarrett D'Amore /*
26*3f7d54a6SGarrett D'Amore  * b_generic.c :
27*3f7d54a6SGarrett D'Amore  *      This file contains the functions for generic block devices
28*3f7d54a6SGarrett D'Amore  *	for libsmedia.
29*3f7d54a6SGarrett D'Amore  */
30*3f7d54a6SGarrett D'Amore 
31*3f7d54a6SGarrett D'Amore #include <stdio.h>
32*3f7d54a6SGarrett D'Amore #include <unistd.h>
33*3f7d54a6SGarrett D'Amore #include <locale.h>
34*3f7d54a6SGarrett D'Amore #include <sys/types.h>
35*3f7d54a6SGarrett D'Amore #include <sys/param.h>
36*3f7d54a6SGarrett D'Amore #include <sys/dkio.h>
37*3f7d54a6SGarrett D'Amore #include <string.h>
38*3f7d54a6SGarrett D'Amore #include "../../../library/inc/smedia.h"
39*3f7d54a6SGarrett D'Amore #include "../../../library/inc/rmedia.h"
40*3f7d54a6SGarrett D'Amore #include "../../../library/common/l_defines.h"
41*3f7d54a6SGarrett D'Amore 
42*3f7d54a6SGarrett D'Amore #define	PERROR(string)	my_perror(gettext(string))
43*3f7d54a6SGarrett D'Amore 
44*3f7d54a6SGarrett D'Amore static void
my_perror(char * err_string)45*3f7d54a6SGarrett D'Amore my_perror(char *err_string)
46*3f7d54a6SGarrett D'Amore {
47*3f7d54a6SGarrett D'Amore 
48*3f7d54a6SGarrett D'Amore 	int error_no;
49*3f7d54a6SGarrett D'Amore 	if (errno == 0)
50*3f7d54a6SGarrett D'Amore 		return;
51*3f7d54a6SGarrett D'Amore 
52*3f7d54a6SGarrett D'Amore 	error_no = errno;
53*3f7d54a6SGarrett D'Amore 	(void) fprintf(stderr, gettext(err_string));
54*3f7d54a6SGarrett D'Amore 	(void) fprintf(stderr, gettext(" : "));
55*3f7d54a6SGarrett D'Amore 	errno = error_no;
56*3f7d54a6SGarrett D'Amore 	perror("");
57*3f7d54a6SGarrett D'Amore }
58*3f7d54a6SGarrett D'Amore 
59*3f7d54a6SGarrett D'Amore int32_t
_m_version_no(void)60*3f7d54a6SGarrett D'Amore _m_version_no(void)
61*3f7d54a6SGarrett D'Amore {
62*3f7d54a6SGarrett D'Amore 	return (SM_BLKDEV_VERSION_1);
63*3f7d54a6SGarrett D'Amore }
64*3f7d54a6SGarrett D'Amore 
65*3f7d54a6SGarrett D'Amore int32_t
_m_device_type(ushort_t ctype,ushort_t mtype)66*3f7d54a6SGarrett D'Amore _m_device_type(ushort_t ctype, ushort_t mtype)
67*3f7d54a6SGarrett D'Amore {
68*3f7d54a6SGarrett D'Amore 	if (ctype == DKC_BLKDEV) {
69*3f7d54a6SGarrett D'Amore 		if (mtype == 0)
70*3f7d54a6SGarrett D'Amore 			return (0);
71*3f7d54a6SGarrett D'Amore 	}
72*3f7d54a6SGarrett D'Amore 	return (-1);
73*3f7d54a6SGarrett D'Amore }
74*3f7d54a6SGarrett D'Amore 
75*3f7d54a6SGarrett D'Amore 
76*3f7d54a6SGarrett D'Amore int32_t
_m_get_media_info(rmedia_handle_t * handle,void * ip)77*3f7d54a6SGarrett D'Amore _m_get_media_info(rmedia_handle_t *handle, void *ip)
78*3f7d54a6SGarrett D'Amore {
79*3f7d54a6SGarrett D'Amore 	smmedium_prop_t *mp = (smmedium_prop_t *)ip;
80*3f7d54a6SGarrett D'Amore 	struct dk_geom		dkg;
81*3f7d54a6SGarrett D'Amore 	struct dk_minfo		minfo;
82*3f7d54a6SGarrett D'Amore 	enum dkio_state		state = DKIO_NONE;
83*3f7d54a6SGarrett D'Amore 	int			ret_val;
84*3f7d54a6SGarrett D'Amore 
85*3f7d54a6SGarrett D'Amore 	if (handle == NULL) {
86*3f7d54a6SGarrett D'Amore 		DPRINTF("Null Handle\n");
87*3f7d54a6SGarrett D'Amore 		errno = EINVAL;
88*3f7d54a6SGarrett D'Amore 		return (-1);
89*3f7d54a6SGarrett D'Amore 	}
90*3f7d54a6SGarrett D'Amore 	if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
91*3f7d54a6SGarrett D'Amore 		DPRINTF2("Signature expected=0x%x, found=0x%x\n",
92*3f7d54a6SGarrett D'Amore 		    LIBSMEDIA_SIGNATURE, handle->sm_signature);
93*3f7d54a6SGarrett D'Amore 		errno = EINVAL;
94*3f7d54a6SGarrett D'Amore 		return (-1);
95*3f7d54a6SGarrett D'Amore 	}
96*3f7d54a6SGarrett D'Amore 
97*3f7d54a6SGarrett D'Amore 	if (ioctl(handle->sm_fd, DKIOCSTATE, &state) < 0) {
98*3f7d54a6SGarrett D'Amore 		PERROR("DKIOCSTATE failed");
99*3f7d54a6SGarrett D'Amore 		return (-1);
100*3f7d54a6SGarrett D'Amore 	}
101*3f7d54a6SGarrett D'Amore 
102*3f7d54a6SGarrett D'Amore 	if (state != DKIO_INSERTED) {
103*3f7d54a6SGarrett D'Amore 		DPRINTF("No media.\n");
104*3f7d54a6SGarrett D'Amore 		mp->sm_media_type = SM_NOT_PRESENT;
105*3f7d54a6SGarrett D'Amore 		mp->sm_version = SMMEDIA_PROP_V_1;
106*3f7d54a6SGarrett D'Amore 		return (0);
107*3f7d54a6SGarrett D'Amore 
108*3f7d54a6SGarrett D'Amore 	}
109*3f7d54a6SGarrett D'Amore 
110*3f7d54a6SGarrett D'Amore 	ret_val = ioctl(handle->sm_fd, DKIOCGMEDIAINFO, &minfo);
111*3f7d54a6SGarrett D'Amore 	if (ret_val < 0) {
112*3f7d54a6SGarrett D'Amore 		DPRINTF("DKIOCGMEDIAINFO ioctl failed");
113*3f7d54a6SGarrett D'Amore 		return (ret_val);
114*3f7d54a6SGarrett D'Amore 	}
115*3f7d54a6SGarrett D'Amore 	ret_val = ioctl(handle->sm_fd, DKIOCGGEOM, &dkg);
116*3f7d54a6SGarrett D'Amore 	if (ret_val < 0) {
117*3f7d54a6SGarrett D'Amore 		DPRINTF("DKIOCGGEOM ioctl failed");
118*3f7d54a6SGarrett D'Amore 		return (ret_val);
119*3f7d54a6SGarrett D'Amore 	}
120*3f7d54a6SGarrett D'Amore 
121*3f7d54a6SGarrett D'Amore 	mp->sm_media_type = SM_BLOCK;
122*3f7d54a6SGarrett D'Amore 	mp->sm_blocksize = minfo.dki_lbsize;
123*3f7d54a6SGarrett D'Amore 	mp->sm_capacity = minfo.dki_capacity;
124*3f7d54a6SGarrett D'Amore 	mp->sm_pcyl = dkg.dkg_pcyl;
125*3f7d54a6SGarrett D'Amore 	mp->sm_nhead = dkg.dkg_nhead;
126*3f7d54a6SGarrett D'Amore 	mp->sm_nsect = dkg.dkg_nsect;
127*3f7d54a6SGarrett D'Amore 	return (0);
128*3f7d54a6SGarrett D'Amore }
129*3f7d54a6SGarrett D'Amore 
130*3f7d54a6SGarrett D'Amore 
131*3f7d54a6SGarrett D'Amore 
132*3f7d54a6SGarrett D'Amore /* ARGSUSED0 */
133*3f7d54a6SGarrett D'Amore 
134*3f7d54a6SGarrett D'Amore int32_t
_m_get_device_info(rmedia_handle_t * handle,void * ip)135*3f7d54a6SGarrett D'Amore _m_get_device_info(rmedia_handle_t *handle, void *ip)
136*3f7d54a6SGarrett D'Amore {
137*3f7d54a6SGarrett D'Amore 	smdevice_info_t *mp = (smdevice_info_t *)ip;
138*3f7d54a6SGarrett D'Amore 	char *vendor_name, *product_name, *fw_version;
139*3f7d54a6SGarrett D'Amore 
140*3f7d54a6SGarrett D'Amore 	if (handle == NULL) {
141*3f7d54a6SGarrett D'Amore 		DPRINTF("Null Handle\n");
142*3f7d54a6SGarrett D'Amore 		errno = EINVAL;
143*3f7d54a6SGarrett D'Amore 		return (-1);
144*3f7d54a6SGarrett D'Amore 	}
145*3f7d54a6SGarrett D'Amore 	if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
146*3f7d54a6SGarrett D'Amore 		DPRINTF2("Signature expected=0x%x, found=0x%x\n",
147*3f7d54a6SGarrett D'Amore 		    LIBSMEDIA_SIGNATURE, handle->sm_signature);
148*3f7d54a6SGarrett D'Amore 		errno = EINVAL;
149*3f7d54a6SGarrett D'Amore 		return (-1);
150*3f7d54a6SGarrett D'Amore 	}
151*3f7d54a6SGarrett D'Amore 	vendor_name = (char *)malloc(1);
152*3f7d54a6SGarrett D'Amore 	if (vendor_name == NULL) {
153*3f7d54a6SGarrett D'Amore 		if (!errno)
154*3f7d54a6SGarrett D'Amore 			errno = ENOMEM;
155*3f7d54a6SGarrett D'Amore 		return (-1);
156*3f7d54a6SGarrett D'Amore 	}
157*3f7d54a6SGarrett D'Amore 	product_name = (char *)malloc(1);
158*3f7d54a6SGarrett D'Amore 	if (product_name == NULL) {
159*3f7d54a6SGarrett D'Amore 		free(vendor_name);
160*3f7d54a6SGarrett D'Amore 		if (!errno)
161*3f7d54a6SGarrett D'Amore 			errno = ENOMEM;
162*3f7d54a6SGarrett D'Amore 		return (-1);
163*3f7d54a6SGarrett D'Amore 	}
164*3f7d54a6SGarrett D'Amore 
165*3f7d54a6SGarrett D'Amore 	fw_version = (char *)malloc(1);
166*3f7d54a6SGarrett D'Amore 	if (fw_version == NULL) {
167*3f7d54a6SGarrett D'Amore 		free(vendor_name);
168*3f7d54a6SGarrett D'Amore 		free(product_name);
169*3f7d54a6SGarrett D'Amore 			if (!errno)
170*3f7d54a6SGarrett D'Amore 		errno = ENOMEM;
171*3f7d54a6SGarrett D'Amore 		return (-1);
172*3f7d54a6SGarrett D'Amore 	}
173*3f7d54a6SGarrett D'Amore 
174*3f7d54a6SGarrett D'Amore 	/* Note: we could potentially offer more here */
175*3f7d54a6SGarrett D'Amore 	vendor_name[0] = 0;
176*3f7d54a6SGarrett D'Amore 	product_name[0] = 0;
177*3f7d54a6SGarrett D'Amore 	fw_version[0] = 0;
178*3f7d54a6SGarrett D'Amore 	mp->sm_interface_type = IF_BLOCK;
179*3f7d54a6SGarrett D'Amore 	mp->sm_vendor_name = vendor_name;
180*3f7d54a6SGarrett D'Amore 	mp->sm_product_name = product_name;
181*3f7d54a6SGarrett D'Amore 	mp->sm_firmware_version = fw_version;
182*3f7d54a6SGarrett D'Amore 	return (0);
183*3f7d54a6SGarrett D'Amore }
184*3f7d54a6SGarrett D'Amore 
185*3f7d54a6SGarrett D'Amore int32_t
_m_free_device_info(rmedia_handle_t * handle,void * ip)186*3f7d54a6SGarrett D'Amore _m_free_device_info(rmedia_handle_t *handle, void *ip)
187*3f7d54a6SGarrett D'Amore {
188*3f7d54a6SGarrett D'Amore 	struct smdevice_info *dev_info = ip;
189*3f7d54a6SGarrett D'Amore 
190*3f7d54a6SGarrett D'Amore 	/* Check for valid handle */
191*3f7d54a6SGarrett D'Amore 	if (handle == NULL) {
192*3f7d54a6SGarrett D'Amore 		DPRINTF("Null Handle\n");
193*3f7d54a6SGarrett D'Amore 		errno = EINVAL;
194*3f7d54a6SGarrett D'Amore 		return (-1);
195*3f7d54a6SGarrett D'Amore 	}
196*3f7d54a6SGarrett D'Amore 	if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
197*3f7d54a6SGarrett D'Amore 		DPRINTF("Invalid signature in handle.\n");
198*3f7d54a6SGarrett D'Amore 		errno = EINVAL;
199*3f7d54a6SGarrett D'Amore 		return (-1);
200*3f7d54a6SGarrett D'Amore 	}
201*3f7d54a6SGarrett D'Amore 
202*3f7d54a6SGarrett D'Amore 	free(dev_info->sm_vendor_name);
203*3f7d54a6SGarrett D'Amore 	free(dev_info->sm_product_name);
204*3f7d54a6SGarrett D'Amore 	free(dev_info->sm_firmware_version);
205*3f7d54a6SGarrett D'Amore 	return (0);
206*3f7d54a6SGarrett D'Amore }
207