blob: 8e101a9655ba4bf3c00966b4fc93c2d33928fa6e [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/block/floppy.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Copyright (C) 1993, 1994 Alain Knaff
6 * Copyright (C) 1998 Alan Cox
7 */
8/*
9 * 02.12.91 - Changed to static variables to indicate need for reset
10 * and recalibrate. This makes some things easier (output_byte reset
11 * checking etc), and means less interrupt jumping in case of errors,
12 * so the code is hopefully easier to understand.
13 */
14
15/*
16 * This file is certainly a mess. I've tried my best to get it working,
17 * but I don't like programming floppies, and I have only one anyway.
18 * Urgel. I should check for more errors, and do more graceful error
19 * recovery. Seems there are problems with several drives. I've tried to
20 * correct them. No promises.
21 */
22
23/*
24 * As with hd.c, all routines within this file can (and will) be called
25 * by interrupts, so extreme caution is needed. A hardware interrupt
26 * handler may not sleep, or a kernel panic will happen. Thus I cannot
27 * call "floppy-on" directly, but have to set a special timer interrupt
28 * etc.
29 */
30
31/*
32 * 28.02.92 - made track-buffering routines, based on the routines written
33 * by entropy@wintermute.wpi.edu (Lawrence Foard). Linus.
34 */
35
36/*
37 * Automatic floppy-detection and formatting written by Werner Almesberger
38 * (almesber@nessie.cs.id.ethz.ch), who also corrected some problems with
39 * the floppy-change signal detection.
40 */
41
42/*
43 * 1992/7/22 -- Hennus Bergman: Added better error reporting, fixed
44 * FDC data overrun bug, added some preliminary stuff for vertical
45 * recording support.
46 *
47 * 1992/9/17: Added DMA allocation & DMA functions. -- hhb.
48 *
49 * TODO: Errors are still not counted properly.
50 */
51
52/* 1992/9/20
53 * Modifications for ``Sector Shifting'' by Rob Hooft (hooft@chem.ruu.nl)
54 * modeled after the freeware MS-DOS program fdformat/88 V1.8 by
55 * Christoph H. Hochst\"atter.
56 * I have fixed the shift values to the ones I always use. Maybe a new
57 * ioctl() should be created to be able to modify them.
58 * There is a bug in the driver that makes it impossible to format a
59 * floppy as the first thing after bootup.
60 */
61
62/*
63 * 1993/4/29 -- Linus -- cleaned up the timer handling in the kernel, and
64 * this helped the floppy driver as well. Much cleaner, and still seems to
65 * work.
66 */
67
68/* 1994/6/24 --bbroad-- added the floppy table entries and made
69 * minor modifications to allow 2.88 floppies to be run.
70 */
71
72/* 1994/7/13 -- Paul Vojta -- modified the probing code to allow three or more
73 * disk types.
74 */
75
76/*
77 * 1994/8/8 -- Alain Knaff -- Switched to fdpatch driver: Support for bigger
78 * format bug fixes, but unfortunately some new bugs too...
79 */
80
81/* 1994/9/17 -- Koen Holtman -- added logging of physical floppy write
82 * errors to allow safe writing by specialized programs.
83 */
84
85/* 1995/4/24 -- Dan Fandrich -- added support for Commodore 1581 3.5" disks
86 * by defining bit 1 of the "stretch" parameter to mean put sectors on the
87 * opposite side of the disk, leaving the sector IDs alone (i.e. Commodore's
88 * drives are "upside-down").
89 */
90
91/*
92 * 1995/8/26 -- Andreas Busse -- added Mips support.
93 */
94
95/*
96 * 1995/10/18 -- Ralf Baechle -- Portability cleanup; move machine dependent
97 * features to asm/floppy.h.
98 */
99
100/*
James Nelsonb88b0982005-11-08 16:52:12 +0100101 * 1998/1/21 -- Richard Gooch <rgooch@atnf.csiro.au> -- devfs support
102 */
103
104/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 * 1998/05/07 -- Russell King -- More portability cleanups; moved definition of
106 * interrupt and dma channel to asm/floppy.h. Cleaned up some formatting &
107 * use of '0' for NULL.
108 */
109
110/*
111 * 1998/06/07 -- Alan Cox -- Merged the 2.0.34 fixes for resource allocation
112 * failures.
113 */
114
115/*
116 * 1998/09/20 -- David Weinehall -- Added slow-down code for buggy PS/2-drives.
117 */
118
119/*
120 * 1999/08/13 -- Paul Slootman -- floppy stopped working on Alpha after 24
121 * days, 6 hours, 32 minutes and 32 seconds (i.e. MAXINT jiffies; ints were
122 * being used to store jiffies, which are unsigned longs).
123 */
124
125/*
126 * 2000/08/28 -- Arnaldo Carvalho de Melo <acme@conectiva.com.br>
127 * - get rid of check_region
128 * - s/suser/capable/
129 */
130
131/*
132 * 2001/08/26 -- Paul Gortmaker - fix insmod oops on machines with no
133 * floppy controller (lingering task on list after module is gone... boom.)
134 */
135
136/*
137 * 2002/02/07 -- Anton Altaparmakov - Fix io ports reservation to correct range
138 * (0x3f2-0x3f5, 0x3f7). This fix is a bit of a hack but the proper fix
139 * requires many non-obvious changes in arch dependent code.
140 */
141
142/* 2003/07/28 -- Daniele Bellucci <bellucda@tiscali.it>.
143 * Better audit of register_blkdev.
144 */
145
146#define FLOPPY_SANITY_CHECK
147#undef FLOPPY_SILENT_DCL_CLEAR
148
149#define REALLY_SLOW_IO
150
151#define DEBUGT 2
152#define DCL_DEBUG /* debug disk change line */
153
154/* do print messages for unexpected interrupts */
155static int print_unex = 1;
156#include <linux/module.h>
157#include <linux/sched.h>
158#include <linux/fs.h>
159#include <linux/kernel.h>
160#include <linux/timer.h>
161#include <linux/workqueue.h>
162#define FDPATCHES
163#include <linux/fdreg.h>
164
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165#include <linux/fd.h>
166#include <linux/hdreg.h>
167
168#include <linux/errno.h>
169#include <linux/slab.h>
170#include <linux/mm.h>
171#include <linux/bio.h>
172#include <linux/string.h>
Marcelo Feitoza Parisi50297cb2006-03-28 01:56:44 -0800173#include <linux/jiffies.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174#include <linux/fcntl.h>
175#include <linux/delay.h>
176#include <linux/mc146818rtc.h> /* CMOS defines */
177#include <linux/ioport.h>
178#include <linux/interrupt.h>
179#include <linux/init.h>
180#include <linux/devfs_fs_kernel.h>
Russell Kingd052d1b2005-10-29 19:07:23 +0100181#include <linux/platform_device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182#include <linux/buffer_head.h> /* for invalidate_buffers() */
Jes Sorensenb1c82b52006-03-23 03:00:26 -0800183#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184
185/*
186 * PS/2 floppies have much slower step rates than regular floppies.
187 * It's been recommended that take about 1/4 of the default speed
188 * in some more extreme cases.
189 */
190static int slow_floppy;
191
192#include <asm/dma.h>
193#include <asm/irq.h>
194#include <asm/system.h>
195#include <asm/io.h>
196#include <asm/uaccess.h>
197
198static int FLOPPY_IRQ = 6;
199static int FLOPPY_DMA = 2;
200static int can_use_virtual_dma = 2;
201/* =======
202 * can use virtual DMA:
203 * 0 = use of virtual DMA disallowed by config
204 * 1 = use of virtual DMA prescribed by config
205 * 2 = no virtual DMA preference configured. By default try hard DMA,
206 * but fall back on virtual DMA when not enough memory available
207 */
208
209static int use_virtual_dma;
210/* =======
211 * use virtual DMA
212 * 0 using hard DMA
213 * 1 using virtual DMA
214 * This variable is set to virtual when a DMA mem problem arises, and
215 * reset back in floppy_grab_irq_and_dma.
216 * It is not safe to reset it in other circumstances, because the floppy
217 * driver may have several buffers in use at once, and we do currently not
218 * record each buffers capabilities
219 */
220
221static DEFINE_SPINLOCK(floppy_lock);
222static struct completion device_release;
223
224static unsigned short virtual_dma_port = 0x3f0;
225irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
226static int set_dor(int fdc, char mask, char data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
228#define K_64 0x10000 /* 64KB */
229
230/* the following is the mask of allowed drives. By default units 2 and
231 * 3 of both floppy controllers are disabled, because switching on the
232 * motor of these drives causes system hangs on some PCI computers. drive
233 * 0 is the low bit (0x1), and drive 7 is the high bit (0x80). Bits are on if
234 * a drive is allowed.
235 *
236 * NOTE: This must come before we include the arch floppy header because
237 * some ports reference this variable from there. -DaveM
238 */
239
240static int allowed_drive_mask = 0x33;
241
242#include <asm/floppy.h>
243
244static int irqdma_allocated;
245
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246#define DEVICE_NAME "floppy"
247
248#include <linux/blkdev.h>
249#include <linux/blkpg.h>
250#include <linux/cdrom.h> /* for the compatibility eject ioctl */
251#include <linux/completion.h>
252
Ingo Molnar6dc659d2006-03-26 01:36:54 -0800253/*
254 * Interrupt freeing also means /proc VFS work - dont do it
255 * from interrupt context. We push this work into keventd:
256 */
257static void fd_free_irq_fn(void *data)
258{
259 fd_free_irq();
260}
261
262static DECLARE_WORK(fd_free_irq_work, fd_free_irq_fn, NULL);
263
264
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265static struct request *current_req;
266static struct request_queue *floppy_queue;
267static void do_fd_request(request_queue_t * q);
268
269#ifndef fd_get_dma_residue
270#define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA)
271#endif
272
273/* Dma Memory related stuff */
274
275#ifndef fd_dma_mem_free
276#define fd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
277#endif
278
279#ifndef fd_dma_mem_alloc
280#define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
281#endif
282
283static inline void fallback_on_nodma_alloc(char **addr, size_t l)
284{
285#ifdef FLOPPY_CAN_FALLBACK_ON_NODMA
286 if (*addr)
287 return; /* we have the memory */
288 if (can_use_virtual_dma != 2)
289 return; /* no fallback allowed */
290 printk
291 ("DMA memory shortage. Temporarily falling back on virtual DMA\n");
292 *addr = (char *)nodma_mem_alloc(l);
293#else
294 return;
295#endif
296}
297
298/* End dma memory related stuff */
299
300static unsigned long fake_change;
301static int initialising = 1;
302
303#define ITYPE(x) (((x)>>2) & 0x1f)
304#define TOMINOR(x) ((x & 3) | ((x & 4) << 5))
305#define UNIT(x) ((x) & 0x03) /* drive on fdc */
306#define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */
307#define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2))
308 /* reverse mapping from unit and fdc to drive */
309#define DP (&drive_params[current_drive])
310#define DRS (&drive_state[current_drive])
311#define DRWE (&write_errors[current_drive])
312#define FDCS (&fdc_state[fdc])
313#define CLEARF(x) (clear_bit(x##_BIT, &DRS->flags))
314#define SETF(x) (set_bit(x##_BIT, &DRS->flags))
315#define TESTF(x) (test_bit(x##_BIT, &DRS->flags))
316
317#define UDP (&drive_params[drive])
318#define UDRS (&drive_state[drive])
319#define UDRWE (&write_errors[drive])
320#define UFDCS (&fdc_state[FDC(drive)])
321#define UCLEARF(x) (clear_bit(x##_BIT, &UDRS->flags))
322#define USETF(x) (set_bit(x##_BIT, &UDRS->flags))
323#define UTESTF(x) (test_bit(x##_BIT, &UDRS->flags))
324
325#define DPRINT(format, args...) printk(DEVICE_NAME "%d: " format, current_drive , ## args)
326
327#define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2)
328#define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
329
330#define CLEARSTRUCT(x) memset((x), 0, sizeof(*(x)))
331
332/* read/write */
333#define COMMAND raw_cmd->cmd[0]
334#define DR_SELECT raw_cmd->cmd[1]
335#define TRACK raw_cmd->cmd[2]
336#define HEAD raw_cmd->cmd[3]
337#define SECTOR raw_cmd->cmd[4]
338#define SIZECODE raw_cmd->cmd[5]
339#define SECT_PER_TRACK raw_cmd->cmd[6]
340#define GAP raw_cmd->cmd[7]
341#define SIZECODE2 raw_cmd->cmd[8]
342#define NR_RW 9
343
344/* format */
345#define F_SIZECODE raw_cmd->cmd[2]
346#define F_SECT_PER_TRACK raw_cmd->cmd[3]
347#define F_GAP raw_cmd->cmd[4]
348#define F_FILL raw_cmd->cmd[5]
349#define NR_F 6
350
351/*
352 * Maximum disk size (in kilobytes). This default is used whenever the
353 * current disk size is unknown.
354 * [Now it is rather a minimum]
355 */
356#define MAX_DISK_SIZE 4 /* 3984 */
357
358/*
359 * globals used by 'result()'
360 */
361#define MAX_REPLIES 16
362static unsigned char reply_buffer[MAX_REPLIES];
363static int inr; /* size of reply buffer, when called from interrupt */
364#define ST0 (reply_buffer[0])
365#define ST1 (reply_buffer[1])
366#define ST2 (reply_buffer[2])
367#define ST3 (reply_buffer[0]) /* result of GETSTATUS */
368#define R_TRACK (reply_buffer[3])
369#define R_HEAD (reply_buffer[4])
370#define R_SECTOR (reply_buffer[5])
371#define R_SIZECODE (reply_buffer[6])
372
373#define SEL_DLY (2*HZ/100)
374
375/*
376 * this struct defines the different floppy drive types.
377 */
378static struct {
379 struct floppy_drive_params params;
380 const char *name; /* name printed while booting */
381} default_drive_params[] = {
382/* NOTE: the time values in jiffies should be in msec!
383 CMOS drive type
384 | Maximum data rate supported by drive type
385 | | Head load time, msec
386 | | | Head unload time, msec (not used)
387 | | | | Step rate interval, usec
388 | | | | | Time needed for spinup time (jiffies)
389 | | | | | | Timeout for spinning down (jiffies)
390 | | | | | | | Spindown offset (where disk stops)
391 | | | | | | | | Select delay
392 | | | | | | | | | RPS
393 | | | | | | | | | | Max number of tracks
394 | | | | | | | | | | | Interrupt timeout
395 | | | | | | | | | | | | Max nonintlv. sectors
396 | | | | | | | | | | | | | -Max Errors- flags */
397{{0, 500, 16, 16, 8000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 80, 3*HZ, 20, {3,1,2,0,2}, 0,
398 0, { 7, 4, 8, 2, 1, 5, 3,10}, 3*HZ/2, 0 }, "unknown" },
399
400{{1, 300, 16, 16, 8000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 40, 3*HZ, 17, {3,1,2,0,2}, 0,
401 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 3*HZ/2, 1 }, "360K PC" }, /*5 1/4 360 KB PC*/
402
403{{2, 500, 16, 16, 6000, 4*HZ/10, 3*HZ, 14, SEL_DLY, 6, 83, 3*HZ, 17, {3,1,2,0,2}, 0,
404 0, { 2, 5, 6,23,10,20,12, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/
405
406{{3, 250, 16, 16, 3000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0,
407 0, { 4,22,21,30, 3, 0, 0, 0}, 3*HZ/2, 4 }, "720k" }, /*3 1/2 DD*/
408
409{{4, 500, 16, 16, 4000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0,
410 0, { 7, 4,25,22,31,21,29,11}, 3*HZ/2, 7 }, "1.44M" }, /*3 1/2 HD*/
411
412{{5, 1000, 15, 8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0,
413 0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M AMI BIOS" }, /*3 1/2 ED*/
414
415{{6, 1000, 15, 8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0,
416 0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M" } /*3 1/2 ED*/
417/* | --autodetected formats--- | | |
418 * read_track | | Name printed when booting
419 * | Native format
420 * Frequency of disk change checks */
421};
422
423static struct floppy_drive_params drive_params[N_DRIVE];
424static struct floppy_drive_struct drive_state[N_DRIVE];
425static struct floppy_write_errors write_errors[N_DRIVE];
426static struct timer_list motor_off_timer[N_DRIVE];
427static struct gendisk *disks[N_DRIVE];
428static struct block_device *opened_bdev[N_DRIVE];
Jes Sorensenb1c82b52006-03-23 03:00:26 -0800429static DEFINE_MUTEX(open_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
431
432/*
433 * This struct defines the different floppy types.
434 *
435 * Bit 0 of 'stretch' tells if the tracks need to be doubled for some
436 * types (e.g. 360kB diskette in 1.2MB drive, etc.). Bit 1 of 'stretch'
437 * tells if the disk is in Commodore 1581 format, which means side 0 sectors
438 * are located on side 1 of the disk but with a side 0 ID, and vice-versa.
439 * This is the same as the Sharp MZ-80 5.25" CP/M disk format, except that the
440 * 1581's logical side 0 is on physical side 1, whereas the Sharp's logical
441 * side 0 is on physical side 0 (but with the misnamed sector IDs).
442 * 'stretch' should probably be renamed to something more general, like
443 * 'options'. Other parameters should be self-explanatory (see also
444 * setfdprm(8)).
445 */
446/*
447 Size
448 | Sectors per track
449 | | Head
450 | | | Tracks
451 | | | | Stretch
452 | | | | | Gap 1 size
453 | | | | | | Data rate, | 0x40 for perp
454 | | | | | | | Spec1 (stepping rate, head unload
455 | | | | | | | | /fmt gap (gap2) */
456static struct floppy_struct floppy_type[32] = {
457 { 0, 0,0, 0,0,0x00,0x00,0x00,0x00,NULL }, /* 0 no testing */
458 { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"d360" }, /* 1 360KB PC */
459 { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,"h1200" }, /* 2 1.2MB AT */
460 { 720, 9,1,80,0,0x2A,0x02,0xDF,0x50,"D360" }, /* 3 360KB SS 3.5" */
461 { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"D720" }, /* 4 720KB 3.5" */
462 { 720, 9,2,40,1,0x23,0x01,0xDF,0x50,"h360" }, /* 5 360KB AT */
463 { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,"h720" }, /* 6 720KB AT */
464 { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"H1440" }, /* 7 1.44MB 3.5" */
465 { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"E2880" }, /* 8 2.88MB 3.5" */
466 { 6240,39,2,80,0,0x1B,0x43,0xAF,0x28,"E3120" }, /* 9 3.12MB 3.5" */
467
468 { 2880,18,2,80,0,0x25,0x00,0xDF,0x02,"h1440" }, /* 10 1.44MB 5.25" */
469 { 3360,21,2,80,0,0x1C,0x00,0xCF,0x0C,"H1680" }, /* 11 1.68MB 3.5" */
470 { 820,10,2,41,1,0x25,0x01,0xDF,0x2E,"h410" }, /* 12 410KB 5.25" */
471 { 1640,10,2,82,0,0x25,0x02,0xDF,0x2E,"H820" }, /* 13 820KB 3.5" */
472 { 2952,18,2,82,0,0x25,0x00,0xDF,0x02,"h1476" }, /* 14 1.48MB 5.25" */
473 { 3444,21,2,82,0,0x25,0x00,0xDF,0x0C,"H1722" }, /* 15 1.72MB 3.5" */
474 { 840,10,2,42,1,0x25,0x01,0xDF,0x2E,"h420" }, /* 16 420KB 5.25" */
475 { 1660,10,2,83,0,0x25,0x02,0xDF,0x2E,"H830" }, /* 17 830KB 3.5" */
476 { 2988,18,2,83,0,0x25,0x00,0xDF,0x02,"h1494" }, /* 18 1.49MB 5.25" */
477 { 3486,21,2,83,0,0x25,0x00,0xDF,0x0C,"H1743" }, /* 19 1.74 MB 3.5" */
478
479 { 1760,11,2,80,0,0x1C,0x09,0xCF,0x00,"h880" }, /* 20 880KB 5.25" */
480 { 2080,13,2,80,0,0x1C,0x01,0xCF,0x00,"D1040" }, /* 21 1.04MB 3.5" */
481 { 2240,14,2,80,0,0x1C,0x19,0xCF,0x00,"D1120" }, /* 22 1.12MB 3.5" */
482 { 3200,20,2,80,0,0x1C,0x20,0xCF,0x2C,"h1600" }, /* 23 1.6MB 5.25" */
483 { 3520,22,2,80,0,0x1C,0x08,0xCF,0x2e,"H1760" }, /* 24 1.76MB 3.5" */
484 { 3840,24,2,80,0,0x1C,0x20,0xCF,0x00,"H1920" }, /* 25 1.92MB 3.5" */
485 { 6400,40,2,80,0,0x25,0x5B,0xCF,0x00,"E3200" }, /* 26 3.20MB 3.5" */
486 { 7040,44,2,80,0,0x25,0x5B,0xCF,0x00,"E3520" }, /* 27 3.52MB 3.5" */
487 { 7680,48,2,80,0,0x25,0x63,0xCF,0x00,"E3840" }, /* 28 3.84MB 3.5" */
488
489 { 3680,23,2,80,0,0x1C,0x10,0xCF,0x00,"H1840" }, /* 29 1.84MB 3.5" */
490 { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" }, /* 30 800KB 3.5" */
491 { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5" */
492};
493
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494#define SECTSIZE (_FD_SECTSIZE(*floppy))
495
496/* Auto-detection: Disk type used until the next media change occurs. */
497static struct floppy_struct *current_type[N_DRIVE];
498
499/*
500 * User-provided type information. current_type points to
501 * the respective entry of this array.
502 */
503static struct floppy_struct user_params[N_DRIVE];
504
505static sector_t floppy_sizes[256];
506
Hannes Reinecke94fd0db2005-07-15 10:09:25 +0200507static char floppy_device_name[] = "floppy";
508
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509/*
510 * The driver is trying to determine the correct media format
511 * while probing is set. rw_interrupt() clears it after a
512 * successful access.
513 */
514static int probing;
515
516/* Synchronization of FDC access. */
517#define FD_COMMAND_NONE -1
518#define FD_COMMAND_ERROR 2
519#define FD_COMMAND_OKAY 3
520
521static volatile int command_status = FD_COMMAND_NONE;
522static unsigned long fdc_busy;
523static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
524static DECLARE_WAIT_QUEUE_HEAD(command_done);
525
526#define NO_SIGNAL (!interruptible || !signal_pending(current))
527#define CALL(x) if ((x) == -EINTR) return -EINTR
528#define ECALL(x) if ((ret = (x))) return ret;
529#define _WAIT(x,i) CALL(ret=wait_til_done((x),i))
530#define WAIT(x) _WAIT((x),interruptible)
531#define IWAIT(x) _WAIT((x),1)
532
533/* Errors during formatting are counted here. */
534static int format_errors;
535
536/* Format request descriptor. */
537static struct format_descr format_req;
538
539/*
540 * Rate is 0 for 500kb/s, 1 for 300kbps, 2 for 250kbps
541 * Spec1 is 0xSH, where S is stepping rate (F=1ms, E=2ms, D=3ms etc),
542 * H is head unload time (1=16ms, 2=32ms, etc)
543 */
544
545/*
546 * Track buffer
547 * Because these are written to by the DMA controller, they must
548 * not contain a 64k byte boundary crossing, or data will be
549 * corrupted/lost.
550 */
551static char *floppy_track_buffer;
552static int max_buffer_sectors;
553
554static int *errors;
555typedef void (*done_f) (int);
556static struct cont_t {
557 void (*interrupt) (void); /* this is called after the interrupt of the
558 * main command */
559 void (*redo) (void); /* this is called to retry the operation */
560 void (*error) (void); /* this is called to tally an error */
561 done_f done; /* this is called to say if the operation has
562 * succeeded/failed */
563} *cont;
564
565static void floppy_ready(void);
566static void floppy_start(void);
567static void process_fd_request(void);
568static void recalibrate_floppy(void);
569static void floppy_shutdown(unsigned long);
570
571static int floppy_grab_irq_and_dma(void);
572static void floppy_release_irq_and_dma(void);
573
574/*
575 * The "reset" variable should be tested whenever an interrupt is scheduled,
576 * after the commands have been sent. This is to ensure that the driver doesn't
577 * get wedged when the interrupt doesn't come because of a failed command.
578 * reset doesn't need to be tested before sending commands, because
579 * output_byte is automatically disabled when reset is set.
580 */
581#define CHECK_RESET { if (FDCS->reset){ reset_fdc(); return; } }
582static void reset_fdc(void);
583
584/*
585 * These are global variables, as that's the easiest way to give
586 * information to interrupts. They are the data used for the current
587 * request.
588 */
589#define NO_TRACK -1
590#define NEED_1_RECAL -2
591#define NEED_2_RECAL -3
592
593static int usage_count;
594
595/* buffer related variables */
596static int buffer_track = -1;
597static int buffer_drive = -1;
598static int buffer_min = -1;
599static int buffer_max = -1;
600
601/* fdc related variables, should end up in a struct */
602static struct floppy_fdc_state fdc_state[N_FDC];
603static int fdc; /* current fdc */
604
605static struct floppy_struct *_floppy = floppy_type;
606static unsigned char current_drive;
607static long current_count_sectors;
608static unsigned char fsector_t; /* sector in track */
609static unsigned char in_sector_offset; /* offset within physical sector,
610 * expressed in units of 512 bytes */
611
612#ifndef fd_eject
613static inline int fd_eject(int drive)
614{
615 return -EINVAL;
616}
617#endif
618
619/*
620 * Debugging
621 * =========
622 */
623#ifdef DEBUGT
624static long unsigned debugtimer;
625
626static inline void set_debugt(void)
627{
628 debugtimer = jiffies;
629}
630
631static inline void debugt(const char *message)
632{
633 if (DP->flags & DEBUGT)
634 printk("%s dtime=%lu\n", message, jiffies - debugtimer);
635}
636#else
637static inline void set_debugt(void) { }
638static inline void debugt(const char *message) { }
639#endif /* DEBUGT */
640
641typedef void (*timeout_fn) (unsigned long);
Ingo Molnar8d06afa2005-09-09 13:10:40 -0700642static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643
644static const char *timeout_message;
645
646#ifdef FLOPPY_SANITY_CHECK
647static void is_alive(const char *message)
648{
649 /* this routine checks whether the floppy driver is "alive" */
650 if (test_bit(0, &fdc_busy) && command_status < 2
651 && !timer_pending(&fd_timeout)) {
652 DPRINT("timeout handler died: %s\n", message);
653 }
654}
655#endif
656
657static void (*do_floppy) (void) = NULL;
658
659#ifdef FLOPPY_SANITY_CHECK
660
661#define OLOGSIZE 20
662
663static void (*lasthandler) (void);
664static unsigned long interruptjiffies;
665static unsigned long resultjiffies;
666static int resultsize;
667static unsigned long lastredo;
668
669static struct output_log {
670 unsigned char data;
671 unsigned char status;
672 unsigned long jiffies;
673} output_log[OLOGSIZE];
674
675static int output_log_pos;
676#endif
677
678#define current_reqD -1
679#define MAXTIMEOUT -2
680
681static void __reschedule_timeout(int drive, const char *message, int marg)
682{
683 if (drive == current_reqD)
684 drive = current_drive;
685 del_timer(&fd_timeout);
686 if (drive < 0 || drive > N_DRIVE) {
687 fd_timeout.expires = jiffies + 20UL * HZ;
688 drive = 0;
689 } else
690 fd_timeout.expires = jiffies + UDP->timeout;
691 add_timer(&fd_timeout);
692 if (UDP->flags & FD_DEBUG) {
693 DPRINT("reschedule timeout ");
694 printk(message, marg);
695 printk("\n");
696 }
697 timeout_message = message;
698}
699
700static void reschedule_timeout(int drive, const char *message, int marg)
701{
702 unsigned long flags;
703
704 spin_lock_irqsave(&floppy_lock, flags);
705 __reschedule_timeout(drive, message, marg);
706 spin_unlock_irqrestore(&floppy_lock, flags);
707}
708
709#define INFBOUND(a,b) (a)=max_t(int, a, b)
710
711#define SUPBOUND(a,b) (a)=min_t(int, a, b)
712
713/*
714 * Bottom half floppy driver.
715 * ==========================
716 *
717 * This part of the file contains the code talking directly to the hardware,
718 * and also the main service loop (seek-configure-spinup-command)
719 */
720
721/*
722 * disk change.
723 * This routine is responsible for maintaining the FD_DISK_CHANGE flag,
724 * and the last_checked date.
725 *
726 * last_checked is the date of the last check which showed 'no disk change'
727 * FD_DISK_CHANGE is set under two conditions:
728 * 1. The floppy has been changed after some i/o to that floppy already
729 * took place.
730 * 2. No floppy disk is in the drive. This is done in order to ensure that
731 * requests are quickly flushed in case there is no disk in the drive. It
732 * follows that FD_DISK_CHANGE can only be cleared if there is a disk in
733 * the drive.
734 *
735 * For 1., maxblock is observed. Maxblock is 0 if no i/o has taken place yet.
736 * For 2., FD_DISK_NEWCHANGE is watched. FD_DISK_NEWCHANGE is cleared on
737 * each seek. If a disk is present, the disk change line should also be
738 * cleared on each seek. Thus, if FD_DISK_NEWCHANGE is clear, but the disk
739 * change line is set, this means either that no disk is in the drive, or
740 * that it has been removed since the last seek.
741 *
742 * This means that we really have a third possibility too:
743 * The floppy has been changed after the last seek.
744 */
745
746static int disk_change(int drive)
747{
748 int fdc = FDC(drive);
749#ifdef FLOPPY_SANITY_CHECK
Marcelo Feitoza Parisi50297cb2006-03-28 01:56:44 -0800750 if (time_before(jiffies, UDRS->select_date + UDP->select_delay))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 DPRINT("WARNING disk change called early\n");
752 if (!(FDCS->dor & (0x10 << UNIT(drive))) ||
753 (FDCS->dor & 3) != UNIT(drive) || fdc != FDC(drive)) {
754 DPRINT("probing disk change on unselected drive\n");
755 DPRINT("drive=%d fdc=%d dor=%x\n", drive, FDC(drive),
756 (unsigned int)FDCS->dor);
757 }
758#endif
759
760#ifdef DCL_DEBUG
761 if (UDP->flags & FD_DEBUG) {
762 DPRINT("checking disk change line for drive %d\n", drive);
763 DPRINT("jiffies=%lu\n", jiffies);
764 DPRINT("disk change line=%x\n", fd_inb(FD_DIR) & 0x80);
765 DPRINT("flags=%lx\n", UDRS->flags);
766 }
767#endif
768 if (UDP->flags & FD_BROKEN_DCL)
769 return UTESTF(FD_DISK_CHANGED);
770 if ((fd_inb(FD_DIR) ^ UDP->flags) & 0x80) {
771 USETF(FD_VERIFY); /* verify write protection */
772 if (UDRS->maxblock) {
773 /* mark it changed */
774 USETF(FD_DISK_CHANGED);
775 }
776
777 /* invalidate its geometry */
778 if (UDRS->keep_data >= 0) {
779 if ((UDP->flags & FTD_MSG) &&
780 current_type[drive] != NULL)
781 DPRINT("Disk type is undefined after "
782 "disk change\n");
783 current_type[drive] = NULL;
784 floppy_sizes[TOMINOR(drive)] = MAX_DISK_SIZE << 1;
785 }
786
787 /*USETF(FD_DISK_NEWCHANGE); */
788 return 1;
789 } else {
790 UDRS->last_checked = jiffies;
791 UCLEARF(FD_DISK_NEWCHANGE);
792 }
793 return 0;
794}
795
796static inline int is_selected(int dor, int unit)
797{
798 return ((dor & (0x10 << unit)) && (dor & 3) == unit);
799}
800
801static int set_dor(int fdc, char mask, char data)
802{
803 register unsigned char drive, unit, newdor, olddor;
804
805 if (FDCS->address == -1)
806 return -1;
807
808 olddor = FDCS->dor;
809 newdor = (olddor & mask) | data;
810 if (newdor != olddor) {
811 unit = olddor & 0x3;
812 if (is_selected(olddor, unit) && !is_selected(newdor, unit)) {
813 drive = REVDRIVE(fdc, unit);
814#ifdef DCL_DEBUG
815 if (UDP->flags & FD_DEBUG) {
816 DPRINT("calling disk change from set_dor\n");
817 }
818#endif
819 disk_change(drive);
820 }
821 FDCS->dor = newdor;
822 fd_outb(newdor, FD_DOR);
823
824 unit = newdor & 0x3;
825 if (!is_selected(olddor, unit) && is_selected(newdor, unit)) {
826 drive = REVDRIVE(fdc, unit);
827 UDRS->select_date = jiffies;
828 }
829 }
830 /*
831 * We should propagate failures to grab the resources back
832 * nicely from here. Actually we ought to rewrite the fd
833 * driver some day too.
834 */
835 if (newdor & FLOPPY_MOTOR_MASK)
836 floppy_grab_irq_and_dma();
837 if (olddor & FLOPPY_MOTOR_MASK)
838 floppy_release_irq_and_dma();
839 return olddor;
840}
841
842static void twaddle(void)
843{
844 if (DP->select_delay)
845 return;
846 fd_outb(FDCS->dor & ~(0x10 << UNIT(current_drive)), FD_DOR);
847 fd_outb(FDCS->dor, FD_DOR);
848 DRS->select_date = jiffies;
849}
850
851/* reset all driver information about the current fdc. This is needed after
852 * a reset, and after a raw command. */
853static void reset_fdc_info(int mode)
854{
855 int drive;
856
857 FDCS->spec1 = FDCS->spec2 = -1;
858 FDCS->need_configure = 1;
859 FDCS->perp_mode = 1;
860 FDCS->rawcmd = 0;
861 for (drive = 0; drive < N_DRIVE; drive++)
862 if (FDC(drive) == fdc && (mode || UDRS->track != NEED_1_RECAL))
863 UDRS->track = NEED_2_RECAL;
864}
865
866/* selects the fdc and drive, and enables the fdc's input/dma. */
867static void set_fdc(int drive)
868{
869 if (drive >= 0 && drive < N_DRIVE) {
870 fdc = FDC(drive);
871 current_drive = drive;
872 }
873 if (fdc != 1 && fdc != 0) {
874 printk("bad fdc value\n");
875 return;
876 }
877 set_dor(fdc, ~0, 8);
878#if N_FDC > 1
879 set_dor(1 - fdc, ~8, 0);
880#endif
881 if (FDCS->rawcmd == 2)
882 reset_fdc_info(1);
883 if (fd_inb(FD_STATUS) != STATUS_READY)
884 FDCS->reset = 1;
885}
886
887/* locks the driver */
888static int _lock_fdc(int drive, int interruptible, int line)
889{
890 if (!usage_count) {
891 printk(KERN_ERR
892 "Trying to lock fdc while usage count=0 at line %d\n",
893 line);
894 return -1;
895 }
896 if (floppy_grab_irq_and_dma() == -1)
897 return -EBUSY;
898
899 if (test_and_set_bit(0, &fdc_busy)) {
900 DECLARE_WAITQUEUE(wait, current);
901 add_wait_queue(&fdc_wait, &wait);
902
903 for (;;) {
904 set_current_state(TASK_INTERRUPTIBLE);
905
906 if (!test_and_set_bit(0, &fdc_busy))
907 break;
908
909 schedule();
910
911 if (!NO_SIGNAL) {
912 remove_wait_queue(&fdc_wait, &wait);
913 return -EINTR;
914 }
915 }
916
917 set_current_state(TASK_RUNNING);
918 remove_wait_queue(&fdc_wait, &wait);
919 }
920 command_status = FD_COMMAND_NONE;
921
922 __reschedule_timeout(drive, "lock fdc", 0);
923 set_fdc(drive);
924 return 0;
925}
926
927#define lock_fdc(drive,interruptible) _lock_fdc(drive,interruptible, __LINE__)
928
929#define LOCK_FDC(drive,interruptible) \
930if (lock_fdc(drive,interruptible)) return -EINTR;
931
932/* unlocks the driver */
933static inline void unlock_fdc(void)
934{
935 unsigned long flags;
936
937 raw_cmd = NULL;
938 if (!test_bit(0, &fdc_busy))
939 DPRINT("FDC access conflict!\n");
940
941 if (do_floppy)
942 DPRINT("device interrupt still active at FDC release: %p!\n",
943 do_floppy);
944 command_status = FD_COMMAND_NONE;
945 spin_lock_irqsave(&floppy_lock, flags);
946 del_timer(&fd_timeout);
947 cont = NULL;
948 clear_bit(0, &fdc_busy);
949 if (elv_next_request(floppy_queue))
950 do_fd_request(floppy_queue);
951 spin_unlock_irqrestore(&floppy_lock, flags);
952 floppy_release_irq_and_dma();
953 wake_up(&fdc_wait);
954}
955
956/* switches the motor off after a given timeout */
957static void motor_off_callback(unsigned long nr)
958{
959 unsigned char mask = ~(0x10 << UNIT(nr));
960
961 set_dor(FDC(nr), mask, 0);
962}
963
964/* schedules motor off */
965static void floppy_off(unsigned int drive)
966{
967 unsigned long volatile delta;
968 register int fdc = FDC(drive);
969
970 if (!(FDCS->dor & (0x10 << UNIT(drive))))
971 return;
972
973 del_timer(motor_off_timer + drive);
974
975 /* make spindle stop in a position which minimizes spinup time
976 * next time */
977 if (UDP->rps) {
978 delta = jiffies - UDRS->first_read_date + HZ -
979 UDP->spindown_offset;
980 delta = ((delta * UDP->rps) % HZ) / UDP->rps;
981 motor_off_timer[drive].expires =
982 jiffies + UDP->spindown - delta;
983 }
984 add_timer(motor_off_timer + drive);
985}
986
987/*
988 * cycle through all N_DRIVE floppy drives, for disk change testing.
989 * stopping at current drive. This is done before any long operation, to
990 * be sure to have up to date disk change information.
991 */
992static void scandrives(void)
993{
994 int i, drive, saved_drive;
995
996 if (DP->select_delay)
997 return;
998
999 saved_drive = current_drive;
1000 for (i = 0; i < N_DRIVE; i++) {
1001 drive = (saved_drive + i + 1) % N_DRIVE;
1002 if (UDRS->fd_ref == 0 || UDP->select_delay != 0)
1003 continue; /* skip closed drives */
1004 set_fdc(drive);
1005 if (!(set_dor(fdc, ~3, UNIT(drive) | (0x10 << UNIT(drive))) &
1006 (0x10 << UNIT(drive))))
1007 /* switch the motor off again, if it was off to
1008 * begin with */
1009 set_dor(fdc, ~(0x10 << UNIT(drive)), 0);
1010 }
1011 set_fdc(saved_drive);
1012}
1013
1014static void empty(void)
1015{
1016}
1017
1018static DECLARE_WORK(floppy_work, NULL, NULL);
1019
1020static void schedule_bh(void (*handler) (void))
1021{
1022 PREPARE_WORK(&floppy_work, (void (*)(void *))handler, NULL);
1023 schedule_work(&floppy_work);
1024}
1025
Ingo Molnar8d06afa2005-09-09 13:10:40 -07001026static DEFINE_TIMER(fd_timer, NULL, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027
1028static void cancel_activity(void)
1029{
1030 unsigned long flags;
1031
1032 spin_lock_irqsave(&floppy_lock, flags);
1033 do_floppy = NULL;
1034 PREPARE_WORK(&floppy_work, (void *)empty, NULL);
1035 del_timer(&fd_timer);
1036 spin_unlock_irqrestore(&floppy_lock, flags);
1037}
1038
1039/* this function makes sure that the disk stays in the drive during the
1040 * transfer */
1041static void fd_watchdog(void)
1042{
1043#ifdef DCL_DEBUG
1044 if (DP->flags & FD_DEBUG) {
1045 DPRINT("calling disk change from watchdog\n");
1046 }
1047#endif
1048
1049 if (disk_change(current_drive)) {
1050 DPRINT("disk removed during i/o\n");
1051 cancel_activity();
1052 cont->done(0);
1053 reset_fdc();
1054 } else {
1055 del_timer(&fd_timer);
1056 fd_timer.function = (timeout_fn) fd_watchdog;
1057 fd_timer.expires = jiffies + HZ / 10;
1058 add_timer(&fd_timer);
1059 }
1060}
1061
1062static void main_command_interrupt(void)
1063{
1064 del_timer(&fd_timer);
1065 cont->interrupt();
1066}
1067
1068/* waits for a delay (spinup or select) to pass */
1069static int fd_wait_for_completion(unsigned long delay, timeout_fn function)
1070{
1071 if (FDCS->reset) {
1072 reset_fdc(); /* do the reset during sleep to win time
1073 * if we don't need to sleep, it's a good
1074 * occasion anyways */
1075 return 1;
1076 }
1077
Marcelo Feitoza Parisi50297cb2006-03-28 01:56:44 -08001078 if (time_before(jiffies, delay)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 del_timer(&fd_timer);
1080 fd_timer.function = function;
1081 fd_timer.expires = delay;
1082 add_timer(&fd_timer);
1083 return 1;
1084 }
1085 return 0;
1086}
1087
1088static DEFINE_SPINLOCK(floppy_hlt_lock);
1089static int hlt_disabled;
1090static void floppy_disable_hlt(void)
1091{
1092 unsigned long flags;
1093
1094 spin_lock_irqsave(&floppy_hlt_lock, flags);
1095 if (!hlt_disabled) {
1096 hlt_disabled = 1;
1097#ifdef HAVE_DISABLE_HLT
1098 disable_hlt();
1099#endif
1100 }
1101 spin_unlock_irqrestore(&floppy_hlt_lock, flags);
1102}
1103
1104static void floppy_enable_hlt(void)
1105{
1106 unsigned long flags;
1107
1108 spin_lock_irqsave(&floppy_hlt_lock, flags);
1109 if (hlt_disabled) {
1110 hlt_disabled = 0;
1111#ifdef HAVE_DISABLE_HLT
1112 enable_hlt();
1113#endif
1114 }
1115 spin_unlock_irqrestore(&floppy_hlt_lock, flags);
1116}
1117
1118static void setup_DMA(void)
1119{
1120 unsigned long f;
1121
1122#ifdef FLOPPY_SANITY_CHECK
1123 if (raw_cmd->length == 0) {
1124 int i;
1125
1126 printk("zero dma transfer size:");
1127 for (i = 0; i < raw_cmd->cmd_count; i++)
1128 printk("%x,", raw_cmd->cmd[i]);
1129 printk("\n");
1130 cont->done(0);
1131 FDCS->reset = 1;
1132 return;
1133 }
1134 if (((unsigned long)raw_cmd->kernel_data) % 512) {
1135 printk("non aligned address: %p\n", raw_cmd->kernel_data);
1136 cont->done(0);
1137 FDCS->reset = 1;
1138 return;
1139 }
1140#endif
1141 f = claim_dma_lock();
1142 fd_disable_dma();
1143#ifdef fd_dma_setup
1144 if (fd_dma_setup(raw_cmd->kernel_data, raw_cmd->length,
1145 (raw_cmd->flags & FD_RAW_READ) ?
1146 DMA_MODE_READ : DMA_MODE_WRITE, FDCS->address) < 0) {
1147 release_dma_lock(f);
1148 cont->done(0);
1149 FDCS->reset = 1;
1150 return;
1151 }
1152 release_dma_lock(f);
1153#else
1154 fd_clear_dma_ff();
1155 fd_cacheflush(raw_cmd->kernel_data, raw_cmd->length);
1156 fd_set_dma_mode((raw_cmd->flags & FD_RAW_READ) ?
1157 DMA_MODE_READ : DMA_MODE_WRITE);
1158 fd_set_dma_addr(raw_cmd->kernel_data);
1159 fd_set_dma_count(raw_cmd->length);
1160 virtual_dma_port = FDCS->address;
1161 fd_enable_dma();
1162 release_dma_lock(f);
1163#endif
1164 floppy_disable_hlt();
1165}
1166
1167static void show_floppy(void);
1168
1169/* waits until the fdc becomes ready */
1170static int wait_til_ready(void)
1171{
1172 int counter, status;
1173 if (FDCS->reset)
1174 return -1;
1175 for (counter = 0; counter < 10000; counter++) {
1176 status = fd_inb(FD_STATUS);
1177 if (status & STATUS_READY)
1178 return status;
1179 }
1180 if (!initialising) {
1181 DPRINT("Getstatus times out (%x) on fdc %d\n", status, fdc);
1182 show_floppy();
1183 }
1184 FDCS->reset = 1;
1185 return -1;
1186}
1187
1188/* sends a command byte to the fdc */
1189static int output_byte(char byte)
1190{
1191 int status;
1192
1193 if ((status = wait_til_ready()) < 0)
1194 return -1;
1195 if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY) {
1196 fd_outb(byte, FD_DATA);
1197#ifdef FLOPPY_SANITY_CHECK
1198 output_log[output_log_pos].data = byte;
1199 output_log[output_log_pos].status = status;
1200 output_log[output_log_pos].jiffies = jiffies;
1201 output_log_pos = (output_log_pos + 1) % OLOGSIZE;
1202#endif
1203 return 0;
1204 }
1205 FDCS->reset = 1;
1206 if (!initialising) {
1207 DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n",
1208 byte, fdc, status);
1209 show_floppy();
1210 }
1211 return -1;
1212}
1213
1214#define LAST_OUT(x) if (output_byte(x)<0){ reset_fdc();return;}
1215
1216/* gets the response from the fdc */
1217static int result(void)
1218{
1219 int i, status = 0;
1220
1221 for (i = 0; i < MAX_REPLIES; i++) {
1222 if ((status = wait_til_ready()) < 0)
1223 break;
1224 status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA;
1225 if ((status & ~STATUS_BUSY) == STATUS_READY) {
1226#ifdef FLOPPY_SANITY_CHECK
1227 resultjiffies = jiffies;
1228 resultsize = i;
1229#endif
1230 return i;
1231 }
1232 if (status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
1233 reply_buffer[i] = fd_inb(FD_DATA);
1234 else
1235 break;
1236 }
1237 if (!initialising) {
1238 DPRINT
1239 ("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
1240 fdc, status, i);
1241 show_floppy();
1242 }
1243 FDCS->reset = 1;
1244 return -1;
1245}
1246
1247#define MORE_OUTPUT -2
1248/* does the fdc need more output? */
1249static int need_more_output(void)
1250{
1251 int status;
1252 if ((status = wait_til_ready()) < 0)
1253 return -1;
1254 if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY)
1255 return MORE_OUTPUT;
1256 return result();
1257}
1258
1259/* Set perpendicular mode as required, based on data rate, if supported.
1260 * 82077 Now tested. 1Mbps data rate only possible with 82077-1.
1261 */
1262static inline void perpendicular_mode(void)
1263{
1264 unsigned char perp_mode;
1265
1266 if (raw_cmd->rate & 0x40) {
1267 switch (raw_cmd->rate & 3) {
1268 case 0:
1269 perp_mode = 2;
1270 break;
1271 case 3:
1272 perp_mode = 3;
1273 break;
1274 default:
1275 DPRINT("Invalid data rate for perpendicular mode!\n");
1276 cont->done(0);
1277 FDCS->reset = 1; /* convenient way to return to
1278 * redo without to much hassle (deep
1279 * stack et al. */
1280 return;
1281 }
1282 } else
1283 perp_mode = 0;
1284
1285 if (FDCS->perp_mode == perp_mode)
1286 return;
1287 if (FDCS->version >= FDC_82077_ORIG) {
1288 output_byte(FD_PERPENDICULAR);
1289 output_byte(perp_mode);
1290 FDCS->perp_mode = perp_mode;
1291 } else if (perp_mode) {
1292 DPRINT("perpendicular mode not supported by this FDC.\n");
1293 }
1294} /* perpendicular_mode */
1295
1296static int fifo_depth = 0xa;
1297static int no_fifo;
1298
1299static int fdc_configure(void)
1300{
1301 /* Turn on FIFO */
1302 output_byte(FD_CONFIGURE);
1303 if (need_more_output() != MORE_OUTPUT)
1304 return 0;
1305 output_byte(0);
1306 output_byte(0x10 | (no_fifo & 0x20) | (fifo_depth & 0xf));
1307 output_byte(0); /* pre-compensation from track
1308 0 upwards */
1309 return 1;
1310}
1311
1312#define NOMINAL_DTR 500
1313
1314/* Issue a "SPECIFY" command to set the step rate time, head unload time,
1315 * head load time, and DMA disable flag to values needed by floppy.
1316 *
1317 * The value "dtr" is the data transfer rate in Kbps. It is needed
1318 * to account for the data rate-based scaling done by the 82072 and 82077
1319 * FDC types. This parameter is ignored for other types of FDCs (i.e.
1320 * 8272a).
1321 *
1322 * Note that changing the data transfer rate has a (probably deleterious)
1323 * effect on the parameters subject to scaling for 82072/82077 FDCs, so
1324 * fdc_specify is called again after each data transfer rate
1325 * change.
1326 *
1327 * srt: 1000 to 16000 in microseconds
1328 * hut: 16 to 240 milliseconds
1329 * hlt: 2 to 254 milliseconds
1330 *
1331 * These values are rounded up to the next highest available delay time.
1332 */
1333static void fdc_specify(void)
1334{
1335 unsigned char spec1, spec2;
1336 unsigned long srt, hlt, hut;
1337 unsigned long dtr = NOMINAL_DTR;
1338 unsigned long scale_dtr = NOMINAL_DTR;
1339 int hlt_max_code = 0x7f;
1340 int hut_max_code = 0xf;
1341
1342 if (FDCS->need_configure && FDCS->version >= FDC_82072A) {
1343 fdc_configure();
1344 FDCS->need_configure = 0;
1345 /*DPRINT("FIFO enabled\n"); */
1346 }
1347
1348 switch (raw_cmd->rate & 0x03) {
1349 case 3:
1350 dtr = 1000;
1351 break;
1352 case 1:
1353 dtr = 300;
1354 if (FDCS->version >= FDC_82078) {
1355 /* chose the default rate table, not the one
1356 * where 1 = 2 Mbps */
1357 output_byte(FD_DRIVESPEC);
1358 if (need_more_output() == MORE_OUTPUT) {
1359 output_byte(UNIT(current_drive));
1360 output_byte(0xc0);
1361 }
1362 }
1363 break;
1364 case 2:
1365 dtr = 250;
1366 break;
1367 }
1368
1369 if (FDCS->version >= FDC_82072) {
1370 scale_dtr = dtr;
1371 hlt_max_code = 0x00; /* 0==256msec*dtr0/dtr (not linear!) */
1372 hut_max_code = 0x0; /* 0==256msec*dtr0/dtr (not linear!) */
1373 }
1374
1375 /* Convert step rate from microseconds to milliseconds and 4 bits */
1376 srt = 16 - (DP->srt * scale_dtr / 1000 + NOMINAL_DTR - 1) / NOMINAL_DTR;
1377 if (slow_floppy) {
1378 srt = srt / 4;
1379 }
1380 SUPBOUND(srt, 0xf);
1381 INFBOUND(srt, 0);
1382
1383 hlt = (DP->hlt * scale_dtr / 2 + NOMINAL_DTR - 1) / NOMINAL_DTR;
1384 if (hlt < 0x01)
1385 hlt = 0x01;
1386 else if (hlt > 0x7f)
1387 hlt = hlt_max_code;
1388
1389 hut = (DP->hut * scale_dtr / 16 + NOMINAL_DTR - 1) / NOMINAL_DTR;
1390 if (hut < 0x1)
1391 hut = 0x1;
1392 else if (hut > 0xf)
1393 hut = hut_max_code;
1394
1395 spec1 = (srt << 4) | hut;
1396 spec2 = (hlt << 1) | (use_virtual_dma & 1);
1397
1398 /* If these parameters did not change, just return with success */
1399 if (FDCS->spec1 != spec1 || FDCS->spec2 != spec2) {
1400 /* Go ahead and set spec1 and spec2 */
1401 output_byte(FD_SPECIFY);
1402 output_byte(FDCS->spec1 = spec1);
1403 output_byte(FDCS->spec2 = spec2);
1404 }
1405} /* fdc_specify */
1406
1407/* Set the FDC's data transfer rate on behalf of the specified drive.
1408 * NOTE: with 82072/82077 FDCs, changing the data rate requires a reissue
1409 * of the specify command (i.e. using the fdc_specify function).
1410 */
1411static int fdc_dtr(void)
1412{
1413 /* If data rate not already set to desired value, set it. */
1414 if ((raw_cmd->rate & 3) == FDCS->dtr)
1415 return 0;
1416
1417 /* Set dtr */
1418 fd_outb(raw_cmd->rate & 3, FD_DCR);
1419
1420 /* TODO: some FDC/drive combinations (C&T 82C711 with TEAC 1.2MB)
1421 * need a stabilization period of several milliseconds to be
1422 * enforced after data rate changes before R/W operations.
1423 * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
1424 */
1425 FDCS->dtr = raw_cmd->rate & 3;
1426 return (fd_wait_for_completion(jiffies + 2UL * HZ / 100,
1427 (timeout_fn) floppy_ready));
1428} /* fdc_dtr */
1429
1430static void tell_sector(void)
1431{
1432 printk(": track %d, head %d, sector %d, size %d",
1433 R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
1434} /* tell_sector */
1435
1436/*
1437 * OK, this error interpreting routine is called after a
1438 * DMA read/write has succeeded
1439 * or failed, so we check the results, and copy any buffers.
1440 * hhb: Added better error reporting.
1441 * ak: Made this into a separate routine.
1442 */
1443static int interpret_errors(void)
1444{
1445 char bad;
1446
1447 if (inr != 7) {
1448 DPRINT("-- FDC reply error");
1449 FDCS->reset = 1;
1450 return 1;
1451 }
1452
1453 /* check IC to find cause of interrupt */
1454 switch (ST0 & ST0_INTR) {
1455 case 0x40: /* error occurred during command execution */
1456 if (ST1 & ST1_EOC)
1457 return 0; /* occurs with pseudo-DMA */
1458 bad = 1;
1459 if (ST1 & ST1_WP) {
1460 DPRINT("Drive is write protected\n");
1461 CLEARF(FD_DISK_WRITABLE);
1462 cont->done(0);
1463 bad = 2;
1464 } else if (ST1 & ST1_ND) {
1465 SETF(FD_NEED_TWADDLE);
1466 } else if (ST1 & ST1_OR) {
1467 if (DP->flags & FTD_MSG)
1468 DPRINT("Over/Underrun - retrying\n");
1469 bad = 0;
1470 } else if (*errors >= DP->max_errors.reporting) {
1471 DPRINT("");
1472 if (ST0 & ST0_ECE) {
1473 printk("Recalibrate failed!");
1474 } else if (ST2 & ST2_CRC) {
1475 printk("data CRC error");
1476 tell_sector();
1477 } else if (ST1 & ST1_CRC) {
1478 printk("CRC error");
1479 tell_sector();
1480 } else if ((ST1 & (ST1_MAM | ST1_ND))
1481 || (ST2 & ST2_MAM)) {
1482 if (!probing) {
1483 printk("sector not found");
1484 tell_sector();
1485 } else
1486 printk("probe failed...");
1487 } else if (ST2 & ST2_WC) { /* seek error */
1488 printk("wrong cylinder");
1489 } else if (ST2 & ST2_BC) { /* cylinder marked as bad */
1490 printk("bad cylinder");
1491 } else {
1492 printk
1493 ("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x",
1494 ST0, ST1, ST2);
1495 tell_sector();
1496 }
1497 printk("\n");
1498
1499 }
1500 if (ST2 & ST2_WC || ST2 & ST2_BC)
1501 /* wrong cylinder => recal */
1502 DRS->track = NEED_2_RECAL;
1503 return bad;
1504 case 0x80: /* invalid command given */
1505 DPRINT("Invalid FDC command given!\n");
1506 cont->done(0);
1507 return 2;
1508 case 0xc0:
1509 DPRINT("Abnormal termination caused by polling\n");
1510 cont->error();
1511 return 2;
1512 default: /* (0) Normal command termination */
1513 return 0;
1514 }
1515}
1516
1517/*
1518 * This routine is called when everything should be correctly set up
1519 * for the transfer (i.e. floppy motor is on, the correct floppy is
1520 * selected, and the head is sitting on the right track).
1521 */
1522static void setup_rw_floppy(void)
1523{
1524 int i, r, flags, dflags;
1525 unsigned long ready_date;
1526 timeout_fn function;
1527
1528 flags = raw_cmd->flags;
1529 if (flags & (FD_RAW_READ | FD_RAW_WRITE))
1530 flags |= FD_RAW_INTR;
1531
1532 if ((flags & FD_RAW_SPIN) && !(flags & FD_RAW_NO_MOTOR)) {
1533 ready_date = DRS->spinup_date + DP->spinup;
1534 /* If spinup will take a long time, rerun scandrives
1535 * again just before spinup completion. Beware that
1536 * after scandrives, we must again wait for selection.
1537 */
Marcelo Feitoza Parisi50297cb2006-03-28 01:56:44 -08001538 if (time_after(ready_date, jiffies + DP->select_delay)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 ready_date -= DP->select_delay;
1540 function = (timeout_fn) floppy_start;
1541 } else
1542 function = (timeout_fn) setup_rw_floppy;
1543
1544 /* wait until the floppy is spinning fast enough */
1545 if (fd_wait_for_completion(ready_date, function))
1546 return;
1547 }
1548 dflags = DRS->flags;
1549
1550 if ((flags & FD_RAW_READ) || (flags & FD_RAW_WRITE))
1551 setup_DMA();
1552
1553 if (flags & FD_RAW_INTR)
1554 do_floppy = main_command_interrupt;
1555
1556 r = 0;
1557 for (i = 0; i < raw_cmd->cmd_count; i++)
1558 r |= output_byte(raw_cmd->cmd[i]);
1559
1560 debugt("rw_command: ");
1561
1562 if (r) {
1563 cont->error();
1564 reset_fdc();
1565 return;
1566 }
1567
1568 if (!(flags & FD_RAW_INTR)) {
1569 inr = result();
1570 cont->interrupt();
1571 } else if (flags & FD_RAW_NEED_DISK)
1572 fd_watchdog();
1573}
1574
1575static int blind_seek;
1576
1577/*
1578 * This is the routine called after every seek (or recalibrate) interrupt
1579 * from the floppy controller.
1580 */
1581static void seek_interrupt(void)
1582{
1583 debugt("seek interrupt:");
1584 if (inr != 2 || (ST0 & 0xF8) != 0x20) {
1585 DPRINT("seek failed\n");
1586 DRS->track = NEED_2_RECAL;
1587 cont->error();
1588 cont->redo();
1589 return;
1590 }
1591 if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek) {
1592#ifdef DCL_DEBUG
1593 if (DP->flags & FD_DEBUG) {
1594 DPRINT
1595 ("clearing NEWCHANGE flag because of effective seek\n");
1596 DPRINT("jiffies=%lu\n", jiffies);
1597 }
1598#endif
1599 CLEARF(FD_DISK_NEWCHANGE); /* effective seek */
1600 DRS->select_date = jiffies;
1601 }
1602 DRS->track = ST1;
1603 floppy_ready();
1604}
1605
1606static void check_wp(void)
1607{
1608 if (TESTF(FD_VERIFY)) {
1609 /* check write protection */
1610 output_byte(FD_GETSTATUS);
1611 output_byte(UNIT(current_drive));
1612 if (result() != 1) {
1613 FDCS->reset = 1;
1614 return;
1615 }
1616 CLEARF(FD_VERIFY);
1617 CLEARF(FD_NEED_TWADDLE);
1618#ifdef DCL_DEBUG
1619 if (DP->flags & FD_DEBUG) {
1620 DPRINT("checking whether disk is write protected\n");
1621 DPRINT("wp=%x\n", ST3 & 0x40);
1622 }
1623#endif
1624 if (!(ST3 & 0x40))
1625 SETF(FD_DISK_WRITABLE);
1626 else
1627 CLEARF(FD_DISK_WRITABLE);
1628 }
1629}
1630
1631static void seek_floppy(void)
1632{
1633 int track;
1634
1635 blind_seek = 0;
1636
1637#ifdef DCL_DEBUG
1638 if (DP->flags & FD_DEBUG) {
1639 DPRINT("calling disk change from seek\n");
1640 }
1641#endif
1642
1643 if (!TESTF(FD_DISK_NEWCHANGE) &&
1644 disk_change(current_drive) && (raw_cmd->flags & FD_RAW_NEED_DISK)) {
1645 /* the media changed flag should be cleared after the seek.
1646 * If it isn't, this means that there is really no disk in
1647 * the drive.
1648 */
1649 SETF(FD_DISK_CHANGED);
1650 cont->done(0);
1651 cont->redo();
1652 return;
1653 }
1654 if (DRS->track <= NEED_1_RECAL) {
1655 recalibrate_floppy();
1656 return;
1657 } else if (TESTF(FD_DISK_NEWCHANGE) &&
1658 (raw_cmd->flags & FD_RAW_NEED_DISK) &&
1659 (DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) {
1660 /* we seek to clear the media-changed condition. Does anybody
1661 * know a more elegant way, which works on all drives? */
1662 if (raw_cmd->track)
1663 track = raw_cmd->track - 1;
1664 else {
1665 if (DP->flags & FD_SILENT_DCL_CLEAR) {
1666 set_dor(fdc, ~(0x10 << UNIT(current_drive)), 0);
1667 blind_seek = 1;
1668 raw_cmd->flags |= FD_RAW_NEED_SEEK;
1669 }
1670 track = 1;
1671 }
1672 } else {
1673 check_wp();
1674 if (raw_cmd->track != DRS->track &&
1675 (raw_cmd->flags & FD_RAW_NEED_SEEK))
1676 track = raw_cmd->track;
1677 else {
1678 setup_rw_floppy();
1679 return;
1680 }
1681 }
1682
1683 do_floppy = seek_interrupt;
1684 output_byte(FD_SEEK);
1685 output_byte(UNIT(current_drive));
1686 LAST_OUT(track);
1687 debugt("seek command:");
1688}
1689
1690static void recal_interrupt(void)
1691{
1692 debugt("recal interrupt:");
1693 if (inr != 2)
1694 FDCS->reset = 1;
1695 else if (ST0 & ST0_ECE) {
1696 switch (DRS->track) {
1697 case NEED_1_RECAL:
1698 debugt("recal interrupt need 1 recal:");
1699 /* after a second recalibrate, we still haven't
1700 * reached track 0. Probably no drive. Raise an
1701 * error, as failing immediately might upset
1702 * computers possessed by the Devil :-) */
1703 cont->error();
1704 cont->redo();
1705 return;
1706 case NEED_2_RECAL:
1707 debugt("recal interrupt need 2 recal:");
1708 /* If we already did a recalibrate,
1709 * and we are not at track 0, this
1710 * means we have moved. (The only way
1711 * not to move at recalibration is to
1712 * be already at track 0.) Clear the
1713 * new change flag */
1714#ifdef DCL_DEBUG
1715 if (DP->flags & FD_DEBUG) {
1716 DPRINT
1717 ("clearing NEWCHANGE flag because of second recalibrate\n");
1718 }
1719#endif
1720
1721 CLEARF(FD_DISK_NEWCHANGE);
1722 DRS->select_date = jiffies;
1723 /* fall through */
1724 default:
1725 debugt("recal interrupt default:");
1726 /* Recalibrate moves the head by at
1727 * most 80 steps. If after one
1728 * recalibrate we don't have reached
1729 * track 0, this might mean that we
1730 * started beyond track 80. Try
1731 * again. */
1732 DRS->track = NEED_1_RECAL;
1733 break;
1734 }
1735 } else
1736 DRS->track = ST1;
1737 floppy_ready();
1738}
1739
1740static void print_result(char *message, int inr)
1741{
1742 int i;
1743
1744 DPRINT("%s ", message);
1745 if (inr >= 0)
1746 for (i = 0; i < inr; i++)
1747 printk("repl[%d]=%x ", i, reply_buffer[i]);
1748 printk("\n");
1749}
1750
1751/* interrupt handler. Note that this can be called externally on the Sparc */
1752irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1753{
1754 void (*handler) (void) = do_floppy;
1755 int do_print;
1756 unsigned long f;
1757
1758 lasthandler = handler;
1759 interruptjiffies = jiffies;
1760
1761 f = claim_dma_lock();
1762 fd_disable_dma();
1763 release_dma_lock(f);
1764
1765 floppy_enable_hlt();
1766 do_floppy = NULL;
1767 if (fdc >= N_FDC || FDCS->address == -1) {
1768 /* we don't even know which FDC is the culprit */
1769 printk("DOR0=%x\n", fdc_state[0].dor);
1770 printk("floppy interrupt on bizarre fdc %d\n", fdc);
1771 printk("handler=%p\n", handler);
1772 is_alive("bizarre fdc");
1773 return IRQ_NONE;
1774 }
1775
1776 FDCS->reset = 0;
1777 /* We have to clear the reset flag here, because apparently on boxes
1778 * with level triggered interrupts (PS/2, Sparc, ...), it is needed to
1779 * emit SENSEI's to clear the interrupt line. And FDCS->reset blocks the
1780 * emission of the SENSEI's.
1781 * It is OK to emit floppy commands because we are in an interrupt
1782 * handler here, and thus we have to fear no interference of other
1783 * activity.
1784 */
1785
1786 do_print = !handler && print_unex && !initialising;
1787
1788 inr = result();
1789 if (do_print)
1790 print_result("unexpected interrupt", inr);
1791 if (inr == 0) {
1792 int max_sensei = 4;
1793 do {
1794 output_byte(FD_SENSEI);
1795 inr = result();
1796 if (do_print)
1797 print_result("sensei", inr);
1798 max_sensei--;
1799 } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2
1800 && max_sensei);
1801 }
1802 if (!handler) {
1803 FDCS->reset = 1;
1804 return IRQ_NONE;
1805 }
1806 schedule_bh(handler);
1807 is_alive("normal interrupt end");
1808
1809 /* FIXME! Was it really for us? */
1810 return IRQ_HANDLED;
1811}
1812
1813static void recalibrate_floppy(void)
1814{
1815 debugt("recalibrate floppy:");
1816 do_floppy = recal_interrupt;
1817 output_byte(FD_RECALIBRATE);
1818 LAST_OUT(UNIT(current_drive));
1819}
1820
1821/*
1822 * Must do 4 FD_SENSEIs after reset because of ``drive polling''.
1823 */
1824static void reset_interrupt(void)
1825{
1826 debugt("reset interrupt:");
1827 result(); /* get the status ready for set_fdc */
1828 if (FDCS->reset) {
1829 printk("reset set in interrupt, calling %p\n", cont->error);
1830 cont->error(); /* a reset just after a reset. BAD! */
1831 }
1832 cont->redo();
1833}
1834
1835/*
1836 * reset is done by pulling bit 2 of DOR low for a while (old FDCs),
1837 * or by setting the self clearing bit 7 of STATUS (newer FDCs)
1838 */
1839static void reset_fdc(void)
1840{
1841 unsigned long flags;
1842
1843 do_floppy = reset_interrupt;
1844 FDCS->reset = 0;
1845 reset_fdc_info(0);
1846
1847 /* Pseudo-DMA may intercept 'reset finished' interrupt. */
1848 /* Irrelevant for systems with true DMA (i386). */
1849
1850 flags = claim_dma_lock();
1851 fd_disable_dma();
1852 release_dma_lock(flags);
1853
1854 if (FDCS->version >= FDC_82072A)
1855 fd_outb(0x80 | (FDCS->dtr & 3), FD_STATUS);
1856 else {
1857 fd_outb(FDCS->dor & ~0x04, FD_DOR);
1858 udelay(FD_RESET_DELAY);
1859 fd_outb(FDCS->dor, FD_DOR);
1860 }
1861}
1862
1863static void show_floppy(void)
1864{
1865 int i;
1866
1867 printk("\n");
1868 printk("floppy driver state\n");
1869 printk("-------------------\n");
1870 printk("now=%lu last interrupt=%lu diff=%lu last called handler=%p\n",
1871 jiffies, interruptjiffies, jiffies - interruptjiffies,
1872 lasthandler);
1873
1874#ifdef FLOPPY_SANITY_CHECK
1875 printk("timeout_message=%s\n", timeout_message);
1876 printk("last output bytes:\n");
1877 for (i = 0; i < OLOGSIZE; i++)
1878 printk("%2x %2x %lu\n",
1879 output_log[(i + output_log_pos) % OLOGSIZE].data,
1880 output_log[(i + output_log_pos) % OLOGSIZE].status,
1881 output_log[(i + output_log_pos) % OLOGSIZE].jiffies);
1882 printk("last result at %lu\n", resultjiffies);
1883 printk("last redo_fd_request at %lu\n", lastredo);
1884 for (i = 0; i < resultsize; i++) {
1885 printk("%2x ", reply_buffer[i]);
1886 }
1887 printk("\n");
1888#endif
1889
1890 printk("status=%x\n", fd_inb(FD_STATUS));
1891 printk("fdc_busy=%lu\n", fdc_busy);
1892 if (do_floppy)
1893 printk("do_floppy=%p\n", do_floppy);
1894 if (floppy_work.pending)
1895 printk("floppy_work.func=%p\n", floppy_work.func);
1896 if (timer_pending(&fd_timer))
1897 printk("fd_timer.function=%p\n", fd_timer.function);
1898 if (timer_pending(&fd_timeout)) {
1899 printk("timer_function=%p\n", fd_timeout.function);
1900 printk("expires=%lu\n", fd_timeout.expires - jiffies);
1901 printk("now=%lu\n", jiffies);
1902 }
1903 printk("cont=%p\n", cont);
1904 printk("current_req=%p\n", current_req);
1905 printk("command_status=%d\n", command_status);
1906 printk("\n");
1907}
1908
1909static void floppy_shutdown(unsigned long data)
1910{
1911 unsigned long flags;
1912
1913 if (!initialising)
1914 show_floppy();
1915 cancel_activity();
1916
1917 floppy_enable_hlt();
1918
1919 flags = claim_dma_lock();
1920 fd_disable_dma();
1921 release_dma_lock(flags);
1922
1923 /* avoid dma going to a random drive after shutdown */
1924
1925 if (!initialising)
1926 DPRINT("floppy timeout called\n");
1927 FDCS->reset = 1;
1928 if (cont) {
1929 cont->done(0);
1930 cont->redo(); /* this will recall reset when needed */
1931 } else {
1932 printk("no cont in shutdown!\n");
1933 process_fd_request();
1934 }
1935 is_alive("floppy shutdown");
1936}
1937
1938/*typedef void (*timeout_fn)(unsigned long);*/
1939
1940/* start motor, check media-changed condition and write protection */
1941static int start_motor(void (*function) (void))
1942{
1943 int mask, data;
1944
1945 mask = 0xfc;
1946 data = UNIT(current_drive);
1947 if (!(raw_cmd->flags & FD_RAW_NO_MOTOR)) {
1948 if (!(FDCS->dor & (0x10 << UNIT(current_drive)))) {
1949 set_debugt();
1950 /* no read since this drive is running */
1951 DRS->first_read_date = 0;
1952 /* note motor start time if motor is not yet running */
1953 DRS->spinup_date = jiffies;
1954 data |= (0x10 << UNIT(current_drive));
1955 }
1956 } else if (FDCS->dor & (0x10 << UNIT(current_drive)))
1957 mask &= ~(0x10 << UNIT(current_drive));
1958
1959 /* starts motor and selects floppy */
1960 del_timer(motor_off_timer + current_drive);
1961 set_dor(fdc, mask, data);
1962
1963 /* wait_for_completion also schedules reset if needed. */
1964 return (fd_wait_for_completion(DRS->select_date + DP->select_delay,
1965 (timeout_fn) function));
1966}
1967
1968static void floppy_ready(void)
1969{
1970 CHECK_RESET;
1971 if (start_motor(floppy_ready))
1972 return;
1973 if (fdc_dtr())
1974 return;
1975
1976#ifdef DCL_DEBUG
1977 if (DP->flags & FD_DEBUG) {
1978 DPRINT("calling disk change from floppy_ready\n");
1979 }
1980#endif
1981 if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) &&
1982 disk_change(current_drive) && !DP->select_delay)
1983 twaddle(); /* this clears the dcl on certain drive/controller
1984 * combinations */
1985
1986#ifdef fd_chose_dma_mode
1987 if ((raw_cmd->flags & FD_RAW_READ) || (raw_cmd->flags & FD_RAW_WRITE)) {
1988 unsigned long flags = claim_dma_lock();
1989 fd_chose_dma_mode(raw_cmd->kernel_data, raw_cmd->length);
1990 release_dma_lock(flags);
1991 }
1992#endif
1993
1994 if (raw_cmd->flags & (FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK)) {
1995 perpendicular_mode();
1996 fdc_specify(); /* must be done here because of hut, hlt ... */
1997 seek_floppy();
1998 } else {
1999 if ((raw_cmd->flags & FD_RAW_READ) ||
2000 (raw_cmd->flags & FD_RAW_WRITE))
2001 fdc_specify();
2002 setup_rw_floppy();
2003 }
2004}
2005
2006static void floppy_start(void)
2007{
2008 reschedule_timeout(current_reqD, "floppy start", 0);
2009
2010 scandrives();
2011#ifdef DCL_DEBUG
2012 if (DP->flags & FD_DEBUG) {
2013 DPRINT("setting NEWCHANGE in floppy_start\n");
2014 }
2015#endif
2016 SETF(FD_DISK_NEWCHANGE);
2017 floppy_ready();
2018}
2019
2020/*
2021 * ========================================================================
2022 * here ends the bottom half. Exported routines are:
2023 * floppy_start, floppy_off, floppy_ready, lock_fdc, unlock_fdc, set_fdc,
2024 * start_motor, reset_fdc, reset_fdc_info, interpret_errors.
2025 * Initialization also uses output_byte, result, set_dor, floppy_interrupt
2026 * and set_dor.
2027 * ========================================================================
2028 */
2029/*
2030 * General purpose continuations.
2031 * ==============================
2032 */
2033
2034static void do_wakeup(void)
2035{
2036 reschedule_timeout(MAXTIMEOUT, "do wakeup", 0);
2037 cont = NULL;
2038 command_status += 2;
2039 wake_up(&command_done);
2040}
2041
2042static struct cont_t wakeup_cont = {
2043 .interrupt = empty,
2044 .redo = do_wakeup,
2045 .error = empty,
2046 .done = (done_f) empty
2047};
2048
2049static struct cont_t intr_cont = {
2050 .interrupt = empty,
2051 .redo = process_fd_request,
2052 .error = empty,
2053 .done = (done_f) empty
2054};
2055
2056static int wait_til_done(void (*handler) (void), int interruptible)
2057{
2058 int ret;
2059
2060 schedule_bh(handler);
2061
2062 if (command_status < 2 && NO_SIGNAL) {
2063 DECLARE_WAITQUEUE(wait, current);
2064
2065 add_wait_queue(&command_done, &wait);
2066 for (;;) {
2067 set_current_state(interruptible ?
2068 TASK_INTERRUPTIBLE :
2069 TASK_UNINTERRUPTIBLE);
2070
2071 if (command_status >= 2 || !NO_SIGNAL)
2072 break;
2073
2074 is_alive("wait_til_done");
2075
2076 schedule();
2077 }
2078
2079 set_current_state(TASK_RUNNING);
2080 remove_wait_queue(&command_done, &wait);
2081 }
2082
2083 if (command_status < 2) {
2084 cancel_activity();
2085 cont = &intr_cont;
2086 reset_fdc();
2087 return -EINTR;
2088 }
2089
2090 if (FDCS->reset)
2091 command_status = FD_COMMAND_ERROR;
2092 if (command_status == FD_COMMAND_OKAY)
2093 ret = 0;
2094 else
2095 ret = -EIO;
2096 command_status = FD_COMMAND_NONE;
2097 return ret;
2098}
2099
2100static void generic_done(int result)
2101{
2102 command_status = result;
2103 cont = &wakeup_cont;
2104}
2105
2106static void generic_success(void)
2107{
2108 cont->done(1);
2109}
2110
2111static void generic_failure(void)
2112{
2113 cont->done(0);
2114}
2115
2116static void success_and_wakeup(void)
2117{
2118 generic_success();
2119 cont->redo();
2120}
2121
2122/*
2123 * formatting and rw support.
2124 * ==========================
2125 */
2126
2127static int next_valid_format(void)
2128{
2129 int probed_format;
2130
2131 probed_format = DRS->probed_format;
2132 while (1) {
2133 if (probed_format >= 8 || !DP->autodetect[probed_format]) {
2134 DRS->probed_format = 0;
2135 return 1;
2136 }
2137 if (floppy_type[DP->autodetect[probed_format]].sect) {
2138 DRS->probed_format = probed_format;
2139 return 0;
2140 }
2141 probed_format++;
2142 }
2143}
2144
2145static void bad_flp_intr(void)
2146{
2147 int err_count;
2148
2149 if (probing) {
2150 DRS->probed_format++;
2151 if (!next_valid_format())
2152 return;
2153 }
2154 err_count = ++(*errors);
2155 INFBOUND(DRWE->badness, err_count);
2156 if (err_count > DP->max_errors.abort)
2157 cont->done(0);
2158 if (err_count > DP->max_errors.reset)
2159 FDCS->reset = 1;
2160 else if (err_count > DP->max_errors.recal)
2161 DRS->track = NEED_2_RECAL;
2162}
2163
2164static void set_floppy(int drive)
2165{
2166 int type = ITYPE(UDRS->fd_device);
2167 if (type)
2168 _floppy = floppy_type + type;
2169 else
2170 _floppy = current_type[drive];
2171}
2172
2173/*
2174 * formatting support.
2175 * ===================
2176 */
2177static void format_interrupt(void)
2178{
2179 switch (interpret_errors()) {
2180 case 1:
2181 cont->error();
2182 case 2:
2183 break;
2184 case 0:
2185 cont->done(1);
2186 }
2187 cont->redo();
2188}
2189
2190#define CODE2SIZE (ssize = ((1 << SIZECODE) + 3) >> 2)
2191#define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80) >>1))
2192#define CT(x) ((x) | 0xc0)
2193static void setup_format_params(int track)
2194{
2195 struct fparm {
2196 unsigned char track, head, sect, size;
2197 } *here = (struct fparm *)floppy_track_buffer;
2198 int il, n;
2199 int count, head_shift, track_shift;
2200
2201 raw_cmd = &default_raw_cmd;
2202 raw_cmd->track = track;
2203
2204 raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
2205 FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK;
2206 raw_cmd->rate = _floppy->rate & 0x43;
2207 raw_cmd->cmd_count = NR_F;
2208 COMMAND = FM_MODE(_floppy, FD_FORMAT);
2209 DR_SELECT = UNIT(current_drive) + PH_HEAD(_floppy, format_req.head);
2210 F_SIZECODE = FD_SIZECODE(_floppy);
2211 F_SECT_PER_TRACK = _floppy->sect << 2 >> F_SIZECODE;
2212 F_GAP = _floppy->fmt_gap;
2213 F_FILL = FD_FILL_BYTE;
2214
2215 raw_cmd->kernel_data = floppy_track_buffer;
2216 raw_cmd->length = 4 * F_SECT_PER_TRACK;
2217
2218 /* allow for about 30ms for data transport per track */
2219 head_shift = (F_SECT_PER_TRACK + 5) / 6;
2220
2221 /* a ``cylinder'' is two tracks plus a little stepping time */
2222 track_shift = 2 * head_shift + 3;
2223
2224 /* position of logical sector 1 on this track */
2225 n = (track_shift * format_req.track + head_shift * format_req.head)
2226 % F_SECT_PER_TRACK;
2227
2228 /* determine interleave */
2229 il = 1;
2230 if (_floppy->fmt_gap < 0x22)
2231 il++;
2232
2233 /* initialize field */
2234 for (count = 0; count < F_SECT_PER_TRACK; ++count) {
2235 here[count].track = format_req.track;
2236 here[count].head = format_req.head;
2237 here[count].sect = 0;
2238 here[count].size = F_SIZECODE;
2239 }
2240 /* place logical sectors */
2241 for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
2242 here[n].sect = count;
2243 n = (n + il) % F_SECT_PER_TRACK;
2244 if (here[n].sect) { /* sector busy, find next free sector */
2245 ++n;
2246 if (n >= F_SECT_PER_TRACK) {
2247 n -= F_SECT_PER_TRACK;
2248 while (here[n].sect)
2249 ++n;
2250 }
2251 }
2252 }
2253 if (_floppy->stretch & FD_ZEROBASED) {
2254 for (count = 0; count < F_SECT_PER_TRACK; count++)
2255 here[count].sect--;
2256 }
2257}
2258
2259static void redo_format(void)
2260{
2261 buffer_track = -1;
2262 setup_format_params(format_req.track << STRETCH(_floppy));
2263 floppy_start();
2264 debugt("queue format request");
2265}
2266
2267static struct cont_t format_cont = {
2268 .interrupt = format_interrupt,
2269 .redo = redo_format,
2270 .error = bad_flp_intr,
2271 .done = generic_done
2272};
2273
2274static int do_format(int drive, struct format_descr *tmp_format_req)
2275{
2276 int ret;
2277
2278 LOCK_FDC(drive, 1);
2279 set_floppy(drive);
2280 if (!_floppy ||
2281 _floppy->track > DP->tracks ||
2282 tmp_format_req->track >= _floppy->track ||
2283 tmp_format_req->head >= _floppy->head ||
2284 (_floppy->sect << 2) % (1 << FD_SIZECODE(_floppy)) ||
2285 !_floppy->fmt_gap) {
2286 process_fd_request();
2287 return -EINVAL;
2288 }
2289 format_req = *tmp_format_req;
2290 format_errors = 0;
2291 cont = &format_cont;
2292 errors = &format_errors;
2293 IWAIT(redo_format);
2294 process_fd_request();
2295 return ret;
2296}
2297
2298/*
2299 * Buffer read/write and support
2300 * =============================
2301 */
2302
2303static void floppy_end_request(struct request *req, int uptodate)
2304{
2305 unsigned int nr_sectors = current_count_sectors;
2306
2307 /* current_count_sectors can be zero if transfer failed */
2308 if (!uptodate)
2309 nr_sectors = req->current_nr_sectors;
2310 if (end_that_request_first(req, uptodate, nr_sectors))
2311 return;
2312 add_disk_randomness(req->rq_disk);
2313 floppy_off((long)req->rq_disk->private_data);
2314 blkdev_dequeue_request(req);
Tejun Heo8ffdc652006-01-06 09:49:03 +01002315 end_that_request_last(req, uptodate);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316
2317 /* We're done with the request */
2318 current_req = NULL;
2319}
2320
2321/* new request_done. Can handle physical sectors which are smaller than a
2322 * logical buffer */
2323static void request_done(int uptodate)
2324{
2325 struct request_queue *q = floppy_queue;
2326 struct request *req = current_req;
2327 unsigned long flags;
2328 int block;
2329
2330 probing = 0;
2331 reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
2332
2333 if (!req) {
2334 printk("floppy.c: no request in request_done\n");
2335 return;
2336 }
2337
2338 if (uptodate) {
2339 /* maintain values for invalidation on geometry
2340 * change */
2341 block = current_count_sectors + req->sector;
2342 INFBOUND(DRS->maxblock, block);
2343 if (block > _floppy->sect)
2344 DRS->maxtrack = 1;
2345
2346 /* unlock chained buffers */
2347 spin_lock_irqsave(q->queue_lock, flags);
2348 floppy_end_request(req, 1);
2349 spin_unlock_irqrestore(q->queue_lock, flags);
2350 } else {
2351 if (rq_data_dir(req) == WRITE) {
2352 /* record write error information */
2353 DRWE->write_errors++;
2354 if (DRWE->write_errors == 1) {
2355 DRWE->first_error_sector = req->sector;
2356 DRWE->first_error_generation = DRS->generation;
2357 }
2358 DRWE->last_error_sector = req->sector;
2359 DRWE->last_error_generation = DRS->generation;
2360 }
2361 spin_lock_irqsave(q->queue_lock, flags);
2362 floppy_end_request(req, 0);
2363 spin_unlock_irqrestore(q->queue_lock, flags);
2364 }
2365}
2366
2367/* Interrupt handler evaluating the result of the r/w operation */
2368static void rw_interrupt(void)
2369{
2370 int nr_sectors, ssize, eoc, heads;
2371
2372 if (R_HEAD >= 2) {
2373 /* some Toshiba floppy controllers occasionnally seem to
2374 * return bogus interrupts after read/write operations, which
2375 * can be recognized by a bad head number (>= 2) */
2376 return;
2377 }
2378
2379 if (!DRS->first_read_date)
2380 DRS->first_read_date = jiffies;
2381
2382 nr_sectors = 0;
2383 CODE2SIZE;
2384
2385 if (ST1 & ST1_EOC)
2386 eoc = 1;
2387 else
2388 eoc = 0;
2389
2390 if (COMMAND & 0x80)
2391 heads = 2;
2392 else
2393 heads = 1;
2394
2395 nr_sectors = (((R_TRACK - TRACK) * heads +
2396 R_HEAD - HEAD) * SECT_PER_TRACK +
2397 R_SECTOR - SECTOR + eoc) << SIZECODE >> 2;
2398
2399#ifdef FLOPPY_SANITY_CHECK
2400 if (nr_sectors / ssize >
2401 (in_sector_offset + current_count_sectors + ssize - 1) / ssize) {
2402 DPRINT("long rw: %x instead of %lx\n",
2403 nr_sectors, current_count_sectors);
2404 printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
2405 printk("rh=%d h=%d\n", R_HEAD, HEAD);
2406 printk("rt=%d t=%d\n", R_TRACK, TRACK);
2407 printk("heads=%d eoc=%d\n", heads, eoc);
2408 printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
2409 fsector_t, ssize);
2410 printk("in_sector_offset=%d\n", in_sector_offset);
2411 }
2412#endif
2413
2414 nr_sectors -= in_sector_offset;
2415 INFBOUND(nr_sectors, 0);
2416 SUPBOUND(current_count_sectors, nr_sectors);
2417
2418 switch (interpret_errors()) {
2419 case 2:
2420 cont->redo();
2421 return;
2422 case 1:
2423 if (!current_count_sectors) {
2424 cont->error();
2425 cont->redo();
2426 return;
2427 }
2428 break;
2429 case 0:
2430 if (!current_count_sectors) {
2431 cont->redo();
2432 return;
2433 }
2434 current_type[current_drive] = _floppy;
2435 floppy_sizes[TOMINOR(current_drive)] = _floppy->size;
2436 break;
2437 }
2438
2439 if (probing) {
2440 if (DP->flags & FTD_MSG)
2441 DPRINT("Auto-detected floppy type %s in fd%d\n",
2442 _floppy->name, current_drive);
2443 current_type[current_drive] = _floppy;
2444 floppy_sizes[TOMINOR(current_drive)] = _floppy->size;
2445 probing = 0;
2446 }
2447
2448 if (CT(COMMAND) != FD_READ ||
2449 raw_cmd->kernel_data == current_req->buffer) {
2450 /* transfer directly from buffer */
2451 cont->done(1);
2452 } else if (CT(COMMAND) == FD_READ) {
2453 buffer_track = raw_cmd->track;
2454 buffer_drive = current_drive;
2455 INFBOUND(buffer_max, nr_sectors + fsector_t);
2456 }
2457 cont->redo();
2458}
2459
2460/* Compute maximal contiguous buffer size. */
2461static int buffer_chain_size(void)
2462{
2463 struct bio *bio;
2464 struct bio_vec *bv;
2465 int size, i;
2466 char *base;
2467
2468 base = bio_data(current_req->bio);
2469 size = 0;
2470
2471 rq_for_each_bio(bio, current_req) {
2472 bio_for_each_segment(bv, bio, i) {
2473 if (page_address(bv->bv_page) + bv->bv_offset !=
2474 base + size)
2475 break;
2476
2477 size += bv->bv_len;
2478 }
2479 }
2480
2481 return size >> 9;
2482}
2483
2484/* Compute the maximal transfer size */
2485static int transfer_size(int ssize, int max_sector, int max_size)
2486{
2487 SUPBOUND(max_sector, fsector_t + max_size);
2488
2489 /* alignment */
2490 max_sector -= (max_sector % _floppy->sect) % ssize;
2491
2492 /* transfer size, beginning not aligned */
2493 current_count_sectors = max_sector - fsector_t;
2494
2495 return max_sector;
2496}
2497
2498/*
2499 * Move data from/to the track buffer to/from the buffer cache.
2500 */
2501static void copy_buffer(int ssize, int max_sector, int max_sector_2)
2502{
2503 int remaining; /* number of transferred 512-byte sectors */
2504 struct bio_vec *bv;
2505 struct bio *bio;
2506 char *buffer, *dma_buffer;
2507 int size, i;
2508
2509 max_sector = transfer_size(ssize,
2510 min(max_sector, max_sector_2),
2511 current_req->nr_sectors);
2512
2513 if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
2514 buffer_max > fsector_t + current_req->nr_sectors)
2515 current_count_sectors = min_t(int, buffer_max - fsector_t,
2516 current_req->nr_sectors);
2517
2518 remaining = current_count_sectors << 9;
2519#ifdef FLOPPY_SANITY_CHECK
2520 if ((remaining >> 9) > current_req->nr_sectors &&
2521 CT(COMMAND) == FD_WRITE) {
2522 DPRINT("in copy buffer\n");
2523 printk("current_count_sectors=%ld\n", current_count_sectors);
2524 printk("remaining=%d\n", remaining >> 9);
2525 printk("current_req->nr_sectors=%ld\n",
2526 current_req->nr_sectors);
2527 printk("current_req->current_nr_sectors=%u\n",
2528 current_req->current_nr_sectors);
2529 printk("max_sector=%d\n", max_sector);
2530 printk("ssize=%d\n", ssize);
2531 }
2532#endif
2533
2534 buffer_max = max(max_sector, buffer_max);
2535
2536 dma_buffer = floppy_track_buffer + ((fsector_t - buffer_min) << 9);
2537
2538 size = current_req->current_nr_sectors << 9;
2539
2540 rq_for_each_bio(bio, current_req) {
2541 bio_for_each_segment(bv, bio, i) {
2542 if (!remaining)
2543 break;
2544
2545 size = bv->bv_len;
2546 SUPBOUND(size, remaining);
2547
2548 buffer = page_address(bv->bv_page) + bv->bv_offset;
2549#ifdef FLOPPY_SANITY_CHECK
2550 if (dma_buffer + size >
2551 floppy_track_buffer + (max_buffer_sectors << 10) ||
2552 dma_buffer < floppy_track_buffer) {
2553 DPRINT("buffer overrun in copy buffer %d\n",
2554 (int)((floppy_track_buffer -
2555 dma_buffer) >> 9));
2556 printk("fsector_t=%d buffer_min=%d\n",
2557 fsector_t, buffer_min);
2558 printk("current_count_sectors=%ld\n",
2559 current_count_sectors);
2560 if (CT(COMMAND) == FD_READ)
2561 printk("read\n");
2562 if (CT(COMMAND) == FD_WRITE)
2563 printk("write\n");
2564 break;
2565 }
2566 if (((unsigned long)buffer) % 512)
2567 DPRINT("%p buffer not aligned\n", buffer);
2568#endif
2569 if (CT(COMMAND) == FD_READ)
2570 memcpy(buffer, dma_buffer, size);
2571 else
2572 memcpy(dma_buffer, buffer, size);
2573
2574 remaining -= size;
2575 dma_buffer += size;
2576 }
2577 }
2578#ifdef FLOPPY_SANITY_CHECK
2579 if (remaining) {
2580 if (remaining > 0)
2581 max_sector -= remaining >> 9;
2582 DPRINT("weirdness: remaining %d\n", remaining >> 9);
2583 }
2584#endif
2585}
2586
2587#if 0
2588static inline int check_dma_crossing(char *start,
2589 unsigned long length, char *message)
2590{
2591 if (CROSS_64KB(start, length)) {
2592 printk("DMA xfer crosses 64KB boundary in %s %p-%p\n",
2593 message, start, start + length);
2594 return 1;
2595 } else
2596 return 0;
2597}
2598#endif
2599
2600/* work around a bug in pseudo DMA
2601 * (on some FDCs) pseudo DMA does not stop when the CPU stops
2602 * sending data. Hence we need a different way to signal the
2603 * transfer length: We use SECT_PER_TRACK. Unfortunately, this
2604 * does not work with MT, hence we can only transfer one head at
2605 * a time
2606 */
2607static void virtualdmabug_workaround(void)
2608{
2609 int hard_sectors, end_sector;
2610
2611 if (CT(COMMAND) == FD_WRITE) {
2612 COMMAND &= ~0x80; /* switch off multiple track mode */
2613
2614 hard_sectors = raw_cmd->length >> (7 + SIZECODE);
2615 end_sector = SECTOR + hard_sectors - 1;
2616#ifdef FLOPPY_SANITY_CHECK
2617 if (end_sector > SECT_PER_TRACK) {
2618 printk("too many sectors %d > %d\n",
2619 end_sector, SECT_PER_TRACK);
2620 return;
2621 }
2622#endif
2623 SECT_PER_TRACK = end_sector; /* make sure SECT_PER_TRACK points
2624 * to end of transfer */
2625 }
2626}
2627
2628/*
2629 * Formulate a read/write request.
2630 * this routine decides where to load the data (directly to buffer, or to
2631 * tmp floppy area), how much data to load (the size of the buffer, the whole
2632 * track, or a single sector)
2633 * All floppy_track_buffer handling goes in here. If we ever add track buffer
2634 * allocation on the fly, it should be done here. No other part should need
2635 * modification.
2636 */
2637
2638static int make_raw_rw_request(void)
2639{
2640 int aligned_sector_t;
2641 int max_sector, max_size, tracksize, ssize;
2642
2643 if (max_buffer_sectors == 0) {
2644 printk("VFS: Block I/O scheduled on unopened device\n");
2645 return 0;
2646 }
2647
2648 set_fdc((long)current_req->rq_disk->private_data);
2649
2650 raw_cmd = &default_raw_cmd;
2651 raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
2652 FD_RAW_NEED_SEEK;
2653 raw_cmd->cmd_count = NR_RW;
2654 if (rq_data_dir(current_req) == READ) {
2655 raw_cmd->flags |= FD_RAW_READ;
2656 COMMAND = FM_MODE(_floppy, FD_READ);
2657 } else if (rq_data_dir(current_req) == WRITE) {
2658 raw_cmd->flags |= FD_RAW_WRITE;
2659 COMMAND = FM_MODE(_floppy, FD_WRITE);
2660 } else {
2661 DPRINT("make_raw_rw_request: unknown command\n");
2662 return 0;
2663 }
2664
2665 max_sector = _floppy->sect * _floppy->head;
2666
2667 TRACK = (int)current_req->sector / max_sector;
2668 fsector_t = (int)current_req->sector % max_sector;
2669 if (_floppy->track && TRACK >= _floppy->track) {
2670 if (current_req->current_nr_sectors & 1) {
2671 current_count_sectors = 1;
2672 return 1;
2673 } else
2674 return 0;
2675 }
2676 HEAD = fsector_t / _floppy->sect;
2677
2678 if (((_floppy->stretch & (FD_SWAPSIDES | FD_ZEROBASED)) ||
2679 TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect)
2680 max_sector = _floppy->sect;
2681
2682 /* 2M disks have phantom sectors on the first track */
2683 if ((_floppy->rate & FD_2M) && (!TRACK) && (!HEAD)) {
2684 max_sector = 2 * _floppy->sect / 3;
2685 if (fsector_t >= max_sector) {
2686 current_count_sectors =
2687 min_t(int, _floppy->sect - fsector_t,
2688 current_req->nr_sectors);
2689 return 1;
2690 }
2691 SIZECODE = 2;
2692 } else
2693 SIZECODE = FD_SIZECODE(_floppy);
2694 raw_cmd->rate = _floppy->rate & 0x43;
2695 if ((_floppy->rate & FD_2M) && (TRACK || HEAD) && raw_cmd->rate == 2)
2696 raw_cmd->rate = 1;
2697
2698 if (SIZECODE)
2699 SIZECODE2 = 0xff;
2700 else
2701 SIZECODE2 = 0x80;
2702 raw_cmd->track = TRACK << STRETCH(_floppy);
2703 DR_SELECT = UNIT(current_drive) + PH_HEAD(_floppy, HEAD);
2704 GAP = _floppy->gap;
2705 CODE2SIZE;
2706 SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE;
2707 SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) +
2708 ((_floppy->stretch & FD_ZEROBASED) ? 0 : 1);
2709
2710 /* tracksize describes the size which can be filled up with sectors
2711 * of size ssize.
2712 */
2713 tracksize = _floppy->sect - _floppy->sect % ssize;
2714 if (tracksize < _floppy->sect) {
2715 SECT_PER_TRACK++;
2716 if (tracksize <= fsector_t % _floppy->sect)
2717 SECTOR--;
2718
2719 /* if we are beyond tracksize, fill up using smaller sectors */
2720 while (tracksize <= fsector_t % _floppy->sect) {
2721 while (tracksize + ssize > _floppy->sect) {
2722 SIZECODE--;
2723 ssize >>= 1;
2724 }
2725 SECTOR++;
2726 SECT_PER_TRACK++;
2727 tracksize += ssize;
2728 }
2729 max_sector = HEAD * _floppy->sect + tracksize;
2730 } else if (!TRACK && !HEAD && !(_floppy->rate & FD_2M) && probing) {
2731 max_sector = _floppy->sect;
2732 } else if (!HEAD && CT(COMMAND) == FD_WRITE) {
2733 /* for virtual DMA bug workaround */
2734 max_sector = _floppy->sect;
2735 }
2736
2737 in_sector_offset = (fsector_t % _floppy->sect) % ssize;
2738 aligned_sector_t = fsector_t - in_sector_offset;
2739 max_size = current_req->nr_sectors;
2740 if ((raw_cmd->track == buffer_track) &&
2741 (current_drive == buffer_drive) &&
2742 (fsector_t >= buffer_min) && (fsector_t < buffer_max)) {
2743 /* data already in track buffer */
2744 if (CT(COMMAND) == FD_READ) {
2745 copy_buffer(1, max_sector, buffer_max);
2746 return 1;
2747 }
2748 } else if (in_sector_offset || current_req->nr_sectors < ssize) {
2749 if (CT(COMMAND) == FD_WRITE) {
2750 if (fsector_t + current_req->nr_sectors > ssize &&
2751 fsector_t + current_req->nr_sectors < ssize + ssize)
2752 max_size = ssize + ssize;
2753 else
2754 max_size = ssize;
2755 }
2756 raw_cmd->flags &= ~FD_RAW_WRITE;
2757 raw_cmd->flags |= FD_RAW_READ;
2758 COMMAND = FM_MODE(_floppy, FD_READ);
2759 } else if ((unsigned long)current_req->buffer < MAX_DMA_ADDRESS) {
2760 unsigned long dma_limit;
2761 int direct, indirect;
2762
2763 indirect =
2764 transfer_size(ssize, max_sector,
2765 max_buffer_sectors * 2) - fsector_t;
2766
2767 /*
2768 * Do NOT use minimum() here---MAX_DMA_ADDRESS is 64 bits wide
2769 * on a 64 bit machine!
2770 */
2771 max_size = buffer_chain_size();
2772 dma_limit =
2773 (MAX_DMA_ADDRESS -
2774 ((unsigned long)current_req->buffer)) >> 9;
2775 if ((unsigned long)max_size > dma_limit) {
2776 max_size = dma_limit;
2777 }
2778 /* 64 kb boundaries */
2779 if (CROSS_64KB(current_req->buffer, max_size << 9))
2780 max_size = (K_64 -
2781 ((unsigned long)current_req->buffer) %
2782 K_64) >> 9;
2783 direct = transfer_size(ssize, max_sector, max_size) - fsector_t;
2784 /*
2785 * We try to read tracks, but if we get too many errors, we
2786 * go back to reading just one sector at a time.
2787 *
2788 * This means we should be able to read a sector even if there
2789 * are other bad sectors on this track.
2790 */
2791 if (!direct ||
2792 (indirect * 2 > direct * 3 &&
2793 *errors < DP->max_errors.read_track &&
2794 /*!TESTF(FD_NEED_TWADDLE) && */
2795 ((!probing
2796 || (DP->read_track & (1 << DRS->probed_format)))))) {
2797 max_size = current_req->nr_sectors;
2798 } else {
2799 raw_cmd->kernel_data = current_req->buffer;
2800 raw_cmd->length = current_count_sectors << 9;
2801 if (raw_cmd->length == 0) {
2802 DPRINT
2803 ("zero dma transfer attempted from make_raw_request\n");
2804 DPRINT("indirect=%d direct=%d fsector_t=%d",
2805 indirect, direct, fsector_t);
2806 return 0;
2807 }
2808/* check_dma_crossing(raw_cmd->kernel_data,
2809 raw_cmd->length,
2810 "end of make_raw_request [1]");*/
2811
2812 virtualdmabug_workaround();
2813 return 2;
2814 }
2815 }
2816
2817 if (CT(COMMAND) == FD_READ)
2818 max_size = max_sector; /* unbounded */
2819
2820 /* claim buffer track if needed */
2821 if (buffer_track != raw_cmd->track || /* bad track */
2822 buffer_drive != current_drive || /* bad drive */
2823 fsector_t > buffer_max ||
2824 fsector_t < buffer_min ||
2825 ((CT(COMMAND) == FD_READ ||
2826 (!in_sector_offset && current_req->nr_sectors >= ssize)) &&
2827 max_sector > 2 * max_buffer_sectors + buffer_min &&
2828 max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)
2829 /* not enough space */
2830 ) {
2831 buffer_track = -1;
2832 buffer_drive = current_drive;
2833 buffer_max = buffer_min = aligned_sector_t;
2834 }
2835 raw_cmd->kernel_data = floppy_track_buffer +
2836 ((aligned_sector_t - buffer_min) << 9);
2837
2838 if (CT(COMMAND) == FD_WRITE) {
2839 /* copy write buffer to track buffer.
2840 * if we get here, we know that the write
2841 * is either aligned or the data already in the buffer
2842 * (buffer will be overwritten) */
2843#ifdef FLOPPY_SANITY_CHECK
2844 if (in_sector_offset && buffer_track == -1)
2845 DPRINT("internal error offset !=0 on write\n");
2846#endif
2847 buffer_track = raw_cmd->track;
2848 buffer_drive = current_drive;
2849 copy_buffer(ssize, max_sector,
2850 2 * max_buffer_sectors + buffer_min);
2851 } else
2852 transfer_size(ssize, max_sector,
2853 2 * max_buffer_sectors + buffer_min -
2854 aligned_sector_t);
2855
2856 /* round up current_count_sectors to get dma xfer size */
2857 raw_cmd->length = in_sector_offset + current_count_sectors;
2858 raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1;
2859 raw_cmd->length <<= 9;
2860#ifdef FLOPPY_SANITY_CHECK
2861 /*check_dma_crossing(raw_cmd->kernel_data, raw_cmd->length,
2862 "end of make_raw_request"); */
2863 if ((raw_cmd->length < current_count_sectors << 9) ||
2864 (raw_cmd->kernel_data != current_req->buffer &&
2865 CT(COMMAND) == FD_WRITE &&
2866 (aligned_sector_t + (raw_cmd->length >> 9) > buffer_max ||
2867 aligned_sector_t < buffer_min)) ||
2868 raw_cmd->length % (128 << SIZECODE) ||
2869 raw_cmd->length <= 0 || current_count_sectors <= 0) {
2870 DPRINT("fractionary current count b=%lx s=%lx\n",
2871 raw_cmd->length, current_count_sectors);
2872 if (raw_cmd->kernel_data != current_req->buffer)
2873 printk("addr=%d, length=%ld\n",
2874 (int)((raw_cmd->kernel_data -
2875 floppy_track_buffer) >> 9),
2876 current_count_sectors);
2877 printk("st=%d ast=%d mse=%d msi=%d\n",
2878 fsector_t, aligned_sector_t, max_sector, max_size);
2879 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2880 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2881 COMMAND, SECTOR, HEAD, TRACK);
2882 printk("buffer drive=%d\n", buffer_drive);
2883 printk("buffer track=%d\n", buffer_track);
2884 printk("buffer_min=%d\n", buffer_min);
2885 printk("buffer_max=%d\n", buffer_max);
2886 return 0;
2887 }
2888
2889 if (raw_cmd->kernel_data != current_req->buffer) {
2890 if (raw_cmd->kernel_data < floppy_track_buffer ||
2891 current_count_sectors < 0 ||
2892 raw_cmd->length < 0 ||
2893 raw_cmd->kernel_data + raw_cmd->length >
2894 floppy_track_buffer + (max_buffer_sectors << 10)) {
2895 DPRINT("buffer overrun in schedule dma\n");
2896 printk("fsector_t=%d buffer_min=%d current_count=%ld\n",
2897 fsector_t, buffer_min, raw_cmd->length >> 9);
2898 printk("current_count_sectors=%ld\n",
2899 current_count_sectors);
2900 if (CT(COMMAND) == FD_READ)
2901 printk("read\n");
2902 if (CT(COMMAND) == FD_WRITE)
2903 printk("write\n");
2904 return 0;
2905 }
2906 } else if (raw_cmd->length > current_req->nr_sectors << 9 ||
2907 current_count_sectors > current_req->nr_sectors) {
2908 DPRINT("buffer overrun in direct transfer\n");
2909 return 0;
2910 } else if (raw_cmd->length < current_count_sectors << 9) {
2911 DPRINT("more sectors than bytes\n");
2912 printk("bytes=%ld\n", raw_cmd->length >> 9);
2913 printk("sectors=%ld\n", current_count_sectors);
2914 }
2915 if (raw_cmd->length == 0) {
2916 DPRINT("zero dma transfer attempted from make_raw_request\n");
2917 return 0;
2918 }
2919#endif
2920
2921 virtualdmabug_workaround();
2922 return 2;
2923}
2924
2925static void redo_fd_request(void)
2926{
2927#define REPEAT {request_done(0); continue; }
2928 int drive;
2929 int tmp;
2930
2931 lastredo = jiffies;
2932 if (current_drive < N_DRIVE)
2933 floppy_off(current_drive);
2934
2935 for (;;) {
2936 if (!current_req) {
2937 struct request *req;
2938
2939 spin_lock_irq(floppy_queue->queue_lock);
2940 req = elv_next_request(floppy_queue);
2941 spin_unlock_irq(floppy_queue->queue_lock);
2942 if (!req) {
2943 do_floppy = NULL;
2944 unlock_fdc();
2945 return;
2946 }
2947 current_req = req;
2948 }
2949 drive = (long)current_req->rq_disk->private_data;
2950 set_fdc(drive);
2951 reschedule_timeout(current_reqD, "redo fd request", 0);
2952
2953 set_floppy(drive);
2954 raw_cmd = &default_raw_cmd;
2955 raw_cmd->flags = 0;
2956 if (start_motor(redo_fd_request))
2957 return;
2958 disk_change(current_drive);
2959 if (test_bit(current_drive, &fake_change) ||
2960 TESTF(FD_DISK_CHANGED)) {
2961 DPRINT("disk absent or changed during operation\n");
2962 REPEAT;
2963 }
2964 if (!_floppy) { /* Autodetection */
2965 if (!probing) {
2966 DRS->probed_format = 0;
2967 if (next_valid_format()) {
2968 DPRINT("no autodetectable formats\n");
2969 _floppy = NULL;
2970 REPEAT;
2971 }
2972 }
2973 probing = 1;
2974 _floppy =
2975 floppy_type + DP->autodetect[DRS->probed_format];
2976 } else
2977 probing = 0;
2978 errors = &(current_req->errors);
2979 tmp = make_raw_rw_request();
2980 if (tmp < 2) {
2981 request_done(tmp);
2982 continue;
2983 }
2984
2985 if (TESTF(FD_NEED_TWADDLE))
2986 twaddle();
2987 schedule_bh(floppy_start);
2988 debugt("queue fd request");
2989 return;
2990 }
2991#undef REPEAT
2992}
2993
2994static struct cont_t rw_cont = {
2995 .interrupt = rw_interrupt,
2996 .redo = redo_fd_request,
2997 .error = bad_flp_intr,
2998 .done = request_done
2999};
3000
3001static void process_fd_request(void)
3002{
3003 cont = &rw_cont;
3004 schedule_bh(redo_fd_request);
3005}
3006
3007static void do_fd_request(request_queue_t * q)
3008{
3009 if (max_buffer_sectors == 0) {
3010 printk("VFS: do_fd_request called on non-open device\n");
3011 return;
3012 }
3013
3014 if (usage_count == 0) {
3015 printk("warning: usage count=0, current_req=%p exiting\n",
3016 current_req);
3017 printk("sect=%ld flags=%lx\n", (long)current_req->sector,
3018 current_req->flags);
3019 return;
3020 }
3021 if (test_bit(0, &fdc_busy)) {
3022 /* fdc busy, this new request will be treated when the
3023 current one is done */
3024 is_alive("do fd request, old request running");
3025 return;
3026 }
3027 lock_fdc(MAXTIMEOUT, 0);
3028 process_fd_request();
3029 is_alive("do fd request");
3030}
3031
3032static struct cont_t poll_cont = {
3033 .interrupt = success_and_wakeup,
3034 .redo = floppy_ready,
3035 .error = generic_failure,
3036 .done = generic_done
3037};
3038
3039static int poll_drive(int interruptible, int flag)
3040{
3041 int ret;
3042 /* no auto-sense, just clear dcl */
3043 raw_cmd = &default_raw_cmd;
3044 raw_cmd->flags = flag;
3045 raw_cmd->track = 0;
3046 raw_cmd->cmd_count = 0;
3047 cont = &poll_cont;
3048#ifdef DCL_DEBUG
3049 if (DP->flags & FD_DEBUG) {
3050 DPRINT("setting NEWCHANGE in poll_drive\n");
3051 }
3052#endif
3053 SETF(FD_DISK_NEWCHANGE);
3054 WAIT(floppy_ready);
3055 return ret;
3056}
3057
3058/*
3059 * User triggered reset
3060 * ====================
3061 */
3062
3063static void reset_intr(void)
3064{
3065 printk("weird, reset interrupt called\n");
3066}
3067
3068static struct cont_t reset_cont = {
3069 .interrupt = reset_intr,
3070 .redo = success_and_wakeup,
3071 .error = generic_failure,
3072 .done = generic_done
3073};
3074
3075static int user_reset_fdc(int drive, int arg, int interruptible)
3076{
3077 int ret;
3078
3079 ret = 0;
3080 LOCK_FDC(drive, interruptible);
3081 if (arg == FD_RESET_ALWAYS)
3082 FDCS->reset = 1;
3083 if (FDCS->reset) {
3084 cont = &reset_cont;
3085 WAIT(reset_fdc);
3086 }
3087 process_fd_request();
3088 return ret;
3089}
3090
3091/*
3092 * Misc Ioctl's and support
3093 * ========================
3094 */
3095static inline int fd_copyout(void __user *param, const void *address,
3096 unsigned long size)
3097{
3098 return copy_to_user(param, address, size) ? -EFAULT : 0;
3099}
3100
3101static inline int fd_copyin(void __user *param, void *address, unsigned long size)
3102{
3103 return copy_from_user(address, param, size) ? -EFAULT : 0;
3104}
3105
3106#define _COPYOUT(x) (copy_to_user((void __user *)param, &(x), sizeof(x)) ? -EFAULT : 0)
3107#define _COPYIN(x) (copy_from_user(&(x), (void __user *)param, sizeof(x)) ? -EFAULT : 0)
3108
3109#define COPYOUT(x) ECALL(_COPYOUT(x))
3110#define COPYIN(x) ECALL(_COPYIN(x))
3111
3112static inline const char *drive_name(int type, int drive)
3113{
3114 struct floppy_struct *floppy;
3115
3116 if (type)
3117 floppy = floppy_type + type;
3118 else {
3119 if (UDP->native_format)
3120 floppy = floppy_type + UDP->native_format;
3121 else
3122 return "(null)";
3123 }
3124 if (floppy->name)
3125 return floppy->name;
3126 else
3127 return "(null)";
3128}
3129
3130/* raw commands */
3131static void raw_cmd_done(int flag)
3132{
3133 int i;
3134
3135 if (!flag) {
3136 raw_cmd->flags |= FD_RAW_FAILURE;
3137 raw_cmd->flags |= FD_RAW_HARDFAILURE;
3138 } else {
3139 raw_cmd->reply_count = inr;
3140 if (raw_cmd->reply_count > MAX_REPLIES)
3141 raw_cmd->reply_count = 0;
3142 for (i = 0; i < raw_cmd->reply_count; i++)
3143 raw_cmd->reply[i] = reply_buffer[i];
3144
3145 if (raw_cmd->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
3146 unsigned long flags;
3147 flags = claim_dma_lock();
3148 raw_cmd->length = fd_get_dma_residue();
3149 release_dma_lock(flags);
3150 }
3151
3152 if ((raw_cmd->flags & FD_RAW_SOFTFAILURE) &&
3153 (!raw_cmd->reply_count || (raw_cmd->reply[0] & 0xc0)))
3154 raw_cmd->flags |= FD_RAW_FAILURE;
3155
3156 if (disk_change(current_drive))
3157 raw_cmd->flags |= FD_RAW_DISK_CHANGE;
3158 else
3159 raw_cmd->flags &= ~FD_RAW_DISK_CHANGE;
3160 if (raw_cmd->flags & FD_RAW_NO_MOTOR_AFTER)
3161 motor_off_callback(current_drive);
3162
3163 if (raw_cmd->next &&
3164 (!(raw_cmd->flags & FD_RAW_FAILURE) ||
3165 !(raw_cmd->flags & FD_RAW_STOP_IF_FAILURE)) &&
3166 ((raw_cmd->flags & FD_RAW_FAILURE) ||
3167 !(raw_cmd->flags & FD_RAW_STOP_IF_SUCCESS))) {
3168 raw_cmd = raw_cmd->next;
3169 return;
3170 }
3171 }
3172 generic_done(flag);
3173}
3174
3175static struct cont_t raw_cmd_cont = {
3176 .interrupt = success_and_wakeup,
3177 .redo = floppy_start,
3178 .error = generic_failure,
3179 .done = raw_cmd_done
3180};
3181
3182static inline int raw_cmd_copyout(int cmd, char __user *param,
3183 struct floppy_raw_cmd *ptr)
3184{
3185 int ret;
3186
3187 while (ptr) {
3188 COPYOUT(*ptr);
3189 param += sizeof(struct floppy_raw_cmd);
3190 if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length) {
3191 if (ptr->length >= 0
3192 && ptr->length <= ptr->buffer_length)
3193 ECALL(fd_copyout
3194 (ptr->data, ptr->kernel_data,
3195 ptr->buffer_length - ptr->length));
3196 }
3197 ptr = ptr->next;
3198 }
3199 return 0;
3200}
3201
3202static void raw_cmd_free(struct floppy_raw_cmd **ptr)
3203{
3204 struct floppy_raw_cmd *next, *this;
3205
3206 this = *ptr;
3207 *ptr = NULL;
3208 while (this) {
3209 if (this->buffer_length) {
3210 fd_dma_mem_free((unsigned long)this->kernel_data,
3211 this->buffer_length);
3212 this->buffer_length = 0;
3213 }
3214 next = this->next;
3215 kfree(this);
3216 this = next;
3217 }
3218}
3219
3220static inline int raw_cmd_copyin(int cmd, char __user *param,
3221 struct floppy_raw_cmd **rcmd)
3222{
3223 struct floppy_raw_cmd *ptr;
3224 int ret;
3225 int i;
3226
3227 *rcmd = NULL;
3228 while (1) {
3229 ptr = (struct floppy_raw_cmd *)
3230 kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER);
3231 if (!ptr)
3232 return -ENOMEM;
3233 *rcmd = ptr;
3234 COPYIN(*ptr);
3235 ptr->next = NULL;
3236 ptr->buffer_length = 0;
3237 param += sizeof(struct floppy_raw_cmd);
3238 if (ptr->cmd_count > 33)
3239 /* the command may now also take up the space
3240 * initially intended for the reply & the
3241 * reply count. Needed for long 82078 commands
3242 * such as RESTORE, which takes ... 17 command
3243 * bytes. Murphy's law #137: When you reserve
3244 * 16 bytes for a structure, you'll one day
3245 * discover that you really need 17...
3246 */
3247 return -EINVAL;
3248
3249 for (i = 0; i < 16; i++)
3250 ptr->reply[i] = 0;
3251 ptr->resultcode = 0;
3252 ptr->kernel_data = NULL;
3253
3254 if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
3255 if (ptr->length <= 0)
3256 return -EINVAL;
3257 ptr->kernel_data =
3258 (char *)fd_dma_mem_alloc(ptr->length);
3259 fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length);
3260 if (!ptr->kernel_data)
3261 return -ENOMEM;
3262 ptr->buffer_length = ptr->length;
3263 }
3264 if (ptr->flags & FD_RAW_WRITE)
3265 ECALL(fd_copyin(ptr->data, ptr->kernel_data,
3266 ptr->length));
3267 rcmd = &(ptr->next);
3268 if (!(ptr->flags & FD_RAW_MORE))
3269 return 0;
3270 ptr->rate &= 0x43;
3271 }
3272}
3273
3274static int raw_cmd_ioctl(int cmd, void __user *param)
3275{
3276 int drive, ret, ret2;
3277 struct floppy_raw_cmd *my_raw_cmd;
3278
3279 if (FDCS->rawcmd <= 1)
3280 FDCS->rawcmd = 1;
3281 for (drive = 0; drive < N_DRIVE; drive++) {
3282 if (FDC(drive) != fdc)
3283 continue;
3284 if (drive == current_drive) {
3285 if (UDRS->fd_ref > 1) {
3286 FDCS->rawcmd = 2;
3287 break;
3288 }
3289 } else if (UDRS->fd_ref) {
3290 FDCS->rawcmd = 2;
3291 break;
3292 }
3293 }
3294
3295 if (FDCS->reset)
3296 return -EIO;
3297
3298 ret = raw_cmd_copyin(cmd, param, &my_raw_cmd);
3299 if (ret) {
3300 raw_cmd_free(&my_raw_cmd);
3301 return ret;
3302 }
3303
3304 raw_cmd = my_raw_cmd;
3305 cont = &raw_cmd_cont;
3306 ret = wait_til_done(floppy_start, 1);
3307#ifdef DCL_DEBUG
3308 if (DP->flags & FD_DEBUG) {
3309 DPRINT("calling disk change from raw_cmd ioctl\n");
3310 }
3311#endif
3312
3313 if (ret != -EINTR && FDCS->reset)
3314 ret = -EIO;
3315
3316 DRS->track = NO_TRACK;
3317
3318 ret2 = raw_cmd_copyout(cmd, param, my_raw_cmd);
3319 if (!ret)
3320 ret = ret2;
3321 raw_cmd_free(&my_raw_cmd);
3322 return ret;
3323}
3324
3325static int invalidate_drive(struct block_device *bdev)
3326{
3327 /* invalidate the buffer track to force a reread */
3328 set_bit((long)bdev->bd_disk->private_data, &fake_change);
3329 process_fd_request();
3330 check_disk_change(bdev);
3331 return 0;
3332}
3333
3334static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
3335 int drive, int type, struct block_device *bdev)
3336{
3337 int cnt;
3338
3339 /* sanity checking for parameters. */
3340 if (g->sect <= 0 ||
3341 g->head <= 0 ||
3342 g->track <= 0 || g->track > UDP->tracks >> STRETCH(g) ||
3343 /* check if reserved bits are set */
3344 (g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_ZEROBASED)) != 0)
3345 return -EINVAL;
3346 if (type) {
3347 if (!capable(CAP_SYS_ADMIN))
3348 return -EPERM;
Jes Sorensenb1c82b52006-03-23 03:00:26 -08003349 mutex_lock(&open_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003350 LOCK_FDC(drive, 1);
3351 floppy_type[type] = *g;
3352 floppy_type[type].name = "user format";
3353 for (cnt = type << 2; cnt < (type << 2) + 4; cnt++)
3354 floppy_sizes[cnt] = floppy_sizes[cnt + 0x80] =
3355 floppy_type[type].size + 1;
3356 process_fd_request();
3357 for (cnt = 0; cnt < N_DRIVE; cnt++) {
3358 struct block_device *bdev = opened_bdev[cnt];
3359 if (!bdev || ITYPE(drive_state[cnt].fd_device) != type)
3360 continue;
Christoph Hellwig2ef41632005-05-05 16:15:59 -07003361 __invalidate_device(bdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003362 }
Jes Sorensenb1c82b52006-03-23 03:00:26 -08003363 mutex_unlock(&open_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364 } else {
3365 int oldStretch;
3366 LOCK_FDC(drive, 1);
3367 if (cmd != FDDEFPRM)
3368 /* notice a disk change immediately, else
3369 * we lose our settings immediately*/
3370 CALL(poll_drive(1, FD_RAW_NEED_DISK));
3371 oldStretch = g->stretch;
3372 user_params[drive] = *g;
3373 if (buffer_drive == drive)
3374 SUPBOUND(buffer_max, user_params[drive].sect);
3375 current_type[drive] = &user_params[drive];
3376 floppy_sizes[drive] = user_params[drive].size;
3377 if (cmd == FDDEFPRM)
3378 DRS->keep_data = -1;
3379 else
3380 DRS->keep_data = 1;
3381 /* invalidation. Invalidate only when needed, i.e.
3382 * when there are already sectors in the buffer cache
3383 * whose number will change. This is useful, because
3384 * mtools often changes the geometry of the disk after
3385 * looking at the boot block */
3386 if (DRS->maxblock > user_params[drive].sect ||
3387 DRS->maxtrack ||
3388 ((user_params[drive].sect ^ oldStretch) &
3389 (FD_SWAPSIDES | FD_ZEROBASED)))
3390 invalidate_drive(bdev);
3391 else
3392 process_fd_request();
3393 }
3394 return 0;
3395}
3396
3397/* handle obsolete ioctl's */
3398static int ioctl_table[] = {
3399 FDCLRPRM,
3400 FDSETPRM,
3401 FDDEFPRM,
3402 FDGETPRM,
3403 FDMSGON,
3404 FDMSGOFF,
3405 FDFMTBEG,
3406 FDFMTTRK,
3407 FDFMTEND,
3408 FDSETEMSGTRESH,
3409 FDFLUSH,
3410 FDSETMAXERRS,
3411 FDGETMAXERRS,
3412 FDGETDRVTYP,
3413 FDSETDRVPRM,
3414 FDGETDRVPRM,
3415 FDGETDRVSTAT,
3416 FDPOLLDRVSTAT,
3417 FDRESET,
3418 FDGETFDCSTAT,
3419 FDWERRORCLR,
3420 FDWERRORGET,
3421 FDRAWCMD,
3422 FDEJECT,
3423 FDTWADDLE
3424};
3425
3426static inline int normalize_ioctl(int *cmd, int *size)
3427{
3428 int i;
3429
3430 for (i = 0; i < ARRAY_SIZE(ioctl_table); i++) {
3431 if ((*cmd & 0xffff) == (ioctl_table[i] & 0xffff)) {
3432 *size = _IOC_SIZE(*cmd);
3433 *cmd = ioctl_table[i];
3434 if (*size > _IOC_SIZE(*cmd)) {
3435 printk("ioctl not yet supported\n");
3436 return -EFAULT;
3437 }
3438 return 0;
3439 }
3440 }
3441 return -EINVAL;
3442}
3443
3444static int get_floppy_geometry(int drive, int type, struct floppy_struct **g)
3445{
3446 if (type)
3447 *g = &floppy_type[type];
3448 else {
3449 LOCK_FDC(drive, 0);
3450 CALL(poll_drive(0, 0));
3451 process_fd_request();
3452 *g = current_type[drive];
3453 }
3454 if (!*g)
3455 return -ENODEV;
3456 return 0;
3457}
3458
Christoph Hellwiga885c8c2006-01-08 01:02:50 -08003459static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
3460{
3461 int drive = (long)bdev->bd_disk->private_data;
3462 int type = ITYPE(drive_state[drive].fd_device);
3463 struct floppy_struct *g;
3464 int ret;
3465
3466 ret = get_floppy_geometry(drive, type, &g);
3467 if (ret)
3468 return ret;
3469
3470 geo->heads = g->head;
3471 geo->sectors = g->sect;
3472 geo->cylinders = g->track;
3473 return 0;
3474}
3475
Linus Torvalds1da177e2005-04-16 15:20:36 -07003476static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
3477 unsigned long param)
3478{
3479#define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data)
3480#define OUT(c,x) case c: outparam = (const char *) (x); break
3481#define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
3482
3483 int drive = (long)inode->i_bdev->bd_disk->private_data;
3484 int i, type = ITYPE(UDRS->fd_device);
3485 int ret;
3486 int size;
3487 union inparam {
3488 struct floppy_struct g; /* geometry */
3489 struct format_descr f;
3490 struct floppy_max_errors max_errors;
3491 struct floppy_drive_params dp;
3492 } inparam; /* parameters coming from user space */
3493 const char *outparam; /* parameters passed back to user space */
3494
3495 /* convert compatibility eject ioctls into floppy eject ioctl.
3496 * We do this in order to provide a means to eject floppy disks before
3497 * installing the new fdutils package */
3498 if (cmd == CDROMEJECT || /* CD-ROM eject */
3499 cmd == 0x6470 /* SunOS floppy eject */ ) {
3500 DPRINT("obsolete eject ioctl\n");
3501 DPRINT("please use floppycontrol --eject\n");
3502 cmd = FDEJECT;
3503 }
3504
Linus Torvalds1da177e2005-04-16 15:20:36 -07003505 /* convert the old style command into a new style command */
3506 if ((cmd & 0xff00) == 0x0200) {
3507 ECALL(normalize_ioctl(&cmd, &size));
3508 } else
3509 return -EINVAL;
3510
3511 /* permission checks */
3512 if (((cmd & 0x40) && !FD_IOCTL_ALLOWED) ||
3513 ((cmd & 0x80) && !capable(CAP_SYS_ADMIN)))
3514 return -EPERM;
3515
3516 /* copyin */
3517 CLEARSTRUCT(&inparam);
3518 if (_IOC_DIR(cmd) & _IOC_WRITE)
3519 ECALL(fd_copyin((void __user *)param, &inparam, size))
3520
3521 switch (cmd) {
3522 case FDEJECT:
3523 if (UDRS->fd_ref != 1)
3524 /* somebody else has this drive open */
3525 return -EBUSY;
3526 LOCK_FDC(drive, 1);
3527
3528 /* do the actual eject. Fails on
3529 * non-Sparc architectures */
3530 ret = fd_eject(UNIT(drive));
3531
3532 USETF(FD_DISK_CHANGED);
3533 USETF(FD_VERIFY);
3534 process_fd_request();
3535 return ret;
3536 case FDCLRPRM:
3537 LOCK_FDC(drive, 1);
3538 current_type[drive] = NULL;
3539 floppy_sizes[drive] = MAX_DISK_SIZE << 1;
3540 UDRS->keep_data = 0;
3541 return invalidate_drive(inode->i_bdev);
3542 case FDSETPRM:
3543 case FDDEFPRM:
3544 return set_geometry(cmd, &inparam.g,
3545 drive, type, inode->i_bdev);
3546 case FDGETPRM:
3547 ECALL(get_floppy_geometry(drive, type,
3548 (struct floppy_struct **)
3549 &outparam));
3550 break;
3551
3552 case FDMSGON:
3553 UDP->flags |= FTD_MSG;
3554 return 0;
3555 case FDMSGOFF:
3556 UDP->flags &= ~FTD_MSG;
3557 return 0;
3558
3559 case FDFMTBEG:
3560 LOCK_FDC(drive, 1);
3561 CALL(poll_drive(1, FD_RAW_NEED_DISK));
3562 ret = UDRS->flags;
3563 process_fd_request();
3564 if (ret & FD_VERIFY)
3565 return -ENODEV;
3566 if (!(ret & FD_DISK_WRITABLE))
3567 return -EROFS;
3568 return 0;
3569 case FDFMTTRK:
3570 if (UDRS->fd_ref != 1)
3571 return -EBUSY;
3572 return do_format(drive, &inparam.f);
3573 case FDFMTEND:
3574 case FDFLUSH:
3575 LOCK_FDC(drive, 1);
3576 return invalidate_drive(inode->i_bdev);
3577
3578 case FDSETEMSGTRESH:
3579 UDP->max_errors.reporting =
3580 (unsigned short)(param & 0x0f);
3581 return 0;
3582 OUT(FDGETMAXERRS, &UDP->max_errors);
3583 IN(FDSETMAXERRS, &UDP->max_errors, max_errors);
3584
3585 case FDGETDRVTYP:
3586 outparam = drive_name(type, drive);
3587 SUPBOUND(size, strlen(outparam) + 1);
3588 break;
3589
3590 IN(FDSETDRVPRM, UDP, dp);
3591 OUT(FDGETDRVPRM, UDP);
3592
3593 case FDPOLLDRVSTAT:
3594 LOCK_FDC(drive, 1);
3595 CALL(poll_drive(1, FD_RAW_NEED_DISK));
3596 process_fd_request();
3597 /* fall through */
3598 OUT(FDGETDRVSTAT, UDRS);
3599
3600 case FDRESET:
3601 return user_reset_fdc(drive, (int)param, 1);
3602
3603 OUT(FDGETFDCSTAT, UFDCS);
3604
3605 case FDWERRORCLR:
3606 CLEARSTRUCT(UDRWE);
3607 return 0;
3608 OUT(FDWERRORGET, UDRWE);
3609
3610 case FDRAWCMD:
3611 if (type)
3612 return -EINVAL;
3613 LOCK_FDC(drive, 1);
3614 set_floppy(drive);
3615 CALL(i = raw_cmd_ioctl(cmd, (void __user *)param));
3616 process_fd_request();
3617 return i;
3618
3619 case FDTWADDLE:
3620 LOCK_FDC(drive, 1);
3621 twaddle();
3622 process_fd_request();
3623 return 0;
3624
3625 default:
3626 return -EINVAL;
3627 }
3628
3629 if (_IOC_DIR(cmd) & _IOC_READ)
3630 return fd_copyout((void __user *)param, outparam, size);
3631 else
3632 return 0;
3633#undef OUT
3634#undef IN
3635}
3636
3637static void __init config_types(void)
3638{
3639 int first = 1;
3640 int drive;
3641
3642 /* read drive info out of physical CMOS */
3643 drive = 0;
3644 if (!UDP->cmos)
3645 UDP->cmos = FLOPPY0_TYPE;
3646 drive = 1;
3647 if (!UDP->cmos && FLOPPY1_TYPE)
3648 UDP->cmos = FLOPPY1_TYPE;
3649
3650 /* XXX */
3651 /* additional physical CMOS drive detection should go here */
3652
3653 for (drive = 0; drive < N_DRIVE; drive++) {
3654 unsigned int type = UDP->cmos;
3655 struct floppy_drive_params *params;
3656 const char *name = NULL;
3657 static char temparea[32];
3658
Tobias Klauser945f3902006-01-08 01:05:11 -08003659 if (type < ARRAY_SIZE(default_drive_params)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003660 params = &default_drive_params[type].params;
3661 if (type) {
3662 name = default_drive_params[type].name;
3663 allowed_drive_mask |= 1 << drive;
3664 } else
3665 allowed_drive_mask &= ~(1 << drive);
3666 } else {
3667 params = &default_drive_params[0].params;
3668 sprintf(temparea, "unknown type %d (usb?)", type);
3669 name = temparea;
3670 }
3671 if (name) {
3672 const char *prepend = ",";
3673 if (first) {
3674 prepend = KERN_INFO "Floppy drive(s):";
3675 first = 0;
3676 }
3677 printk("%s fd%d is %s", prepend, drive, name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003678 }
3679 *UDP = *params;
3680 }
3681 if (!first)
3682 printk("\n");
3683}
3684
3685static int floppy_release(struct inode *inode, struct file *filp)
3686{
3687 int drive = (long)inode->i_bdev->bd_disk->private_data;
3688
Jes Sorensenb1c82b52006-03-23 03:00:26 -08003689 mutex_lock(&open_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003690 if (UDRS->fd_ref < 0)
3691 UDRS->fd_ref = 0;
3692 else if (!UDRS->fd_ref--) {
3693 DPRINT("floppy_release with fd_ref == 0");
3694 UDRS->fd_ref = 0;
3695 }
3696 if (!UDRS->fd_ref)
3697 opened_bdev[drive] = NULL;
3698 floppy_release_irq_and_dma();
Jes Sorensenb1c82b52006-03-23 03:00:26 -08003699 mutex_unlock(&open_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700 return 0;
3701}
3702
3703/*
3704 * floppy_open check for aliasing (/dev/fd0 can be the same as
3705 * /dev/PS0 etc), and disallows simultaneous access to the same
3706 * drive with different device numbers.
3707 */
3708static int floppy_open(struct inode *inode, struct file *filp)
3709{
3710 int drive = (long)inode->i_bdev->bd_disk->private_data;
3711 int old_dev;
3712 int try;
3713 int res = -EBUSY;
3714 char *tmp;
3715
3716 filp->private_data = (void *)0;
Jes Sorensenb1c82b52006-03-23 03:00:26 -08003717 mutex_lock(&open_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718 old_dev = UDRS->fd_device;
3719 if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev)
3720 goto out2;
3721
3722 if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) {
3723 USETF(FD_DISK_CHANGED);
3724 USETF(FD_VERIFY);
3725 }
3726
3727 if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3728 goto out2;
3729
3730 if (floppy_grab_irq_and_dma())
3731 goto out2;
3732
3733 if (filp->f_flags & O_EXCL)
3734 UDRS->fd_ref = -1;
3735 else
3736 UDRS->fd_ref++;
3737
3738 opened_bdev[drive] = inode->i_bdev;
3739
3740 res = -ENXIO;
3741
3742 if (!floppy_track_buffer) {
3743 /* if opening an ED drive, reserve a big buffer,
3744 * else reserve a small one */
3745 if ((UDP->cmos == 6) || (UDP->cmos == 5))
3746 try = 64; /* Only 48 actually useful */
3747 else
3748 try = 32; /* Only 24 actually useful */
3749
3750 tmp = (char *)fd_dma_mem_alloc(1024 * try);
3751 if (!tmp && !floppy_track_buffer) {
3752 try >>= 1; /* buffer only one side */
3753 INFBOUND(try, 16);
3754 tmp = (char *)fd_dma_mem_alloc(1024 * try);
3755 }
3756 if (!tmp && !floppy_track_buffer) {
3757 fallback_on_nodma_alloc(&tmp, 2048 * try);
3758 }
3759 if (!tmp && !floppy_track_buffer) {
3760 DPRINT("Unable to allocate DMA memory\n");
3761 goto out;
3762 }
3763 if (floppy_track_buffer) {
3764 if (tmp)
3765 fd_dma_mem_free((unsigned long)tmp, try * 1024);
3766 } else {
3767 buffer_min = buffer_max = -1;
3768 floppy_track_buffer = tmp;
3769 max_buffer_sectors = try;
3770 }
3771 }
3772
3773 UDRS->fd_device = iminor(inode);
3774 set_capacity(disks[drive], floppy_sizes[iminor(inode)]);
3775 if (old_dev != -1 && old_dev != iminor(inode)) {
3776 if (buffer_drive == drive)
3777 buffer_track = -1;
3778 }
3779
3780 /* Allow ioctls if we have write-permissions even if read-only open.
3781 * Needed so that programs such as fdrawcmd still can work on write
3782 * protected disks */
Christoph Hellwig8c744fb2005-11-08 21:35:04 -08003783 if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784 filp->private_data = (void *)8;
3785
3786 if (UFDCS->rawcmd == 1)
3787 UFDCS->rawcmd = 2;
3788
3789 if (!(filp->f_flags & O_NDELAY)) {
3790 if (filp->f_mode & 3) {
3791 UDRS->last_checked = 0;
3792 check_disk_change(inode->i_bdev);
3793 if (UTESTF(FD_DISK_CHANGED))
3794 goto out;
3795 }
3796 res = -EROFS;
3797 if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
3798 goto out;
3799 }
Jes Sorensenb1c82b52006-03-23 03:00:26 -08003800 mutex_unlock(&open_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801 return 0;
3802out:
3803 if (UDRS->fd_ref < 0)
3804 UDRS->fd_ref = 0;
3805 else
3806 UDRS->fd_ref--;
3807 if (!UDRS->fd_ref)
3808 opened_bdev[drive] = NULL;
3809 floppy_release_irq_and_dma();
3810out2:
Jes Sorensenb1c82b52006-03-23 03:00:26 -08003811 mutex_unlock(&open_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003812 return res;
3813}
3814
3815/*
3816 * Check if the disk has been changed or if a change has been faked.
3817 */
3818static int check_floppy_change(struct gendisk *disk)
3819{
3820 int drive = (long)disk->private_data;
3821
3822 if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
3823 return 1;
3824
Marcelo Feitoza Parisi50297cb2006-03-28 01:56:44 -08003825 if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826 if (floppy_grab_irq_and_dma()) {
3827 return 1;
3828 }
3829
3830 lock_fdc(drive, 0);
3831 poll_drive(0, 0);
3832 process_fd_request();
3833 floppy_release_irq_and_dma();
3834 }
3835
3836 if (UTESTF(FD_DISK_CHANGED) ||
3837 UTESTF(FD_VERIFY) ||
3838 test_bit(drive, &fake_change) ||
3839 (!ITYPE(UDRS->fd_device) && !current_type[drive]))
3840 return 1;
3841 return 0;
3842}
3843
3844/*
3845 * This implements "read block 0" for floppy_revalidate().
3846 * Needed for format autodetection, checking whether there is
3847 * a disk in the drive, and whether that disk is writable.
3848 */
3849
3850static int floppy_rb0_complete(struct bio *bio, unsigned int bytes_done,
3851 int err)
3852{
3853 if (bio->bi_size)
3854 return 1;
3855
3856 complete((struct completion *)bio->bi_private);
3857 return 0;
3858}
3859
3860static int __floppy_read_block_0(struct block_device *bdev)
3861{
3862 struct bio bio;
3863 struct bio_vec bio_vec;
3864 struct completion complete;
3865 struct page *page;
3866 size_t size;
3867
3868 page = alloc_page(GFP_NOIO);
3869 if (!page) {
3870 process_fd_request();
3871 return -ENOMEM;
3872 }
3873
3874 size = bdev->bd_block_size;
3875 if (!size)
3876 size = 1024;
3877
3878 bio_init(&bio);
3879 bio.bi_io_vec = &bio_vec;
3880 bio_vec.bv_page = page;
3881 bio_vec.bv_len = size;
3882 bio_vec.bv_offset = 0;
3883 bio.bi_vcnt = 1;
3884 bio.bi_idx = 0;
3885 bio.bi_size = size;
3886 bio.bi_bdev = bdev;
3887 bio.bi_sector = 0;
3888 init_completion(&complete);
3889 bio.bi_private = &complete;
3890 bio.bi_end_io = floppy_rb0_complete;
3891
3892 submit_bio(READ, &bio);
3893 generic_unplug_device(bdev_get_queue(bdev));
3894 process_fd_request();
3895 wait_for_completion(&complete);
3896
3897 __free_page(page);
3898
3899 return 0;
3900}
3901
3902/* revalidate the floppy disk, i.e. trigger format autodetection by reading
3903 * the bootblock (block 0). "Autodetection" is also needed to check whether
3904 * there is a disk in the drive at all... Thus we also do it for fixed
3905 * geometry formats */
3906static int floppy_revalidate(struct gendisk *disk)
3907{
3908 int drive = (long)disk->private_data;
3909#define NO_GEOM (!current_type[drive] && !ITYPE(UDRS->fd_device))
3910 int cf;
3911 int res = 0;
3912
3913 if (UTESTF(FD_DISK_CHANGED) ||
3914 UTESTF(FD_VERIFY) || test_bit(drive, &fake_change) || NO_GEOM) {
3915 if (usage_count == 0) {
3916 printk("VFS: revalidate called on non-open device.\n");
3917 return -EFAULT;
3918 }
3919 lock_fdc(drive, 0);
3920 cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY);
3921 if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)) {
3922 process_fd_request(); /*already done by another thread */
3923 return 0;
3924 }
3925 UDRS->maxblock = 0;
3926 UDRS->maxtrack = 0;
3927 if (buffer_drive == drive)
3928 buffer_track = -1;
3929 clear_bit(drive, &fake_change);
3930 UCLEARF(FD_DISK_CHANGED);
3931 if (cf)
3932 UDRS->generation++;
3933 if (NO_GEOM) {
3934 /* auto-sensing */
3935 res = __floppy_read_block_0(opened_bdev[drive]);
3936 } else {
3937 if (cf)
3938 poll_drive(0, FD_RAW_NEED_DISK);
3939 process_fd_request();
3940 }
3941 }
3942 set_capacity(disk, floppy_sizes[UDRS->fd_device]);
3943 return res;
3944}
3945
3946static struct block_device_operations floppy_fops = {
3947 .owner = THIS_MODULE,
3948 .open = floppy_open,
3949 .release = floppy_release,
3950 .ioctl = fd_ioctl,
Christoph Hellwiga885c8c2006-01-08 01:02:50 -08003951 .getgeo = fd_getgeo,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003952 .media_changed = check_floppy_change,
3953 .revalidate_disk = floppy_revalidate,
3954};
Linus Torvalds1da177e2005-04-16 15:20:36 -07003955
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956/*
3957 * Floppy Driver initialization
3958 * =============================
3959 */
3960
3961/* Determine the floppy disk controller type */
3962/* This routine was written by David C. Niemi */
3963static char __init get_fdc_version(void)
3964{
3965 int r;
3966
3967 output_byte(FD_DUMPREGS); /* 82072 and better know DUMPREGS */
3968 if (FDCS->reset)
3969 return FDC_NONE;
3970 if ((r = result()) <= 0x00)
3971 return FDC_NONE; /* No FDC present ??? */
3972 if ((r == 1) && (reply_buffer[0] == 0x80)) {
3973 printk(KERN_INFO "FDC %d is an 8272A\n", fdc);
3974 return FDC_8272A; /* 8272a/765 don't know DUMPREGS */
3975 }
3976 if (r != 10) {
3977 printk
3978 ("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n",
3979 fdc, r);
3980 return FDC_UNKNOWN;
3981 }
3982
3983 if (!fdc_configure()) {
3984 printk(KERN_INFO "FDC %d is an 82072\n", fdc);
3985 return FDC_82072; /* 82072 doesn't know CONFIGURE */
3986 }
3987
3988 output_byte(FD_PERPENDICULAR);
3989 if (need_more_output() == MORE_OUTPUT) {
3990 output_byte(0);
3991 } else {
3992 printk(KERN_INFO "FDC %d is an 82072A\n", fdc);
3993 return FDC_82072A; /* 82072A as found on Sparcs. */
3994 }
3995
3996 output_byte(FD_UNLOCK);
3997 r = result();
3998 if ((r == 1) && (reply_buffer[0] == 0x80)) {
3999 printk(KERN_INFO "FDC %d is a pre-1991 82077\n", fdc);
4000 return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know
4001 * LOCK/UNLOCK */
4002 }
4003 if ((r != 1) || (reply_buffer[0] != 0x00)) {
4004 printk("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
4005 fdc, r);
4006 return FDC_UNKNOWN;
4007 }
4008 output_byte(FD_PARTID);
4009 r = result();
4010 if (r != 1) {
4011 printk("FDC %d init: PARTID: unexpected return of %d bytes.\n",
4012 fdc, r);
4013 return FDC_UNKNOWN;
4014 }
4015 if (reply_buffer[0] == 0x80) {
4016 printk(KERN_INFO "FDC %d is a post-1991 82077\n", fdc);
4017 return FDC_82077; /* Revised 82077AA passes all the tests */
4018 }
4019 switch (reply_buffer[0] >> 5) {
4020 case 0x0:
4021 /* Either a 82078-1 or a 82078SL running at 5Volt */
4022 printk(KERN_INFO "FDC %d is an 82078.\n", fdc);
4023 return FDC_82078;
4024 case 0x1:
4025 printk(KERN_INFO "FDC %d is a 44pin 82078\n", fdc);
4026 return FDC_82078;
4027 case 0x2:
4028 printk(KERN_INFO "FDC %d is a S82078B\n", fdc);
4029 return FDC_S82078B;
4030 case 0x3:
4031 printk(KERN_INFO "FDC %d is a National Semiconductor PC87306\n",
4032 fdc);
4033 return FDC_87306;
4034 default:
4035 printk(KERN_INFO
4036 "FDC %d init: 82078 variant with unknown PARTID=%d.\n",
4037 fdc, reply_buffer[0] >> 5);
4038 return FDC_82078_UNKN;
4039 }
4040} /* get_fdc_version */
4041
4042/* lilo configuration */
4043
4044static void __init floppy_set_flags(int *ints, int param, int param2)
4045{
4046 int i;
4047
4048 for (i = 0; i < ARRAY_SIZE(default_drive_params); i++) {
4049 if (param)
4050 default_drive_params[i].params.flags |= param2;
4051 else
4052 default_drive_params[i].params.flags &= ~param2;
4053 }
4054 DPRINT("%s flag 0x%x\n", param2 ? "Setting" : "Clearing", param);
4055}
4056
4057static void __init daring(int *ints, int param, int param2)
4058{
4059 int i;
4060
4061 for (i = 0; i < ARRAY_SIZE(default_drive_params); i++) {
4062 if (param) {
4063 default_drive_params[i].params.select_delay = 0;
4064 default_drive_params[i].params.flags |=
4065 FD_SILENT_DCL_CLEAR;
4066 } else {
4067 default_drive_params[i].params.select_delay =
4068 2 * HZ / 100;
4069 default_drive_params[i].params.flags &=
4070 ~FD_SILENT_DCL_CLEAR;
4071 }
4072 }
4073 DPRINT("Assuming %s floppy hardware\n", param ? "standard" : "broken");
4074}
4075
4076static void __init set_cmos(int *ints, int dummy, int dummy2)
4077{
4078 int current_drive = 0;
4079
4080 if (ints[0] != 2) {
4081 DPRINT("wrong number of parameters for CMOS\n");
4082 return;
4083 }
4084 current_drive = ints[1];
4085 if (current_drive < 0 || current_drive >= 8) {
4086 DPRINT("bad drive for set_cmos\n");
4087 return;
4088 }
4089#if N_FDC > 1
4090 if (current_drive >= 4 && !FDC2)
4091 FDC2 = 0x370;
4092#endif
4093 DP->cmos = ints[2];
4094 DPRINT("setting CMOS code to %d\n", ints[2]);
4095}
4096
4097static struct param_table {
4098 const char *name;
4099 void (*fn) (int *ints, int param, int param2);
4100 int *var;
4101 int def_param;
4102 int param2;
4103} config_params[] __initdata = {
4104 {"allowed_drive_mask", NULL, &allowed_drive_mask, 0xff, 0}, /* obsolete */
4105 {"all_drives", NULL, &allowed_drive_mask, 0xff, 0}, /* obsolete */
4106 {"asus_pci", NULL, &allowed_drive_mask, 0x33, 0},
4107 {"irq", NULL, &FLOPPY_IRQ, 6, 0},
4108 {"dma", NULL, &FLOPPY_DMA, 2, 0},
4109 {"daring", daring, NULL, 1, 0},
4110#if N_FDC > 1
4111 {"two_fdc", NULL, &FDC2, 0x370, 0},
4112 {"one_fdc", NULL, &FDC2, 0, 0},
4113#endif
4114 {"thinkpad", floppy_set_flags, NULL, 1, FD_INVERTED_DCL},
4115 {"broken_dcl", floppy_set_flags, NULL, 1, FD_BROKEN_DCL},
4116 {"messages", floppy_set_flags, NULL, 1, FTD_MSG},
4117 {"silent_dcl_clear", floppy_set_flags, NULL, 1, FD_SILENT_DCL_CLEAR},
4118 {"debug", floppy_set_flags, NULL, 1, FD_DEBUG},
4119 {"nodma", NULL, &can_use_virtual_dma, 1, 0},
4120 {"omnibook", NULL, &can_use_virtual_dma, 1, 0},
4121 {"yesdma", NULL, &can_use_virtual_dma, 0, 0},
4122 {"fifo_depth", NULL, &fifo_depth, 0xa, 0},
4123 {"nofifo", NULL, &no_fifo, 0x20, 0},
4124 {"usefifo", NULL, &no_fifo, 0, 0},
4125 {"cmos", set_cmos, NULL, 0, 0},
4126 {"slow", NULL, &slow_floppy, 1, 0},
4127 {"unexpected_interrupts", NULL, &print_unex, 1, 0},
4128 {"no_unexpected_interrupts", NULL, &print_unex, 0, 0},
4129 {"L40SX", NULL, &print_unex, 0, 0}
4130
4131 EXTRA_FLOPPY_PARAMS
4132};
4133
4134static int __init floppy_setup(char *str)
4135{
4136 int i;
4137 int param;
4138 int ints[11];
4139
4140 str = get_options(str, ARRAY_SIZE(ints), ints);
4141 if (str) {
4142 for (i = 0; i < ARRAY_SIZE(config_params); i++) {
4143 if (strcmp(str, config_params[i].name) == 0) {
4144 if (ints[0])
4145 param = ints[1];
4146 else
4147 param = config_params[i].def_param;
4148 if (config_params[i].fn)
4149 config_params[i].
4150 fn(ints, param,
4151 config_params[i].param2);
4152 if (config_params[i].var) {
4153 DPRINT("%s=%d\n", str, param);
4154 *config_params[i].var = param;
4155 }
4156 return 1;
4157 }
4158 }
4159 }
4160 if (str) {
4161 DPRINT("unknown floppy option [%s]\n", str);
4162
4163 DPRINT("allowed options are:");
4164 for (i = 0; i < ARRAY_SIZE(config_params); i++)
4165 printk(" %s", config_params[i].name);
4166 printk("\n");
4167 } else
4168 DPRINT("botched floppy option\n");
4169 DPRINT("Read Documentation/floppy.txt\n");
4170 return 0;
4171}
4172
4173static int have_no_fdc = -ENODEV;
4174
Andrew Morton9a8af6b2005-07-27 17:37:34 -07004175static ssize_t floppy_cmos_show(struct device *dev,
4176 struct device_attribute *attr, char *buf)
Hannes Reinecke94fd0db2005-07-15 10:09:25 +02004177{
Andrew Morton9a8af6b2005-07-27 17:37:34 -07004178 struct platform_device *p;
4179 int drive;
Hannes Reinecke94fd0db2005-07-15 10:09:25 +02004180
Andrew Morton9a8af6b2005-07-27 17:37:34 -07004181 p = container_of(dev, struct platform_device,dev);
4182 drive = p->id;
4183 return sprintf(buf, "%X\n", UDP->cmos);
Hannes Reinecke94fd0db2005-07-15 10:09:25 +02004184}
Hannes Reinecke94fd0db2005-07-15 10:09:25 +02004185DEVICE_ATTR(cmos,S_IRUGO,floppy_cmos_show,NULL);
4186
Linus Torvalds1da177e2005-04-16 15:20:36 -07004187static void floppy_device_release(struct device *dev)
4188{
4189 complete(&device_release);
4190}
4191
Hannes Reinecke94fd0db2005-07-15 10:09:25 +02004192static struct platform_device floppy_device[N_DRIVE];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004193
4194static struct kobject *floppy_find(dev_t dev, int *part, void *data)
4195{
4196 int drive = (*part & 3) | ((*part & 0x80) >> 5);
4197 if (drive >= N_DRIVE ||
4198 !(allowed_drive_mask & (1 << drive)) ||
4199 fdc_state[FDC(drive)].version == FDC_NONE)
4200 return NULL;
Tobias Klauser945f3902006-01-08 01:05:11 -08004201 if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004202 return NULL;
4203 *part = 0;
4204 return get_disk(disks[drive]);
4205}
4206
4207static int __init floppy_init(void)
4208{
4209 int i, unit, drive;
4210 int err, dr;
4211
4212 raw_cmd = NULL;
4213
4214 for (dr = 0; dr < N_DRIVE; dr++) {
4215 disks[dr] = alloc_disk(1);
4216 if (!disks[dr]) {
4217 err = -ENOMEM;
4218 goto out_put_disk;
4219 }
4220
4221 disks[dr]->major = FLOPPY_MAJOR;
4222 disks[dr]->first_minor = TOMINOR(dr);
4223 disks[dr]->fops = &floppy_fops;
4224 sprintf(disks[dr]->disk_name, "fd%d", dr);
4225
4226 init_timer(&motor_off_timer[dr]);
4227 motor_off_timer[dr].data = dr;
4228 motor_off_timer[dr].function = motor_off_callback;
4229 }
4230
Linus Torvalds1da177e2005-04-16 15:20:36 -07004231 err = register_blkdev(FLOPPY_MAJOR, "fd");
4232 if (err)
Greg Kroah-Hartman8ab5e4c2005-06-20 21:15:16 -07004233 goto out_put_disk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004234
4235 floppy_queue = blk_init_queue(do_fd_request, &floppy_lock);
4236 if (!floppy_queue) {
4237 err = -ENOMEM;
4238 goto out_unreg_blkdev;
4239 }
4240 blk_queue_max_sectors(floppy_queue, 64);
4241
4242 blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
4243 floppy_find, NULL, NULL);
4244
4245 for (i = 0; i < 256; i++)
4246 if (ITYPE(i))
4247 floppy_sizes[i] = floppy_type[ITYPE(i)].size;
4248 else
4249 floppy_sizes[i] = MAX_DISK_SIZE << 1;
4250
4251 reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
4252 config_types();
4253
4254 for (i = 0; i < N_FDC; i++) {
4255 fdc = i;
4256 CLEARSTRUCT(FDCS);
4257 FDCS->dtr = -1;
4258 FDCS->dor = 0x4;
4259#if defined(__sparc__) || defined(__mc68000__)
4260 /*sparcs/sun3x don't have a DOR reset which we can fall back on to */
4261#ifdef __mc68000__
4262 if (MACH_IS_SUN3X)
4263#endif
4264 FDCS->version = FDC_82072A;
4265#endif
4266 }
4267
4268 use_virtual_dma = can_use_virtual_dma & 1;
David Woodhouse1269277a2006-04-24 23:22:17 +01004269#if defined(CONFIG_PPC_MERGE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270 if (check_legacy_ioport(FDC1)) {
4271 del_timer(&fd_timeout);
4272 err = -ENODEV;
4273 goto out_unreg_region;
4274 }
4275#endif
4276 fdc_state[0].address = FDC1;
4277 if (fdc_state[0].address == -1) {
4278 del_timer(&fd_timeout);
4279 err = -ENODEV;
4280 goto out_unreg_region;
4281 }
4282#if N_FDC > 1
4283 fdc_state[1].address = FDC2;
4284#endif
4285
4286 fdc = 0; /* reset fdc in case of unexpected interrupt */
4287 err = floppy_grab_irq_and_dma();
4288 if (err) {
4289 del_timer(&fd_timeout);
4290 err = -EBUSY;
4291 goto out_unreg_region;
4292 }
4293
4294 /* initialise drive state */
4295 for (drive = 0; drive < N_DRIVE; drive++) {
4296 CLEARSTRUCT(UDRS);
4297 CLEARSTRUCT(UDRWE);
4298 USETF(FD_DISK_NEWCHANGE);
4299 USETF(FD_DISK_CHANGED);
4300 USETF(FD_VERIFY);
4301 UDRS->fd_device = -1;
4302 floppy_track_buffer = NULL;
4303 max_buffer_sectors = 0;
4304 }
4305 /*
4306 * Small 10 msec delay to let through any interrupt that
4307 * initialization might have triggered, to not
4308 * confuse detection:
4309 */
4310 msleep(10);
4311
4312 for (i = 0; i < N_FDC; i++) {
4313 fdc = i;
4314 FDCS->driver_version = FD_DRIVER_VERSION;
4315 for (unit = 0; unit < 4; unit++)
4316 FDCS->track[unit] = 0;
4317 if (FDCS->address == -1)
4318 continue;
4319 FDCS->rawcmd = 2;
4320 if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) {
4321 /* free ioports reserved by floppy_grab_irq_and_dma() */
4322 release_region(FDCS->address + 2, 4);
4323 release_region(FDCS->address + 7, 1);
4324 FDCS->address = -1;
4325 FDCS->version = FDC_NONE;
4326 continue;
4327 }
4328 /* Try to determine the floppy controller type */
4329 FDCS->version = get_fdc_version();
4330 if (FDCS->version == FDC_NONE) {
4331 /* free ioports reserved by floppy_grab_irq_and_dma() */
4332 release_region(FDCS->address + 2, 4);
4333 release_region(FDCS->address + 7, 1);
4334 FDCS->address = -1;
4335 continue;
4336 }
4337 if (can_use_virtual_dma == 2 && FDCS->version < FDC_82072A)
4338 can_use_virtual_dma = 0;
4339
4340 have_no_fdc = 0;
4341 /* Not all FDCs seem to be able to handle the version command
4342 * properly, so force a reset for the standard FDC clones,
4343 * to avoid interrupt garbage.
4344 */
4345 user_reset_fdc(-1, FD_RESET_ALWAYS, 0);
4346 }
4347 fdc = 0;
4348 del_timer(&fd_timeout);
4349 current_drive = 0;
4350 floppy_release_irq_and_dma();
4351 initialising = 0;
4352 if (have_no_fdc) {
4353 DPRINT("no floppy controllers found\n");
4354 err = have_no_fdc;
4355 goto out_flush_work;
4356 }
4357
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358 for (drive = 0; drive < N_DRIVE; drive++) {
4359 if (!(allowed_drive_mask & (1 << drive)))
4360 continue;
4361 if (fdc_state[FDC(drive)].version == FDC_NONE)
4362 continue;
Hannes Reinecke94fd0db2005-07-15 10:09:25 +02004363
4364 floppy_device[drive].name = floppy_device_name;
4365 floppy_device[drive].id = drive;
4366 floppy_device[drive].dev.release = floppy_device_release;
4367
4368 err = platform_device_register(&floppy_device[drive]);
4369 if (err)
4370 goto out_flush_work;
4371
4372 device_create_file(&floppy_device[drive].dev,&dev_attr_cmos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004373 /* to be cleaned up... */
4374 disks[drive]->private_data = (void *)(long)drive;
4375 disks[drive]->queue = floppy_queue;
4376 disks[drive]->flags |= GENHD_FL_REMOVABLE;
Hannes Reinecke94fd0db2005-07-15 10:09:25 +02004377 disks[drive]->driverfs_dev = &floppy_device[drive].dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004378 add_disk(disks[drive]);
4379 }
4380
4381 return 0;
4382
4383out_flush_work:
4384 flush_scheduled_work();
4385 if (usage_count)
4386 floppy_release_irq_and_dma();
4387out_unreg_region:
4388 blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
4389 blk_cleanup_queue(floppy_queue);
4390out_unreg_blkdev:
4391 unregister_blkdev(FLOPPY_MAJOR, "fd");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004392out_put_disk:
4393 while (dr--) {
4394 del_timer(&motor_off_timer[dr]);
4395 put_disk(disks[dr]);
4396 }
4397 return err;
4398}
4399
4400static DEFINE_SPINLOCK(floppy_usage_lock);
4401
4402static int floppy_grab_irq_and_dma(void)
4403{
4404 unsigned long flags;
4405
4406 spin_lock_irqsave(&floppy_usage_lock, flags);
4407 if (usage_count++) {
4408 spin_unlock_irqrestore(&floppy_usage_lock, flags);
4409 return 0;
4410 }
4411 spin_unlock_irqrestore(&floppy_usage_lock, flags);
Ingo Molnar6dc659d2006-03-26 01:36:54 -08004412
4413 /*
4414 * We might have scheduled a free_irq(), wait it to
4415 * drain first:
4416 */
4417 flush_scheduled_work();
4418
Linus Torvalds1da177e2005-04-16 15:20:36 -07004419 if (fd_request_irq()) {
4420 DPRINT("Unable to grab IRQ%d for the floppy driver\n",
4421 FLOPPY_IRQ);
4422 spin_lock_irqsave(&floppy_usage_lock, flags);
4423 usage_count--;
4424 spin_unlock_irqrestore(&floppy_usage_lock, flags);
4425 return -1;
4426 }
4427 if (fd_request_dma()) {
4428 DPRINT("Unable to grab DMA%d for the floppy driver\n",
4429 FLOPPY_DMA);
4430 fd_free_irq();
4431 spin_lock_irqsave(&floppy_usage_lock, flags);
4432 usage_count--;
4433 spin_unlock_irqrestore(&floppy_usage_lock, flags);
4434 return -1;
4435 }
4436
4437 for (fdc = 0; fdc < N_FDC; fdc++) {
4438 if (FDCS->address != -1) {
4439 if (!request_region(FDCS->address + 2, 4, "floppy")) {
4440 DPRINT("Floppy io-port 0x%04lx in use\n",
4441 FDCS->address + 2);
4442 goto cleanup1;
4443 }
4444 if (!request_region(FDCS->address + 7, 1, "floppy DIR")) {
4445 DPRINT("Floppy io-port 0x%04lx in use\n",
4446 FDCS->address + 7);
4447 goto cleanup2;
4448 }
4449 /* address + 6 is reserved, and may be taken by IDE.
4450 * Unfortunately, Adaptec doesn't know this :-(, */
4451 }
4452 }
4453 for (fdc = 0; fdc < N_FDC; fdc++) {
4454 if (FDCS->address != -1) {
4455 reset_fdc_info(1);
4456 fd_outb(FDCS->dor, FD_DOR);
4457 }
4458 }
4459 fdc = 0;
4460 set_dor(0, ~0, 8); /* avoid immediate interrupt */
4461
4462 for (fdc = 0; fdc < N_FDC; fdc++)
4463 if (FDCS->address != -1)
4464 fd_outb(FDCS->dor, FD_DOR);
4465 /*
4466 * The driver will try and free resources and relies on us
4467 * to know if they were allocated or not.
4468 */
4469 fdc = 0;
4470 irqdma_allocated = 1;
4471 return 0;
4472cleanup2:
4473 release_region(FDCS->address + 2, 4);
4474cleanup1:
4475 fd_free_irq();
4476 fd_free_dma();
4477 while (--fdc >= 0) {
4478 release_region(FDCS->address + 2, 4);
4479 release_region(FDCS->address + 7, 1);
4480 }
4481 spin_lock_irqsave(&floppy_usage_lock, flags);
4482 usage_count--;
4483 spin_unlock_irqrestore(&floppy_usage_lock, flags);
4484 return -1;
4485}
4486
4487static void floppy_release_irq_and_dma(void)
4488{
4489 int old_fdc;
4490#ifdef FLOPPY_SANITY_CHECK
4491#ifndef __sparc__
4492 int drive;
4493#endif
4494#endif
4495 long tmpsize;
4496 unsigned long tmpaddr;
4497 unsigned long flags;
4498
4499 spin_lock_irqsave(&floppy_usage_lock, flags);
4500 if (--usage_count) {
4501 spin_unlock_irqrestore(&floppy_usage_lock, flags);
4502 return;
4503 }
4504 spin_unlock_irqrestore(&floppy_usage_lock, flags);
4505 if (irqdma_allocated) {
4506 fd_disable_dma();
4507 fd_free_dma();
Ingo Molnar6dc659d2006-03-26 01:36:54 -08004508 schedule_work(&fd_free_irq_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004509 irqdma_allocated = 0;
4510 }
4511 set_dor(0, ~0, 8);
4512#if N_FDC > 1
4513 set_dor(1, ~8, 0);
4514#endif
4515 floppy_enable_hlt();
4516
4517 if (floppy_track_buffer && max_buffer_sectors) {
4518 tmpsize = max_buffer_sectors * 1024;
4519 tmpaddr = (unsigned long)floppy_track_buffer;
4520 floppy_track_buffer = NULL;
4521 max_buffer_sectors = 0;
4522 buffer_min = buffer_max = -1;
4523 fd_dma_mem_free(tmpaddr, tmpsize);
4524 }
4525#ifdef FLOPPY_SANITY_CHECK
4526#ifndef __sparc__
4527 for (drive = 0; drive < N_FDC * 4; drive++)
4528 if (timer_pending(motor_off_timer + drive))
4529 printk("motor off timer %d still active\n", drive);
4530#endif
4531
4532 if (timer_pending(&fd_timeout))
4533 printk("floppy timer still active:%s\n", timeout_message);
4534 if (timer_pending(&fd_timer))
4535 printk("auxiliary floppy timer still active\n");
4536 if (floppy_work.pending)
4537 printk("work still pending\n");
4538#endif
4539 old_fdc = fdc;
4540 for (fdc = 0; fdc < N_FDC; fdc++)
4541 if (FDCS->address != -1) {
4542 release_region(FDCS->address + 2, 4);
4543 release_region(FDCS->address + 7, 1);
4544 }
4545 fdc = old_fdc;
4546}
4547
4548#ifdef MODULE
4549
4550static char *floppy;
4551
Linus Torvalds1da177e2005-04-16 15:20:36 -07004552static void __init parse_floppy_cfg_string(char *cfg)
4553{
4554 char *ptr;
4555
4556 while (*cfg) {
4557 for (ptr = cfg; *cfg && *cfg != ' ' && *cfg != '\t'; cfg++) ;
4558 if (*cfg) {
4559 *cfg = '\0';
4560 cfg++;
4561 }
4562 if (*ptr)
4563 floppy_setup(ptr);
4564 }
4565}
4566
Sam Ravnborg1efa6462006-03-25 03:07:13 -08004567int __init init_module(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004568{
4569 if (floppy)
4570 parse_floppy_cfg_string(floppy);
4571 return floppy_init();
4572}
4573
4574void cleanup_module(void)
4575{
4576 int drive;
4577
4578 init_completion(&device_release);
4579 blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
4580 unregister_blkdev(FLOPPY_MAJOR, "fd");
4581
4582 for (drive = 0; drive < N_DRIVE; drive++) {
4583 del_timer_sync(&motor_off_timer[drive]);
4584
4585 if ((allowed_drive_mask & (1 << drive)) &&
4586 fdc_state[FDC(drive)].version != FDC_NONE) {
4587 del_gendisk(disks[drive]);
Hannes Reinecke94fd0db2005-07-15 10:09:25 +02004588 device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos);
4589 platform_device_unregister(&floppy_device[drive]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004590 }
4591 put_disk(disks[drive]);
4592 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004593
4594 del_timer_sync(&fd_timeout);
4595 del_timer_sync(&fd_timer);
4596 blk_cleanup_queue(floppy_queue);
4597
4598 if (usage_count)
4599 floppy_release_irq_and_dma();
4600
4601 /* eject disk, if any */
4602 fd_eject(0);
4603
Ingo Molnar6dc659d2006-03-26 01:36:54 -08004604 flush_scheduled_work(); /* fd_free_irq() might be pending */
4605
Linus Torvalds1da177e2005-04-16 15:20:36 -07004606 wait_for_completion(&device_release);
4607}
4608
4609module_param(floppy, charp, 0);
4610module_param(FLOPPY_IRQ, int, 0);
4611module_param(FLOPPY_DMA, int, 0);
4612MODULE_AUTHOR("Alain L. Knaff");
4613MODULE_SUPPORTED_DEVICE("fd");
4614MODULE_LICENSE("GPL");
4615
4616#else
4617
4618__setup("floppy=", floppy_setup);
4619module_init(floppy_init)
4620#endif
4621
4622MODULE_ALIAS_BLOCKDEV_MAJOR(FLOPPY_MAJOR);