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