This source file includes following definitions.
- __get_order
- dma_mem_alloc
- ITYPE
- XTYPE
- TYPE
- DRIVE
- set_debugt
- debugt
- is_alive
- reschedule_timeout
- disk_change
- is_selected
- set_dor
- twaddle
- reset_fdc_info
- set_fdc
- lock_fdc
- unlock_fdc
- motor_off_callback
- floppy_off
- scandrives
- fd_watchdog
- main_command_interrupt
- wait_for_completion
- floppy_disable_hlt
- floppy_enable_hlt
- setup_DMA
- output_byte
- result
- perpendicular_mode
- fdc_specify
- fdc_dtr
- tell_sector
- interpret_errors
- setup_rw_floppy
- seek_interrupt
- check_wp
- seek_floppy
- recal_interrupt
- unexpected_floppy_interrupt
- floppy_interrupt
- recalibrate_floppy
- reset_interrupt
- reset_fdc
- empty
- show_floppy
- floppy_shutdown
- start_motor
- floppy_ready
- floppy_start
- do_wakeup
- wait_til_done
- generic_done
- generic_success
- generic_failure
- success_and_wakeup
- failure_and_wakeup
- next_valid_format
- bad_flp_intr
- set_floppy
- format_interrupt
- setup_format_params
- redo_format
- do_format
- request_done
- rw_interrupt
- buffer_chain_size
- transfer_size
- copy_buffer
- make_raw_rw_request
- redo_fd_request
- process_fd_request
- do_fd_request
- poll_drive
- reset_intr
- user_reset_fdc
- fd_copyout
- drive_name
- raw_cmd_ioctl
- invalidate_drive
- fd_ioctl
- config_types
- floppy_read
- floppy_write
- floppy_release
- floppy_open
- check_floppy_change
- floppy_revalidate
- get_fdc_version
- floppy_invert_dcl
- daring
- allow_drives
- fdc2_adr
- unex
- set_cmos
- floppy_setup
- floppy_init
- floppy_grab_irq_and_dma
- floppy_release_irq_and_dma
- mod_setup
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 #define CONFIG_FLOPPY_SANITY
91 #undef CONFIG_FLOPPY_SILENT_DCL_CLEAR
92
93 #define REALLY_SLOW_IO
94
95 #define DEBUGT 2
96 #define DCL_DEBUG
97
98 #include <linux/config.h>
99
100
101 static int print_unex=1;
102
103 #ifdef MODULE
104 #define FD_MODULE
105
106 #include <linux/module.h>
107
108
109
110 #include <linux/version.h>
111 char kernel_version[] = UTS_RELEASE;
112
113 int FLOPPY_IRQ=6;
114 int FLOPPY_DMA=2;
115 int ALLOWED_DRIVE_MASK = 0x33;
116 int FDC1 = 0x3f0;
117 int FDC2 = -1;
118
119 #endif
120
121 #ifndef FD_MODULE
122
123
124
125
126
127 static int ALLOWED_DRIVE_MASK=0x33;
128
129 #define FLOPPY_IRQ 6
130 #define FLOPPY_DMA 2
131 #define FDC1 0x3f0
132 static int FDC2=-1;
133 #endif
134
135 #define MODULE_AWARE_DRIVER
136
137 #include <linux/sched.h>
138 #include <linux/fs.h>
139 #include <linux/kernel.h>
140 #include <linux/timer.h>
141 #include <linux/tqueue.h>
142 #define FDPATCHES
143 #include <linux/fdreg.h>
144 #include <linux/fd.h>
145 #include <linux/errno.h>
146 #include <linux/malloc.h>
147 #include <linux/mm.h>
148 #include <linux/string.h>
149 #include <linux/fcntl.h>
150 #include <linux/delay.h>
151 #include <linux/mc146818rtc.h>
152 #include <linux/ioport.h>
153
154 #include <asm/dma.h>
155 #include <asm/irq.h>
156 #include <asm/system.h>
157 #include <asm/io.h>
158 #include <asm/segment.h>
159
160 #define MAJOR_NR FLOPPY_MAJOR
161 #include "blk.h"
162
163
164
165
166
167 static inline int __get_order (int size)
168 {
169 int order;
170
171 #ifdef _ASM_IO_H2
172 __asm__ __volatile__("bsr %1,%0"
173 : "=r" (order)
174 : "r" (size / PAGE_SIZE) );
175 #else
176 for (order = 0; order < NR_MEM_LISTS; ++order)
177 if (size <= (PAGE_SIZE << order))
178 return order;
179 #endif
180 return NR_MEM_LISTS;
181 }
182
183 static unsigned long dma_mem_alloc(int size)
184 {
185 int order = __get_order(size);
186
187 if (order >= NR_MEM_LISTS)
188 return(0);
189 return __get_dma_pages(GFP_KERNEL,order);
190 }
191
192
193
194 static unsigned int fake_change = 0;
195 static int initialising=1;
196
197
198
199
200 #ifdef __alpha__
201 #define FLOPPY0_TYPE 6
202 #define FLOPPY1_TYPE 0
203 #else
204 #define FLOPPY0_TYPE ((CMOS_READ(0x10) >> 4) & 15)
205 #define FLOPPY1_TYPE (CMOS_READ(0x10) & 15)
206 #endif
207
208 #define N_FDC 2
209 #define N_DRIVE 8
210
211 static inline int ITYPE(int x) {
212 return (x>>2) & 0x1f;
213 }
214 static inline int XTYPE(int x) {
215 return ITYPE(x);
216 }
217 static inline int TYPE(kdev_t x) {
218 return (MINOR(x)>>2) & 0x1f;
219 }
220 static inline int DRIVE(kdev_t x) {
221 return (MINOR(x)&0x03) | ((MINOR(x)&0x80 ) >> 5);
222 }
223 #define TOMINOR(x) ((x & 3) | ((x & 4) << 5))
224 #define UNIT(x) ( (x) & 0x03 )
225 #define FDC(x) ( ((x) & 0x04) >> 2 )
226 #define REVDRIVE(fdc, unit) ( (unit) + ((fdc) << 2 ))
227
228 #define DP (&drive_params[current_drive])
229 #define DRS (&drive_state[current_drive])
230 #define DRWE (&write_errors[current_drive])
231 #define FDCS (&fdc_state[fdc])
232 #define CLEARF(x) (clear_bit(x##_BIT, &DRS->flags))
233 #define SETF(x) (set_bit(x##_BIT, &DRS->flags))
234 #define TESTF(x) (test_bit(x##_BIT, &DRS->flags))
235
236 #define UDP (&drive_params[drive])
237 #define UDRS (&drive_state[drive])
238 #define UDRWE (&write_errors[drive])
239 #define UFDCS (&fdc_state[FDC(drive)])
240 #define UCLEARF(x) (clear_bit(x##_BIT, &UDRS->flags))
241 #define USETF(x) (set_bit(x##_BIT, &UDRS->flags))
242 #define UTESTF(x) (test_bit(x##_BIT, &UDRS->flags))
243
244 #define DPRINT(x) printk(DEVICE_NAME "%d: " x,current_drive)
245
246 #define DPRINT1(x,x1) \
247 printk(DEVICE_NAME "%d: " x,current_drive,(x1))
248
249 #define DPRINT2(x,x1,x2) \
250 printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2))
251
252 #define DPRINT3(x,x1,x2,x3) \
253 printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2),(x3))
254
255 #define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2)
256 #define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
257
258
259 #define COMMAND raw_cmd.cmd[0]
260 #define DR_SELECT raw_cmd.cmd[1]
261 #define TRACK raw_cmd.cmd[2]
262 #define HEAD raw_cmd.cmd[3]
263 #define SECTOR raw_cmd.cmd[4]
264 #define SIZECODE raw_cmd.cmd[5]
265 #define SECT_PER_TRACK raw_cmd.cmd[6]
266 #define GAP raw_cmd.cmd[7]
267 #define SIZECODE2 raw_cmd.cmd[8]
268 #define NR_RW 9
269
270
271 #define F_SIZECODE raw_cmd.cmd[2]
272 #define F_SECT_PER_TRACK raw_cmd.cmd[3]
273 #define F_GAP raw_cmd.cmd[4]
274 #define F_FILL raw_cmd.cmd[5]
275 #define NR_F 6
276
277
278
279
280
281
282 #define MAX_DISK_SIZE 2
283
284
285 #define K_64 0x10000
286
287
288
289
290
291
292
293
294
295 #ifdef __alpha__
296 # define CROSS_64KB(a,s) (0)
297 #else
298 # define CROSS_64KB(a,s) \
299 ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)
300 #endif
301
302
303
304
305 #define MAX_REPLIES 10
306 static unsigned char reply_buffer[MAX_REPLIES];
307 static int inr;
308 #define ST0 (reply_buffer[0])
309 #define ST1 (reply_buffer[1])
310 #define ST2 (reply_buffer[2])
311 #define ST3 (reply_buffer[0])
312 #define R_TRACK (reply_buffer[3])
313 #define R_HEAD (reply_buffer[4])
314 #define R_SECTOR (reply_buffer[5])
315 #define R_SIZECODE (reply_buffer[6])
316
317 #define SEL_DLY (2*HZ/100)
318
319 #define ARRAY_SIZE(x) (sizeof(x) / sizeof( (x)[0] ))
320
321
322
323 static struct {
324 struct floppy_drive_params params;
325 const char *name;
326 } default_drive_params[]= {
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342 {{0, 500, 16, 16, 8000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 80, 3*HZ, 20, {3,1,2,0,2}, 0,
343 0, { 7, 4, 8, 2, 1, 5, 3,10}, 3*HZ/2, 0 }, "unknown" },
344
345 {{1, 300, 16, 16, 8000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 40, 3*HZ, 17, {3,1,2,0,2}, 0,
346 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 3*HZ/2, 1 }, "360K PC" },
347
348 {{2, 500, 16, 16, 6000, 4*HZ/10, 3*HZ, 14, SEL_DLY, 6, 83, 3*HZ, 17, {3,1,2,0,2}, 0,
349 0, { 2, 5, 6,23,10,20,11, 0}, 3*HZ/2, 2 }, "1.2M" },
350
351 {{3, 250, 16, 16, 3000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0,
352 0, { 4,22,21,30, 3, 0, 0, 0}, 3*HZ/2, 4 }, "720k" },
353
354 {{4, 500, 16, 16, 4000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0,
355 0, { 7, 4,25,22,31,21,29,11}, 3*HZ/2, 7 }, "1.44M" },
356
357 {{5, 1000, 15, 8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0,
358 0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M AMI BIOS" },
359
360 {{6, 1000, 15, 8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0,
361 0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M" }
362
363
364
365
366 };
367
368 static struct floppy_drive_params drive_params[N_DRIVE];
369 static struct floppy_drive_struct drive_state[N_DRIVE];
370 static struct floppy_write_errors write_errors[N_DRIVE];
371 static struct floppy_raw_cmd raw_cmd;
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387 static struct floppy_struct floppy_type[32] = {
388 { 0, 0,0, 0,0,0x00,0x00,0x00,0x00,NULL },
389 { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"d360" },
390 { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,"h1200" },
391 { 720, 9,1,80,0,0x2A,0x02,0xDF,0x50,"D360" },
392 { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"D720" },
393 { 720, 9,2,40,1,0x23,0x01,0xDF,0x50,"h360" },
394 { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,"h720" },
395 { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"H1440" },
396 { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"E2880" },
397 { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"CompaQ"},
398
399 { 2880,18,2,80,0,0x25,0x00,0xDF,0x02,"h1440" },
400 { 3360,21,2,80,0,0x1C,0x00,0xCF,0x0C,"H1680" },
401 { 820,10,2,41,1,0x25,0x01,0xDF,0x2E,"h410" },
402 { 1640,10,2,82,0,0x25,0x02,0xDF,0x2E,"H820" },
403 { 2952,18,2,82,0,0x25,0x00,0xDF,0x02,"h1476" },
404 { 3444,21,2,82,0,0x25,0x00,0xDF,0x0C,"H1722" },
405 { 840,10,2,42,1,0x25,0x01,0xDF,0x2E,"h420" },
406 { 1660,10,2,83,0,0x25,0x02,0xDF,0x2E,"H830" },
407 { 2988,18,2,83,0,0x25,0x00,0xDF,0x02,"h1494" },
408 { 3486,21,2,83,0,0x25,0x00,0xDF,0x0C,"H1743" },
409
410 { 1760,11,2,80,0,0x1C,0x09,0xCF,0x00,"h880" },
411 { 2080,13,2,80,0,0x1C,0x01,0xCF,0x00,"D1040" },
412 { 2240,14,2,80,0,0x1C,0x19,0xCF,0x00,"D1120" },
413 { 3200,20,2,80,0,0x1C,0x20,0xCF,0x2C,"h1600" },
414 { 3520,22,2,80,0,0x1C,0x08,0xCF,0x2e,"H1760" },
415 { 3840,24,2,80,0,0x1C,0x20,0xCF,0x00,"H1920" },
416 { 6400,40,2,80,0,0x25,0x5B,0xCF,0x00,"E3200" },
417 { 7040,44,2,80,0,0x25,0x5B,0xCF,0x00,"E3520" },
418 { 7680,48,2,80,0,0x25,0x63,0xCF,0x00,"E3840" },
419
420 { 3680,23,2,80,0,0x1C,0x10,0xCF,0x00,"H1840" },
421 { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" },
422 { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" },
423 };
424
425 #define NUMBER(x) (sizeof(x) / sizeof(*(x)))
426 #define SECTSIZE ( _FD_SECTSIZE(*floppy))
427
428
429 struct floppy_struct *current_type[N_DRIVE] = {
430 NULL, NULL, NULL, NULL,
431 NULL, NULL, NULL, NULL
432 };
433
434
435
436
437
438 struct floppy_struct user_params[N_DRIVE];
439
440 static int floppy_sizes[256];
441 static int floppy_blocksizes[256] = { 0, };
442
443
444
445
446
447
448 static int probing = 0;
449
450
451 #define FD_COMMAND_DETECT -2
452 #define FD_COMMAND_NONE -1
453 #define FD_COMMAND_ERROR 2
454 #define FD_COMMAND_OKAY 3
455
456 static volatile int command_status = FD_COMMAND_NONE, fdc_busy = 0;
457 static struct wait_queue *fdc_wait = NULL, *command_done = NULL;
458 #define NO_SIGNAL (!(current->signal & ~current->blocked) || !interruptible)
459 #define CALL(x) if( (x) == -EINTR) return -EINTR;
460 #define _WAIT(x,i) CALL(ret=wait_til_done((x),i))
461 #define WAIT(x) _WAIT((x),interruptible)
462 #define IWAIT(x) _WAIT((x),1)
463
464
465 static int format_errors;
466
467
468 static struct format_descr format_req;
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483 char *floppy_track_buffer=0;
484 int max_buffer_sectors=0;
485
486 int *errors;
487 typedef void (*done_f)(int);
488 struct cont_t {
489 void (*interrupt)(void);
490
491 void (*redo)(void);
492 void (*error)(void);
493 done_f done;
494 } *cont=NULL;
495
496 static void floppy_ready(void);
497 static void floppy_start(void);
498 static void process_fd_request(void);
499 static void recalibrate_floppy(void);
500 static void floppy_shutdown(void);
501
502 static int floppy_grab_irq_and_dma(void);
503 static void floppy_release_irq_and_dma(void);
504
505
506
507
508
509
510
511
512 #define CHECK_RESET { if ( FDCS->reset ){ reset_fdc(); return ; } }
513 static void reset_fdc(void);
514
515
516
517
518
519
520 #define NO_TRACK -1
521 #define NEED_1_RECAL -2
522 #define NEED_2_RECAL -3
523
524
525 static int usage_count = 0;
526
527
528
529 static int buffer_track = -1;
530 static int buffer_drive = -1;
531 static int buffer_min = -1;
532 static int buffer_max = -1;
533
534
535 static struct floppy_fdc_state fdc_state[N_FDC];
536 static int fdc;
537
538 static struct floppy_struct * floppy = floppy_type;
539 static unsigned char current_drive = 0;
540 static long current_count_sectors = 0;
541 static char *current_addr = 0;
542 static unsigned char sector_t;
543
544 #ifdef DEBUGT
545 long unsigned debugtimer;
546 #endif
547
548
549
550
551
552 static inline void set_debugt(void)
553 {
554 #ifdef DEBUGT
555 debugtimer = jiffies;
556 #endif
557 }
558
559 static inline void debugt(const char *message)
560 {
561 #ifdef DEBUGT
562 if ( DP->flags & DEBUGT )
563 printk("%s dtime=%lu\n", message, jiffies-debugtimer );
564 #endif
565 }
566
567 typedef void (*timeout_fn)(unsigned long);
568 static struct timer_list fd_timeout ={ NULL, NULL, 0, 0,
569 (timeout_fn) floppy_shutdown };
570
571 static const char *timeout_message;
572
573 #ifdef CONFIG_FLOPPY_SANITY
574 static void is_alive(const char *message)
575 {
576
577 if (fdc_busy && command_status < 2 && !fd_timeout.prev){
578 DPRINT1("timeout handler died: %s\n",message);
579 }
580 }
581 #endif
582
583 #ifdef CONFIG_FLOPPY_SANITY
584
585 #define OLOGSIZE 20
586
587 void (*lasthandler)(void) = NULL;
588 int interruptjiffies=0;
589 int resultjiffies=0;
590 int resultsize=0;
591 int lastredo=0;
592
593 static struct output_log {
594 unsigned char data;
595 unsigned char status;
596 unsigned long jiffies;
597 } output_log[OLOGSIZE];
598
599 static int output_log_pos=0;
600 #endif
601
602 #define CURRENTD -1
603 #define MAXTIMEOUT -2
604
605
606
607 static void reschedule_timeout(int drive, const char *message, int marg)
608 {
609 if (drive == CURRENTD )
610 drive = current_drive;
611 del_timer(&fd_timeout);
612 if (drive < 0 || drive > N_DRIVE) {
613 fd_timeout.expires = jiffies + 20*HZ;
614 drive=0;
615 } else
616 fd_timeout.expires = jiffies + UDP->timeout;
617 add_timer(&fd_timeout);
618 if (UDP->flags & FD_DEBUG){
619 DPRINT("reschedule timeout ");
620 printk(message, marg);
621 printk("\n");
622 }
623 timeout_message = message;
624 }
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659 static int disk_change(int drive)
660 {
661 int fdc=FDC(drive);
662 #ifdef CONFIG_FLOPPY_SANITY
663 if(jiffies < UDP->select_delay + UDRS->select_date)
664 DPRINT("WARNING disk change called early\n");
665 if(! (FDCS->dor & (0x10 << UNIT(drive))) ||
666 (FDCS->dor & 3) != UNIT(drive) ||
667 fdc != FDC(drive)){
668 DPRINT("probing disk change on unselected drive\n");
669 DPRINT3("drive=%d fdc=%d dor=%x\n",drive, FDC(drive),
670 FDCS->dor);
671 }
672 #endif
673
674 #ifdef DCL_DEBUG
675 if (UDP->flags & FD_DEBUG){
676 DPRINT1("checking disk change line for drive %d\n",drive);
677 DPRINT1("jiffies=%ld\n", jiffies);
678 DPRINT1("disk change line=%x\n",inb_p(FD_DIR)&0x80);
679 DPRINT1("flags=%x\n",UDRS->flags);
680 }
681 #endif
682 if (UDP->flags & FD_BROKEN_DCL)
683 return UTESTF(FD_DISK_CHANGED);
684 if( (inb_p(FD_DIR) ^ UDP->flags) & 0x80){
685 USETF(FD_VERIFY);
686 if(UDRS->maxblock){
687
688 USETF(FD_DISK_CHANGED);
689
690
691 if (UDRS->keep_data >= 0) {
692 if ((UDP->flags & FTD_MSG) &&
693 current_type[drive] != NULL)
694 DPRINT("Disk type is undefined after "
695 "disk change\n");
696 current_type[drive] = NULL;
697 floppy_sizes[TOMINOR(current_drive)] = MAX_DISK_SIZE;
698 }
699 }
700
701 return 1;
702 } else {
703 UDRS->last_checked=jiffies;
704 UCLEARF(FD_DISK_NEWCHANGE);
705 }
706 return 0;
707 }
708
709 static inline int is_selected(int dor, int unit)
710 {
711 return ( (dor & (0x10 << unit)) && (dor &3) == unit);
712 }
713
714 static int set_dor(int fdc, char mask, char data)
715 {
716 register unsigned char drive, unit, newdor,olddor;
717
718 if(FDCS->address == -1)
719 return -1;
720
721 olddor = FDCS->dor;
722 newdor = (olddor & mask) | data;
723 if ( newdor != olddor ){
724 unit = olddor & 0x3;
725 if(is_selected(olddor, unit) && !is_selected(newdor,unit)){
726 drive = REVDRIVE(fdc,unit);
727 #ifdef DCL_DEBUG
728 if (UDP->flags & FD_DEBUG){
729 DPRINT("calling disk change from set_dor\n");
730 }
731 #endif
732 disk_change(drive);
733 }
734 FDCS->dor = newdor;
735 outb_p(newdor, FD_DOR);
736
737 unit = newdor & 0x3;
738 if(!is_selected(olddor, unit) && is_selected(newdor,unit)){
739 drive = REVDRIVE(fdc,unit);
740 UDRS->select_date = jiffies;
741 }
742 }
743 if ( newdor & 0xf0 )
744 floppy_grab_irq_and_dma();
745 if( olddor & 0xf0 )
746 floppy_release_irq_and_dma();
747 return olddor;
748 }
749
750 static void twaddle(void)
751 {
752 if (DP->select_delay)
753 return;
754 outb_p(FDCS->dor & ~(0x10<<UNIT(current_drive)),FD_DOR);
755 outb_p(FDCS->dor, FD_DOR);
756 DRS->select_date = jiffies;
757 }
758
759
760
761 static void reset_fdc_info(int mode)
762 {
763 int drive;
764
765 FDCS->spec1 = FDCS->spec2 = -1;
766 FDCS->need_configure = 1;
767 FDCS->perp_mode = 1;
768 FDCS->rawcmd = 0;
769 for ( drive = 0; drive < N_DRIVE; drive++)
770 if (FDC(drive) == fdc &&
771 ( mode || UDRS->track != NEED_1_RECAL))
772 UDRS->track = NEED_2_RECAL;
773 }
774
775
776 static void set_fdc(int drive)
777 {
778 if (drive >= 0 && drive < N_DRIVE){
779 fdc = FDC(drive);
780 current_drive = drive;
781 }
782 set_dor(fdc,~0,8);
783 set_dor(1-fdc, ~8, 0);
784 if ( FDCS->rawcmd == 2 )
785 reset_fdc_info(1);
786 if( inb_p(FD_STATUS) != STATUS_READY )
787 FDCS->reset = 1;
788 }
789
790
791 static int lock_fdc(int drive, int interruptible)
792 {
793 if(!usage_count){
794 printk("trying to lock fdc while usage count=0\n");
795 return -1;
796 }
797 floppy_grab_irq_and_dma();
798 if (!current->pid)
799 run_task_queue(&tq_timer);
800 cli();
801 while (fdc_busy && NO_SIGNAL)
802 interruptible_sleep_on(&fdc_wait);
803 if(fdc_busy){
804 sti();
805 return -EINTR;
806 }
807 fdc_busy = 1;
808 sti();
809 command_status = FD_COMMAND_NONE;
810 set_fdc(drive);
811 reschedule_timeout(drive, "lock fdc", 0);
812 return 0;
813 }
814
815 #define LOCK_FDC(drive,interruptible) \
816 if(lock_fdc(drive,interruptible)) return -EINTR;
817
818
819
820 static inline void unlock_fdc(void)
821 {
822 if (!fdc_busy)
823 DPRINT("FDC access conflict!\n");
824
825 if ( DEVICE_INTR )
826 DPRINT1("device interrupt still active at FDC release: %p!\n",
827 DEVICE_INTR);
828 command_status = FD_COMMAND_NONE;
829 del_timer(&fd_timeout);
830 cont = NULL;
831 fdc_busy = 0;
832 floppy_release_irq_and_dma();
833 wake_up(&fdc_wait);
834 }
835
836
837 static void motor_off_callback(unsigned long nr)
838 {
839 unsigned char mask = ~(0x10 << UNIT(nr));
840
841 set_dor( FDC(nr), mask, 0 );
842 }
843
844 static struct timer_list motor_off_timer[N_DRIVE] = {
845 { NULL, NULL, 0, 0, motor_off_callback },
846 { NULL, NULL, 0, 1, motor_off_callback },
847 { NULL, NULL, 0, 2, motor_off_callback },
848 { NULL, NULL, 0, 3, motor_off_callback },
849 { NULL, NULL, 0, 4, motor_off_callback },
850 { NULL, NULL, 0, 5, motor_off_callback },
851 { NULL, NULL, 0, 6, motor_off_callback },
852 { NULL, NULL, 0, 7, motor_off_callback }
853 };
854
855
856 static void floppy_off(unsigned int drive)
857 {
858 unsigned long volatile delta;
859 register int fdc=FDC(drive);
860
861 if( !(FDCS->dor & ( 0x10 << UNIT(drive))))
862 return;
863
864 del_timer(motor_off_timer+drive);
865
866
867
868 if (UDP->rps ){
869 delta = jiffies - UDRS->first_read_date + HZ -
870 UDP->spindown_offset;
871 delta = (( delta * UDP->rps) % HZ ) / UDP->rps;
872 motor_off_timer[drive].expires = jiffies + UDP->spindown - delta;
873 }
874 add_timer(motor_off_timer+drive);
875 }
876
877
878
879
880
881
882 static void scandrives(void)
883 {
884 int i, drive, saved_drive;
885
886 if (DP->select_delay)
887 return;
888
889 saved_drive = current_drive;
890 for(i=0; i< N_DRIVE; i++){
891 drive = (saved_drive + i + 1 ) % N_DRIVE;
892 if ( UDRS->fd_ref == 0 || UDP->select_delay != 0)
893 continue;
894 set_fdc(drive);
895 if(! (set_dor( fdc, ~3, UNIT(drive) | ( 0x10 << UNIT(drive))) &
896 (0x10 << UNIT(drive))))
897
898
899 set_dor( fdc, ~( 0x10 << UNIT(drive) ), 0 );
900 }
901 set_fdc(saved_drive);
902 }
903
904 static struct timer_list fd_timer ={ NULL, NULL, 0, 0, 0 };
905
906
907
908 static void fd_watchdog(void)
909 {
910 #ifdef DCL_DEBUG
911 if (DP->flags & FD_DEBUG){
912 DPRINT("calling disk change from watchdog\n");
913 }
914 #endif
915
916 if ( disk_change(current_drive) ){
917 DPRINT("disk removed during i/o\n");
918 floppy_shutdown();
919 } else {
920 del_timer(&fd_timer);
921 fd_timer.function = (timeout_fn) fd_watchdog;
922 fd_timer.expires = jiffies + HZ / 10;
923 add_timer(&fd_timer);
924 }
925 }
926
927 static void main_command_interrupt(void)
928 {
929 del_timer(&fd_timer);
930 cont->interrupt();
931 }
932
933
934 static int wait_for_completion(int delay, timeout_fn function)
935 {
936 if ( FDCS->reset ){
937 reset_fdc();
938
939
940 return 1;
941 }
942
943 if ( jiffies < delay ){
944 del_timer(&fd_timer);
945 fd_timer.function = function;
946 fd_timer.expires = delay;
947 add_timer(&fd_timer);
948 return 1;
949 }
950 return 0;
951 }
952
953 static int hlt_disabled=0;
954 static void floppy_disable_hlt(void)
955 {
956 unsigned long flags;
957 save_flags(flags);
958 cli();
959 if(!hlt_disabled){
960 hlt_disabled=1;
961 #ifdef HAVE_DISABLE_HLT
962 disable_hlt();
963 #endif
964 }
965 restore_flags(flags);
966 }
967
968 static void floppy_enable_hlt(void)
969 {
970 unsigned long flags;
971 save_flags(flags);
972 cli();
973 if(hlt_disabled){
974 hlt_disabled=0;
975 #ifdef HAVE_DISABLE_HLT
976 enable_hlt();
977 #endif
978 }
979 restore_flags(flags);
980 }
981
982
983 static void setup_DMA(void)
984 {
985 #ifdef CONFIG_FLOPPY_SANITY
986 if (raw_cmd.length == 0){
987 int i;
988
989 printk("zero dma transfer size:");
990 for(i=0; i< raw_cmd.cmd_count; i++)
991 printk("%x,", raw_cmd.cmd[i]);
992 printk("\n");
993 cont->done(0);
994 FDCS->reset = 1;
995 return;
996 }
997 if ((!CURRENT ||
998 CURRENT->buffer != current_addr ||
999 raw_cmd.length > 512 * CURRENT->nr_sectors) &&
1000 (current_addr < floppy_track_buffer ||
1001 current_addr + raw_cmd.length >
1002 floppy_track_buffer + 1024 * max_buffer_sectors)){
1003 printk("bad address. start=%p lg=%lx tb=%p\n",
1004 current_addr, raw_cmd.length, floppy_track_buffer);
1005 if ( CURRENT ){
1006 printk("buffer=%p nr=%lx cnr=%lx\n",
1007 CURRENT->buffer, CURRENT->nr_sectors,
1008 CURRENT->current_nr_sectors);
1009 }
1010 cont->done(0);
1011 FDCS->reset=1;
1012 return;
1013 }
1014 if ((long) current_addr % 512 ){
1015 printk("non aligned address: %p\n", current_addr );
1016 cont->done(0);
1017 FDCS->reset=1;
1018 return;
1019 }
1020 if (CROSS_64KB(current_addr, raw_cmd.length)) {
1021 printk("DMA crossing 64-K boundary %p-%p\n",
1022 current_addr, current_addr + raw_cmd.length);
1023 cont->done(0);
1024 FDCS->reset=1;
1025 return;
1026 }
1027 #endif
1028 cli();
1029 disable_dma(FLOPPY_DMA);
1030 clear_dma_ff(FLOPPY_DMA);
1031 set_dma_mode(FLOPPY_DMA,
1032 (raw_cmd.flags & FD_RAW_READ)?
1033 DMA_MODE_READ : DMA_MODE_WRITE);
1034 set_dma_addr(FLOPPY_DMA, virt_to_bus(current_addr));
1035 set_dma_count(FLOPPY_DMA, raw_cmd.length);
1036 enable_dma(FLOPPY_DMA);
1037 sti();
1038 floppy_disable_hlt();
1039 }
1040
1041
1042 static int output_byte(char byte)
1043 {
1044 int counter;
1045 unsigned char status = 0;
1046 unsigned char rstatus;
1047
1048 if (FDCS->reset)
1049 return -1;
1050 for(counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
1051 rstatus = inb_p(FD_STATUS);
1052 status = rstatus &(STATUS_READY|STATUS_DIR|STATUS_DMA);
1053 if (!(status & STATUS_READY))
1054 continue;
1055 if (status == STATUS_READY){
1056 outb_p(byte,FD_DATA);
1057
1058 #ifdef CONFIG_FLOPPY_SANITY
1059 output_log[output_log_pos].data = byte;
1060 output_log[output_log_pos].status = rstatus;
1061 output_log[output_log_pos].jiffies = jiffies;
1062 output_log_pos = (output_log_pos + 1) % OLOGSIZE;
1063 #endif
1064 return 0;
1065 } else
1066 break;
1067 }
1068 FDCS->reset = 1;
1069 if ( !initialising )
1070 DPRINT2("Unable to send byte %x to FDC. Status=%x\n",
1071 byte, status);
1072 return -1;
1073 }
1074 #define LAST_OUT(x) if(output_byte(x)){ reset_fdc();return;}
1075
1076
1077 static int result(void)
1078 {
1079 int i = 0, counter, status = 0;
1080
1081 if (FDCS->reset)
1082 return -1;
1083 for (counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
1084 status = inb_p(FD_STATUS)&
1085 (STATUS_DIR|STATUS_READY|STATUS_BUSY|STATUS_DMA);
1086 if (!(status & STATUS_READY))
1087 continue;
1088 if (status == STATUS_READY){
1089 #ifdef CONFIG_FLOPPY_SANITY
1090 resultjiffies = jiffies;
1091 resultsize = i;
1092 #endif
1093 return i;
1094 }
1095 if (status & STATUS_DMA )
1096 break;
1097 if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {
1098 if (i >= MAX_REPLIES) {
1099 DPRINT("floppy_stat reply overrun\n");
1100 break;
1101 }
1102 reply_buffer[i++] = inb_p(FD_DATA);
1103 }
1104 }
1105 FDCS->reset = 1;
1106 if ( !initialising )
1107 DPRINT3("Getstatus times out (%x) on fdc %d [%d]\n",
1108 status, fdc, i);
1109 return -1;
1110 }
1111
1112
1113
1114
1115 static inline void perpendicular_mode(void)
1116 {
1117 unsigned char perp_mode;
1118
1119 if (!floppy)
1120 return;
1121 if (floppy->rate & 0x40){
1122 switch(raw_cmd.rate){
1123 case 0:
1124 perp_mode=2;
1125 break;
1126 case 3:
1127 perp_mode=3;
1128 break;
1129 default:
1130 DPRINT("Invalid data rate for perpendicular mode!\n");
1131 cont->done(0);
1132 FDCS->reset = 1;
1133
1134
1135 return;
1136 }
1137 } else
1138 perp_mode = 0;
1139
1140 if ( FDCS->perp_mode == perp_mode )
1141 return;
1142 if (FDCS->version >= FDC_82077_ORIG && FDCS->has_fifo) {
1143 output_byte(FD_PERPENDICULAR);
1144 output_byte(perp_mode);
1145 FDCS->perp_mode = perp_mode;
1146 } else if (perp_mode) {
1147 DPRINT("perpendicular mode not supported by this FDC.\n");
1148 }
1149 }
1150
1151 #define NOMINAL_DTR 500
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172 static void fdc_specify(void)
1173 {
1174 unsigned char spec1, spec2;
1175 int srt, hlt, hut;
1176 unsigned long dtr = NOMINAL_DTR;
1177 unsigned long scale_dtr = NOMINAL_DTR;
1178 int hlt_max_code = 0x7f;
1179 int hut_max_code = 0xf;
1180
1181 if (FDCS->need_configure && FDCS->has_fifo) {
1182 if ( FDCS->reset )
1183 return;
1184
1185
1186 output_byte(FD_CONFIGURE);
1187 output_byte(0);
1188 output_byte(0x2A);
1189 output_byte(0);
1190 if ( FDCS->reset ){
1191 FDCS->has_fifo=0;
1192 return;
1193 }
1194 FDCS->need_configure = 0;
1195
1196 }
1197
1198 switch (raw_cmd.rate & 0x03) {
1199 case 3:
1200 dtr = 1000;
1201 break;
1202 case 1:
1203 dtr = 300;
1204 break;
1205 case 2:
1206 dtr = 250;
1207 break;
1208 }
1209
1210 if (FDCS->version >= FDC_82072) {
1211 scale_dtr = dtr;
1212 hlt_max_code = 0x00;
1213 hut_max_code = 0x0;
1214 }
1215
1216
1217 srt = 16 - (DP->srt*scale_dtr/1000 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1218 if (srt > 0xf)
1219 srt = 0xf;
1220 else if (srt < 0)
1221 srt = 0;
1222
1223 hlt = (DP->hlt*scale_dtr/2 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1224 if (hlt < 0x01)
1225 hlt = 0x01;
1226 else if (hlt > 0x7f)
1227 hlt = hlt_max_code;
1228
1229 hut = (DP->hut*scale_dtr/16 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1230 if (hut < 0x1)
1231 hut = 0x1;
1232 else if (hut > 0xf)
1233 hut = hut_max_code;
1234
1235 spec1 = (srt << 4) | hut;
1236 spec2 = (hlt << 1);
1237
1238
1239 if (FDCS->spec1 != spec1 || FDCS->spec2 != spec2) {
1240
1241 output_byte(FD_SPECIFY);
1242 output_byte(FDCS->spec1 = spec1);
1243 output_byte(FDCS->spec2 = spec2);
1244 }
1245 }
1246
1247
1248
1249
1250
1251 static int fdc_dtr(void)
1252 {
1253
1254 if ( raw_cmd.rate == FDCS->dtr)
1255 return 0;
1256
1257
1258 outb_p(raw_cmd.rate, FD_DCR);
1259
1260
1261
1262
1263
1264
1265 FDCS->dtr = raw_cmd.rate;
1266 return(wait_for_completion(jiffies+2*HZ/100,
1267 (timeout_fn) floppy_ready));
1268 }
1269
1270 static void tell_sector(void)
1271 {
1272 printk(": track %d, head %d, sector %d, size %d",
1273 R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
1274 }
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284 static int interpret_errors(void)
1285 {
1286 char bad;
1287
1288 if (inr!=7) {
1289 DPRINT("-- FDC reply error");
1290 FDCS->reset = 1;
1291 return 1;
1292 }
1293
1294
1295 switch ((ST0 & ST0_INTR)>>6) {
1296 case 1:
1297 bad = 1;
1298 if (ST1 & ST1_WP) {
1299 DPRINT("Drive is write protected\n");
1300 CLEARF(FD_DISK_WRITABLE);
1301 cont->done(0);
1302 bad = 2;
1303 } else if (ST1 & ST1_ND) {
1304 SETF(FD_NEED_TWADDLE);
1305 } else if (ST1 & ST1_OR) {
1306 if (DP->flags & FTD_MSG )
1307 DPRINT("Over/Underrun - retrying\n");
1308 bad = 0;
1309 }else if(*errors >= DP->max_errors.reporting){
1310 DPRINT("");
1311 if (ST0 & ST0_ECE) {
1312 printk("Recalibrate failed!");
1313 } else if (ST2 & ST2_CRC) {
1314 printk("data CRC error");
1315 tell_sector();
1316 } else if (ST1 & ST1_CRC) {
1317 printk("CRC error");
1318 tell_sector();
1319 } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
1320 if (!probing) {
1321 printk("sector not found");
1322 tell_sector();
1323 } else
1324 printk("probe failed...");
1325 } else if (ST2 & ST2_WC) {
1326 printk("wrong cylinder");
1327 } else if (ST2 & ST2_BC) {
1328 printk("bad cylinder");
1329 } else {
1330 printk("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", ST0, ST1, ST2);
1331 tell_sector();
1332 }
1333 printk("\n");
1334
1335 }
1336 if ( ST2 & ST2_WC || ST2 & ST2_BC)
1337
1338 DRS->track = NEED_2_RECAL;
1339 return bad;
1340 case 2:
1341 DPRINT("Invalid FDC command given!\n");
1342 cont->done(0);
1343 return 2;
1344 case 3:
1345 DPRINT("Abnormal termination caused by polling\n");
1346 cont->error();
1347 return 2;
1348 default:
1349 return 0;
1350 }
1351 }
1352
1353
1354
1355
1356
1357
1358 static void setup_rw_floppy(void)
1359 {
1360 int i,ready_date,r, flags,dflags;
1361 timeout_fn function;
1362
1363 flags = raw_cmd.flags;
1364 if ( flags & ( FD_RAW_READ | FD_RAW_WRITE))
1365 flags |= FD_RAW_INTR;
1366
1367 if ((flags & FD_RAW_SPIN) && !(flags & FD_RAW_NO_MOTOR)){
1368 ready_date = DRS->spinup_date + DP->spinup;
1369
1370
1371
1372
1373 if ( ready_date > jiffies + DP->select_delay){
1374 ready_date -= DP->select_delay;
1375 function = (timeout_fn) floppy_start;
1376 } else
1377 function = (timeout_fn) setup_rw_floppy;
1378
1379
1380 if (wait_for_completion(ready_date,function))
1381 return;
1382 }
1383 dflags = DRS->flags;
1384
1385 if ( (flags & FD_RAW_READ) || (flags & FD_RAW_WRITE))
1386 setup_DMA();
1387
1388 if ( flags & FD_RAW_INTR )
1389 SET_INTR(main_command_interrupt);
1390
1391 r=0;
1392 for(i=0; i< raw_cmd.cmd_count; i++)
1393 r|=output_byte( raw_cmd.cmd[i] );
1394
1395 #ifdef DEBUGT
1396 debugt("rw_command: ");
1397 #endif
1398 if ( r ){
1399 reset_fdc();
1400 return;
1401 }
1402
1403 if ( ! ( flags & FD_RAW_INTR )){
1404 inr = result();
1405 cont->interrupt();
1406 } else if ( flags & FD_RAW_NEED_DISK )
1407 fd_watchdog();
1408 }
1409
1410 static int blind_seek;
1411
1412
1413
1414
1415
1416 static void seek_interrupt(void)
1417 {
1418 #ifdef DEBUGT
1419 debugt("seek interrupt:");
1420 #endif
1421 if (inr != 2 || (ST0 & 0xF8) != 0x20 ) {
1422 DPRINT("seek failed\n");
1423 DRS->track = NEED_2_RECAL;
1424 cont->error();
1425 cont->redo();
1426 return;
1427 }
1428 if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek){
1429 #ifdef DCL_DEBUG
1430 if (DP->flags & FD_DEBUG){
1431 DPRINT("clearing NEWCHANGE flag because of effective seek\n");
1432 DPRINT1("jiffies=%ld\n", jiffies);
1433 }
1434 #endif
1435 CLEARF(FD_DISK_NEWCHANGE);
1436 DRS->select_date = jiffies;
1437 }
1438 DRS->track = ST1;
1439 floppy_ready();
1440 }
1441
1442 static void check_wp(void)
1443 {
1444 if (TESTF(FD_VERIFY)) {
1445
1446 output_byte( FD_GETSTATUS );
1447 output_byte( UNIT(current_drive) );
1448 if ( result() != 1 ){
1449 FDCS->reset = 1;
1450 return;
1451 }
1452 CLEARF(FD_VERIFY);
1453 CLEARF(FD_NEED_TWADDLE);
1454 #ifdef DCL_DEBUG
1455 if (DP->flags & FD_DEBUG){
1456 DPRINT("checking whether disk is write protected\n");
1457 DPRINT1("wp=%x\n",ST3 & 0x40);
1458 }
1459 #endif
1460 if (!( ST3 & 0x40))
1461 SETF(FD_DISK_WRITABLE);
1462 else
1463 CLEARF(FD_DISK_WRITABLE);
1464 }
1465 }
1466
1467 static void seek_floppy(void)
1468 {
1469 int track;
1470
1471 blind_seek=0;
1472
1473 #ifdef DCL_DEBUG
1474 if (DP->flags & FD_DEBUG){
1475 DPRINT("calling disk change from seek\n");
1476 }
1477 #endif
1478
1479 if (!TESTF(FD_DISK_NEWCHANGE) &&
1480 disk_change(current_drive) &&
1481 (raw_cmd.flags & FD_RAW_NEED_DISK)){
1482
1483
1484
1485
1486 SETF(FD_DISK_CHANGED);
1487 cont->done(0);
1488 cont->redo();
1489 return;
1490 }
1491 if ( DRS->track <= NEED_1_RECAL ){
1492 recalibrate_floppy();
1493 return;
1494 } else if (TESTF(FD_DISK_NEWCHANGE) &&
1495 (raw_cmd.flags & FD_RAW_NEED_DISK) &&
1496 (DRS->track <= NO_TRACK || DRS->track == raw_cmd.track)) {
1497
1498
1499 if ( raw_cmd.track )
1500 track = raw_cmd.track - 1;
1501 else {
1502 if(DP->flags & FD_SILENT_DCL_CLEAR){
1503 set_dor(fdc, ~(0x10 << UNIT(current_drive)), 0);
1504 blind_seek = 1;
1505 raw_cmd.flags |= FD_RAW_NEED_SEEK;
1506 }
1507 track = 1;
1508 }
1509 } else {
1510 check_wp();
1511 if (raw_cmd.track != DRS->track &&
1512 (raw_cmd.flags & FD_RAW_NEED_SEEK))
1513 track = raw_cmd.track;
1514 else {
1515 setup_rw_floppy();
1516 return;
1517 }
1518 }
1519
1520 SET_INTR(seek_interrupt);
1521 output_byte(FD_SEEK);
1522 output_byte(UNIT(current_drive));
1523 LAST_OUT(track);
1524 #ifdef DEBUGT
1525 debugt("seek command:");
1526 #endif
1527 }
1528
1529 static void recal_interrupt(void)
1530 {
1531 #ifdef DEBUGT
1532 debugt("recal interrupt:");
1533 #endif
1534 if (inr !=2 )
1535 FDCS->reset = 1;
1536 else if (ST0 & ST0_ECE) {
1537 switch(DRS->track){
1538 case NEED_1_RECAL:
1539 #ifdef DEBUGT
1540 debugt("recal interrupt need 1 recal:");
1541 #endif
1542
1543
1544
1545
1546 cont->error();
1547 cont->redo();
1548 return;
1549 case NEED_2_RECAL:
1550 #ifdef DEBUGT
1551 debugt("recal interrupt need 2 recal:");
1552 #endif
1553
1554
1555
1556
1557
1558 #ifdef DCL_DEBUG
1559 if (DP->flags & FD_DEBUG){
1560 DPRINT("clearing NEWCHANGE flag because of second recalibrate\n");
1561 }
1562 #endif
1563
1564 CLEARF(FD_DISK_NEWCHANGE);
1565 DRS->select_date = jiffies;
1566
1567 default:
1568 #ifdef DEBUGT
1569 debugt("recal interrupt default:");
1570 #endif
1571
1572
1573
1574
1575
1576 DRS->track = NEED_1_RECAL;
1577 break;
1578 }
1579 } else
1580 DRS->track = ST1;
1581 floppy_ready();
1582 }
1583
1584
1585
1586
1587
1588 static void unexpected_floppy_interrupt(void)
1589 {
1590 int i;
1591 if ( initialising )
1592 return;
1593 if(print_unex){
1594 DPRINT("unexpected interrupt\n");
1595 if ( inr >= 0 )
1596 for(i=0; i<inr; i++)
1597 printk("%d %x\n", i, reply_buffer[i] );
1598 }
1599 while(1){
1600 output_byte(FD_SENSEI);
1601 inr=result();
1602 if ( inr != 2 )
1603 break;
1604 if(print_unex){
1605 printk("sensei\n");
1606 for(i=0; i<inr; i++)
1607 printk("%d %x\n", i, reply_buffer[i] );
1608 }
1609 }
1610 FDCS->reset = 1;
1611 }
1612
1613 struct tq_struct floppy_tq =
1614 { 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
1615
1616
1617 static void floppy_interrupt(int irq, struct pt_regs * regs)
1618 {
1619 void (*handler)(void) = DEVICE_INTR;
1620
1621 lasthandler = handler;
1622 interruptjiffies = jiffies;
1623
1624 floppy_enable_hlt();
1625 CLEAR_INTR;
1626 if ( fdc >= N_FDC || FDCS->address == -1){
1627
1628 printk("DOR0=%x\n", fdc_state[0].dor);
1629 printk("floppy interrupt on bizarre fdc %d\n",fdc);
1630 printk("handler=%p\n", handler);
1631 is_alive("bizarre fdc");
1632 return;
1633 }
1634 inr = result();
1635 if (!handler){
1636 unexpected_floppy_interrupt();
1637 is_alive("unexpected");
1638 return;
1639 }
1640 if ( inr == 0 ){
1641 do {
1642 output_byte(FD_SENSEI);
1643 inr = result();
1644 } while ( (ST0 & 0x83) != UNIT(current_drive) && inr == 2);
1645 }
1646 floppy_tq.routine = (void *)(void *) handler;
1647 queue_task_irq(&floppy_tq, &tq_timer);
1648 is_alive("normal interrupt end");
1649 }
1650
1651 static void recalibrate_floppy(void)
1652 {
1653 #ifdef DEBUGT
1654 debugt("recalibrate floppy:");
1655 #endif
1656 SET_INTR(recal_interrupt);
1657 output_byte(FD_RECALIBRATE);
1658 LAST_OUT(UNIT(current_drive));
1659 }
1660
1661
1662
1663
1664 static void reset_interrupt(void)
1665 {
1666 #ifdef DEBUGT
1667 debugt("reset interrupt:");
1668 #endif
1669 fdc_specify();
1670 result();
1671 if ( FDCS->reset )
1672 cont->error();
1673 cont->redo();
1674 }
1675
1676
1677
1678
1679
1680 static void reset_fdc(void)
1681 {
1682 SET_INTR(reset_interrupt);
1683 FDCS->reset = 0;
1684 reset_fdc_info(0);
1685 if ( FDCS->version >= FDC_82077 )
1686 outb_p(0x80 | ( FDCS->dtr &3), FD_STATUS);
1687 else {
1688 outb_p(FDCS->dor & ~0x04, FD_DOR);
1689 udelay(FD_RESET_DELAY);
1690 outb(FDCS->dor, FD_DOR);
1691 }
1692 }
1693
1694 static void empty(void)
1695 {
1696 }
1697
1698 void show_floppy(void)
1699 {
1700 int i;
1701
1702 printk("\n");
1703 printk("floppy driver state\n");
1704 printk("-------------------\n");
1705 printk("now=%ld last interrupt=%d last called handler=%p\n",
1706 jiffies, interruptjiffies, lasthandler);
1707
1708
1709 #ifdef CONFIG_FLOPPY_SANITY
1710 printk("timeout_message=%s\n", timeout_message);
1711 printk("last output bytes:\n");
1712 for(i=0; i < OLOGSIZE; i++)
1713 printk("%2x %2x %ld\n",
1714 output_log[(i+output_log_pos) % OLOGSIZE].data,
1715 output_log[(i+output_log_pos) % OLOGSIZE].status,
1716 output_log[(i+output_log_pos) % OLOGSIZE].jiffies);
1717 printk("last result at %d\n", resultjiffies);
1718 printk("last redo_fd_request at %d\n", lastredo);
1719 for(i=0; i<resultsize; i++){
1720 printk("%2x ", reply_buffer[i]);
1721 }
1722 printk("\n");
1723 #endif
1724
1725 #if 0
1726 for(i=0; i<N_FDC; i++){
1727 if(FDCS->address != -1){
1728 printk("dor %d = %x\n", i, fdc_state[i].dor );
1729 outb_p(fdc_state[i].address+2, fdc_state[i].dor);
1730 udelay(1000);
1731 }
1732 }
1733 #endif
1734 printk("status=%x\n", inb_p(FD_STATUS));
1735 printk("fdc_busy=%d\n", fdc_busy);
1736 if( DEVICE_INTR)
1737 printk("DEVICE_INTR=%p\n", DEVICE_INTR);
1738 if(floppy_tq.sync)
1739 printk("floppy_tq.routine=%p\n", floppy_tq.routine);
1740 if(fd_timer.prev)
1741 printk("fd_timer.function=%p\n", fd_timer.function);
1742 if(fd_timeout.prev){
1743 printk("timer_table=%p\n",fd_timeout.function);
1744 printk("expires=%ld\n",fd_timeout.expires-jiffies);
1745 printk("now=%ld\n",jiffies);
1746 }
1747 printk("cont=%p\n", cont);
1748 printk("CURRENT=%p\n", CURRENT);
1749 printk("command_status=%d\n", command_status);
1750 printk("\n");
1751 }
1752
1753 static void floppy_shutdown(void)
1754 {
1755 if(!initialising)
1756 show_floppy();
1757 CLEAR_INTR;
1758 floppy_tq.routine = (void *)(void *) empty;
1759 del_timer( &fd_timer);
1760
1761 floppy_enable_hlt();
1762 disable_dma(FLOPPY_DMA);
1763
1764
1765 if(!initialising)
1766 DPRINT("floppy timeout\n");
1767 FDCS->reset = 1;
1768 if (cont){
1769 cont->done(0);
1770 cont->redo();
1771 } else {
1772 printk("no cont in shutdown!\n");
1773 process_fd_request();
1774 }
1775 is_alive("floppy shutdown");
1776 }
1777
1778
1779
1780 static int start_motor( void (*function)(void) )
1781 {
1782 int mask, data;
1783
1784 mask = 0xfc;
1785 data = UNIT(current_drive);
1786 if (!(raw_cmd.flags & FD_RAW_NO_MOTOR)){
1787 if(!(FDCS->dor & ( 0x10 << UNIT(current_drive) ) )){
1788 set_debugt();
1789
1790 DRS->first_read_date = 0;
1791
1792 DRS->spinup_date = jiffies;
1793 data |= (0x10 << UNIT(current_drive));
1794 }
1795 } else
1796 if (FDCS->dor & ( 0x10 << UNIT(current_drive) ) )
1797 mask &= ~(0x10 << UNIT(current_drive));
1798
1799
1800 del_timer(motor_off_timer + current_drive);
1801 set_dor( fdc, mask, data);
1802
1803
1804 return(wait_for_completion(DRS->select_date+DP->select_delay,
1805 (timeout_fn) function));
1806 }
1807
1808 static void floppy_ready(void)
1809 {
1810 CHECK_RESET;
1811 if(start_motor(floppy_ready)) return;
1812 if(fdc_dtr()) return;
1813
1814 #ifdef DCL_DEBUG
1815 if (DP->flags & FD_DEBUG){
1816 DPRINT("calling disk change from floppy_ready\n");
1817 }
1818 #endif
1819
1820 if(!(raw_cmd.flags & FD_RAW_NO_MOTOR) &&
1821 disk_change(current_drive) &&
1822 !DP->select_delay)
1823 twaddle();
1824
1825
1826 if ( raw_cmd.flags & (FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK)){
1827 perpendicular_mode();
1828 fdc_specify();
1829 seek_floppy();
1830 } else
1831 setup_rw_floppy();
1832 }
1833
1834 static void floppy_start(void)
1835 {
1836 reschedule_timeout(CURRENTD, "floppy start", 0);
1837
1838 scandrives();
1839 #ifdef DCL_DEBUG
1840 if (DP->flags & FD_DEBUG){
1841 DPRINT("setting NEWCHANGE in floppy_start\n");
1842 }
1843 #endif
1844 SETF(FD_DISK_NEWCHANGE);
1845 floppy_ready();
1846 }
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862 static void do_wakeup(void)
1863 {
1864 reschedule_timeout(MAXTIMEOUT, "do wakeup", 0);
1865 cont = 0;
1866 command_status += 2;
1867 wake_up(&command_done);
1868 }
1869
1870 static struct cont_t wakeup_cont={
1871 empty,
1872 do_wakeup,
1873 empty,
1874 (done_f)empty
1875 };
1876
1877 static int wait_til_done( void (*handler)(void ), int interruptible )
1878 {
1879 int ret;
1880
1881 floppy_tq.routine = (void *)(void *) handler;
1882 queue_task(&floppy_tq, &tq_timer);
1883
1884 cli();
1885 while(command_status < 2 && NO_SIGNAL){
1886 is_alive("wait_til_done");
1887 if (current->pid)
1888 interruptible_sleep_on(&command_done);
1889 else {
1890 sti();
1891 run_task_queue(&tq_timer);
1892 cli();
1893 }
1894 }
1895 if(command_status < 2){
1896 sti();
1897 floppy_shutdown();
1898 process_fd_request();
1899 return -EINTR;
1900 }
1901 sti();
1902
1903 if ( FDCS->reset )
1904 command_status = FD_COMMAND_ERROR;
1905 if ( command_status == FD_COMMAND_OKAY )
1906 ret=0;
1907 else
1908 ret=-EIO;
1909 command_status = FD_COMMAND_NONE;
1910 return ret;
1911 }
1912
1913 static void generic_done(int result)
1914 {
1915 command_status = result;
1916 cont = &wakeup_cont;
1917 }
1918
1919 static void generic_success(void)
1920 {
1921 generic_done(1);
1922 }
1923
1924 static void generic_failure(void)
1925 {
1926 generic_done(0);
1927 }
1928
1929 static void success_and_wakeup(void)
1930 {
1931 generic_success();
1932 do_wakeup();
1933 }
1934
1935 static void failure_and_wakeup(void)
1936 {
1937 generic_failure();
1938 do_wakeup();
1939 }
1940
1941
1942
1943
1944
1945
1946 static int next_valid_format(void)
1947 {
1948 int probed_format;
1949
1950 probed_format = DRS->probed_format;
1951 while(1){
1952 if ( probed_format >= 8 ||
1953 ! DP->autodetect[probed_format] ){
1954 DRS->probed_format = 0;
1955 return 1;
1956 }
1957 if ( floppy_type[DP->autodetect[probed_format]].sect ){
1958 DRS->probed_format = probed_format;
1959 return 0;
1960 }
1961 probed_format++;
1962 }
1963 }
1964
1965 static void bad_flp_intr(void)
1966 {
1967 if ( probing ){
1968 DRS->probed_format++;
1969 if ( !next_valid_format())
1970 return;
1971 }
1972 (*errors)++;
1973 if (*errors > DRWE->badness)
1974 DRWE->badness = *errors;
1975 if (*errors > DP->max_errors.abort)
1976 cont->done(0);
1977 if (*errors > DP->max_errors.reset)
1978 FDCS->reset = 1;
1979 else if (*errors > DP->max_errors.recal)
1980 DRS->track = NEED_2_RECAL;
1981 }
1982
1983 static void set_floppy(kdev_t device)
1984 {
1985 if (TYPE(device))
1986 floppy = TYPE(device) + floppy_type;
1987 else
1988 floppy = current_type[ DRIVE(device) ];
1989 }
1990
1991
1992
1993
1994
1995 static void format_interrupt(void)
1996 {
1997 switch (interpret_errors()){
1998 case 1:
1999 cont->error();
2000 case 2:
2001 break;
2002 case 0:
2003 cont->done(1);
2004 }
2005 cont->redo();
2006 }
2007
2008 #define CODE2SIZE (ssize = ( ( 1 << SIZECODE ) + 3 ) >> 2)
2009 #define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80 ) >>1))
2010 #define CT(x) ( (x) | 0x40 )
2011 static void setup_format_params(void)
2012 {
2013 struct fparm {
2014 unsigned char track,head,sect,size;
2015 } *here = (struct fparm *)floppy_track_buffer;
2016 int il,n;
2017 int count,head_shift,track_shift;
2018
2019 raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
2020 FD_RAW_NEED_SEEK;
2021 raw_cmd.rate = floppy->rate & 0x3;
2022 raw_cmd.cmd_count = NR_F;
2023 COMMAND = FM_MODE(floppy,FD_FORMAT);
2024 DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,format_req.head);
2025 F_SIZECODE = FD_SIZECODE(floppy);
2026 F_SECT_PER_TRACK = floppy->sect << 2 >> F_SIZECODE;
2027 F_GAP = floppy->fmt_gap;
2028 F_FILL = FD_FILL_BYTE;
2029
2030 current_addr = floppy_track_buffer;
2031 raw_cmd.length = 4 * F_SECT_PER_TRACK;
2032
2033
2034 head_shift = (F_SECT_PER_TRACK + 5) / 6;
2035
2036
2037 track_shift = 2 * head_shift + 3;
2038
2039
2040 n = (track_shift * format_req.track + head_shift * format_req.head )
2041 % F_SECT_PER_TRACK;
2042
2043
2044 il = 1;
2045 if (floppy->sect > DP->interleave_sect && F_SIZECODE == 2)
2046 il++;
2047
2048
2049 for (count = 0; count < F_SECT_PER_TRACK; ++count) {
2050 here[count].track = format_req.track;
2051 here[count].head = format_req.head;
2052 here[count].sect = 0;
2053 here[count].size = F_SIZECODE;
2054 }
2055
2056 for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
2057 here[n].sect = count;
2058 n = (n+il) % F_SECT_PER_TRACK;
2059 if (here[n].sect) {
2060 ++n;
2061 if (n>= F_SECT_PER_TRACK) {
2062 n-=F_SECT_PER_TRACK;
2063 while (here[n].sect) ++n;
2064 }
2065 }
2066 }
2067 }
2068
2069 static void redo_format(void)
2070 {
2071 raw_cmd.track = format_req.track << STRETCH(floppy);
2072 buffer_track = -1;
2073 setup_format_params();
2074 floppy_start();
2075 #ifdef DEBUGT
2076 debugt("queue format request");
2077 #endif
2078 }
2079
2080 static struct cont_t format_cont={
2081 format_interrupt,
2082 redo_format,
2083 bad_flp_intr,
2084 generic_done };
2085
2086 static int do_format(kdev_t device, struct format_descr *tmp_format_req)
2087 {
2088 int ret;
2089 int drive=DRIVE(device);
2090
2091 LOCK_FDC(drive,1);
2092 set_floppy(device);
2093 if (!floppy ||
2094 floppy->track > DP->tracks ||
2095 tmp_format_req->track >= floppy->track ||
2096 tmp_format_req->head >= floppy->head ||
2097 (floppy->sect << 2) % (1 << FD_SIZECODE(floppy)) ||
2098 !floppy->fmt_gap) {
2099 process_fd_request();
2100 return -EINVAL;
2101 }
2102 format_req = *tmp_format_req;
2103 format_errors = 0;
2104 cont = &format_cont;
2105 errors = &format_errors;
2106 IWAIT(redo_format);
2107 process_fd_request();
2108 return ret;
2109 }
2110
2111
2112
2113
2114
2115
2116
2117
2118 static void request_done(int uptodate)
2119 {
2120 int block;
2121
2122 probing = 0;
2123 reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
2124
2125 if (!CURRENT){
2126 DPRINT("request list destroyed in floppy request done\n");
2127 return;
2128 }
2129 if (uptodate){
2130
2131
2132 block = current_count_sectors + CURRENT->sector;
2133 if (block > DRS->maxblock)
2134 DRS->maxblock=block;
2135 if ( block > floppy->sect)
2136 DRS->maxtrack = 1;
2137
2138
2139 while (current_count_sectors && CURRENT &&
2140 current_count_sectors >= CURRENT->current_nr_sectors ){
2141 current_count_sectors -= CURRENT->current_nr_sectors;
2142 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
2143 CURRENT->sector += CURRENT->current_nr_sectors;
2144 end_request(1);
2145 }
2146 if ( current_count_sectors && CURRENT){
2147
2148 CURRENT->buffer += current_count_sectors <<9;
2149 CURRENT->current_nr_sectors -= current_count_sectors;
2150 CURRENT->nr_sectors -= current_count_sectors;
2151 CURRENT->sector += current_count_sectors;
2152 return;
2153 }
2154
2155 if ( current_count_sectors && ! CURRENT )
2156 DPRINT("request list destroyed in floppy request done\n");
2157
2158 } else {
2159 if(CURRENT->cmd == WRITE) {
2160
2161 DRWE->write_errors++;
2162 if(DRWE->write_errors == 1) {
2163 DRWE->first_error_sector = CURRENT->sector;
2164 DRWE->first_error_generation = DRS->generation;
2165 }
2166 DRWE->last_error_sector = CURRENT->sector;
2167 DRWE->last_error_generation = DRS->generation;
2168 }
2169 end_request(0);
2170 }
2171 }
2172
2173
2174 static void rw_interrupt(void)
2175 {
2176 int nr_sectors, ssize;
2177
2178 if ( ! DRS->first_read_date )
2179 DRS->first_read_date = jiffies;
2180
2181 nr_sectors = 0;
2182 CODE2SIZE;
2183 nr_sectors = ((R_TRACK-TRACK)*floppy->head+R_HEAD-HEAD) *
2184 floppy->sect + ((R_SECTOR-SECTOR) << SIZECODE >> 2) -
2185 (sector_t % floppy->sect) % ssize;
2186
2187 #ifdef CONFIG_FLOPPY_SANITY
2188 if ( nr_sectors > current_count_sectors + ssize -
2189 (current_count_sectors + sector_t) % ssize +
2190 sector_t % ssize){
2191 DPRINT2("long rw: %x instead of %lx\n",
2192 nr_sectors, current_count_sectors);
2193 printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
2194 printk("rh=%d h=%d\n", R_HEAD, HEAD);
2195 printk("rt=%d t=%d\n", R_TRACK, TRACK);
2196 printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
2197 sector_t, ssize);
2198 }
2199 #endif
2200 if ( nr_sectors < 0 )
2201 nr_sectors = 0;
2202 if ( nr_sectors < current_count_sectors )
2203 current_count_sectors = nr_sectors;
2204
2205 switch (interpret_errors()){
2206 case 2:
2207 cont->redo();
2208 return;
2209 case 1:
2210 if ( !current_count_sectors){
2211 cont->error();
2212 cont->redo();
2213 return;
2214 }
2215 break;
2216 case 0:
2217 if ( !current_count_sectors){
2218 cont->redo();
2219 return;
2220 }
2221 current_type[current_drive] = floppy;
2222 floppy_sizes[TOMINOR(current_drive)] = floppy->size >> 1;
2223 break;
2224 }
2225
2226 if (probing) {
2227 if (DP->flags & FTD_MSG)
2228 DPRINT2("Auto-detected floppy type %s in fd%d\n",
2229 floppy->name,current_drive);
2230 current_type[current_drive] = floppy;
2231 floppy_sizes[TOMINOR(current_drive)] = floppy->size >> 1;
2232 probing = 0;
2233 }
2234
2235 if ( CT(COMMAND) != FD_READ || current_addr == CURRENT->buffer ){
2236
2237 cont->done(1);
2238 } else if ( CT(COMMAND) == FD_READ){
2239 buffer_track = raw_cmd.track;
2240 buffer_drive = current_drive;
2241 if ( nr_sectors + sector_t > buffer_max )
2242 buffer_max = nr_sectors + sector_t;
2243 }
2244 cont->redo();
2245 }
2246
2247
2248 static int buffer_chain_size(void)
2249 {
2250 struct buffer_head *bh;
2251 int size;
2252 char *base;
2253
2254 base = CURRENT->buffer;
2255 size = CURRENT->current_nr_sectors << 9;
2256 bh = CURRENT->bh;
2257
2258 if (bh){
2259 bh = bh->b_reqnext;
2260 while ( bh && bh->b_data == base + size ){
2261 size += bh->b_size;
2262 bh = bh->b_reqnext;
2263 }
2264 }
2265 return size >> 9;
2266 }
2267
2268
2269 static int transfer_size(int ssize, int max_sector, int max_size)
2270 {
2271 if ( max_sector > sector_t + max_size)
2272 max_sector = sector_t + max_size;
2273
2274
2275 max_sector -= (max_sector % floppy->sect ) % ssize;
2276
2277
2278 current_count_sectors = max_sector - sector_t ;
2279
2280 return max_sector;
2281 }
2282
2283
2284
2285
2286 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
2287 {
2288 int remaining;
2289 struct buffer_head *bh;
2290 char *buffer, *dma_buffer;
2291 int size;
2292
2293 if ( max_sector > max_sector_2 )
2294 max_sector = max_sector_2;
2295
2296 max_sector = transfer_size(ssize, max_sector, CURRENT->nr_sectors);
2297
2298 if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
2299 buffer_max > sector_t + CURRENT->nr_sectors){
2300 current_count_sectors = buffer_max - sector_t;
2301 if ( current_count_sectors > CURRENT->nr_sectors )
2302 current_count_sectors = CURRENT->nr_sectors;
2303 }
2304 remaining = current_count_sectors << 9;
2305 #ifdef CONFIG_FLOPPY_SANITY
2306 if ((remaining >> 9) > CURRENT->nr_sectors &&
2307 CT(COMMAND) == FD_WRITE ){
2308 DPRINT("in copy buffer\n");
2309 printk("current_count_sectors=%ld\n", current_count_sectors);
2310 printk("remaining=%d\n", remaining >> 9);
2311 printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
2312 printk("CURRENT->current_nr_sectors=%ld\n",
2313 CURRENT->current_nr_sectors);
2314 printk("max_sector=%d\n", max_sector);
2315 printk("ssize=%d\n", ssize);
2316 }
2317 #endif
2318
2319 if ( max_sector > buffer_max )
2320 buffer_max = max_sector;
2321
2322 dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
2323
2324 bh = CURRENT->bh;
2325 size = CURRENT->current_nr_sectors << 9;
2326 buffer = CURRENT->buffer;
2327
2328 while ( remaining > 0){
2329 if ( size > remaining )
2330 size = remaining;
2331 #ifdef CONFIG_FLOPPY_SANITY
2332 if (dma_buffer + size >
2333 floppy_track_buffer + (max_buffer_sectors << 10) ||
2334 dma_buffer < floppy_track_buffer ){
2335 DPRINT1("buffer overrun in copy buffer %d\n",
2336 (int) ((floppy_track_buffer - dma_buffer) >>9));
2337 printk("sector_t=%d buffer_min=%d\n",
2338 sector_t, buffer_min);
2339 printk("current_count_sectors=%ld\n",
2340 current_count_sectors);
2341 if ( CT(COMMAND) == FD_READ )
2342 printk("read\n");
2343 if ( CT(COMMAND) == FD_READ )
2344 printk("write\n");
2345 break;
2346 }
2347 if ( ((unsigned long)buffer) % 512 )
2348 DPRINT1("%p buffer not aligned\n", buffer);
2349 #endif
2350 if ( CT(COMMAND) == FD_READ )
2351 memcpy( buffer, dma_buffer, size);
2352 else
2353 memcpy( dma_buffer, buffer, size);
2354 remaining -= size;
2355 if ( !remaining)
2356 break;
2357
2358 dma_buffer += size;
2359 bh = bh->b_reqnext;
2360 #ifdef CONFIG_FLOPPY_SANITY
2361 if ( !bh){
2362 DPRINT("bh=null in copy buffer after copy\n");
2363 break;
2364 }
2365 #endif
2366 size = bh->b_size;
2367 buffer = bh->b_data;
2368 }
2369 #ifdef CONFIG_FLOPPY_SANITY
2370 if ( remaining ){
2371 if ( remaining > 0 )
2372 max_sector -= remaining >> 9;
2373 DPRINT1("weirdness: remaining %d\n", remaining>>9);
2374 }
2375 #endif
2376 }
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388 static int make_raw_rw_request(void)
2389 {
2390 int aligned_sector_t;
2391 int max_sector, max_size, tracksize, ssize;
2392
2393 set_fdc(DRIVE(CURRENT->rq_dev));
2394
2395 raw_cmd.flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
2396 FD_RAW_NEED_SEEK;
2397 raw_cmd.cmd_count = NR_RW;
2398 if (CURRENT->cmd == READ){
2399 raw_cmd.flags |= FD_RAW_READ;
2400 COMMAND = FM_MODE(floppy,FD_READ);
2401 } else if (CURRENT->cmd == WRITE){
2402 raw_cmd.flags |= FD_RAW_WRITE;
2403 COMMAND = FM_MODE(floppy,FD_WRITE);
2404 } else {
2405 DPRINT("make_raw_rw_request: unknown command\n");
2406 return 0;
2407 }
2408
2409 max_sector = floppy->sect * floppy->head;
2410
2411 TRACK = CURRENT->sector / max_sector;
2412 sector_t = CURRENT->sector % max_sector;
2413 if ( floppy->track && TRACK >= floppy->track )
2414 return 0;
2415 HEAD = sector_t / floppy->sect;
2416
2417 if (((floppy->stretch & FD_SWAPSIDES) || TESTF( FD_NEED_TWADDLE)) &&
2418 sector_t < floppy->sect )
2419 max_sector = floppy->sect;
2420
2421
2422 if ( (floppy->rate & FD_2M ) && (!TRACK) && (!HEAD)){
2423 max_sector = 2 * floppy->sect / 3;
2424 if (sector_t >= max_sector){
2425 current_count_sectors = (floppy->sect - sector_t);
2426 if ( current_count_sectors > CURRENT->nr_sectors )
2427 current_count_sectors = CURRENT->nr_sectors;
2428 return 1;
2429 }
2430 SIZECODE = 2;
2431 } else
2432 SIZECODE = FD_SIZECODE(floppy);
2433 raw_cmd.rate = floppy->rate & 3;
2434 if ((floppy->rate & FD_2M) &&
2435 (TRACK || HEAD ) &&
2436 raw_cmd.rate == 2)
2437 raw_cmd.rate = 1;
2438
2439 if ( SIZECODE )
2440 SIZECODE2 = 0xff;
2441 else
2442 SIZECODE2 = 0x80;
2443 raw_cmd.track = TRACK << STRETCH(floppy);
2444 DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,HEAD);
2445 GAP = floppy->gap;
2446 CODE2SIZE;
2447 SECT_PER_TRACK = floppy->sect << 2 >> SIZECODE;
2448 SECTOR = ((sector_t % floppy->sect) << 2 >> SIZECODE) + 1;
2449 tracksize = floppy->sect - floppy->sect % ssize;
2450 if ( tracksize < floppy->sect ){
2451 SECT_PER_TRACK ++;
2452 if ( tracksize <= sector_t % floppy->sect)
2453 SECTOR--;
2454 while ( tracksize <= sector_t % floppy->sect){
2455 while( tracksize + ssize > floppy->sect ){
2456 SIZECODE--;
2457 ssize >>= 1;
2458 }
2459 SECTOR++; SECT_PER_TRACK ++;
2460 tracksize += ssize;
2461 }
2462 max_sector = HEAD * floppy->sect + tracksize;
2463 } else if ( !TRACK && !HEAD && !( floppy->rate & FD_2M ) && probing)
2464 max_sector = floppy->sect;
2465
2466 aligned_sector_t = sector_t - ( sector_t % floppy->sect ) % ssize;
2467 max_size = CURRENT->nr_sectors;
2468 if ((raw_cmd.track == buffer_track) && (current_drive == buffer_drive) &&
2469 (sector_t >= buffer_min) && (sector_t < buffer_max)) {
2470
2471 if (CT(COMMAND) == FD_READ) {
2472 copy_buffer(1, max_sector, buffer_max);
2473 return 1;
2474 }
2475 } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
2476 if (CT(COMMAND) == FD_WRITE){
2477 if(sector_t + CURRENT->nr_sectors > ssize &&
2478 sector_t + CURRENT->nr_sectors < ssize + ssize)
2479 max_size = ssize + ssize;
2480 else
2481 max_size = ssize;
2482 }
2483 raw_cmd.flags &= ~FD_RAW_WRITE;
2484 raw_cmd.flags |= FD_RAW_READ;
2485 COMMAND = FM_MODE(floppy,FD_READ);
2486 } else if ((unsigned long)CURRENT->buffer < MAX_DMA_ADDRESS ) {
2487 int direct, indirect;
2488
2489 indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
2490 sector_t;
2491
2492 max_size = buffer_chain_size();
2493 if ( max_size > ( MAX_DMA_ADDRESS - ((unsigned long) CURRENT->buffer))>>9)
2494 max_size=(MAX_DMA_ADDRESS - ((unsigned long) CURRENT->buffer))>>9;
2495
2496 if (CROSS_64KB(CURRENT->buffer, max_size << 9))
2497 max_size = ( K_64 - ((long) CURRENT->buffer) % K_64)>>9;
2498 direct = transfer_size(ssize,max_sector,max_size) - sector_t;
2499
2500
2501
2502
2503
2504
2505
2506 if (!direct ||
2507 (indirect * 2 > direct * 3 &&
2508 *errors < DP->max_errors.read_track &&
2509
2510 ((!probing || (DP->read_track&(1<<DRS->probed_format)))))){
2511 max_size = CURRENT->nr_sectors;
2512 } else {
2513 current_addr = CURRENT->buffer;
2514 raw_cmd.length = current_count_sectors << 9;
2515 if (raw_cmd.length == 0){
2516 DPRINT("zero dma transfer attempted from make_raw_request\n");
2517 DPRINT3("indirect=%d direct=%d sector_t=%d",
2518 indirect, direct, sector_t);
2519 return 0;
2520 }
2521 return 2;
2522 }
2523 }
2524
2525 if ( CT(COMMAND) == FD_READ )
2526 max_size = max_sector;
2527
2528
2529 if (buffer_track != raw_cmd.track ||
2530 buffer_drive !=current_drive ||
2531 sector_t > buffer_max ||
2532 sector_t < buffer_min ||
2533 ((CT(COMMAND) == FD_READ ||
2534 (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize ))&&
2535 max_sector > 2 * max_buffer_sectors + buffer_min &&
2536 max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
2537 ){
2538 buffer_track = -1;
2539 buffer_drive = current_drive;
2540 buffer_max = buffer_min = aligned_sector_t;
2541 }
2542 current_addr = floppy_track_buffer +((aligned_sector_t-buffer_min )<<9);
2543
2544 if ( CT(COMMAND) == FD_WRITE ){
2545
2546
2547
2548
2549 #ifdef CONFIG_FLOPPY_SANITY
2550 if (sector_t != aligned_sector_t && buffer_track == -1 )
2551 DPRINT("internal error offset !=0 on write\n");
2552 #endif
2553 buffer_track = raw_cmd.track;
2554 buffer_drive = current_drive;
2555 copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min);
2556 } else
2557 transfer_size(ssize, max_sector,
2558 2*max_buffer_sectors+buffer_min-aligned_sector_t);
2559
2560
2561 raw_cmd.length = sector_t+current_count_sectors-aligned_sector_t;
2562 raw_cmd.length = ((raw_cmd.length -1)|(ssize-1))+1;
2563 raw_cmd.length <<= 9;
2564 #ifdef CONFIG_FLOPPY_SANITY
2565 if ((raw_cmd.length < current_count_sectors << 9) ||
2566 (current_addr != CURRENT->buffer &&
2567 CT(COMMAND) == FD_WRITE &&
2568 (aligned_sector_t + (raw_cmd.length >> 9) > buffer_max ||
2569 aligned_sector_t < buffer_min )) ||
2570 raw_cmd.length % ( 128 << SIZECODE ) ||
2571 raw_cmd.length <= 0 || current_count_sectors <= 0){
2572 DPRINT2("fractionary current count b=%lx s=%lx\n",
2573 raw_cmd.length, current_count_sectors);
2574 if ( current_addr != CURRENT->buffer )
2575 printk("addr=%d, length=%ld\n",
2576 (int) ((current_addr - floppy_track_buffer ) >> 9),
2577 current_count_sectors);
2578 printk("st=%d ast=%d mse=%d msi=%d\n",
2579 sector_t, aligned_sector_t, max_sector, max_size);
2580 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2581 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2582 COMMAND, SECTOR, HEAD, TRACK);
2583 printk("buffer drive=%d\n", buffer_drive);
2584 printk("buffer track=%d\n", buffer_track);
2585 printk("buffer_min=%d\n", buffer_min );
2586 printk("buffer_max=%d\n", buffer_max );
2587 return 0;
2588 }
2589
2590 if (current_addr != CURRENT->buffer ){
2591 if (current_addr < floppy_track_buffer ||
2592 current_count_sectors < 0 ||
2593 raw_cmd.length < 0 ||
2594 current_addr + raw_cmd.length >
2595 floppy_track_buffer + (max_buffer_sectors << 10)){
2596 DPRINT("buffer overrun in schedule dma\n");
2597 printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2598 sector_t, buffer_min,
2599 raw_cmd.length >> 9 );
2600 printk("current_count_sectors=%ld\n",
2601 current_count_sectors);
2602 if ( CT(COMMAND) == FD_READ )
2603 printk("read\n");
2604 if ( CT(COMMAND) == FD_READ )
2605 printk("write\n");
2606 return 0;
2607 }
2608 } else if (raw_cmd.length > CURRENT->nr_sectors << 9 ||
2609 current_count_sectors > CURRENT->nr_sectors){
2610 DPRINT("buffer overrun in direct transfer\n");
2611 return 0;
2612 } else if ( raw_cmd.length < current_count_sectors << 9 ){
2613 DPRINT("more sectors than bytes\n");
2614 printk("bytes=%ld\n", raw_cmd.length >> 9 );
2615 printk("sectors=%ld\n", current_count_sectors);
2616 }
2617 if (raw_cmd.length == 0){
2618 DPRINT("zero dma transfer attempted from make_raw_request\n");
2619 return 0;
2620 }
2621 #endif
2622 return 2;
2623 }
2624
2625 static void redo_fd_request(void)
2626 {
2627 #define REPEAT {request_done(0); continue; }
2628 kdev_t device;
2629 int tmp;
2630 #if 0
2631 kdev_t error = 0;
2632 #endif
2633
2634 lastredo = jiffies;
2635 if (current_drive < N_DRIVE)
2636 floppy_off(current_drive);
2637
2638 if (CURRENT && CURRENT->rq_status == RQ_INACTIVE){
2639 DPRINT("current not active!\n");
2640 return;
2641 }
2642
2643 while(1){
2644 if (!CURRENT) {
2645 CLEAR_INTR;
2646 unlock_fdc();
2647 return;
2648 }
2649 if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
2650 panic(DEVICE_NAME ": request list destroyed");
2651 if (CURRENT->bh && !CURRENT->bh->b_lock)
2652 panic(DEVICE_NAME ": block not locked");
2653 #if 0
2654 if (!CURRENT->bh->b_count &&
2655 (CURRENT->errors || error == CURRENT->rq_dev)){
2656 error = CURRENT->rq_dev;
2657 DPRINT("skipping read ahead buffer\n");
2658 REPEAT;
2659 }
2660 error = 0;
2661 #endif
2662 device = CURRENT->rq_dev;
2663 set_fdc( DRIVE(device));
2664 reschedule_timeout(CURRENTD, "redo fd request", 0);
2665
2666 set_floppy(device);
2667 if(start_motor(redo_fd_request)) return;
2668 if(test_bit(current_drive, &fake_change) ||
2669 TESTF(FD_DISK_CHANGED)){
2670 DPRINT("disk absent or changed during operation\n");
2671 REPEAT;
2672 }
2673 if (!floppy) {
2674 if (!probing){
2675 DRS->probed_format = 0;
2676 if ( next_valid_format() ){
2677 DPRINT("no autodetectable formats\n");
2678 floppy = NULL;
2679 REPEAT;
2680 }
2681 }
2682 probing = 1;
2683 floppy = floppy_type+DP->autodetect[DRS->probed_format];
2684 } else
2685 probing = 0;
2686 errors = & (CURRENT->errors);
2687 tmp = make_raw_rw_request();
2688 if ( tmp < 2 ){
2689 request_done(tmp);
2690 continue;
2691 }
2692
2693 if (TESTF(FD_NEED_TWADDLE))
2694 twaddle();
2695 floppy_tq.routine = (void *)(void *) floppy_start;
2696 queue_task(&floppy_tq, &tq_timer);
2697 #ifdef DEBUGT
2698 debugt("queue fd request");
2699 #endif
2700 return;
2701 }
2702 #undef REPEAT
2703 }
2704
2705 static struct cont_t rw_cont={
2706 rw_interrupt,
2707 redo_fd_request,
2708 bad_flp_intr,
2709 request_done };
2710
2711 struct tq_struct request_tq =
2712 { 0, 0, (void *) (void *) redo_fd_request, 0 };
2713
2714 static void process_fd_request(void)
2715 {
2716 cont = &rw_cont;
2717 queue_task(&request_tq, &tq_timer);
2718 }
2719
2720 static void do_fd_request(void)
2721 {
2722 if (fdc_busy){
2723
2724
2725 is_alive("do fd request, old request running");
2726 return;
2727 }
2728
2729 floppy_grab_irq_and_dma();
2730 fdc_busy=1;
2731 reschedule_timeout(MAXTIMEOUT, "do fd request",0);
2732 process_fd_request();
2733 is_alive("do fd request");
2734 }
2735
2736 static struct cont_t poll_cont={
2737 success_and_wakeup,
2738 floppy_ready,
2739 generic_failure,
2740 generic_done };
2741
2742 static int poll_drive(int interruptible, int flag)
2743 {
2744 int ret;
2745
2746 raw_cmd.flags= flag;
2747 raw_cmd.track=0;
2748 raw_cmd.cmd_count=0;
2749 cont = &poll_cont;
2750 #ifdef DCL_DEBUG
2751 if (DP->flags & FD_DEBUG){
2752 DPRINT("setting NEWCHANGE in poll_drive\n");
2753 }
2754 #endif
2755 SETF(FD_DISK_NEWCHANGE);
2756 WAIT(floppy_ready);
2757 return ret;
2758 }
2759
2760
2761
2762
2763
2764
2765 static void reset_intr(void)
2766 {
2767 printk("weird, reset interrupt called\n");
2768 }
2769
2770 static struct cont_t reset_cont={
2771 reset_intr,
2772 success_and_wakeup,
2773 generic_failure,
2774 generic_done };
2775
2776 static int user_reset_fdc(int drive, int arg, int interruptible)
2777 {
2778 int ret;
2779
2780 ret=0;
2781 if(arg == FD_RESET_IF_NEEDED && !FDCS->reset)
2782 return 0;
2783 LOCK_FDC(drive,interruptible);
2784 if(arg == FD_RESET_ALWAYS)
2785 FDCS->reset=1;
2786 if ( FDCS->reset ){
2787 cont = &reset_cont;
2788 reschedule_timeout(CURRENTD, "user reset fdc", 0);
2789 WAIT(reset_fdc);
2790 }
2791 process_fd_request();
2792 return ret;
2793 }
2794
2795
2796
2797
2798
2799 static int fd_copyout(void *param, volatile void *address, int size)
2800 {
2801 int i;
2802
2803 i = verify_area(VERIFY_WRITE,param,size);
2804 if (i)
2805 return i;
2806 memcpy_tofs(param,(void *) address, size);
2807 return 0;
2808 }
2809
2810 #define COPYOUT(x) (fd_copyout( (void *)param, &(x), sizeof(x)))
2811 #define COPYIN(x) (memcpy_fromfs( &(x), (void *) param, sizeof(x)),0)
2812
2813 static const char *drive_name(int type, int drive )
2814 {
2815 struct floppy_struct *floppy;
2816
2817 if ( type )
2818 floppy = floppy_type + type;
2819 else {
2820 if ( UDP->native_format )
2821 floppy = floppy_type + UDP->native_format;
2822 else
2823 return "(null)";
2824 }
2825 if ( floppy->name )
2826 return floppy->name;
2827 else
2828 return "(null)";
2829 }
2830
2831
2832 static struct cont_t raw_cmd_cont={
2833 success_and_wakeup,
2834 failure_and_wakeup,
2835 generic_failure,
2836 generic_done };
2837
2838 static int raw_cmd_ioctl(void *param)
2839 {
2840 int i, drive, count, ret;
2841
2842 if ( FDCS->rawcmd <= 1 )
2843 FDCS->rawcmd = 1;
2844 for ( drive= 0; drive < N_DRIVE; drive++){
2845 if ( FDC(drive) != fdc)
2846 continue;
2847 if ( drive == current_drive ){
2848 if ( UDRS->fd_ref > 1 ){
2849 FDCS->rawcmd = 2;
2850 break;
2851 }
2852 } else if ( UDRS->fd_ref ){
2853 FDCS->rawcmd = 2;
2854 break;
2855 }
2856 }
2857
2858 if(FDCS->reset)
2859 return -EIO;
2860
2861 COPYIN(raw_cmd);
2862 raw_cmd.rate &= 0x03;
2863 count = raw_cmd.length;
2864 if (raw_cmd.flags & (FD_RAW_WRITE | FD_RAW_READ)){
2865 if(count > max_buffer_sectors * 1024 )
2866 return -ENOMEM;
2867 if(count == 0){
2868 printk("attempt to do a 0 byte dma transfer\n");
2869 return -EINVAL;
2870 }
2871 buffer_track = -1;
2872 }
2873 if ( raw_cmd.flags & FD_RAW_WRITE ){
2874 i = verify_area(VERIFY_READ, raw_cmd.data, count );
2875 if (i)
2876 return i;
2877 memcpy_fromfs(floppy_track_buffer, raw_cmd.data, count);
2878 }
2879
2880 current_addr = floppy_track_buffer;
2881 cont = &raw_cmd_cont;
2882 IWAIT(floppy_start);
2883 #ifdef DCL_DEBUG
2884 if (DP->flags & FD_DEBUG){
2885 DPRINT("calling disk change from raw_cmd ioctl\n");
2886 }
2887 #endif
2888 if( disk_change(current_drive) )
2889 raw_cmd.flags |= FD_RAW_DISK_CHANGE;
2890 else
2891 raw_cmd.flags &= ~FD_RAW_DISK_CHANGE;
2892 if(raw_cmd.flags & FD_RAW_NO_MOTOR_AFTER)
2893 motor_off_callback(current_drive);
2894
2895 if ( !ret && !FDCS->reset ){
2896 raw_cmd.reply_count = inr;
2897 for( i=0; i< raw_cmd.reply_count; i++)
2898 raw_cmd.reply[i] = reply_buffer[i];
2899 if ( raw_cmd.flags & ( FD_RAW_READ | FD_RAW_WRITE ))
2900 raw_cmd.length = get_dma_residue(FLOPPY_DMA);
2901 } else
2902 ret = -EIO;
2903 DRS->track = NO_TRACK;
2904 if ( ret )
2905 return ret;
2906
2907 if ( raw_cmd.flags & FD_RAW_READ ){
2908 i=fd_copyout( raw_cmd.data, floppy_track_buffer, count);
2909 if (i)
2910 return i;
2911 }
2912
2913 return COPYOUT(raw_cmd);
2914 }
2915
2916 static int invalidate_drive(kdev_t rdev)
2917 {
2918
2919 set_bit( DRIVE(rdev), &fake_change);
2920 process_fd_request();
2921 check_disk_change(rdev);
2922 return 0;
2923 }
2924
2925 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
2926 unsigned long param)
2927 {
2928 #define IOCTL_MODE_BIT 8
2929 #define OPEN_WRITE_BIT 16
2930 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
2931
2932 struct floppy_struct newparams;
2933 struct format_descr tmp_format_req;
2934 int i,drive,type,cnt;
2935 kdev_t device;
2936 struct floppy_struct *this_floppy;
2937 const char *name;
2938
2939 device = inode->i_rdev;
2940 switch (cmd) {
2941 RO_IOCTLS(device,param);
2942 }
2943 type = TYPE(device);
2944 drive = DRIVE(device);
2945 switch (cmd) {
2946 case FDGETDRVTYP:
2947 i=verify_area(VERIFY_WRITE,(void *) param,16);
2948 if (i)
2949 return i;
2950 name = drive_name(type,drive);
2951 for ( cnt=0; cnt<16; cnt++){
2952 put_user(name[cnt], ((char*)param)+cnt);
2953 if ( ! *name )
2954 break;
2955 }
2956 return 0;
2957 case FDGETMAXERRS:
2958 return COPYOUT(UDP->max_errors);
2959 case FDGETPRM:
2960 if (type)
2961 this_floppy = &floppy_type[type];
2962 else if ((this_floppy = current_type[drive]) ==
2963 NULL)
2964 return -ENODEV;
2965 return COPYOUT(this_floppy[0]);
2966 case FDPOLLDRVSTAT:
2967 LOCK_FDC(drive,1);
2968 CALL(poll_drive(1, FD_RAW_NEED_DISK));
2969 process_fd_request();
2970
2971 case FDGETDRVSTAT:
2972 return COPYOUT(*UDRS);
2973 case FDGETFDCSTAT:
2974 return COPYOUT(*UFDCS);
2975 case FDGETDRVPRM:
2976 return COPYOUT(*UDP);
2977 case FDWERRORGET:
2978 return COPYOUT(*UDRWE);
2979 }
2980 if (!IOCTL_ALLOWED)
2981 return -EPERM;
2982 switch (cmd) {
2983 case FDWERRORCLR:
2984 UDRWE->write_errors = 0;
2985 UDRWE->first_error_sector = 0;
2986 UDRWE->first_error_generation = 0;
2987 UDRWE->last_error_sector = 0;
2988 UDRWE->last_error_generation = 0;
2989 UDRWE->badness = 0;
2990 return 0;
2991 case FDRAWCMD:
2992 if (type)
2993 return -EINVAL;
2994 LOCK_FDC(drive,1);
2995 set_floppy(device);
2996 CALL(i = raw_cmd_ioctl((void *) param));
2997 process_fd_request();
2998 return i;
2999 case FDFMTTRK:
3000 if (UDRS->fd_ref != 1)
3001 return -EBUSY;
3002 COPYIN(tmp_format_req);
3003 return do_format(device, &tmp_format_req);
3004 case FDSETMAXERRS:
3005 return COPYIN(UDP->max_errors);
3006 case FDFMTBEG:
3007 return 0;
3008 case FDCLRPRM:
3009 LOCK_FDC(drive,1);
3010 current_type[drive] = NULL;
3011 floppy_sizes[drive] = MAX_DISK_SIZE;
3012 UDRS->keep_data = 0;
3013 return invalidate_drive(device);
3014 case FDFMTEND:
3015 case FDFLUSH:
3016 LOCK_FDC(drive,1);
3017 return invalidate_drive(device);
3018 case FDSETPRM:
3019 case FDDEFPRM:
3020 COPYIN(newparams);
3021
3022 if(newparams.sect <= 0 ||
3023 newparams.head <= 0 ||
3024 newparams.track <= 0 ||
3025 newparams.track > UDP->tracks>> STRETCH(&newparams) ||
3026
3027 (newparams.stretch & ~(FD_STRETCH | FD_SWAPSIDES)) != 0)
3028 return -EINVAL;
3029 if ( type){
3030 if ( !suser() )
3031 return -EPERM;
3032 LOCK_FDC(drive,1);
3033 for ( cnt = 0; cnt < N_DRIVE; cnt++){
3034 if (XTYPE(drive_state[cnt].fd_device) == type &&
3035 drive_state[cnt].fd_ref)
3036 set_bit(drive, &fake_change);
3037 }
3038 floppy_type[type] = newparams;
3039 floppy_type[type].name="user format";
3040 for (cnt = type << 2 ;
3041 cnt < (type << 2 ) + 4 ;
3042 cnt++)
3043 floppy_sizes[cnt]=
3044 floppy_sizes[cnt+0x80]=
3045 floppy_type[type].size>>1;
3046 process_fd_request();
3047 for ( cnt = 0; cnt < N_DRIVE; cnt++){
3048 if (XTYPE(drive_state[cnt].fd_device) == type &&
3049 drive_state[cnt].fd_ref)
3050 check_disk_change(to_kdev_t(drive_state[cnt].fd_device));
3051 }
3052 return 0;
3053 }
3054
3055 LOCK_FDC(drive,1);
3056 if ( cmd != FDDEFPRM )
3057
3058
3059 CALL(poll_drive(1,0));
3060 user_params[drive] = newparams;
3061 if (buffer_drive == drive &&
3062 buffer_max > user_params[drive].sect)
3063 buffer_max=user_params[drive].sect;
3064 current_type[drive] = &user_params[drive];
3065 floppy_sizes[drive] = user_params[drive].size >> 1;
3066 if (cmd == FDDEFPRM)
3067 DRS->keep_data = -1;
3068 else
3069 DRS->keep_data = 1;
3070
3071
3072
3073
3074
3075 if (DRS->maxblock >
3076 user_params[drive].sect ||
3077 DRS->maxtrack )
3078 invalidate_drive(device);
3079 else
3080 process_fd_request();
3081 return 0;
3082 case FDRESET:
3083 return user_reset_fdc( drive, (int)param, 1);
3084 case FDMSGON:
3085 UDP->flags |= FTD_MSG;
3086 return 0;
3087 case FDMSGOFF:
3088 UDP->flags &= ~FTD_MSG;
3089 return 0;
3090 case FDSETEMSGTRESH:
3091 UDP->max_errors.reporting =
3092 (unsigned short) (param & 0x0f);
3093 return 0;
3094 case FDTWADDLE:
3095 LOCK_FDC(drive,1);
3096 twaddle();
3097 process_fd_request();
3098 }
3099 if ( ! suser() )
3100 return -EPERM;
3101 switch(cmd){
3102 case FDSETDRVPRM:
3103 return COPYIN(*UDP);
3104 default:
3105 return -EINVAL;
3106 }
3107 return 0;
3108 #undef IOCTL_ALLOWED
3109 }
3110
3111 static void config_types(void)
3112 {
3113 int first=1;
3114 int drive;
3115
3116
3117 drive=0;
3118 if (!UDP->cmos )
3119 UDP->cmos= FLOPPY0_TYPE;
3120 drive=1;
3121 if (!UDP->cmos && FLOPPY1_TYPE)
3122 UDP->cmos = FLOPPY1_TYPE;
3123
3124
3125
3126
3127 for (drive=0; drive < N_DRIVE; drive++){
3128 if (UDP->cmos >= 0 && UDP->cmos <= NUMBER(default_drive_params))
3129 memcpy((char *) UDP,
3130 (char *) (&default_drive_params[(int)UDP->cmos].params),
3131 sizeof(struct floppy_drive_params));
3132 if (UDP->cmos){
3133 if (first)
3134 printk("Floppy drive(s): ");
3135 else
3136 printk(", ");
3137 first=0;
3138 if (UDP->cmos > 0 ){
3139 ALLOWED_DRIVE_MASK |= 1 << drive;
3140 printk("fd%d is %s", drive,
3141 default_drive_params[(int)UDP->cmos].name);
3142 } else
3143 printk("fd%d is unknown type %d",drive,
3144 UDP->cmos);
3145 }
3146 }
3147 if(!first)
3148 printk("\n");
3149 }
3150
3151 static int floppy_read(struct inode * inode, struct file * filp,
3152 char * buf, int count)
3153 {
3154 int drive = DRIVE(inode->i_rdev);
3155
3156 check_disk_change(inode->i_rdev);
3157 if (UTESTF(FD_DISK_CHANGED))
3158 return -ENXIO;
3159 return block_read(inode, filp, buf, count);
3160 }
3161
3162 static int floppy_write(struct inode * inode, struct file * filp,
3163 const char * buf, int count)
3164 {
3165 int block;
3166 int ret;
3167 int drive = DRIVE(inode->i_rdev);
3168
3169 if(!UDRS->maxblock)
3170 UDRS->maxblock=1;
3171 check_disk_change(inode->i_rdev);
3172 if (UTESTF(FD_DISK_CHANGED))
3173 return -ENXIO;
3174 if(!UTESTF(FD_DISK_WRITABLE))
3175 return -EROFS;
3176 block = (filp->f_pos + count) >> 9;
3177 if(block > UDRS->maxblock)
3178 UDRS->maxblock = block;
3179 ret= block_write(inode, filp, buf, count);
3180 return ret;
3181 }
3182
3183 static void floppy_release(struct inode * inode, struct file * filp)
3184 {
3185 int drive;
3186
3187 drive = DRIVE(inode->i_rdev);
3188
3189 if( !filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
3190
3191
3192 block_fsync(inode,filp);
3193
3194 if (UDRS->fd_ref < 0)
3195 UDRS->fd_ref=0;
3196 else if (!UDRS->fd_ref--) {
3197 DPRINT("floppy_release with fd_ref == 0");
3198 UDRS->fd_ref = 0;
3199 }
3200 floppy_release_irq_and_dma();
3201 }
3202
3203
3204
3205
3206
3207
3208 #define RETERR(x) \
3209 do{floppy_release(inode,filp); \
3210 return -(x);}while(0)
3211
3212 static int floppy_open(struct inode * inode, struct file * filp)
3213 {
3214 int drive;
3215 kdev_t old_dev;
3216 int try;
3217 char *tmp;
3218
3219 if (!filp) {
3220 DPRINT("Weird, open called with filp=0\n");
3221 return -EIO;
3222 }
3223
3224 drive = DRIVE(inode->i_rdev);
3225
3226 if (drive >= N_DRIVE ||
3227 !( ALLOWED_DRIVE_MASK & ( 1 << drive)) ||
3228 fdc_state[FDC(drive)].version == FDC_NONE)
3229 return -ENXIO;
3230
3231 if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
3232 return -ENXIO;
3233 old_dev = to_kdev_t(UDRS->fd_device);
3234 if (UDRS->fd_ref && old_dev != inode->i_rdev)
3235 return -EBUSY;
3236
3237 if(!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
3238 USETF(FD_DISK_CHANGED);
3239 USETF(FD_VERIFY);
3240 }
3241
3242 if(UDRS->fd_ref == -1 ||
3243 (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3244 return -EBUSY;
3245
3246 if (floppy_grab_irq_and_dma())
3247 return -EBUSY;
3248
3249 if (filp->f_flags & O_EXCL)
3250 UDRS->fd_ref = -1;
3251 else
3252 UDRS->fd_ref++;
3253
3254 if (!floppy_track_buffer){
3255
3256
3257 if ((UDP->cmos == 6) || (UDP->cmos == 5))
3258 try = 64;
3259 else
3260 try = 32;
3261
3262 tmp=(char *)dma_mem_alloc(1024 * try);
3263 if (!tmp) {
3264 try >>= 1;
3265 if (try < 16)
3266 try=16;
3267 tmp= (char *)dma_mem_alloc(1024*try);
3268 }
3269 if (!tmp) {
3270 DPRINT("Unable to allocate DMA memory\n");
3271 RETERR(ENXIO);
3272 }
3273 if (floppy_track_buffer){
3274 free_pages((unsigned long)tmp,__get_order(try*1024));
3275 }else {
3276 floppy_track_buffer = tmp;
3277 max_buffer_sectors = try;
3278 }
3279 }
3280
3281 UDRS->fd_device = kdev_t_to_nr(inode->i_rdev);
3282
3283 if (old_dev && old_dev != inode->i_rdev) {
3284 if (buffer_drive == drive)
3285 buffer_track = -1;
3286 invalidate_buffers(old_dev);
3287 }
3288
3289
3290 if ((filp->f_mode & 2) || (permission(inode,2) == 0))
3291 filp->f_mode |= IOCTL_MODE_BIT;
3292 if (filp->f_mode & 2)
3293 filp->f_mode |= OPEN_WRITE_BIT;
3294
3295 if (UFDCS->rawcmd == 1)
3296 UFDCS->rawcmd = 2;
3297
3298 if (filp->f_flags & O_NDELAY)
3299 return 0;
3300 if (filp->f_mode & 3) {
3301 UDRS->last_checked = 0;
3302 check_disk_change(inode->i_rdev);
3303 if (UTESTF(FD_DISK_CHANGED))
3304 RETERR(ENXIO);
3305 }
3306 if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
3307 RETERR(EROFS);
3308 return 0;
3309 #undef RETERR
3310 }
3311
3312
3313
3314
3315 static int check_floppy_change(kdev_t dev)
3316 {
3317 int drive = DRIVE( dev );
3318
3319 if (MAJOR(dev) != MAJOR_NR) {
3320 DPRINT("floppy_changed: not a floppy\n");
3321 return 0;
3322 }
3323
3324 if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
3325 return 1;
3326
3327 if(UDRS->last_checked + UDP->checkfreq < jiffies){
3328 lock_fdc(drive,0);
3329 poll_drive(0,0);
3330 process_fd_request();
3331 }
3332
3333 if(UTESTF(FD_DISK_CHANGED) ||
3334 UTESTF(FD_VERIFY) ||
3335 test_bit(drive, &fake_change) ||
3336 (!TYPE(dev) && !current_type[drive]))
3337 return 1;
3338 return 0;
3339 }
3340
3341
3342
3343
3344
3345 static int floppy_revalidate(kdev_t dev)
3346 {
3347 #define NO_GEOM (!current_type[drive] && !TYPE(dev))
3348 struct buffer_head * bh;
3349 int drive=DRIVE(dev);
3350 int cf;
3351
3352 if(UTESTF(FD_DISK_CHANGED) ||
3353 UTESTF(FD_VERIFY) ||
3354 test_bit(drive, &fake_change) ||
3355 NO_GEOM){
3356 lock_fdc(drive,0);
3357 cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY);
3358 if(! (cf || test_bit(drive, &fake_change) || NO_GEOM)){
3359 process_fd_request();
3360 return 0;
3361 }
3362 UDRS->maxblock = 0;
3363 UDRS->maxtrack = 0;
3364 if ( buffer_drive == drive)
3365 buffer_track = -1;
3366 clear_bit(drive, &fake_change);
3367 UCLEARF(FD_DISK_CHANGED);
3368 if(cf)
3369 UDRS->generation++;
3370 if(NO_GEOM){
3371
3372 int size = floppy_blocksizes[MINOR(dev)];
3373 if (!size)
3374 size = 1024;
3375 if (!(bh = getblk(dev,0,size))){
3376 process_fd_request();
3377 return 1;
3378 }
3379 if ( bh && ! bh->b_uptodate)
3380 ll_rw_block(READ, 1, &bh);
3381 process_fd_request();
3382 wait_on_buffer(bh);
3383 brelse(bh);
3384 return 0;
3385 }
3386 if(cf)
3387 poll_drive(0, FD_RAW_NEED_DISK);
3388 process_fd_request();
3389 }
3390 return 0;
3391 }
3392
3393 static struct file_operations floppy_fops = {
3394 NULL,
3395 floppy_read,
3396 floppy_write,
3397 NULL,
3398 NULL,
3399 fd_ioctl,
3400 NULL,
3401 floppy_open,
3402 floppy_release,
3403 block_fsync,
3404 NULL,
3405 check_floppy_change,
3406 floppy_revalidate,
3407 };
3408
3409
3410
3411
3412
3413
3414
3415
3416 static char get_fdc_version(void)
3417 {
3418 int r;
3419
3420 output_byte(FD_DUMPREGS);
3421 if ( FDCS->reset )
3422 return FDC_NONE;
3423 if ( (r = result()) <= 0x00)
3424 return FDC_NONE;
3425 if ((r==1) && (reply_buffer[0] == 0x80)){
3426 printk("FDC %d is a 8272A\n",fdc);
3427 return FDC_8272A;
3428 }
3429 if (r != 10) {
3430 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
3431 return FDC_UNKNOWN;
3432 }
3433 output_byte(FD_VERSION);
3434 r = result();
3435 if ((r == 1) && (reply_buffer[0] == 0x80)){
3436 printk("FDC %d is a 82072\n",fdc);
3437 return FDC_82072;
3438 }
3439 if ((r != 1) || (reply_buffer[0] != 0x90)) {
3440 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
3441 return FDC_UNKNOWN;
3442 }
3443 output_byte(FD_UNLOCK);
3444 r = result();
3445 if ((r == 1) && (reply_buffer[0] == 0x80)){
3446 printk("FDC %d is a pre-1991 82077\n", fdc);
3447 return FDC_82077_ORIG;
3448 }
3449 if ((r != 1) || (reply_buffer[0] != 0x00)) {
3450 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
3451 return FDC_UNKNOWN;
3452 }
3453 printk("FDC %d is a post-1991 82077\n",fdc);
3454 return FDC_82077;
3455 }
3456
3457
3458
3459
3460
3461
3462 void floppy_invert_dcl(int *ints,int param)
3463 {
3464 int i;
3465
3466 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3467 if (param)
3468 default_drive_params[i].params.flags |= 0x80;
3469 else
3470 default_drive_params[i].params.flags &= ~0x80;
3471 }
3472 DPRINT("Configuring drives for inverted dcl\n");
3473 }
3474
3475 static void daring(int *ints,int param)
3476 {
3477 int i;
3478
3479 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3480 if (param){
3481 default_drive_params[i].params.select_delay = 0;
3482 default_drive_params[i].params.flags |= FD_SILENT_DCL_CLEAR;
3483 } else {
3484 default_drive_params[i].params.select_delay = 2*HZ/100;
3485 default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR;
3486 }
3487 }
3488 DPRINT1("Assuming %s floppy hardware\n", param ? "standard" : "broken");
3489 }
3490
3491 static void allow_drives(int *ints, int param)
3492 {
3493 ALLOWED_DRIVE_MASK=param;
3494 DPRINT1("setting allowed_drive_mask to 0x%x\n", param);
3495 }
3496
3497 static void fdc2_adr(int *ints, int param)
3498 {
3499 FDC2 = param;
3500 if(param)
3501 DPRINT1("enabling second fdc at address 0x%3x\n", FDC2);
3502 else
3503 DPRINT("disabling second fdc\n");
3504 }
3505
3506 static void unex(int *ints,int param)
3507 {
3508 print_unex = param;
3509 DPRINT1("%sprinting messages for unexpected interrupts\n",
3510 param ? "" : "not ");
3511 }
3512
3513 static void set_cmos(int *ints, int dummy)
3514 {
3515 int current_drive=0;
3516
3517 if ( ints[0] != 2 ){
3518 DPRINT("wrong number of parameter for cmos\n");
3519 return;
3520 }
3521 current_drive = ints[1];
3522 if (current_drive < 0 || current_drive >= 8 ){
3523 DPRINT("bad drive for set_cmos\n");
3524 return;
3525 }
3526 if(ints[2] <= 0 || ints[2] >= NUMBER(default_drive_params)){
3527 DPRINT1("bad cmos code %d\n", ints[2]);
3528 return;
3529 }
3530 DP->cmos = ints[2];
3531 DPRINT1("setting cmos code to %d\n", ints[2]);
3532 }
3533
3534 static struct param_table {
3535 const char *name;
3536 void (*fn)(int *ints, int param);
3537 int def_param;
3538 } config_params[]={
3539 { "allowed_drive_mask", allow_drives, 0xff },
3540 { "all_drives", allow_drives, 0xff },
3541 { "asus_pci", allow_drives, 0x33 },
3542
3543 { "daring", daring, 1},
3544
3545 { "two_fdc", fdc2_adr, 0x370 },
3546 { "one_fdc", fdc2_adr, 0 },
3547
3548 { "thinkpad", floppy_invert_dcl, 1 },
3549
3550 { "cmos", set_cmos, 0 },
3551
3552 { "unexpected_interrupts", unex, 1 },
3553 { "no_unexpected_interrupts", unex, 0 },
3554 { "L40SX", unex, 0 } };
3555
3556 #define FLOPPY_SETUP
3557 void floppy_setup(char *str, int *ints)
3558 {
3559 int i;
3560 int param;
3561 if(!str)
3562 return;
3563 for(i=0; i< ARRAY_SIZE(config_params); i++){
3564 if (strcmp(str,config_params[i].name) == 0 ){
3565 if (ints[0] )
3566 param = ints[1];
3567 else
3568 param = config_params[i].def_param;
3569 config_params[i].fn(ints,param);
3570 return;
3571 }
3572 }
3573 DPRINT1("unknown floppy option [%s]\n", str);
3574 DPRINT("allowed options are:");
3575 for(i=0; i< ARRAY_SIZE(config_params); i++)
3576 printk(" %s",config_params[i].name);
3577 printk("\n");
3578 DPRINT("Read linux/drivers/block/README.fd\n");
3579 }
3580
3581 int floppy_init(void)
3582 {
3583 int i,drive;
3584 int have_no_fdc=0;
3585
3586 sti();
3587
3588 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
3589 printk("Unable to get major %d for floppy\n",MAJOR_NR);
3590 return -EBUSY;
3591 }
3592
3593 for(i=0; i<256; i++)
3594 if ( ITYPE(i))
3595 floppy_sizes[i] = floppy_type[ITYPE(i)].size >> 1;
3596 else
3597 floppy_sizes[i] = MAX_DISK_SIZE;
3598
3599 blk_size[MAJOR_NR] = floppy_sizes;
3600 blksize_size[MAJOR_NR] = floppy_blocksizes;
3601 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3602 reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
3603 config_types();
3604
3605 fdc_state[0].address = FDC1;
3606 fdc_state[0].dor = 0;
3607 #if N_FDC > 1
3608 fdc_state[1].address = FDC2;
3609 fdc_state[1].dor = 0;
3610 #endif
3611
3612 for (i = 0 ; i < N_FDC ; i++) {
3613 fdc = i;
3614 FDCS->dtr = -1;
3615 FDCS->dor = 0x4;
3616 FDCS->reset = 0;
3617 FDCS->version = FDC_NONE;
3618 }
3619
3620 if(floppy_grab_irq_and_dma()){
3621 unregister_blkdev(MAJOR_NR,"fd");
3622 return -EBUSY;
3623 }
3624
3625
3626 for (drive = 0; drive < N_DRIVE ; drive++) {
3627 UDRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE | FD_DISK_CHANGED;
3628 UDRS->generation = 0;
3629 UDRS->keep_data = 0;
3630 UDRS->fd_ref = 0;
3631 UDRS->fd_device = 0;
3632 floppy_track_buffer = NULL;
3633 max_buffer_sectors = 0;
3634 UDRWE->write_errors = 0;
3635 UDRWE->first_error_sector = 0;
3636 UDRWE->first_error_generation = 0;
3637 UDRWE->last_error_sector = 0;
3638 UDRWE->last_error_generation = 0;
3639 UDRWE->badness = 0;
3640 }
3641
3642 for (i = 0 ; i < N_FDC ; i++) {
3643 fdc = i;
3644 if (FDCS->address == -1 )
3645 continue;
3646 FDCS->rawcmd = 2;
3647 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED,0)){
3648 FDCS->address = -1;
3649 continue;
3650 }
3651
3652 FDCS->version = get_fdc_version();
3653 if (FDCS->version == FDC_NONE){
3654 FDCS->address = -1;
3655 continue;
3656 }
3657
3658 request_region(FDCS->address, 6, "floppy");
3659 request_region(FDCS->address+7, 1, "floppy DIR");
3660
3661
3662
3663 have_no_fdc = 0;
3664
3665
3666
3667
3668 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
3669 user_reset_fdc(-1,FD_RESET_ALWAYS,0);
3670 }
3671 fdc=0;
3672 del_timer(&fd_timeout);
3673 current_drive = 0;
3674 floppy_release_irq_and_dma();
3675 initialising=0;
3676 if(have_no_fdc)
3677 unregister_blkdev(MAJOR_NR,"fd");
3678 return have_no_fdc;
3679 }
3680
3681 static int floppy_grab_irq_and_dma(void)
3682 {
3683 int i;
3684 cli();
3685 if (usage_count++){
3686 sti();
3687 return 0;
3688 }
3689 sti();
3690 #ifdef FD_MODULE
3691 MOD_INC_USE_COUNT;
3692 #endif
3693 for(i=0; i< N_FDC; i++){
3694 if(FDCS->address != -1){
3695 fdc = i;
3696 reset_fdc_info(1);
3697 outb_p(FDCS->dor, FD_DOR);
3698 }
3699 }
3700 set_dor(0, ~0, 8);
3701
3702 if (request_irq(FLOPPY_IRQ, floppy_interrupt,
3703 SA_INTERRUPT|SA_SAMPLE_RANDOM, "floppy")) {
3704 DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
3705 FLOPPY_IRQ);
3706 return -1;
3707 }
3708 if (request_dma(FLOPPY_DMA,"floppy")) {
3709 DPRINT1("Unable to grab DMA%d for the floppy driver\n",
3710 FLOPPY_DMA);
3711 free_irq(FLOPPY_IRQ);
3712 return -1;
3713 }
3714 for(fdc = 0; fdc < N_FDC ; fdc++)
3715 if(FDCS->address != -1)
3716 outb_p(FDCS->dor, FD_DOR);
3717 fdc = 0;
3718 enable_irq(FLOPPY_IRQ);
3719 return 0;
3720 }
3721
3722 static void floppy_release_irq_and_dma(void)
3723 {
3724 #ifdef CONFIG_FLOPPY_SANITY
3725 int drive;
3726 #endif
3727 long tmpsize;
3728 void *tmpaddr;
3729
3730 cli();
3731 if (--usage_count){
3732 sti();
3733 return;
3734 }
3735 sti();
3736 #ifdef FD_MODULE
3737 MOD_DEC_USE_COUNT;
3738 #endif
3739 disable_dma(FLOPPY_DMA);
3740 free_dma(FLOPPY_DMA);
3741 disable_irq(FLOPPY_IRQ);
3742 free_irq(FLOPPY_IRQ);
3743
3744 set_dor(0, ~0, 8);
3745 #if N_FDC > 1
3746 set_dor(1, ~8, 0);
3747 #endif
3748 floppy_enable_hlt();
3749
3750 if (floppy_track_buffer && max_buffer_sectors) {
3751 tmpsize = max_buffer_sectors*1024;
3752 tmpaddr = (void *)floppy_track_buffer;
3753 floppy_track_buffer = 0;
3754 max_buffer_sectors = 0;
3755 free_pages((unsigned long)tmpaddr, __get_order(tmpsize));
3756 }
3757
3758 #ifdef CONFIG_FLOPPY_SANITY
3759 for(drive=0; drive < N_FDC * 4; drive++)
3760 if( motor_off_timer[drive].next )
3761 printk("motor off timer %d still active\n", drive);
3762
3763 if(fd_timeout.next)
3764 printk("floppy timer still active:%s\n", timeout_message);
3765 if (fd_timer.next)
3766 printk("auxiliary floppy timer still active\n");
3767 if(floppy_tq.sync)
3768 printk("task queue still active\n");
3769 #endif
3770 }
3771
3772
3773 #ifdef MODULE
3774
3775 extern char *get_options(char *str, int *ints);
3776
3777 static void mod_setup(char *pattern, void (*setup)(char *, int *))
3778 {
3779 int i;
3780 char c;
3781 int j;
3782 int match;
3783 char buffer[100];
3784 int ints[11];
3785 int length = strlen(pattern)+1;
3786
3787 match=0;
3788 j=1;
3789
3790 for(i=current->mm->env_start;
3791 i< current->mm->env_end;
3792 i ++){
3793 c= get_fs_byte(i);
3794 if(match){
3795 if(j==99)
3796 c='\0';
3797 buffer[j] = c;
3798 if(!c || c == ' ' || c == '\t'){
3799 if(j){
3800 buffer[j] = '\0';
3801 setup(get_options(buffer,ints),ints);
3802 }
3803 j=0;
3804 } else
3805 j++;
3806 if(!c)
3807 break;
3808 continue;
3809 }
3810 if( (!j && !c) ||
3811 ( j && c == pattern[j-1]))
3812 j++;
3813 else
3814 j=0;
3815 if(j==length){
3816 match=1;
3817 j=0;
3818 }
3819 }
3820 }
3821
3822
3823 #ifdef __cplusplus
3824 extern "C" {
3825 #endif
3826 int init_module(void)
3827 {
3828 int ret;
3829 printk("inserting floppy driver for %s\n", kernel_version);
3830
3831 mod_setup("floppy=", floppy_setup);
3832
3833 ret = floppy_init();
3834 return 0;
3835 }
3836
3837 void cleanup_module(void)
3838 {
3839 int fdc;
3840
3841 for(fdc=0; fdc<2; fdc++)
3842 if (FDCS->address != -1){
3843 release_region(FDCS->address, 6);
3844 release_region(FDCS->address+7, 1);
3845 }
3846
3847 unregister_blkdev(MAJOR_NR, "fd");
3848
3849 blk_dev[MAJOR_NR].request_fn = 0;
3850 }
3851
3852 #ifdef __cplusplus
3853 }
3854 #endif
3855
3856 #endif