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