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