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 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 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 67 _m_version_no(void) 68 { 69 return (SM_FD_VERSION_1); 70 } 71 72 int32_t 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 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 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 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 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 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 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