xref: /aosp_15_r20/external/mtools/devices.c (revision d5c9a868b113e0ec0db2f27bc2ce8a253e77c4b0)
1*d5c9a868SElliott Hughes /*  Copyright 1986-1992 Emmet P. Gray.
2*d5c9a868SElliott Hughes  *  Copyright 1996-2003,2006,2007,2009 Alain Knaff.
3*d5c9a868SElliott Hughes  *  This file is part of mtools.
4*d5c9a868SElliott Hughes  *
5*d5c9a868SElliott Hughes  *  Mtools is free software: you can redistribute it and/or modify
6*d5c9a868SElliott Hughes  *  it under the terms of the GNU General Public License as published by
7*d5c9a868SElliott Hughes  *  the Free Software Foundation, either version 3 of the License, or
8*d5c9a868SElliott Hughes  *  (at your option) any later version.
9*d5c9a868SElliott Hughes  *
10*d5c9a868SElliott Hughes  *  Mtools is distributed in the hope that it will be useful,
11*d5c9a868SElliott Hughes  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12*d5c9a868SElliott Hughes  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*d5c9a868SElliott Hughes  *  GNU General Public License for more details.
14*d5c9a868SElliott Hughes  *
15*d5c9a868SElliott Hughes  *  You should have received a copy of the GNU General Public License
16*d5c9a868SElliott Hughes  *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
17*d5c9a868SElliott Hughes  */
18*d5c9a868SElliott Hughes 
19*d5c9a868SElliott Hughes /*
20*d5c9a868SElliott Hughes  * Device tables.  See the Configure file for a complete description.
21*d5c9a868SElliott Hughes  */
22*d5c9a868SElliott Hughes 
23*d5c9a868SElliott Hughes #define NO_TERMIO
24*d5c9a868SElliott Hughes #include "sysincludes.h"
25*d5c9a868SElliott Hughes #include "msdos.h"
26*d5c9a868SElliott Hughes #include "mtools.h"
27*d5c9a868SElliott Hughes #include "devices.h"
28*d5c9a868SElliott Hughes 
29*d5c9a868SElliott Hughes #define INIT_NOOP
30*d5c9a868SElliott Hughes 
31*d5c9a868SElliott Hughes #define DEF_ARG1(x) (x), 0x2,0,(char *)0, 0, 0, 0, 0, 0, 0, NULL
32*d5c9a868SElliott Hughes #define DEF_ARG0(x) 0,DEF_ARG1(x)
33*d5c9a868SElliott Hughes 
34*d5c9a868SElliott Hughes #define MDEF_ARG 0L,DEF_ARG0(MFORMAT_ONLY_FLAG)
35*d5c9a868SElliott Hughes #define FDEF_ARG 0L,DEF_ARG0(0)
36*d5c9a868SElliott Hughes 
37*d5c9a868SElliott Hughes #pragma GCC diagnostic push
38*d5c9a868SElliott Hughes #pragma GCC diagnostic ignored "-Wunused-macros"
39*d5c9a868SElliott Hughes 
40*d5c9a868SElliott Hughes #define VOLD_DEF_ARG 0L,DEF_ARG0(VOLD_FLAG|MFORMAT_ONLY_FLAG)
41*d5c9a868SElliott Hughes 
42*d5c9a868SElliott Hughes #define MED312	12,0,80,2,36,0,MDEF_ARG /* 3 1/2 extra density */
43*d5c9a868SElliott Hughes #define MHD312	12,0,80,2,18,0,MDEF_ARG /* 3 1/2 high density */
44*d5c9a868SElliott Hughes #define MDD312	12,0,80,2, 9,0,MDEF_ARG /* 3 1/2 double density */
45*d5c9a868SElliott Hughes #define MHD514	12,0,80,2,15,0,MDEF_ARG /* 5 1/4 high density */
46*d5c9a868SElliott Hughes #define MDD514	12,0,40,2, 9,0,MDEF_ARG /* 5 1/4 double density (360k) */
47*d5c9a868SElliott Hughes #define MSS514	12,0,40,1, 9,0,MDEF_ARG /* 5 1/4 single sided DD, (180k) */
48*d5c9a868SElliott Hughes #define MDDsmall	12,0,40,2, 8,0,MDEF_ARG /* 5 1/4 double density (320k) */
49*d5c9a868SElliott Hughes #define MSSsmall	12,0,40,1, 8,0,MDEF_ARG /* 5 1/4 single sided DD, (160k) */
50*d5c9a868SElliott Hughes 
51*d5c9a868SElliott Hughes #define FED312	12,0,80,2,36,0,FDEF_ARG /* 3 1/2 extra density */
52*d5c9a868SElliott Hughes #define FHD312	12,0,80,2,18,0,FDEF_ARG /* 3 1/2 high density */
53*d5c9a868SElliott Hughes #define FDD312	12,0,80,2, 9,0,FDEF_ARG /* 3 1/2 double density */
54*d5c9a868SElliott Hughes #define FHD514	12,0,80,2,15,0,FDEF_ARG /* 5 1/4 high density */
55*d5c9a868SElliott Hughes #define FDD514	12,0,40,2, 9,0,FDEF_ARG /* 5 1/4 double density (360k) */
56*d5c9a868SElliott Hughes #define FSS514	12,0,40,1, 9,0,FDEF_ARG /* 5 1/4 single sided DD, (180k) */
57*d5c9a868SElliott Hughes #define FDDsmall	12,0,40,2, 8,0,FDEF_ARG /* 5 1/4 double density (320k) */
58*d5c9a868SElliott Hughes #define FSSsmall	12,0,40,1, 8,0,FDEF_ARG /* 5 1/4 single sided DD, (160k) */
59*d5c9a868SElliott Hughes 
60*d5c9a868SElliott Hughes #define GENHD	16,0, 0,0, 0,0,MDEF_ARG /* Generic 16 bit FAT fs */
61*d5c9a868SElliott Hughes #define GENFD	12,0,80,2,18,0,MDEF_ARG /* Generic 12 bit FAT fs */
62*d5c9a868SElliott Hughes #define VOLDFD	12,0,80,2,18,0,VOLD_DEF_ARG /* Generic 12 bit FAT fs with vold */
63*d5c9a868SElliott Hughes #define GEN    	 0,0, 0,0, 0,0,MDEF_ARG /* Generic fs of any FAT bits */
64*d5c9a868SElliott Hughes 
65*d5c9a868SElliott Hughes #define ZIPJAZ(x,c,h,s,y) 16,(x),(c),(h),(s),(s),0L, 4, \
66*d5c9a868SElliott Hughes 		DEF_ARG1((y)|MFORMAT_ONLY_FLAG) /* Jaz disks */
67*d5c9a868SElliott Hughes 
68*d5c9a868SElliott Hughes #define JAZ(x)	 ZIPJAZ(x,1021, 64, 32, 0)
69*d5c9a868SElliott Hughes #define RJAZ(x)	 ZIPJAZ(x,1021, 64, 32, SCSI_FLAG|PRIV_FLAG)
70*d5c9a868SElliott Hughes #define ZIP(x)	 ZIPJAZ(x,96, 64, 32, 0)
71*d5c9a868SElliott Hughes #define RZIP(x)	 ZIPJAZ(x,96, 64, 32, SCSI_FLAG|PRIV_FLAG)
72*d5c9a868SElliott Hughes 
73*d5c9a868SElliott Hughes #pragma GCC diagnostic pop
74*d5c9a868SElliott Hughes 
75*d5c9a868SElliott Hughes #define REMOTE    {"$DISPLAY", 'X', 0,0, 0,0, 0,0,0L, DEF_ARG0(FLOPPYD_FLAG)}
76*d5c9a868SElliott Hughes 
77*d5c9a868SElliott Hughes 
78*d5c9a868SElliott Hughes 
79*d5c9a868SElliott Hughes #if defined(INIT_GENERIC) || defined(INIT_NOOP)
compare_geom(struct device * dev,struct device * orig_dev)80*d5c9a868SElliott Hughes static int compare_geom(struct device *dev, struct device *orig_dev)
81*d5c9a868SElliott Hughes {
82*d5c9a868SElliott Hughes 	if(IS_MFORMAT_ONLY(orig_dev))
83*d5c9a868SElliott Hughes 		return 0; /* geometry only for mformatting ==> ok */
84*d5c9a868SElliott Hughes 	if(!orig_dev || !orig_dev->tracks || !dev || !dev->tracks)
85*d5c9a868SElliott Hughes 		return 0; /* no original device. This is ok */
86*d5c9a868SElliott Hughes 	return(orig_dev->tracks != dev->tracks ||
87*d5c9a868SElliott Hughes 	       orig_dev->heads != dev->heads ||
88*d5c9a868SElliott Hughes 	       orig_dev->sectors  != dev->sectors);
89*d5c9a868SElliott Hughes }
90*d5c9a868SElliott Hughes #endif
91*d5c9a868SElliott Hughes 
92*d5c9a868SElliott Hughes #define devices const_devices
93*d5c9a868SElliott Hughes 
94*d5c9a868SElliott Hughes 
95*d5c9a868SElliott Hughes #ifdef __CYGWIN__
96*d5c9a868SElliott Hughes #define predefined_devices
97*d5c9a868SElliott Hughes struct device devices[] = {
98*d5c9a868SElliott Hughes    {"\\\\\\\\.\\\\A:", 'A', GENFD },
99*d5c9a868SElliott Hughes };
100*d5c9a868SElliott Hughes #endif /* CYGWIN */
101*d5c9a868SElliott Hughes 
102*d5c9a868SElliott Hughes 
103*d5c9a868SElliott Hughes #ifdef OS_aux
104*d5c9a868SElliott Hughes #define predefined_devices
105*d5c9a868SElliott Hughes struct device devices[] = {
106*d5c9a868SElliott Hughes    {"/dev/floppy0", 'A', GENFD },
107*d5c9a868SElliott Hughes    {"/dev/rdsk/c104d0s31", 'J', JAZ(O_EXCL) },
108*d5c9a868SElliott Hughes    {"/dev/rdsk/c105d0s31", 'Z', ZIP(O_EXCL) },
109*d5c9a868SElliott Hughes    REMOTE
110*d5c9a868SElliott Hughes };
111*d5c9a868SElliott Hughes #endif /* aux */
112*d5c9a868SElliott Hughes 
113*d5c9a868SElliott Hughes 
114*d5c9a868SElliott Hughes #ifdef OS_lynxos
115*d5c9a868SElliott Hughes #define predefined_devices
116*d5c9a868SElliott Hughes struct device devices[] = {
117*d5c9a868SElliott Hughes 	{"/dev/fd1440.0", 	'A', MHD312 },
118*d5c9a868SElliott Hughes 	REMOTE
119*d5c9a868SElliott Hughes };
120*d5c9a868SElliott Hughes #endif
121*d5c9a868SElliott Hughes 
122*d5c9a868SElliott Hughes 
123*d5c9a868SElliott Hughes #ifdef __BEOS__
124*d5c9a868SElliott Hughes #define predefined_devices
125*d5c9a868SElliott Hughes struct device devices[] = {
126*d5c9a868SElliott Hughes 	{"/dev/disk/floppy/raw", 	'A', MHD312 },
127*d5c9a868SElliott Hughes 	REMOTE
128*d5c9a868SElliott Hughes };
129*d5c9a868SElliott Hughes #endif /* BEBOX */
130*d5c9a868SElliott Hughes 
131*d5c9a868SElliott Hughes 
132*d5c9a868SElliott Hughes #ifdef OS_hpux
133*d5c9a868SElliott Hughes 
134*d5c9a868SElliott Hughes #define predefined_devices
135*d5c9a868SElliott Hughes struct device devices[] = {
136*d5c9a868SElliott Hughes #ifdef OS_hpux10
137*d5c9a868SElliott Hughes /* hpux10 uses different device names according to Frank Maritato
138*d5c9a868SElliott Hughes  * <[email protected]> */
139*d5c9a868SElliott Hughes 	{"/dev/floppy/c0t0d0",		'A', MHD312 },
140*d5c9a868SElliott Hughes 	{"/dev/floppy/c0t0d1",		'B', MHD312 }, /* guessed by me */
141*d5c9a868SElliott Hughes  	{"/dev/rscsi",			'C', GENHD }, /* guessed by me */
142*d5c9a868SElliott Hughes #else
143*d5c9a868SElliott Hughes /* Use rfloppy, according to Simao Campos <[email protected]> */
144*d5c9a868SElliott Hughes 	{"/dev/rfloppy/c201d0s0",	'A', FHD312 },
145*d5c9a868SElliott Hughes 	{"/dev/rfloppy/c20Ad0s0", 	'A', FHD312 },
146*d5c9a868SElliott Hughes  	{"/dev/rfloppy/c201d1s0",	'B', FHD312 },
147*d5c9a868SElliott Hughes  	{"/dev/rfloppy/c20Ad1s0",	'B', FHD312 },
148*d5c9a868SElliott Hughes  	{"/dev/rscsi",			'C', GENHD },
149*d5c9a868SElliott Hughes #endif
150*d5c9a868SElliott Hughes 	{"/dev/rdsk/c201d4",		'J', RJAZ(O_EXCL) },
151*d5c9a868SElliott Hughes 	{"/dev/rdsk/c201d4s0",		'J', RJAZ(O_EXCL) },
152*d5c9a868SElliott Hughes 	{"/dev/rdsk/c201d5",		'Z', RZIP(O_EXCL) },
153*d5c9a868SElliott Hughes 	{"/dev/rdsk/c201d5s0",		'Z', RZIP(O_EXCL) },
154*d5c9a868SElliott Hughes 	REMOTE
155*d5c9a868SElliott Hughes };
156*d5c9a868SElliott Hughes 
157*d5c9a868SElliott Hughes #ifdef HAVE_SYS_FLOPPY
158*d5c9a868SElliott Hughes /* geometry setting ioctl's contributed by Paolo Zeppegno
159*d5c9a868SElliott Hughes  * <[email protected]>, may cause "Not a typewriter" messages on other
160*d5c9a868SElliott Hughes  * versions according to [email protected] */
161*d5c9a868SElliott Hughes 
162*d5c9a868SElliott Hughes #include <sys/floppy.h>
163*d5c9a868SElliott Hughes #undef SSIZE
164*d5c9a868SElliott Hughes 
165*d5c9a868SElliott Hughes struct generic_floppy_struct
166*d5c9a868SElliott Hughes {
167*d5c9a868SElliott Hughes   struct floppy_geometry fg;
168*d5c9a868SElliott Hughes };
169*d5c9a868SElliott Hughes 
170*d5c9a868SElliott Hughes #define BLOCK_MAJOR 24
171*d5c9a868SElliott Hughes #define CHAR_MAJOR 112
172*d5c9a868SElliott Hughes 
get_parameters(int fd,struct generic_floppy_struct * floppy)173*d5c9a868SElliott Hughes static inline int get_parameters(int fd, struct generic_floppy_struct *floppy)
174*d5c9a868SElliott Hughes {
175*d5c9a868SElliott Hughes 	if (ioctl(fd, FLOPPY_GET_GEOMETRY, &(floppy->fg)) != 0) {
176*d5c9a868SElliott Hughes 		perror("FLOPPY_GET_GEOMETRY");
177*d5c9a868SElliott Hughes 		return(1);
178*d5c9a868SElliott Hughes 	}
179*d5c9a868SElliott Hughes 
180*d5c9a868SElliott Hughes 	return 0;
181*d5c9a868SElliott Hughes }
182*d5c9a868SElliott Hughes 
183*d5c9a868SElliott Hughes #define TRACKS(floppy) floppy.fg.tracks
184*d5c9a868SElliott Hughes #define HEADS(floppy) floppy.fg.heads
185*d5c9a868SElliott Hughes #define SECTORS(floppy) floppy.fg.sectors
186*d5c9a868SElliott Hughes #define FD_SECTSIZE(floppy) floppy.fg.sector_size
187*d5c9a868SElliott Hughes #define FD_SET_SECTSIZE(floppy,v) { floppy.fg.sector_size = v; }
188*d5c9a868SElliott Hughes 
set_parameters(int fd,struct generic_floppy_struct * floppy,struct MT_STAT * buf)189*d5c9a868SElliott Hughes static inline int set_parameters(int fd, struct generic_floppy_struct *floppy,
190*d5c9a868SElliott Hughes 				 struct MT_STAT *buf)
191*d5c9a868SElliott Hughes {
192*d5c9a868SElliott Hughes 	if (ioctl(fd, FLOPPY_SET_GEOMETRY, &(floppy->fg)) != 0) {
193*d5c9a868SElliott Hughes 		perror("");
194*d5c9a868SElliott Hughes 		return(1);
195*d5c9a868SElliott Hughes 	}
196*d5c9a868SElliott Hughes 
197*d5c9a868SElliott Hughes 	return 0;
198*d5c9a868SElliott Hughes }
199*d5c9a868SElliott Hughes #define INIT_GENERIC
200*d5c9a868SElliott Hughes #endif
201*d5c9a868SElliott Hughes 
202*d5c9a868SElliott Hughes #endif /* hpux */
203*d5c9a868SElliott Hughes 
204*d5c9a868SElliott Hughes 
205*d5c9a868SElliott Hughes #if (defined(OS_sinix) || defined(VENDOR_sni) || defined(SNI))
206*d5c9a868SElliott Hughes #define predefined_devices
207*d5c9a868SElliott Hughes struct device devices[] = {
208*d5c9a868SElliott Hughes #ifdef CPU_mips     /* for Siemens Nixdorf's  SINIX-N/O (mips) 5.4x SVR4 */
209*d5c9a868SElliott Hughes 	{ "/dev/at/flp/f0t",    'A', FHD312},
210*d5c9a868SElliott Hughes 	{ "/dev/fd0",           'A', GENFD},
211*d5c9a868SElliott Hughes #else
212*d5c9a868SElliott Hughes #ifdef CPU_i386     /* for Siemens Nixdorf's  SINIX-D/L (intel) 5.4x SVR4 */
213*d5c9a868SElliott Hughes 	{ "/dev/fd0135ds18",	'A', FHD312},
214*d5c9a868SElliott Hughes 	{ "/dev/fd0135ds9",	'A', FDD312},
215*d5c9a868SElliott Hughes 	{ "/dev/fd0",		'A', GENFD},
216*d5c9a868SElliott Hughes 	{ "/dev/fd1135ds15",	'B', FHD514},
217*d5c9a868SElliott Hughes 	{ "/dev/fd1135ds9",	'B', FDD514},
218*d5c9a868SElliott Hughes 	{ "/dev/fd1",		'B', GENFD},
219*d5c9a868SElliott Hughes #endif /* CPU_i386 */
220*d5c9a868SElliott Hughes #endif /*mips*/
221*d5c9a868SElliott Hughes 	REMOTE
222*d5c9a868SElliott Hughes };
223*d5c9a868SElliott Hughes #endif
224*d5c9a868SElliott Hughes 
225*d5c9a868SElliott Hughes #ifdef OS_ultrix
226*d5c9a868SElliott Hughes #define predefined_devices
227*d5c9a868SElliott Hughes struct device devices[] = {
228*d5c9a868SElliott Hughes 	{"/dev/rfd0a",		'A', GENFD}, /* guessed */
229*d5c9a868SElliott Hughes 	{"/dev/rfd0c",		'A', GENFD}, /* guessed */
230*d5c9a868SElliott Hughes 	REMOTE
231*d5c9a868SElliott Hughes };
232*d5c9a868SElliott Hughes 
233*d5c9a868SElliott Hughes #endif
234*d5c9a868SElliott Hughes 
235*d5c9a868SElliott Hughes 
236*d5c9a868SElliott Hughes #ifdef OS_isc
237*d5c9a868SElliott Hughes #define predefined_devices
238*d5c9a868SElliott Hughes #if (defined(OS_isc2) && defined(OLDSTUFF))
239*d5c9a868SElliott Hughes struct device devices[] = {
240*d5c9a868SElliott Hughes 	{"/dev/rdsk/f0d9dt",   	'A', FDD514},
241*d5c9a868SElliott Hughes 	{"/dev/rdsk/f0q15dt",	'A', FHD514},
242*d5c9a868SElliott Hughes 	{"/dev/rdsk/f0d8dt",	'A', FDDsmall},
243*d5c9a868SElliott Hughes 	{"/dev/rdsk/f13ht",	'B', FHD312},
244*d5c9a868SElliott Hughes 	{"/dev/rdsk/f13dt",	'B', FDD312},
245*d5c9a868SElliott Hughes 	{"/dev/rdsk/0p1",	'C', GENHD},
246*d5c9a868SElliott Hughes 	{"/usr/vpix/defaults/C:",'D',12, 0, 0, 0, 0,8704L,DEF_ARG0},
247*d5c9a868SElliott Hughes 	{"$HOME/vpix/C:", 	'E', 12, 0, 0, 0, 0,8704L,MDEF_ARG},
248*d5c9a868SElliott Hughes 	REMOTE
249*d5c9a868SElliott Hughes };
250*d5c9a868SElliott Hughes #else
251*d5c9a868SElliott Hughes /* contributed by [email protected] (Larry Jones) */
252*d5c9a868SElliott Hughes struct device devices[] = {
253*d5c9a868SElliott Hughes 	{"/dev/rfd0",		'A', GEN},
254*d5c9a868SElliott Hughes 	{"/dev/rfd1",		'B', GEN},
255*d5c9a868SElliott Hughes 	{"/dev/rdsk/0p1",	'C', GEN},
256*d5c9a868SElliott Hughes 	{"/usr/vpix/defaults/C:",'D', GEN, 1},
257*d5c9a868SElliott Hughes 	{"$HOME/vpix/C:", 	'E', GEN, 1},
258*d5c9a868SElliott Hughes 	REMOTE
259*d5c9a868SElliott Hughes };
260*d5c9a868SElliott Hughes 
261*d5c9a868SElliott Hughes #include <sys/vtoc.h>
262*d5c9a868SElliott Hughes #include <sys/sysmacros.h>
263*d5c9a868SElliott Hughes #undef SSIZE
264*d5c9a868SElliott Hughes #define BLOCK_MAJOR 1
265*d5c9a868SElliott Hughes #define CHAR_MAJOR  1
266*d5c9a868SElliott Hughes #define generic_floppy_struct disk_parms
267*d5c9a868SElliott Hughes int ioctl(int, int, void *);
268*d5c9a868SElliott Hughes 
get_parameters(int fd,struct generic_floppy_struct * floppy)269*d5c9a868SElliott Hughes static int get_parameters(int fd, struct generic_floppy_struct *floppy)
270*d5c9a868SElliott Hughes {
271*d5c9a868SElliott Hughes 	mt_off_t off;
272*d5c9a868SElliott Hughes 	char buf[512];
273*d5c9a868SElliott Hughes 
274*d5c9a868SElliott Hughes 	off = lseek(fd, 0, SEEK_CUR);
275*d5c9a868SElliott Hughes 	if(off < 0) {
276*d5c9a868SElliott Hughes 		perror("device seek 1");
277*d5c9a868SElliott Hughes 		exit(1);
278*d5c9a868SElliott Hughes 	}
279*d5c9a868SElliott Hughes 	if (off == 0) {
280*d5c9a868SElliott Hughes 		/* need to read at least 1 sector to get correct info */
281*d5c9a868SElliott Hughes 		read(fd, buf, sizeof buf);
282*d5c9a868SElliott Hughes 		if(lseek(fd, 0, SEEK_SET) < 0) {
283*d5c9a868SElliott Hughes 			perror("device seek 2");
284*d5c9a868SElliott Hughes 			exit(1);
285*d5c9a868SElliott Hughes 		}
286*d5c9a868SElliott Hughes 	}
287*d5c9a868SElliott Hughes 	return ioctl(fd, V_GETPARMS, floppy);
288*d5c9a868SElliott Hughes }
289*d5c9a868SElliott Hughes 
290*d5c9a868SElliott Hughes #define TRACKS(floppy)  (floppy).dp_cyls
291*d5c9a868SElliott Hughes #define HEADS(floppy)   (floppy).dp_heads
292*d5c9a868SElliott Hughes #define SECTORS(floppy) (floppy).dp_sectors
293*d5c9a868SElliott Hughes #define FD_SECTSIZE(floppy) (floppy).dp_secsiz
294*d5c9a868SElliott Hughes #define FD_SET_SECTSIZE(floppy,v) { (floppy).dp_secsiz = (v); }
295*d5c9a868SElliott Hughes 
set_parameters(int fd,struct generic_floppy_struct * floppy,struct MT_STAT * buf)296*d5c9a868SElliott Hughes static int set_parameters(int fd, struct generic_floppy_struct *floppy,
297*d5c9a868SElliott Hughes 	struct MT_STAT *buf)
298*d5c9a868SElliott Hughes {
299*d5c9a868SElliott Hughes 	return 1;
300*d5c9a868SElliott Hughes }
301*d5c9a868SElliott Hughes 
302*d5c9a868SElliott Hughes #define INIT_GENERIC
303*d5c9a868SElliott Hughes #endif
304*d5c9a868SElliott Hughes #endif /* isc */
305*d5c9a868SElliott Hughes 
306*d5c9a868SElliott Hughes #ifdef CPU_i370
307*d5c9a868SElliott Hughes #define predefined_devices
308*d5c9a868SElliott Hughes struct device devices[] = {
309*d5c9a868SElliott Hughes 	{"/dev/rfd0", 'A', GENFD},
310*d5c9a868SElliott Hughes 	REMOTE
311*d5c9a868SElliott Hughes };
312*d5c9a868SElliott Hughes #endif /* CPU_i370 */
313*d5c9a868SElliott Hughes 
314*d5c9a868SElliott Hughes #ifdef OS_aix
315*d5c9a868SElliott Hughes /* modified by Federico Bianchi */
316*d5c9a868SElliott Hughes #define predefined_devices
317*d5c9a868SElliott Hughes struct device devices[] = {
318*d5c9a868SElliott Hughes 	{"/dev/fd0",'A',GENFD},
319*d5c9a868SElliott Hughes 	REMOTE
320*d5c9a868SElliott Hughes };
321*d5c9a868SElliott Hughes #endif /* aix */
322*d5c9a868SElliott Hughes 
323*d5c9a868SElliott Hughes 
324*d5c9a868SElliott Hughes #ifdef OS_osf4
325*d5c9a868SElliott Hughes /* modified by Chris Samuel <[email protected]> */
326*d5c9a868SElliott Hughes #define predefined_devices
327*d5c9a868SElliott Hughes struct device devices[] = {
328*d5c9a868SElliott Hughes 	{"/dev/fd0c",'A',GENFD},
329*d5c9a868SElliott Hughes 	REMOTE
330*d5c9a868SElliott Hughes };
331*d5c9a868SElliott Hughes #endif /* OS_osf4 */
332*d5c9a868SElliott Hughes 
333*d5c9a868SElliott Hughes 
334*d5c9a868SElliott Hughes #ifdef OS_solaris
335*d5c9a868SElliott Hughes 
336*d5c9a868SElliott Hughes #ifdef USING_NEW_VOLD
337*d5c9a868SElliott Hughes 
338*d5c9a868SElliott Hughes char *alias_name = NULL;
339*d5c9a868SElliott Hughes 
340*d5c9a868SElliott Hughes extern char *media_oldaliases(char *);
341*d5c9a868SElliott Hughes extern char *media_findname(char *);
342*d5c9a868SElliott Hughes 
getVoldName(struct device * dev,char * name)343*d5c9a868SElliott Hughes char *getVoldName(struct device *dev, char *name)
344*d5c9a868SElliott Hughes {
345*d5c9a868SElliott Hughes 	char *rname;
346*d5c9a868SElliott Hughes 
347*d5c9a868SElliott Hughes 	if(!SHOULD_USE_VOLD(dev))
348*d5c9a868SElliott Hughes 		return name;
349*d5c9a868SElliott Hughes 
350*d5c9a868SElliott Hughes 	/***
351*d5c9a868SElliott Hughes 	 * Solaris specific routines to use the volume management
352*d5c9a868SElliott Hughes 	 * daemon and libraries to get the correct device name...
353*d5c9a868SElliott Hughes 	 ***/
354*d5c9a868SElliott Hughes 	rname = media_findname(name);
355*d5c9a868SElliott Hughes #ifdef HAVE_MEDIA_OLDALIASES
356*d5c9a868SElliott Hughes 	if (rname == NULL) {
357*d5c9a868SElliott Hughes 		if ((alias_name = media_oldaliases(name)) != NULL)
358*d5c9a868SElliott Hughes 			rname = media_findname(alias_name);
359*d5c9a868SElliott Hughes 	}
360*d5c9a868SElliott Hughes #endif
361*d5c9a868SElliott Hughes 	if (rname == NULL) {
362*d5c9a868SElliott Hughes 		fprintf(stderr,
363*d5c9a868SElliott Hughes 				"No such volume or no media in device: %s.\n",
364*d5c9a868SElliott Hughes 				name);
365*d5c9a868SElliott Hughes 		exit(1);
366*d5c9a868SElliott Hughes 	}
367*d5c9a868SElliott Hughes 	return rname;
368*d5c9a868SElliott Hughes }
369*d5c9a868SElliott Hughes #endif /* USING_NEW_VOLD */
370*d5c9a868SElliott Hughes 
371*d5c9a868SElliott Hughes #define predefined_devices
372*d5c9a868SElliott Hughes struct device devices[] = {
373*d5c9a868SElliott Hughes #ifdef  USING_NEW_VOLD
374*d5c9a868SElliott Hughes 	{"floppy", 'A', VOLDFD },
375*d5c9a868SElliott Hughes #elif	USING_VOLD
376*d5c9a868SElliott Hughes 	{"/vol/dev/aliases/floppy0", 'A', GENFD},
377*d5c9a868SElliott Hughes 	{"/dev/rdiskette", 'B', GENFD},
378*d5c9a868SElliott Hughes #else	/* ! USING_VOLD */
379*d5c9a868SElliott Hughes 	{"/dev/rdiskette", 'A', GENFD},
380*d5c9a868SElliott Hughes 	{"/vol/dev/aliases/floppy0", 'B', GENFD},
381*d5c9a868SElliott Hughes #endif	/* USING_VOLD */
382*d5c9a868SElliott Hughes 	{"/dev/rdsk/c0t4d0s2", 'J', RJAZ(O_NDELAY)},
383*d5c9a868SElliott Hughes 	{"/dev/rdsk/c0t5d0s2", 'Z', RZIP(O_NDELAY)},
384*d5c9a868SElliott Hughes 	REMOTE
385*d5c9a868SElliott Hughes };
386*d5c9a868SElliott Hughes 
387*d5c9a868SElliott Hughes 
388*d5c9a868SElliott Hughes 
389*d5c9a868SElliott Hughes #ifdef HAVE_SYS_FDIO_H
390*d5c9a868SElliott Hughes /*
391*d5c9a868SElliott Hughes  * Ofer Licht <[email protected]>, May 14, 1997.
392*d5c9a868SElliott Hughes  */
393*d5c9a868SElliott Hughes 
394*d5c9a868SElliott Hughes #define INIT_GENERIC
395*d5c9a868SElliott Hughes 
396*d5c9a868SElliott Hughes #include <sys/fdio.h>
397*d5c9a868SElliott Hughes #include <sys/mkdev.h>	/* for major() */
398*d5c9a868SElliott Hughes 
399*d5c9a868SElliott Hughes struct generic_floppy_struct
400*d5c9a868SElliott Hughes {
401*d5c9a868SElliott Hughes   struct fd_char fdchar;
402*d5c9a868SElliott Hughes };
403*d5c9a868SElliott Hughes 
404*d5c9a868SElliott Hughes #define BLOCK_MAJOR 36
405*d5c9a868SElliott Hughes #define CHAR_MAJOR 36
406*d5c9a868SElliott Hughes 
get_parameters(int fd,struct generic_floppy_struct * floppy)407*d5c9a868SElliott Hughes static inline int get_parameters(int fd, struct generic_floppy_struct *floppy)
408*d5c9a868SElliott Hughes {
409*d5c9a868SElliott Hughes 	if (ioctl(fd, FDIOGCHAR, &(floppy->fdchar)) != 0) {
410*d5c9a868SElliott Hughes 		perror("");
411*d5c9a868SElliott Hughes 		ioctl(fd, FDEJECT, NULL);
412*d5c9a868SElliott Hughes 		return(1);
413*d5c9a868SElliott Hughes 	}
414*d5c9a868SElliott Hughes 	return 0;
415*d5c9a868SElliott Hughes }
416*d5c9a868SElliott Hughes 
417*d5c9a868SElliott Hughes #define TRACKS(floppy) floppy.fdchar.fdc_ncyl
418*d5c9a868SElliott Hughes #define HEADS(floppy) floppy.fdchar.fdc_nhead
419*d5c9a868SElliott Hughes #define SECTORS(floppy) floppy.fdchar.fdc_secptrack
420*d5c9a868SElliott Hughes /* SECTORS_PER_DISK(floppy) not used */
421*d5c9a868SElliott Hughes #define FD_SECTSIZE(floppy) floppy.fdchar.fdc_sec_size
422*d5c9a868SElliott Hughes #define FD_SET_SECTSIZE(floppy,v) { floppy.fdchar.fdc_sec_size = v; }
423*d5c9a868SElliott Hughes 
set_parameters(int fd,struct generic_floppy_struct * floppy,struct MT_STAT * buf UNUSEDP)424*d5c9a868SElliott Hughes static inline int set_parameters(int fd, struct generic_floppy_struct *floppy,
425*d5c9a868SElliott Hughes 				 struct MT_STAT *buf UNUSEDP)
426*d5c9a868SElliott Hughes {
427*d5c9a868SElliott Hughes 	if (ioctl(fd, FDIOSCHAR, &(floppy->fdchar)) != 0) {
428*d5c9a868SElliott Hughes 		ioctl(fd, FDEJECT, NULL);
429*d5c9a868SElliott Hughes 		perror("");
430*d5c9a868SElliott Hughes 		return(1);
431*d5c9a868SElliott Hughes 	}
432*d5c9a868SElliott Hughes 	return 0;
433*d5c9a868SElliott Hughes }
434*d5c9a868SElliott Hughes #endif
435*d5c9a868SElliott Hughes #endif /* solaris */
436*d5c9a868SElliott Hughes 
437*d5c9a868SElliott Hughes #ifdef OS_sunos3
438*d5c9a868SElliott Hughes #define predefined_devices
439*d5c9a868SElliott Hughes struct device devices[] = {
440*d5c9a868SElliott Hughes 	{"/dev/rfdl0c",	'A', FDD312},
441*d5c9a868SElliott Hughes 	{"/dev/rfd0c",	'A', FHD312},
442*d5c9a868SElliott Hughes 	REMOTE
443*d5c9a868SElliott Hughes };
444*d5c9a868SElliott Hughes #endif /* OS_sunos3 */
445*d5c9a868SElliott Hughes 
446*d5c9a868SElliott Hughes #ifdef OS_xenix
447*d5c9a868SElliott Hughes #define predefined_devices
448*d5c9a868SElliott Hughes struct device devices[] = {
449*d5c9a868SElliott Hughes 	{"/dev/fd096ds15",	'A', FHD514},
450*d5c9a868SElliott Hughes 	{"/dev/fd048ds9",	'A', FDD514},
451*d5c9a868SElliott Hughes 	{"/dev/fd1135ds18",	'B', FHD312},
452*d5c9a868SElliott Hughes 	{"/dev/fd1135ds9",	'B', FDD312},
453*d5c9a868SElliott Hughes 	{"/dev/hd0d",		'C', GENHD},
454*d5c9a868SElliott Hughes 	REMOTE
455*d5c9a868SElliott Hughes };
456*d5c9a868SElliott Hughes #endif /* OS_xenix */
457*d5c9a868SElliott Hughes 
458*d5c9a868SElliott Hughes #ifdef OS_sco
459*d5c9a868SElliott Hughes #define predefined_devices
460*d5c9a868SElliott Hughes struct device devices[] = {
461*d5c9a868SElliott Hughes 	{ "/dev/fd0135ds18",	'A', FHD312},
462*d5c9a868SElliott Hughes 	{ "/dev/fd0135ds9",	'A', FDD312},
463*d5c9a868SElliott Hughes 	{ "/dev/fd0",		'A', GENFD},
464*d5c9a868SElliott Hughes 	{ "/dev/fd1135ds15",	'B', FHD514},
465*d5c9a868SElliott Hughes 	{ "/dev/fd1135ds9",	'B', FDD514},
466*d5c9a868SElliott Hughes 	{ "/dev/fd1",		'B', GENFD},
467*d5c9a868SElliott Hughes 	{ "/dev/hd0d",		'C', GENHD},
468*d5c9a868SElliott Hughes 	REMOTE
469*d5c9a868SElliott Hughes };
470*d5c9a868SElliott Hughes #endif /* OS_sco */
471*d5c9a868SElliott Hughes 
472*d5c9a868SElliott Hughes 
473*d5c9a868SElliott Hughes #ifdef OS_irix
474*d5c9a868SElliott Hughes #define predefined_devices
475*d5c9a868SElliott Hughes struct device devices[] = {
476*d5c9a868SElliott Hughes   { "/dev/rdsk/fds0d2.3.5hi",	'A', FHD312},
477*d5c9a868SElliott Hughes   { "/dev/rdsk/fds0d2.3.5",	'A', FDD312},
478*d5c9a868SElliott Hughes   { "/dev/rdsk/fds0d2.96",	'A', FHD514},
479*d5c9a868SElliott Hughes   {"/dev/rdsk/fds0d2.48",	'A', FDD514},
480*d5c9a868SElliott Hughes   REMOTE
481*d5c9a868SElliott Hughes };
482*d5c9a868SElliott Hughes #endif /* OS_irix */
483*d5c9a868SElliott Hughes 
484*d5c9a868SElliott Hughes 
485*d5c9a868SElliott Hughes #ifdef OS_sunos4
486*d5c9a868SElliott Hughes #include <sys/ioctl.h>
487*d5c9a868SElliott Hughes #include <sun/dkio.h>
488*d5c9a868SElliott Hughes 
489*d5c9a868SElliott Hughes #define predefined_devices
490*d5c9a868SElliott Hughes struct device devices[] = {
491*d5c9a868SElliott Hughes 	{"/dev/rfd0c",	'A', GENFD},
492*d5c9a868SElliott Hughes 	{"/dev/rsd4c",	'J', RJAZ(O_NDELAY)},
493*d5c9a868SElliott Hughes 	{"/dev/rsd5c",	'Z', RZIP(O_NDELAY)},
494*d5c9a868SElliott Hughes 	REMOTE
495*d5c9a868SElliott Hughes };
496*d5c9a868SElliott Hughes 
497*d5c9a868SElliott Hughes /*
498*d5c9a868SElliott Hughes  * Stuffing back the floppy parameters into the driver allows for gems
499*d5c9a868SElliott Hughes  * like 10 sector or single sided floppies from Atari ST systems.
500*d5c9a868SElliott Hughes  *
501*d5c9a868SElliott Hughes  * Martin Schulz, Universite de Moncton, N.B., Canada, March 11, 1991.
502*d5c9a868SElliott Hughes  */
503*d5c9a868SElliott Hughes 
504*d5c9a868SElliott Hughes #define INIT_GENERIC
505*d5c9a868SElliott Hughes 
506*d5c9a868SElliott Hughes struct generic_floppy_struct
507*d5c9a868SElliott Hughes {
508*d5c9a868SElliott Hughes   struct fdk_char dkbuf;
509*d5c9a868SElliott Hughes   struct dk_map dkmap;
510*d5c9a868SElliott Hughes };
511*d5c9a868SElliott Hughes 
512*d5c9a868SElliott Hughes #define BLOCK_MAJOR 16
513*d5c9a868SElliott Hughes #define CHAR_MAJOR 54
514*d5c9a868SElliott Hughes 
get_parameters(int fd,struct generic_floppy_struct * floppy)515*d5c9a868SElliott Hughes static inline int get_parameters(int fd, struct generic_floppy_struct *floppy)
516*d5c9a868SElliott Hughes {
517*d5c9a868SElliott Hughes 	if (ioctl(fd, DKIOCGPART, &(floppy->dkmap)) != 0) {
518*d5c9a868SElliott Hughes 		perror("DKIOCGPART");
519*d5c9a868SElliott Hughes 		ioctl(fd, FDKEJECT, NULL);
520*d5c9a868SElliott Hughes 		return(1);
521*d5c9a868SElliott Hughes 	}
522*d5c9a868SElliott Hughes 
523*d5c9a868SElliott Hughes 	if (ioctl(fd, FDKIOGCHAR, &( floppy->dkbuf)) != 0) {
524*d5c9a868SElliott Hughes 		perror("");
525*d5c9a868SElliott Hughes 		ioctl(fd, FDKEJECT, NULL);
526*d5c9a868SElliott Hughes 		return(1);
527*d5c9a868SElliott Hughes 	}
528*d5c9a868SElliott Hughes 	return 0;
529*d5c9a868SElliott Hughes }
530*d5c9a868SElliott Hughes 
531*d5c9a868SElliott Hughes #define TRACKS(floppy) floppy.dkbuf.ncyl
532*d5c9a868SElliott Hughes #define HEADS(floppy) floppy.dkbuf.nhead
533*d5c9a868SElliott Hughes #define SECTORS(floppy) floppy.dkbuf.secptrack
534*d5c9a868SElliott Hughes #define SECTORS_PER_DISK(floppy) floppy.dkmap.dkl_nblk
535*d5c9a868SElliott Hughes #define FD_SECTSIZE(floppy) floppy.dkbuf.sec_size
536*d5c9a868SElliott Hughes #define FD_SET_SECTSIZE(floppy,v) { floppy.dkbuf.sec_size = v; }
537*d5c9a868SElliott Hughes 
set_parameters(int fd,struct generic_floppy_struct * floppy,struct MT_STAT * buf)538*d5c9a868SElliott Hughes static inline int set_parameters(int fd, struct generic_floppy_struct *floppy,
539*d5c9a868SElliott Hughes 				 struct MT_STAT *buf)
540*d5c9a868SElliott Hughes {
541*d5c9a868SElliott Hughes 	if (ioctl(fd, FDKIOSCHAR, &(floppy->dkbuf)) != 0) {
542*d5c9a868SElliott Hughes 		ioctl(fd, FDKEJECT, NULL);
543*d5c9a868SElliott Hughes 		perror("");
544*d5c9a868SElliott Hughes 		return(1);
545*d5c9a868SElliott Hughes 	}
546*d5c9a868SElliott Hughes 
547*d5c9a868SElliott Hughes 	if (ioctl(fd, ( unsigned int) DKIOCSPART, &(floppy->dkmap)) != 0) {
548*d5c9a868SElliott Hughes 		ioctl(fd, FDKEJECT, NULL);
549*d5c9a868SElliott Hughes 		perror("");
550*d5c9a868SElliott Hughes 		return(1);
551*d5c9a868SElliott Hughes 	}
552*d5c9a868SElliott Hughes 	return 0;
553*d5c9a868SElliott Hughes }
554*d5c9a868SElliott Hughes #define INIT_GENERIC
555*d5c9a868SElliott Hughes #endif /* sparc && sunos */
556*d5c9a868SElliott Hughes 
557*d5c9a868SElliott Hughes 
558*d5c9a868SElliott Hughes #ifdef DPX1000
559*d5c9a868SElliott Hughes #define predefined_devices
560*d5c9a868SElliott Hughes struct device devices[] = {
561*d5c9a868SElliott Hughes 	/* [block device]: DPX1000 has /dev/flbm60, DPX2 has /dev/easyfb */
562*d5c9a868SElliott Hughes 	{"/dev/flbm60", 'A', MHD514};
563*d5c9a868SElliott Hughes 	{"/dev/flbm60", 'B', MDD514},
564*d5c9a868SElliott Hughes 	{"/dev/flbm60", 'C', MDDsmall},
565*d5c9a868SElliott Hughes 	{"/dev/flbm60", 'D', MSS},
566*d5c9a868SElliott Hughes 	{"/dev/flbm60", 'E', MSSsmall},
567*d5c9a868SElliott Hughes 	REMOTE
568*d5c9a868SElliott Hughes };
569*d5c9a868SElliott Hughes #endif /* DPX1000 */
570*d5c9a868SElliott Hughes 
571*d5c9a868SElliott Hughes #ifdef OS_bosx
572*d5c9a868SElliott Hughes #define predefined_devices
573*d5c9a868SElliott Hughes struct device devices[] = {
574*d5c9a868SElliott Hughes 	/* [block device]: DPX1000 has /dev/flbm60, DPX2 has /dev/easyfb */
575*d5c9a868SElliott Hughes 	{"/dev/easyfb", 'A', MHD514},
576*d5c9a868SElliott Hughes 	{"/dev/easyfb", 'B', MDD514},
577*d5c9a868SElliott Hughes 	{"/dev/easyfb", 'C', MDDsmall},
578*d5c9a868SElliott Hughes 	{"/dev/easyfb", 'D', MSS},
579*d5c9a868SElliott Hughes 	{"/dev/easyfb", 'E', MSSsmall},
580*d5c9a868SElliott Hughes 	REMOTE
581*d5c9a868SElliott Hughes };
582*d5c9a868SElliott Hughes #endif /* OS_bosx */
583*d5c9a868SElliott Hughes 
584*d5c9a868SElliott Hughes #ifdef OS_linux
585*d5c9a868SElliott Hughes 
586*d5c9a868SElliott Hughes static const char *error_msg[22]={
587*d5c9a868SElliott Hughes "Missing Data Address Mark",
588*d5c9a868SElliott Hughes "Bad cylinder",
589*d5c9a868SElliott Hughes "Scan not satisfied",
590*d5c9a868SElliott Hughes "Scan equal hit",
591*d5c9a868SElliott Hughes "Wrong cylinder",
592*d5c9a868SElliott Hughes "CRC error in data field",
593*d5c9a868SElliott Hughes "Control Mark = deleted",
594*d5c9a868SElliott Hughes 0,
595*d5c9a868SElliott Hughes 
596*d5c9a868SElliott Hughes "Missing Address Mark",
597*d5c9a868SElliott Hughes "Write Protect",
598*d5c9a868SElliott Hughes "No Data - unreadable",
599*d5c9a868SElliott Hughes 0,
600*d5c9a868SElliott Hughes "OverRun",
601*d5c9a868SElliott Hughes "CRC error in data or address",
602*d5c9a868SElliott Hughes 0,
603*d5c9a868SElliott Hughes "End Of Cylinder",
604*d5c9a868SElliott Hughes 
605*d5c9a868SElliott Hughes 0,
606*d5c9a868SElliott Hughes 0,
607*d5c9a868SElliott Hughes 0,
608*d5c9a868SElliott Hughes "Not ready",
609*d5c9a868SElliott Hughes "Equipment check error",
610*d5c9a868SElliott Hughes "Seek end" };
611*d5c9a868SElliott Hughes 
612*d5c9a868SElliott Hughes 
print_message(RawRequest_t * raw_cmd,const char * message)613*d5c9a868SElliott Hughes static __inline__ void print_message(RawRequest_t *raw_cmd,const char *message)
614*d5c9a868SElliott Hughes {
615*d5c9a868SElliott Hughes 	int i, code;
616*d5c9a868SElliott Hughes 	if(!message)
617*d5c9a868SElliott Hughes 		return;
618*d5c9a868SElliott Hughes 
619*d5c9a868SElliott Hughes 	fprintf(stderr,"   ");
620*d5c9a868SElliott Hughes 	for (i=0; i< raw_cmd->cmd_count; i++)
621*d5c9a868SElliott Hughes 		fprintf(stderr,"%2.2x ",
622*d5c9a868SElliott Hughes 			(int)raw_cmd->cmd[i] );
623*d5c9a868SElliott Hughes 	fprintf(stderr,"\n");
624*d5c9a868SElliott Hughes 	for (i=0; i< raw_cmd->reply_count; i++)
625*d5c9a868SElliott Hughes 		fprintf(stderr,"%2.2x ",
626*d5c9a868SElliott Hughes 			(int)raw_cmd->reply[i] );
627*d5c9a868SElliott Hughes 	fprintf(stderr,"\n");
628*d5c9a868SElliott Hughes 	code = (raw_cmd->reply[0] <<16) +
629*d5c9a868SElliott Hughes 		(raw_cmd->reply[1] << 8) +
630*d5c9a868SElliott Hughes 		raw_cmd->reply[2];
631*d5c9a868SElliott Hughes 	for(i=0; i<22; i++){
632*d5c9a868SElliott Hughes 		if ((code & (1 << i)) && error_msg[i])
633*d5c9a868SElliott Hughes 			fprintf(stderr,"%s\n",
634*d5c9a868SElliott Hughes 				error_msg[i]);
635*d5c9a868SElliott Hughes 	}
636*d5c9a868SElliott Hughes }
637*d5c9a868SElliott Hughes 
638*d5c9a868SElliott Hughes 
639*d5c9a868SElliott Hughes /* return values:
640*d5c9a868SElliott Hughes  *  -1: Fatal error, don't bother retrying.
641*d5c9a868SElliott Hughes  *   0: OK
642*d5c9a868SElliott Hughes  *   1: minor error, retry
643*d5c9a868SElliott Hughes  */
644*d5c9a868SElliott Hughes 
send_one_cmd(int fd,RawRequest_t * raw_cmd,const char * message)645*d5c9a868SElliott Hughes int send_one_cmd(int fd, RawRequest_t *raw_cmd, const char *message)
646*d5c9a868SElliott Hughes {
647*d5c9a868SElliott Hughes 	if (ioctl( fd, FDRAWCMD, raw_cmd) >= 0) {
648*d5c9a868SElliott Hughes 		if (raw_cmd->reply_count < 7) {
649*d5c9a868SElliott Hughes 			fprintf(stderr,"Short reply from FDC\n");
650*d5c9a868SElliott Hughes 			return -1;
651*d5c9a868SElliott Hughes 		}
652*d5c9a868SElliott Hughes 		return 0;
653*d5c9a868SElliott Hughes 	}
654*d5c9a868SElliott Hughes 
655*d5c9a868SElliott Hughes 	switch(errno) {
656*d5c9a868SElliott Hughes 		case EBUSY:
657*d5c9a868SElliott Hughes 			fprintf(stderr, "FDC busy, sleeping for a second\n");
658*d5c9a868SElliott Hughes 			sleep(1);
659*d5c9a868SElliott Hughes 			return 1;
660*d5c9a868SElliott Hughes 		case EIO:
661*d5c9a868SElliott Hughes 			fprintf(stderr,"resetting controller\n");
662*d5c9a868SElliott Hughes 			if(ioctl(fd, FDRESET, 2)  < 0){
663*d5c9a868SElliott Hughes 				perror("reset");
664*d5c9a868SElliott Hughes 				return -1;
665*d5c9a868SElliott Hughes 			}
666*d5c9a868SElliott Hughes 			return 1;
667*d5c9a868SElliott Hughes 		default:
668*d5c9a868SElliott Hughes 			perror(message);
669*d5c9a868SElliott Hughes 			return -1;
670*d5c9a868SElliott Hughes 	}
671*d5c9a868SElliott Hughes }
672*d5c9a868SElliott Hughes 
673*d5c9a868SElliott Hughes 
674*d5c9a868SElliott Hughes /*
675*d5c9a868SElliott Hughes  * return values
676*d5c9a868SElliott Hughes  *  -1: error
677*d5c9a868SElliott Hughes  *   0: OK, last sector
678*d5c9a868SElliott Hughes  *   1: more raw commands follow
679*d5c9a868SElliott Hughes  */
680*d5c9a868SElliott Hughes 
analyze_one_reply(RawRequest_t * raw_cmd,int * bytes,int do_print)681*d5c9a868SElliott Hughes int analyze_one_reply(RawRequest_t *raw_cmd, int *bytes, int do_print)
682*d5c9a868SElliott Hughes {
683*d5c9a868SElliott Hughes 
684*d5c9a868SElliott Hughes 	if(raw_cmd->reply_count == 7) {
685*d5c9a868SElliott Hughes 		int end;
686*d5c9a868SElliott Hughes 
687*d5c9a868SElliott Hughes 		if (raw_cmd->reply[3] != raw_cmd->cmd[2]) {
688*d5c9a868SElliott Hughes 			/* end of cylinder */
689*d5c9a868SElliott Hughes 			end = raw_cmd->cmd[6] + 1;
690*d5c9a868SElliott Hughes 		} else {
691*d5c9a868SElliott Hughes 			end = raw_cmd->reply[5];
692*d5c9a868SElliott Hughes 		}
693*d5c9a868SElliott Hughes 
694*d5c9a868SElliott Hughes 		*bytes = end - raw_cmd->cmd[4];
695*d5c9a868SElliott Hughes 		/* FIXME: over/under run */
696*d5c9a868SElliott Hughes 		*bytes = *bytes << (7 + raw_cmd->cmd[5]);
697*d5c9a868SElliott Hughes 	} else
698*d5c9a868SElliott Hughes 		*bytes = 0;
699*d5c9a868SElliott Hughes 
700*d5c9a868SElliott Hughes 	switch(raw_cmd->reply[0] & 0xc0){
701*d5c9a868SElliott Hughes 		case 0x40:
702*d5c9a868SElliott Hughes 			if ((raw_cmd->reply[0] & 0x38) == 0 &&
703*d5c9a868SElliott Hughes 			    (raw_cmd->reply[1]) == 0x80 &&
704*d5c9a868SElliott Hughes 			    (raw_cmd->reply[2]) == 0) {
705*d5c9a868SElliott Hughes 				*bytes += 1 << (7 + raw_cmd->cmd[5]);
706*d5c9a868SElliott Hughes 				break;
707*d5c9a868SElliott Hughes 			}
708*d5c9a868SElliott Hughes 
709*d5c9a868SElliott Hughes 			if ( raw_cmd->reply[1] & ST1_WP ){
710*d5c9a868SElliott Hughes 				*bytes = 0;
711*d5c9a868SElliott Hughes 				fprintf(stderr,
712*d5c9a868SElliott Hughes 					"This disk is write protected\n");
713*d5c9a868SElliott Hughes 				return -1;
714*d5c9a868SElliott Hughes 			}
715*d5c9a868SElliott Hughes 			if(!*bytes && do_print)
716*d5c9a868SElliott Hughes 				print_message(raw_cmd, "");
717*d5c9a868SElliott Hughes 			return -1;
718*d5c9a868SElliott Hughes 		case 0x80:
719*d5c9a868SElliott Hughes 			*bytes = 0;
720*d5c9a868SElliott Hughes 			fprintf(stderr,
721*d5c9a868SElliott Hughes 				"invalid command given\n");
722*d5c9a868SElliott Hughes 			return -1;
723*d5c9a868SElliott Hughes 		case 0xc0:
724*d5c9a868SElliott Hughes 			*bytes = 0;
725*d5c9a868SElliott Hughes 			fprintf(stderr,
726*d5c9a868SElliott Hughes 				"abnormal termination caused by polling\n");
727*d5c9a868SElliott Hughes 			return -1;
728*d5c9a868SElliott Hughes 		default:
729*d5c9a868SElliott Hughes 			break;
730*d5c9a868SElliott Hughes 	}
731*d5c9a868SElliott Hughes #ifdef FD_RAW_MORE
732*d5c9a868SElliott Hughes 	if(raw_cmd->flags & FD_RAW_MORE)
733*d5c9a868SElliott Hughes 		return 1;
734*d5c9a868SElliott Hughes #endif
735*d5c9a868SElliott Hughes 	return 0;
736*d5c9a868SElliott Hughes }
737*d5c9a868SElliott Hughes 
738*d5c9a868SElliott Hughes #define predefined_devices
739*d5c9a868SElliott Hughes struct device devices[] = {
740*d5c9a868SElliott Hughes 	{"/dev/fd0", 'A', 0, 0, 80,2, 18,0, MDEF_ARG },
741*d5c9a868SElliott Hughes 	{"/dev/fd1", 'B', 0, 0, 0,0, 0,0, FDEF_ARG },
742*d5c9a868SElliott Hughes 	/* we assume that the Zip or Jaz drive is the second on the SCSI bus */
743*d5c9a868SElliott Hughes 	{"/dev/sdb4",'J', GENHD },
744*d5c9a868SElliott Hughes 	{"/dev/sdb4",'Z', GENHD },
745*d5c9a868SElliott Hughes 	/*	{"/dev/sda4",'D', GENHD },*/
746*d5c9a868SElliott Hughes 	REMOTE
747*d5c9a868SElliott Hughes };
748*d5c9a868SElliott Hughes 
749*d5c9a868SElliott Hughes /*
750*d5c9a868SElliott Hughes  * Stuffing back the floppy parameters into the driver allows for gems
751*d5c9a868SElliott Hughes  * like 21 sector or single sided floppies from Atari ST systems.
752*d5c9a868SElliott Hughes  *
753*d5c9a868SElliott Hughes  * Alain Knaff, Universit� Joseph Fourier, France, November 12, 1993.
754*d5c9a868SElliott Hughes  */
755*d5c9a868SElliott Hughes 
756*d5c9a868SElliott Hughes 
757*d5c9a868SElliott Hughes #define INIT_GENERIC
758*d5c9a868SElliott Hughes #define generic_floppy_struct floppy_struct
759*d5c9a868SElliott Hughes #define BLOCK_MAJOR 2
760*d5c9a868SElliott Hughes #define SECTORS(floppy) floppy.sect
761*d5c9a868SElliott Hughes #define TRACKS(floppy) floppy.track
762*d5c9a868SElliott Hughes #define HEADS(floppy) floppy.head
763*d5c9a868SElliott Hughes #define SECTORS_PER_DISK(floppy) floppy.size
764*d5c9a868SElliott Hughes #define STRETCH(floppy) floppy.stretch
765*d5c9a868SElliott Hughes #define USE_2M(floppy) ((floppy.rate & FD_2M) ? 0xff : 0x80 )
766*d5c9a868SElliott Hughes #define SSIZE(floppy) ((((floppy.rate & 0x38) >> 3 ) + 2) % 8)
767*d5c9a868SElliott Hughes 
set_2m(struct floppy_struct * floppy,unsigned int value)768*d5c9a868SElliott Hughes static __inline__ void set_2m(struct floppy_struct *floppy, unsigned int value)
769*d5c9a868SElliott Hughes {
770*d5c9a868SElliott Hughes 	uint8_t v;
771*d5c9a868SElliott Hughes 	if (value & 0x7f)
772*d5c9a868SElliott Hughes 		v = FD_2M;
773*d5c9a868SElliott Hughes 	else
774*d5c9a868SElliott Hughes 		v = 0;
775*d5c9a868SElliott Hughes 	floppy->rate = (floppy->rate & ~FD_2M) | v;
776*d5c9a868SElliott Hughes }
777*d5c9a868SElliott Hughes #define SET_2M set_2m
778*d5c9a868SElliott Hughes 
set_ssize(struct floppy_struct * floppy,int value)779*d5c9a868SElliott Hughes static __inline__ void set_ssize(struct floppy_struct *floppy, int value)
780*d5c9a868SElliott Hughes {
781*d5c9a868SElliott Hughes 	uint8_t v = (uint8_t) ((( (value & 7) + 6 ) % 8) << 3);
782*d5c9a868SElliott Hughes 
783*d5c9a868SElliott Hughes 	floppy->rate = (floppy->rate & ~0x38) | v;
784*d5c9a868SElliott Hughes }
785*d5c9a868SElliott Hughes 
786*d5c9a868SElliott Hughes #define SET_SSIZE set_ssize
787*d5c9a868SElliott Hughes 
set_parameters(int fd,struct floppy_struct * floppy,struct MT_STAT * buf)788*d5c9a868SElliott Hughes static __inline__ int set_parameters(int fd, struct floppy_struct *floppy,
789*d5c9a868SElliott Hughes 				     struct MT_STAT *buf)
790*d5c9a868SElliott Hughes {
791*d5c9a868SElliott Hughes 	if ( ( MINOR(buf->st_rdev ) & 0x7f ) > 3 )
792*d5c9a868SElliott Hughes 		return 1;
793*d5c9a868SElliott Hughes 
794*d5c9a868SElliott Hughes 	return ioctl(fd, FDSETPRM, floppy);
795*d5c9a868SElliott Hughes }
796*d5c9a868SElliott Hughes 
get_parameters(int fd,struct floppy_struct * floppy)797*d5c9a868SElliott Hughes static __inline__ int get_parameters(int fd, struct floppy_struct *floppy)
798*d5c9a868SElliott Hughes {
799*d5c9a868SElliott Hughes 	return ioctl(fd, FDGETPRM, floppy);
800*d5c9a868SElliott Hughes }
801*d5c9a868SElliott Hughes 
802*d5c9a868SElliott Hughes #include "linux/hdreg.h"
803*d5c9a868SElliott Hughes #include "linux/fs.h"
804*d5c9a868SElliott Hughes 
ulong_to_sectors(unsigned long raw_sect)805*d5c9a868SElliott Hughes static uint32_t ulong_to_sectors(unsigned long raw_sect) {
806*d5c9a868SElliott Hughes 	/* Number of sectors must fit into 32bit value */
807*d5c9a868SElliott Hughes 	if (raw_sect > ULONG_MAX) {
808*d5c9a868SElliott Hughes 		fprintf(stderr, "Too many sectors for FAT %8lx\n",raw_sect);
809*d5c9a868SElliott Hughes 		exit(1);
810*d5c9a868SElliott Hughes 	}
811*d5c9a868SElliott Hughes 	return (uint32_t) raw_sect;
812*d5c9a868SElliott Hughes }
813*d5c9a868SElliott Hughes 
get_sector_size(int fd)814*d5c9a868SElliott Hughes int get_sector_size(int fd) {
815*d5c9a868SElliott Hughes 	int sec_size;
816*d5c9a868SElliott Hughes 	if (ioctl(fd, BLKSSZGET, &sec_size) != 0 || sec_size <= 0) {
817*d5c9a868SElliott Hughes 		fprintf(stderr, "Could not get sector size of device (%s)",
818*d5c9a868SElliott Hughes 			strerror(errno));
819*d5c9a868SElliott Hughes 		return -1;
820*d5c9a868SElliott Hughes 	}
821*d5c9a868SElliott Hughes 
822*d5c9a868SElliott Hughes 	/* Cap sector size at 4096 */
823*d5c9a868SElliott Hughes 	if(sec_size > 4096)
824*d5c9a868SElliott Hughes 		sec_size = 4096;
825*d5c9a868SElliott Hughes 	return sec_size;
826*d5c9a868SElliott Hughes }
827*d5c9a868SElliott Hughes 
get_block_geom(int fd,struct device * dev)828*d5c9a868SElliott Hughes static int get_block_geom(int fd, struct device *dev) {
829*d5c9a868SElliott Hughes 	struct hd_geometry geom;
830*d5c9a868SElliott Hughes 	int sec_size;
831*d5c9a868SElliott Hughes 	unsigned long size;
832*d5c9a868SElliott Hughes 	uint16_t heads=dev->heads;
833*d5c9a868SElliott Hughes 	uint16_t sectors=dev->sectors;
834*d5c9a868SElliott Hughes 	uint32_t sect_per_track;
835*d5c9a868SElliott Hughes 
836*d5c9a868SElliott Hughes 	if (ioctl(fd, HDIO_GETGEO, &geom) < 0) {
837*d5c9a868SElliott Hughes 		fprintf(stderr, "Could not get geometry of device (%s)",
838*d5c9a868SElliott Hughes 			strerror(errno));
839*d5c9a868SElliott Hughes 		return -1;
840*d5c9a868SElliott Hughes 	}
841*d5c9a868SElliott Hughes 
842*d5c9a868SElliott Hughes 	if (ioctl(fd, BLKGETSIZE, &size) < 0) {
843*d5c9a868SElliott Hughes 		fprintf(stderr, "Could not get size of device (%s)",
844*d5c9a868SElliott Hughes 			strerror(errno));
845*d5c9a868SElliott Hughes 		return -1;
846*d5c9a868SElliott Hughes 	}
847*d5c9a868SElliott Hughes 
848*d5c9a868SElliott Hughes 	sec_size = get_sector_size(fd);
849*d5c9a868SElliott Hughes 	if(sec_size < 0)
850*d5c9a868SElliott Hughes 		return -1;
851*d5c9a868SElliott Hughes 
852*d5c9a868SElliott Hughes 	dev->ssize = 0;
853*d5c9a868SElliott Hughes 	while (dev->ssize < 0x7F && (128 << dev->ssize) < sec_size)
854*d5c9a868SElliott Hughes 		dev->ssize++;
855*d5c9a868SElliott Hughes 
856*d5c9a868SElliott Hughes 	if(!heads)
857*d5c9a868SElliott Hughes 		heads = geom.heads;
858*d5c9a868SElliott Hughes 	if(!sectors)
859*d5c9a868SElliott Hughes 		sectors = geom.sectors;
860*d5c9a868SElliott Hughes 
861*d5c9a868SElliott Hughes 	sect_per_track = heads * sectors;
862*d5c9a868SElliott Hughes 	if(!dev->hidden) {
863*d5c9a868SElliott Hughes 		uint32_t hidden;
864*d5c9a868SElliott Hughes 		hidden = geom.start % sect_per_track;
865*d5c9a868SElliott Hughes 		if(hidden && hidden != sectors) {
866*d5c9a868SElliott Hughes 			fprintf(stderr,
867*d5c9a868SElliott Hughes 				"Hidden (%d) does not match sectors (%d)\n",
868*d5c9a868SElliott Hughes 				hidden, sectors);
869*d5c9a868SElliott Hughes 			return -1;
870*d5c9a868SElliott Hughes 		}
871*d5c9a868SElliott Hughes 		dev->hidden = hidden;
872*d5c9a868SElliott Hughes 	}
873*d5c9a868SElliott Hughes 	dev->heads = heads;
874*d5c9a868SElliott Hughes 	dev->sectors = sectors;
875*d5c9a868SElliott Hughes 	if(!dev->tracks)
876*d5c9a868SElliott Hughes 		dev->tracks = ulong_to_sectors((size + dev->hidden % sect_per_track) / sect_per_track);
877*d5c9a868SElliott Hughes 	return 0;
878*d5c9a868SElliott Hughes }
879*d5c9a868SElliott Hughes 
880*d5c9a868SElliott Hughes #define HAVE_GET_BLOCK_GEOM
881*d5c9a868SElliott Hughes 
882*d5c9a868SElliott Hughes #endif /* linux */
883*d5c9a868SElliott Hughes 
884*d5c9a868SElliott Hughes 
885*d5c9a868SElliott Hughes /* OS/2, gcc+emx */
886*d5c9a868SElliott Hughes #ifdef __EMX__
887*d5c9a868SElliott Hughes #define predefined_devices
888*d5c9a868SElliott Hughes struct device devices[] = {
889*d5c9a868SElliott Hughes   {"A:", 'A', GENFD},
890*d5c9a868SElliott Hughes   {"B:", 'B', GENFD},
891*d5c9a868SElliott Hughes };
892*d5c9a868SElliott Hughes #define INIT_NOOP
893*d5c9a868SElliott Hughes #endif
894*d5c9a868SElliott Hughes 
895*d5c9a868SElliott Hughes 
896*d5c9a868SElliott Hughes 
897*d5c9a868SElliott Hughes /*** /jes -- for D.O.S. 486 BL DX2/80 ***/
898*d5c9a868SElliott Hughes /*** Jean-Marc Zucconi <[email protected]> 2001/03/30 ***/
899*d5c9a868SElliott Hughes #ifdef OS_freebsd
900*d5c9a868SElliott Hughes #define predefined_devices
901*d5c9a868SElliott Hughes struct device devices[] = {
902*d5c9a868SElliott Hughes 	{"/dev/fd0.1440", 'A', FHD312},
903*d5c9a868SElliott Hughes 	{"/dev/fd0.720",  'A', FDD312},
904*d5c9a868SElliott Hughes 	{"/dev/fd1.1200", 'B', MHD514},
905*d5c9a868SElliott Hughes 	{"/dev/sd0s1",     'C', GENHD},
906*d5c9a868SElliott Hughes 	REMOTE
907*d5c9a868SElliott Hughes };
908*d5c9a868SElliott Hughes #endif /* __FreeBSD__ */
909*d5c9a868SElliott Hughes 
910*d5c9a868SElliott Hughes /*** /jes -- for ALR 486 DX4/100 ***/
911*d5c9a868SElliott Hughes #if defined(OS_netbsd) || defined(OS_netbsdelf)
912*d5c9a868SElliott Hughes #define predefined_devices
913*d5c9a868SElliott Hughes struct device devices[] = {
914*d5c9a868SElliott Hughes 	{"/dev/rfd0a", 'A', FHD312},
915*d5c9a868SElliott Hughes 	{"/dev/rfd0f", 'A', FDD312},
916*d5c9a868SElliott Hughes 	{"/dev/rfd0f", 'S', MDD312},
917*d5c9a868SElliott Hughes 	{"/dev/rfd1a", 'B', FHD514},
918*d5c9a868SElliott Hughes 	{"/dev/rfd1d", 'B', FDD514},
919*d5c9a868SElliott Hughes 	{"/dev/rfd1d", 'T', MDD514},
920*d5c9a868SElliott Hughes 	{"/dev/rwd0d", 'C', 16, 0, 0, 0, 0, 0, 63L*512L, DEF_ARG0(0)},
921*d5c9a868SElliott Hughes 	REMOTE
922*d5c9a868SElliott Hughes };
923*d5c9a868SElliott Hughes #endif /* OS_NetBSD */
924*d5c9a868SElliott Hughes 
925*d5c9a868SElliott Hughes /* [email protected] 2000/05/19 */
926*d5c9a868SElliott Hughes #if defined(OS_openbsd)
927*d5c9a868SElliott Hughes #define predefined_devices
928*d5c9a868SElliott Hughes struct device devices[] = {
929*d5c9a868SElliott Hughes 	{"/dev/rfd0Bc", 'A', FHD312},
930*d5c9a868SElliott Hughes 	{"/dev/rfd0Fc", 'A', FDD312},
931*d5c9a868SElliott Hughes 	{"/dev/rfd1Cc", 'B', FHD514},
932*d5c9a868SElliott Hughes 	{"/dev/rfd1Dc", 'B', FDD514},
933*d5c9a868SElliott Hughes 	{"/dev/rwd0c", 'C', 16, 0, 0, 0, 0, 0, 63L*512L, DEF_ARG0(0)},
934*d5c9a868SElliott Hughes 	REMOTE
935*d5c9a868SElliott Hughes };
936*d5c9a868SElliott Hughes #endif /* OS_openbsd */
937*d5c9a868SElliott Hughes 
938*d5c9a868SElliott Hughes 
939*d5c9a868SElliott Hughes 
940*d5c9a868SElliott Hughes #if (!defined(predefined_devices) && defined (CPU_m68000) && defined (OS_sysv))
941*d5c9a868SElliott Hughes #include <sys/gdioctl.h>
942*d5c9a868SElliott Hughes 
943*d5c9a868SElliott Hughes #define predefined_devices
944*d5c9a868SElliott Hughes struct device devices[] = {
945*d5c9a868SElliott Hughes 	{"/dev/rfp020",		'A', 12,O_NDELAY,40,2, 9, 0, MDEF_ARG},
946*d5c9a868SElliott Hughes 	{"/usr/bin/DOS/dvd000", 'C', GENFD},
947*d5c9a868SElliott Hughes 	REMOTE
948*d5c9a868SElliott Hughes };
949*d5c9a868SElliott Hughes 
950*d5c9a868SElliott Hughes #undef INIT_NOOP
init_geom(int fd,struct device * dev,struct device * orig_dev,struct MT_STAT * statbuf)951*d5c9a868SElliott Hughes int init_geom(int fd, struct device *dev, struct device *orig_dev,
952*d5c9a868SElliott Hughes 	      struct MT_STAT *statbuf)
953*d5c9a868SElliott Hughes {
954*d5c9a868SElliott Hughes 	struct gdctl gdbuf;
955*d5c9a868SElliott Hughes 
956*d5c9a868SElliott Hughes 	if (ioctl(fd, GDGETA, &gdbuf) == -1) {
957*d5c9a868SElliott Hughes 		ioctl(fd, GDDISMNT, &gdbuf);
958*d5c9a868SElliott Hughes 		return 1;
959*d5c9a868SElliott Hughes 	}
960*d5c9a868SElliott Hughes 	if((dev->use_2m & 0x7f) || (dev->ssize & 0x7f))
961*d5c9a868SElliott Hughes 		return 1;
962*d5c9a868SElliott Hughes 
963*d5c9a868SElliott Hughes 	SET_INT(gdbuf.params.cyls,dev->ntracks);
964*d5c9a868SElliott Hughes 	SET_INT(gdbuf.params.heads,dev->nheads);
965*d5c9a868SElliott Hughes 	SET_INT(gdbuf.params.psectrk,dev->nsect);
966*d5c9a868SElliott Hughes 	dev->ntracks = gdbuf.params.cyls;
967*d5c9a868SElliott Hughes 	dev->nheads = gdbuf.params.heads;
968*d5c9a868SElliott Hughes 	dev->nsect = gdbuf.params.psectrk;
969*d5c9a868SElliott Hughes 	dev->use_2m = 0x80;
970*d5c9a868SElliott Hughes 	dev->ssize = 0x02;
971*d5c9a868SElliott Hughes 
972*d5c9a868SElliott Hughes 	gdbuf.params.pseccyl = gdbuf.params.psectrk * gdbuf.params.heads;
973*d5c9a868SElliott Hughes 	gdbuf.params.flags = 1;		/* disk type flag */
974*d5c9a868SElliott Hughes 	gdbuf.params.step = 0;		/* step rate for controller */
975*d5c9a868SElliott Hughes 	gdbuf.params.sectorsz = 512;	/* sector size */
976*d5c9a868SElliott Hughes 
977*d5c9a868SElliott Hughes 	if (ioctl(fd, GDSETA, &gdbuf) < 0) {
978*d5c9a868SElliott Hughes 		ioctl(fd, GDDISMNT, &gdbuf);
979*d5c9a868SElliott Hughes 		return(1);
980*d5c9a868SElliott Hughes 	}
981*d5c9a868SElliott Hughes 	return(0);
982*d5c9a868SElliott Hughes }
983*d5c9a868SElliott Hughes #endif /* (defined (m68000) && defined (sysv))*/
984*d5c9a868SElliott Hughes 
985*d5c9a868SElliott Hughes #ifdef CPU_alpha
986*d5c9a868SElliott Hughes #ifndef OS_osf4
987*d5c9a868SElliott Hughes #ifdef __osf__
988*d5c9a868SElliott Hughes #include <sys/fcntl.h>
989*d5c9a868SElliott Hughes #define predefined_devices
990*d5c9a868SElliott Hughes struct device devices[] = {
991*d5c9a868SElliott Hughes 	{"/dev/rfd0c",		'A', GENFD},
992*d5c9a868SElliott Hughes 	REMOTE
993*d5c9a868SElliott Hughes };
994*d5c9a868SElliott Hughes #endif
995*d5c9a868SElliott Hughes #endif
996*d5c9a868SElliott Hughes #endif
997*d5c9a868SElliott Hughes 
998*d5c9a868SElliott Hughes #ifdef OS_osf
999*d5c9a868SElliott Hughes #ifndef predefined_devices
1000*d5c9a868SElliott Hughes #define predefined_devices
1001*d5c9a868SElliott Hughes struct device devices[] = {
1002*d5c9a868SElliott Hughes 	{"/dev/fd0a", 'A',  MHD312 } };
1003*d5c9a868SElliott Hughes 	REMOTE
1004*d5c9a868SElliott Hughes #endif
1005*d5c9a868SElliott Hughes #endif
1006*d5c9a868SElliott Hughes 
1007*d5c9a868SElliott Hughes 
1008*d5c9a868SElliott Hughes #ifdef OS_nextstep
1009*d5c9a868SElliott Hughes #define predefined_devices
1010*d5c9a868SElliott Hughes struct device devices[] = {
1011*d5c9a868SElliott Hughes #ifdef CPU_m68k
1012*d5c9a868SElliott Hughes 	{"/dev/rfd0b", 'A', MED312 },
1013*d5c9a868SElliott Hughes 	REMOTE
1014*d5c9a868SElliott Hughes #else
1015*d5c9a868SElliott Hughes 	{"/dev/rfd0b", 'A', MHD312 },
1016*d5c9a868SElliott Hughes 	REMOTE
1017*d5c9a868SElliott Hughes #endif
1018*d5c9a868SElliott Hughes };
1019*d5c9a868SElliott Hughes #endif
1020*d5c9a868SElliott Hughes 
1021*d5c9a868SElliott Hughes 
1022*d5c9a868SElliott Hughes #if (!defined(predefined_devices) && defined(OS_sysv4))
1023*d5c9a868SElliott Hughes #ifdef __uxp__
1024*d5c9a868SElliott Hughes #define predefined_devices
1025*d5c9a868SElliott Hughes struct device devices[] = {
1026*d5c9a868SElliott Hughes       {"/dev/fpd0",   'A', FHD312},
1027*d5c9a868SElliott Hughes       {"/dev/fpd0",   'A', FDD312},
1028*d5c9a868SElliott Hughes 	  REMOTE
1029*d5c9a868SElliott Hughes };
1030*d5c9a868SElliott Hughes #else
1031*d5c9a868SElliott Hughes #define predefined_devices
1032*d5c9a868SElliott Hughes struct device devices[] = {
1033*d5c9a868SElliott Hughes 	{"/dev/rdsk/f1q15dt",	'B', FHD514},
1034*d5c9a868SElliott Hughes 	{"/dev/rdsk/f1d9dt",	'B', FDD514},
1035*d5c9a868SElliott Hughes 	{"/dev/rdsk/f1d8dt",	'B', FDDsmall},
1036*d5c9a868SElliott Hughes 	{"/dev/rdsk/f03ht",	'A', FHD312},
1037*d5c9a868SElliott Hughes 	{"/dev/rdsk/f03dt",	'A', FDD312},
1038*d5c9a868SElliott Hughes 	{"/dev/rdsk/dos",	'C', GENHD},
1039*d5c9a868SElliott Hughes 	REMOTE
1040*d5c9a868SElliott Hughes };
1041*d5c9a868SElliott Hughes #endif
1042*d5c9a868SElliott Hughes #endif /* sysv4 */
1043*d5c9a868SElliott Hughes 
1044*d5c9a868SElliott Hughes #ifdef OS_mingw32msvc
1045*d5c9a868SElliott Hughes #define predefined_devices
1046*d5c9a868SElliott Hughes struct device devices[] = {
1047*d5c9a868SElliott Hughes    {"\\\\.\\A:", 'A', GENFD },
1048*d5c9a868SElliott Hughes };
1049*d5c9a868SElliott Hughes #endif
1050*d5c9a868SElliott Hughes 
1051*d5c9a868SElliott Hughes #ifdef INIT_GENERIC
1052*d5c9a868SElliott Hughes 
1053*d5c9a868SElliott Hughes #ifndef USE_2M
1054*d5c9a868SElliott Hughes #define USE_2M(x) 0x80
1055*d5c9a868SElliott Hughes #endif
1056*d5c9a868SElliott Hughes 
1057*d5c9a868SElliott Hughes #ifndef SSIZE
1058*d5c9a868SElliott Hughes #define SSIZE(x) 0x02
1059*d5c9a868SElliott Hughes #endif
1060*d5c9a868SElliott Hughes 
1061*d5c9a868SElliott Hughes #ifndef SET_2M
1062*d5c9a868SElliott Hughes #define SET_2M(x,y) return -1
1063*d5c9a868SElliott Hughes #endif
1064*d5c9a868SElliott Hughes 
1065*d5c9a868SElliott Hughes #ifndef SET_SSIZE
1066*d5c9a868SElliott Hughes #define SET_SSIZE(x,y) return -1
1067*d5c9a868SElliott Hughes #endif
1068*d5c9a868SElliott Hughes 
1069*d5c9a868SElliott Hughes #undef INIT_NOOP
init_geom(int fd,struct device * dev,struct device * orig_dev,struct MT_STAT * statbuf)1070*d5c9a868SElliott Hughes int init_geom(int fd, struct device *dev, struct device *orig_dev,
1071*d5c9a868SElliott Hughes 	      struct MT_STAT *statbuf)
1072*d5c9a868SElliott Hughes {
1073*d5c9a868SElliott Hughes 	struct generic_floppy_struct floppy;
1074*d5c9a868SElliott Hughes 	int change;
1075*d5c9a868SElliott Hughes 
1076*d5c9a868SElliott Hughes #ifdef HAVE_GET_BLOCK_GEOM
1077*d5c9a868SElliott Hughes 	/**
1078*d5c9a868SElliott Hughes 	 * Block device which *isn't* a floppy device
1079*d5c9a868SElliott Hughes 	 */
1080*d5c9a868SElliott Hughes 	if (S_ISBLK(statbuf->st_mode) &&
1081*d5c9a868SElliott Hughes 	    major(statbuf->st_rdev) != BLOCK_MAJOR) {
1082*d5c9a868SElliott Hughes 		get_block_geom(fd, dev);
1083*d5c9a868SElliott Hughes 		return compare_geom(dev, orig_dev);
1084*d5c9a868SElliott Hughes 	}
1085*d5c9a868SElliott Hughes #endif
1086*d5c9a868SElliott Hughes 
1087*d5c9a868SElliott Hughes 	/*
1088*d5c9a868SElliott Hughes 	 * succeed if we don't have a floppy
1089*d5c9a868SElliott Hughes 	 * this is the case for dosemu floppy image files for instance
1090*d5c9a868SElliott Hughes 	 */
1091*d5c9a868SElliott Hughes 	if (!((S_ISBLK(statbuf->st_mode) &&
1092*d5c9a868SElliott Hughes 	       major(statbuf->st_rdev) == BLOCK_MAJOR)
1093*d5c9a868SElliott Hughes #ifdef CHAR_MAJOR
1094*d5c9a868SElliott Hughes 	      || (S_ISCHR(statbuf->st_mode) &&
1095*d5c9a868SElliott Hughes 		  major(statbuf->st_rdev) == CHAR_MAJOR)
1096*d5c9a868SElliott Hughes #endif
1097*d5c9a868SElliott Hughes 		))
1098*d5c9a868SElliott Hughes 		return compare_geom(dev, orig_dev);
1099*d5c9a868SElliott Hughes 
1100*d5c9a868SElliott Hughes 	/*
1101*d5c9a868SElliott Hughes 	 * We first try to get the current floppy parameters from the kernel.
1102*d5c9a868SElliott Hughes 	 * This allows us to
1103*d5c9a868SElliott Hughes 	 * 1. get the rate
1104*d5c9a868SElliott Hughes 	 * 2. skip the parameter setting if the parameters are already o.k.
1105*d5c9a868SElliott Hughes 	 */
1106*d5c9a868SElliott Hughes 
1107*d5c9a868SElliott Hughes 	if (get_parameters( fd, & floppy ) )
1108*d5c9a868SElliott Hughes 		/*
1109*d5c9a868SElliott Hughes 		 * autodetection failure.
1110*d5c9a868SElliott Hughes 		 * This mostly occurs because of an absent or unformatted disks.
1111*d5c9a868SElliott Hughes 		 *
1112*d5c9a868SElliott Hughes 		 * It might also occur because of bizarre formats (for example
1113*d5c9a868SElliott Hughes 		 * rate 1 on a 3 1/2 disk).
1114*d5c9a868SElliott Hughes 
1115*d5c9a868SElliott Hughes 		 * If this is the case, the user should do an explicit
1116*d5c9a868SElliott Hughes 		 * setfdprm before calling mtools
1117*d5c9a868SElliott Hughes 		 *
1118*d5c9a868SElliott Hughes 		 * Another cause might be pre-existing wrong parameters. The
1119*d5c9a868SElliott Hughes 		 * user should do an setfdprm -c to repair this situation.
1120*d5c9a868SElliott Hughes 		 *
1121*d5c9a868SElliott Hughes 		 * ...fail immediately... ( Theoretically, we could try to save
1122*d5c9a868SElliott Hughes 		 * the situation by trying out all rates, but it would be slow
1123*d5c9a868SElliott Hughes 		 * and awkward)
1124*d5c9a868SElliott Hughes 		 */
1125*d5c9a868SElliott Hughes 		return 1;
1126*d5c9a868SElliott Hughes 
1127*d5c9a868SElliott Hughes 
1128*d5c9a868SElliott Hughes 	/*
1129*d5c9a868SElliott Hughes 	 * if we have already have the correct parameters, keep them.
1130*d5c9a868SElliott Hughes 	 * the number of tracks doesn't need to match exactly, it may be bigger.
1131*d5c9a868SElliott Hughes 	 * the number of heads and sectors must match exactly, to avoid
1132*d5c9a868SElliott Hughes 	 * miscalculation of the location of a block on the disk
1133*d5c9a868SElliott Hughes 	 */
1134*d5c9a868SElliott Hughes 	change = 0;
1135*d5c9a868SElliott Hughes 	if(compare(dev->sectors, SECTORS(floppy))){
1136*d5c9a868SElliott Hughes 		SECTORS(floppy) = dev->sectors;
1137*d5c9a868SElliott Hughes 		change = 1;
1138*d5c9a868SElliott Hughes 	} else
1139*d5c9a868SElliott Hughes 		dev->sectors = (uint16_t) SECTORS(floppy);
1140*d5c9a868SElliott Hughes 
1141*d5c9a868SElliott Hughes 	if(compare(dev->heads, HEADS(floppy))){
1142*d5c9a868SElliott Hughes 		HEADS(floppy) = dev->heads;
1143*d5c9a868SElliott Hughes 		change = 1;
1144*d5c9a868SElliott Hughes 	} else
1145*d5c9a868SElliott Hughes 		dev->heads = (uint16_t) HEADS(floppy);
1146*d5c9a868SElliott Hughes 
1147*d5c9a868SElliott Hughes 	if(compare(dev->tracks, (unsigned int) TRACKS(floppy))){
1148*d5c9a868SElliott Hughes 		TRACKS(floppy) = dev->tracks;
1149*d5c9a868SElliott Hughes 		change = 1;
1150*d5c9a868SElliott Hughes 	} else
1151*d5c9a868SElliott Hughes 		dev->tracks = TRACKS(floppy);
1152*d5c9a868SElliott Hughes 
1153*d5c9a868SElliott Hughes 
1154*d5c9a868SElliott Hughes 	if(compare(dev->use_2m, USE_2M(floppy))){
1155*d5c9a868SElliott Hughes 		SET_2M(&floppy, dev->use_2m);
1156*d5c9a868SElliott Hughes 		change = 1;
1157*d5c9a868SElliott Hughes 	} else
1158*d5c9a868SElliott Hughes 		dev->use_2m = USE_2M(floppy);
1159*d5c9a868SElliott Hughes 
1160*d5c9a868SElliott Hughes 	if( ! (dev->ssize & 0x80) )
1161*d5c9a868SElliott Hughes 		dev->ssize = 0;
1162*d5c9a868SElliott Hughes 	if(compare(dev->ssize, SSIZE(floppy) + 128)){
1163*d5c9a868SElliott Hughes 		SET_SSIZE(&floppy, dev->ssize);
1164*d5c9a868SElliott Hughes 		change = 1;
1165*d5c9a868SElliott Hughes 	} else
1166*d5c9a868SElliott Hughes 		dev->ssize = SSIZE(floppy);
1167*d5c9a868SElliott Hughes 
1168*d5c9a868SElliott Hughes 	if(!change)
1169*d5c9a868SElliott Hughes 		/* no change, succeed */
1170*d5c9a868SElliott Hughes 		return 0;
1171*d5c9a868SElliott Hughes 
1172*d5c9a868SElliott Hughes #ifdef SECTORS_PER_TRACK
1173*d5c9a868SElliott Hughes 	SECTORS_PER_TRACK(floppy) = dev->sectors * dev->heads;
1174*d5c9a868SElliott Hughes #endif
1175*d5c9a868SElliott Hughes 
1176*d5c9a868SElliott Hughes #ifdef SECTORS_PER_DISK
1177*d5c9a868SElliott Hughes 	SECTORS_PER_DISK(floppy) = dev->sectors * dev->heads * dev->tracks;
1178*d5c9a868SElliott Hughes #endif
1179*d5c9a868SElliott Hughes 
1180*d5c9a868SElliott Hughes #ifdef STRETCH
1181*d5c9a868SElliott Hughes 	/* ... and the stretch */
1182*d5c9a868SElliott Hughes 	if ( dev->tracks > 41 )
1183*d5c9a868SElliott Hughes 		STRETCH(floppy) = 0;
1184*d5c9a868SElliott Hughes 	else
1185*d5c9a868SElliott Hughes 		STRETCH(floppy) = 1;
1186*d5c9a868SElliott Hughes #endif
1187*d5c9a868SElliott Hughes 
1188*d5c9a868SElliott Hughes 	return set_parameters( fd, &floppy, statbuf);
1189*d5c9a868SElliott Hughes }
1190*d5c9a868SElliott Hughes #endif /* INIT_GENERIC */
1191*d5c9a868SElliott Hughes 
1192*d5c9a868SElliott Hughes #ifdef INIT_NOOP
init_geom(int fd,struct device * dev,struct device * orig_dev,struct MT_STAT * statbuf)1193*d5c9a868SElliott Hughes int init_geom(int fd, struct device *dev, struct device *orig_dev,
1194*d5c9a868SElliott Hughes 			  struct MT_STAT *statbuf)
1195*d5c9a868SElliott Hughes {
1196*d5c9a868SElliott Hughes 	return compare_geom(dev, orig_dev);
1197*d5c9a868SElliott Hughes }
1198*d5c9a868SElliott Hughes #endif
1199*d5c9a868SElliott Hughes 
1200*d5c9a868SElliott Hughes #ifdef predefined_devices
1201*d5c9a868SElliott Hughes const unsigned int nr_const_devices = sizeof(const_devices) / sizeof(*const_devices);
1202*d5c9a868SElliott Hughes #else
1203*d5c9a868SElliott Hughes struct device devices[]={
1204*d5c9a868SElliott Hughes 	{"/dev/fd0", 'A', 0, O_EXCL, 0,0, 0,0, MDEF_ARG},
1205*d5c9a868SElliott Hughes 	/* to shut up Ultrix's native compiler, we can't make this empty :( */
1206*d5c9a868SElliott Hughes };
1207*d5c9a868SElliott Hughes const unsigned int nr_const_devices = 0;
1208*d5c9a868SElliott Hughes #endif
1209