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) 1999-2001 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 /*
28 * f_generic.c :
29 * This file contains all the functionalities except format of
30 * floppy plug-in for libsm.so.
31 */
32
33 #include <sys/types.h>
34 #include <sys/fdio.h>
35 #include <stdlib.h>
36 #include <sys/smedia.h>
37 #include "../../../library/inc/rmedia.h"
38 #include "f_defines.h"
39
40
41 void
my_perror(char * err_string)42 my_perror(char *err_string)
43 {
44
45 int error_no;
46 if (errno == 0)
47 return;
48
49 error_no = errno;
50 (void) fprintf(stderr, gettext(err_string));
51 (void) fprintf(stderr, gettext(" : "));
52 errno = error_no;
53 perror("");
54 }
55
56 int32_t
_m_device_type(ushort_t ctype,ushort_t mtype)57 _m_device_type(ushort_t ctype, ushort_t mtype)
58 {
59 if ((ctype == DKC_INTEL82077) || (ctype == DKC_UNKNOWN)) {
60 if (mtype == 0)
61 return (0);
62 }
63 return (-1);
64 }
65
66 int32_t
_m_version_no(void)67 _m_version_no(void)
68 {
69 return (SM_FD_VERSION_1);
70 }
71
72 int32_t
_m_get_media_info(rmedia_handle_t * handle,void * ip)73 _m_get_media_info(rmedia_handle_t *handle, void *ip)
74 {
75 smmedium_prop_t *med_info = (smmedium_prop_t *)ip;
76 struct fd_char fdchar;
77
78 /* Check for valid handle */
79 if (handle == NULL) {
80 DPRINTF("Null Handle\n");
81 errno = EINVAL;
82 return (-1);
83 }
84 if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
85 DPRINTF("Invalid signature in handle.\n");
86 DPRINTF2(
87 "Signature expected=0x%x found=0x%x\n",
88 LIBSMEDIA_SIGNATURE,
89 handle->sm_signature);
90 errno = EINVAL;
91 return (-1);
92 }
93 if (handle->sm_fd < 0) {
94 DPRINTF("Invalid file handle.\n");
95 errno = EINVAL;
96 return (-1);
97 }
98 if (ioctl(handle->sm_fd, FDIOGCHAR, &fdchar) < 0) {
99 PERROR("Ioctl failed :");
100 return (-1);
101 }
102
103 med_info->sm_media_type = SM_FLOPPY;
104 med_info->sm_blocksize = fdchar.fdc_sec_size;
105 med_info->sm_capacity = fdchar.fdc_ncyl * fdchar.fdc_nhead
106 * fdchar.fdc_secptrack;
107 med_info->sm_pcyl = fdchar.fdc_ncyl;
108 med_info->sm_nhead = fdchar.fdc_nhead;
109 med_info->sm_nsect = fdchar.fdc_secptrack;
110 return (0);
111 }
112
113 /* ARGSUSED0 */
114 int32_t
_m_get_device_info(rmedia_handle_t * handle,void * ip)115 _m_get_device_info(rmedia_handle_t *handle, void *ip)
116 {
117 smdevice_info_t *dev_info = (smdevice_info_t *)ip;
118 char *vendor_name, *product_name, *fw_version;
119
120 /* Check for valid handle */
121 if (handle == NULL) {
122 DPRINTF("Null Handle\n");
123 errno = EINVAL;
124 return (-1);
125 }
126 if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
127 DPRINTF("Invalid signature in handle.\n");
128 DPRINTF2(
129 "Signature expected=0x%x found=0x%x\n",
130 LIBSMEDIA_SIGNATURE,
131 handle->sm_signature);
132 errno = EINVAL;
133 return (-1);
134 }
135 if (handle->sm_fd < 0) {
136 DPRINTF("Invalid file handle.\n");
137 errno = EINVAL;
138 return (-1);
139 }
140 vendor_name = (char *)malloc(1);
141 if (vendor_name == NULL) {
142 if (!errno)
143 errno = ENOMEM;
144 return (-1);
145 }
146 product_name = (char *)malloc(1);
147 if (product_name == NULL) {
148 free(vendor_name);
149 if (!errno)
150 errno = ENOMEM;
151 return (-1);
152 }
153
154 fw_version = (char *)malloc(1);
155 if (fw_version == NULL) {
156 free(vendor_name);
157 free(product_name);
158 if (!errno)
159 errno = ENOMEM;
160 return (-1);
161 }
162
163 vendor_name[0] = 0;
164 product_name[0] = 0;
165 fw_version[0] = 0;
166
167 dev_info->sm_interface_type = IF_FLOPPY;
168 dev_info->sm_vendor_name = vendor_name;
169 dev_info->sm_product_name = product_name;
170 dev_info->sm_firmware_version = fw_version;
171
172 return (0);
173 }
174
175 int32_t
_m_free_device_info(rmedia_handle_t * handle,void * ip)176 _m_free_device_info(rmedia_handle_t *handle, void *ip)
177 {
178 struct smdevice_info *dev_info = ip;
179
180 /* Check for valid handle */
181 if (handle == NULL) {
182 DPRINTF("Null Handle\n");
183 errno = EINVAL;
184 return (-1);
185 }
186 if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
187 DPRINTF("Invalid signature in handle.\n");
188 errno = EINVAL;
189 return (-1);
190 }
191
192 free(dev_info->sm_vendor_name);
193 free(dev_info->sm_product_name);
194 free(dev_info->sm_firmware_version);
195 return (0);
196 }
197
198 /* ARGSUSED1 */
199 int32_t
_m_get_media_status(rmedia_handle_t * handle,void * ip)200 _m_get_media_status(rmedia_handle_t *handle, void *ip)
201 {
202 smwp_state_t *wp = ip;
203 int32_t j;
204
205 if (ioctl(handle->sm_fd, FDGETCHANGE, &j)) {
206 return (-1);
207 }
208 if (j & FDGC_CURWPROT)
209 wp->sm_new_state = SM_WRITE_PROTECT_NOPASSWD;
210 else
211 wp->sm_new_state = SM_WRITE_PROTECT_DISABLE;
212 return (0);
213 }
214
215 int32_t
_m_raw_read(rmedia_handle_t * handle,void * ip)216 _m_raw_read(rmedia_handle_t *handle, void *ip)
217 {
218 struct raw_params *r_p = (struct raw_params *)ip;
219
220 int32_t sector_size;
221 int32_t ret_val;
222 struct fd_raw fdraw;
223 struct fd_char fdchar;
224 int32_t cyl, rem, head, start_sector;
225
226
227 /* Check for valid handle */
228 if (handle == NULL) {
229 DPRINTF("Null Handle\n");
230 errno = EINVAL;
231 return (-1);
232 }
233 if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
234 DPRINTF("Invalid signature in handle.\n");
235 DPRINTF2(
236 "Signature expected=0x%x found=0x%x\n",
237 LIBSMEDIA_SIGNATURE,
238 handle->sm_signature);
239 errno = EINVAL;
240 return (-1);
241 }
242 if (handle->sm_fd < 0) {
243 DPRINTF("Invalid file handle.\n");
244 errno = EINVAL;
245 return (-1);
246 }
247 if (ioctl(handle->sm_fd, FDIOGCHAR, &fdchar) < 0) {
248 PERROR("Ioctl failed :");
249 return (-1);
250 }
251
252 sector_size = fdchar.fdc_sec_size;
253
254 if ((!r_p->size) || (r_p->size % sector_size)) {
255 errno = EINVAL;
256 return (-1);
257 }
258
259 cyl = r_p->offset/(fdchar.fdc_nhead * fdchar.fdc_secptrack);
260 rem = r_p->offset%(fdchar.fdc_nhead * fdchar.fdc_secptrack);
261 head = rem/fdchar.fdc_secptrack;
262 start_sector = rem%fdchar.fdc_secptrack + 1;
263
264 fdraw.fdr_nbytes = r_p->size;
265 fdraw.fdr_addr = r_p->buffer;
266
267
268 fdraw.fdr_cmd[0] = (uint8_t)0xE0 | FDRAW_RDCMD; /* command */
269 /* MFM | MT | SK| FDRAW_RDCMD */
270 fdraw.fdr_cmd[1] = (head << 2); /* using head 1 */
271 fdraw.fdr_cmd[2] = cyl; /* track number */
272 fdraw.fdr_cmd[3] = head; /* drive head number */
273 fdraw.fdr_cmd[4] = start_sector; /* start sector number */
274 fdraw.fdr_cmd[5] = (sector_size == 512) ? 2 : 3;
275 fdraw.fdr_cmd[6] = fdchar.fdc_secptrack;
276 fdraw.fdr_cmd[7] = 0x1B; /* GPLN, GAP length */
277 fdraw.fdr_cmd[8] = (uchar_t)0xFF; /* SSSDTL, data length */
278 fdraw.fdr_cnum = 0x9; /* NCBRW, no. cmd bytes defined in fdreg.h */
279
280 errno = 0;
281 ret_val = ioctl(handle->sm_fd, FDRAW, &fdraw);
282 if (ret_val < 0) {
283 PERROR("RAW READ failed:");
284 return (-1);
285 }
286
287 return (fdraw.fdr_nbytes);
288 }
289 int32_t
_m_raw_write(rmedia_handle_t * handle,void * ip)290 _m_raw_write(rmedia_handle_t *handle, void *ip)
291 {
292 struct raw_params *r_p = (struct raw_params *)ip;
293
294 int32_t sector_size;
295 int32_t ret_val;
296 struct fd_raw fdraw;
297 struct fd_char fdchar;
298 int32_t cyl, rem, head, start_sector;
299
300
301 /* Check for valid handle */
302 if (handle == NULL) {
303 DPRINTF("Null Handle\n");
304 errno = EINVAL;
305 return (-1);
306 }
307 if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
308 DPRINTF("Invalid signature in handle.\n");
309 DPRINTF2(
310 "Signature expected=0x%x, found=0x%x\n",
311 LIBSMEDIA_SIGNATURE, handle->sm_signature);
312 errno = EINVAL;
313 return (-1);
314 }
315 if (handle->sm_fd < 0) {
316 DPRINTF("Invalid file handle.\n");
317 errno = EINVAL;
318 return (-1);
319 }
320 if (ioctl(handle->sm_fd, FDIOGCHAR, &fdchar) < 0) {
321 PERROR("Ioctl failed :");
322 return (-1);
323 }
324
325 sector_size = fdchar.fdc_sec_size;
326
327 if ((!r_p->size) || (r_p->size % sector_size)) {
328 errno = EINVAL;
329 return (-1);
330 }
331
332 cyl = r_p->offset/(fdchar.fdc_nhead * fdchar.fdc_secptrack);
333 rem = r_p->offset%(fdchar.fdc_nhead * fdchar.fdc_secptrack);
334 head = rem/fdchar.fdc_secptrack;
335 start_sector = rem%fdchar.fdc_secptrack + 1;
336
337 fdraw.fdr_nbytes = r_p->size;
338 fdraw.fdr_addr = r_p->buffer;
339
340
341 fdraw.fdr_cmd[0] = (uint8_t)0xE0| FDRAW_WRCMD; /* command */
342 /* MFM | MT | SK| FDRAW_WRCMD; */
343 fdraw.fdr_cmd[1] = (head << 2); /* using head 1 */
344 fdraw.fdr_cmd[2] = cyl; /* track number */
345 fdraw.fdr_cmd[3] = head; /* drive head number */
346 fdraw.fdr_cmd[4] = start_sector; /* start sector number */
347 fdraw.fdr_cmd[5] = (sector_size == 512) ? 2 : 3;
348 fdraw.fdr_cmd[6] = fdchar.fdc_secptrack;
349 fdraw.fdr_cmd[7] = 0x1B; /* GPLN, GAP length */
350 fdraw.fdr_cmd[8] = (uchar_t)0xFF; /* SSSDTL, data length */
351 fdraw.fdr_cnum = 0x9; /* NCBRW, no. cmd bytes defined in fdreg.h */
352
353 errno = 0;
354 ret_val = ioctl(handle->sm_fd, FDRAW, &fdraw);
355 if (ret_val < 0) {
356 PERROR("RAW READ failed:");
357 return (-1);
358 }
359
360 return (fdraw.fdr_nbytes);
361 }
362
363 /* ARGSUSED */
364 int32_t
_m_eject(rmedia_handle_t * handle,void * ip)365 _m_eject(rmedia_handle_t *handle, void *ip)
366 {
367
368 /* Check for valid handle */
369 if (handle == NULL) {
370 DPRINTF("Null Handle\n");
371 errno = EINVAL;
372 return (-1);
373 }
374 if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
375 DPRINTF("Invalid signature in handle.\n");
376 DPRINTF2(
377 "Signature expected=0x%x found=0x%x\n",
378 LIBSMEDIA_SIGNATURE, handle->sm_signature);
379 errno = EINVAL;
380 return (-1);
381 }
382 if (handle->sm_fd < 0) {
383 DPRINTF("Invalid file handle.\n");
384 errno = EINVAL;
385 return (-1);
386 }
387 #ifdef sparc
388 return (ioctl(handle->sm_fd, FDEJECT));
389 #else
390 errno = ENOTSUP;
391 return (-1);
392 #endif
393 }
394