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