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