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