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