1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright (c) 2001 by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate  * All rights reserved.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * a_generic.c :
31*0Sstevel@tonic-gate  *      This file contains generic PCATA related functions for pcata plug-in
32*0Sstevel@tonic-gate  * 	for libsm.so.
33*0Sstevel@tonic-gate  */
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #include <sys/types.h>
36*0Sstevel@tonic-gate #include <sys/stat.h>
37*0Sstevel@tonic-gate #include <sys/ioctl.h>
38*0Sstevel@tonic-gate #include <dirent.h>
39*0Sstevel@tonic-gate #include <fcntl.h>
40*0Sstevel@tonic-gate #include <sys/dkio.h>
41*0Sstevel@tonic-gate #include <sys/dktp/dadkio.h>
42*0Sstevel@tonic-gate #include <string.h>
43*0Sstevel@tonic-gate #include "../../../library/inc/smedia.h"
44*0Sstevel@tonic-gate #include "../../../library/inc/rmedia.h"
45*0Sstevel@tonic-gate #include "../../../library/common/l_defines.h"
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate #define	PERROR(string)  my_perror(gettext(string))
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate static void
my_perror(char * err_string)50*0Sstevel@tonic-gate my_perror(char *err_string)
51*0Sstevel@tonic-gate {
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate 	int error_no;
54*0Sstevel@tonic-gate 	if (errno == 0)
55*0Sstevel@tonic-gate 		return;
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate 	error_no = errno;
58*0Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(err_string));
59*0Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(" : "));
60*0Sstevel@tonic-gate 	errno = error_no;
61*0Sstevel@tonic-gate 	perror("");
62*0Sstevel@tonic-gate }
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate int32_t
_m_version_no(void)65*0Sstevel@tonic-gate _m_version_no(void)
66*0Sstevel@tonic-gate {
67*0Sstevel@tonic-gate 	return (SM_PCATA_VERSION_1);
68*0Sstevel@tonic-gate }
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate int32_t
_m_device_type(ushort_t ctype,ushort_t mtype)71*0Sstevel@tonic-gate _m_device_type(ushort_t ctype, ushort_t mtype)
72*0Sstevel@tonic-gate {
73*0Sstevel@tonic-gate 	if (ctype == DKC_PCMCIA_ATA) {
74*0Sstevel@tonic-gate 		if (mtype == 0)
75*0Sstevel@tonic-gate 			return (0);
76*0Sstevel@tonic-gate 	}
77*0Sstevel@tonic-gate 	return (-1);
78*0Sstevel@tonic-gate }
79*0Sstevel@tonic-gate 
80*0Sstevel@tonic-gate 
81*0Sstevel@tonic-gate int32_t
_m_get_media_info(rmedia_handle_t * handle,void * ip)82*0Sstevel@tonic-gate _m_get_media_info(rmedia_handle_t *handle, void *ip)
83*0Sstevel@tonic-gate {
84*0Sstevel@tonic-gate 	smmedium_prop_t *medinfo = ip;
85*0Sstevel@tonic-gate 	struct dk_minfo media_info;
86*0Sstevel@tonic-gate 	struct dk_geom	dkgeom;
87*0Sstevel@tonic-gate 	int32_t ret_val;
88*0Sstevel@tonic-gate 	enum dkio_state state = DKIO_NONE;
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate 	if (handle == NULL) {
91*0Sstevel@tonic-gate 		DPRINTF("Null Handle\n");
92*0Sstevel@tonic-gate 		errno = EINVAL;
93*0Sstevel@tonic-gate 		return (-1);
94*0Sstevel@tonic-gate 	}
95*0Sstevel@tonic-gate 	if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
96*0Sstevel@tonic-gate 		DPRINTF2(
97*0Sstevel@tonic-gate 		    "Signature expected=0x%x, found=0x%x\n",
98*0Sstevel@tonic-gate 		    LIBSMEDIA_SIGNATURE, handle->sm_signature);
99*0Sstevel@tonic-gate 		errno = EINVAL;
100*0Sstevel@tonic-gate 		return (-1);
101*0Sstevel@tonic-gate 	}
102*0Sstevel@tonic-gate 	if (handle->sm_fd < 0) {
103*0Sstevel@tonic-gate 		DPRINTF("Invalid file handle.\n");
104*0Sstevel@tonic-gate 		errno = EINVAL;
105*0Sstevel@tonic-gate 		return (-1);
106*0Sstevel@tonic-gate 	}
107*0Sstevel@tonic-gate 	if (ioctl(handle->sm_fd, DKIOCSTATE, &state) < 0) {
108*0Sstevel@tonic-gate 		PERROR("DKIOCSTATE failed");
109*0Sstevel@tonic-gate 		return (-1);
110*0Sstevel@tonic-gate 	}
111*0Sstevel@tonic-gate 	if (state != DKIO_INSERTED) {
112*0Sstevel@tonic-gate 		DPRINTF("No media.\n");
113*0Sstevel@tonic-gate 		medinfo->sm_media_type = SM_NOT_PRESENT;
114*0Sstevel@tonic-gate 		medinfo->sm_version = SMMEDIA_PROP_V_1;
115*0Sstevel@tonic-gate 		return (0);
116*0Sstevel@tonic-gate 	}
117*0Sstevel@tonic-gate 
118*0Sstevel@tonic-gate 	(void) memset((void *) medinfo, 0, sizeof (smmedium_prop_t));
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate 	ret_val = ioctl(handle->sm_fd, DKIOCGMEDIAINFO, &media_info);
121*0Sstevel@tonic-gate 	if (ret_val < 0) {
122*0Sstevel@tonic-gate 		DPRINTF("DKIOCGMEDIAINFO ioctl failed");
123*0Sstevel@tonic-gate 		return (ret_val);
124*0Sstevel@tonic-gate 	}
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate 	medinfo->sm_media_type = media_info.dki_media_type;
127*0Sstevel@tonic-gate 	medinfo->sm_blocksize = media_info.dki_lbsize;
128*0Sstevel@tonic-gate 	medinfo->sm_capacity = media_info.dki_capacity;
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate 	/* Is it a removable magnetic disk? */
131*0Sstevel@tonic-gate 	if (medinfo->sm_media_type == DK_FIXED_DISK) {
132*0Sstevel@tonic-gate 		int32_t removable = 0;
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate 		ret_val = ioctl(handle->sm_fd, DKIOCREMOVABLE, &removable);
135*0Sstevel@tonic-gate 		if (ret_val < 0) {
136*0Sstevel@tonic-gate 			DPRINTF("DKIOCREMOVABLE ioctl failed");
137*0Sstevel@tonic-gate 			return (ret_val);
138*0Sstevel@tonic-gate 		}
139*0Sstevel@tonic-gate 		if (removable) {
140*0Sstevel@tonic-gate 			medinfo->sm_media_type = SM_PCMCIA_ATA;
141*0Sstevel@tonic-gate 		}
142*0Sstevel@tonic-gate 	}
143*0Sstevel@tonic-gate 	ret_val = ioctl(handle->sm_fd, DKIOCGGEOM, &dkgeom);
144*0Sstevel@tonic-gate 	if (ret_val < 0) {
145*0Sstevel@tonic-gate #ifdef sparc
146*0Sstevel@tonic-gate 		DPRINTF("DKIOCGGEOM ioctl failed");
147*0Sstevel@tonic-gate 		return (ret_val);
148*0Sstevel@tonic-gate #else /* !sparc */
149*0Sstevel@tonic-gate 		/*
150*0Sstevel@tonic-gate 		 * Try getting Physical geometry on x86.
151*0Sstevel@tonic-gate 		 */
152*0Sstevel@tonic-gate 		ret_val = ioctl(handle->sm_fd, DKIOCG_PHYGEOM, &dkgeom);
153*0Sstevel@tonic-gate 		if (ret_val < 0) {
154*0Sstevel@tonic-gate 			DPRINTF("DKIOCG_PHYGEOM ioctl failed");
155*0Sstevel@tonic-gate 			return (ret_val);
156*0Sstevel@tonic-gate 		}
157*0Sstevel@tonic-gate #endif /* sparc */
158*0Sstevel@tonic-gate 	}
159*0Sstevel@tonic-gate 
160*0Sstevel@tonic-gate 	medinfo->sm_pcyl = dkgeom.dkg_pcyl;
161*0Sstevel@tonic-gate 	medinfo->sm_nhead = dkgeom.dkg_nhead;
162*0Sstevel@tonic-gate 	medinfo->sm_nsect = dkgeom.dkg_nsect;
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 	return (0);
165*0Sstevel@tonic-gate }
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate /* ARGSUSED0 */
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate int32_t
_m_get_device_info(rmedia_handle_t * handle,void * ip)170*0Sstevel@tonic-gate _m_get_device_info(rmedia_handle_t *handle, void *ip)
171*0Sstevel@tonic-gate {
172*0Sstevel@tonic-gate 	smdevice_info_t *mp = (smdevice_info_t *)ip;
173*0Sstevel@tonic-gate 	char *vendor_name, *product_name, *fw_version;
174*0Sstevel@tonic-gate 
175*0Sstevel@tonic-gate 	if (handle == NULL) {
176*0Sstevel@tonic-gate 		DPRINTF("Null Handle\n");
177*0Sstevel@tonic-gate 		errno = EINVAL;
178*0Sstevel@tonic-gate 		return (-1);
179*0Sstevel@tonic-gate 	}
180*0Sstevel@tonic-gate 	if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
181*0Sstevel@tonic-gate 		DPRINTF2(
182*0Sstevel@tonic-gate 			"Signature expected=0x%x, found=0x%x\n",
183*0Sstevel@tonic-gate 			LIBSMEDIA_SIGNATURE, handle->sm_signature);
184*0Sstevel@tonic-gate 		errno = EINVAL;
185*0Sstevel@tonic-gate 		return (-1);
186*0Sstevel@tonic-gate 	}
187*0Sstevel@tonic-gate 	if (handle->sm_fd < 0) {
188*0Sstevel@tonic-gate 		DPRINTF("Invalid file handle.\n");
189*0Sstevel@tonic-gate 		errno = EINVAL;
190*0Sstevel@tonic-gate 		return (-1);
191*0Sstevel@tonic-gate 	}
192*0Sstevel@tonic-gate 	vendor_name = (char *)malloc(1);
193*0Sstevel@tonic-gate 	if (vendor_name == NULL) {
194*0Sstevel@tonic-gate 		if (!errno)
195*0Sstevel@tonic-gate 			errno = ENOMEM;
196*0Sstevel@tonic-gate 		return (-1);
197*0Sstevel@tonic-gate 	}
198*0Sstevel@tonic-gate 	product_name = (char *)malloc(1);
199*0Sstevel@tonic-gate 	if (product_name == NULL) {
200*0Sstevel@tonic-gate 		free(vendor_name);
201*0Sstevel@tonic-gate 		if (!errno)
202*0Sstevel@tonic-gate 			errno = ENOMEM;
203*0Sstevel@tonic-gate 		return (-1);
204*0Sstevel@tonic-gate 	}
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate 	fw_version = (char *)malloc(1);
207*0Sstevel@tonic-gate 	if (fw_version == NULL) {
208*0Sstevel@tonic-gate 		free(vendor_name);
209*0Sstevel@tonic-gate 		free(product_name);
210*0Sstevel@tonic-gate 		if (!errno)
211*0Sstevel@tonic-gate 			errno = ENOMEM;
212*0Sstevel@tonic-gate 		return (-1);
213*0Sstevel@tonic-gate 	}
214*0Sstevel@tonic-gate 
215*0Sstevel@tonic-gate 	vendor_name[0] = NULL;
216*0Sstevel@tonic-gate 	product_name[0] = NULL;
217*0Sstevel@tonic-gate 	fw_version[0] = NULL;
218*0Sstevel@tonic-gate 	mp->sm_interface_type = IF_PCMCIA;
219*0Sstevel@tonic-gate 	mp->sm_vendor_name = vendor_name;
220*0Sstevel@tonic-gate 	mp->sm_product_name = product_name;
221*0Sstevel@tonic-gate 	mp->sm_firmware_version = fw_version;
222*0Sstevel@tonic-gate 	return (0);
223*0Sstevel@tonic-gate }
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate 
226*0Sstevel@tonic-gate int32_t
_m_free_device_info(rmedia_handle_t * handle,void * ip)227*0Sstevel@tonic-gate _m_free_device_info(rmedia_handle_t *handle, void *ip)
228*0Sstevel@tonic-gate {
229*0Sstevel@tonic-gate 	struct smdevice_info *dev_info = ip;
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate 	/* Check for valid handle */
232*0Sstevel@tonic-gate 	if (handle == NULL) {
233*0Sstevel@tonic-gate 		DPRINTF("Null Handle\n");
234*0Sstevel@tonic-gate 		errno = EINVAL;
235*0Sstevel@tonic-gate 		return (-1);
236*0Sstevel@tonic-gate 	}
237*0Sstevel@tonic-gate 	if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
238*0Sstevel@tonic-gate 		DPRINTF("Invalid signature in handle.\n");
239*0Sstevel@tonic-gate 		errno = EINVAL;
240*0Sstevel@tonic-gate 		return (-1);
241*0Sstevel@tonic-gate 	}
242*0Sstevel@tonic-gate 
243*0Sstevel@tonic-gate 	free(dev_info->sm_vendor_name);
244*0Sstevel@tonic-gate 	free(dev_info->sm_product_name);
245*0Sstevel@tonic-gate 	free(dev_info->sm_firmware_version);
246*0Sstevel@tonic-gate 	return (0);
247*0Sstevel@tonic-gate }
248