This source file includes following definitions.
- select_callback
- floppy_select
- motor_on_callback
- motor_off_callback
- floppy_on
- floppy_off
- request_done
- floppy_change
- setup_DMA
- output_byte
- output_byte_force
- result
- bad_flp_intr
- perpendicular_mode
- configure_fdc_mode
- tell_sector
- rw_interrupt
- setup_rw_floppy
- seek_interrupt
- transfer
- recal_interrupt
- unexpected_floppy_interrupt
- recalibrate_floppy
- reset_interrupt
- reset_floppy
- floppy_shutdown
- shake_done
- retry_recal
- shake_zero
- shake_one
- floppy_ready
- setup_format_params
- redo_fd_request
- do_fd_request
- fd_ioctl
- find_base
- config_types
- floppy_open
- floppy_release
- check_floppy_change
- floppy_interrupt
- floppy_init
- floppy_grab_irq_and_dma
- floppy_release_irq_and_dma
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 #define REALLY_SLOW_IO
73 #define FLOPPY_IRQ 6
74 #define FLOPPY_DMA 2
75 #define FDC_FIFO_UNTESTED
76
77 #define FDC_FIFO_BUG
78
79 #include <linux/sched.h>
80 #include <linux/fs.h>
81 #include <linux/kernel.h>
82 #include <linux/timer.h>
83 #include <linux/fdreg.h>
84 #include <linux/fd.h>
85 #include <linux/errno.h>
86
87 #include <asm/dma.h>
88 #include <asm/irq.h>
89 #include <asm/system.h>
90 #include <asm/io.h>
91 #include <asm/segment.h>
92
93 #define MAJOR_NR FLOPPY_MAJOR
94 #include "blk.h"
95
96 static unsigned int changed_floppies = 0, fake_change = 0;
97
98 static int initial_reset_flag = 0;
99 static int need_configure = 1;
100 static int recalibrate = 0;
101 static int reset = 0;
102 static int recover = 0;
103 static int seek = 0;
104
105 static unsigned char current_DOR = 0x0C;
106 static unsigned char running = 0;
107
108 #define TYPE(x) ((x)>>2)
109 #define DRIVE(x) ((x)&0x03)
110
111
112
113
114
115
116 #define MAX_ERRORS 12
117
118
119
120
121
122 #define MAX_DISK_SIZE 2880
123
124
125
126
127
128 #define MAX_BUFFER_SECTORS 36
129
130
131
132
133
134
135
136
137
138
139 #define LAST_DMA_ADDR (0x100000 - BLOCK_SIZE)
140
141
142
143
144 #define MAX_REPLIES 7
145 static unsigned char reply_buffer[MAX_REPLIES];
146 #define ST0 (reply_buffer[0])
147 #define ST1 (reply_buffer[1])
148 #define ST2 (reply_buffer[2])
149 #define ST3 (reply_buffer[3])
150
151
152
153
154
155
156
157
158 static struct floppy_struct floppy_type[] = {
159 { 0, 0,0, 0,0,0x00,0x00,0x00,0x00,NULL },
160 { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,NULL },
161 { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,NULL },
162 { 720, 9,2,40,1,0x2A,0x02,0xDF,0x50,NULL },
163 { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,NULL },
164 { 720, 9,2,40,1,0x23,0x01,0xDF,0x50,NULL },
165 { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,NULL },
166 { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL },
167 { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,NULL },
168 { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,NULL },
169 };
170
171
172
173
174
175
176 static struct floppy_struct floppy_types[] = {
177 { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"360k/PC" },
178 { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"360k/PC" },
179 { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,"1.2M" },
180 { 720, 9,2,40,1,0x23,0x01,0xDF,0x50,"360k/AT" },
181 { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"720k" },
182 { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"720k" },
183 { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"1.44M" },
184 { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"720k/AT" },
185 { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"2.88M-AMI" },
186 { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"1.44M-AMI" },
187 { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"2.88M" },
188 { 2880,18,2,80,0,0x1B,0x40,0xCF,0x6C,"1.44MX" },
189 };
190
191
192 struct floppy_struct *current_type[4] = { NULL, NULL, NULL, NULL };
193
194
195 struct floppy_struct *base_type[4];
196
197
198
199
200
201 struct floppy_struct user_params[4];
202
203 static int floppy_sizes[] ={
204 MAX_DISK_SIZE, MAX_DISK_SIZE, MAX_DISK_SIZE, MAX_DISK_SIZE,
205 360, 360, 360, 360,
206 1200,1200,1200,1200,
207 360, 360, 360, 360,
208 720, 720, 720, 720,
209 360, 360, 360, 360,
210 720, 720, 720, 720,
211 1440,1440,1440,1440,
212 2880,2880,2880,2880
213 };
214
215
216
217
218
219
220 static int probing = 0;
221
222
223
224
225
226
227 static int keep_data[4] = { 0,0,0,0 };
228
229
230
231
232
233
234 static ftd_msg[4] = { 0,0,0,0 };
235
236
237
238 static fd_ref[4] = { 0,0,0,0 };
239 static fd_device[4] = { 0,0,0,0 };
240
241
242 static volatile int format_status = FORMAT_NONE, fdc_busy = 0;
243 static struct wait_queue *fdc_wait = NULL, *format_done = NULL;
244
245
246 static int format_errors;
247
248
249 static struct format_descr format_req;
250
251
252
253
254
255 #define CURRENT_DEVICE (format_status == FORMAT_BUSY ? format_req.device : \
256 (CURRENT->dev))
257
258
259 #define CURRENT_ERRORS (format_status == FORMAT_BUSY ? format_errors : \
260 (CURRENT->errors))
261
262
263
264
265
266
267 static unsigned short min_report_error_cnt[4] = {2, 2, 2, 2};
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285 extern char tmp_floppy_area[BLOCK_SIZE];
286 extern char floppy_track_buffer[512*2*MAX_BUFFER_SECTORS];
287
288 static void redo_fd_request(void);
289 static void floppy_ready(void);
290 static void recalibrate_floppy(void);
291
292 int floppy_grab_irq_and_dma(void);
293 void floppy_release_irq_and_dma(void);
294
295
296
297
298
299
300 #define NO_TRACK 255
301
302 static int read_track = 0;
303 static int buffer_track = -1;
304 static int buffer_drive = -1;
305 static int cur_spec1 = -1;
306 static int cur_rate = -1;
307 static struct floppy_struct * floppy = floppy_type;
308 static unsigned char current_drive = 255;
309 static unsigned char sector = 0;
310 static unsigned char head = 0;
311 static unsigned char track = 0;
312 static unsigned char seek_track = 0;
313 static unsigned char current_track = NO_TRACK;
314 static unsigned char command = 0;
315 static unsigned char fdc_version = 0x90;
316
317 static void select_callback(unsigned long unused)
318 {
319 floppy_ready();
320 }
321
322 static void floppy_select(unsigned int nr)
323 {
324 static struct timer_list select = { NULL, NULL, 0, 0, select_callback };
325
326 if (current_drive == (current_DOR & 3)) {
327 floppy_ready();
328 return;
329 }
330 seek = 1;
331 current_track = NO_TRACK;
332 current_DOR &= 0xFC;
333 current_DOR |= current_drive;
334 outb(current_DOR,FD_DOR);
335 del_timer(&select);
336 select.expires = 2;
337 add_timer(&select);
338 }
339
340 static void motor_on_callback(unsigned long nr)
341 {
342 running |= 0x10 << nr;
343 floppy_select(nr);
344 }
345
346 static struct timer_list motor_on_timer[4] = {
347 { NULL, NULL, 0, 0, motor_on_callback },
348 { NULL, NULL, 0, 1, motor_on_callback },
349 { NULL, NULL, 0, 2, motor_on_callback },
350 { NULL, NULL, 0, 3, motor_on_callback }
351 };
352
353 static void motor_off_callback(unsigned long nr)
354 {
355 unsigned char mask = ~(0x10 << nr);
356 cli();
357 running &= mask;
358 current_DOR &= mask;
359 outb(current_DOR,FD_DOR);
360 sti();
361 }
362
363 static struct timer_list motor_off_timer[4] = {
364 { NULL, NULL, 0, 0, motor_off_callback },
365 { NULL, NULL, 0, 1, motor_off_callback },
366 { NULL, NULL, 0, 2, motor_off_callback },
367 { NULL, NULL, 0, 3, motor_off_callback }
368 };
369
370 static void floppy_on(unsigned int nr)
371 {
372 unsigned char mask = 0x10 << nr;
373
374 del_timer(motor_off_timer + nr);
375 if (mask & running)
376 floppy_select(nr);
377 if (!(mask & current_DOR)) {
378 del_timer(motor_on_timer + nr);
379 motor_on_timer[nr].expires = HZ;
380 add_timer(motor_on_timer + nr);
381 }
382 current_DOR &= 0xFC;
383 current_DOR |= mask;
384 current_DOR |= nr;
385 outb(current_DOR,FD_DOR);
386 }
387
388 static void floppy_off(unsigned int nr)
389 {
390 del_timer(motor_off_timer+nr);
391 motor_off_timer[nr].expires = 3*HZ;
392 add_timer(motor_off_timer+nr);
393 }
394
395 void request_done(int uptodate)
396 {
397 timer_active &= ~(1 << FLOPPY_TIMER);
398 if (format_status != FORMAT_BUSY)
399 end_request(uptodate);
400 else {
401 format_status = uptodate ? FORMAT_OKAY : FORMAT_ERROR;
402 wake_up(&format_done);
403 }
404 }
405
406
407
408
409
410
411
412 static int floppy_change(struct buffer_head * bh)
413 {
414 unsigned int mask = 1 << (bh->b_dev & 0x03);
415
416 if (MAJOR(bh->b_dev) != MAJOR_NR) {
417 printk("floppy_changed: not a floppy\n");
418 return 0;
419 }
420 if (fake_change & mask) {
421 buffer_track = -1;
422 fake_change &= ~mask;
423
424 changed_floppies &= ~mask;
425 return 1;
426 }
427 if (changed_floppies & mask) {
428 buffer_track = -1;
429 changed_floppies &= ~mask;
430 recalibrate = 1;
431 return 1;
432 }
433 if (!bh)
434 return 0;
435 if (bh->b_dirt)
436 ll_rw_block(WRITE, 1, &bh);
437 else {
438 buffer_track = -1;
439 bh->b_uptodate = 0;
440 ll_rw_block(READ, 1, &bh);
441 }
442 wait_on_buffer(bh);
443 if (changed_floppies & mask) {
444 changed_floppies &= ~mask;
445 recalibrate = 1;
446 return 1;
447 }
448 return 0;
449 }
450
451 #define copy_buffer(from,to) \
452 __asm__("cld ; rep ; movsl" \
453 : \
454 :"c" (BLOCK_SIZE/4),"S" ((long)(from)),"D" ((long)(to)) \
455 :"cx","di","si")
456
457 static void setup_DMA(void)
458 {
459 unsigned long addr,count;
460 unsigned char dma_code;
461
462 dma_code = DMA_WRITE;
463 if (command == FD_READ)
464 dma_code = DMA_READ;
465 if (command == FD_FORMAT) {
466 addr = (long) tmp_floppy_area;
467 count = floppy->sect*4;
468 } else {
469 addr = (long) CURRENT->buffer;
470 count = 1024;
471 }
472 if (read_track) {
473
474 buffer_drive = buffer_track = -1;
475 count = floppy->sect*floppy->head*512;
476 addr = (long) floppy_track_buffer;
477 } else if (addr >= LAST_DMA_ADDR) {
478 addr = (long) tmp_floppy_area;
479 if (command == FD_WRITE)
480 copy_buffer(CURRENT->buffer,tmp_floppy_area);
481 }
482 cli();
483 disable_dma(FLOPPY_DMA);
484 clear_dma_ff(FLOPPY_DMA);
485 set_dma_mode(FLOPPY_DMA, (command == FD_READ)? DMA_MODE_READ : DMA_MODE_WRITE);
486 set_dma_addr(FLOPPY_DMA, addr);
487 set_dma_count(FLOPPY_DMA, count);
488 enable_dma(FLOPPY_DMA);
489 sti();
490 }
491
492 static void output_byte(char byte)
493 {
494 int counter;
495 unsigned char status;
496
497 if (reset)
498 return;
499 for(counter = 0 ; counter < 10000 ; counter++) {
500 status = inb_p(FD_STATUS) & (STATUS_READY | STATUS_DIR);
501 if (status == STATUS_READY) {
502 outb(byte,FD_DATA);
503 return;
504 }
505 }
506 current_track = NO_TRACK;
507 reset = 1;
508 printk("Unable to send byte to FDC\n");
509 }
510
511 #ifdef FDC_FIFO_BUG
512
513 static void output_byte_force(char byte)
514 {
515 int counter;
516 unsigned char status;
517
518 if (reset)
519 return;
520 for (counter = 0 ; counter < 10000 ; counter++) {
521 status = inb_p(FD_STATUS);
522 if ((status & (STATUS_READY | STATUS_DIR)) == STATUS_READY) {
523 outb(byte,FD_DATA);
524 return;
525 }
526 if ((status & (STATUS_READY | STATUS_BUSY)) == (STATUS_READY | STATUS_BUSY)) {
527 outb(byte,FD_DATA);
528 return;
529 }
530 }
531 current_track = NO_TRACK;
532 reset = 1;
533 printk("Unable to send byte to FDC\n");
534 }
535 #endif
536
537 static int result(void)
538 {
539 int i = 0, counter, status;
540
541 if (reset)
542 return -1;
543 for (counter = 0 ; counter < 10000 ; counter++) {
544 status = inb_p(FD_STATUS)&(STATUS_DIR|STATUS_READY|STATUS_BUSY);
545 if (status == STATUS_READY) {
546 return i;
547 }
548 if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {
549 if (i >= MAX_REPLIES) {
550 printk("floppy_stat reply overrun\n");
551 break;
552 }
553 reply_buffer[i++] = inb_p(FD_DATA);
554 }
555 }
556 reset = 1;
557 current_track = NO_TRACK;
558 printk("Getstatus times out\n");
559 return -1;
560 }
561
562 static void bad_flp_intr(void)
563 {
564 int errors;
565
566 current_track = NO_TRACK;
567 if (format_status == FORMAT_BUSY)
568 errors = ++format_errors;
569 else if (!CURRENT) {
570 printk(DEVICE_NAME ": no current request\n");
571 reset = recalibrate = 1;
572 return;
573 } else
574 errors = ++CURRENT->errors;
575 if (errors > MAX_ERRORS) {
576 request_done(0);
577 }
578 if (errors > MAX_ERRORS/2)
579 reset = 1;
580 else
581 recalibrate = 1;
582 }
583
584
585
586
587
588
589 static inline void perpendicular_mode(unsigned char rate)
590 {
591 if (fdc_version == FDC_TYPE_82077) {
592 output_byte(FD_PERPENDICULAR);
593 if (rate & 0x40) {
594 unsigned char r = rate & 0x03;
595 if (r == 0)
596 #ifndef FDC_FIFO_BUG
597 output_byte(2);
598 #else
599 output_byte_force(2);
600 #endif
601 else if (r == 3)
602 #ifndef FDC_FIFO_BUG
603 output_byte(3);
604 #else
605 output_byte_force(3);
606 #endif
607 else {
608 printk(DEVICE_NAME ": Invalid data rate for perpendicular mode!\n");
609 reset = 1;
610 }
611 } else
612 #ifndef FDC_FIFO_BUG
613 output_byte(0);
614 #else
615 output_byte_force(0);
616 #endif
617 } else {
618 if (rate & 0x40) {
619 printk(DEVICE_NAME ": perpendicular mode not supported by this FDC.\n");
620 reset = 1;
621 }
622 }
623 }
624
625
626
627
628
629
630
631
632 static void configure_fdc_mode(void)
633 {
634 if (need_configure && (fdc_version == FDC_TYPE_82077)) {
635
636 output_byte(FD_CONFIGURE);
637 #ifndef FDC_FIFO_BUG
638 output_byte(0);
639 #else
640 output_byte_force(0);
641 #endif
642 output_byte(0x1A);
643 #ifndef FDC_FIFO_BUG
644 output_byte(0);
645 #else
646 output_byte_force(0);
647 #endif
648 need_configure = 0;
649 printk(DEVICE_NAME ": FIFO enabled\n");
650 }
651 if (cur_spec1 != floppy->spec1) {
652 cur_spec1 = floppy->spec1;
653 output_byte(FD_SPECIFY);
654 output_byte(cur_spec1);
655 output_byte(6);
656 }
657 if (cur_rate != floppy->rate) {
658
659 perpendicular_mode(floppy->rate);
660 outb_p((cur_rate = (floppy->rate)) & ~0x40, FD_DCR);
661 }
662 }
663
664
665 static void tell_sector(int nr)
666 {
667 if (nr!=7) {
668 printk(" -- FDC reply errror");
669 reset = 1;
670 } else
671 printk(": track %d, head %d, sector %d", reply_buffer[3],
672 reply_buffer[4], reply_buffer[5]);
673 }
674
675
676
677
678
679
680
681 static void rw_interrupt(void)
682 {
683 char * buffer_area;
684 int nr;
685 char bad;
686
687 nr = result();
688
689 switch ((ST0 & ST0_INTR)>>6) {
690 case 1:
691 bad = 1;
692 if (ST1 & ST1_WP) {
693 printk(DEVICE_NAME ": Drive %d is write protected\n", current_drive);
694 request_done(0);
695 bad = 0;
696 } else if (ST1 & ST1_OR) {
697 if (ftd_msg[ST0 & ST0_DS])
698 printk(DEVICE_NAME ": Over/Underrun - retrying\n");
699
700 bad = 0;
701 } else if (CURRENT_ERRORS > min_report_error_cnt[ST0 & ST0_DS]) {
702 printk(DEVICE_NAME " %d: ", ST0 & ST0_DS);
703 if (ST0 & ST0_ECE) {
704 printk("Recalibrate failed!");
705 } else if (ST2 & ST2_CRC) {
706 printk("data CRC error");
707 tell_sector(nr);
708 } else if (ST1 & ST1_CRC) {
709 printk("CRC error");
710 tell_sector(nr);
711 } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
712 if (!probing) {
713 printk("sector not found");
714 tell_sector(nr);
715 } else
716 printk("probe failed...");
717 } else if (ST2 & ST2_WC) {
718 printk("wrong cylinder");
719 } else if (ST2 & ST2_BC) {
720 printk("bad cylinder");
721 } else {
722 printk("unknown error. ST[0..3] are: 0x%x 0x%x 0x%x 0x%x\n", ST0, ST1, ST2, ST3);
723 }
724 printk("\n");
725
726 }
727 if (bad)
728 bad_flp_intr();
729 redo_fd_request();
730 return;
731 case 2:
732 printk(DEVICE_NAME ": Invalid FDC command given!\n");
733 request_done(0);
734 return;
735 case 3:
736 printk(DEVICE_NAME ": Abnormal termination caused by polling\n");
737 bad_flp_intr();
738 redo_fd_request();
739 return;
740 default:
741 break;
742 }
743
744 if (probing) {
745 int drive = MINOR(CURRENT->dev);
746
747 if (ftd_msg[drive])
748 printk("Auto-detected floppy type %s in fd%d\n",
749 floppy->name,drive);
750 current_type[drive] = floppy;
751 floppy_sizes[drive] = floppy->size >> 1;
752 probing = 0;
753 }
754 if (read_track) {
755 buffer_track = seek_track;
756 buffer_drive = current_drive;
757 buffer_area = floppy_track_buffer +
758 ((sector-1 + head*floppy->sect)<<9);
759 copy_buffer(buffer_area,CURRENT->buffer);
760 } else if (command == FD_READ &&
761 (unsigned long)(CURRENT->buffer) >= LAST_DMA_ADDR)
762 copy_buffer(tmp_floppy_area,CURRENT->buffer);
763 request_done(1);
764 redo_fd_request();
765 }
766
767
768
769
770
771
772
773
774 inline void setup_rw_floppy(void)
775 {
776 setup_DMA();
777 do_floppy = rw_interrupt;
778 output_byte(command);
779 if (command != FD_FORMAT) {
780 if (read_track) {
781 output_byte(current_drive);
782 output_byte(track);
783 output_byte(0);
784 output_byte(1);
785 } else {
786 output_byte(head<<2 | current_drive);
787 output_byte(track);
788 output_byte(head);
789 output_byte(sector);
790 }
791 output_byte(2);
792 output_byte(floppy->sect);
793 output_byte(floppy->gap);
794 output_byte(0xFF);
795 } else {
796 output_byte(head<<2 | current_drive);
797 output_byte(2);
798 output_byte(floppy->sect);
799 output_byte(floppy->fmt_gap);
800 output_byte(FD_FILL_BYTE);
801 }
802 if (reset)
803 redo_fd_request();
804 }
805
806
807
808
809
810
811 static void seek_interrupt(void)
812 {
813
814 output_byte(FD_SENSEI);
815 if (result() != 2 || (ST0 & 0xF8) != 0x20 || ST1 != seek_track) {
816 printk(DEVICE_NAME ": seek failed\n");
817 recalibrate = 1;
818 bad_flp_intr();
819 redo_fd_request();
820 return;
821 }
822 current_track = ST1;
823 setup_rw_floppy();
824 }
825
826
827
828
829
830
831
832 static void transfer(void)
833 {
834 read_track = (command == FD_READ) && (CURRENT_ERRORS < 4) &&
835 (floppy->sect <= MAX_BUFFER_SECTORS);
836
837 configure_fdc_mode();
838
839 if (reset) {
840 redo_fd_request();
841 return;
842 }
843 if (!seek) {
844 setup_rw_floppy();
845 return;
846 }
847
848 do_floppy = seek_interrupt;
849 output_byte(FD_SEEK);
850 if (read_track)
851 output_byte(current_drive);
852 else
853 output_byte((head<<2) | current_drive);
854 output_byte(seek_track);
855 if (reset)
856 redo_fd_request();
857 }
858
859
860
861
862
863 static void recal_interrupt(void)
864 {
865 output_byte(FD_SENSEI);
866 current_track = NO_TRACK;
867 if (result()!=2 || (ST0 & 0xE0) == 0x60)
868 reset = 1;
869
870 if ((ST0 & 0x10) == 0x10)
871 recalibrate_floppy();
872 else
873 redo_fd_request();
874 }
875
876 static void unexpected_floppy_interrupt(void)
877 {
878 current_track = NO_TRACK;
879 output_byte(FD_SENSEI);
880 printk(DEVICE_NAME ": unexpected interrupt\n");
881 if (result()!=2 || (ST0 & 0xE0) == 0x60)
882 reset = 1;
883 else
884 recalibrate = 1;
885 }
886
887 static void recalibrate_floppy(void)
888 {
889 recalibrate = 0;
890 current_track = 0;
891 do_floppy = recal_interrupt;
892 output_byte(FD_RECALIBRATE);
893 output_byte(head<<2 | current_drive);
894 if (reset)
895 redo_fd_request();
896 }
897
898
899
900
901 static void reset_interrupt(void)
902 {
903 short i;
904
905 for (i=0; i<4; i++) {
906 output_byte(FD_SENSEI);
907 (void) result();
908 }
909 output_byte(FD_SPECIFY);
910 output_byte(cur_spec1);
911 output_byte(6);
912 configure_fdc_mode();
913 if (initial_reset_flag) {
914 initial_reset_flag = 0;
915 recalibrate = 1;
916 reset = 0;
917 return;
918 }
919 if (!recover)
920 redo_fd_request();
921 else {
922 recalibrate_floppy();
923 recover = 0;
924 }
925 }
926
927
928
929
930 static void reset_floppy(void)
931 {
932 int i;
933
934 do_floppy = reset_interrupt;
935 reset = 0;
936 current_track = NO_TRACK;
937 cur_spec1 = -1;
938 cur_rate = -1;
939 recalibrate = 1;
940 need_configure = 1;
941 if (!initial_reset_flag)
942 printk("Reset-floppy called\n");
943 cli();
944 outb_p(current_DOR & ~0x04, FD_DOR);
945 for (i=0 ; i<1000 ; i++)
946 __asm__("nop");
947 outb(current_DOR, FD_DOR);
948 sti();
949 }
950
951 static void floppy_shutdown(void)
952 {
953 cli();
954 do_floppy = NULL;
955 request_done(0);
956 recover = 1;
957 reset_floppy();
958 sti();
959 redo_fd_request();
960 }
961
962 static void shake_done(void)
963 {
964 current_track = NO_TRACK;
965 if (inb(FD_DIR) & 0x80)
966 request_done(0);
967 redo_fd_request();
968 }
969
970 static int retry_recal(void (*proc)(void))
971 {
972 output_byte(FD_SENSEI);
973 if (result() == 2 && (ST0 & 0x10) != 0x10) return 0;
974 do_floppy = proc;
975 output_byte(FD_RECALIBRATE);
976 output_byte(head<<2 | current_drive);
977 return 1;
978 }
979
980 static void shake_zero(void)
981 {
982 if (!retry_recal(shake_zero)) shake_done();
983 }
984
985 static void shake_one(void)
986 {
987 if (retry_recal(shake_one)) return;
988 do_floppy = shake_done;
989 output_byte(FD_SEEK);
990 output_byte(head << 2 | current_drive);
991 output_byte(1);
992 }
993
994 static void floppy_ready(void)
995 {
996 if (inb(FD_DIR) & 0x80) {
997 changed_floppies |= 1<<current_drive;
998 buffer_track = -1;
999 if (keep_data[current_drive]) {
1000 if (keep_data[current_drive] > 0)
1001 keep_data[current_drive]--;
1002 } else {
1003 if (ftd_msg[current_drive] && current_type[current_drive] != NULL)
1004 printk("Disk type is undefined after disk "
1005 "change in fd%d\n",current_drive);
1006 current_type[current_drive] = NULL;
1007 floppy_sizes[current_drive] = MAX_DISK_SIZE;
1008 }
1009
1010
1011
1012 if (!reset && !recalibrate) {
1013 if (current_track && current_track != NO_TRACK)
1014 do_floppy = shake_zero;
1015 else
1016 do_floppy = shake_one;
1017 output_byte(FD_RECALIBRATE);
1018 output_byte(head<<2 | current_drive);
1019 return;
1020 }
1021 }
1022 if (reset) {
1023 reset_floppy();
1024 return;
1025 }
1026 if (recalibrate) {
1027 recalibrate_floppy();
1028 return;
1029 }
1030 transfer();
1031 }
1032
1033 static void setup_format_params(void)
1034 {
1035 unsigned char *here = (unsigned char *) tmp_floppy_area;
1036 int count,head_shift,track_shift,total_shift;
1037
1038
1039 head_shift = floppy->sect / 6;
1040
1041 track_shift = 2 * head_shift + 1;
1042
1043 total_shift = floppy->sect -
1044 ((track_shift * track + head_shift * head) % floppy->sect);
1045
1046
1047 for (count = 0; count < floppy->sect; count++) {
1048 *here++ = track;
1049 *here++ = head;
1050 *here++ = 1 + (( count + total_shift ) % floppy->sect);
1051 *here++ = 2;
1052 }
1053 }
1054
1055 static void redo_fd_request(void)
1056 {
1057 unsigned int block;
1058 char * buffer_area;
1059 int device;
1060
1061 if (CURRENT && CURRENT->dev < 0) return;
1062
1063 repeat:
1064 if (format_status == FORMAT_WAIT)
1065 format_status = FORMAT_BUSY;
1066 if (format_status != FORMAT_BUSY) {
1067 if (!CURRENT) {
1068 if (!fdc_busy)
1069 printk("FDC access conflict!");
1070 fdc_busy = 0;
1071 wake_up(&fdc_wait);
1072 CLEAR_INTR;
1073 return;
1074 }
1075 if (MAJOR(CURRENT->dev) != MAJOR_NR)
1076 panic(DEVICE_NAME ": request list destroyed"); \
1077 if (CURRENT->bh) {
1078 if (!CURRENT->bh->b_lock)
1079 panic(DEVICE_NAME ": block not locked");
1080 }
1081 }
1082 seek = 0;
1083 probing = 0;
1084 device = MINOR(CURRENT_DEVICE);
1085 if (device > 3)
1086 floppy = (device >> 2) + floppy_type;
1087 else {
1088 floppy = current_type[device & 3];
1089 if (!floppy) {
1090 probing = 1;
1091 floppy = base_type[device & 3];
1092 if (!floppy) {
1093 request_done(0);
1094 goto repeat;
1095 }
1096 if (CURRENT_ERRORS & 1)
1097 floppy++;
1098 }
1099 }
1100 if (format_status != FORMAT_BUSY) {
1101 if (current_drive != CURRENT_DEV) {
1102 current_track = NO_TRACK;
1103 current_drive = CURRENT_DEV;
1104 }
1105 block = CURRENT->sector;
1106 if (block+2 > floppy->size) {
1107 request_done(0);
1108 goto repeat;
1109 }
1110 sector = block % floppy->sect;
1111 block /= floppy->sect;
1112 head = block % floppy->head;
1113 track = block / floppy->head;
1114 seek_track = track << floppy->stretch;
1115 if (CURRENT->cmd == READ)
1116 command = FD_READ;
1117 else if (CURRENT->cmd == WRITE)
1118 command = FD_WRITE;
1119 else {
1120 printk("do_fd_request: unknown command\n");
1121 request_done(0);
1122 goto repeat;
1123 }
1124 } else {
1125 if (current_drive != (format_req.device & 3))
1126 current_track = NO_TRACK;
1127 current_drive = format_req.device & 3;
1128 if (((unsigned) format_req.track) >= floppy->track ||
1129 (format_req.head & 0xfffe) || probing) {
1130 request_done(0);
1131 goto repeat;
1132 }
1133 head = format_req.head;
1134 track = format_req.track;
1135 seek_track = track << floppy->stretch;
1136 if (seek_track == buffer_track) buffer_track = -1;
1137 command = FD_FORMAT;
1138 setup_format_params();
1139 }
1140 timer_table[FLOPPY_TIMER].expires = jiffies+10*HZ;
1141 timer_active |= 1 << FLOPPY_TIMER;
1142 if ((seek_track == buffer_track) &&
1143 (current_drive == buffer_drive)) {
1144 buffer_area = floppy_track_buffer +
1145 ((sector + head*floppy->sect)<<9);
1146 if (command == FD_READ) {
1147 copy_buffer(buffer_area,CURRENT->buffer);
1148 request_done(1);
1149 goto repeat;
1150 } else if (command == FD_WRITE)
1151 copy_buffer(CURRENT->buffer,buffer_area);
1152 }
1153 if (seek_track != current_track)
1154 seek = 1;
1155 sector++;
1156 del_timer(motor_off_timer + current_drive);
1157 floppy_on(current_drive);
1158 }
1159
1160 void do_fd_request(void)
1161 {
1162 cli();
1163 while (fdc_busy) sleep_on(&fdc_wait);
1164 fdc_busy = 1;
1165 sti();
1166 redo_fd_request();
1167 }
1168
1169 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1170 unsigned long param)
1171 {
1172 int i,drive,cnt,okay;
1173 struct floppy_struct *this_floppy;
1174
1175 switch (cmd) {
1176 RO_IOCTLS(inode->i_rdev,param);
1177 }
1178 drive = MINOR(inode->i_rdev);
1179 switch (cmd) {
1180 case FDFMTBEG:
1181 if (!suser())
1182 return -EPERM;
1183 return 0;
1184 case FDFMTEND:
1185 if (!suser())
1186 return -EPERM;
1187 cli();
1188 fake_change |= 1 << (drive & 3);
1189 sti();
1190 drive &= 3;
1191 cmd = FDCLRPRM;
1192 break;
1193 case FDGETPRM:
1194 if (drive > 3) this_floppy = &floppy_type[drive >> 2];
1195 else if ((this_floppy = current_type[drive & 3]) == NULL)
1196 return -ENODEV;
1197 i = verify_area(VERIFY_WRITE,(void *) param,sizeof(struct floppy_struct));
1198 if (i)
1199 return i;
1200 for (cnt = 0; cnt < sizeof(struct floppy_struct); cnt++)
1201 put_fs_byte(((char *) this_floppy)[cnt],
1202 (char *) param+cnt);
1203 return 0;
1204 case FDFMTTRK:
1205 if (!suser())
1206 return -EPERM;
1207 if (fd_ref[drive & 3] != 1)
1208 return -EBUSY;
1209 cli();
1210 while (format_status != FORMAT_NONE)
1211 sleep_on(&format_done);
1212 for (cnt = 0; cnt < sizeof(struct format_descr); cnt++)
1213 ((char *) &format_req)[cnt] = get_fs_byte(
1214 (char *) param+cnt);
1215 format_req.device = drive;
1216 format_status = FORMAT_WAIT;
1217 format_errors = 0;
1218 while (format_status != FORMAT_OKAY && format_status !=
1219 FORMAT_ERROR) {
1220 if (fdc_busy) sleep_on(&fdc_wait);
1221 else {
1222 fdc_busy = 1;
1223 redo_fd_request();
1224 }
1225 }
1226 while (format_status != FORMAT_OKAY && format_status !=
1227 FORMAT_ERROR)
1228 sleep_on(&format_done);
1229 sti();
1230 okay = format_status == FORMAT_OKAY;
1231 format_status = FORMAT_NONE;
1232 floppy_off(drive & 3);
1233 wake_up(&format_done);
1234 return okay ? 0 : -EIO;
1235 case FDFLUSH:
1236 if (!permission(inode, 2))
1237 return -EPERM;
1238 cli();
1239 fake_change |= 1 << (drive & 3);
1240 sti();
1241 check_disk_change(inode->i_rdev);
1242 return 0;
1243 }
1244 if (!suser())
1245 return -EPERM;
1246 if (drive < 0 || drive > 3)
1247 return -EINVAL;
1248 switch (cmd) {
1249 case FDCLRPRM:
1250 current_type[drive] = NULL;
1251 floppy_sizes[drive] = MAX_DISK_SIZE;
1252 keep_data[drive] = 0;
1253 break;
1254 case FDSETPRM:
1255 case FDDEFPRM:
1256 memcpy_fromfs(user_params+drive,
1257 (void *) param,
1258 sizeof(struct floppy_struct));
1259 current_type[drive] = &user_params[drive];
1260 floppy_sizes[drive] = user_params[drive].size >> 1;
1261 if (cmd == FDDEFPRM)
1262 keep_data[drive] = -1;
1263 else {
1264 cli();
1265 while (fdc_busy) sleep_on(&fdc_wait);
1266 fdc_busy = 1;
1267 sti();
1268 outb_p((current_DOR & 0xfc) | drive |
1269 (0x10 << drive),FD_DOR);
1270 for (cnt = 0; cnt < 1000; cnt++) __asm__("nop");
1271 if (inb(FD_DIR) & 0x80)
1272 keep_data[drive] = 1;
1273 else
1274 keep_data[drive] = 0;
1275 outb_p(current_DOR,FD_DOR);
1276 fdc_busy = 0;
1277 wake_up(&fdc_wait);
1278 }
1279 break;
1280 case FDMSGON:
1281 ftd_msg[drive] = 1;
1282 break;
1283 case FDMSGOFF:
1284 ftd_msg[drive] = 0;
1285 break;
1286 case FDSETEMSGTRESH:
1287 min_report_error_cnt[drive] = (unsigned short) (param & 0x0f);
1288 break;
1289 default:
1290 return -EINVAL;
1291 }
1292 return 0;
1293 }
1294
1295 #define CMOS_READ(addr) ({ \
1296 outb_p(addr,0x70); \
1297 inb_p(0x71); \
1298 })
1299
1300 static struct floppy_struct *find_base(int drive,int code)
1301 {
1302 struct floppy_struct *base;
1303
1304 if (code > 0 && code < 7) {
1305 base = &floppy_types[(code-1)*2];
1306 printk("fd%d is %s",drive,base->name);
1307 return base;
1308 } else if (!code) {
1309 printk("fd%d is not installed", drive);
1310 return NULL;
1311 }
1312 printk("fd%d is unknown type %d",drive,code);
1313 return NULL;
1314 }
1315
1316 static void config_types(void)
1317 {
1318 printk("Floppy drive(s): ");
1319 base_type[0] = find_base(0,(CMOS_READ(0x10) >> 4) & 15);
1320 if ((CMOS_READ(0x10) & 15) == 0)
1321 base_type[1] = NULL;
1322 else {
1323 printk(", ");
1324 base_type[1] = find_base(1,CMOS_READ(0x10) & 15);
1325 }
1326 base_type[2] = base_type[3] = NULL;
1327 printk("\n");
1328 }
1329
1330
1331
1332
1333
1334
1335 static int floppy_open(struct inode * inode, struct file * filp)
1336 {
1337 int drive;
1338 int old_dev;
1339
1340 drive = inode->i_rdev & 3;
1341 old_dev = fd_device[drive];
1342 if (fd_ref[drive])
1343 if (old_dev != inode->i_rdev)
1344 return -EBUSY;
1345 if (floppy_grab_irq_and_dma())
1346 return -EBUSY;
1347 fd_ref[drive]++;
1348 fd_device[drive] = inode->i_rdev;
1349 buffer_drive = buffer_track = -1;
1350 if (old_dev && old_dev != inode->i_rdev)
1351 invalidate_buffers(old_dev);
1352 if (filp && filp->f_mode)
1353 check_disk_change(inode->i_rdev);
1354 return 0;
1355 }
1356
1357 static void floppy_release(struct inode * inode, struct file * filp)
1358 {
1359 fsync_dev(inode->i_rdev);
1360 if (!fd_ref[inode->i_rdev & 3]--) {
1361 printk("floppy_release with fd_ref == 0");
1362 fd_ref[inode->i_rdev & 3] = 0;
1363 }
1364 floppy_release_irq_and_dma();
1365 }
1366
1367 static int check_floppy_change(dev_t dev)
1368 {
1369 int i;
1370 struct buffer_head * bh;
1371
1372 if (!(bh = getblk(dev,0,1024)))
1373 return 0;
1374 i = floppy_change(bh);
1375 brelse(bh);
1376 return i;
1377 }
1378
1379 static struct file_operations floppy_fops = {
1380 NULL,
1381 block_read,
1382 block_write,
1383 NULL,
1384 NULL,
1385 fd_ioctl,
1386 NULL,
1387 floppy_open,
1388 floppy_release,
1389 block_fsync,
1390 NULL,
1391 check_floppy_change,
1392 NULL
1393 };
1394
1395
1396 static void floppy_interrupt(int unused)
1397 {
1398 void (*handler)(void) = DEVICE_INTR;
1399
1400 DEVICE_INTR = NULL;
1401 if (!handler)
1402 handler = unexpected_floppy_interrupt;
1403 handler();
1404 }
1405
1406
1407
1408
1409
1410 static struct sigaction floppy_sigaction = {
1411 floppy_interrupt,
1412 0,
1413 SA_INTERRUPT,
1414 NULL
1415 };
1416
1417 void floppy_init(void)
1418 {
1419 outb(current_DOR,FD_DOR);
1420 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
1421 printk("Unable to get major %d for floppy\n",MAJOR_NR);
1422 return;
1423 }
1424 blk_size[MAJOR_NR] = floppy_sizes;
1425 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1426 timer_table[FLOPPY_TIMER].fn = floppy_shutdown;
1427 timer_active &= ~(1 << FLOPPY_TIMER);
1428 config_types();
1429
1430 output_byte(FD_VERSION);
1431 if (result() != 1) {
1432 printk(DEVICE_NAME ": FDC failed to return version byte\n");
1433 fdc_version = FDC_TYPE_STD;
1434 } else
1435 fdc_version = reply_buffer[0];
1436 if (fdc_version != FDC_TYPE_STD)
1437 printk(DEVICE_NAME ": FDC version 0x%x\n", fdc_version);
1438 #ifndef FDC_FIFO_UNTESTED
1439 fdc_version = FDC_TYPE_STD;
1440 #endif
1441
1442
1443
1444
1445
1446 if (fdc_version == FDC_TYPE_STD) {
1447 initial_reset_flag = 1;
1448 reset_floppy();
1449 }
1450 }
1451
1452 static int usage_count = 0;
1453
1454 int floppy_grab_irq_and_dma(void)
1455 {
1456 if (usage_count++)
1457 return 0;
1458 if (irqaction(FLOPPY_IRQ,&floppy_sigaction)) {
1459 printk("Unable to grab IRQ%d for the floppy driver\n", FLOPPY_IRQ);
1460 return -1;
1461 }
1462 if (request_dma(FLOPPY_DMA)) {
1463 printk("Unable to grab DMA%d for the floppy driver\n", FLOPPY_DMA);
1464 free_irq(FLOPPY_IRQ);
1465 return -1;
1466 }
1467 enable_irq(FLOPPY_IRQ);
1468 return 0;
1469 }
1470
1471 void floppy_release_irq_and_dma(void)
1472 {
1473 if (--usage_count)
1474 return;
1475 disable_dma(FLOPPY_DMA);
1476 free_dma(FLOPPY_DMA);
1477 disable_irq(FLOPPY_IRQ);
1478 free_irq(FLOPPY_IRQ);
1479 }