OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [block/] [floppy.c] - Blame information for rev 1626

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.