1/*
2 *  linux/kernel/arch/arm/drivers/block/fd1772.c
3 *  Based on ataflop.c in the m68k Linux
4 *  Copyright (C) 1993  Greg Harp
5 *  Atari Support by Bjoern Brauel, Roman Hodek
6 *  Archimedes Support by Dave Gilbert (linux@treblig.org)
7 *
8 *  Big cleanup Sep 11..14 1994 Roman Hodek:
9 *   - Driver now works interrupt driven
10 *   - Support for two drives; should work, but I cannot test that :-(
11 *   - Reading is done in whole tracks and buffered to speed up things
12 *   - Disk change detection and drive deselecting after motor-off
13 *     similar to TOS
14 *   - Autodetection of disk format (DD/HD); untested yet, because I
15 *     don't have an HD drive :-(
16 *
17 *  Fixes Nov 13 1994 Martin Schaller:
18 *   - Autodetection works now
19 *   - Support for 5 1/4" disks
20 *   - Removed drive type (unknown on atari)
21 *   - Do seeks with 8 Mhz
22 *
23 *  Changes by Andreas Schwab:
24 *   - After errors in multiple read mode try again reading single sectors
25 *  (Feb 1995):
26 *   - Clean up error handling
27 *   - Set blk_size for proper size checking
28 *   - Initialize track register when testing presence of floppy
29 *   - Implement some ioctl's
30 *
31 *  Changes by Torsten Lang:
32 *   - When probing the floppies we should add the FDC1772CMDADD_H flag since
33 *     the FDC1772 will otherwise wait forever when no disk is inserted...
34 *
35 *  Things left to do:
36 *   - Formatting
37 *   - Maybe a better strategy for disk change detection (does anyone
38 *     know one?)
39 *   - There are some strange problems left: The strangest one is
40 *     that, at least on my TT (4+4MB), the first 2 Bytes of the last
41 *     page of the TT-Ram (!) change their contents (some bits get
42 *     set) while a floppy DMA is going on. But there are no accesses
43 *     to these memory locations from the kernel... (I tested that by
44 *     making the page read-only). I cannot explain what's going on...
45 *   - Sometimes the drive-change-detection stops to work. The
46 *     function is still called, but the WP bit always reads as 0...
47 *     Maybe a problem with the status reg mode or a timing problem.
48 *     Note 10/12/94: The change detection now seems to work reliably.
49 *     There is no proof, but I've seen no hang for a long time...
50 *
51 * ARCHIMEDES changes: (gilbertd@cs.man.ac.uk)
52 *     26/12/95 - Changed all names starting with FDC to FDC1772
53 *                Removed all references to clock speed of FDC - we're stuck with 8MHz
54 *                Modified disk_type structure to remove HD formats
55 *
56 *      7/ 1/96 - Wrote FIQ code, removed most remaining atariisms
57 *
58 *     13/ 1/96 - Well I think its read a single sector; but there is a problem
59 *                fd_rwsec_done which is called in FIQ mode starts another transfer
60 *                off (in fd_rwsec) while still in FIQ mode.  Because its still in
61 *                FIQ mode it can't service the DMA and loses data. So need to
62 *                heavily restructure.
63 *     14/ 1/96 - Found that the definitions of the register numbers of the
64 *                FDC were multiplied by 2 in the header for the 16bit words
65 *                of the atari so half the writes were going in the wrong place.
66 *                Also realised that the FIQ entry didn't make any attempt to
67 *                preserve registers or return correctly; now in assembler.
68 *
69 *     11/ 2/96 - Hmm - doesn't work on real machine.  Auto detect doesn't
70 *                and hacking that past seems to wait forever - check motor
71 *                being turned on.
72 *
73 *     17/ 2/96 - still having problems - forcing track to -1 when selecting
74 *                new drives seems to allow it to read first few sectors
75 *                but then we get solid hangs at apparently random places
76 *                which change depending what is happening.
77 *
78 *      9/ 3/96 - Fiddled a lot of stuff around to move to kernel 1.3.35
79 *                A lot of fiddling in DMA stuff. Having problems with it
80 *                constnatly thinking its timeing out. Ah - its timeout
81 *                was set to (6*HZ) rather than jiffies+(6*HZ).  Now giving
82 *                duff data!
83 *
84 *      5/ 4/96 - Made it use the new IOC_ macros rather than *ioc
85 *                Hmm - giving unexpected FIQ and then timeouts
86 *     18/ 8/96 - Ran through indent -kr -i8
87 *                Some changes to disc change detect; don't know how well it
88 *                works.
89 *     24/ 8/96 - Put all the track buffering code back in from the atari
90 *                code - I wonder if it will still work... No :-)
91 *                Still works if I turn off track buffering.
92 *     25/ 8/96 - Changed the timer expires that I'd added back to be
93 *                jiffies + ....; and it all sprang to life! Got 2.8K/sec
94 *                off a cp -r of a 679K disc (showed 94% cpu usage!)
95 *                (PC gets 14.3K/sec - 0% CPU!) Hmm - hard drive corrupt!
96 *                Also perhaps that compile was with cache off.
97 *                changed cli in fd_readtrack_check to cliIF
98 *                changed vmallocs to kmalloc (whats the difference!!)
99 *                Removed the busy wait loop in do_fd_request and replaced
100 *                by a routine on tq_immediate; only 11% cpu on a dd off the
101 *                raw disc - but the speed is the same.
102 *	1/ 9/96 - Idea (failed!) - set the 'disable spin-up sequence'
103 *		  when we read the track if we know the motor is on; didn't
104 *		  help - perhaps we have to do it in stepping as well.
105 *		  Nope. Still doesn't help.
106 *		  Hmm - what seems to be happening is that fd_readtrack_check
107 *		  is never getting called. Its job is to terminate the read
108 *		  just after we think we should have got the data; otherwise
109 *		  the fdc takes 1 second to timeout; which is what's happening
110 *		  Now I can see 'readtrack_timer' being set (which should do the
111 *		  call); but it never seems to be called - hmm!
112 *		  OK - I've moved the check to my tq_immediate code -
113 *		  and it WORKS! 13.95K/second at 19% CPU.
114 *		  I wish I knew why that timer didn't work.....
115 *
116 *     16/11/96 - Fiddled and frigged for 2.0.18
117 *
118 * DAG 30/01/99 - Started frobbing for 2.2.1
119 * DAG 20/06/99 - A little more frobbing:
120 *		  Included include/asm/uaccess.h for get_user/put_user
121 *
122 * DAG  1/09/00 - Dusted off for 2.4.0-test7
123 *                MAX_SECTORS was name clashing so it is now FD1772_...
124 *                Minor parameter, name layouts for 2.4.x differences
125 */
126
127#include <linux/sched.h>
128#include <linux/fs.h>
129#include <linux/fcntl.h>
130#include <linux/slab.h>
131#include <linux/kernel.h>
132#include <linux/interrupt.h>
133#include <linux/timer.h>
134#include <linux/workqueue.h>
135#include <linux/fd.h>
136#include <linux/fd1772.h>
137#include <linux/errno.h>
138#include <linux/types.h>
139#include <linux/delay.h>
140#include <linux/mm.h>
141#include <linux/bitops.h>
142
143#include <asm/arch/oldlatches.h>
144#include <asm/dma.h>
145#include <asm/hardware.h>
146#include <asm/hardware/ioc.h>
147#include <asm/io.h>
148#include <asm/irq.h>
149#include <asm/mach-types.h>
150#include <asm/pgtable.h>
151#include <asm/system.h>
152#include <asm/uaccess.h>
153
154
155/* Note: FD_MAX_UNITS could be redefined to 2 for the Atari (with
156 * little additional rework in this file). But I'm not yet sure if
157 * some other code depends on the number of floppies... (It is defined
158 * in a public header!)
159 */
160
161/* Ditto worries for Arc - DAG */
162#define FD_MAX_UNITS 4
163#define TRACKBUFFER 0
164/*#define DEBUG*/
165
166#ifdef DEBUG
167#define DPRINT(a)	printk a
168#else
169#define DPRINT(a)
170#endif
171
172static struct request_queue *floppy_queue;
173
174#define MAJOR_NR FLOPPY_MAJOR
175#define FLOPPY_DMA 0
176#define DEVICE_NAME "floppy"
177#define QUEUE (floppy_queue)
178#define CURRENT elv_next_request(floppy_queue)
179
180/* Disk types: DD */
181static struct archy_disk_type {
182	const char *name;
183	unsigned spt;		/* sectors per track */
184	unsigned blocks;	/* total number of blocks */
185	unsigned stretch;	/* track doubling ? */
186} disk_type[] = {
187
188	{ "d360", 9, 720, 0 },			/* 360kB diskette */
189	{ "D360", 9, 720, 1 },			/* 360kb in 720kb drive */
190	{ "D720", 9, 1440, 0 },			/* 720kb diskette (DD) */
191	/*{ "D820", 10,1640, 0}, *//* DD disk with 82 tracks/10 sectors
192	                              - DAG - can't see how type detect can distinguish this
193				      from 720K until it reads block 4 by which time its too late! */
194};
195
196#define	NUM_DISK_TYPES (sizeof(disk_type)/sizeof(*disk_type))
197
198/*
199 * Maximum disk size (in kilobytes). This default is used whenever the
200 * current disk size is unknown.
201 */
202#define MAX_DISK_SIZE 720
203
204static struct gendisk *disks[FD_MAX_UNIT];
205
206/* current info on each unit */
207static struct archy_floppy_struct {
208	int connected;		/* !=0 : drive is connected */
209	int autoprobe;		/* !=0 : do autoprobe       */
210
211	struct archy_disk_type *disktype;	/* current type of disk */
212
213	int track;		/* current head position or -1
214				   * if unknown */
215	unsigned int steprate;	/* steprate setting */
216	unsigned int wpstat;	/* current state of WP signal
217				   * (for disk change detection) */
218} unit[FD_MAX_UNITS];
219
220/* DAG: On Arc we spin on a flag being cleared by fdc1772_comendhandler which
221   is an assembler routine */
222extern void fdc1772_comendhandler(void);	/* Actually doens't have these parameters - see fd1772.S */
223extern volatile int fdc1772_comendstatus;
224extern volatile int fdc1772_fdc_int_done;
225
226#define FDC1772BASE ((0x210000>>2)|0x80000000)
227
228#define FDC1772_READ(reg) inb(FDC1772BASE+(reg/2))
229
230/* DAG: You wouldn't be silly to ask why FDC1772_WRITE is a function rather
231   than the #def below - well simple - the #def won't compile - and I
232   don't understand why (__outwc not defined) */
233/* NOTE: Reg is 0,2,4,6 as opposed to 0,1,2,3 or 0,4,8,12 to keep compatibility
234   with the ST version of fd1772.h */
235/*#define FDC1772_WRITE(reg,val) outw(val,(reg+FDC1772BASE)); */
236void FDC1772_WRITE(int reg, unsigned char val)
237{
238	if (reg == FDC1772REG_CMD) {
239		DPRINT(("FDC1772_WRITE new command 0x%x @ %d\n", val,jiffies));
240		if (fdc1772_fdc_int_done) {
241			DPRINT(("FDC1772_WRITE: Hmm fdc1772_fdc_int_done true - resetting\n"));
242			fdc1772_fdc_int_done = 0;
243		};
244	};
245	outb(val, (reg / 2) + FDC1772BASE);
246};
247
248#define	FD1772_MAX_SECTORS	22
249
250unsigned char *DMABuffer;	/* buffer for writes */
251/*static unsigned long PhysDMABuffer; *//* physical address */
252/* DAG: On Arc we just go straight for the DMA buffer */
253#define PhysDMABuffer DMABuffer
254
255#ifdef TRACKBUFFER
256unsigned char *TrackBuffer;       /* buffer for reads */
257#define PhysTrackBuffer TrackBuffer /* physical address */
258static int BufferDrive, BufferSide, BufferTrack;
259static int read_track;    /* non-zero if we are reading whole tracks */
260
261#define SECTOR_BUFFER(sec)  (TrackBuffer + ((sec)-1)*512)
262#define IS_BUFFERED(drive,side,track) \
263    (BufferDrive == (drive) && BufferSide == (side) && BufferTrack == (track))
264#endif
265
266/*
267 * These are global variables, as that's the easiest way to give
268 * information to interrupts. They are the data used for the current
269 * request.
270 */
271static int SelectedDrive = 0;
272static int ReqCmd, ReqBlock;
273static int ReqSide, ReqTrack, ReqSector, ReqCnt;
274static int HeadSettleFlag = 0;
275static unsigned char *ReqData, *ReqBuffer;
276static int MotorOn = 0, MotorOffTrys;
277
278/* Synchronization of FDC1772 access. */
279static volatile int fdc_busy = 0;
280static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
281
282
283/* long req'd for set_bit --RR */
284static unsigned long changed_floppies = 0xff, fake_change = 0;
285#define	CHECK_CHANGE_DELAY	HZ/2
286
287/* DAG - increased to 30*HZ - not sure if this is the correct thing to do */
288#define	FD_MOTOR_OFF_DELAY	(10*HZ)
289#define	FD_MOTOR_OFF_MAXTRY	(10*20)
290
291#define FLOPPY_TIMEOUT		(6*HZ)
292#define RECALIBRATE_ERRORS	4	/* After this many errors the drive
293					 * will be recalibrated. */
294#define MAX_ERRORS		8	/* After this many errors the driver
295					 * will give up. */
296
297#define	START_MOTOR_OFF_TIMER(delay)				\
298	do {							\
299		motor_off_timer.expires = jiffies + (delay);	\
300		add_timer( &motor_off_timer );			\
301		MotorOffTrys = 0;				\
302	} while(0)
303
304#define	START_CHECK_CHANGE_TIMER(delay)				\
305	do {							\
306	        mod_timer(&fd_timer, jiffies + (delay));	\
307	} while(0)
308
309#define	START_TIMEOUT()						\
310	do {							\
311		mod_timer(&timeout_timer, jiffies+FLOPPY_TIMEOUT); \
312	} while(0)
313
314#define	STOP_TIMEOUT()						\
315	do {							\
316		del_timer( &timeout_timer );			\
317	} while(0)
318
319#define ENABLE_IRQ() enable_irq(FIQ_FD1772+64);
320
321#define DISABLE_IRQ() disable_irq(FIQ_FD1772+64);
322
323static void fd1772_checkint(void);
324
325DECLARE_WORK(fd1772_tq, (void *)fd1772_checkint, NULL);
326/*
327 * The driver is trying to determine the correct media format
328 * while Probing is set. fd_rwsec_done() clears it after a
329 * successful access.
330 */
331static int Probing = 0;
332
333/* This flag is set when a dummy seek is necessary to make the WP
334 * status bit accessible.
335 */
336static int NeedSeek = 0;
337
338
339/***************************** Prototypes *****************************/
340
341static void fd_select_side(int side);
342static void fd_select_drive(int drive);
343static void fd_deselect(void);
344static void fd_motor_off_timer(unsigned long dummy);
345static void check_change(unsigned long dummy);
346static void floppy_irqconsequencehandler(void);
347static void fd_error(void);
348static void do_fd_action(int drive);
349static void fd_calibrate(void);
350static void fd_calibrate_done(int status);
351static void fd_seek(void);
352static void fd_seek_done(int status);
353static void fd_rwsec(void);
354#ifdef TRACKBUFFER
355static void fd_readtrack_check( unsigned long dummy );
356#endif
357static void fd_rwsec_done(int status);
358static void fd_times_out(unsigned long dummy);
359static void finish_fdc(void);
360static void finish_fdc_done(int dummy);
361static void floppy_off(unsigned int nr);
362static void setup_req_params(int drive);
363static void redo_fd_request(void);
364static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int
365		    cmd, unsigned long param);
366static void fd_probe(int drive);
367static int fd_test_drive_present(int drive);
368static void config_types(void);
369static int floppy_open(struct inode *inode, struct file *filp);
370static int floppy_release(struct inode *inode, struct file *filp);
371static void do_fd_request(request_queue_t *);
372
373/************************* End of Prototypes **************************/
374
375static DEFINE_TIMER(motor_off_timer, fd_motor_off_timer, 0, 0);
376
377#ifdef TRACKBUFFER
378static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0);
379#endif
380
381static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0);
382
383static DEFINE_TIMER(fd_timer, check_change, 0, 0);
384
385/* DAG: Haven't got a clue what this is? */
386int stdma_islocked(void)
387{
388	return 0;
389};
390
391/* Select the side to use. */
392
393static void fd_select_side(int side)
394{
395	oldlatch_aupdate(LATCHA_SIDESEL, side ? 0 : LATCHA_SIDESEL);
396}
397
398
399/* Select a drive, update the FDC1772's track register
400 */
401
402static void fd_select_drive(int drive)
403{
404#ifdef DEBUG
405	printk("fd_select_drive:%d\n", drive);
406#endif
407	/* Hmm - nowhere do we seem to turn the motor on - I'm going to do it here! */
408	oldlatch_aupdate(LATCHA_MOTOR | LATCHA_INUSE, 0);
409
410	if (drive == SelectedDrive)
411		return;
412
413	oldlatch_aupdate(LATCHA_FDSELALL, 0xf - (1 << drive));
414
415	/* restore track register to saved value */
416	FDC1772_WRITE(FDC1772REG_TRACK, unit[drive].track);
417	udelay(25);
418
419	SelectedDrive = drive;
420}
421
422
423/* Deselect both drives. */
424
425static void fd_deselect(void)
426{
427	unsigned long flags;
428
429	DPRINT(("fd_deselect\n"));
430
431	oldlatch_aupdate(LATCHA_FDSELALL | LATCHA_MOTOR | LATCHA_INUSE, 0xf | LATCHA_MOTOR | LATCHA_INUSE);
432
433	SelectedDrive = -1;
434}
435
436
437/* This timer function deselects the drives when the FDC1772 switched the
438 * motor off. The deselection cannot happen earlier because the FDC1772
439 * counts the index signals, which arrive only if one drive is selected.
440 */
441
442static void fd_motor_off_timer(unsigned long dummy)
443{
444	unsigned long flags;
445	unsigned char status;
446	int delay;
447
448	del_timer(&motor_off_timer);
449
450	if (SelectedDrive < 0)
451		/* no drive selected, needn't deselect anyone */
452		return;
453
454	save_flags(flags);
455	cli();
456
457	if (fdc_busy)		/* was stdma_islocked */
458		goto retry;
459
460	status = FDC1772_READ(FDC1772REG_STATUS);
461
462	if (!(status & 0x80)) {
463		/*
464		 * motor already turned off by FDC1772 -> deselect drives
465		 * In actual fact its this deselection which turns the motor
466		 * off on the Arc, since the motor control is actually on
467		 * Latch A
468		 */
469		DPRINT(("fdc1772: deselecting in fd_motor_off_timer\n"));
470		fd_deselect();
471		MotorOn = 0;
472		restore_flags(flags);
473		return;
474	}
475	/* not yet off, try again */
476
477retry:
478	restore_flags(flags);
479	/* Test again later; if tested too often, it seems there is no disk
480	 * in the drive and the FDC1772 will leave the motor on forever (or,
481	 * at least until a disk is inserted). So we'll test only twice
482	 * per second from then on...
483	 */
484	delay = (MotorOffTrys < FD_MOTOR_OFF_MAXTRY) ?
485	    (++MotorOffTrys, HZ / 20) : HZ / 2;
486	START_MOTOR_OFF_TIMER(delay);
487}
488
489
490/* This function is repeatedly called to detect disk changes (as good
491 * as possible) and keep track of the current state of the write protection.
492 */
493
494static void check_change(unsigned long dummy)
495{
496	static int drive = 0;
497
498	unsigned long flags;
499	int stat;
500
501	if (fdc_busy)
502		return;		/* Don't start poking about if the fdc is busy */
503
504	return;			/* let's just forget it for the mo DAG */
505
506	if (++drive > 1 || !unit[drive].connected)
507		drive = 0;
508
509	save_flags(flags);
510	cli();
511
512	if (!stdma_islocked()) {
513		stat = !!(FDC1772_READ(FDC1772REG_STATUS) & FDC1772STAT_WPROT);
514
515		/* The idea here is that if the write protect line has changed then
516		the disc must have changed */
517		if (stat != unit[drive].wpstat) {
518			DPRINT(("wpstat[%d] = %d\n", drive, stat));
519			unit[drive].wpstat = stat;
520			set_bit(drive, &changed_floppies);
521		}
522	}
523	restore_flags(flags);
524
525	START_CHECK_CHANGE_TIMER(CHECK_CHANGE_DELAY);
526}
527
528
529/* Handling of the Head Settling Flag: This flag should be set after each
530 * seek operation, because we don't use seeks with verify.
531 */
532
533static inline void set_head_settle_flag(void)
534{
535	HeadSettleFlag = FDC1772CMDADD_E;
536}
537
538static inline int get_head_settle_flag(void)
539{
540	int tmp = HeadSettleFlag;
541	HeadSettleFlag = 0;
542	return (tmp);
543}
544
545
546
547
548/* General Interrupt Handling */
549
550static inline void copy_buffer(void *from, void *to)
551{
552	ulong *p1 = (ulong *) from, *p2 = (ulong *) to;
553	int cnt;
554
555	for (cnt = 512 / 4; cnt; cnt--)
556		*p2++ = *p1++;
557}
558
559static void (*FloppyIRQHandler) (int status) = NULL;
560
561static void floppy_irqconsequencehandler(void)
562{
563	unsigned char status;
564	void (*handler) (int);
565
566	fdc1772_fdc_int_done = 0;
567
568	handler = FloppyIRQHandler;
569	FloppyIRQHandler = NULL;
570
571	if (handler) {
572		nop();
573		status = (unsigned char) fdc1772_comendstatus;
574		DPRINT(("FDC1772 irq, status = %02x handler = %08lx\n", (unsigned int) status, (unsigned long) handler));
575		handler(status);
576	} else {
577		DPRINT(("FDC1772 irq, no handler status=%02x\n", fdc1772_comendstatus));
578	}
579	DPRINT(("FDC1772 irq: end of floppy_irq\n"));
580}
581
582
583/* Error handling: If some error happened, retry some times, then
584 * recalibrate, then try again, and fail after MAX_ERRORS.
585 */
586
587static void fd_error(void)
588{
589	printk("FDC1772: fd_error\n");
590	/*panic("fd1772: fd_error"); *//* DAG tmp */
591	if (!CURRENT)
592		return;
593	CURRENT->errors++;
594	if (CURRENT->errors >= MAX_ERRORS) {
595		printk("fd%d: too many errors.\n", SelectedDrive);
596		end_request(CURRENT, 0);
597	} else if (CURRENT->errors == RECALIBRATE_ERRORS) {
598		printk("fd%d: recalibrating\n", SelectedDrive);
599		if (SelectedDrive != -1)
600			unit[SelectedDrive].track = -1;
601	}
602	redo_fd_request();
603}
604
605
606
607#define	SET_IRQ_HANDLER(proc) do { FloppyIRQHandler = (proc); } while(0)
608
609
610/* do_fd_action() is the general procedure for a fd request: All
611 * required parameter settings (drive select, side select, track
612 * position) are checked and set if needed. For each of these
613 * parameters and the actual reading or writing exist two functions:
614 * one that starts the setting (or skips it if possible) and one
615 * callback for the "done" interrupt. Each done func calls the next
616 * set function to propagate the request down to fd_rwsec_done().
617 */
618
619static void do_fd_action(int drive)
620{
621	struct request *req;
622	DPRINT(("do_fd_action unit[drive].track=%d\n", unit[drive].track));
623
624#ifdef TRACKBUFFER
625repeat:
626
627	if (IS_BUFFERED( drive, ReqSide, ReqTrack )) {
628		req = CURRENT;
629		if (ReqCmd == READ) {
630			copy_buffer( SECTOR_BUFFER(ReqSector), ReqData );
631			if (++ReqCnt < req->current_nr_sectors) {
632				/* read next sector */
633				setup_req_params( drive );
634				goto repeat;
635			} else {
636				/* all sectors finished */
637				req->nr_sectors -= req->current_nr_sectors;
638				req->sector += req->current_nr_sectors;
639				end_request(req, 1);
640				redo_fd_request();
641				return;
642			}
643		} else {
644			/* cmd == WRITE, pay attention to track buffer
645			 * consistency! */
646			copy_buffer( ReqData, SECTOR_BUFFER(ReqSector) );
647		}
648	}
649#endif
650
651	if (SelectedDrive != drive) {
652		/*unit[drive].track = -1; DAG */
653		fd_select_drive(drive);
654	};
655
656
657	if (unit[drive].track == -1)
658		fd_calibrate();
659	else if (unit[drive].track != ReqTrack << unit[drive].disktype->stretch)
660		fd_seek();
661	else
662		fd_rwsec();
663}
664
665
666/* Seek to track 0 if the current track is unknown */
667
668static void fd_calibrate(void)
669{
670	DPRINT(("fd_calibrate\n"));
671	if (unit[SelectedDrive].track >= 0) {
672		fd_calibrate_done(0);
673		return;
674	}
675	DPRINT(("fd_calibrate (after track compare)\n"));
676	SET_IRQ_HANDLER(fd_calibrate_done);
677	/* we can't verify, since the speed may be incorrect */
678	FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_RESTORE | unit[SelectedDrive].steprate);
679
680	NeedSeek = 1;
681	MotorOn = 1;
682	START_TIMEOUT();
683	/* wait for IRQ */
684}
685
686
687static void fd_calibrate_done(int status)
688{
689	DPRINT(("fd_calibrate_done()\n"));
690	STOP_TIMEOUT();
691
692	/* set the correct speed now */
693	if (status & FDC1772STAT_RECNF) {
694		printk("fd%d: restore failed\n", SelectedDrive);
695		fd_error();
696	} else {
697		unit[SelectedDrive].track = 0;
698		fd_seek();
699	}
700}
701
702
703/* Seek the drive to the requested track. The drive must have been
704 * calibrated at some point before this.
705 */
706
707static void fd_seek(void)
708{
709	unsigned long flags;
710	DPRINT(("fd_seek() to track %d (unit[SelectedDrive].track=%d)\n", ReqTrack,
711		unit[SelectedDrive].track));
712	if (unit[SelectedDrive].track == ReqTrack <<
713	    unit[SelectedDrive].disktype->stretch) {
714		fd_seek_done(0);
715		return;
716	}
717	FDC1772_WRITE(FDC1772REG_DATA, ReqTrack <<
718		      unit[SelectedDrive].disktype->stretch);
719	udelay(25);
720	save_flags(flags);
721	clf();
722	SET_IRQ_HANDLER(fd_seek_done);
723	FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_SEEK | unit[SelectedDrive].steprate |
724		/* DAG */
725		(MotorOn?FDC1772CMDADD_H:0));
726
727	restore_flags(flags);
728	MotorOn = 1;
729	set_head_settle_flag();
730	START_TIMEOUT();
731	/* wait for IRQ */
732}
733
734
735static void fd_seek_done(int status)
736{
737	DPRINT(("fd_seek_done()\n"));
738	STOP_TIMEOUT();
739
740	/* set the correct speed */
741	if (status & FDC1772STAT_RECNF) {
742		printk("fd%d: seek error (to track %d)\n",
743		       SelectedDrive, ReqTrack);
744		/* we don't know exactly which track we are on now! */
745		unit[SelectedDrive].track = -1;
746		fd_error();
747	} else {
748		unit[SelectedDrive].track = ReqTrack <<
749		    unit[SelectedDrive].disktype->stretch;
750		NeedSeek = 0;
751		fd_rwsec();
752	}
753}
754
755
756/* This does the actual reading/writing after positioning the head
757 * over the correct track.
758 */
759
760#ifdef TRACKBUFFER
761static int MultReadInProgress = 0;
762#endif
763
764
765static void fd_rwsec(void)
766{
767	unsigned long paddr, flags;
768	unsigned int rwflag, old_motoron;
769	unsigned int track;
770
771	DPRINT(("fd_rwsec(), Sec=%d, Access=%c\n", ReqSector, ReqCmd == WRITE ? 'w' : 'r'));
772	if (ReqCmd == WRITE) {
773		/*cache_push( (unsigned long)ReqData, 512 ); */
774		paddr = (unsigned long) ReqData;
775		rwflag = 0x100;
776	} else {
777		paddr = (unsigned long) PhysDMABuffer;
778#ifdef TRACKBUFFER
779		if (read_track)
780			paddr = (unsigned long)PhysTrackBuffer;
781#endif
782		rwflag = 0;
783	}
784
785	DPRINT(("fd_rwsec() before sidesel rwflag=%d sec=%d trk=%d\n", rwflag,
786		ReqSector, FDC1772_READ(FDC1772REG_TRACK)));
787	fd_select_side(ReqSide);
788
789	/*DPRINT(("fd_rwsec() before start sector \n")); */
790	/* Start sector of this operation */
791#ifdef TRACKBUFFER
792	FDC1772_WRITE( FDC1772REG_SECTOR, !read_track ? ReqSector : 1 );
793#else
794	FDC1772_WRITE( FDC1772REG_SECTOR, ReqSector );
795#endif
796
797	/* Cheat for track if stretch != 0 */
798	if (unit[SelectedDrive].disktype->stretch) {
799		track = FDC1772_READ(FDC1772REG_TRACK);
800		FDC1772_WRITE(FDC1772REG_TRACK, track >>
801			      unit[SelectedDrive].disktype->stretch);
802	}
803	udelay(25);
804
805	DPRINT(("fd_rwsec() before setup DMA \n"));
806	/* Setup DMA - Heavily modified by DAG */
807	save_flags(flags);
808	clf();
809	disable_dma(FLOPPY_DMA);
810	set_dma_mode(FLOPPY_DMA, rwflag ? DMA_MODE_WRITE : DMA_MODE_READ);
811	set_dma_addr(FLOPPY_DMA, (long) paddr);		/* DAG - changed from Atari specific */
812#ifdef TRACKBUFFER
813	set_dma_count(FLOPPY_DMA,(!read_track ? 1 : unit[SelectedDrive].disktype->spt)*512);
814#else
815	set_dma_count(FLOPPY_DMA, 512);		/* Block/sector size - going to have to change */
816#endif
817	SET_IRQ_HANDLER(fd_rwsec_done);
818	/* Turn on dma int */
819	enable_dma(FLOPPY_DMA);
820	/* Now give it something to do */
821	FDC1772_WRITE(FDC1772REG_CMD, (rwflag ? (FDC1772CMD_WRSEC | FDC1772CMDADD_P) :
822#ifdef TRACKBUFFER
823	      (FDC1772CMD_RDSEC | (read_track ? FDC1772CMDADD_M : 0) |
824	      /* Hmm - the idea here is to stop the FDC spinning the disc
825	      up when we know that we already still have it spinning */
826	      (MotorOn?FDC1772CMDADD_H:0))
827#else
828	      FDC1772CMD_RDSEC
829#endif
830		));
831
832	restore_flags(flags);
833	DPRINT(("fd_rwsec() after DMA setup flags=0x%08x\n", flags));
834	/*sti(); *//* DAG - Hmm */
835	/* Hmm - should do something DAG */
836	old_motoron = MotorOn;
837	MotorOn = 1;
838	NeedSeek = 1;
839
840	/* wait for interrupt */
841
842#ifdef TRACKBUFFER
843	if (read_track) {
844		/*
845		 * If reading a whole track, wait about one disk rotation and
846		 * then check if all sectors are read. The FDC will even
847		 * search for the first non-existant sector and need 1 sec to
848		 * recognise that it isn't present :-(
849		 */
850		/* 1 rot. + 5 rot.s if motor was off  */
851		mod_timer(&readtrack_timer, jiffies + HZ/5 + (old_motoron ? 0 : HZ));
852		DPRINT(("Setting readtrack_timer to %d @ %d\n",
853			readtrack_timer.expires,jiffies));
854		MultReadInProgress = 1;
855	}
856#endif
857
858	/*DPRINT(("fd_rwsec() before START_TIMEOUT \n")); */
859	START_TIMEOUT();
860	/*DPRINT(("fd_rwsec() after START_TIMEOUT \n")); */
861}
862
863
864#ifdef TRACKBUFFER
865
866static void fd_readtrack_check(unsigned long dummy)
867{
868	unsigned long flags, addr;
869	extern unsigned char *fdc1772_dataaddr;
870
871	DPRINT(("fd_readtrack_check @ %d\n",jiffies));
872
873	save_flags(flags);
874	clf();
875
876	del_timer( &readtrack_timer );
877
878	if (!MultReadInProgress) {
879		/* This prevents a race condition that could arise if the
880		 * interrupt is triggered while the calling of this timer
881		 * callback function takes place. The IRQ function then has
882		 * already cleared 'MultReadInProgress'  when control flow
883		 * gets here.
884		 */
885		restore_flags(flags);
886		return;
887	}
888
889	/* get the current DMA address */
890	addr=(unsigned long)fdc1772_dataaddr; /* DAG - ? */
891	DPRINT(("fd_readtrack_check: addr=%x PhysTrackBuffer=%x\n",addr,PhysTrackBuffer));
892
893	if (addr >= (unsigned int)PhysTrackBuffer + unit[SelectedDrive].disktype->spt*512) {
894		/* already read enough data, force an FDC interrupt to stop
895		 * the read operation
896		 */
897		SET_IRQ_HANDLER( NULL );
898		restore_flags(flags);
899		DPRINT(("fd_readtrack_check(): done\n"));
900		FDC1772_WRITE( FDC1772REG_CMD, FDC1772CMD_FORCI );
901		udelay(25);
902
903		/* No error until now -- the FDC would have interrupted
904		 * otherwise!
905		 */
906		fd_rwsec_done( 0 );
907	} else {
908		/* not yet finished, wait another tenth rotation */
909		restore_flags(flags);
910		DPRINT(("fd_readtrack_check(): not yet finished\n"));
911		readtrack_timer.expires = jiffies + HZ/5/10;
912		add_timer( &readtrack_timer );
913	}
914}
915
916#endif
917
918static void fd_rwsec_done(int status)
919{
920	unsigned int track;
921
922	DPRINT(("fd_rwsec_done() status=%d @ %d\n", status,jiffies));
923
924#ifdef TRACKBUFFER
925	if (read_track && !MultReadInProgress)
926		return;
927
928	MultReadInProgress = 0;
929
930	STOP_TIMEOUT();
931
932	if (read_track)
933		del_timer( &readtrack_timer );
934#endif
935
936
937	/* Correct the track if stretch != 0 */
938	if (unit[SelectedDrive].disktype->stretch) {
939		track = FDC1772_READ(FDC1772REG_TRACK);
940		FDC1772_WRITE(FDC1772REG_TRACK, track <<
941			      unit[SelectedDrive].disktype->stretch);
942	}
943	if (ReqCmd == WRITE && (status & FDC1772STAT_WPROT)) {
944		printk("fd%d: is write protected\n", SelectedDrive);
945		goto err_end;
946	}
947	if ((status & FDC1772STAT_RECNF)
948#ifdef TRACKBUFFER
949	    /* RECNF is no error after a multiple read when the FDC
950	     * searched for a non-existant sector!
951	     */
952	    && !(read_track &&
953	       FDC1772_READ(FDC1772REG_SECTOR) > unit[SelectedDrive].disktype->spt)
954#endif
955	    ) {
956		if (Probing) {
957			if (unit[SelectedDrive].disktype > disk_type) {
958				/* try another disk type */
959				unit[SelectedDrive].disktype--;
960				set_capacity(disks[SelectedDrive],
961				    unit[SelectedDrive].disktype->blocks);
962			} else
963				Probing = 0;
964		} else {
965			/* record not found, but not probing. Maybe stretch wrong ? Restart probing */
966			if (unit[SelectedDrive].autoprobe) {
967				unit[SelectedDrive].disktype = disk_type + NUM_DISK_TYPES - 1;
968				set_capacity(disks[SelectedDrive],
969				    unit[SelectedDrive].disktype->blocks);
970				Probing = 1;
971			}
972		}
973		if (Probing) {
974			setup_req_params(SelectedDrive);
975#ifdef TRACKBUFFER
976			BufferDrive = -1;
977#endif
978			do_fd_action(SelectedDrive);
979			return;
980		}
981		printk("fd%d: sector %d not found (side %d, track %d)\n",
982		       SelectedDrive, FDC1772_READ(FDC1772REG_SECTOR), ReqSide, ReqTrack);
983		goto err_end;
984	}
985	if (status & FDC1772STAT_CRC) {
986		printk("fd%d: CRC error (side %d, track %d, sector %d)\n",
987		       SelectedDrive, ReqSide, ReqTrack, FDC1772_READ(FDC1772REG_SECTOR));
988		goto err_end;
989	}
990	if (status & FDC1772STAT_LOST) {
991		printk("fd%d: lost data (side %d, track %d, sector %d)\n",
992		       SelectedDrive, ReqSide, ReqTrack, FDC1772_READ(FDC1772REG_SECTOR));
993		goto err_end;
994	}
995	Probing = 0;
996
997	if (ReqCmd == READ) {
998#ifdef TRACKBUFFER
999		if (!read_track) {
1000			/*cache_clear (PhysDMABuffer, 512);*/
1001			copy_buffer (DMABuffer, ReqData);
1002		} else {
1003			/*cache_clear (PhysTrackBuffer, FD1772_MAX_SECTORS * 512);*/
1004			BufferDrive = SelectedDrive;
1005			BufferSide  = ReqSide;
1006			BufferTrack = ReqTrack;
1007			copy_buffer (SECTOR_BUFFER (ReqSector), ReqData);
1008		}
1009#else
1010		/*cache_clear( PhysDMABuffer, 512 ); */
1011		copy_buffer(DMABuffer, ReqData);
1012#endif
1013	}
1014	if (++ReqCnt < CURRENT->current_nr_sectors) {
1015		/* read next sector */
1016		setup_req_params(SelectedDrive);
1017		do_fd_action(SelectedDrive);
1018	} else {
1019		/* all sectors finished */
1020		CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
1021		CURRENT->sector += CURRENT->current_nr_sectors;
1022		end_request(CURRENT, 1);
1023		redo_fd_request();
1024	}
1025	return;
1026
1027err_end:
1028#ifdef TRACKBUFFER
1029	BufferDrive = -1;
1030#endif
1031
1032	fd_error();
1033}
1034
1035
1036static void fd_times_out(unsigned long dummy)
1037{
1038	SET_IRQ_HANDLER(NULL);
1039	/* If the timeout occurred while the readtrack_check timer was
1040	 * active, we need to cancel it, else bad things will happen */
1041	del_timer( &readtrack_timer );
1042	FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_FORCI);
1043	udelay(25);
1044
1045	printk("floppy timeout\n");
1046	STOP_TIMEOUT();		/* hmm - should we do this ? */
1047	fd_error();
1048}
1049
1050
1051/* The (noop) seek operation here is needed to make the WP bit in the
1052 * FDC1772 status register accessible for check_change. If the last disk
1053 * operation would have been a RDSEC, this bit would always read as 0
1054 * no matter what :-( To save time, the seek goes to the track we're
1055 * already on.
1056 */
1057
1058static void finish_fdc(void)
1059{
1060	/* DAG - just try without this dummy seek! */
1061	finish_fdc_done(0);
1062	return;
1063
1064	if (!NeedSeek) {
1065		finish_fdc_done(0);
1066	} else {
1067		DPRINT(("finish_fdc: dummy seek started\n"));
1068		FDC1772_WRITE(FDC1772REG_DATA, unit[SelectedDrive].track);
1069		SET_IRQ_HANDLER(finish_fdc_done);
1070		FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_SEEK);
1071		MotorOn = 1;
1072		START_TIMEOUT();
1073		/* we must wait for the IRQ here, because the ST-DMA is
1074		 * released immediately afterwards and the interrupt may be
1075		 * delivered to the wrong driver.
1076		 */
1077	}
1078}
1079
1080
1081static void finish_fdc_done(int dummy)
1082{
1083	unsigned long flags;
1084
1085	DPRINT(("finish_fdc_done entered\n"));
1086	STOP_TIMEOUT();
1087	NeedSeek = 0;
1088
1089	if (timer_pending(&fd_timer) &&
1090	    time_after(jiffies + 5, fd_timer.expires))
1091		/* If the check for a disk change is done too early after this
1092		 * last seek command, the WP bit still reads wrong :-((
1093		 */
1094		mod_timer(&fd_timer, jiffies + 5);
1095	else {
1096		/*      START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY ); */
1097	};
1098	del_timer(&motor_off_timer);
1099	START_MOTOR_OFF_TIMER(FD_MOTOR_OFF_DELAY);
1100
1101	save_flags(flags);
1102	cli();
1103	/* stdma_release(); - not sure if I should do something DAG  */
1104	fdc_busy = 0;
1105	wake_up(&fdc_wait);
1106	restore_flags(flags);
1107
1108	DPRINT(("finish_fdc() finished\n"));
1109}
1110
1111
1112/* Prevent "aliased" accesses. */
1113static int fd_ref[4];
1114static int fd_device[4];
1115
1116/* dummy for blk.h */
1117static void floppy_off(unsigned int nr)
1118{
1119}
1120
1121
1122/* On the old arcs write protect depends on the particular model
1123   of machine.  On the A310, R140, and A440 there is a disc changed
1124   detect, however on the A4x0/1 range there is not.  There
1125   is nothing to tell you which machine your on.
1126   At the moment I'm just marking changed always. I've
1127   left the Atari's 'change on write protect change' code in this
1128   part (but nothing sets it).
1129   RiscOS apparently checks the disc serial number etc. to detect changes
1130   - but if it sees a disc change line go high (?) it flips to using
1131   it. Well  maybe I'll add that in the future (!?)
1132*/
1133static int check_floppy_change(struct gendisk *disk)
1134{
1135	struct archy_floppy_struct *p = disk->private_data;
1136	unsigned int drive = p - unit;
1137
1138	if (test_bit(drive, &fake_change)) {
1139		/* simulated change (e.g. after formatting) */
1140		return 1;
1141	}
1142	if (test_bit(drive, &changed_floppies)) {
1143		/* surely changed (the WP signal changed at least once) */
1144		return 1;
1145	}
1146	if (p->wpstat) {
1147		/* WP is on -> could be changed: to be sure, buffers should be
1148		   * invalidated...
1149		 */
1150		return 1;
1151	}
1152	return 1; /* DAG - was 0 */
1153}
1154
1155static int floppy_revalidate(struct gendisk *disk)
1156{
1157	struct archy_floppy_struct *p = disk->private_data;
1158	unsigned int drive = p - unit;
1159
1160	if (test_bit(drive, &changed_floppies) || test_bit(drive, &fake_change)
1161	    || unit[drive].disktype == 0) {
1162#ifdef TRACKBUFFER
1163		BufferDrive = -1;
1164#endif
1165		clear_bit(drive, &fake_change);
1166		clear_bit(drive, &changed_floppies);
1167		p->disktype = 0;
1168	}
1169	return 0;
1170}
1171
1172/* This sets up the global variables describing the current request. */
1173
1174static void setup_req_params(int drive)
1175{
1176	int block = ReqBlock + ReqCnt;
1177
1178	ReqTrack = block / unit[drive].disktype->spt;
1179	ReqSector = block - ReqTrack * unit[drive].disktype->spt + 1;
1180	ReqSide = ReqTrack & 1;
1181	ReqTrack >>= 1;
1182	ReqData = ReqBuffer + 512 * ReqCnt;
1183
1184#ifdef TRACKBUFFER
1185	read_track = (ReqCmd == READ && CURRENT->errors == 0);
1186#endif
1187
1188	DPRINT(("Request params: Si=%d Tr=%d Se=%d Data=%08lx\n", ReqSide,
1189		ReqTrack, ReqSector, (unsigned long) ReqData));
1190}
1191
1192
1193static void redo_fd_request(void)
1194{
1195	int drive, type;
1196	struct archy_floppy_struct *floppy;
1197
1198	DPRINT(("redo_fd_request: CURRENT=%p dev=%s CURRENT->sector=%ld\n",
1199		CURRENT, CURRENT ? CURRENT->rq_disk->disk_name : "",
1200		CURRENT ? CURRENT->sector : 0));
1201
1202repeat:
1203
1204	if (!CURRENT)
1205		goto the_end;
1206
1207	floppy = CURRENT->rq_disk->private_data;
1208	drive = floppy - unit;
1209	type = fd_device[drive];
1210
1211	if (!floppy->connected) {
1212		/* drive not connected */
1213		printk("Unknown Device: fd%d\n", drive);
1214		end_request(CURRENT, 0);
1215		goto repeat;
1216	}
1217	if (type == 0) {
1218		if (!floppy->disktype) {
1219			Probing = 1;
1220			floppy->disktype = disk_type + NUM_DISK_TYPES - 1;
1221			set_capacity(disks[drive], floppy->disktype->blocks);
1222			floppy->autoprobe = 1;
1223		}
1224	} else {
1225		/* user supplied disk type */
1226		--type;
1227		if (type >= NUM_DISK_TYPES) {
1228			printk("fd%d: invalid disk format", drive);
1229			end_request(CURRENT, 0);
1230			goto repeat;
1231		}
1232		floppy->disktype = &disk_type[type];
1233		set_capacity(disks[drive], floppy->disktype->blocks);
1234		floppy->autoprobe = 0;
1235	}
1236
1237	if (CURRENT->sector + 1 > floppy->disktype->blocks) {
1238		end_request(CURRENT, 0);
1239		goto repeat;
1240	}
1241	/* stop deselect timer */
1242	del_timer(&motor_off_timer);
1243
1244	ReqCnt = 0;
1245	ReqCmd = CURRENT->cmd;
1246	ReqBlock = CURRENT->sector;
1247	ReqBuffer = CURRENT->buffer;
1248	setup_req_params(drive);
1249	do_fd_action(drive);
1250
1251	return;
1252
1253the_end:
1254	finish_fdc();
1255}
1256
1257static void fd1772_checkint(void)
1258{
1259	extern int fdc1772_bytestogo;
1260
1261	/*printk("fd1772_checkint %d\n",fdc1772_fdc_int_done);*/
1262	if (fdc1772_fdc_int_done)
1263		floppy_irqconsequencehandler();
1264	if ((MultReadInProgress) && (fdc1772_bytestogo==0)) fd_readtrack_check(0);
1265	if (fdc_busy) {
1266		schedule_work(&fd1772_tq);
1267	}
1268}
1269
1270static void do_fd_request(request_queue_t* q)
1271{
1272	unsigned long flags;
1273
1274	DPRINT(("do_fd_request for pid %d\n", current->pid));
1275	if (fdc_busy) return;
1276	save_flags(flags);
1277	cli();
1278	wait_event(fdc_wait, !fdc_busy);
1279	fdc_busy = 1;
1280	ENABLE_IRQ();
1281	restore_flags(flags);
1282
1283	fdc1772_fdc_int_done = 0;
1284
1285	redo_fd_request();
1286
1287	schedule_work(&fd1772_tq);
1288}
1289
1290
1291static int invalidate_drive(struct block_device *bdev)
1292{
1293	struct archy_floppy_struct *p = bdev->bd_disk->private_data;
1294	/* invalidate the buffer track to force a reread */
1295#ifdef TRACKBUFFER
1296	BufferDrive = -1;
1297#endif
1298
1299	set_bit(p - unit, &fake_change);
1300	return 0;
1301}
1302
1303static int fd_ioctl(struct inode *inode, struct file *filp,
1304		    unsigned int cmd, unsigned long param)
1305{
1306	struct block_device *bdev = inode->i_bdev;
1307
1308	switch (cmd) {
1309	case FDFMTEND:
1310	case FDFLUSH:
1311		invalidate_drive(bdev);
1312		check_disk_change(bdev);
1313	case FDFMTBEG:
1314		return 0;
1315	default:
1316		return -EINVAL;
1317	}
1318}
1319
1320
1321/* Initialize the 'unit' variable for drive 'drive' */
1322
1323static void fd_probe(int drive)
1324{
1325	unit[drive].connected = 0;
1326	unit[drive].disktype = NULL;
1327
1328	if (!fd_test_drive_present(drive))
1329		return;
1330
1331	unit[drive].connected = 1;
1332	unit[drive].track = -1; /* If we put the auto detect back in this can go to 0 */
1333	unit[drive].steprate = FDC1772STEP_6;
1334	MotorOn = 1;		/* from probe restore operation! */
1335}
1336
1337
1338/* This function tests the physical presence of a floppy drive (not
1339 * whether a disk is inserted). This is done by issuing a restore
1340 * command, waiting max. 2 seconds (that should be enough to move the
1341 * head across the whole disk) and looking at the state of the "TR00"
1342 * signal. This should now be raised if there is a drive connected
1343 * (and there is no hardware failure :-) Otherwise, the drive is
1344 * declared absent.
1345 */
1346
1347static int fd_test_drive_present(int drive)
1348{
1349	unsigned long timeout;
1350	unsigned char status;
1351	int ok;
1352
1353	printk("fd_test_drive_present %d\n", drive);
1354	if (drive > 1)
1355		return (0);
1356	return (1);		/* Simple hack for the moment - the autodetect doesn't seem to work on arc */
1357	fd_select_drive(drive);
1358
1359	/* disable interrupt temporarily */
1360	DISABLE_IRQ();
1361	FDC1772_WRITE(FDC1772REG_TRACK, 0x00);	/* was ff00 why? */
1362	FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_RESTORE | FDC1772CMDADD_H | FDC1772STEP_6);
1363
1364	/*printk("fd_test_drive_present: Going into timeout loop\n"); */
1365	for (ok = 0, timeout = jiffies + 2 * HZ + HZ / 2; time_before(jiffies, timeout);) {
1366		/*  What does this piece of atariism do? - query for an interrupt? */
1367		/*  if (!(mfp.par_dt_reg & 0x20))
1368		   break; */
1369		/* Well this is my nearest guess - quit when we get an FDC interrupt */
1370		if (ioc_readb(IOC_FIQSTAT) & 2)
1371			break;
1372	}
1373
1374	/*printk("fd_test_drive_present: Coming out of timeout loop\n"); */
1375	status = FDC1772_READ(FDC1772REG_STATUS);
1376	ok = (status & FDC1772STAT_TR00) != 0;
1377
1378	/*printk("fd_test_drive_present: ok=%d\n",ok); */
1379	/* force interrupt to abort restore operation (FDC1772 would try
1380	 * about 50 seconds!) */
1381	FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_FORCI);
1382	udelay(500);
1383	status = FDC1772_READ(FDC1772REG_STATUS);
1384	udelay(20);
1385	/*printk("fd_test_drive_present: just before OK code %d\n",ok); */
1386
1387	if (ok) {
1388		/* dummy seek command to make WP bit accessible */
1389		FDC1772_WRITE(FDC1772REG_DATA, 0);
1390		FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_SEEK);
1391		printk("fd_test_drive_present: just before wait for int\n");
1392		/* DAG: Guess means wait for interrupt */
1393		while (!(ioc_readb(IOC_FIQSTAT) & 2));
1394		printk("fd_test_drive_present: just after wait for int\n");
1395		status = FDC1772_READ(FDC1772REG_STATUS);
1396	}
1397	printk("fd_test_drive_present: just before ENABLE_IRQ\n");
1398	ENABLE_IRQ();
1399	printk("fd_test_drive_present: about to return\n");
1400	return (ok);
1401}
1402
1403
1404/* Look how many and which kind of drives are connected. If there are
1405 * floppies, additionally start the disk-change and motor-off timers.
1406 */
1407
1408static void config_types(void)
1409{
1410	int drive, cnt = 0;
1411
1412	printk("Probing floppy drive(s):\n");
1413	for (drive = 0; drive < FD_MAX_UNITS; drive++) {
1414		fd_probe(drive);
1415		if (unit[drive].connected) {
1416			printk("fd%d\n", drive);
1417			++cnt;
1418		}
1419	}
1420
1421	if (FDC1772_READ(FDC1772REG_STATUS) & FDC1772STAT_BUSY) {
1422		/* If FDC1772 is still busy from probing, give it another FORCI
1423		 * command to abort the operation. If this isn't done, the FDC1772
1424		 * will interrupt later and its IRQ line stays low, because
1425		 * the status register isn't read. And this will block any
1426		 * interrupts on this IRQ line :-(
1427		 */
1428		FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_FORCI);
1429		udelay(500);
1430		FDC1772_READ(FDC1772REG_STATUS);
1431		udelay(20);
1432	}
1433	if (cnt > 0) {
1434		START_MOTOR_OFF_TIMER(FD_MOTOR_OFF_DELAY);
1435		if (cnt == 1)
1436			fd_select_drive(0);
1437		/*START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY ); */
1438	}
1439}
1440
1441/*
1442 * floppy_open check for aliasing (/dev/fd0 can be the same as
1443 * /dev/PS0 etc), and disallows simultaneous access to the same
1444 * drive with different device numbers.
1445 */
1446
1447static int floppy_open(struct inode *inode, struct file *filp)
1448{
1449	int drive = iminor(inode) & 3;
1450	int type =  iminor(inode) >> 2;
1451	int old_dev = fd_device[drive];
1452
1453	if (fd_ref[drive] && old_dev != type)
1454		return -EBUSY;
1455
1456	if (fd_ref[drive] == -1 || (fd_ref[drive] && filp->f_flags & O_EXCL))
1457		return -EBUSY;
1458
1459	if (filp->f_flags & O_EXCL)
1460		fd_ref[drive] = -1;
1461	else
1462		fd_ref[drive]++;
1463
1464	fd_device[drive] = type;
1465
1466	if (filp->f_flags & O_NDELAY)
1467		return 0;
1468
1469	if (filp->f_mode & 3) {
1470		check_disk_change(inode->i_bdev);
1471		if (filp->f_mode & 2) {
1472			if (unit[drive].wpstat) {
1473				floppy_release(inode, filp);
1474				return -EROFS;
1475			}
1476		}
1477	}
1478	return 0;
1479}
1480
1481
1482static int floppy_release(struct inode *inode, struct file *filp)
1483{
1484	int drive = iminor(inode) & 3;
1485
1486	if (fd_ref[drive] < 0)
1487		fd_ref[drive] = 0;
1488	else if (!fd_ref[drive]--) {
1489		printk("floppy_release with fd_ref == 0");
1490		fd_ref[drive] = 0;
1491	}
1492
1493	return 0;
1494}
1495
1496static struct block_device_operations floppy_fops =
1497{
1498	.open		= floppy_open,
1499	.release	= floppy_release,
1500	.ioctl		= fd_ioctl,
1501	.media_changed	= check_floppy_change,
1502	.revalidate_disk= floppy_revalidate,
1503};
1504
1505static struct kobject *floppy_find(dev_t dev, int *part, void *data)
1506{
1507	int drive = *part & 3;
1508	if ((*part >> 2) > NUM_DISK_TYPES || drive >= FD_MAX_UNITS)
1509		return NULL;
1510	*part = 0;
1511	return get_disk(disks[drive]);
1512}
1513
1514int fd1772_init(void)
1515{
1516	static DEFINE_SPINLOCK(lock);
1517	int i, err = -ENOMEM;
1518
1519	if (!machine_is_archimedes())
1520		return 0;
1521
1522	for (i = 0; i < FD_MAX_UNITS; i++) {
1523		disks[i] = alloc_disk(1);
1524		if (!disks[i])
1525			goto err_disk;
1526	}
1527
1528	err = register_blkdev(MAJOR_NR, "fd");
1529	if (err)
1530		goto err_disk;
1531
1532	err = -EBUSY;
1533	if (request_dma(FLOPPY_DMA, "fd1772")) {
1534		printk("Unable to grab DMA%d for the floppy (1772) driver\n", FLOPPY_DMA);
1535		goto err_blkdev;
1536	};
1537
1538	if (request_dma(FIQ_FD1772, "fd1772 end")) {
1539		printk("Unable to grab DMA%d for the floppy (1772) driver\n", FIQ_FD1772);
1540		goto err_dma1;
1541	};
1542
1543	/* initialize variables */
1544	SelectedDrive = -1;
1545#ifdef TRACKBUFFER
1546	BufferDrive = BufferSide = BufferTrack = -1;
1547	/* Atari uses 512 - I want to eventually cope with 1K sectors */
1548	DMABuffer = kmalloc((FD1772_MAX_SECTORS+1)*512,GFP_KERNEL);
1549	TrackBuffer = DMABuffer + 512;
1550#else
1551	/* Allocate memory for the DMAbuffer - on the Atari this takes it
1552	   out of some special memory... */
1553	DMABuffer = kmalloc(2048);	/* Copes with pretty large sectors */
1554#endif
1555	err = -ENOMEM;
1556	if (!DMAbuffer)
1557		goto err_dma2;
1558
1559	enable_dma(FIQ_FD1772);	/* This inserts a call to our command end routine */
1560
1561	floppy_queue = blk_init_queue(do_fd_request, &lock);
1562	if (!floppy_queue)
1563		goto err_queue;
1564
1565	for (i = 0; i < FD_MAX_UNITS; i++) {
1566		unit[i].track = -1;
1567		disks[i]->major = MAJOR_NR;
1568		disks[i]->first_minor = 0;
1569		disks[i]->fops = &floppy_fops;
1570		sprintf(disks[i]->disk_name, "fd%d", i);
1571		disks[i]->private_data = &unit[i];
1572		disks[i]->queue = floppy_queue;
1573		set_capacity(disks[i], MAX_DISK_SIZE * 2);
1574	}
1575	blk_register_region(MKDEV(MAJOR_NR, 0), 256, THIS_MODULE,
1576				floppy_find, NULL, NULL);
1577
1578	for (i = 0; i < FD_MAX_UNITS; i++)
1579		add_disk(disks[i]);
1580
1581	config_types();
1582
1583	return 0;
1584
1585 err_queue:
1586	kfree(DMAbuffer);
1587 err_dma2:
1588	free_dma(FIQ_FD1772);
1589
1590 err_dma1:
1591	free_dma(FLOPPY_DMA);
1592
1593 err_blkdev:
1594	unregister_blkdev(MAJOR_NR, "fd");
1595
1596 err_disk:
1597	while (i--)
1598		put_disk(disks[i]);
1599	return err;
1600}
1601