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 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(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 char *timeout_message;
561
562 #ifdef CONFIG_FLOPPY_SANITY
563 static void is_alive(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, 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 = 2000;
603 drive=0;
604 } else
605 fd_timeout.expires = 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 = 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 = 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 - jiffies;
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;
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;
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);
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 int ret;
2735
2736 raw_cmd.flags= flag;
2737 raw_cmd.track=0;
2738 raw_cmd.cmd_count=0;
2739 cont = &poll_cont;
2740 #ifdef DCL_DEBUG
2741 if (DP->flags & FD_DEBUG){
2742 DPRINT("setting NEWCHANGE in poll_drive\n");
2743 }
2744 #endif
2745 SETF(FD_DISK_NEWCHANGE);
2746 WAIT(floppy_ready);
2747 return ret;
2748 }
2749
2750
2751
2752
2753
2754
2755 static void reset_intr(void)
2756 {
2757 printk("weird, reset interrupt called\n");
2758 }
2759
2760 static struct cont_t reset_cont={
2761 reset_intr,
2762 success_and_wakeup,
2763 generic_failure,
2764 generic_done };
2765
2766 static int user_reset_fdc(int drive, int arg, int interruptible)
2767 {
2768 int ret;
2769
2770 ret=0;
2771 if(arg == FD_RESET_IF_NEEDED && !FDCS->reset)
2772 return 0;
2773 LOCK_FDC(drive,interruptible);
2774 if(arg == FD_RESET_ALWAYS)
2775 FDCS->reset=1;
2776 if ( FDCS->reset ){
2777 cont = &reset_cont;
2778 reschedule_timeout(CURRENTD, "user reset fdc", 0);
2779 WAIT(reset_fdc);
2780 }
2781 process_fd_request();
2782 return ret;
2783 }
2784
2785
2786
2787
2788
2789 static int fd_copyout(void *param, volatile void *address, int size)
2790 {
2791 int i;
2792
2793 i = verify_area(VERIFY_WRITE,param,size);
2794 if (i)
2795 return i;
2796 memcpy_tofs(param,(void *) address, size);
2797 return 0;
2798 }
2799
2800 #define COPYOUT(x) (fd_copyout( (void *)param, &(x), sizeof(x)))
2801 #define COPYIN(x) (memcpy_fromfs( &(x), (void *) param, sizeof(x)),0)
2802
2803 static char *drive_name(int type, int drive )
2804 {
2805 struct floppy_struct *floppy;
2806
2807 if ( type )
2808 floppy = floppy_type + type;
2809 else {
2810 if ( UDP->native_format )
2811 floppy = floppy_type + UDP->native_format;
2812 else
2813 return "(null)";
2814 }
2815 if ( floppy->name )
2816 return floppy->name;
2817 else
2818 return "(null)";
2819 }
2820
2821
2822 static struct cont_t raw_cmd_cont={
2823 success_and_wakeup,
2824 failure_and_wakeup,
2825 generic_failure,
2826 generic_done };
2827
2828 static int raw_cmd_ioctl(void *param)
2829 {
2830 int i, drive, count, ret;
2831
2832 if ( FDCS->rawcmd <= 1 )
2833 FDCS->rawcmd = 1;
2834 for ( drive= 0; drive < N_DRIVE; drive++){
2835 if ( FDC(drive) != fdc)
2836 continue;
2837 if ( drive == current_drive ){
2838 if ( UDRS->fd_ref > 1 ){
2839 FDCS->rawcmd = 2;
2840 break;
2841 }
2842 } else if ( UDRS->fd_ref ){
2843 FDCS->rawcmd = 2;
2844 break;
2845 }
2846 }
2847
2848 if(FDCS->reset)
2849 return -EIO;
2850
2851 COPYIN(raw_cmd);
2852 raw_cmd.rate &= 0x03;
2853 count = raw_cmd.length;
2854 if (raw_cmd.flags & (FD_RAW_WRITE | FD_RAW_READ)){
2855 if(count > max_buffer_sectors * 1024 )
2856 return -ENOMEM;
2857 if(count == 0){
2858 printk("attempt to do a 0 byte dma transfer\n");
2859 return -EINVAL;
2860 }
2861 buffer_track = -1;
2862 }
2863 if ( raw_cmd.flags & FD_RAW_WRITE ){
2864 i = verify_area(VERIFY_READ, raw_cmd.data, count );
2865 if (i)
2866 return i;
2867 memcpy_fromfs(floppy_track_buffer, raw_cmd.data, count);
2868 }
2869
2870 current_addr = floppy_track_buffer;
2871 cont = &raw_cmd_cont;
2872 IWAIT(floppy_start);
2873 #ifdef DCL_DEBUG
2874 if (DP->flags & FD_DEBUG){
2875 DPRINT("calling disk change from raw_cmd ioctl\n");
2876 }
2877 #endif
2878 if( disk_change(current_drive) )
2879 raw_cmd.flags |= FD_RAW_DISK_CHANGE;
2880 else
2881 raw_cmd.flags &= ~FD_RAW_DISK_CHANGE;
2882 if(raw_cmd.flags & FD_RAW_NO_MOTOR_AFTER)
2883 motor_off_callback(current_drive);
2884
2885 if ( !ret && !FDCS->reset ){
2886 raw_cmd.reply_count = inr;
2887 for( i=0; i< raw_cmd.reply_count; i++)
2888 raw_cmd.reply[i] = reply_buffer[i];
2889 if ( raw_cmd.flags & ( FD_RAW_READ | FD_RAW_WRITE ))
2890 raw_cmd.length = get_dma_residue(FLOPPY_DMA);
2891 } else
2892 ret = -EIO;
2893 DRS->track = NO_TRACK;
2894 if ( ret )
2895 return ret;
2896
2897 if ( raw_cmd.flags & FD_RAW_READ ){
2898 i=fd_copyout( raw_cmd.data, floppy_track_buffer, count);
2899 if (i)
2900 return i;
2901 }
2902
2903 return COPYOUT(raw_cmd);
2904 }
2905
2906 static int invalidate_drive(int rdev)
2907 {
2908
2909 set_bit( DRIVE(rdev), &fake_change);
2910 process_fd_request();
2911 check_disk_change(rdev);
2912 return 0;
2913 }
2914
2915 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
2916 unsigned long param)
2917 {
2918 #define IOCTL_MODE_BIT 8
2919 #define OPEN_WRITE_BIT 16
2920 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
2921
2922 struct floppy_struct newparams;
2923 struct format_descr tmp_format_req;
2924 int i,device,drive,type,cnt;
2925 struct floppy_struct *this_floppy;
2926 char *name;
2927
2928 device = inode->i_rdev;
2929 switch (cmd) {
2930 RO_IOCTLS(device,param);
2931 }
2932 type = TYPE(device);
2933 drive = DRIVE(device);
2934 switch (cmd) {
2935 case FDGETDRVTYP:
2936 i=verify_area(VERIFY_WRITE,(void *) param,16);
2937 if (i)
2938 return i;
2939 name = drive_name(type,drive);
2940 for ( cnt=0; cnt<16; cnt++){
2941 put_user(name[cnt], ((char*)param)+cnt);
2942 if ( ! *name )
2943 break;
2944 }
2945 return 0;
2946 case FDGETMAXERRS:
2947 return COPYOUT(UDP->max_errors);
2948 case FDGETPRM:
2949 if (type)
2950 this_floppy = &floppy_type[type];
2951 else if ((this_floppy = current_type[drive]) ==
2952 NULL)
2953 return -ENODEV;
2954 return COPYOUT(this_floppy[0]);
2955 case FDPOLLDRVSTAT:
2956 LOCK_FDC(drive,1);
2957 CALL(poll_drive(1, FD_RAW_NEED_DISK));
2958 process_fd_request();
2959
2960 case FDGETDRVSTAT:
2961 return COPYOUT(*UDRS);
2962 case FDGETFDCSTAT:
2963 return COPYOUT(*UFDCS);
2964 case FDGETDRVPRM:
2965 return COPYOUT(*UDP);
2966 case FDWERRORGET:
2967 return COPYOUT(*UDRWE);
2968 }
2969 if (!IOCTL_ALLOWED)
2970 return -EPERM;
2971 switch (cmd) {
2972 case FDWERRORCLR:
2973 UDRWE->write_errors = 0;
2974 UDRWE->first_error_sector = 0;
2975 UDRWE->first_error_generation = 0;
2976 UDRWE->last_error_sector = 0;
2977 UDRWE->last_error_generation = 0;
2978 UDRWE->badness = 0;
2979 return 0;
2980 case FDRAWCMD:
2981 if (type)
2982 return -EINVAL;
2983 LOCK_FDC(drive,1);
2984 set_floppy(device);
2985 CALL(i = raw_cmd_ioctl((void *) param));
2986 process_fd_request();
2987 return i;
2988 case FDFMTTRK:
2989 if (UDRS->fd_ref != 1)
2990 return -EBUSY;
2991 COPYIN(tmp_format_req);
2992 return do_format(device, &tmp_format_req);
2993 case FDSETMAXERRS:
2994 return COPYIN(UDP->max_errors);
2995 case FDFMTBEG:
2996 return 0;
2997 case FDCLRPRM:
2998 LOCK_FDC(drive,1);
2999 current_type[drive] = NULL;
3000 floppy_sizes[drive] = MAX_DISK_SIZE;
3001 UDRS->keep_data = 0;
3002 return invalidate_drive(device);
3003 case FDFMTEND:
3004 case FDFLUSH:
3005 LOCK_FDC(drive,1);
3006 return invalidate_drive(device);
3007 case FDSETPRM:
3008 case FDDEFPRM:
3009 COPYIN(newparams);
3010
3011 if(newparams.sect <= 0 ||
3012 newparams.head <= 0 ||
3013 newparams.track <= 0 ||
3014 newparams.track > UDP->tracks>> STRETCH(&newparams) ||
3015
3016 (newparams.stretch & ~(FD_STRETCH | FD_SWAPSIDES)) != 0)
3017 return -EINVAL;
3018 if ( type){
3019 if ( !suser() )
3020 return -EPERM;
3021 LOCK_FDC(drive,1);
3022 for ( cnt = 0; cnt < N_DRIVE; cnt++){
3023 if (TYPE(drive_state[cnt].fd_device) == type &&
3024 drive_state[cnt].fd_ref)
3025 set_bit(drive, &fake_change);
3026 }
3027 floppy_type[type] = newparams;
3028 floppy_type[type].name="user format";
3029 for (cnt = type << 2 ;
3030 cnt < (type << 2 ) + 4 ;
3031 cnt++)
3032 floppy_sizes[cnt]=
3033 floppy_sizes[cnt+0x80]=
3034 floppy_type[type].size>>1;
3035 process_fd_request();
3036 for ( cnt = 0; cnt < N_DRIVE; cnt++){
3037 if (TYPE(drive_state[cnt].fd_device) == type &&
3038 drive_state[cnt].fd_ref)
3039 check_disk_change(drive_state[cnt].
3040 fd_device);
3041 }
3042 return 0;
3043 }
3044
3045 LOCK_FDC(drive,1);
3046 if ( cmd != FDDEFPRM )
3047
3048
3049 CALL(poll_drive(1,0));
3050 user_params[drive] = newparams;
3051 if (buffer_drive == drive &&
3052 buffer_max > user_params[drive].sect)
3053 buffer_max=user_params[drive].sect;
3054 current_type[drive] = &user_params[drive];
3055 floppy_sizes[drive] = user_params[drive].size >> 1;
3056 if (cmd == FDDEFPRM)
3057 DRS->keep_data = -1;
3058 else
3059 DRS->keep_data = 1;
3060
3061
3062
3063
3064
3065 if (DRS->maxblock >
3066 user_params[drive].sect ||
3067 DRS->maxtrack )
3068 invalidate_drive(device);
3069 else
3070 process_fd_request();
3071 return 0;
3072 case FDRESET:
3073 return user_reset_fdc( drive, (int)param, 1);
3074 case FDMSGON:
3075 UDP->flags |= FTD_MSG;
3076 return 0;
3077 case FDMSGOFF:
3078 UDP->flags &= ~FTD_MSG;
3079 return 0;
3080 case FDSETEMSGTRESH:
3081 UDP->max_errors.reporting =
3082 (unsigned short) (param & 0x0f);
3083 return 0;
3084 case FDTWADDLE:
3085 LOCK_FDC(drive,1);
3086 twaddle();
3087 process_fd_request();
3088 }
3089 if ( ! suser() )
3090 return -EPERM;
3091 switch(cmd){
3092 case FDSETDRVPRM:
3093 return COPYIN(*UDP);
3094 default:
3095 return -EINVAL;
3096 }
3097 return 0;
3098 #undef IOCTL_ALLOWED
3099 }
3100
3101 static void config_types(void)
3102 {
3103 int first=1;
3104 int drive;
3105
3106
3107 drive=0;
3108 if (!UDP->cmos )
3109 UDP->cmos= FLOPPY0_TYPE;
3110 drive=1;
3111 if (!UDP->cmos && FLOPPY1_TYPE)
3112 UDP->cmos = FLOPPY1_TYPE;
3113
3114
3115
3116
3117 for (drive=0; drive < N_DRIVE; drive++){
3118 if (UDP->cmos >= 0 && UDP->cmos <= NUMBER(default_drive_params))
3119 memcpy((char *) UDP,
3120 (char *) (&default_drive_params[(int)UDP->cmos].params),
3121 sizeof(struct floppy_drive_params));
3122 if (UDP->cmos){
3123 if (first)
3124 printk("Floppy drive(s): ");
3125 else
3126 printk(", ");
3127 first=0;
3128 if (UDP->cmos > 0 ){
3129 ALLOWED_DRIVE_MASK |= 1 << drive;
3130 printk("fd%d is %s", drive,
3131 default_drive_params[(int)UDP->cmos].name);
3132 } else
3133 printk("fd%d is unknown type %d",drive,
3134 UDP->cmos);
3135 }
3136 }
3137 if(!first)
3138 printk("\n");
3139 }
3140
3141 static int floppy_read(struct inode * inode, struct file * filp,
3142 char * buf, int count)
3143 {
3144 int drive = DRIVE(inode->i_rdev);
3145
3146 check_disk_change(inode->i_rdev);
3147 if (UTESTF(FD_DISK_CHANGED))
3148 return -ENXIO;
3149 return block_read(inode, filp, buf, count);
3150 }
3151
3152 static int floppy_write(struct inode * inode, struct file * filp,
3153 char * buf, int count)
3154 {
3155 int block;
3156 int ret;
3157 int drive = DRIVE(inode->i_rdev);
3158
3159 if(!UDRS->maxblock)
3160 UDRS->maxblock=1;
3161 check_disk_change(inode->i_rdev);
3162 if (UTESTF(FD_DISK_CHANGED))
3163 return -ENXIO;
3164 if(!UTESTF(FD_DISK_WRITABLE))
3165 return -EROFS;
3166 block = (filp->f_pos + count) >> 9;
3167 if(block > UDRS->maxblock)
3168 UDRS->maxblock = block;
3169 ret= block_write(inode, filp, buf, count);
3170 return ret;
3171 }
3172
3173 static void floppy_release(struct inode * inode, struct file * filp)
3174 {
3175 int drive;
3176
3177 drive = DRIVE(inode->i_rdev);
3178
3179 if( !filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
3180
3181
3182 block_fsync(inode,filp);
3183
3184 if (UDRS->fd_ref < 0)
3185 UDRS->fd_ref=0;
3186 else if (!UDRS->fd_ref--) {
3187 DPRINT("floppy_release with fd_ref == 0");
3188 UDRS->fd_ref = 0;
3189 }
3190 floppy_release_irq_and_dma();
3191 }
3192
3193
3194
3195
3196
3197
3198 #define RETERR(x) \
3199 do{floppy_release(inode,filp); \
3200 return -(x);}while(0)
3201
3202 static int floppy_open(struct inode * inode, struct file * filp)
3203 {
3204 int drive;
3205 int old_dev;
3206 int try;
3207 char *tmp;
3208
3209 if (!filp) {
3210 DPRINT("Weird, open called with filp=0\n");
3211 return -EIO;
3212 }
3213
3214 drive = DRIVE(inode->i_rdev);
3215
3216 if (drive >= N_DRIVE ||
3217 !( ALLOWED_DRIVE_MASK & ( 1 << drive)) ||
3218 fdc_state[FDC(drive)].version == FDC_NONE)
3219 return -ENXIO;
3220
3221 if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
3222 return -ENXIO;
3223 old_dev = UDRS->fd_device;
3224 if (UDRS->fd_ref && old_dev != inode->i_rdev)
3225 return -EBUSY;
3226
3227 if(!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
3228 USETF(FD_DISK_CHANGED);
3229 USETF(FD_VERIFY);
3230 }
3231
3232 if(UDRS->fd_ref == -1 ||
3233 (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3234 return -EBUSY;
3235
3236 if (floppy_grab_irq_and_dma())
3237 return -EBUSY;
3238
3239 if (filp->f_flags & O_EXCL)
3240 UDRS->fd_ref = -1;
3241 else
3242 UDRS->fd_ref++;
3243
3244 if (!floppy_track_buffer){
3245
3246
3247 if ((UDP->cmos == 6) || (UDP->cmos == 5))
3248 try = 64;
3249 else
3250 try = 32;
3251
3252 tmp=(char *)dma_mem_alloc(1024 * try);
3253 if (!tmp) {
3254 try >>= 1;
3255 if (try < 16)
3256 try=16;
3257 tmp= (char *)dma_mem_alloc(1024*try);
3258 }
3259 if (!tmp) {
3260 DPRINT("Unable to allocate DMA memory\n");
3261 RETERR(ENXIO);
3262 }
3263 if (floppy_track_buffer){
3264 free_pages((unsigned long)tmp,__get_order(try*1024));
3265 }else {
3266 floppy_track_buffer = tmp;
3267 max_buffer_sectors = try;
3268 }
3269 }
3270
3271 UDRS->fd_device = inode->i_rdev;
3272
3273 if (old_dev && old_dev != inode->i_rdev) {
3274 if (buffer_drive == drive)
3275 buffer_track = -1;
3276 invalidate_buffers(old_dev);
3277 }
3278
3279
3280 if ((filp->f_mode & 2) || (permission(inode,2) == 0))
3281 filp->f_mode |= IOCTL_MODE_BIT;
3282 if (filp->f_mode & 2)
3283 filp->f_mode |= OPEN_WRITE_BIT;
3284
3285 if (UFDCS->rawcmd == 1)
3286 UFDCS->rawcmd = 2;
3287
3288 if (filp->f_flags & O_NDELAY)
3289 return 0;
3290 if (filp->f_mode & 3) {
3291 UDRS->last_checked = 0;
3292 check_disk_change(inode->i_rdev);
3293 if (UTESTF(FD_DISK_CHANGED))
3294 RETERR(ENXIO);
3295 }
3296 if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
3297 RETERR(EROFS);
3298 return 0;
3299 #undef RETERR
3300 }
3301
3302
3303
3304
3305 static int check_floppy_change(dev_t dev)
3306 {
3307 int drive = DRIVE( dev );
3308
3309 if (MAJOR(dev) != MAJOR_NR) {
3310 DPRINT("floppy_changed: not a floppy\n");
3311 return 0;
3312 }
3313
3314 if (UTESTF(FD_DISK_CHANGED))
3315 return 1;
3316
3317 if(UDRS->last_checked + UDP->checkfreq < jiffies){
3318 lock_fdc(drive,0);
3319 poll_drive(0,0);
3320 process_fd_request();
3321 }
3322
3323 if(UTESTF(FD_DISK_CHANGED) ||
3324 test_bit(drive, &fake_change) ||
3325 (!TYPE(dev) && !current_type[drive]))
3326 return 1;
3327 return 0;
3328 }
3329
3330
3331
3332
3333
3334 static int floppy_revalidate(dev_t dev)
3335 {
3336 #define NO_GEOM (!current_type[drive] && !TYPE(dev))
3337 struct buffer_head * bh;
3338 int drive=DRIVE(dev);
3339 int cf;
3340
3341 if(UTESTF(FD_DISK_CHANGED) || test_bit(drive, &fake_change) || NO_GEOM){
3342 lock_fdc(drive,0);
3343 cf = UTESTF(FD_DISK_CHANGED);
3344 if(! (cf || test_bit(drive, &fake_change) || NO_GEOM)){
3345 process_fd_request();
3346 return 0;
3347 }
3348 UDRS->maxblock = 0;
3349 UDRS->maxtrack = 0;
3350 if ( buffer_drive == drive)
3351 buffer_track = -1;
3352 clear_bit(drive, &fake_change);
3353 UCLEARF(FD_DISK_CHANGED);
3354 if(cf)
3355 UDRS->generation++;
3356 if(NO_GEOM){
3357
3358 int size = floppy_blocksizes[MINOR(dev)];
3359 if (!size)
3360 size = 1024;
3361 if (!(bh = getblk(dev,0,size))){
3362 process_fd_request();
3363 return 1;
3364 }
3365 if ( bh && ! bh->b_uptodate)
3366 ll_rw_block(READ, 1, &bh);
3367 process_fd_request();
3368 wait_on_buffer(bh);
3369 brelse(bh);
3370 return 0;
3371 }
3372 if(cf)
3373 poll_drive(0, FD_RAW_NEED_DISK);
3374 process_fd_request();
3375 }
3376 return 0;
3377 }
3378
3379 static struct file_operations floppy_fops = {
3380 NULL,
3381 floppy_read,
3382 floppy_write,
3383 NULL,
3384 NULL,
3385 fd_ioctl,
3386 NULL,
3387 floppy_open,
3388 floppy_release,
3389 block_fsync,
3390 NULL,
3391 check_floppy_change,
3392 floppy_revalidate,
3393 };
3394
3395
3396
3397
3398
3399
3400
3401
3402 static char get_fdc_version(void)
3403 {
3404 int r;
3405
3406 output_byte(FD_DUMPREGS);
3407 if ( FDCS->reset )
3408 return FDC_NONE;
3409 if ( (r = result()) <= 0x00)
3410 return FDC_NONE;
3411 if ((r==1) && (reply_buffer[0] == 0x80)){
3412 printk("FDC %d is a 8272A\n",fdc);
3413 return FDC_8272A;
3414 }
3415 if (r != 10) {
3416 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
3417 return FDC_UNKNOWN;
3418 }
3419 output_byte(FD_VERSION);
3420 r = result();
3421 if ((r == 1) && (reply_buffer[0] == 0x80)){
3422 printk("FDC %d is a 82072\n",fdc);
3423 return FDC_82072;
3424 }
3425 if ((r != 1) || (reply_buffer[0] != 0x90)) {
3426 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
3427 return FDC_UNKNOWN;
3428 }
3429 output_byte(FD_UNLOCK);
3430 r = result();
3431 if ((r == 1) && (reply_buffer[0] == 0x80)){
3432 printk("FDC %d is a pre-1991 82077\n", fdc);
3433 return FDC_82077_ORIG;
3434 }
3435 if ((r != 1) || (reply_buffer[0] != 0x00)) {
3436 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
3437 return FDC_UNKNOWN;
3438 }
3439 printk("FDC %d is a post-1991 82077\n",fdc);
3440 return FDC_82077;
3441 }
3442
3443
3444
3445
3446
3447
3448 void floppy_invert_dcl(int *ints,int param)
3449 {
3450 int i;
3451
3452 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3453 if (param)
3454 default_drive_params[i].params.flags |= 0x80;
3455 else
3456 default_drive_params[i].params.flags &= ~0x80;
3457 }
3458 DPRINT("Configuring drives for inverted dcl\n");
3459 }
3460
3461 static void daring(int *ints,int param)
3462 {
3463 int i;
3464
3465 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3466 if (param){
3467 default_drive_params[i].params.select_delay = 0;
3468 default_drive_params[i].params.flags |= FD_SILENT_DCL_CLEAR;
3469 } else {
3470 default_drive_params[i].params.select_delay = 2*HZ/100;
3471 default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR;
3472 }
3473 }
3474 DPRINT1("Assuming %s floppy hardware\n", param ? "standard" : "broken");
3475 }
3476
3477 static void allow_drives(int *ints, int param)
3478 {
3479 ALLOWED_DRIVE_MASK=param;
3480 DPRINT1("setting allowed_drive_mask to 0x%x\n", param);
3481 }
3482
3483 static void fdc2_adr(int *ints, int param)
3484 {
3485 FDC2 = param;
3486 if(param)
3487 DPRINT1("enabling second fdc at address 0x%3x\n", FDC2);
3488 else
3489 DPRINT("disabling second fdc\n");
3490 }
3491
3492 static void unex(int *ints,int param)
3493 {
3494 print_unex = param;
3495 DPRINT1("%sprinting messages for unexpected interrupts\n",
3496 param ? "" : "not ");
3497 }
3498
3499 static void set_cmos(int *ints, int dummy)
3500 {
3501 int current_drive=0;
3502
3503 if ( ints[0] != 2 ){
3504 DPRINT("wrong number of parameter for cmos\n");
3505 return;
3506 }
3507 current_drive = ints[1];
3508 if (current_drive < 0 || current_drive >= 8 ){
3509 DPRINT("bad drive for set_cmos\n");
3510 return;
3511 }
3512 if(ints[2] <= 0 || ints[2] >= NUMBER(default_drive_params)){
3513 DPRINT1("bad cmos code %d\n", ints[2]);
3514 return;
3515 }
3516 DP->cmos = ints[2];
3517 DPRINT1("setting cmos code to %d\n", ints[2]);
3518 }
3519
3520 static struct param_table {
3521 char *name;
3522 void (*fn)(int *ints, int param);
3523 int def_param;
3524 } config_params[]={
3525 { "allowed_drive_mask", allow_drives, 0xff },
3526 { "all_drives", allow_drives, 0xff },
3527 { "asus_pci", allow_drives, 0x33 },
3528
3529 { "daring", daring, 1},
3530
3531 { "two_fdc", fdc2_adr, 0x370 },
3532 { "one_fdc", fdc2_adr, 0 },
3533
3534 { "thinkpad", floppy_invert_dcl, 1 },
3535
3536 { "cmos", set_cmos, 0 },
3537
3538 { "unexpected_interrupts", unex, 1 },
3539 { "no_unexpected_interrupts", unex, 0 },
3540 { "L40SX", unex, 0 } };
3541
3542 #define FLOPPY_SETUP
3543 void floppy_setup(char *str, int *ints)
3544 {
3545 int i;
3546 int param;
3547 if(!str)
3548 return;
3549 for(i=0; i< ARRAY_SIZE(config_params); i++){
3550 if (strcmp(str,config_params[i].name) == 0 ){
3551 if (ints[0] )
3552 param = ints[1];
3553 else
3554 param = config_params[i].def_param;
3555 config_params[i].fn(ints,param);
3556 return;
3557 }
3558 }
3559 DPRINT1("unknown floppy option %s\n", str);
3560 DPRINT("allowed options are:");
3561 for(i=0; i< ARRAY_SIZE(config_params); i++)
3562 printk(" %s",config_params[i].name);
3563 printk("\n");
3564 DPRINT("Read linux/drivers/block/README.fd\n");
3565 }
3566
3567 int floppy_init(void)
3568 {
3569 int i,drive;
3570 int have_no_fdc=0;
3571
3572 sti();
3573
3574 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
3575 printk("Unable to get major %d for floppy\n",MAJOR_NR);
3576 return -EBUSY;
3577 }
3578
3579 for(i=0; i<256; i++)
3580 if ( TYPE(i))
3581 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
3582 else
3583 floppy_sizes[i] = MAX_DISK_SIZE;
3584
3585 blk_size[MAJOR_NR] = floppy_sizes;
3586 blksize_size[MAJOR_NR] = floppy_blocksizes;
3587 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3588 reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
3589 config_types();
3590
3591 fdc_state[0].address = FDC1;
3592 fdc_state[0].dor = 0;
3593 #if N_FDC > 1
3594 fdc_state[1].address = FDC2;
3595 fdc_state[1].dor = 0;
3596 #endif
3597
3598 for (i = 0 ; i < N_FDC ; i++) {
3599 fdc = i;
3600 FDCS->dtr = -1;
3601 FDCS->dor = 0x4;
3602 FDCS->reset = 0;
3603 FDCS->version = FDC_NONE;
3604 }
3605
3606 if(floppy_grab_irq_and_dma()){
3607 unregister_blkdev(MAJOR_NR,"fd");
3608 return -EBUSY;
3609 }
3610
3611
3612 for (drive = 0; drive < N_DRIVE ; drive++) {
3613 UDRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE | FD_DISK_CHANGED;
3614 UDRS->generation = 0;
3615 UDRS->keep_data = 0;
3616 UDRS->fd_ref = 0;
3617 UDRS->fd_device = 0;
3618 floppy_track_buffer = NULL;
3619 max_buffer_sectors = 0;
3620 UDRWE->write_errors = 0;
3621 UDRWE->first_error_sector = 0;
3622 UDRWE->first_error_generation = 0;
3623 UDRWE->last_error_sector = 0;
3624 UDRWE->last_error_generation = 0;
3625 UDRWE->badness = 0;
3626 }
3627
3628 for (i = 0 ; i < N_FDC ; i++) {
3629 fdc = i;
3630 if (FDCS->address == -1 )
3631 continue;
3632 FDCS->rawcmd = 2;
3633 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED,0)){
3634 FDCS->address = -1;
3635 continue;
3636 }
3637
3638 FDCS->version = get_fdc_version();
3639 if (FDCS->version == FDC_NONE){
3640 FDCS->address = -1;
3641 continue;
3642 }
3643
3644 request_region(FDCS->address, 6, "floppy");
3645 request_region(FDCS->address+7, 1, "floppy DIR");
3646
3647
3648
3649 have_no_fdc = 0;
3650
3651
3652
3653
3654 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
3655 user_reset_fdc(-1,FD_RESET_ALWAYS,0);
3656 }
3657 fdc=0;
3658 del_timer(&fd_timeout);
3659 current_drive = 0;
3660 floppy_release_irq_and_dma();
3661 initialising=0;
3662 if(have_no_fdc)
3663 unregister_blkdev(MAJOR_NR,"fd");
3664 return have_no_fdc;
3665 }
3666
3667 static int floppy_grab_irq_and_dma(void)
3668 {
3669 int i;
3670 cli();
3671 if (usage_count++){
3672 sti();
3673 return 0;
3674 }
3675 sti();
3676 #ifdef FD_MODULE
3677 MOD_INC_USE_COUNT;
3678 #endif
3679 for(i=0; i< N_FDC; i++){
3680 if(FDCS->address != -1){
3681 fdc = i;
3682 reset_fdc_info(1);
3683 outb_p(FDCS->dor, FD_DOR);
3684 }
3685 }
3686 set_dor(0, ~0, 8);
3687
3688 if (request_irq(FLOPPY_IRQ, floppy_interrupt, SA_INTERRUPT, "floppy")) {
3689 DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
3690 FLOPPY_IRQ);
3691 return -1;
3692 }
3693 if (request_dma(FLOPPY_DMA,"floppy")) {
3694 DPRINT1("Unable to grab DMA%d for the floppy driver\n",
3695 FLOPPY_DMA);
3696 free_irq(FLOPPY_IRQ);
3697 return -1;
3698 }
3699 for(fdc = 0; fdc < N_FDC ; fdc++)
3700 if(FDCS->address != -1)
3701 outb_p(FDCS->dor, FD_DOR);
3702 fdc = 0;
3703 enable_irq(FLOPPY_IRQ);
3704 return 0;
3705 }
3706
3707 static void floppy_release_irq_and_dma(void)
3708 {
3709 #ifdef CONFIG_FLOPPY_SANITY
3710 int drive;
3711 #endif
3712 long tmpsize;
3713 void *tmpaddr;
3714
3715 cli();
3716 if (--usage_count){
3717 sti();
3718 return;
3719 }
3720 sti();
3721 #ifdef FD_MODULE
3722 MOD_DEC_USE_COUNT;
3723 #endif
3724 disable_dma(FLOPPY_DMA);
3725 free_dma(FLOPPY_DMA);
3726 disable_irq(FLOPPY_IRQ);
3727 free_irq(FLOPPY_IRQ);
3728
3729 set_dor(0, ~0, 8);
3730 #if N_FDC > 1
3731 set_dor(1, ~8, 0);
3732 #endif
3733 floppy_enable_hlt();
3734
3735 if (floppy_track_buffer && max_buffer_sectors) {
3736 tmpsize = max_buffer_sectors*1024;
3737 tmpaddr = (void *)floppy_track_buffer;
3738 floppy_track_buffer = 0;
3739 max_buffer_sectors = 0;
3740 free_pages((unsigned long)tmpaddr, __get_order(tmpsize));
3741 }
3742
3743 #ifdef CONFIG_FLOPPY_SANITY
3744 for(drive=0; drive < N_FDC * 4; drive++)
3745 if( motor_off_timer[drive].next )
3746 printk("motor off timer %d still active\n", drive);
3747
3748 if(fd_timeout.next)
3749 printk("floppy timer still active:%s\n", timeout_message);
3750 if (fd_timer.next)
3751 printk("auxiliary floppy timer still active\n");
3752 if(floppy_tq.sync)
3753 printk("task queue still active\n");
3754 #endif
3755 }
3756
3757
3758 #ifdef MODULE
3759
3760 extern char *get_options(char *str, int *ints);
3761
3762 #if 0
3763
3764
3765 int ENVIRON = 0x60090b34;
3766
3767 static void
3768 mod_setup(char *name,
3769 void (*setup)(char *, int *)) {
3770 char **environ,*env,*ptr,c,i;
3771 char line[100];
3772 int ints[11];
3773
3774 environ = (char **) get_fs_long( ENVIRON );
3775
3776 while((env = (char *)get_fs_long(environ))){
3777 for(i=0; i<strlen(name); i++)
3778 if ( (char) get_fs_byte(env++) != name[i] )
3779 break;
3780 if(i == strlen(name)){
3781 ptr=line;
3782 while(ptr < line+99){
3783 c = (char)get_fs_byte(env++);
3784 if ( c== ' ' || !c ){
3785 *ptr='\0';
3786 if(ptr!=line)
3787 setup(get_options(line,ints),
3788 ints);
3789 ptr=line;
3790 if (!c)
3791 break;
3792 } else
3793 *ptr++ = c;
3794 }
3795 }
3796 environ++;
3797 }
3798 }
3799 #endif
3800
3801 #ifdef __cplusplus
3802 extern "C" {
3803 #endif
3804 int init_module(void)
3805 {
3806 int ret;
3807 printk("inserting floppy driver for %s\n", kernel_version);
3808
3809
3810
3811
3812 ret = floppy_init();
3813 return 0;
3814 }
3815
3816 void cleanup_module(void)
3817 {
3818 int fdc;
3819
3820 for(fdc=0; fdc<2; fdc++)
3821 if (FDCS->address != -1){
3822 release_region(FDCS->address, 6);
3823 release_region(FDCS->address+7, 1);
3824 }
3825
3826 unregister_blkdev(MAJOR_NR, "fd");
3827
3828 blk_dev[MAJOR_NR].request_fn = 0;
3829 }
3830
3831 #ifdef __cplusplus
3832 }
3833 #endif
3834
3835 #endif