File: /usr/src/linux/drivers/block/ataflop.c

1     /*
2      *  drivers/block/ataflop.c
3      *
4      *  Copyright (C) 1993  Greg Harp
5      *  Atari Support by Bjoern Brauel, Roman Hodek
6      *
7      *  Big cleanup Sep 11..14 1994 Roman Hodek:
8      *   - Driver now works interrupt driven
9      *   - Support for two drives; should work, but I cannot test that :-(
10      *   - Reading is done in whole tracks and buffered to speed up things
11      *   - Disk change detection and drive deselecting after motor-off
12      *     similar to TOS
13      *   - Autodetection of disk format (DD/HD); untested yet, because I
14      *     don't have an HD drive :-(
15      *
16      *  Fixes Nov 13 1994 Martin Schaller:
17      *   - Autodetection works now
18      *   - Support for 5 1/4'' disks
19      *   - Removed drive type (unknown on atari)
20      *   - Do seeks with 8 Mhz
21      *
22      *  Changes by Andreas Schwab:
23      *   - After errors in multiple read mode try again reading single sectors
24      *  (Feb 1995):
25      *   - Clean up error handling
26      *   - Set blk_size for proper size checking
27      *   - Initialize track register when testing presence of floppy
28      *   - Implement some ioctl's
29      *
30      *  Changes by Torsten Lang:
31      *   - When probing the floppies we should add the FDCCMDADD_H flag since
32      *     the FDC will otherwise wait forever when no disk is inserted...
33      *
34      * ++ Freddi Aschwanden (fa) 20.9.95 fixes for medusa:
35      *  - MFPDELAY() after each FDC access -> atari 
36      *  - more/other disk formats
37      *  - DMA to the block buffer directly if we have a 32bit DMA
38      *  - for medusa, the step rate is always 3ms
39      *  - on medusa, use only cache_push()
40      * Roman:
41      *  - Make disk format numbering independent from minors
42      *  - Let user set max. supported drive type (speeds up format
43      *    detection, saves buffer space)
44      *
45      * Roman 10/15/95:
46      *  - implement some more ioctls
47      *  - disk formatting
48      *  
49      * Andreas 95/12/12:
50      *  - increase gap size at start of track for HD/ED disks
51      *
52      * Michael (MSch) 11/07/96:
53      *  - implemented FDSETPRM and FDDEFPRM ioctl
54      *
55      * Andreas (97/03/19):
56      *  - implemented missing BLK* ioctls
57      *
58      *  Things left to do:
59      *   - Formatting
60      *   - Maybe a better strategy for disk change detection (does anyone
61      *     know one?)
62      */
63     
64     #include <linux/module.h>
65     
66     #include <linux/sched.h>
67     #include <linux/string.h>
68     #include <linux/fs.h>
69     #include <linux/fcntl.h>
70     #include <linux/kernel.h>
71     #include <linux/timer.h>
72     #include <linux/fd.h>
73     #include <linux/errno.h>
74     #include <linux/types.h>
75     #include <linux/delay.h>
76     #include <linux/mm.h>
77     #include <linux/slab.h>
78     #include <linux/init.h>
79     
80     #include <asm/setup.h>
81     #include <asm/system.h>
82     #include <asm/bitops.h>
83     #include <asm/irq.h>
84     #include <asm/pgtable.h>
85     #include <asm/uaccess.h>
86     
87     #include <asm/atafd.h>
88     #include <asm/atafdreg.h>
89     #include <asm/atarihw.h>
90     #include <asm/atariints.h>
91     #include <asm/atari_stdma.h>
92     #include <asm/atari_stram.h>
93     
94     #define MAJOR_NR FLOPPY_MAJOR
95     #include <linux/blk.h>
96     #include <linux/blkpg.h>
97     
98     #define	FD_MAX_UNITS 2
99     
100     #undef DEBUG
101     
102     /* Disk types: DD, HD, ED */
103     static struct atari_disk_type {
104     	const char	*name;
105     	unsigned	spt;		/* sectors per track */
106     	unsigned	blocks;		/* total number of blocks */
107     	unsigned	fdc_speed;	/* fdc_speed setting */
108     	unsigned 	stretch;	/* track doubling ? */
109     } disk_type[] = {
110     	{ "d360",  9, 720, 0, 0},	/*  0: 360kB diskette */
111     	{ "D360",  9, 720, 0, 1},	/*  1: 360kb in 720k or 1.2MB drive */
112     	{ "D720",  9,1440, 0, 0},	/*  2: 720kb in 720k or 1.2MB drive */
113     	{ "D820", 10,1640, 0, 0},	/*  3: DD disk with 82 tracks/10 sectors */
114     /* formats above are probed for type DD */
115     #define	MAX_TYPE_DD 3
116     	{ "h1200",15,2400, 3, 0},	/*  4: 1.2MB diskette */
117     	{ "H1440",18,2880, 3, 0},	/*  5: 1.4 MB diskette (HD) */
118     	{ "H1640",20,3280, 3, 0},	/*  6: 1.64MB diskette (fat HD) 82 tr 20 sec */
119     /* formats above are probed for types DD and HD */
120     #define	MAX_TYPE_HD 6
121     	{ "E2880",36,5760, 3, 0},	/*  7: 2.8 MB diskette (ED) */
122     	{ "E3280",40,6560, 3, 0},	/*  8: 3.2 MB diskette (fat ED) 82 tr 40 sec */
123     /* formats above are probed for types DD, HD and ED */
124     #define	MAX_TYPE_ED 8
125     /* types below are never autoprobed */
126     	{ "H1680",21,3360, 3, 0},	/*  9: 1.68MB diskette (fat HD) 80 tr 21 sec */
127     	{ "h410",10,820, 0, 1},		/* 10: 410k diskette 41 tr 10 sec, stretch */
128     	{ "h1476",18,2952, 3, 0},	/* 11: 1.48MB diskette 82 tr 18 sec */
129     	{ "H1722",21,3444, 3, 0},	/* 12: 1.72MB diskette 82 tr 21 sec */
130     	{ "h420",10,840, 0, 1},		/* 13: 420k diskette 42 tr 10 sec, stretch */
131     	{ "H830",10,1660, 0, 0},	/* 14: 820k diskette 83 tr 10 sec */
132     	{ "h1494",18,2952, 3, 0},	/* 15: 1.49MB diskette 83 tr 18 sec */
133     	{ "H1743",21,3486, 3, 0},	/* 16: 1.74MB diskette 83 tr 21 sec */
134     	{ "h880",11,1760, 0, 0},	/* 17: 880k diskette 80 tr 11 sec */
135     	{ "D1040",13,2080, 0, 0},	/* 18: 1.04MB diskette 80 tr 13 sec */
136     	{ "D1120",14,2240, 0, 0},	/* 19: 1.12MB diskette 80 tr 14 sec */
137     	{ "h1600",20,3200, 3, 0},	/* 20: 1.60MB diskette 80 tr 20 sec */
138     	{ "H1760",22,3520, 3, 0},	/* 21: 1.76MB diskette 80 tr 22 sec */
139     	{ "H1920",24,3840, 3, 0},	/* 22: 1.92MB diskette 80 tr 24 sec */
140     	{ "E3200",40,6400, 3, 0},	/* 23: 3.2MB diskette 80 tr 40 sec */
141     	{ "E3520",44,7040, 3, 0},	/* 24: 3.52MB diskette 80 tr 44 sec */
142     	{ "E3840",48,7680, 3, 0},	/* 25: 3.84MB diskette 80 tr 48 sec */
143     	{ "H1840",23,3680, 3, 0},	/* 26: 1.84MB diskette 80 tr 23 sec */
144     	{ "D800",10,1600, 0, 0},	/* 27: 800k diskette 80 tr 10 sec */
145     };
146     
147     static int StartDiskType[] = {
148     	MAX_TYPE_DD,
149     	MAX_TYPE_HD,
150     	MAX_TYPE_ED
151     };
152     
153     #define	TYPE_DD		0
154     #define	TYPE_HD		1
155     #define	TYPE_ED		2
156     
157     static int DriveType = TYPE_HD;
158     
159     /* Array for translating minors into disk formats */
160     static struct {
161     	int 	 index;
162     	unsigned drive_types;
163     } minor2disktype[] = {
164     	{  0, TYPE_DD },	/*  1: d360 */
165     	{  4, TYPE_HD },	/*  2: h1200 */
166     	{  1, TYPE_DD },	/*  3: D360 */
167     	{  2, TYPE_DD },	/*  4: D720 */
168     	{  1, TYPE_DD },	/*  5: h360 = D360 */
169     	{  2, TYPE_DD },	/*  6: h720 = D720 */
170     	{  5, TYPE_HD },	/*  7: H1440 */
171     	{  7, TYPE_ED },	/*  8: E2880 */
172     /* some PC formats :-) */
173     	{  8, TYPE_ED },	/*  9: E3280    <- was "CompaQ" == E2880 for PC */
174     	{  5, TYPE_HD },	/* 10: h1440 = H1440 */
175     	{  9, TYPE_HD },	/* 11: H1680 */
176     	{ 10, TYPE_DD },	/* 12: h410  */
177     	{  3, TYPE_DD },	/* 13: H820     <- == D820, 82x10 */
178     	{ 11, TYPE_HD },	/* 14: h1476 */
179     	{ 12, TYPE_HD },	/* 15: H1722 */
180     	{ 13, TYPE_DD },	/* 16: h420  */
181     	{ 14, TYPE_DD },	/* 17: H830  */
182     	{ 15, TYPE_HD },	/* 18: h1494 */
183     	{ 16, TYPE_HD },	/* 19: H1743 */
184     	{ 17, TYPE_DD },	/* 20: h880  */
185     	{ 18, TYPE_DD },	/* 21: D1040 */
186     	{ 19, TYPE_DD },	/* 22: D1120 */
187     	{ 20, TYPE_HD },	/* 23: h1600 */
188     	{ 21, TYPE_HD },	/* 24: H1760 */
189     	{ 22, TYPE_HD },	/* 25: H1920 */
190     	{ 23, TYPE_ED },	/* 26: E3200 */
191     	{ 24, TYPE_ED },	/* 27: E3520 */
192     	{ 25, TYPE_ED },	/* 28: E3840 */
193     	{ 26, TYPE_HD },	/* 29: H1840 */
194     	{ 27, TYPE_DD },	/* 30: D800  */
195     	{  6, TYPE_HD },	/* 31: H1640    <- was H1600 == h1600 for PC */
196     };
197     
198     #define NUM_DISK_MINORS (sizeof(minor2disktype)/sizeof(*minor2disktype))
199     
200     /*
201      * Maximum disk size (in kilobytes). This default is used whenever the
202      * current disk size is unknown.
203      */
204     #define MAX_DISK_SIZE 3280
205     
206     /*
207      * MSch: User-provided type information. 'drive' points to
208      * the respective entry of this array. Set by FDSETPRM ioctls.
209      */
210     static struct atari_disk_type user_params[FD_MAX_UNITS];
211     
212     /*
213      * User-provided permanent type information. 'drive' points to
214      * the respective entry of this array.  Set by FDDEFPRM ioctls, 
215      * restored upon disk change by floppy_revalidate() if valid (as seen by
216      * default_params[].blocks > 0 - a bit in unit[].flags might be used for this?)
217      */
218     static struct atari_disk_type default_params[FD_MAX_UNITS];
219     
220     static int floppy_sizes[256];
221     static int floppy_blocksizes[256];
222     
223     /* current info on each unit */
224     static struct atari_floppy_struct {
225     	int connected;				/* !=0 : drive is connected */
226     	int autoprobe;				/* !=0 : do autoprobe	    */
227     
228     	struct atari_disk_type	*disktype;	/* current type of disk */
229     
230     	int track;		/* current head position or -1 if
231     				   unknown */
232     	unsigned int steprate;	/* steprate setting */
233     	unsigned int wpstat;	/* current state of WP signal (for
234     				   disk change detection) */
235     	int flags;		/* flags */
236     } unit[FD_MAX_UNITS];
237     
238     #define	UD	unit[drive]
239     #define	UDT	unit[drive].disktype
240     #define	SUD	unit[SelectedDrive]
241     #define	SUDT	unit[SelectedDrive].disktype
242     
243     
244     #define FDC_READ(reg) ({			\
245         /* unsigned long __flags; */		\
246         unsigned short __val;			\
247         /* save_flags(__flags); cli(); */		\
248         dma_wd.dma_mode_status = 0x80 | (reg);	\
249         udelay(25);					\
250         __val = dma_wd.fdc_acces_seccount;		\
251         MFPDELAY();					\
252         /* restore_flags(__flags); */		\
253         __val & 0xff;				\
254     })
255     
256     #define FDC_WRITE(reg,val)			\
257         do {					\
258     	/* unsigned long __flags; */		\
259     	/* save_flags(__flags); cli(); */	\
260     	dma_wd.dma_mode_status = 0x80 | (reg);	\
261     	udelay(25);				\
262     	dma_wd.fdc_acces_seccount = (val);	\
263     	MFPDELAY();				\
264             /* restore_flags(__flags); */		\
265         } while(0)
266     
267     
268     /* Buffering variables:
269      * First, there is a DMA buffer in ST-RAM that is used for floppy DMA
270      * operations. Second, a track buffer is used to cache a whole track
271      * of the disk to save read operations. These are two separate buffers
272      * because that allows write operations without clearing the track buffer.
273      */
274     
275     static int MaxSectors[] = {
276     	11, 22, 44
277     };
278     static int BufferSize[] = {
279     	15*512, 30*512, 60*512
280     };
281     
282     #define	BUFFER_SIZE	(BufferSize[DriveType])
283     
284     unsigned char *DMABuffer;			  /* buffer for writes */
285     static unsigned long PhysDMABuffer;   /* physical address */
286     
287     static int UseTrackbuffer = -1;		  /* Do track buffering? */
288     MODULE_PARM(UseTrackbuffer, "i");
289     
290     unsigned char *TrackBuffer;			  /* buffer for reads */
291     static unsigned long PhysTrackBuffer; /* physical address */
292     static int BufferDrive, BufferSide, BufferTrack;
293     static int read_track;		/* non-zero if we are reading whole tracks */
294     
295     #define	SECTOR_BUFFER(sec)	(TrackBuffer + ((sec)-1)*512)
296     #define	IS_BUFFERED(drive,side,track) \
297         (BufferDrive == (drive) && BufferSide == (side) && BufferTrack == (track))
298     
299     /*
300      * These are global variables, as that's the easiest way to give
301      * information to interrupts. They are the data used for the current
302      * request.
303      */
304     static int SelectedDrive = 0;
305     static int ReqCmd, ReqBlock;
306     static int ReqSide, ReqTrack, ReqSector, ReqCnt;
307     static int HeadSettleFlag = 0;
308     static unsigned char *ReqData, *ReqBuffer;
309     static int MotorOn = 0, MotorOffTrys;
310     static int IsFormatting = 0, FormatError;
311     
312     static int UserSteprate[FD_MAX_UNITS] = { -1, -1 };
313     MODULE_PARM(UserSteprate, "1-" __MODULE_STRING(FD_MAX_UNITS) "i");
314     
315     /* Synchronization of FDC access. */
316     static volatile int fdc_busy = 0;
317     static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
318     static DECLARE_WAIT_QUEUE_HEAD(format_wait);
319     
320     static unsigned long changed_floppies = 0xff, fake_change = 0;
321     #define	CHECK_CHANGE_DELAY	HZ/2
322     
323     #define	FD_MOTOR_OFF_DELAY	(3*HZ)
324     #define	FD_MOTOR_OFF_MAXTRY	(10*20)
325     
326     #define FLOPPY_TIMEOUT		(6*HZ)
327     #define RECALIBRATE_ERRORS	4	/* After this many errors the drive
328     					 * will be recalibrated. */
329     #define MAX_ERRORS		8	/* After this many errors the driver
330     					 * will give up. */
331     
332     
333     /*
334      * The driver is trying to determine the correct media format
335      * while Probing is set. fd_rwsec_done() clears it after a
336      * successful access.
337      */
338     static int Probing = 0;
339     
340     /* This flag is set when a dummy seek is necessary to make the WP
341      * status bit accessible.
342      */
343     static int NeedSeek = 0;
344     
345     
346     #ifdef DEBUG
347     #define DPRINT(a)	printk a
348     #else
349     #define DPRINT(a)
350     #endif
351     
352     /***************************** Prototypes *****************************/
353     
354     static void fd_select_side( int side );
355     static void fd_select_drive( int drive );
356     static void fd_deselect( void );
357     static void fd_motor_off_timer( unsigned long dummy );
358     static void check_change( void );
359     static __inline__ void set_head_settle_flag( void );
360     static __inline__ int get_head_settle_flag( void );
361     static void floppy_irq (int irq, void *dummy, struct pt_regs *fp);
362     static void fd_error( void );
363     static int do_format(kdev_t drive, struct atari_format_descr *desc);
364     static void do_fd_action( int drive );
365     static void fd_calibrate( void );
366     static void fd_calibrate_done( int status );
367     static void fd_seek( void );
368     static void fd_seek_done( int status );
369     static void fd_rwsec( void );
370     static void fd_readtrack_check( unsigned long dummy );
371     static void fd_rwsec_done( int status );
372     static void fd_rwsec_done1(int status);
373     static void fd_writetrack( void );
374     static void fd_writetrack_done( int status );
375     static void fd_times_out( unsigned long dummy );
376     static void finish_fdc( void );
377     static void finish_fdc_done( int dummy );
378     static void floppy_off( unsigned int nr);
379     static __inline__ void copy_buffer( void *from, void *to);
380     static void setup_req_params( int drive );
381     static void redo_fd_request( void);
382     static int invalidate_drive(kdev_t rdev);
383     static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int
384                          cmd, unsigned long param);
385     static void fd_probe( int drive );
386     static int fd_test_drive_present( int drive );
387     static void config_types( void );
388     static int floppy_open( struct inode *inode, struct file *filp );
389     static int floppy_release( struct inode * inode, struct file * filp );
390     
391     /************************* End of Prototypes **************************/
392     
393     static struct timer_list motor_off_timer =
394     	{ function: fd_motor_off_timer };
395     static struct timer_list readtrack_timer =
396     	{ function: fd_readtrack_check };
397     
398     static struct timer_list timeout_timer =
399     	{ function: fd_times_out };
400     
401     static struct timer_list fd_timer =
402     	{ function: check_change };
403     	
404     static inline void
405     start_motor_off_timer(void)
406     {
407     	mod_timer(&motor_off_timer, jiffies + FD_MOTOR_OFF_DELAY);
408     	MotorOffTrys = 0;
409     }
410     
411     static inline void
412     start_check_change_timer( void )
413     {
414     	mod_timer(&fd_timer, jiffies + CHECK_CHANGE_DELAY);
415     }
416     
417     static inline void
418     start_timeout(void)
419     {
420     	mod_timer(&timeout_timer, jiffies + FLOPPY_TIMEOUT);
421     }
422     
423     static inline void
424     stop_timeout(void)
425     {
426     	del_timer(&timeout_timer);
427     }
428     
429     /* Select the side to use. */
430     
431     static void fd_select_side( int side )
432     {
433     	unsigned long flags;
434     
435     	save_flags(flags);
436     	cli(); /* protect against various other ints mucking around with the PSG */
437       
438     	sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */
439     	sound_ym.wd_data = (side == 0) ? sound_ym.rd_data_reg_sel | 0x01 :
440     	                                 sound_ym.rd_data_reg_sel & 0xfe;
441     
442     	restore_flags(flags);
443     }
444     
445     
446     /* Select a drive, update the FDC's track register and set the correct
447      * clock speed for this disk's type.
448      */
449     
450     static void fd_select_drive( int drive )
451     {
452     	unsigned long flags;
453     	unsigned char tmp;
454       
455     	if (drive == SelectedDrive)
456     	  return;
457     
458     	save_flags(flags);
459     	cli(); /* protect against various other ints mucking around with the PSG */
460     	sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */
461     	tmp = sound_ym.rd_data_reg_sel;
462     	sound_ym.wd_data = (tmp | DSKDRVNONE) & ~(drive == 0 ? DSKDRV0 : DSKDRV1);
463     	atari_dont_touch_floppy_select = 1;
464     	restore_flags(flags);
465     
466     	/* restore track register to saved value */
467     	FDC_WRITE( FDCREG_TRACK, UD.track );
468     	udelay(25);
469     
470     	/* select 8/16 MHz */
471     	if (UDT)
472     		if (ATARIHW_PRESENT(FDCSPEED))
473     			dma_wd.fdc_speed = UDT->fdc_speed;
474     	
475     	SelectedDrive = drive;
476     }
477     
478     
479     /* Deselect both drives. */
480     
481     static void fd_deselect( void )
482     {
483     	unsigned long flags;
484     
485     	save_flags(flags);
486     	cli(); /* protect against various other ints mucking around with the PSG */
487     	atari_dont_touch_floppy_select = 0;
488     	sound_ym.rd_data_reg_sel=14;	/* Select PSG Port A */
489     	sound_ym.wd_data = (sound_ym.rd_data_reg_sel |
490     			    (MACH_IS_FALCON ? 3 : 7)); /* no drives selected */
491     	/* On Falcon, the drive B select line is used on the printer port, so
492     	 * leave it alone... */
493     	SelectedDrive = -1;
494     	restore_flags(flags);
495     }
496     
497     
498     /* This timer function deselects the drives when the FDC switched the
499      * motor off. The deselection cannot happen earlier because the FDC
500      * counts the index signals, which arrive only if one drive is selected.
501      */
502     
503     static void fd_motor_off_timer( unsigned long dummy )
504     {
505     	unsigned char status;
506     
507     	if (SelectedDrive < 0)
508     		/* no drive selected, needn't deselect anyone */
509     		return;
510     
511     	if (stdma_islocked())
512     		goto retry;
513     
514     	status = FDC_READ( FDCREG_STATUS );
515     
516     	if (!(status & 0x80)) {
517     		/* motor already turned off by FDC -> deselect drives */
518     		MotorOn = 0;
519     		fd_deselect();
520     		return;
521     	}
522     	/* not yet off, try again */
523     
524       retry:
525     	/* Test again later; if tested too often, it seems there is no disk
526     	 * in the drive and the FDC will leave the motor on forever (or,
527     	 * at least until a disk is inserted). So we'll test only twice
528     	 * per second from then on...
529     	 */
530     	mod_timer(&motor_off_timer,
531     		  jiffies + (MotorOffTrys++ < FD_MOTOR_OFF_MAXTRY ? HZ/20 : HZ/2));
532     }
533     
534     
535     /* This function is repeatedly called to detect disk changes (as good
536      * as possible) and keep track of the current state of the write protection.
537      */
538     
539     static void check_change( void )
540     {
541     	static int    drive = 0;
542     
543     	unsigned long flags;
544     	unsigned char old_porta;
545     	int			  stat;
546     
547     	if (++drive > 1 || !UD.connected)
548     		drive = 0;
549     
550     	save_flags(flags);
551     	cli(); /* protect against various other ints mucking around with the PSG */
552     
553     	if (!stdma_islocked()) {
554     		sound_ym.rd_data_reg_sel = 14;
555     		old_porta = sound_ym.rd_data_reg_sel;
556     		sound_ym.wd_data = (old_porta | DSKDRVNONE) &
557     			               ~(drive == 0 ? DSKDRV0 : DSKDRV1);
558     		stat = !!(FDC_READ( FDCREG_STATUS ) & FDCSTAT_WPROT);
559     		sound_ym.wd_data = old_porta;
560     
561     		if (stat != UD.wpstat) {
562     			DPRINT(( "wpstat[%d] = %d\n", drive, stat ));
563     			UD.wpstat = stat;
564     			set_bit (drive, &changed_floppies);
565     		}
566     	}
567     	restore_flags(flags);
568     
569     	start_check_change_timer();
570     }
571     
572      
573     /* Handling of the Head Settling Flag: This flag should be set after each
574      * seek operation, because we don't use seeks with verify.
575      */
576     
577     static __inline__ void set_head_settle_flag( void )
578     {
579     	HeadSettleFlag = FDCCMDADD_E;
580     }
581     
582     static __inline__ int get_head_settle_flag( void )
583     {
584     	int	tmp = HeadSettleFlag;
585     	HeadSettleFlag = 0;
586     	return( tmp );
587     }
588     
589       
590       
591     
592     /* General Interrupt Handling */
593     
594     static void (*FloppyIRQHandler)( int status ) = NULL;
595     
596     static void floppy_irq (int irq, void *dummy, struct pt_regs *fp)
597     {
598     	unsigned char status;
599     	void (*handler)( int );
600     
601     	handler = xchg(&FloppyIRQHandler, NULL);
602     
603     	if (handler) {
604     		nop();
605     		status = FDC_READ( FDCREG_STATUS );
606     		DPRINT(("FDC irq, status = %02x handler = %08lx\n",status,(unsigned long)handler));
607     		handler( status );
608     	}
609     	else {
610     		DPRINT(("FDC irq, no handler\n"));
611     	}
612     }
613     
614     
615     /* Error handling: If some error happened, retry some times, then
616      * recalibrate, then try again, and fail after MAX_ERRORS.
617      */
618     
619     static void fd_error( void )
620     {
621     	if (IsFormatting) {
622     		IsFormatting = 0;
623     		FormatError = 1;
624     		wake_up( &format_wait );
625     		return;
626     	}
627     		
628     	if (QUEUE_EMPTY) return;
629     	CURRENT->errors++;
630     	if (CURRENT->errors >= MAX_ERRORS) {
631     		printk(KERN_ERR "fd%d: too many errors.\n", SelectedDrive );
632     		end_request( 0 );
633     	}
634     	else if (CURRENT->errors == RECALIBRATE_ERRORS) {
635     		printk(KERN_WARNING "fd%d: recalibrating\n", SelectedDrive );
636     		if (SelectedDrive != -1)
637     			SUD.track = -1;
638     	}
639     	redo_fd_request();
640     }
641     
642     
643     
644     #define	SET_IRQ_HANDLER(proc) do { FloppyIRQHandler = (proc); } while(0)
645     
646     
647     /* ---------- Formatting ---------- */
648     
649     #define FILL(n,val)		\
650         do {			\
651     	memset( p, val, n );	\
652     	p += n;			\
653         } while(0)
654     
655     static int do_format(kdev_t device, struct atari_format_descr *desc)
656     {
657     	unsigned char	*p;
658     	int sect, nsect;
659     	unsigned long	flags;
660     	int type, drive = MINOR(device) & 3;
661     
662     	DPRINT(("do_format( dr=%d tr=%d he=%d offs=%d )\n",
663     		drive, desc->track, desc->head, desc->sect_offset ));
664     
665     	save_flags(flags);
666     	cli();
667     	while( fdc_busy ) sleep_on( &fdc_wait );
668     	fdc_busy = 1;
669     	stdma_lock(floppy_irq, NULL);
670     	atari_turnon_irq( IRQ_MFP_FDC ); /* should be already, just to be sure */
671     	restore_flags(flags);
672     
673     	type = MINOR(device) >> 2;
674     	if (type) {
675     		if (--type >= NUM_DISK_MINORS ||
676     		    minor2disktype[type].drive_types > DriveType) {
677     			redo_fd_request();
678     			return -EINVAL;
679     		}
680     		type = minor2disktype[type].index;
681     		UDT = &disk_type[type];
682     	}
683     
684     	if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) {
685     		redo_fd_request();
686     		return -EINVAL;
687     	}
688     
689     	nsect = UDT->spt;
690     	p = TrackBuffer;
691     	/* The track buffer is used for the raw track data, so its
692     	   contents become invalid! */
693     	BufferDrive = -1;
694     	/* stop deselect timer */
695     	del_timer( &motor_off_timer );
696     
697     	FILL( 60 * (nsect / 9), 0x4e );
698     	for( sect = 0; sect < nsect; ++sect ) {
699     		FILL( 12, 0 );
700     		FILL( 3, 0xf5 );
701     		*p++ = 0xfe;
702     		*p++ = desc->track;
703     		*p++ = desc->head;
704     		*p++ = (nsect + sect - desc->sect_offset) % nsect + 1;
705     		*p++ = 2;
706     		*p++ = 0xf7;
707     		FILL( 22, 0x4e );
708     		FILL( 12, 0 );
709     		FILL( 3, 0xf5 );
710     		*p++ = 0xfb;
711     		FILL( 512, 0xe5 );
712     		*p++ = 0xf7;
713     		FILL( 40, 0x4e );
714     	}
715     	FILL( TrackBuffer+BUFFER_SIZE-p, 0x4e );
716     
717     	IsFormatting = 1;
718     	FormatError = 0;
719     	ReqTrack = desc->track;
720     	ReqSide  = desc->head;
721     	do_fd_action( drive );
722     
723     	sleep_on( &format_wait );
724     
725     	redo_fd_request();
726     	return( FormatError ? -EIO : 0 );	
727     }
728     
729     
730     /* do_fd_action() is the general procedure for a fd request: All
731      * required parameter settings (drive select, side select, track
732      * position) are checked and set if needed. For each of these
733      * parameters and the actual reading or writing exist two functions:
734      * one that starts the setting (or skips it if possible) and one
735      * callback for the "done" interrupt. Each done func calls the next
736      * set function to propagate the request down to fd_rwsec_done().
737      */
738     
739     static void do_fd_action( int drive )
740     {
741     	DPRINT(("do_fd_action\n"));
742     	
743     	if (UseTrackbuffer && !IsFormatting) {
744     	repeat:
745     	    if (IS_BUFFERED( drive, ReqSide, ReqTrack )) {
746     		if (ReqCmd == READ) {
747     		    copy_buffer( SECTOR_BUFFER(ReqSector), ReqData );
748     		    if (++ReqCnt < CURRENT->current_nr_sectors) {
749     			/* read next sector */
750     			setup_req_params( drive );
751     			goto repeat;
752     		    }
753     		    else {
754     			/* all sectors finished */
755     			CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
756     			CURRENT->sector += CURRENT->current_nr_sectors;
757     			end_request( 1 );
758     			redo_fd_request();
759     			return;
760     		    }
761     		}
762     		else {
763     		    /* cmd == WRITE, pay attention to track buffer
764     		     * consistency! */
765     		    copy_buffer( ReqData, SECTOR_BUFFER(ReqSector) );
766     		}
767     	    }
768     	}
769     
770     	if (SelectedDrive != drive)
771     		fd_select_drive( drive );
772         
773     	if (UD.track == -1)
774     		fd_calibrate();
775     	else if (UD.track != ReqTrack << UDT->stretch)
776     		fd_seek();
777     	else if (IsFormatting)
778     		fd_writetrack();
779     	else
780     		fd_rwsec();
781     }
782     
783     
784     /* Seek to track 0 if the current track is unknown */
785     
786     static void fd_calibrate( void )
787     {
788     	if (SUD.track >= 0) {
789     		fd_calibrate_done( 0 );
790     		return;
791     	}
792     
793     	if (ATARIHW_PRESENT(FDCSPEED))
794     		dma_wd.fdc_speed = 0; 	/* always seek with 8 Mhz */;
795     	DPRINT(("fd_calibrate\n"));
796     	SET_IRQ_HANDLER( fd_calibrate_done );
797     	/* we can't verify, since the speed may be incorrect */
798     	FDC_WRITE( FDCREG_CMD, FDCCMD_RESTORE | SUD.steprate );
799     
800     	NeedSeek = 1;
801     	MotorOn = 1;
802     	start_timeout();
803     	/* wait for IRQ */
804     }
805     
806     
807     static void fd_calibrate_done( int status )
808     {
809     	DPRINT(("fd_calibrate_done()\n"));
810     	stop_timeout();
811         
812     	/* set the correct speed now */
813     	if (ATARIHW_PRESENT(FDCSPEED))
814     		dma_wd.fdc_speed = SUDT->fdc_speed;
815     	if (status & FDCSTAT_RECNF) {
816     		printk(KERN_ERR "fd%d: restore failed\n", SelectedDrive );
817     		fd_error();
818     	}
819     	else {
820     		SUD.track = 0;
821     		fd_seek();
822     	}
823     }
824       
825       
826     /* Seek the drive to the requested track. The drive must have been
827      * calibrated at some point before this.
828      */
829       
830     static void fd_seek( void )
831     {
832     	if (SUD.track == ReqTrack << SUDT->stretch) {
833     		fd_seek_done( 0 );
834     		return;
835     	}
836     
837     	if (ATARIHW_PRESENT(FDCSPEED)) {
838     		dma_wd.fdc_speed = 0;	/* always seek witch 8 Mhz */
839     		MFPDELAY();
840     	}
841     
842     	DPRINT(("fd_seek() to track %d\n",ReqTrack));
843     	FDC_WRITE( FDCREG_DATA, ReqTrack << SUDT->stretch);
844     	udelay(25);
845     	SET_IRQ_HANDLER( fd_seek_done );
846     	FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK | SUD.steprate );
847     
848     	MotorOn = 1;
849     	set_head_settle_flag();
850     	start_timeout();
851     	/* wait for IRQ */
852     }
853     
854     
855     static void fd_seek_done( int status )
856     {
857     	DPRINT(("fd_seek_done()\n"));
858     	stop_timeout();
859     	
860     	/* set the correct speed */
861     	if (ATARIHW_PRESENT(FDCSPEED))
862     		dma_wd.fdc_speed = SUDT->fdc_speed;
863     	if (status & FDCSTAT_RECNF) {
864     		printk(KERN_ERR "fd%d: seek error (to track %d)\n",
865     				SelectedDrive, ReqTrack );
866     		/* we don't know exactly which track we are on now! */
867     		SUD.track = -1;
868     		fd_error();
869     	}
870     	else {
871     		SUD.track = ReqTrack << SUDT->stretch;
872     		NeedSeek = 0;
873     		if (IsFormatting)
874     			fd_writetrack();
875     		else
876     			fd_rwsec();
877     	}
878     }
879     
880     
881     /* This does the actual reading/writing after positioning the head
882      * over the correct track.
883      */
884     
885     static int MultReadInProgress = 0;
886     
887     
888     static void fd_rwsec( void )
889     {
890     	unsigned long paddr, flags;
891     	unsigned int  rwflag, old_motoron;
892     	unsigned int track;
893     	
894     	DPRINT(("fd_rwsec(), Sec=%d, Access=%c\n",ReqSector, ReqCmd == WRITE ? 'w' : 'r' ));
895     	if (ReqCmd == WRITE) {
896     		if (ATARIHW_PRESENT(EXTD_DMA)) {
897     			paddr = virt_to_phys(ReqData);
898     		}
899     		else {
900     			copy_buffer( ReqData, DMABuffer );
901     			paddr = PhysDMABuffer;
902     		}
903     		dma_cache_maintenance( paddr, 512, 1 );
904     		rwflag = 0x100;
905     	}
906     	else {
907     		if (read_track)
908     			paddr = PhysTrackBuffer;
909     		else
910     			paddr = ATARIHW_PRESENT(EXTD_DMA) ? 
911     				virt_to_phys(ReqData) : PhysDMABuffer;
912     		rwflag = 0;
913     	}
914     
915     	fd_select_side( ReqSide );
916       
917     	/* Start sector of this operation */
918     	FDC_WRITE( FDCREG_SECTOR, read_track ? 1 : ReqSector );
919     	MFPDELAY();
920     	/* Cheat for track if stretch != 0 */
921     	if (SUDT->stretch) {
922     		track = FDC_READ( FDCREG_TRACK);
923     		MFPDELAY();
924     		FDC_WRITE( FDCREG_TRACK, track >> SUDT->stretch);
925     	}
926     	udelay(25);
927       
928     	/* Setup DMA */
929     	save_flags(flags);  
930     	cli();
931     	dma_wd.dma_lo = (unsigned char)paddr;
932     	MFPDELAY();
933     	paddr >>= 8;
934     	dma_wd.dma_md = (unsigned char)paddr;
935     	MFPDELAY();
936     	paddr >>= 8;
937     	if (ATARIHW_PRESENT(EXTD_DMA))
938     		st_dma_ext_dmahi = (unsigned short)paddr;
939     	else
940     		dma_wd.dma_hi = (unsigned char)paddr;
941     	MFPDELAY();
942     	restore_flags(flags);
943       
944     	/* Clear FIFO and switch DMA to correct mode */  
945     	dma_wd.dma_mode_status = 0x90 | rwflag;  
946     	MFPDELAY();
947     	dma_wd.dma_mode_status = 0x90 | (rwflag ^ 0x100);  
948     	MFPDELAY();
949     	dma_wd.dma_mode_status = 0x90 | rwflag;
950     	MFPDELAY();
951       
952     	/* How many sectors for DMA */
953     	dma_wd.fdc_acces_seccount = read_track ? SUDT->spt : 1;
954       
955     	udelay(25);  
956       
957     	/* Start operation */
958     	dma_wd.dma_mode_status = FDCSELREG_STP | rwflag;
959     	udelay(25);
960     	SET_IRQ_HANDLER( fd_rwsec_done );
961     	dma_wd.fdc_acces_seccount =
962     	  (get_head_settle_flag() |
963     	   (rwflag ? FDCCMD_WRSEC : (FDCCMD_RDSEC | (read_track ? FDCCMDADD_M : 0))));
964     
965     	old_motoron = MotorOn;
966     	MotorOn = 1;
967     	NeedSeek = 1;
968     	/* wait for interrupt */
969     
970     	if (read_track) {
971     		/* If reading a whole track, wait about one disk rotation and
972     		 * then check if all sectors are read. The FDC will even
973     		 * search for the first non-existent sector and need 1 sec to
974     		 * recognise that it isn't present :-(
975     		 */
976     		MultReadInProgress = 1;
977     		mod_timer(&readtrack_timer,
978     			  /* 1 rot. + 5 rot.s if motor was off  */
979     			  jiffies + HZ/5 + (old_motoron ? 0 : HZ));
980     	}
981     	start_timeout();
982     }
983     
984         
985     static void fd_readtrack_check( unsigned long dummy )
986     {
987     	unsigned long flags, addr, addr2;
988     
989     	save_flags(flags);  
990     	cli();
991     
992     	if (!MultReadInProgress) {
993     		/* This prevents a race condition that could arise if the
994     		 * interrupt is triggered while the calling of this timer
995     		 * callback function takes place. The IRQ function then has
996     		 * already cleared 'MultReadInProgress'  when flow of control
997     		 * gets here.
998     		 */
999     		restore_flags(flags);
1000     		return;
1001     	}
1002     
1003     	/* get the current DMA address */
1004     	/* ++ f.a. read twice to avoid being fooled by switcher */
1005     	addr = 0;
1006     	do {
1007     		addr2 = addr;
1008     		addr = dma_wd.dma_lo & 0xff;
1009     		MFPDELAY();
1010     		addr |= (dma_wd.dma_md & 0xff) << 8;
1011     		MFPDELAY();
1012     		if (ATARIHW_PRESENT( EXTD_DMA ))
1013     			addr |= (st_dma_ext_dmahi & 0xffff) << 16;
1014     		else
1015     			addr |= (dma_wd.dma_hi & 0xff) << 16;
1016     		MFPDELAY();
1017     	} while(addr != addr2);
1018       
1019     	if (addr >= PhysTrackBuffer + SUDT->spt*512) {
1020     		/* already read enough data, force an FDC interrupt to stop
1021     		 * the read operation
1022     		 */
1023     		SET_IRQ_HANDLER( NULL );
1024     		MultReadInProgress = 0;
1025     		restore_flags(flags);
1026     		DPRINT(("fd_readtrack_check(): done\n"));
1027     		FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
1028     		udelay(25);
1029     
1030     		/* No error until now -- the FDC would have interrupted
1031     		 * otherwise!
1032     		 */
1033     		fd_rwsec_done1(0);
1034     	}
1035     	else {
1036     		/* not yet finished, wait another tenth rotation */
1037     		restore_flags(flags);
1038     		DPRINT(("fd_readtrack_check(): not yet finished\n"));
1039     		mod_timer(&readtrack_timer, jiffies + HZ/5/10);
1040     	}
1041     }
1042     
1043     
1044     static void fd_rwsec_done( int status )
1045     {
1046     	DPRINT(("fd_rwsec_done()\n"));
1047     
1048     	if (read_track) {
1049     		del_timer(&readtrack_timer);
1050     		if (!MultReadInProgress)
1051     			return;
1052     		MultReadInProgress = 0;
1053     	}
1054     	fd_rwsec_done1(status);
1055     }
1056     
1057     static void fd_rwsec_done1(int status)
1058     {
1059     	unsigned int track;
1060     
1061     	stop_timeout();
1062     	
1063     	/* Correct the track if stretch != 0 */
1064     	if (SUDT->stretch) {
1065     		track = FDC_READ( FDCREG_TRACK);
1066     		MFPDELAY();
1067     		FDC_WRITE( FDCREG_TRACK, track << SUDT->stretch);
1068     	}
1069     
1070     	if (!UseTrackbuffer) {
1071     		dma_wd.dma_mode_status = 0x90;
1072     		MFPDELAY();
1073     		if (!(dma_wd.dma_mode_status & 0x01)) {
1074     			printk(KERN_ERR "fd%d: DMA error\n", SelectedDrive );
1075     			goto err_end;
1076     		}
1077     	}
1078     	MFPDELAY();
1079     
1080     	if (ReqCmd == WRITE && (status & FDCSTAT_WPROT)) {
1081     		printk(KERN_NOTICE "fd%d: is write protected\n", SelectedDrive );
1082     		goto err_end;
1083     	}	
1084     	if ((status & FDCSTAT_RECNF) &&
1085     	    /* RECNF is no error after a multiple read when the FDC
1086     	       searched for a non-existent sector! */
1087     	    !(read_track && FDC_READ(FDCREG_SECTOR) > SUDT->spt)) {
1088     		if (Probing) {
1089     			if (SUDT > disk_type) {
1090     			    if (SUDT[-1].blocks > ReqBlock) {
1091     				/* try another disk type */
1092     				SUDT--;
1093     				floppy_sizes[SelectedDrive] = SUDT->blocks >> 1;
1094     			    } else
1095     				Probing = 0;
1096     			}
1097     			else {
1098     				if (SUD.flags & FTD_MSG)
1099     					printk(KERN_INFO "fd%d: Auto-detected floppy type %s\n",
1100     					       SelectedDrive, SUDT->name );
1101     				Probing=0;
1102     			}
1103     		} else {	
1104     /* record not found, but not probing. Maybe stretch wrong ? Restart probing */
1105     			if (SUD.autoprobe) {
1106     				SUDT = disk_type + StartDiskType[DriveType];
1107     				floppy_sizes[SelectedDrive] = SUDT->blocks >> 1;
1108     				Probing = 1;
1109     			}
1110     		}
1111     		if (Probing) {
1112     			if (ATARIHW_PRESENT(FDCSPEED)) {
1113     				dma_wd.fdc_speed = SUDT->fdc_speed;
1114     				MFPDELAY();
1115     			}
1116     			setup_req_params( SelectedDrive );
1117     			BufferDrive = -1;
1118     			do_fd_action( SelectedDrive );
1119     			return;
1120     		}
1121     
1122     		printk(KERN_ERR "fd%d: sector %d not found (side %d, track %d)\n",
1123     		       SelectedDrive, FDC_READ (FDCREG_SECTOR), ReqSide, ReqTrack );
1124     		goto err_end;
1125     	}
1126     	if (status & FDCSTAT_CRC) {
1127     		printk(KERN_ERR "fd%d: CRC error (side %d, track %d, sector %d)\n",
1128     		       SelectedDrive, ReqSide, ReqTrack, FDC_READ (FDCREG_SECTOR) );
1129     		goto err_end;
1130     	}
1131     	if (status & FDCSTAT_LOST) {
1132     		printk(KERN_ERR "fd%d: lost data (side %d, track %d, sector %d)\n",
1133     		       SelectedDrive, ReqSide, ReqTrack, FDC_READ (FDCREG_SECTOR) );
1134     		goto err_end;
1135     	}
1136     
1137     	Probing = 0;
1138     	
1139     	if (ReqCmd == READ) {
1140     		if (!read_track) {
1141     			void *addr;
1142     			addr = ATARIHW_PRESENT( EXTD_DMA ) ? ReqData : DMABuffer;
1143     			dma_cache_maintenance( virt_to_phys(addr), 512, 0 );
1144     			if (!ATARIHW_PRESENT( EXTD_DMA ))
1145     				copy_buffer (addr, ReqData);
1146     		} else {
1147     			dma_cache_maintenance( PhysTrackBuffer, MaxSectors[DriveType] * 512, 0 );
1148     			BufferDrive = SelectedDrive;
1149     			BufferSide  = ReqSide;
1150     			BufferTrack = ReqTrack;
1151     			copy_buffer (SECTOR_BUFFER (ReqSector), ReqData);
1152     		}
1153     	}
1154       
1155     	if (++ReqCnt < CURRENT->current_nr_sectors) {
1156     		/* read next sector */
1157     		setup_req_params( SelectedDrive );
1158     		do_fd_action( SelectedDrive );
1159     	}
1160     	else {
1161     		/* all sectors finished */
1162     		CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
1163     		CURRENT->sector += CURRENT->current_nr_sectors;
1164     		end_request( 1 );
1165     		redo_fd_request();
1166     	}
1167     	return;
1168       
1169       err_end:
1170     	BufferDrive = -1;
1171     	fd_error();
1172     }
1173     
1174     
1175     static void fd_writetrack( void )
1176     {
1177     	unsigned long paddr, flags;
1178     	unsigned int track;
1179     	
1180     	DPRINT(("fd_writetrack() Tr=%d Si=%d\n", ReqTrack, ReqSide ));
1181     
1182     	paddr = PhysTrackBuffer;
1183     	dma_cache_maintenance( paddr, BUFFER_SIZE, 1 );
1184     
1185     	fd_select_side( ReqSide );
1186       
1187     	/* Cheat for track if stretch != 0 */
1188     	if (SUDT->stretch) {
1189     		track = FDC_READ( FDCREG_TRACK);
1190     		MFPDELAY();
1191     		FDC_WRITE(FDCREG_TRACK,track >> SUDT->stretch);
1192     	}
1193     	udelay(40);
1194       
1195     	/* Setup DMA */
1196     	save_flags(flags);  
1197     	cli();
1198     	dma_wd.dma_lo = (unsigned char)paddr;
1199     	MFPDELAY();
1200     	paddr >>= 8;
1201     	dma_wd.dma_md = (unsigned char)paddr;
1202     	MFPDELAY();
1203     	paddr >>= 8;
1204     	if (ATARIHW_PRESENT( EXTD_DMA ))
1205     		st_dma_ext_dmahi = (unsigned short)paddr;
1206     	else
1207     		dma_wd.dma_hi = (unsigned char)paddr;
1208     	MFPDELAY();
1209     	restore_flags(flags);
1210       
1211     	/* Clear FIFO and switch DMA to correct mode */  
1212     	dma_wd.dma_mode_status = 0x190;  
1213     	MFPDELAY();
1214     	dma_wd.dma_mode_status = 0x90;  
1215     	MFPDELAY();
1216     	dma_wd.dma_mode_status = 0x190;
1217     	MFPDELAY();
1218       
1219     	/* How many sectors for DMA */
1220     	dma_wd.fdc_acces_seccount = BUFFER_SIZE/512;
1221     	udelay(40);  
1222       
1223     	/* Start operation */
1224     	dma_wd.dma_mode_status = FDCSELREG_STP | 0x100;
1225     	udelay(40);
1226     	SET_IRQ_HANDLER( fd_writetrack_done );
1227     	dma_wd.fdc_acces_seccount = FDCCMD_WRTRA | get_head_settle_flag(); 
1228     
1229     	MotorOn = 1;
1230     	start_timeout();
1231     	/* wait for interrupt */
1232     }
1233     
1234     
1235     static void fd_writetrack_done( int status )
1236     {
1237     	DPRINT(("fd_writetrack_done()\n"));
1238     
1239     	stop_timeout();
1240     
1241     	if (status & FDCSTAT_WPROT) {
1242     		printk(KERN_NOTICE "fd%d: is write protected\n", SelectedDrive );
1243     		goto err_end;
1244     	}	
1245     	if (status & FDCSTAT_LOST) {
1246     		printk(KERN_ERR "fd%d: lost data (side %d, track %d)\n",
1247     				SelectedDrive, ReqSide, ReqTrack );
1248     		goto err_end;
1249     	}
1250     
1251     	wake_up( &format_wait );
1252     	return;
1253     
1254       err_end:
1255     	fd_error();
1256     }
1257     
1258     static void fd_times_out( unsigned long dummy )
1259     {
1260     	atari_disable_irq( IRQ_MFP_FDC );
1261     	if (!FloppyIRQHandler) goto end; /* int occurred after timer was fired, but
1262     					  * before we came here... */
1263     
1264     	SET_IRQ_HANDLER( NULL );
1265     	/* If the timeout occurred while the readtrack_check timer was
1266     	 * active, we need to cancel it, else bad things will happen */
1267     	if (UseTrackbuffer)
1268     		del_timer( &readtrack_timer );
1269     	FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
1270     	udelay( 25 );
1271     	
1272     	printk(KERN_ERR "floppy timeout\n" );
1273     	fd_error();
1274       end:
1275     	atari_enable_irq( IRQ_MFP_FDC );
1276     }
1277     
1278     
1279     /* The (noop) seek operation here is needed to make the WP bit in the
1280      * FDC status register accessible for check_change. If the last disk
1281      * operation would have been a RDSEC, this bit would always read as 0
1282      * no matter what :-( To save time, the seek goes to the track we're
1283      * already on.
1284      */
1285     
1286     static void finish_fdc( void )
1287     {
1288     	if (!NeedSeek) {
1289     		finish_fdc_done( 0 );
1290     	}
1291     	else {
1292     		DPRINT(("finish_fdc: dummy seek started\n"));
1293     		FDC_WRITE (FDCREG_DATA, SUD.track);
1294     		SET_IRQ_HANDLER( finish_fdc_done );
1295     		FDC_WRITE (FDCREG_CMD, FDCCMD_SEEK);
1296     		MotorOn = 1;
1297     		start_timeout();
1298     		/* we must wait for the IRQ here, because the ST-DMA
1299     		   is released immediately afterwards and the interrupt
1300     		   may be delivered to the wrong driver. */
1301     	  }
1302     }
1303     
1304     
1305     static void finish_fdc_done( int dummy )
1306     {
1307     	unsigned long flags;
1308     
1309     	DPRINT(("finish_fdc_done entered\n"));
1310     	stop_timeout();
1311     	NeedSeek = 0;
1312     
1313     	if (timer_pending(&fd_timer) && time_before(fd_timer.expires, jiffies + 5))
1314     		/* If the check for a disk change is done too early after this
1315     		 * last seek command, the WP bit still reads wrong :-((
1316     		 */
1317     		mod_timer(&fd_timer, jiffies + 5);
1318     	else
1319     		start_check_change_timer();
1320     	start_motor_off_timer();
1321     
1322     	save_flags(flags);
1323     	cli();
1324     	stdma_release();
1325     	fdc_busy = 0;
1326     	wake_up( &fdc_wait );
1327     	restore_flags(flags);
1328     
1329     	DPRINT(("finish_fdc() finished\n"));
1330     }
1331     
1332     
1333     /* Prevent "aliased" accesses. */
1334     static int fd_ref[4] = { 0,0,0,0 };
1335     static int fd_device[4] = { 0,0,0,0 };
1336     
1337     /*
1338      * Current device number. Taken either from the block header or from the
1339      * format request descriptor.
1340      */
1341     #define CURRENT_DEVICE (CURRENT->rq_dev)
1342     
1343     /* Current error count. */
1344     #define CURRENT_ERRORS (CURRENT->errors)
1345     
1346     
1347     /* dummy for blk.h */
1348     static void floppy_off( unsigned int nr) {}
1349     
1350     
1351     /* The detection of disk changes is a dark chapter in Atari history :-(
1352      * Because the "Drive ready" signal isn't present in the Atari
1353      * hardware, one has to rely on the "Write Protect". This works fine,
1354      * as long as no write protected disks are used. TOS solves this
1355      * problem by introducing tri-state logic ("maybe changed") and
1356      * looking at the serial number in block 0. This isn't possible for
1357      * Linux, since the floppy driver can't make assumptions about the
1358      * filesystem used on the disk and thus the contents of block 0. I've
1359      * chosen the method to always say "The disk was changed" if it is
1360      * unsure whether it was. This implies that every open or mount
1361      * invalidates the disk buffers if you work with write protected
1362      * disks. But at least this is better than working with incorrect data
1363      * due to unrecognised disk changes.
1364      */
1365     
1366     static int check_floppy_change (kdev_t dev)
1367     {
1368     	unsigned int drive = MINOR(dev) & 0x03;
1369     
1370     	if (MAJOR(dev) != MAJOR_NR) {
1371     		printk(KERN_ERR "floppy_changed: not a floppy\n");
1372     		return 0;
1373     	}
1374     	
1375     	if (test_bit (drive, &fake_change)) {
1376     		/* simulated change (e.g. after formatting) */
1377     		return 1;
1378     	}
1379     	if (test_bit (drive, &changed_floppies)) {
1380     		/* surely changed (the WP signal changed at least once) */
1381     		return 1;
1382     	}
1383     	if (UD.wpstat) {
1384     		/* WP is on -> could be changed: to be sure, buffers should be
1385     		 * invalidated...
1386     		 */
1387     		return 1;
1388     	}
1389     
1390     	return 0;
1391     }
1392     
1393     static int floppy_revalidate (kdev_t dev)
1394     {
1395     	int drive = MINOR(dev) & 3;
1396     
1397     	if (test_bit(drive, &changed_floppies) ||
1398     	    test_bit(drive, &fake_change) ||
1399     	    unit[drive].disktype == 0) {
1400     		if (UD.flags & FTD_MSG)
1401     			printk(KERN_ERR "floppy: clear format %p!\n", UDT);
1402     		BufferDrive = -1;
1403     		clear_bit(drive, &fake_change);
1404     		clear_bit(drive, &changed_floppies);
1405     		/* MSch: clearing geometry makes sense only for autoprobe
1406     		   formats, for 'permanent user-defined' parameter:
1407     		   restore default_params[] here if flagged valid! */
1408     		if (default_params[drive].blocks == 0)
1409     			UDT = 0;
1410     		else
1411     			UDT = &default_params[drive];
1412     	}
1413     	return 0;
1414     }
1415     
1416     static __inline__ void copy_buffer(void *from, void *to)
1417     {
1418     	ulong	*p1 = (ulong *)from, *p2 = (ulong *)to;
1419     	int		cnt;
1420     
1421     	for( cnt = 512/4; cnt; cnt-- )
1422     		*p2++ = *p1++;
1423     }
1424     
1425     
1426     /* This sets up the global variables describing the current request. */
1427     
1428     static void setup_req_params( int drive )
1429     {
1430     	int block = ReqBlock + ReqCnt;
1431     
1432     	ReqTrack = block / UDT->spt;
1433     	ReqSector = block - ReqTrack * UDT->spt + 1;
1434     	ReqSide = ReqTrack & 1;
1435     	ReqTrack >>= 1;
1436     	ReqData = ReqBuffer + 512 * ReqCnt;
1437     
1438     	if (UseTrackbuffer)
1439     		read_track = (ReqCmd == READ && CURRENT_ERRORS == 0);
1440     	else
1441     		read_track = 0;
1442     
1443     	DPRINT(("Request params: Si=%d Tr=%d Se=%d Data=%08lx\n",ReqSide,
1444     			ReqTrack, ReqSector, (unsigned long)ReqData ));
1445     }
1446     
1447     
1448     static void redo_fd_request(void)
1449     {
1450     	int device, drive, type;
1451       
1452     	DPRINT(("redo_fd_request: CURRENT=%08lx CURRENT->dev=%04x CURRENT->sector=%ld\n",
1453     		(unsigned long)CURRENT, !QUEUE_EMPTY ? CURRENT->rq_dev : 0,
1454     		!QUEUE_EMPTY ? CURRENT->sector : 0 ));
1455     
1456     	IsFormatting = 0;
1457     
1458     	if (!QUEUE_EMPTY && CURRENT->rq_status == RQ_INACTIVE){
1459     		return;
1460     	}
1461     
1462     repeat:
1463         
1464     	if (QUEUE_EMPTY)
1465     		goto the_end;
1466     
1467     	if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
1468     		panic(DEVICE_NAME ": request list destroyed");
1469     
1470     	if (CURRENT->bh && !buffer_locked(CURRENT->bh))
1471     		panic(DEVICE_NAME ": block not locked");
1472     
1473     	device = MINOR(CURRENT_DEVICE);
1474     	drive = device & 3;
1475     	type = device >> 2;
1476     	
1477     	if (!UD.connected) {
1478     		/* drive not connected */
1479     		printk(KERN_ERR "Unknown Device: fd%d\n", drive );
1480     		end_request(0);
1481     		goto repeat;
1482     	}
1483     		
1484     	if (type == 0) {
1485     		if (!UDT) {
1486     			Probing = 1;
1487     			UDT = disk_type + StartDiskType[DriveType];
1488     			floppy_sizes[drive] = UDT->blocks >> 1;
1489     			UD.autoprobe = 1;
1490     		}
1491     	} 
1492     	else {
1493     		/* user supplied disk type */
1494     		if (--type >= NUM_DISK_MINORS) {
1495     			printk(KERN_WARNING "fd%d: invalid disk format", drive );
1496     			end_request( 0 );
1497     			goto repeat;
1498     		}
1499     		if (minor2disktype[type].drive_types > DriveType)  {
1500     			printk(KERN_WARNING "fd%d: unsupported disk format", drive );
1501     			end_request( 0 );
1502     			goto repeat;
1503     		}
1504     		type = minor2disktype[type].index;
1505     		UDT = &disk_type[type];
1506     		floppy_sizes[drive] = UDT->blocks >> 1;
1507     		UD.autoprobe = 0;
1508     	}
1509     	
1510     	if (CURRENT->sector + 1 > UDT->blocks) {
1511     		end_request(0);
1512     		goto repeat;
1513     	}
1514     
1515     	/* stop deselect timer */
1516     	del_timer( &motor_off_timer );
1517     		
1518     	ReqCnt = 0;
1519     	ReqCmd = CURRENT->cmd;
1520     	ReqBlock = CURRENT->sector;
1521     	ReqBuffer = CURRENT->buffer;
1522     	setup_req_params( drive );
1523     	do_fd_action( drive );
1524     
1525     	return;
1526     
1527       the_end:
1528     	finish_fdc();
1529     }
1530     
1531     
1532     void do_fd_request(request_queue_t * q)
1533     {
1534      	unsigned long flags;
1535     
1536     	DPRINT(("do_fd_request for pid %d\n",current->pid));
1537     	while( fdc_busy ) sleep_on( &fdc_wait );
1538     	fdc_busy = 1;
1539     	stdma_lock(floppy_irq, NULL);
1540     
1541     	atari_disable_irq( IRQ_MFP_FDC );
1542     	save_flags(flags);	/* The request function is called with ints
1543     	sti();				 * disabled... so must save the IPL for later */ 
1544     	redo_fd_request();
1545     	restore_flags(flags);
1546     	atari_enable_irq( IRQ_MFP_FDC );
1547     }
1548     
1549     
1550     static int invalidate_drive(kdev_t rdev)
1551     {
1552     	/* invalidate the buffer track to force a reread */
1553     	BufferDrive = -1;
1554     	set_bit(MINOR(rdev) & 3, &fake_change);
1555     	check_disk_change(rdev);
1556     	return 0;
1557     }
1558     
1559     static int fd_ioctl(struct inode *inode, struct file *filp,
1560     		    unsigned int cmd, unsigned long param)
1561     {
1562     	int drive, type;
1563     	kdev_t device;
1564     	struct atari_format_descr fmt_desc;
1565     	struct atari_disk_type *dtp;
1566     	struct floppy_struct getprm;
1567     	int settype;
1568     	struct floppy_struct setprm;
1569     
1570     	device = inode->i_rdev;
1571     	switch (cmd) {
1572     		case BLKROSET:
1573     		case BLKROGET:
1574     		case BLKRASET:
1575     		case BLKRAGET:
1576     		case BLKFLSBUF:
1577     			return blk_ioctl(device, cmd, param);
1578     	}
1579     	drive = MINOR (device);
1580     	type  = drive >> 2;
1581     	drive &= 3;
1582     	switch (cmd) {
1583     	case FDGETPRM:
1584     	case BLKGETSIZE:
1585     		if (type) {
1586     			if (--type >= NUM_DISK_MINORS)
1587     				return -ENODEV;
1588     			if (minor2disktype[type].drive_types > DriveType)
1589     				return -ENODEV;
1590     			type = minor2disktype[type].index;
1591     			dtp = &disk_type[type];
1592     			if (UD.flags & FTD_MSG)
1593     			    printk (KERN_ERR "floppy%d: found dtp %p name %s!\n",
1594     			        drive, dtp, dtp->name);
1595     		}
1596     		else {
1597     			if (!UDT)
1598     				return -ENXIO;
1599     			else
1600     				dtp = UDT;
1601     		}
1602     		if (cmd == BLKGETSIZE)
1603     			return put_user(dtp->blocks, (long *)param);
1604     
1605     		memset((void *)&getprm, 0, sizeof(getprm));
1606     		getprm.size = dtp->blocks;
1607     		getprm.sect = dtp->spt;
1608     		getprm.head = 2;
1609     		getprm.track = dtp->blocks/dtp->spt/2;
1610     		getprm.stretch = dtp->stretch;
1611     		if (copy_to_user((void *)param, &getprm, sizeof(getprm)))
1612     			return -EFAULT;
1613     		return 0;
1614     	}
1615     	switch (cmd) {
1616     	case FDSETPRM:
1617     	case FDDEFPRM:
1618     	        /* 
1619     		 * MSch 7/96: simple 'set geometry' case: just set the
1620     		 * 'default' device params (minor == 0).
1621     		 * Currently, the drive geometry is cleared after each
1622     		 * disk change and subsequent revalidate()! simple
1623     		 * implementation of FDDEFPRM: save geometry from a
1624     		 * FDDEFPRM call and restore it in floppy_revalidate() !
1625     		 */
1626     
1627     		/* get the parameters from user space */
1628     		if (fd_ref[drive] != 1 && fd_ref[drive] != -1)
1629     			return -EBUSY;
1630     		if (copy_from_user(&setprm, (void *) param, sizeof(setprm)))
1631     			return -EFAULT;
1632     		/* 
1633     		 * first of all: check for floppy change and revalidate, 
1634     		 * or the next access will revalidate - and clear UDT :-(
1635     		 */
1636     
1637     		if (check_floppy_change(device))
1638     		        floppy_revalidate(device);
1639     
1640     		if (UD.flags & FTD_MSG)
1641     		    printk (KERN_INFO "floppy%d: setting size %d spt %d str %d!\n",
1642     			drive, setprm.size, setprm.sect, setprm.stretch);
1643     
1644     		/* what if type > 0 here? Overwrite specified entry ? */
1645     		if (type) {
1646     		        /* refuse to re-set a predefined type for now */
1647     			redo_fd_request();
1648     			return -EINVAL;
1649     		}
1650     
1651     		/* 
1652     		 * type == 0: first look for a matching entry in the type list,
1653     		 * and set the UD.disktype field to use the perdefined entry.
1654     		 * TODO: add user-defined format to head of autoprobe list ? 
1655     		 * Useful to include the user-type for future autodetection!
1656     		 */
1657     
1658     		for (settype = 0; settype < NUM_DISK_MINORS; settype++) {
1659     			int setidx = 0;
1660     			if (minor2disktype[settype].drive_types > DriveType) {
1661     				/* skip this one, invalid for drive ... */
1662     				continue;
1663     			}
1664     			setidx = minor2disktype[settype].index;
1665     			dtp = &disk_type[setidx];
1666     
1667     			/* found matching entry ?? */
1668     			if (   dtp->blocks  == setprm.size 
1669     			    && dtp->spt     == setprm.sect
1670     			    && dtp->stretch == setprm.stretch ) {
1671     				if (UD.flags & FTD_MSG)
1672     				    printk (KERN_INFO "floppy%d: setting %s %p!\n",
1673     				        drive, dtp->name, dtp);
1674     				UDT = dtp;
1675     				floppy_sizes[drive] = UDT->blocks >> 1;
1676     
1677     				if (cmd == FDDEFPRM) {
1678     				  /* save settings as permanent default type */
1679     				  default_params[drive].name    = dtp->name;
1680     				  default_params[drive].spt     = dtp->spt;
1681     				  default_params[drive].blocks  = dtp->blocks;
1682     				  default_params[drive].fdc_speed = dtp->fdc_speed;
1683     				  default_params[drive].stretch = dtp->stretch;
1684     				}
1685     				
1686     				return 0;
1687     			}
1688     
1689     		}
1690     
1691     		/* no matching disk type found above - setting user_params */
1692     
1693     	       	if (cmd == FDDEFPRM) {
1694     			/* set permanent type */
1695     			dtp = &default_params[drive];
1696     		} else
1697     			/* set user type (reset by disk change!) */
1698     			dtp = &user_params[drive];
1699     
1700     		dtp->name   = "user format";
1701     		dtp->blocks = setprm.size;
1702     		dtp->spt    = setprm.sect;
1703     		if (setprm.sect > 14) 
1704     			dtp->fdc_speed = 3;
1705     		else
1706     			dtp->fdc_speed = 0;
1707     		dtp->stretch = setprm.stretch;
1708     
1709     		if (UD.flags & FTD_MSG)
1710     			printk (KERN_INFO "floppy%d: blk %d spt %d str %d!\n",
1711     				drive, dtp->blocks, dtp->spt, dtp->stretch);
1712     
1713     		/* sanity check */
1714     		if (!dtp || setprm.track != dtp->blocks/dtp->spt/2 ||
1715     		    setprm.head != 2) {
1716     			redo_fd_request();
1717     			return -EINVAL;
1718     		}
1719     
1720     		UDT = dtp;
1721     		floppy_sizes[drive] = UDT->blocks >> 1;
1722     
1723     		return 0;
1724     	case FDMSGON:
1725     		UD.flags |= FTD_MSG;
1726     		return 0;
1727     	case FDMSGOFF:
1728     		UD.flags &= ~FTD_MSG;
1729     		return 0;
1730     	case FDSETEMSGTRESH:
1731     		return -EINVAL;
1732     	case FDFMTBEG:
1733     		return 0;
1734     	case FDFMTTRK:
1735     		if (fd_ref[drive] != 1 && fd_ref[drive] != -1)
1736     			return -EBUSY;
1737     		if (copy_from_user(&fmt_desc, (void *) param, sizeof(fmt_desc)))
1738     			return -EFAULT;
1739     		return do_format(device, &fmt_desc);
1740     	case FDCLRPRM:
1741     		UDT = NULL;
1742     		/* MSch: invalidate default_params */
1743     		default_params[drive].blocks  = 0;
1744     		floppy_sizes[drive] = MAX_DISK_SIZE;
1745     		return invalidate_drive (device);
1746     	case FDFMTEND:
1747     	case FDFLUSH:
1748     		return invalidate_drive(device);
1749     	}
1750     	return -EINVAL;
1751     }
1752     
1753     
1754     /* Initialize the 'unit' variable for drive 'drive' */
1755     
1756     static void __init fd_probe( int drive )
1757     {
1758     	UD.connected = 0;
1759     	UDT  = NULL;
1760     
1761     	if (!fd_test_drive_present( drive ))
1762     		return;
1763     
1764     	UD.connected = 1;
1765     	UD.track     = 0;
1766     	switch( UserSteprate[drive] ) {
1767     	case 2:
1768     		UD.steprate = FDCSTEP_2;
1769     		break;
1770     	case 3:
1771     		UD.steprate = FDCSTEP_3;
1772     		break;
1773     	case 6:
1774     		UD.steprate = FDCSTEP_6;
1775     		break;
1776     	case 12:
1777     		UD.steprate = FDCSTEP_12;
1778     		break;
1779     	default: /* should be -1 for "not set by user" */
1780     		if (ATARIHW_PRESENT( FDCSPEED ) || MACH_IS_MEDUSA)
1781     			UD.steprate = FDCSTEP_3;
1782     		else
1783     			UD.steprate = FDCSTEP_6;
1784     		break;
1785     	}
1786     	MotorOn = 1;	/* from probe restore operation! */
1787     }
1788     
1789     
1790     /* This function tests the physical presence of a floppy drive (not
1791      * whether a disk is inserted). This is done by issuing a restore
1792      * command, waiting max. 2 seconds (that should be enough to move the
1793      * head across the whole disk) and looking at the state of the "TR00"
1794      * signal. This should now be raised if there is a drive connected
1795      * (and there is no hardware failure :-) Otherwise, the drive is
1796      * declared absent.
1797      */
1798     
1799     static int __init fd_test_drive_present( int drive )
1800     {
1801     	unsigned long timeout;
1802     	unsigned char status;
1803     	int ok;
1804     	
1805     	if (drive >= (MACH_IS_FALCON ? 1 : 2)) return( 0 );
1806     	fd_select_drive( drive );
1807     
1808     	/* disable interrupt temporarily */
1809     	atari_turnoff_irq( IRQ_MFP_FDC );
1810     	FDC_WRITE (FDCREG_TRACK, 0xff00);
1811     	FDC_WRITE( FDCREG_CMD, FDCCMD_RESTORE | FDCCMDADD_H | FDCSTEP_6 );
1812     
1813     	timeout = jiffies + 2*HZ+HZ/2;
1814     	while (time_before(jiffies, timeout))
1815     		if (!(mfp.par_dt_reg & 0x20))
1816     			break;
1817     
1818     	status = FDC_READ( FDCREG_STATUS );
1819     	ok = (status & FDCSTAT_TR00) != 0;
1820     
1821     	/* force interrupt to abort restore operation (FDC would try
1822     	 * about 50 seconds!) */
1823     	FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
1824     	udelay(500);
1825     	status = FDC_READ( FDCREG_STATUS );
1826     	udelay(20);
1827     
1828     	if (ok) {
1829     		/* dummy seek command to make WP bit accessible */
1830     		FDC_WRITE( FDCREG_DATA, 0 );
1831     		FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK );
1832     		while( mfp.par_dt_reg & 0x20 )
1833     			;
1834     		status = FDC_READ( FDCREG_STATUS );
1835     	}
1836     
1837     	atari_turnon_irq( IRQ_MFP_FDC );
1838     	return( ok );
1839     }
1840     
1841     
1842     /* Look how many and which kind of drives are connected. If there are
1843      * floppies, additionally start the disk-change and motor-off timers.
1844      */
1845     
1846     static void __init config_types( void )
1847     {
1848     	int drive, cnt = 0;
1849     
1850     	/* for probing drives, set the FDC speed to 8 MHz */
1851     	if (ATARIHW_PRESENT(FDCSPEED))
1852     		dma_wd.fdc_speed = 0;
1853     
1854     	printk(KERN_INFO "Probing floppy drive(s):\n");
1855     	for( drive = 0; drive < FD_MAX_UNITS; drive++ ) {
1856     		fd_probe( drive );
1857     		if (UD.connected) {
1858     			printk(KERN_INFO "fd%d\n", drive);
1859     			++cnt;
1860     		}
1861     	}
1862     
1863     	if (FDC_READ( FDCREG_STATUS ) & FDCSTAT_BUSY) {
1864     		/* If FDC is still busy from probing, give it another FORCI
1865     		 * command to abort the operation. If this isn't done, the FDC
1866     		 * will interrupt later and its IRQ line stays low, because
1867     		 * the status register isn't read. And this will block any
1868     		 * interrupts on this IRQ line :-(
1869     		 */
1870     		FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
1871     		udelay(500);
1872     		FDC_READ( FDCREG_STATUS );
1873     		udelay(20);
1874     	}
1875     	
1876     	if (cnt > 0) {
1877     		start_motor_off_timer();
1878     		if (cnt == 1) fd_select_drive( 0 );
1879     		start_check_change_timer();
1880     	}
1881     }
1882     
1883     /*
1884      * floppy_open check for aliasing (/dev/fd0 can be the same as
1885      * /dev/PS0 etc), and disallows simultaneous access to the same
1886      * drive with different device numbers.
1887      */
1888     
1889     static int floppy_open( struct inode *inode, struct file *filp )
1890     {
1891     	int drive, type;
1892     	int old_dev;
1893     
1894     	if (!filp) {
1895     		DPRINT (("Weird, open called with filp=0\n"));
1896     		return -EIO;
1897     	}
1898     
1899     	drive = MINOR(inode->i_rdev) & 3;
1900     	type  = MINOR(inode->i_rdev) >> 2;
1901     	DPRINT(("fd_open: type=%d\n",type));
1902     	if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS)
1903     		return -ENXIO;
1904     
1905     	old_dev = fd_device[drive];
1906     
1907     	if (fd_ref[drive] && old_dev != MINOR(inode->i_rdev))
1908     		return -EBUSY;
1909     
1910     	if (fd_ref[drive] == -1 || (fd_ref[drive] && filp->f_flags & O_EXCL))
1911     		return -EBUSY;
1912     
1913     	MOD_INC_USE_COUNT;
1914     
1915     	if (filp->f_flags & O_EXCL)
1916     		fd_ref[drive] = -1;
1917     	else
1918     		fd_ref[drive]++;
1919     
1920     	fd_device[drive] = MINOR(inode->i_rdev);
1921     
1922     	if (old_dev && old_dev != MINOR(inode->i_rdev))
1923     		invalidate_buffers(MKDEV(FLOPPY_MAJOR, old_dev));
1924     
1925     	if (filp->f_flags & O_NDELAY)
1926     		return 0;
1927     
1928     	if (filp->f_mode & 3) {
1929     		check_disk_change(inode->i_rdev);
1930     		if (filp->f_mode & 2) {
1931     			if (UD.wpstat) {
1932     				floppy_release(inode, filp);
1933     				return -EROFS;
1934     			}
1935     		}
1936     	}
1937     
1938     	return 0;
1939     }
1940     
1941     
1942     static int floppy_release( struct inode * inode, struct file * filp )
1943     {
1944     	int drive = MINOR(inode->i_rdev) & 3;
1945     
1946     	if (fd_ref[drive] < 0)
1947     		fd_ref[drive] = 0;
1948     	else if (!fd_ref[drive]--) {
1949     		printk(KERN_ERR "floppy_release with fd_ref == 0");
1950     		fd_ref[drive] = 0;
1951     	}
1952     
1953     	MOD_DEC_USE_COUNT;
1954     	return 0;
1955     }
1956     
1957     static struct block_device_operations floppy_fops = {
1958     	open:			floppy_open,
1959     	release:		floppy_release,
1960     	ioctl:			fd_ioctl,
1961     	check_media_change:	check_floppy_change,
1962     	revalidate:		floppy_revalidate,
1963     };
1964     
1965     int __init atari_floppy_init (void)
1966     {
1967     	int i;
1968     
1969     	if (!MACH_IS_ATARI)
1970     		/* Amiga, Mac, ... don't have Atari-compatible floppy :-) */
1971     		return -ENXIO;
1972     
1973     	if (MACH_IS_HADES)
1974     		/* Hades doesn't have Atari-compatible floppy */
1975     		return -ENXIO;
1976     
1977     	if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
1978     		printk(KERN_ERR "Unable to get major %d for floppy\n",MAJOR_NR);
1979     		return -EBUSY;
1980     	}
1981     
1982     	if (UseTrackbuffer < 0)
1983     		/* not set by user -> use default: for now, we turn
1984     		   track buffering off for all Medusas, though it
1985     		   could be used with ones that have a counter
1986     		   card. But the test is too hard :-( */
1987     		UseTrackbuffer = !MACH_IS_MEDUSA;
1988     
1989     	/* initialize variables */
1990     	SelectedDrive = -1;
1991     	BufferDrive = -1;
1992     
1993     	DMABuffer = atari_stram_alloc(BUFFER_SIZE+512, "ataflop");
1994     	if (!DMABuffer) {
1995     		printk(KERN_ERR "atari_floppy_init: cannot get dma buffer\n");
1996     		unregister_blkdev(MAJOR_NR, "fd");
1997     		return -ENOMEM;
1998     	}
1999     	TrackBuffer = DMABuffer + 512;
2000     	PhysDMABuffer = virt_to_phys(DMABuffer);
2001     	PhysTrackBuffer = virt_to_phys(TrackBuffer);
2002     	BufferDrive = BufferSide = BufferTrack = -1;
2003     
2004     	for (i = 0; i < FD_MAX_UNITS; i++) {
2005     		unit[i].track = -1;
2006     		unit[i].flags = 0;
2007     	}
2008     
2009     	for (i = 0; i < 256; i++)
2010     		if ((i >> 2) > 0 && (i >> 2) <= NUM_DISK_MINORS) {
2011     			int type = minor2disktype[(i >> 2) - 1].index;
2012     			floppy_sizes[i] = disk_type[type].blocks >> 1;
2013     		} else
2014     			floppy_sizes[i] = MAX_DISK_SIZE;
2015     
2016     	blk_size[MAJOR_NR] = floppy_sizes;
2017     	blksize_size[MAJOR_NR] = floppy_blocksizes;
2018     	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
2019     
2020     	printk(KERN_INFO "Atari floppy driver: max. %cD, %strack buffering\n",
2021     	       DriveType == 0 ? 'D' : DriveType == 1 ? 'H' : 'E',
2022     	       UseTrackbuffer ? "" : "no ");
2023     	config_types();
2024     
2025     	(void)do_floppy; /* avoid warning about unused variable */
2026     	return 0;
2027     }
2028     
2029     
2030     void __init atari_floppy_setup( char *str, int *ints )
2031     {
2032     	int i;
2033     	
2034     	if (ints[0] < 1) {
2035     		printk(KERN_ERR "ataflop_setup: no arguments!\n" );
2036     		return;
2037     	}
2038     	else if (ints[0] > 2+FD_MAX_UNITS) {
2039     		printk(KERN_ERR "ataflop_setup: too many arguments\n" );
2040     	}
2041     
2042     	if (ints[1] < 0 || ints[1] > 2)
2043     		printk(KERN_ERR "ataflop_setup: bad drive type\n" );
2044     	else
2045     		DriveType = ints[1];
2046     
2047     	if (ints[0] >= 2)
2048     		UseTrackbuffer = (ints[2] > 0);
2049     
2050     	for( i = 3; i <= ints[0] && i-3 < FD_MAX_UNITS; ++i ) {
2051     		if (ints[i] != 2 && ints[i] != 3 && ints[i] != 6 && ints[i] != 12)
2052     			printk(KERN_ERR "ataflop_setup: bad steprate\n" );
2053     		else
2054     			UserSteprate[i-3] = ints[i];
2055     	}
2056     }
2057     
2058     #ifdef MODULE
2059     
2060     MODULE_LICENSE("GPL");
2061     
2062     int init_module (void)
2063     {
2064     	if (!MACH_IS_ATARI)
2065     		return -ENXIO;
2066     	return atari_floppy_init ();
2067     }
2068     
2069     void cleanup_module (void)
2070     {
2071     	unregister_blkdev(MAJOR_NR, "fd");
2072     
2073     	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
2074     	del_timer_sync(&fd_timer);
2075     	atari_stram_free( DMABuffer );
2076     }
2077     #endif
2078     
2079