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