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 /*
24*0Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
25*0Sstevel@tonic-gate * Use is subject to license terms.
26*0Sstevel@tonic-gate */
27*0Sstevel@tonic-gate
28*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
29*0Sstevel@tonic-gate
30*0Sstevel@tonic-gate /*
31*0Sstevel@tonic-gate * f_format.c :
32*0Sstevel@tonic-gate * This file contains the format functions for floppy plug-in for
33*0Sstevel@tonic-gate * library libsm.so.
34*0Sstevel@tonic-gate */
35*0Sstevel@tonic-gate
36*0Sstevel@tonic-gate #include <stdio.h>
37*0Sstevel@tonic-gate #include <sys/types.h>
38*0Sstevel@tonic-gate #include <sys/dklabel.h>
39*0Sstevel@tonic-gate #include <sys/dkio.h>
40*0Sstevel@tonic-gate #include <sys/fdio.h>
41*0Sstevel@tonic-gate #include <fcntl.h>
42*0Sstevel@tonic-gate #include <unistd.h>
43*0Sstevel@tonic-gate #include <locale.h>
44*0Sstevel@tonic-gate #include <errno.h>
45*0Sstevel@tonic-gate #include <sys/param.h>
46*0Sstevel@tonic-gate #include <stdlib.h>
47*0Sstevel@tonic-gate #include <sys/smedia.h>
48*0Sstevel@tonic-gate #include "../../../library/inc/rmedia.h"
49*0Sstevel@tonic-gate #include "f_defines.h"
50*0Sstevel@tonic-gate
51*0Sstevel@tonic-gate /*
52*0Sstevel@tonic-gate * extern functions
53*0Sstevel@tonic-gate */
54*0Sstevel@tonic-gate
55*0Sstevel@tonic-gate extern void my_perror(char *err_string);
56*0Sstevel@tonic-gate /*
57*0Sstevel@tonic-gate * local functions
58*0Sstevel@tonic-gate */
59*0Sstevel@tonic-gate static void restore_default_chars(int32_t fd,
60*0Sstevel@tonic-gate struct fd_char save_fdchar,
61*0Sstevel@tonic-gate struct dk_allmap save_allmap);
62*0Sstevel@tonic-gate static int32_t
format_floppy(int32_t fd,void * ip)63*0Sstevel@tonic-gate format_floppy(int32_t fd, void *ip)
64*0Sstevel@tonic-gate {
65*0Sstevel@tonic-gate struct format_track *ft = (struct format_track *)ip;
66*0Sstevel@tonic-gate int32_t format_flags;
67*0Sstevel@tonic-gate int32_t transfer_rate = 1000; /* transfer rate code */
68*0Sstevel@tonic-gate int32_t sec_size = 512; /* sector size */
69*0Sstevel@tonic-gate uchar_t gap = 0x54; /* format gap size */
70*0Sstevel@tonic-gate uchar_t *fbuf, *p;
71*0Sstevel@tonic-gate int32_t cyl_size;
72*0Sstevel@tonic-gate int32_t i;
73*0Sstevel@tonic-gate int32_t chgd; /* for testing disk changed/present */
74*0Sstevel@tonic-gate int32_t cyl, hd;
75*0Sstevel@tonic-gate int32_t size_of_part, size_of_dev;
76*0Sstevel@tonic-gate int32_t spt = 36; /* sectors per track */
77*0Sstevel@tonic-gate int32_t drive_size;
78*0Sstevel@tonic-gate uchar_t num_cyl = 80; /* max number of cylinders */
79*0Sstevel@tonic-gate struct fd_char save_fdchar; /* original diskette characteristics */
80*0Sstevel@tonic-gate struct dk_allmap save_allmap; /* original diskette partition info */
81*0Sstevel@tonic-gate int32_t D_flag = 0; /* double (aka low) density flag */
82*0Sstevel@tonic-gate int32_t E_flag = 0; /* extended density */
83*0Sstevel@tonic-gate int32_t H_flag = 0; /* high density */
84*0Sstevel@tonic-gate int32_t M_flag = 0; /* medium density */
85*0Sstevel@tonic-gate struct fd_char fdchar;
86*0Sstevel@tonic-gate struct dk_geom fdgeom;
87*0Sstevel@tonic-gate struct dk_allmap allmap;
88*0Sstevel@tonic-gate struct dk_cinfo dkinfo;
89*0Sstevel@tonic-gate int32_t start_head, end_head, start_cyl, end_cyl;
90*0Sstevel@tonic-gate
91*0Sstevel@tonic-gate /* for verify buffers */
92*0Sstevel@tonic-gate static uchar_t *obuf;
93*0Sstevel@tonic-gate
94*0Sstevel@tonic-gate
95*0Sstevel@tonic-gate /* FDRAW ioctl command structures for seeking and formatting */
96*0Sstevel@tonic-gate struct fd_raw fdr_seek = {
97*0Sstevel@tonic-gate FDRAW_SEEK, 0, 0, 0, 0, 0, 0, 0, 0, 0,
98*0Sstevel@tonic-gate 3,
99*0Sstevel@tonic-gate 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100*0Sstevel@tonic-gate 0,
101*0Sstevel@tonic-gate 0
102*0Sstevel@tonic-gate };
103*0Sstevel@tonic-gate
104*0Sstevel@tonic-gate struct fd_raw fdr_form = {
105*0Sstevel@tonic-gate 0x4D, 0, 2, 0, 0x54, (char)0xA5, 0, 0, 0, 0,
106*0Sstevel@tonic-gate 6,
107*0Sstevel@tonic-gate 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108*0Sstevel@tonic-gate 0, /* nbytes */
109*0Sstevel@tonic-gate 0 /* addr */
110*0Sstevel@tonic-gate };
111*0Sstevel@tonic-gate
112*0Sstevel@tonic-gate format_flags = ft->flag;
113*0Sstevel@tonic-gate
114*0Sstevel@tonic-gate DPRINTF1("Format flag is %d\n", format_flags);
115*0Sstevel@tonic-gate if (format_flags == SM_FORMAT_HD) {
116*0Sstevel@tonic-gate H_flag = 1;
117*0Sstevel@tonic-gate } else if (format_flags == SM_FORMAT_DD) {
118*0Sstevel@tonic-gate D_flag = 1;
119*0Sstevel@tonic-gate } else if (format_flags == SM_FORMAT_ED) {
120*0Sstevel@tonic-gate E_flag = 1;
121*0Sstevel@tonic-gate } else if (format_flags == SM_FORMAT_MD) {
122*0Sstevel@tonic-gate M_flag = 1;
123*0Sstevel@tonic-gate } else {
124*0Sstevel@tonic-gate DPRINTF("Invalid operation \n");
125*0Sstevel@tonic-gate errno = ENOTSUP;
126*0Sstevel@tonic-gate return (-1);
127*0Sstevel@tonic-gate }
128*0Sstevel@tonic-gate
129*0Sstevel@tonic-gate
130*0Sstevel@tonic-gate /*
131*0Sstevel@tonic-gate * restore drive to default geometry and characteristics
132*0Sstevel@tonic-gate * (probably not implemented on sparc)
133*0Sstevel@tonic-gate */
134*0Sstevel@tonic-gate (void) ioctl(fd, FDDEFGEOCHAR, NULL);
135*0Sstevel@tonic-gate
136*0Sstevel@tonic-gate
137*0Sstevel@tonic-gate if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) {
138*0Sstevel@tonic-gate PERROR("DKIOCINFO failed.");
139*0Sstevel@tonic-gate exit(3);
140*0Sstevel@tonic-gate }
141*0Sstevel@tonic-gate
142*0Sstevel@tonic-gate
143*0Sstevel@tonic-gate /* get the default partititon maps */
144*0Sstevel@tonic-gate if (ioctl(fd, DKIOCGAPART, &allmap) < 0) {
145*0Sstevel@tonic-gate PERROR("DKIOCGAPART failed.");
146*0Sstevel@tonic-gate return (-1);
147*0Sstevel@tonic-gate }
148*0Sstevel@tonic-gate
149*0Sstevel@tonic-gate /* Save the original default partition maps */
150*0Sstevel@tonic-gate save_allmap = allmap;
151*0Sstevel@tonic-gate
152*0Sstevel@tonic-gate /* find out the characteristics of the default diskette */
153*0Sstevel@tonic-gate if (ioctl(fd, FDIOGCHAR, &fdchar) < 0) {
154*0Sstevel@tonic-gate PERROR("FDIOGCHAR failed.");
155*0Sstevel@tonic-gate return (-1);
156*0Sstevel@tonic-gate }
157*0Sstevel@tonic-gate
158*0Sstevel@tonic-gate /* Save the original characteristics of the default diskette */
159*0Sstevel@tonic-gate save_fdchar = fdchar;
160*0Sstevel@tonic-gate
161*0Sstevel@tonic-gate /*
162*0Sstevel@tonic-gate * The user may only format the entire diskette.
163*0Sstevel@tonic-gate * formatting partion a or b is not allowed
164*0Sstevel@tonic-gate */
165*0Sstevel@tonic-gate size_of_part = allmap.dka_map[dkinfo.dki_partition].dkl_nblk
166*0Sstevel@tonic-gate * DEV_BSIZE;
167*0Sstevel@tonic-gate size_of_dev = fdchar.fdc_ncyl * fdchar.fdc_nhead
168*0Sstevel@tonic-gate * fdchar.fdc_secptrack * fdchar.fdc_sec_size;
169*0Sstevel@tonic-gate
170*0Sstevel@tonic-gate if (size_of_part != size_of_dev) {
171*0Sstevel@tonic-gate DPRINTF("The entire diskette must be formatted\n");
172*0Sstevel@tonic-gate DPRINTF1("size_of_part %d\n", size_of_part);
173*0Sstevel@tonic-gate DPRINTF1("size_of_dev %d\n", size_of_dev);
174*0Sstevel@tonic-gate errno = ENOTSUP;
175*0Sstevel@tonic-gate return (-1);
176*0Sstevel@tonic-gate }
177*0Sstevel@tonic-gate
178*0Sstevel@tonic-gate /* find out the geometry of the drive */
179*0Sstevel@tonic-gate if (ioctl(fd, DKIOCGGEOM, &fdgeom) < 0) {
180*0Sstevel@tonic-gate PERROR("DKIOCGGEOM failed.");
181*0Sstevel@tonic-gate return (-1);
182*0Sstevel@tonic-gate }
183*0Sstevel@tonic-gate
184*0Sstevel@tonic-gate #ifdef sparc
185*0Sstevel@tonic-gate fdchar.fdc_medium = 3;
186*0Sstevel@tonic-gate #endif
187*0Sstevel@tonic-gate if (fdchar.fdc_medium == 5)
188*0Sstevel@tonic-gate drive_size = 5;
189*0Sstevel@tonic-gate else
190*0Sstevel@tonic-gate drive_size = 3;
191*0Sstevel@tonic-gate
192*0Sstevel@tonic-gate /*
193*0Sstevel@tonic-gate * set proper density flag in case we're formating to default
194*0Sstevel@tonic-gate * characteristics because no density switch was input
195*0Sstevel@tonic-gate */
196*0Sstevel@tonic-gate
197*0Sstevel@tonic-gate /* XXX */
198*0Sstevel@tonic-gate if ((E_flag | H_flag | D_flag | M_flag) == 0) {
199*0Sstevel@tonic-gate switch (fdchar.fdc_transfer_rate) {
200*0Sstevel@tonic-gate case 1000:
201*0Sstevel@tonic-gate /* assumes only ED uses 1.0 MB/sec */
202*0Sstevel@tonic-gate E_flag++;
203*0Sstevel@tonic-gate break;
204*0Sstevel@tonic-gate case 500:
205*0Sstevel@tonic-gate default:
206*0Sstevel@tonic-gate /*
207*0Sstevel@tonic-gate * default to HD even though High density and
208*0Sstevel@tonic-gate * "medium" density both use 500 KB/sec
209*0Sstevel@tonic-gate */
210*0Sstevel@tonic-gate H_flag++;
211*0Sstevel@tonic-gate break;
212*0Sstevel@tonic-gate #ifndef sparc
213*0Sstevel@tonic-gate case 250:
214*0Sstevel@tonic-gate /* assumes only DD uses 250 KB/sec */
215*0Sstevel@tonic-gate D_flag++;
216*0Sstevel@tonic-gate break;
217*0Sstevel@tonic-gate #endif
218*0Sstevel@tonic-gate }
219*0Sstevel@tonic-gate }
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gate if (H_flag) {
222*0Sstevel@tonic-gate transfer_rate = 500;
223*0Sstevel@tonic-gate num_cyl = 80;
224*0Sstevel@tonic-gate sec_size = 512;
225*0Sstevel@tonic-gate if (drive_size == 5) {
226*0Sstevel@tonic-gate spt = 15;
227*0Sstevel@tonic-gate } else {
228*0Sstevel@tonic-gate spt = 18;
229*0Sstevel@tonic-gate }
230*0Sstevel@tonic-gate gap = 0x54;
231*0Sstevel@tonic-gate } else if (D_flag) {
232*0Sstevel@tonic-gate transfer_rate = 250;
233*0Sstevel@tonic-gate if (drive_size == 5) {
234*0Sstevel@tonic-gate if (fdchar.fdc_transfer_rate == 500) {
235*0Sstevel@tonic-gate /*
236*0Sstevel@tonic-gate * formatting a 360KB DD diskette in
237*0Sstevel@tonic-gate * a 1.2MB drive is not a good idea
238*0Sstevel@tonic-gate */
239*0Sstevel@tonic-gate transfer_rate = 300;
240*0Sstevel@tonic-gate fdchar.fdc_steps = 2;
241*0Sstevel@tonic-gate }
242*0Sstevel@tonic-gate num_cyl = 40;
243*0Sstevel@tonic-gate gap = 0x50;
244*0Sstevel@tonic-gate } else {
245*0Sstevel@tonic-gate num_cyl = 80;
246*0Sstevel@tonic-gate gap = 0x54;
247*0Sstevel@tonic-gate }
248*0Sstevel@tonic-gate sec_size = 512;
249*0Sstevel@tonic-gate spt = 9;
250*0Sstevel@tonic-gate } else if (M_flag) {
251*0Sstevel@tonic-gate #ifdef sparc
252*0Sstevel@tonic-gate transfer_rate = 500;
253*0Sstevel@tonic-gate #else
254*0Sstevel@tonic-gate /*
255*0Sstevel@tonic-gate * 416.67 KB/sec is the effective transfer rate of a "medium"
256*0Sstevel@tonic-gate * density diskette spun at 300 rpm instead of 360 rpm
257*0Sstevel@tonic-gate */
258*0Sstevel@tonic-gate transfer_rate = 417;
259*0Sstevel@tonic-gate #endif
260*0Sstevel@tonic-gate num_cyl = 77;
261*0Sstevel@tonic-gate sec_size = 1024;
262*0Sstevel@tonic-gate spt = 8;
263*0Sstevel@tonic-gate gap = 0x74;
264*0Sstevel@tonic-gate } else if (E_flag) {
265*0Sstevel@tonic-gate transfer_rate = 1000;
266*0Sstevel@tonic-gate num_cyl = 80;
267*0Sstevel@tonic-gate sec_size = 512;
268*0Sstevel@tonic-gate spt = 36;
269*0Sstevel@tonic-gate gap = 0x54;
270*0Sstevel@tonic-gate }
271*0Sstevel@tonic-gate
272*0Sstevel@tonic-gate /*
273*0Sstevel@tonic-gate * Medium density diskettes have 1024 byte blocks. The dk_map
274*0Sstevel@tonic-gate * structure in dklabel.h assumes the blocks size is DEVBSIZE (512)
275*0Sstevel@tonic-gate * bytes. The dkl_nblk field is in terms of DEVBSIZE byte blocks
276*0Sstevel@tonic-gate * while the spt variable is in terms of the true block size on
277*0Sstevel@tonic-gate * the diskette.
278*0Sstevel@tonic-gate */
279*0Sstevel@tonic-gate if (allmap.dka_map[2].dkl_nblk !=
280*0Sstevel@tonic-gate (2 * num_cyl * spt * (M_flag ? 2 : 1))) {
281*0Sstevel@tonic-gate allmap.dka_map[1].dkl_cylno = num_cyl - 1;
282*0Sstevel@tonic-gate allmap.dka_map[0].dkl_nblk = 2 * (num_cyl - 1) * spt *
283*0Sstevel@tonic-gate (M_flag ? 2 : 1);
284*0Sstevel@tonic-gate allmap.dka_map[1].dkl_nblk = 2 * spt * (M_flag ? 2 : 1);
285*0Sstevel@tonic-gate allmap.dka_map[2].dkl_nblk = 2 * num_cyl * spt *
286*0Sstevel@tonic-gate (M_flag ? 2 : 1);
287*0Sstevel@tonic-gate if (allmap.dka_map[3].dkl_nblk)
288*0Sstevel@tonic-gate allmap.dka_map[3].dkl_nblk = 2 * (num_cyl - 1) * spt *
289*0Sstevel@tonic-gate (M_flag ? 2 : 1);
290*0Sstevel@tonic-gate if (allmap.dka_map[4].dkl_nblk)
291*0Sstevel@tonic-gate allmap.dka_map[4].dkl_nblk =
292*0Sstevel@tonic-gate 2 * spt * (M_flag ? 2 : 1);
293*0Sstevel@tonic-gate }
294*0Sstevel@tonic-gate
295*0Sstevel@tonic-gate
296*0Sstevel@tonic-gate
297*0Sstevel@tonic-gate #ifndef sparc
298*0Sstevel@tonic-gate if (num_cyl > fdchar.fdc_ncyl || spt > fdchar.fdc_secptrack ||
299*0Sstevel@tonic-gate transfer_rate > fdchar.fdc_transfer_rate) {
300*0Sstevel@tonic-gate PERROR("drive not capable of requested density");
301*0Sstevel@tonic-gate return (-1);
302*0Sstevel@tonic-gate }
303*0Sstevel@tonic-gate #endif
304*0Sstevel@tonic-gate if (num_cyl != fdchar.fdc_ncyl || spt != fdchar.fdc_secptrack ||
305*0Sstevel@tonic-gate transfer_rate != fdchar.fdc_transfer_rate) {
306*0Sstevel@tonic-gate /*
307*0Sstevel@tonic-gate * -- CAUTION --
308*0Sstevel@tonic-gate * The SPARC fd driver is using a non-zero value in
309*0Sstevel@tonic-gate * fdc_medium to indicate the 360 rpm, 77 track,
310*0Sstevel@tonic-gate * 9 sectors/track, 1024 bytes/sector mode of operation
311*0Sstevel@tonic-gate * (similar to an 8", DS/DD, 1.2 MB floppy).
312*0Sstevel@tonic-gate *
313*0Sstevel@tonic-gate * The x86 fd driver uses fdc_medium as the diameter
314*0Sstevel@tonic-gate * indicator, either 3 or 5. It should not be modified.
315*0Sstevel@tonic-gate */
316*0Sstevel@tonic-gate #ifdef sparc
317*0Sstevel@tonic-gate fdchar.fdc_medium = M_flag ? 1 : 0;
318*0Sstevel@tonic-gate #endif
319*0Sstevel@tonic-gate fdchar.fdc_transfer_rate = transfer_rate;
320*0Sstevel@tonic-gate fdchar.fdc_ncyl = num_cyl;
321*0Sstevel@tonic-gate fdchar.fdc_sec_size = sec_size;
322*0Sstevel@tonic-gate fdchar.fdc_secptrack = spt;
323*0Sstevel@tonic-gate
324*0Sstevel@tonic-gate if (ioctl(fd, FDIOSCHAR, &fdchar) < 0) {
325*0Sstevel@tonic-gate PERROR("FDIOSCHAR (density selection) failed");
326*0Sstevel@tonic-gate /* restore the default characteristics */
327*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap);
328*0Sstevel@tonic-gate return (-1);
329*0Sstevel@tonic-gate }
330*0Sstevel@tonic-gate if (ioctl(fd, DKIOCSAPART, &allmap) < 0) {
331*0Sstevel@tonic-gate PERROR("DKIOCSAPART failed");
332*0Sstevel@tonic-gate
333*0Sstevel@tonic-gate /* restore the default characteristics */
334*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap);
335*0Sstevel@tonic-gate return (-1);
336*0Sstevel@tonic-gate }
337*0Sstevel@tonic-gate }
338*0Sstevel@tonic-gate
339*0Sstevel@tonic-gate cyl_size = 2 * sec_size * spt;
340*0Sstevel@tonic-gate
341*0Sstevel@tonic-gate if ((obuf = (uchar_t *)malloc((size_t)cyl_size)) == 0) {
342*0Sstevel@tonic-gate PERROR("car't malloc verify buffer");
343*0Sstevel@tonic-gate /* restore the default characteristics */
344*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap);
345*0Sstevel@tonic-gate return (-1);
346*0Sstevel@tonic-gate }
347*0Sstevel@tonic-gate /*
348*0Sstevel@tonic-gate * for those systems that support this ioctl, they will
349*0Sstevel@tonic-gate * return whether or not a diskette is in the drive.
350*0Sstevel@tonic-gate */
351*0Sstevel@tonic-gate if (ioctl(fd, FDGETCHANGE, &chgd) == 0) {
352*0Sstevel@tonic-gate if (chgd & FDGC_CURRENT) {
353*0Sstevel@tonic-gate (void) fprintf(stderr,
354*0Sstevel@tonic-gate gettext("no diskette in drive \n"));
355*0Sstevel@tonic-gate
356*0Sstevel@tonic-gate /* restore the default characteristics */
357*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap);
358*0Sstevel@tonic-gate return (-1);
359*0Sstevel@tonic-gate }
360*0Sstevel@tonic-gate if (chgd & FDGC_CURWPROT) {
361*0Sstevel@tonic-gate (void) fprintf(stderr,
362*0Sstevel@tonic-gate gettext("Media is write protected\n"));
363*0Sstevel@tonic-gate
364*0Sstevel@tonic-gate /* restore the default characteristics */
365*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap);
366*0Sstevel@tonic-gate return (-1);
367*0Sstevel@tonic-gate }
368*0Sstevel@tonic-gate }
369*0Sstevel@tonic-gate
370*0Sstevel@tonic-gate if ((fbuf = (uchar_t *)malloc((unsigned)(4 * spt))) == 0) {
371*0Sstevel@tonic-gate PERROR("Could not malloc format header buffer");
372*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap);
373*0Sstevel@tonic-gate return (-1);
374*0Sstevel@tonic-gate }
375*0Sstevel@tonic-gate /*
376*0Sstevel@tonic-gate * do the format, a track at a time
377*0Sstevel@tonic-gate */
378*0Sstevel@tonic-gate if (ft->track_no == -1) {
379*0Sstevel@tonic-gate start_cyl = 0;
380*0Sstevel@tonic-gate end_cyl = num_cyl;
381*0Sstevel@tonic-gate start_head = 0;
382*0Sstevel@tonic-gate end_head = fdchar.fdc_nhead;
383*0Sstevel@tonic-gate } else {
384*0Sstevel@tonic-gate start_cyl = ft->track_no;
385*0Sstevel@tonic-gate end_cyl = ft->track_no + 1;
386*0Sstevel@tonic-gate start_head = ft->head;
387*0Sstevel@tonic-gate end_head = ft->head + 1;
388*0Sstevel@tonic-gate if ((end_cyl > num_cyl) || (end_head > fdchar.fdc_nhead)) {
389*0Sstevel@tonic-gate errno = EINVAL;
390*0Sstevel@tonic-gate return (-1);
391*0Sstevel@tonic-gate }
392*0Sstevel@tonic-gate }
393*0Sstevel@tonic-gate
394*0Sstevel@tonic-gate for (cyl = start_cyl; cyl < (int32_t)end_cyl; cyl++) {
395*0Sstevel@tonic-gate /*
396*0Sstevel@tonic-gate * This is not the optimal ioctl to format the floppy.
397*0Sstevel@tonic-gate * The device driver should do do the work,
398*0Sstevel@tonic-gate * instead of this program mucking with a lot
399*0Sstevel@tonic-gate * of low-level, device-dependent code.
400*0Sstevel@tonic-gate */
401*0Sstevel@tonic-gate fdr_seek.fdr_cmd[2] = cyl;
402*0Sstevel@tonic-gate if (ioctl(fd, FDRAW, &fdr_seek) < 0) {
403*0Sstevel@tonic-gate (void) fprintf(stderr,
404*0Sstevel@tonic-gate gettext(" seek to cyl %d failed\n"),
405*0Sstevel@tonic-gate cyl);
406*0Sstevel@tonic-gate
407*0Sstevel@tonic-gate /* restore the default characteristics */
408*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap);
409*0Sstevel@tonic-gate return (-1);
410*0Sstevel@tonic-gate }
411*0Sstevel@tonic-gate /*
412*0Sstevel@tonic-gate * Assume that the fd driver has issued a SENSE_INT
413*0Sstevel@tonic-gate * command to complete the seek operation.
414*0Sstevel@tonic-gate */
415*0Sstevel@tonic-gate
416*0Sstevel@tonic-gate for (hd = start_head; hd < end_head; hd++) {
417*0Sstevel@tonic-gate p = (uchar_t *)fbuf;
418*0Sstevel@tonic-gate for (i = 1; i <= spt; i++) {
419*0Sstevel@tonic-gate *p++ = (uchar_t)cyl;
420*0Sstevel@tonic-gate *p++ = (uchar_t)hd;
421*0Sstevel@tonic-gate *p++ = (uchar_t)i; /* sector # */
422*0Sstevel@tonic-gate *p++ = (sec_size == 1024) ? 3 : 2;
423*0Sstevel@tonic-gate }
424*0Sstevel@tonic-gate /*
425*0Sstevel@tonic-gate * ASSUME the fd driver is going to set drive-select
426*0Sstevel@tonic-gate * bits in the second command byte
427*0Sstevel@tonic-gate */
428*0Sstevel@tonic-gate fdr_form.fdr_cmd[1] = hd << 2;
429*0Sstevel@tonic-gate fdr_form.fdr_cmd[2] = (sec_size == 1024) ? 3 : 2;
430*0Sstevel@tonic-gate fdr_form.fdr_cmd[3] = spt;
431*0Sstevel@tonic-gate fdr_form.fdr_cmd[4] = gap;
432*0Sstevel@tonic-gate fdr_form.fdr_nbytes = 4 * spt;
433*0Sstevel@tonic-gate fdr_form.fdr_addr = (char *)fbuf;
434*0Sstevel@tonic-gate
435*0Sstevel@tonic-gate if (ioctl(fd, FDRAW, &fdr_form) < 0) {
436*0Sstevel@tonic-gate
437*0Sstevel@tonic-gate
438*0Sstevel@tonic-gate (void) fprintf(stderr,
439*0Sstevel@tonic-gate gettext(
440*0Sstevel@tonic-gate "format of cyl %d head %d failed\n"),
441*0Sstevel@tonic-gate cyl, hd);
442*0Sstevel@tonic-gate
443*0Sstevel@tonic-gate /* restore the default characteristics */
444*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar,
445*0Sstevel@tonic-gate save_allmap);
446*0Sstevel@tonic-gate return (-1);
447*0Sstevel@tonic-gate }
448*0Sstevel@tonic-gate if (fdr_form.fdr_result[0] & 0xC0) {
449*0Sstevel@tonic-gate if (fdr_form.fdr_result[1] & 0x02) {
450*0Sstevel@tonic-gate (void) fprintf(stderr, gettext(
451*0Sstevel@tonic-gate /*CSTYLED*/
452*0Sstevel@tonic-gate "diskette is write protected\n"));
453*0Sstevel@tonic-gate
454*0Sstevel@tonic-gate /*
455*0Sstevel@tonic-gate * restore the default
456*0Sstevel@tonic-gate * characteristics
457*0Sstevel@tonic-gate */
458*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar,
459*0Sstevel@tonic-gate save_allmap);
460*0Sstevel@tonic-gate return (-1);
461*0Sstevel@tonic-gate }
462*0Sstevel@tonic-gate (void) fprintf(stderr,
463*0Sstevel@tonic-gate gettext(
464*0Sstevel@tonic-gate "format of cyl %d head %d failed\n"),
465*0Sstevel@tonic-gate cyl, hd);
466*0Sstevel@tonic-gate
467*0Sstevel@tonic-gate /* restore the default characteristics */
468*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar,
469*0Sstevel@tonic-gate save_allmap);
470*0Sstevel@tonic-gate return (-1);
471*0Sstevel@tonic-gate }
472*0Sstevel@tonic-gate
473*0Sstevel@tonic-gate }
474*0Sstevel@tonic-gate
475*0Sstevel@tonic-gate /*
476*0Sstevel@tonic-gate * do a quick verify
477*0Sstevel@tonic-gate */
478*0Sstevel@tonic-gate if (llseek(fd, cyl * cyl_size, 0) != cyl * cyl_size) {
479*0Sstevel@tonic-gate PERROR(" bad seek to format verify, ");
480*0Sstevel@tonic-gate /* restore the default characteristics */
481*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar,
482*0Sstevel@tonic-gate save_allmap);
483*0Sstevel@tonic-gate return (-1);
484*0Sstevel@tonic-gate }
485*0Sstevel@tonic-gate if (fdchar.fdc_nhead == end_head) {
486*0Sstevel@tonic-gate if (read(fd, obuf, cyl_size) != cyl_size) {
487*0Sstevel@tonic-gate PERROR("Could not read format data");
488*0Sstevel@tonic-gate /* restore the default characteristics */
489*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar,
490*0Sstevel@tonic-gate save_allmap);
491*0Sstevel@tonic-gate return (-1);
492*0Sstevel@tonic-gate }
493*0Sstevel@tonic-gate }
494*0Sstevel@tonic-gate }
495*0Sstevel@tonic-gate if (llseek(fd, (off_t)0, 0) != 0) {
496*0Sstevel@tonic-gate PERROR("seek to blk 0 failed");
497*0Sstevel@tonic-gate /* restore the default characteristics */
498*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap);
499*0Sstevel@tonic-gate return (-1);
500*0Sstevel@tonic-gate }
501*0Sstevel@tonic-gate return (0);
502*0Sstevel@tonic-gate }
503*0Sstevel@tonic-gate
504*0Sstevel@tonic-gate
505*0Sstevel@tonic-gate /*
506*0Sstevel@tonic-gate * Restore the default characteristics of the floppy diskette.
507*0Sstevel@tonic-gate * Fdformat changes the characteristics in the process of formatting.
508*0Sstevel@tonic-gate * If fdformat fails while in the process of doing the format, fdformat
509*0Sstevel@tonic-gate * should clean up after itself and reset the driver back to the original
510*0Sstevel@tonic-gate * state.
511*0Sstevel@tonic-gate */
512*0Sstevel@tonic-gate
513*0Sstevel@tonic-gate static void
restore_default_chars(int32_t fd,struct fd_char save_fdchar,struct dk_allmap save_allmap)514*0Sstevel@tonic-gate restore_default_chars(int32_t fd,
515*0Sstevel@tonic-gate struct fd_char save_fdchar,
516*0Sstevel@tonic-gate struct dk_allmap save_allmap)
517*0Sstevel@tonic-gate {
518*0Sstevel@tonic-gate
519*0Sstevel@tonic-gate
520*0Sstevel@tonic-gate /*
521*0Sstevel@tonic-gate * When this function is called, fdformat is failing anyways,
522*0Sstevel@tonic-gate * so the errors are not processed.
523*0Sstevel@tonic-gate */
524*0Sstevel@tonic-gate
525*0Sstevel@tonic-gate (void) ioctl(fd, FDIOSCHAR, &save_fdchar);
526*0Sstevel@tonic-gate
527*0Sstevel@tonic-gate (void) ioctl(fd, DKIOCSAPART, &save_allmap);
528*0Sstevel@tonic-gate
529*0Sstevel@tonic-gate /*
530*0Sstevel@tonic-gate * Before looking at the diskette's characteristics, format_floppy()
531*0Sstevel@tonic-gate * sets the x86 floppy driver to the default characteristics.
532*0Sstevel@tonic-gate * restore drive to default geometry and
533*0Sstevel@tonic-gate * characteristics. This ioctl isn't implemented on
534*0Sstevel@tonic-gate * sparc.
535*0Sstevel@tonic-gate */
536*0Sstevel@tonic-gate (void) ioctl(fd, FDDEFGEOCHAR, NULL);
537*0Sstevel@tonic-gate
538*0Sstevel@tonic-gate }
539*0Sstevel@tonic-gate
540*0Sstevel@tonic-gate int32_t
_m_media_format(rmedia_handle_t * handle,void * ip)541*0Sstevel@tonic-gate _m_media_format(rmedia_handle_t *handle, void *ip) {
542*0Sstevel@tonic-gate struct format_track ft;
543*0Sstevel@tonic-gate
544*0Sstevel@tonic-gate /* Check for valid handle */
545*0Sstevel@tonic-gate if (handle == NULL) {
546*0Sstevel@tonic-gate DPRINTF("Null Handle\n");
547*0Sstevel@tonic-gate errno = EINVAL;
548*0Sstevel@tonic-gate return (-1);
549*0Sstevel@tonic-gate }
550*0Sstevel@tonic-gate if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
551*0Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
552*0Sstevel@tonic-gate DPRINTF2(
553*0Sstevel@tonic-gate "Signature expected=0x%x, found=0x%x\n",
554*0Sstevel@tonic-gate LIBSMEDIA_SIGNATURE, handle->sm_signature);
555*0Sstevel@tonic-gate errno = EINVAL;
556*0Sstevel@tonic-gate return (-1);
557*0Sstevel@tonic-gate }
558*0Sstevel@tonic-gate if (handle->sm_fd < 0) {
559*0Sstevel@tonic-gate DPRINTF("Invalid file handle.\n");
560*0Sstevel@tonic-gate errno = EINVAL;
561*0Sstevel@tonic-gate return (-1);
562*0Sstevel@tonic-gate }
563*0Sstevel@tonic-gate DPRINTF("Format floppy called \n");
564*0Sstevel@tonic-gate ft.track_no = (-1);
565*0Sstevel@tonic-gate ft.head = (-1);
566*0Sstevel@tonic-gate ft.flag = ((struct format_flags *)ip)->flavor;
567*0Sstevel@tonic-gate return (format_floppy(handle->sm_fd, &ft));
568*0Sstevel@tonic-gate
569*0Sstevel@tonic-gate }
570*0Sstevel@tonic-gate
571*0Sstevel@tonic-gate int32_t
_m_media_format_track(rmedia_handle_t * handle,void * ip)572*0Sstevel@tonic-gate _m_media_format_track(rmedia_handle_t *handle, void *ip)
573*0Sstevel@tonic-gate {
574*0Sstevel@tonic-gate
575*0Sstevel@tonic-gate /* Check for valid handle */
576*0Sstevel@tonic-gate if (handle == NULL) {
577*0Sstevel@tonic-gate DPRINTF("Null Handle\n");
578*0Sstevel@tonic-gate errno = EINVAL;
579*0Sstevel@tonic-gate return (-1);
580*0Sstevel@tonic-gate }
581*0Sstevel@tonic-gate if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
582*0Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
583*0Sstevel@tonic-gate DPRINTF2(
584*0Sstevel@tonic-gate "Signature expected=0x%x, found=0x%x\n",
585*0Sstevel@tonic-gate LIBSMEDIA_SIGNATURE, handle->sm_signature);
586*0Sstevel@tonic-gate errno = EINVAL;
587*0Sstevel@tonic-gate return (-1);
588*0Sstevel@tonic-gate }
589*0Sstevel@tonic-gate if (handle->sm_fd < 0) {
590*0Sstevel@tonic-gate DPRINTF("Invalid file handle.\n");
591*0Sstevel@tonic-gate errno = EINVAL;
592*0Sstevel@tonic-gate return (-1);
593*0Sstevel@tonic-gate }
594*0Sstevel@tonic-gate #ifdef DEBUG
595*0Sstevel@tonic-gate if (ip != NULL) {
596*0Sstevel@tonic-gate struct format_track *ft = (struct format_track *)ip;
597*0Sstevel@tonic-gate DPRINTF2("Format track %d head %d\n", ft->track_no, ft->head);
598*0Sstevel@tonic-gate }
599*0Sstevel@tonic-gate #endif /* DEBUG */
600*0Sstevel@tonic-gate return (format_floppy(handle->sm_fd, ip));
601*0Sstevel@tonic-gate }
602