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