This source file includes following definitions.
- set_debugt
- debugt
- disk_change
- 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
- setup_DMA
- output_byte
- result
- perpendicular_mode
- fdc_specify
- fdc_dtr
- tell_sector
- interpret_errors
- setup_rw_floppy
- seek_interrupt
- check_wp
- seek_floppy
- recal_interrupt
- unexpected_floppy_interrupt
- floppy_interrupt
- recalibrate_floppy
- reset_interrupt
- reset_fdc
- empty
- show_floppy
- floppy_shutdown
- start_motor
- floppy_ready
- floppy_start
- do_wakeup
- wait_til_done
- generic_done
- generic_success
- generic_failure
- success_and_wakeup
- failure_and_wakeup
- next_valid_format
- bad_flp_intr
- set_floppy
- format_interrupt
- setup_format_params
- redo_format
- do_format
- request_done
- rw_interrupt
- buffer_chain_size
- transfer_size
- copy_buffer
- make_raw_rw_request
- redo_fd_request
- do_fd_request
- reset_intr
- user_reset_fdc
- fd_copyout
- drive_name
- raw_cmd_ioctl
- invalidate_drive
- fd_ioctl
- set_base_type
- config_types
- floppy_is_wp
- WRAPPER
- floppy_open
- check_floppy_change
- floppy_revalidate
- get_fdc_version
- floppy_init
- floppy_grab_irq_and_dma
- floppy_release_irq_and_dma
1
2
3
4
5
6
7
8
9
10 #define SANITY
11
12
13
14
15
16
17
18 #define ALLOWED_DRIVE_MASK 0x33
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
100
101
102
103
104
105
106
107
108
109
110
111
112 #define REALLY_SLOW_IO
113 #define FLOPPY_IRQ 6
114 #define FLOPPY_DMA 2
115
116 #define DEBUGT 2
117
118 #include <linux/config.h>
119 #include <linux/sched.h>
120 #include <linux/fs.h>
121 #include <linux/kernel.h>
122 #include <linux/timer.h>
123 #include <linux/tqueue.h>
124 #define FDPATCHES
125 #include <linux/fdreg.h>
126 #include <linux/fd.h>
127 #include <linux/errno.h>
128 #include <linux/malloc.h>
129 #include <linux/string.h>
130 #include <linux/fcntl.h>
131 #include <linux/delay.h>
132
133 #include <asm/dma.h>
134 #include <asm/irq.h>
135 #include <asm/system.h>
136 #include <asm/io.h>
137 #include <asm/segment.h>
138
139 #define MAJOR_NR FLOPPY_MAJOR
140 #include "blk.h"
141
142 static unsigned int changed_floppies = 0xff, fake_change = 0;
143 static int initialising=1;
144
145
146 #ifdef HAVE_2_CONTROLLERS
147 #define N_FDC 2
148 #define N_DRIVE 8
149 #else
150 #define N_FDC 1
151 #define N_DRIVE 4
152 #endif
153
154 #define TYPE(x) ( ((x)>>2) & 0x1f )
155 #define DRIVE(x) ( ((x)&0x03) | (((x)&0x80 ) >> 5))
156 #define UNIT(x) ( (x) & 0x03 )
157 #define FDC(x) ( ((x) & 0x04) >> 2 )
158 #define REVDRIVE(fdc, unit) ( (unit) + ((fdc) << 2 ))
159
160 #define DP (&drive_params[current_drive])
161 #define DRS (&drive_state[current_drive])
162 #define DRWE (&write_errors[current_drive])
163 #define FDCS (&fdc_state[fdc])
164
165 #define UDP (&drive_params[drive])
166 #define UDRS (&drive_state[drive])
167 #define UDRWE (&write_errors[drive])
168 #define UFDCS (&fdc_state[FDC(drive)])
169
170 #define DPRINT(x) printk(DEVICE_NAME "%d: " x,current_drive);
171
172 #define DPRINT1(x,x1) \
173 printk(DEVICE_NAME "%d: " x,current_drive,(x1));
174
175 #define DPRINT2(x,x1,x2) \
176 printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2));
177
178 #define DPRINT3(x,x1,x2,x3) \
179 printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2),(x3));
180
181
182 #define COMMAND raw_cmd.cmd[0]
183 #define DR_SELECT raw_cmd.cmd[1]
184 #define TRACK raw_cmd.cmd[2]
185 #define HEAD raw_cmd.cmd[3]
186 #define SECTOR raw_cmd.cmd[4]
187 #define SIZECODE raw_cmd.cmd[5]
188 #define SECT_PER_TRACK raw_cmd.cmd[6]
189 #define GAP raw_cmd.cmd[7]
190 #define SIZECODE2 raw_cmd.cmd[8]
191 #define NR_RW 9
192
193
194 #define F_SIZECODE raw_cmd.cmd[2]
195 #define F_SECT_PER_TRACK raw_cmd.cmd[3]
196 #define F_GAP raw_cmd.cmd[4]
197 #define F_FILL raw_cmd.cmd[5]
198 #define NR_F 6
199
200
201
202
203
204 #define MAX_DISK_SIZE 3984
205
206
207
208
209
210
211
212
213
214
215
216 #define LAST_DMA_ADDR (0x1000000)
217 #define K_64 (0x10000)
218
219
220
221
222 #define MAX_REPLIES 10
223 static unsigned char reply_buffer[MAX_REPLIES];
224 static int inr;
225 #define ST0 (reply_buffer[0])
226 #define ST1 (reply_buffer[1])
227 #define ST2 (reply_buffer[2])
228 #define ST3 (reply_buffer[0])
229 #define R_TRACK (reply_buffer[3])
230 #define R_HEAD (reply_buffer[4])
231 #define R_SECTOR (reply_buffer[5])
232 #define R_SIZECODE (reply_buffer[6])
233
234
235
236
237 static struct {
238 struct floppy_drive_params params;
239 char *name;
240 } default_drive_params[]= {
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256 {{0, 500, 16, 16, 8000, 100, 300, 0, 2, 5, 80, 3*HZ, 20, {3,1,2,0,2}, 0,
257 0, { 7, 4, 8, 2, 1, 5, 3,10}, 150, 0 }, "unknown" },
258
259 {{1, 300, 16, 16, 8000, 100, 300, 0, 2, 5, 40, 3*HZ, 17, {3,1,2,0,2}, 0,
260 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 150, 1 }, "360K PC" },
261
262 {{2, 500, 16, 16, 6000, 40, 300, 14, 2, 6, 83, 3*HZ, 17, {3,1,2,0,2}, 0,
263 0, { 2, 5, 6,23,10,20,11, 0}, 150, 2 }, "1.2M" },
264
265 {{3, 250, 16, 16, 3000, 100, 300, 0, 2, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0,
266 0, { 4,22,21,30, 3, 0, 0, 0}, 150, 4 }, "720k" },
267
268 {{4, 500, 16, 16, 4000, 40, 300, 10, 2, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0,
269 0, { 7, 4,25,22,31,21,29,11}, 150, 7 }, "1.44M" },
270
271 {{5, 1000, 15, 8, 3000, 40, 300, 10, 2, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0,
272 0, { 7, 8, 4,25,28,22,31,21}, 150, 8 }, "2.88M AMI BIOS" },
273
274 {{6, 1000, 15, 8, 3000, 40, 300, 10, 2, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0,
275 0, { 7, 8, 4,25,28,22,31,21}, 150, 8 }, "2.88M" }
276
277
278
279
280 };
281
282 static struct floppy_drive_params drive_params[N_DRIVE];
283 static struct floppy_drive_struct volatile drive_state[N_DRIVE];
284 static struct floppy_write_errors volatile write_errors[N_DRIVE];
285 static struct floppy_raw_cmd raw_cmd;
286
287
288
289
290
291
292
293
294 static struct floppy_struct floppy_type[32] = {
295 { 0, 0,0, 0,0,0x00,0x00,0x00,0x00,NULL },
296 { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"d360" },
297 { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,"h1200" },
298 { 720, 9,1,80,0,0x2A,0x02,0xDF,0x50,"D360" },
299 { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"D720" },
300 { 720, 9,2,40,1,0x23,0x01,0xDF,0x50,"h360" },
301 { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,"h720" },
302 { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"H1440" },
303 { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"E2880" },
304 { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"CompaQ"},
305
306 { 2880,18,2,80,0,0x25,0x00,0xDF,0x02,"h1440" },
307 { 3360,21,2,80,0,0x1C,0x00,0xCF,0x0C,"H1680" },
308 { 820,10,2,41,1,0x25,0x01,0xDF,0x2E,"h410" },
309 { 1640,10,2,82,0,0x25,0x02,0xDF,0x2E,"H820" },
310 { 2952,18,2,82,0,0x25,0x00,0xDF,0x02,"h1476" },
311 { 3444,21,2,82,0,0x25,0x00,0xDF,0x0C,"H1722" },
312 { 840,10,2,42,1,0x25,0x01,0xDF,0x2E,"h420" },
313 { 1660,10,2,83,0,0x25,0x02,0xDF,0x2E,"H830" },
314 { 2988,18,2,83,0,0x25,0x00,0xDF,0x02,"h1494" },
315 { 3486,21,2,83,0,0x25,0x00,0xDF,0x0C,"H1743" },
316
317 { 1760,11,2,80,0,0x1C,0x09,0xCF,0x00,"h880" },
318 { 2080,13,2,80,0,0x1C,0x01,0xCF,0x00,"D1040" },
319 { 2240,14,2,80,0,0x1C,0x19,0xCF,0x00,"D1120" },
320 { 3200,20,2,80,0,0x1C,0x20,0xCF,0x2C,"h1600" },
321 { 3520,22,2,80,0,0x1C,0x08,0xCF,0x2e,"H1760" },
322 { 3840,24,2,80,0,0x1C,0x20,0xCF,0x00,"H1920" },
323 { 6400,40,2,80,0,0x25,0x5B,0xCF,0x00,"E3200" },
324 { 7040,44,2,80,0,0x25,0x5B,0xCF,0x00,"E3520" },
325 { 7680,48,2,80,0,0x25,0x63,0xCF,0x00,"E3840" },
326
327 { 3680,23,2,80,0,0x1C,0x10,0xCF,0x00,"H1840" },
328 { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" },
329 { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" },
330 };
331
332 #define NUMBER(x) (sizeof(x) / sizeof(*(x)))
333 #define SECTSIZE ( _FD_SECTSIZE(*floppy))
334
335
336 struct floppy_struct *current_type[N_DRIVE] = {
337 NULL, NULL, NULL, NULL
338 #ifdef HAVE_2_CONTROLLERS
339 ,
340 NULL, NULL, NULL, NULL
341 #endif
342 };
343
344
345
346
347
348 struct floppy_struct user_params[N_DRIVE];
349
350 static int floppy_sizes[256];
351 static int floppy_blocksizes[256] = { 0, };
352
353
354
355
356
357
358 static int probing = 0;
359
360
361 #define FD_COMMAND_DETECT -2
362 #define FD_COMMAND_NONE -1
363 #define FD_COMMAND_ERROR 2
364 #define FD_COMMAND_OKAY 3
365
366 static volatile int command_status = FD_COMMAND_NONE, fdc_busy = 0;
367 static struct wait_queue *fdc_wait = NULL, *command_done = NULL;
368 #define NO_SIGNAL (!(current->signal & ~current->blocked) || !interruptible)
369 #define CALL(x) if( (x) == -EINTR) return -EINTR;
370
371
372 static int format_errors;
373
374
375 static struct format_descr format_req;
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390 extern char floppy_track_buffer[512*2*MAX_BUFFER_SECTORS];
391 #define max_buffer_sectors MAX_BUFFER_SECTORS
392
393 int *errors;
394 typedef void (*done_f)(int);
395 struct cont_t {
396 void (*interrupt)(void);
397
398 void (*redo)(void);
399 void (*error)(void);
400 done_f done;
401 } *cont;
402
403 static void floppy_start(void);
404 static void redo_fd_request(void);
405 static void recalibrate_floppy(void);
406 static void seek_floppy(void);
407 static void floppy_shutdown(void);
408
409 static int floppy_grab_irq_and_dma(void);
410 static void floppy_release_irq_and_dma(void);
411
412
413
414
415
416
417
418
419 #define CHECK_RESET { if ( FDCS->reset ){ reset_fdc(); return ; } }
420 static void reset_fdc(void);
421
422
423
424
425
426
427 #define NO_TRACK -1
428 #define NEED_1_RECAL -2
429 #define NEED_2_RECAL -3
430 #define PROVEN_ABSENT -4
431
432
433 static int buffer_track = -1;
434 static int buffer_drive = -1;
435 static int buffer_min = -1;
436 static int buffer_max = -1;
437
438
439 static struct floppy_fdc_state fdc_state[N_FDC];
440 int fdc;
441
442 static struct floppy_struct * floppy = floppy_type;
443 static unsigned char current_drive = 255;
444 static long current_count_sectors = 0;
445 static char *current_addr = 0;
446 static unsigned char sector_t;
447
448 #ifdef DEBUGT
449 long unsigned debugtimer;
450 #endif
451
452
453
454
455
456 static inline void set_debugt(void)
457 {
458 #ifdef DEBUGT
459 debugtimer = jiffies;
460 #endif
461 }
462
463 static inline void debugt(char *message)
464 {
465 #ifdef DEBUGT
466 if ( DP->flags & DEBUGT )
467 printk("%s dtime=%lu\n", message, jiffies-debugtimer );
468 #endif
469 }
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501 static int disk_change(int drive)
502 {
503 if(jiffies < DP->select_delay + DRS->select_date)
504 udelay(20000);
505
506 if(inb_p(FD_DIR) & 0x80){
507 UDRS->flags |= FD_VERIFY;
508
509 if(UDRS->maxblock ||
510 !(UDRS->flags & FD_DISK_NEWCHANGE)){
511
512 set_bit(drive,&changed_floppies);
513
514
515 if (UDRS->keep_data >= 0) {
516 if ((DP->flags & FTD_MSG) &&
517 current_type[drive] != NULL)
518 DPRINT("Disk type is undefined after "
519 "disk change\n");
520 current_type[drive] = NULL;
521 floppy_sizes[drive] = MAX_DISK_SIZE;
522 }
523 }
524 UDRS->flags |= FD_DISK_NEWCHANGE;
525 return 1;
526 } else {
527 UDRS->last_checked=jiffies;
528 UDRS->flags &= ~FD_DISK_NEWCHANGE;
529 return 0;
530 }
531 }
532
533 static int locked=0;
534 static int set_dor(int fdc, char mask, char data)
535 {
536 register unsigned char drive, unit, newdor,olddor;
537
538 locked=1;
539 olddor = FDCS->dor;
540 newdor = (olddor & mask) | data;
541 if ( newdor != olddor ){
542 unit = olddor & 0x3;
543 drive = REVDRIVE(fdc,unit);
544 if ( olddor & ( 0x10 << unit ))
545 disk_change(drive);
546 FDCS->dor = newdor;
547 outb_p( newdor, FD_DOR);
548 }
549 locked=0;
550 return olddor;
551 }
552
553 static void twaddle(void)
554 {
555 cli();
556 outb_p(FDCS->dor & ~(0x10<<UNIT(current_drive)),FD_DOR);
557 outb_p(FDCS->dor, FD_DOR);
558 sti();
559 }
560
561
562
563 static void reset_fdc_info(int mode)
564 {
565 int drive;
566
567 FDCS->spec1 = FDCS->spec2 = -1;
568 FDCS->need_configure = 1;
569 FDCS->perp_mode = 1;
570 FDCS->rawcmd = 0;
571 for ( drive = 0; drive < N_DRIVE; drive++)
572 if (FDC(drive) == fdc &&
573 UDRS->track != PROVEN_ABSENT &&
574 ( mode || UDRS->track != NEED_1_RECAL))
575 UDRS->track = NEED_2_RECAL;
576 }
577
578
579 static void set_fdc(int drive)
580 {
581 if ( drive >= 0 ){
582 fdc = FDC(drive);
583 current_drive = drive;
584 }
585 set_dor(fdc,~0,8);
586 #ifdef HAVE_2_CONTROLLERS
587 set_dor(1-fdc, ~8, 0);
588 #endif
589 if ( FDCS->rawcmd == 2 )
590 reset_fdc_info(1);
591 if( inb_p(FD_STATUS) != STATUS_READY )
592 FDCS->reset = 1;
593 }
594
595 static int usage_count = 0;
596
597 static int lock_fdc(int drive, int interruptible)
598 {
599
600 if(!usage_count){
601 printk("trying to lock fdc while usage count=0\n");
602 return -1;
603 }
604 floppy_grab_irq_and_dma();
605 cli();
606 while (fdc_busy && NO_SIGNAL)
607 interruptible_sleep_on(&fdc_wait);
608 if(fdc_busy){
609 sti();
610 return -EINTR;
611 }
612 fdc_busy = 1;
613 sti();
614 command_status = FD_COMMAND_NONE;
615 set_fdc(drive);
616 return 0;
617 }
618
619 #define LOCK_FDC(drive,interruptible) \
620 if(lock_fdc(drive,interruptible)) return -EINTR;
621
622
623 static inline void unlock_fdc(void)
624 {
625 if (!fdc_busy)
626 DPRINT("FDC access conflict!\n");
627
628 if ( DEVICE_INTR )
629 DPRINT1("device interrupt still active at FDC release: %p!\n",
630 DEVICE_INTR);
631 command_status = FD_COMMAND_NONE;
632 timer_active &= ~(1 << FLOPPY_TIMER);
633 fdc_busy = 0;
634 floppy_release_irq_and_dma();
635 wake_up(&fdc_wait);
636 }
637
638
639 static void motor_off_callback(unsigned long nr)
640 {
641 unsigned char mask = ~(0x10 << UNIT(nr));
642
643 if(locked)
644 floppy_off(nr);
645 else
646 set_dor( FDC(nr), mask, 0 );
647 }
648
649 static struct timer_list motor_off_timer[N_DRIVE] = {
650 { NULL, NULL, 0, 0, motor_off_callback },
651 { NULL, NULL, 0, 1, motor_off_callback },
652 { NULL, NULL, 0, 2, motor_off_callback },
653 { NULL, NULL, 0, 3, motor_off_callback }
654 #ifdef HAVE_2_CONTROLLERS
655 ,
656 { NULL, NULL, 0, 4, motor_off_callback },
657 { NULL, NULL, 0, 5, motor_off_callback },
658 { NULL, NULL, 0, 6, motor_off_callback },
659 { NULL, NULL, 0, 7, motor_off_callback }
660 #endif
661 };
662
663
664 static void floppy_off(unsigned int nr)
665 {
666 unsigned long volatile delta;
667 register int fdc=FDC(nr);
668
669 if( !(FDCS->dor & ( 0x10 << UNIT(nr))))
670 return;
671
672 del_timer(motor_off_timer+nr);
673
674
675
676 if ( drive_params[nr].rps ){
677 delta = jiffies - drive_state[nr].first_read_date + HZ -
678 drive_params[nr].spindown_offset;
679 delta = (( delta * drive_params[nr].rps) % HZ ) /
680 drive_params[nr].rps;
681 motor_off_timer[nr].expires = drive_params[nr].spindown - delta;
682 }
683 add_timer(motor_off_timer+nr);
684 }
685
686
687
688
689
690
691 static void scandrives(void)
692 {
693 int i, drive, saved_drive;
694
695 saved_drive = current_drive % N_DRIVE;
696 for(i=0; i< N_DRIVE; i++){
697 drive = (saved_drive + i + 1 ) % N_DRIVE;
698 if ( UDRS->fd_ref == 0 )
699 continue;
700 set_fdc(drive);
701 if (!(FDCS->dor & (0x10 << UNIT(drive))) ||
702 ((FDCS->dor & 0x3) != UNIT(drive)))
703 UDRS->select_date = jiffies;
704 if(! (set_dor( fdc, ~3, UNIT(drive) | ( 0x10 << UNIT(drive))) &
705 (0x10 << UNIT(drive))))
706
707
708 set_dor( fdc, ~( 0x10 << UNIT(drive) ), 0 );
709 }
710 current_drive = saved_drive;
711 }
712
713 typedef void (*timeout_fn)(unsigned long);
714 static struct timer_list fd_timer ={ NULL, NULL, 0, 0, 0 };
715
716
717
718 static void fd_watchdog(void)
719 {
720 if ( disk_change(current_drive) ){
721 DPRINT("disk removed during i/o\n");
722 floppy_shutdown();
723 } else {
724 del_timer(&fd_timer);
725 fd_timer.function = (timeout_fn) fd_watchdog;
726 fd_timer.expires = 10;
727 add_timer(&fd_timer);
728 }
729 }
730
731 static void main_command_interrupt(void)
732 {
733 del_timer(&fd_timer);
734 cont->interrupt();
735 }
736
737
738 static int wait_for_completion(int nr, int delay, timeout_fn function)
739 {
740 if ( FDCS->reset ){
741 reset_fdc();
742
743
744 return 1;
745 }
746
747 if ( jiffies < delay ){
748 del_timer(&fd_timer);
749 fd_timer.function = function;
750 fd_timer.expires = delay - jiffies;
751 add_timer(&fd_timer);
752 return 1;
753 }
754 return 0;
755 }
756
757 static void setup_DMA(void)
758 {
759 #ifdef SANITY
760 if ((!CURRENT ||
761 CURRENT->buffer != current_addr ||
762 raw_cmd.length > 512 * CURRENT->nr_sectors) &&
763 (current_addr < floppy_track_buffer ||
764 current_addr + raw_cmd.length >
765 floppy_track_buffer + 1024 * max_buffer_sectors)){
766 printk("bad address. start=%p lg=%lx tb=%p\n",
767 current_addr, raw_cmd.length, floppy_track_buffer);
768 if ( CURRENT ){
769 printk("buffer=%p nr=%lx cnr=%lx\n",
770 CURRENT->buffer, CURRENT->nr_sectors,
771 CURRENT->current_nr_sectors);
772 }
773 cont->done(0);
774 FDCS->reset=1;
775 return;
776 }
777 if ((long) current_addr % 512 ){
778 printk("non aligned address: %p\n", current_addr );
779 cont->done(0);
780 FDCS->reset=1;
781 return;
782 }
783 if ( ( (long)current_addr & ~(64*1024-1) ) !=
784 ((long)(current_addr + raw_cmd.length-1) & ~(64*1024-1))){
785 printk("DMA crossing 64-K boundary %p-%p\n",
786 current_addr, current_addr + raw_cmd.length);
787 cont->done(0);
788 FDCS->reset=1;
789 return;
790 }
791
792 #endif
793 cli();
794 disable_dma(FLOPPY_DMA);
795 clear_dma_ff(FLOPPY_DMA);
796 set_dma_mode(FLOPPY_DMA,
797 (raw_cmd.flags & FD_RAW_READ)?
798 DMA_MODE_READ : DMA_MODE_WRITE);
799 set_dma_addr(FLOPPY_DMA, (long) current_addr);
800 set_dma_count(FLOPPY_DMA, raw_cmd.length);
801 enable_dma(FLOPPY_DMA);
802 sti();
803 }
804
805
806 static int output_byte(char byte)
807 {
808 int counter;
809 unsigned char status;
810
811 if (FDCS->reset)
812 return -1;
813 for(counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
814 status = inb_p(FD_STATUS) &(STATUS_READY|STATUS_DIR|STATUS_DMA);
815 if (!(status & STATUS_READY))
816 continue;
817 if (status == STATUS_READY){
818 outb_p(byte,FD_DATA);
819 return 0;
820 } else
821 break;
822 }
823 FDCS->reset = 1;
824 if ( !initialising )
825 DPRINT2("Unable to send byte %x to FDC. Status=%x\n",
826 byte, status);
827 return -1;
828 }
829 #define LAST_OUT(x) if(output_byte(x)){ reset_fdc();return;}
830
831
832 static int result(void)
833 {
834 int i = 0, counter, status;
835
836 if (FDCS->reset)
837 return -1;
838 for (counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
839 status = inb_p(FD_STATUS)&
840 (STATUS_DIR|STATUS_READY|STATUS_BUSY|STATUS_DMA);
841 if (!(status & STATUS_READY))
842 continue;
843 if (status == STATUS_READY)
844 return i;
845 if (status & STATUS_DMA )
846 break;
847 if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {
848 if (i >= MAX_REPLIES) {
849 DPRINT("floppy_stat reply overrun\n");
850 break;
851 }
852 reply_buffer[i++] = inb_p(FD_DATA);
853 }
854 }
855 FDCS->reset = 1;
856 if ( !initialising )
857 DPRINT3("Getstatus times out (%x) on fdc %d [%d]\n",
858 status, fdc, i);
859 return -1;
860 }
861
862
863
864
865 static inline void perpendicular_mode(void)
866 {
867 unsigned char perp_mode;
868
869 if (!floppy)
870 return;
871 if (floppy->rate & 0x40){
872 switch(raw_cmd.rate){
873 case 0:
874 perp_mode=2;
875 break;
876 case 3:
877 perp_mode=3;
878 break;
879 default:
880 DPRINT("Invalid data rate for perpendicular mode!\n");
881 cont->done(0);
882 FDCS->reset = 1;
883
884
885 return;
886 }
887 } else
888 perp_mode = 0;
889
890 if ( FDCS->perp_mode == perp_mode )
891 return;
892 if (FDCS->version >= FDC_82077_ORIG && FDCS->has_fifo) {
893 output_byte(FD_PERPENDICULAR);
894 output_byte(perp_mode);
895 FDCS->perp_mode = perp_mode;
896 } else if (perp_mode) {
897 DPRINT("perpendicular mode not supported by this FDC.\n");
898 }
899 }
900
901 #define NOMINAL_DTR 500
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922 static void fdc_specify(void)
923 {
924 unsigned char spec1, spec2;
925 int srt, hlt, hut;
926 unsigned long dtr = NOMINAL_DTR;
927 unsigned long scale_dtr = NOMINAL_DTR;
928 int hlt_max_code = 0x7f;
929 int hut_max_code = 0xf;
930
931 if (FDCS->need_configure && FDCS->has_fifo) {
932 if ( FDCS->reset )
933 return;
934
935
936 output_byte(FD_CONFIGURE);
937 output_byte(0);
938 output_byte(0x1A);
939 output_byte(0);
940 if ( FDCS->reset ){
941 FDCS->has_fifo=0;
942 return;
943 }
944 FDCS->need_configure = 0;
945
946 }
947
948 switch (raw_cmd.rate & 0x03) {
949 case 3:
950 dtr = 1000;
951 break;
952 case 1:
953 dtr = 300;
954 break;
955 case 2:
956 dtr = 250;
957 break;
958 }
959
960 if (FDCS->version >= FDC_82072) {
961 scale_dtr = dtr;
962 hlt_max_code = 0x00;
963 hut_max_code = 0x0;
964 }
965
966
967 srt = 16 - (DP->srt*scale_dtr/1000 + NOMINAL_DTR - 1)/NOMINAL_DTR;
968 if (srt > 0xf)
969 srt = 0xf;
970 else if (srt < 0)
971 srt = 0;
972
973 hlt = (DP->hlt*scale_dtr/2 + NOMINAL_DTR - 1)/NOMINAL_DTR;
974 if (hlt < 0x01)
975 hlt = 0x01;
976 else if (hlt > 0x7f)
977 hlt = hlt_max_code;
978
979 hut = (DP->hut*scale_dtr/16 + NOMINAL_DTR - 1)/NOMINAL_DTR;
980 if (hut < 0x1)
981 hut = 0x1;
982 else if (hut > 0xf)
983 hut = hut_max_code;
984
985 spec1 = (srt << 4) | hut;
986 spec2 = (hlt << 1);
987
988
989 if (FDCS->spec1 != spec1 || FDCS->spec2 != spec2) {
990
991 output_byte(FD_SPECIFY);
992 output_byte(FDCS->spec1 = spec1);
993 output_byte(FDCS->spec2 = spec2);
994 }
995 }
996
997
998
999
1000
1001 static void fdc_dtr(void)
1002 {
1003
1004 if ( raw_cmd.rate == FDCS->dtr)
1005 return;
1006
1007
1008 outb_p(raw_cmd.rate, FD_DCR);
1009
1010
1011
1012
1013
1014
1015 udelay(5000);
1016 FDCS->dtr = raw_cmd.rate;
1017 }
1018
1019 static void tell_sector(void)
1020 {
1021 printk(": track %d, head %d, sector %d, size %d",
1022 R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
1023 }
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033 static int interpret_errors(void)
1034 {
1035 char bad;
1036
1037 if (inr!=7) {
1038 DPRINT("-- FDC reply error");
1039 FDCS->reset = 1;
1040 return 1;
1041 }
1042
1043
1044 switch ((ST0 & ST0_INTR)>>6) {
1045 case 1:
1046 bad = 1;
1047 if (ST1 & ST1_WP) {
1048 DPRINT("Drive is write protected\n");
1049 DRS->flags &= ~FD_DISK_WRITABLE;
1050 cont->done(0);
1051 bad = 2;
1052 } else if (ST1 & ST1_ND) {
1053 DRS->flags |= FD_NEED_TWADDLE;
1054 } else if (ST1 & ST1_OR) {
1055 if (DP->flags & FTD_MSG )
1056 DPRINT("Over/Underrun - retrying\n");
1057 bad = 0;
1058 }else if(*errors >= DP->max_errors.reporting){
1059 DPRINT("");
1060 if (ST0 & ST0_ECE) {
1061 printk("Recalibrate failed!");
1062 } else if (ST2 & ST2_CRC) {
1063 printk("data CRC error");
1064 tell_sector();
1065 } else if (ST1 & ST1_CRC) {
1066 printk("CRC error");
1067 tell_sector();
1068 } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
1069 if (!probing) {
1070 printk("sector not found");
1071 tell_sector();
1072 } else
1073 printk("probe failed...");
1074 } else if (ST2 & ST2_WC) {
1075 printk("wrong cylinder");
1076 } else if (ST2 & ST2_BC) {
1077 printk("bad cylinder");
1078 } else {
1079 printk("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", ST0, ST1, ST2);
1080 tell_sector();
1081 }
1082 printk("\n");
1083
1084 }
1085 if ( ST2 & ST2_WC || ST2 & ST2_BC)
1086
1087 DRS->track = NEED_2_RECAL;
1088 return bad;
1089 case 2:
1090 DPRINT("Invalid FDC command given!\n");
1091 cont->done(0);
1092 return 2;
1093 case 3:
1094 DPRINT("Abnormal termination caused by polling\n");
1095 cont->error();
1096 return 2;
1097 default:
1098 return 0;
1099 }
1100 }
1101
1102
1103
1104
1105
1106
1107 static void setup_rw_floppy(void)
1108 {
1109 int i,ready_date,r, flags,dflags;
1110 timeout_fn function;
1111
1112 flags = raw_cmd.flags;
1113 if ( flags & ( FD_RAW_READ | FD_RAW_WRITE))
1114 flags |= FD_RAW_INTR;
1115
1116 if ((flags & FD_RAW_SPIN) && !(flags & FD_RAW_NO_MOTOR)){
1117 ready_date = DRS->spinup_date + DP->spinup;
1118
1119
1120
1121
1122 if ( ready_date > jiffies + DP->select_delay){
1123 ready_date -= DP->select_delay;
1124 function = (timeout_fn) floppy_start;
1125 } else
1126 function = (timeout_fn) setup_rw_floppy;
1127
1128
1129 if (wait_for_completion(current_drive,ready_date,function))
1130 return;
1131 }
1132 dflags = DRS->flags;
1133
1134 if ( (flags & FD_RAW_READ) || (flags & FD_RAW_WRITE))
1135 setup_DMA();
1136
1137 if ( flags & FD_RAW_INTR )
1138 SET_INTR(main_command_interrupt);
1139
1140 r=0;
1141 for(i=0; i< raw_cmd.cmd_count; i++)
1142 r|=output_byte( raw_cmd.cmd[i] );
1143
1144 #ifdef DEBUGT
1145 debugt("rw_command: ");
1146 #endif
1147 if ( r ){
1148 reset_fdc();
1149 return;
1150 }
1151
1152 if ( ! ( flags & FD_RAW_INTR )){
1153 inr = result();
1154 cont->interrupt();
1155 } else if ( flags & FD_RAW_NEED_DISK )
1156 fd_watchdog();
1157 }
1158
1159 #ifdef SILENT_DC_CLEAR
1160 static int blind_seek;
1161 #endif
1162
1163
1164
1165
1166
1167 static void seek_interrupt(void)
1168 {
1169 #ifdef DEBUGT
1170 debugt("seek interrupt:");
1171 #endif
1172 #ifdef SILENT_DC_CLEAR
1173 set_dor(fdc, ~0, (0x10 << UNIT(current_drive)));
1174 #endif
1175 if (inr != 2 || (ST0 & 0xF8) != 0x20 ) {
1176 DPRINT("seek failed\n");
1177 DRS->track = NEED_2_RECAL;
1178 cont->error();
1179 cont->redo();
1180 return;
1181 }
1182 if (DRS->track >= 0 && DRS->track != ST1
1183 #ifdef SILENT_DC_CLEAR
1184 && !blind_seek
1185 #endif
1186 )
1187 DRS->flags &= ~FD_DISK_NEWCHANGE;
1188 DRS->track = ST1;
1189 DRS->select_date = jiffies;
1190 seek_floppy();
1191 }
1192
1193 static void check_wp(void)
1194 {
1195 if (DRS->flags & FD_VERIFY) {
1196
1197 output_byte( FD_GETSTATUS );
1198 output_byte( UNIT(current_drive) );
1199 if ( result() != 1 ){
1200 FDCS->reset = 1;
1201 return;
1202 }
1203 DRS->flags &= ~(FD_VERIFY | FD_DISK_WRITABLE | FD_NEED_TWADDLE);
1204
1205 if (!( ST3 & 0x40))
1206 DRS->flags |= FD_DISK_WRITABLE;
1207 }
1208 }
1209
1210 static void seek_floppy(void)
1211 {
1212 int track;
1213
1214 #ifdef SILENT_DC_CLEAR
1215 blind_seek=0;
1216 #endif
1217 disk_change(current_drive);
1218 if ((raw_cmd.flags & FD_RAW_NEED_DISK) &&
1219 test_bit(current_drive,&changed_floppies)){
1220
1221
1222
1223
1224 cont->done(0);
1225 cont->redo();
1226 return;
1227 }
1228 if ( DRS->track <= NEED_1_RECAL ){
1229 recalibrate_floppy();
1230 return;
1231 } else if ((DRS->flags & FD_DISK_NEWCHANGE) &&
1232 (raw_cmd.flags & FD_RAW_NEED_DISK) &&
1233 (DRS->track <= NO_TRACK || DRS->track == raw_cmd.track)) {
1234
1235
1236 if ( raw_cmd.track )
1237 track = raw_cmd.track - 1;
1238 else {
1239 #ifdef SILENT_DC_CLEAR
1240 set_dor(fdc, ~ (0x10 << UNIT(current_drive)), 0);
1241 blind_seek = 1;
1242 #endif
1243 track = 1;
1244 }
1245 } else {
1246 check_wp();
1247 if (raw_cmd.track != DRS->track)
1248 track = raw_cmd.track;
1249 else {
1250 setup_rw_floppy();
1251 return;
1252 }
1253 }
1254
1255 #ifndef SILENT_DC_CLEAR
1256 if ( !track && DRS->track >= 0 && DRS->track < 80 ){
1257 DRS->flags &= ~FD_DISK_NEWCHANGE;
1258
1259
1260 recalibrate_floppy();
1261 } else
1262 #endif
1263 {
1264 SET_INTR(seek_interrupt);
1265 output_byte(FD_SEEK);
1266 output_byte(UNIT(current_drive));
1267 LAST_OUT(track);
1268 #ifdef DEBUGT
1269 debugt("seek command:");
1270 #endif
1271 }
1272 }
1273
1274 static void recal_interrupt(void)
1275 {
1276 #ifdef DEBUGT
1277 debugt("recal interrupt:");
1278 #endif
1279 if (inr !=2 )
1280 FDCS->reset = 1;
1281 else if (ST0 & ST0_ECE) {
1282 switch(DRS->track){
1283 case PROVEN_ABSENT:
1284 #ifdef DEBUGT
1285 debugt("recal interrupt proven absent:");
1286 #endif
1287
1288 case NEED_1_RECAL:
1289 #ifdef DEBUGT
1290 debugt("recal interrupt need 1 recal:");
1291 #endif
1292
1293
1294
1295
1296 cont->error();
1297 cont->redo();
1298 return;
1299 case NEED_2_RECAL:
1300 #ifdef DEBUGT
1301 debugt("recal interrupt need 2 recal:");
1302 #endif
1303
1304
1305
1306
1307
1308 DRS->flags &= ~FD_DISK_NEWCHANGE;
1309
1310 default:
1311 #ifdef DEBUGT
1312 debugt("recal interrupt default:");
1313 #endif
1314
1315
1316
1317
1318
1319 DRS->track = NEED_1_RECAL;
1320 break;
1321 }
1322 } else
1323 DRS->track = ST1;
1324 seek_floppy();
1325 }
1326
1327
1328
1329
1330
1331 static void unexpected_floppy_interrupt(void)
1332 {
1333 int i;
1334 if ( initialising )
1335 return;
1336 DPRINT("unexpected interrupt\n");
1337 if ( inr >= 0 )
1338 for(i=0; i<inr; i++)
1339 printk("%d %x\n", i, reply_buffer[i] );
1340 while(1){
1341 output_byte(FD_SENSEI);
1342 inr=result();
1343 if ( inr != 2 )
1344 break;
1345 printk("sensei\n");
1346 for(i=0; i<inr; i++)
1347 printk("%d %x\n", i, reply_buffer[i] );
1348 }
1349 FDCS->reset = 1;
1350 }
1351
1352 struct tq_struct floppy_tq =
1353 { 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
1354
1355
1356 static void floppy_interrupt(int unused)
1357 {
1358 void (*handler)(void) = DEVICE_INTR;
1359
1360 CLEAR_INTR;
1361 if ( fdc >= N_FDC ){
1362 printk("floppy interrupt on bizarre fdc\n");
1363 return;
1364 }
1365 inr = result();
1366 if (!handler){
1367 unexpected_floppy_interrupt();
1368 return;
1369 }
1370 if ( inr == 0 ){
1371 do {
1372 output_byte(FD_SENSEI);
1373 inr = result();
1374 } while ( (ST0 & 0x83) != UNIT(current_drive) && inr == 2);
1375 }
1376 floppy_tq.routine = (void *)(void *) handler;
1377 queue_task_irq(&floppy_tq, &tq_timer);
1378 }
1379
1380 static void recalibrate_floppy(void)
1381 {
1382 #ifdef DEBUGT
1383 debugt("recalibrate floppy:");
1384 #endif
1385 SET_INTR(recal_interrupt);
1386 output_byte(FD_RECALIBRATE);
1387 LAST_OUT(UNIT(current_drive));
1388 }
1389
1390
1391
1392
1393 static void reset_interrupt(void)
1394 {
1395 #ifdef DEBUGT
1396 debugt("reset interrupt:");
1397 #endif
1398 fdc_specify();
1399 result();
1400 if ( FDCS->reset )
1401 cont->error();
1402 cont->redo();
1403 }
1404
1405
1406
1407
1408
1409 static void reset_fdc(void)
1410 {
1411 SET_INTR(reset_interrupt);
1412 FDCS->reset = 0;
1413 reset_fdc_info(0);
1414 if ( FDCS->version >= FDC_82077 )
1415 outb_p(0x80 | ( FDCS->dtr &3), FD_STATUS);
1416 else {
1417 outb_p(FDCS->dor & ~0x04, FD_DOR);
1418 udelay(FD_RESET_DELAY);
1419 outb(FDCS->dor, FD_DOR);
1420 }
1421 }
1422
1423 static void empty(void)
1424 {
1425 }
1426
1427 void show_floppy(void)
1428 {
1429 int i;
1430
1431 printk("\n");
1432 printk("floppy driver state\n");
1433 printk("-------------------\n");
1434 for(i=0; i<N_FDC; i++){
1435 printk("dor %d = %x\n", i, fdc_state[i].dor );
1436 outb_p(fdc_state[i].address+2, fdc_state[i].dor);
1437 udelay(1000);
1438 }
1439 printk("status=%x\n", inb_p(FD_STATUS));
1440 printk("fdc_busy=%d\n", fdc_busy);
1441 if( DEVICE_INTR)
1442 printk("DEVICE_INTR=%p\n", DEVICE_INTR);
1443 if(floppy_tq.sync)
1444 printk("floppy_tq.routine=%p\n", floppy_tq.routine);
1445 if(fd_timer.prev)
1446 printk("fd_timer.function=%p\n", fd_timer.function);
1447 if( timer_active & (1 << FLOPPY_TIMER)){
1448 printk("timer_table=%p\n",timer_table[FLOPPY_TIMER].fn);
1449 printk("expires=%ld\n",timer_table[FLOPPY_TIMER].expires);
1450 printk("now=%ld\n",jiffies);
1451 }
1452 printk("cont=%p\n", cont);
1453 printk("CURRENT=%p\n", CURRENT);
1454 printk("command_status=%d\n", command_status);
1455 printk("\n");
1456 }
1457
1458 static void floppy_shutdown(void)
1459 {
1460 CLEAR_INTR;
1461 floppy_tq.routine = (void *)(void *) empty;
1462 del_timer( &fd_timer);
1463
1464 disable_dma(FLOPPY_DMA);
1465
1466
1467 if(!initialising)
1468 DPRINT("floppy timeout\n");
1469 FDCS->reset = 1;
1470 cont->done(0);
1471 cont->redo();
1472 }
1473
1474
1475 static void start_motor(void)
1476 {
1477 int mask, data;
1478
1479 mask = 0xfc;
1480 data = UNIT(current_drive);
1481 if ( (FDCS->dor & 0x03) != UNIT(current_drive) ||
1482 !(FDCS->dor & ( 0x10 << UNIT(current_drive) ) ))
1483
1484 DRS->select_date = jiffies;
1485
1486 if (!(raw_cmd.flags & FD_RAW_NO_MOTOR)){
1487 if(!(FDCS->dor & ( 0x10 << UNIT(current_drive) ) )){
1488 set_debugt();
1489
1490 DRS->first_read_date = 0;
1491
1492 DRS->spinup_date = jiffies;
1493 data |= (0x10 << UNIT(current_drive));
1494 }
1495 } else
1496 if (FDCS->dor & ( 0x10 << UNIT(current_drive) ) )
1497 mask &= ~(0x10 << UNIT(current_drive));
1498
1499
1500 del_timer(motor_off_timer + current_drive);
1501 set_dor( fdc, mask, data);
1502 if( raw_cmd.flags & FD_RAW_NO_MOTOR)
1503 return;
1504
1505 disk_change(current_drive);
1506
1507 return;
1508 }
1509
1510 static void floppy_ready(void)
1511 {
1512 CHECK_RESET;
1513 start_motor();
1514
1515
1516 if(wait_for_completion(current_drive,
1517 DRS->select_date+DP->select_delay,
1518 (timeout_fn) floppy_ready))
1519 return;
1520 fdc_dtr();
1521 if ( raw_cmd.flags & FD_RAW_NEED_SEEK ){
1522 perpendicular_mode();
1523 fdc_specify();
1524 seek_floppy();
1525 } else
1526 setup_rw_floppy();
1527 }
1528
1529 static void floppy_start(void)
1530 {
1531 timer_table[FLOPPY_TIMER].expires = jiffies + DP->timeout;
1532 timer_active |= 1 << FLOPPY_TIMER;
1533 scandrives();
1534 floppy_ready();
1535 }
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551 static void do_wakeup(void)
1552 {
1553 timer_active &= ~(1 << FLOPPY_TIMER);
1554 cont = 0;
1555 command_status += 2;
1556 wake_up(&command_done);
1557 }
1558
1559 static struct cont_t wakeup_cont={
1560 empty,
1561 do_wakeup,
1562 empty,
1563 (done_f)empty
1564 };
1565
1566 static int wait_til_done( void (*handler)(void ), int interruptible )
1567 {
1568 int ret;
1569
1570 floppy_tq.routine = (void *)(void *) handler;
1571 queue_task(&floppy_tq, &tq_timer);
1572
1573 cli();
1574 while(command_status < 2 && NO_SIGNAL)
1575 if (current->pid)
1576 interruptible_sleep_on(&command_done);
1577 else {
1578 sti();
1579 run_task_queue(&tq_timer);
1580 cli();
1581 }
1582 if(command_status < 2){
1583 sti();
1584 floppy_shutdown();
1585 redo_fd_request();
1586 return -EINTR;
1587 }
1588 sti();
1589
1590 if ( FDCS->reset )
1591 command_status = FD_COMMAND_ERROR;
1592 if ( command_status == FD_COMMAND_OKAY )
1593 ret=0;
1594 else
1595 ret=-EIO;
1596 command_status = FD_COMMAND_NONE;
1597 return ret;
1598 }
1599
1600 static void generic_done(int result)
1601 {
1602 command_status = result;
1603 cont = &wakeup_cont;
1604 }
1605
1606 static void generic_success(void)
1607 {
1608 generic_done(1);
1609 }
1610
1611 static void generic_failure(void)
1612 {
1613 generic_done(0);
1614 }
1615
1616 static void success_and_wakeup(void)
1617 {
1618 generic_success();
1619 do_wakeup();
1620 }
1621
1622 static void failure_and_wakeup(void)
1623 {
1624 generic_failure();
1625 do_wakeup();
1626 }
1627
1628
1629
1630
1631
1632
1633 static int next_valid_format(void)
1634 {
1635 int probed_format;
1636 while(1){
1637 probed_format = DRS->probed_format;
1638 if ( probed_format > N_DRIVE ||
1639 ! DP->autodetect[probed_format] ){
1640 DRS->probed_format = 0;
1641 return 1;
1642 }
1643 if ( floppy_type[DP->autodetect[probed_format]].sect ){
1644 DRS->probed_format = probed_format;
1645 return 0;
1646 }
1647 probed_format++;
1648 }
1649 }
1650
1651 static void bad_flp_intr(void)
1652 {
1653 if ( probing ){
1654 DRS->probed_format++;
1655 if ( !next_valid_format())
1656 return;
1657 }
1658 (*errors)++;
1659 if (*errors > DRWE->badness)
1660 DRWE->badness = *errors;
1661 if (*errors > DP->max_errors.abort)
1662 cont->done(0);
1663 if (*errors > DP->max_errors.reset)
1664 FDCS->reset = 1;
1665 else if (*errors > DP->max_errors.recal)
1666 DRS->track = NEED_2_RECAL;
1667 }
1668
1669 static void set_floppy(int device)
1670 {
1671 if (TYPE(device))
1672 floppy = TYPE(device) + floppy_type;
1673 else
1674 floppy = current_type[ DRIVE(device) ];
1675 }
1676
1677
1678
1679
1680
1681 static void format_interrupt(void)
1682 {
1683 switch (interpret_errors()){
1684 case 1:
1685 cont->error();
1686 case 2:
1687 break;
1688 case 0:
1689 cont->done(1);
1690 }
1691 cont->redo();
1692 }
1693
1694 #define CODE2SIZE (ssize = ( ( 1 << SIZECODE ) + 3 ) >> 2)
1695 #define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80 ) >>1))
1696 #define CT(x) ( (x) | 0x40 )
1697 static void setup_format_params(void)
1698 {
1699 struct fparm {
1700 unsigned char track,head,sect,size;
1701 } *here = (struct fparm *)floppy_track_buffer;
1702 int il,n;
1703 int count,head_shift,track_shift;
1704
1705 raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
1706 FD_RAW_NEED_SEEK;
1707 raw_cmd.rate = floppy->rate & 0x3;
1708 raw_cmd.cmd_count = NR_F;
1709 COMMAND = FM_MODE(floppy,FD_FORMAT);
1710 DR_SELECT = UNIT(current_drive) + ( format_req.head << 2 );
1711 F_SIZECODE = FD_SIZECODE(floppy);
1712 F_SECT_PER_TRACK = floppy->sect << 2 >> F_SIZECODE;
1713 F_GAP = floppy->fmt_gap;
1714 F_FILL = FD_FILL_BYTE;
1715
1716 current_addr = floppy_track_buffer;
1717 raw_cmd.length = 4 * F_SECT_PER_TRACK;
1718
1719
1720 head_shift = (F_SECT_PER_TRACK + 5) / 6;
1721
1722
1723 track_shift = 2 * head_shift + 1;
1724
1725
1726 n = (track_shift * format_req.track + head_shift * format_req.head )
1727 % F_SECT_PER_TRACK;
1728
1729
1730 il = 1;
1731 if (floppy->sect > DP->interleave_sect && F_SIZECODE == 2)
1732 il++;
1733
1734
1735 for (count = 0; count < F_SECT_PER_TRACK; ++count) {
1736 here[count].track = format_req.track;
1737 here[count].head = format_req.head;
1738 here[count].sect = 0;
1739 here[count].size = F_SIZECODE;
1740 }
1741
1742 for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
1743 here[n].sect = count;
1744 n = (n+il) % F_SECT_PER_TRACK;
1745 if (here[n].sect) {
1746 ++n;
1747 if (n>= F_SECT_PER_TRACK) {
1748 n-=F_SECT_PER_TRACK;
1749 while (here[n].sect) ++n;
1750 }
1751 }
1752 }
1753 }
1754
1755 static void redo_format(void)
1756 {
1757 raw_cmd.track = format_req.track << floppy->stretch;
1758 buffer_track = -1;
1759 setup_format_params();
1760 clear_bit(current_drive, &changed_floppies);
1761 floppy_start();
1762 #ifdef DEBUGT
1763 debugt("queue format request");
1764 #endif
1765 }
1766
1767 static struct cont_t format_cont={
1768 format_interrupt,
1769 redo_format,
1770 bad_flp_intr,
1771 generic_done };
1772
1773 static int do_format(int device, struct format_descr *tmp_format_req)
1774 {
1775 int okay;
1776
1777 LOCK_FDC(DRIVE(device),1);
1778 set_floppy(device);
1779 if (!floppy ||
1780 tmp_format_req->track >= floppy->track ||
1781 tmp_format_req->head >= floppy->head){
1782 redo_fd_request();
1783 return -EINVAL;
1784 }
1785 format_req = *tmp_format_req;
1786 format_errors = 0;
1787 cont = &format_cont;
1788 errors = &format_errors;
1789 CALL(okay=wait_til_done(redo_format,1));
1790 redo_fd_request();
1791 return okay;
1792 }
1793
1794
1795
1796
1797
1798
1799
1800
1801 static void request_done(int uptodate)
1802 {
1803 int block;
1804
1805 probing = 0;
1806 timer_active &= ~(1 << FLOPPY_TIMER);
1807
1808 if (!CURRENT){
1809 DPRINT("request list destroyed in floppy request done\n");
1810 return;
1811 }
1812 if (uptodate){
1813
1814
1815 block = current_count_sectors + CURRENT->sector;
1816 if (block > DRS->maxblock)
1817 DRS->maxblock=block;
1818 if ( block > floppy->sect)
1819 DRS->maxtrack = 1;
1820
1821
1822 while (current_count_sectors && CURRENT &&
1823 current_count_sectors >= CURRENT->current_nr_sectors ){
1824 current_count_sectors -= CURRENT->current_nr_sectors;
1825 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
1826 CURRENT->sector += CURRENT->current_nr_sectors;
1827 end_request(1);
1828 }
1829 if ( current_count_sectors && CURRENT){
1830
1831 CURRENT->buffer += current_count_sectors <<9;
1832 CURRENT->current_nr_sectors -= current_count_sectors;
1833 CURRENT->nr_sectors -= current_count_sectors;
1834 CURRENT->sector += current_count_sectors;
1835 return;
1836 }
1837
1838 if ( current_count_sectors && ! CURRENT )
1839 DPRINT("request list destroyed in floppy request done\n");
1840
1841 } else {
1842 if(CURRENT->cmd == WRITE) {
1843
1844 DRWE->write_errors++;
1845 if(DRWE->write_errors == 1) {
1846 DRWE->first_error_sector = CURRENT->sector;
1847 DRWE->first_error_generation = DRS->generation;
1848 }
1849 DRWE->last_error_sector = CURRENT->sector;
1850 DRWE->last_error_generation = DRS->generation;
1851 }
1852 end_request(0);
1853 }
1854 }
1855
1856
1857 static void rw_interrupt(void)
1858 {
1859 int nr_sectors, ssize;
1860
1861 if ( ! DRS->first_read_date )
1862 DRS->first_read_date = jiffies;
1863
1864 nr_sectors = 0;
1865 CODE2SIZE;
1866 nr_sectors = ((R_TRACK-TRACK)*floppy->head+R_HEAD-HEAD) *
1867 floppy->sect + ((R_SECTOR-SECTOR) << SIZECODE >> 2) -
1868 (sector_t % floppy->sect) % ssize;
1869
1870 #ifdef SANITY
1871 if ( nr_sectors > current_count_sectors + ssize -
1872 (current_count_sectors + sector_t) % ssize +
1873 sector_t % ssize){
1874 DPRINT2("long rw: %x instead of %lx\n",
1875 nr_sectors, current_count_sectors);
1876 printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
1877 printk("rh=%d h=%d\n", R_HEAD, HEAD);
1878 printk("rt=%d t=%d\n", R_TRACK, TRACK);
1879 printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
1880 sector_t, ssize);
1881 }
1882 #endif
1883 if ( nr_sectors < 0 )
1884 nr_sectors = 0;
1885 if ( nr_sectors < current_count_sectors )
1886 current_count_sectors = nr_sectors;
1887
1888 switch (interpret_errors()){
1889 case 2:
1890 cont->redo();
1891 return;
1892 case 1:
1893 if ( !current_count_sectors){
1894 cont->error();
1895 cont->redo();
1896 return;
1897 }
1898 break;
1899 case 0:
1900 if ( !current_count_sectors){
1901 cont->redo();
1902 return;
1903 }
1904 current_type[current_drive] = floppy;
1905 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
1906 floppy->size >> 1;
1907 break;
1908 }
1909
1910 if (probing) {
1911 if (DP->flags & FTD_MSG)
1912 DPRINT2("Auto-detected floppy type %s in fd%d\n",
1913 floppy->name,current_drive);
1914 current_type[current_drive] = floppy;
1915 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
1916 floppy->size >> 1;
1917 probing = 0;
1918 }
1919
1920 if ( CT(COMMAND) != FD_READ || current_addr == CURRENT->buffer ){
1921
1922 cont->done(1);
1923 } else if ( CT(COMMAND) == FD_READ){
1924 buffer_track = raw_cmd.track;
1925 buffer_drive = current_drive;
1926 if ( nr_sectors + sector_t > buffer_max )
1927 buffer_max = nr_sectors + sector_t;
1928 }
1929 cont->redo();
1930 }
1931
1932
1933 static int buffer_chain_size(void)
1934 {
1935 struct buffer_head *bh;
1936 int size;
1937 char *base;
1938
1939 base = CURRENT->buffer;
1940 size = CURRENT->current_nr_sectors << 9;
1941 bh = CURRENT->bh;
1942
1943 if(bh){
1944 bh = bh->b_reqnext;
1945 while ( bh && bh->b_data == base + size ){
1946 size += bh->b_size;
1947 bh = bh->b_reqnext;
1948 }
1949 }
1950 return size >> 9;
1951 }
1952
1953
1954 static int transfer_size(int ssize, int max_sector, int max_size)
1955 {
1956 if ( max_sector > sector_t + max_size)
1957 max_sector = sector_t + max_size;
1958
1959
1960 max_sector -= (max_sector % floppy->sect ) % ssize;
1961
1962
1963 current_count_sectors = max_sector - sector_t ;
1964
1965 return max_sector;
1966 }
1967
1968
1969
1970
1971 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
1972 {
1973 int remaining;
1974 struct buffer_head *bh;
1975 char *buffer, *dma_buffer;
1976 int size;
1977
1978 if ( max_sector > max_sector_2 )
1979 max_sector = max_sector_2;
1980
1981 max_sector = transfer_size(ssize, max_sector, CURRENT->nr_sectors);
1982
1983 if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
1984 buffer_max > sector_t + CURRENT->nr_sectors){
1985 current_count_sectors = buffer_max - sector_t;
1986 if ( current_count_sectors > CURRENT->nr_sectors )
1987 current_count_sectors = CURRENT->nr_sectors;
1988 }
1989 remaining = current_count_sectors << 9;
1990 #ifdef SANITY
1991 if ((remaining >> 9) > CURRENT->nr_sectors &&
1992 CT(COMMAND) == FD_WRITE ){
1993 DPRINT("in copy buffer\n");
1994 printk("current_count_sectors=%ld\n", current_count_sectors);
1995 printk("remaining=%d\n", remaining >> 9);
1996 printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
1997 printk("CURRENT->current_nr_sectors=%ld\n",
1998 CURRENT->current_nr_sectors);
1999 printk("max_sector=%d\n", max_sector);
2000 printk("ssize=%d\n", ssize);
2001 }
2002 #endif
2003
2004 if ( max_sector > buffer_max )
2005 buffer_max = max_sector;
2006
2007 dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
2008
2009 bh = CURRENT->bh;
2010 size = CURRENT->current_nr_sectors << 9;
2011 buffer = CURRENT->buffer;
2012
2013 while ( remaining > 0){
2014 if ( size > remaining )
2015 size = remaining;
2016 #ifdef SANITY
2017 if (dma_buffer + size >
2018 floppy_track_buffer + (max_buffer_sectors << 10) ||
2019 dma_buffer < floppy_track_buffer ){
2020 DPRINT1("buffer overrun in copy buffer %d\n",
2021 (floppy_track_buffer - dma_buffer) >>9);
2022 printk("sector_t=%d buffer_min=%d\n",
2023 sector_t, buffer_min);
2024 printk("current_count_sectors=%ld\n",
2025 current_count_sectors);
2026 if ( CT(COMMAND) == FD_READ )
2027 printk("read\n");
2028 if ( CT(COMMAND) == FD_READ )
2029 printk("write\n");
2030 break;
2031 }
2032 if ( ((int)buffer) % 512 )
2033 DPRINT1("%p buffer not aligned\n", buffer);
2034 #endif
2035 if ( CT(COMMAND) == FD_READ )
2036 memcpy( buffer, dma_buffer, size);
2037 else
2038 memcpy( dma_buffer, buffer, size);
2039 remaining -= size;
2040 if ( !remaining)
2041 break;
2042
2043 dma_buffer += size;
2044 bh = bh->b_reqnext;
2045 #ifdef SANITY
2046 if ( !bh){
2047 DPRINT("bh=null in copy buffer after copy\n");
2048 break;
2049 }
2050 #endif
2051 size = bh->b_size;
2052 buffer = bh->b_data;
2053 }
2054 #ifdef SANITY
2055 if ( remaining ){
2056 if ( remaining > 0 )
2057 max_sector -= remaining >> 9;
2058 DPRINT1("weirdness: remaining %d\n", remaining>>9);
2059 }
2060 #endif
2061 }
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073 static int make_raw_rw_request(void)
2074 {
2075 int aligned_sector_t;
2076 int max_sector, max_size, tracksize, ssize;
2077
2078 current_drive = DRIVE(CURRENT->dev);
2079
2080 raw_cmd.flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
2081 FD_RAW_NEED_SEEK;
2082 raw_cmd.cmd_count = NR_RW;
2083 if (CURRENT->cmd == READ){
2084 raw_cmd.flags |= FD_RAW_READ;
2085 COMMAND = FM_MODE(floppy,FD_READ);
2086 } else if (CURRENT->cmd == WRITE){
2087 raw_cmd.flags |= FD_RAW_WRITE;
2088 COMMAND = FM_MODE(floppy,FD_WRITE);
2089 } else {
2090 DPRINT("make_raw_rw_request: unknown command\n");
2091 return 0;
2092 }
2093
2094 max_sector = floppy->sect * floppy->head;
2095 TRACK = CURRENT->sector / max_sector;
2096 sector_t = CURRENT->sector % max_sector;
2097 if ( floppy->track && TRACK >= floppy->track )
2098 return 0;
2099 HEAD = sector_t / floppy->sect;
2100
2101 if ( (DRS->flags & FD_NEED_TWADDLE) && sector_t < floppy->sect )
2102 max_sector = floppy->sect;
2103
2104
2105 if ( (floppy->rate & FD_2M ) && (!TRACK) && (!HEAD)){
2106 max_sector = 2 * floppy->sect / 3;
2107 if (sector_t >= max_sector){
2108 current_count_sectors = (floppy->sect - sector_t);
2109 if ( current_count_sectors > CURRENT->nr_sectors )
2110 current_count_sectors = CURRENT->nr_sectors;
2111 return 1;
2112 }
2113 SIZECODE = 2;
2114 } else
2115 SIZECODE = FD_SIZECODE(floppy);
2116 raw_cmd.rate = floppy->rate & 3;
2117 if ((floppy->rate & FD_2M) &&
2118 (TRACK || HEAD ) &&
2119 raw_cmd.rate == 2)
2120 raw_cmd.rate = 1;
2121
2122 if ( SIZECODE )
2123 SIZECODE2 = 0xff;
2124 else
2125 SIZECODE2 = 0x80;
2126 raw_cmd.track = TRACK << floppy->stretch;
2127 DR_SELECT = UNIT(current_drive) + ( HEAD << 2 );
2128 GAP = floppy->gap;
2129 CODE2SIZE;
2130 SECT_PER_TRACK = floppy->sect << 2 >> SIZECODE;
2131 SECTOR = ((sector_t % floppy->sect) << 2 >> SIZECODE) + 1;
2132 tracksize = floppy->sect - floppy->sect % ssize;
2133 if ( tracksize < floppy->sect ){
2134 SECT_PER_TRACK ++;
2135 if ( tracksize <= sector_t % floppy->sect)
2136 SECTOR--;
2137 while ( tracksize <= sector_t % floppy->sect){
2138 while( tracksize + ssize > floppy->sect ){
2139 SIZECODE--;
2140 ssize >>= 1;
2141 }
2142 SECTOR++; SECT_PER_TRACK ++;
2143 tracksize += ssize;
2144 }
2145 max_sector = HEAD * floppy->sect + tracksize;
2146 } else if ( !TRACK && !HEAD && !( floppy->rate & FD_2M ) && probing)
2147 max_sector = floppy->sect;
2148
2149 aligned_sector_t = sector_t - ( sector_t % floppy->sect ) % ssize;
2150 max_size = CURRENT->nr_sectors;
2151 if ((raw_cmd.track == buffer_track) && (current_drive == buffer_drive) &&
2152 (sector_t >= buffer_min) && (sector_t < buffer_max)) {
2153
2154 if (CT(COMMAND) == FD_READ) {
2155 copy_buffer(1, max_sector, buffer_max);
2156 return 1;
2157 }
2158 } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
2159 if (CT(COMMAND) == FD_WRITE){
2160 if(sector_t + CURRENT->nr_sectors > ssize &&
2161 sector_t + CURRENT->nr_sectors < ssize + ssize)
2162 max_size = ssize + ssize;
2163 else
2164 max_size = ssize;
2165 }
2166 raw_cmd.flags &= ~FD_RAW_WRITE;
2167 raw_cmd.flags |= FD_RAW_READ;
2168 COMMAND = FM_MODE(floppy,FD_READ);
2169 } else if ((long)CURRENT->buffer <= LAST_DMA_ADDR ) {
2170 int direct, indirect;
2171
2172 indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
2173 sector_t;
2174
2175 max_size = buffer_chain_size();
2176 if ( max_size > ( LAST_DMA_ADDR - ((long) CURRENT->buffer))>>9)
2177 max_size=(LAST_DMA_ADDR - ((long)CURRENT->buffer))>>9;
2178
2179 if ( ((max_size << 9) + ((long) CURRENT->buffer)) / K_64 !=
2180 ((long) CURRENT->buffer ) / K_64 )
2181 max_size = ( K_64 - ((long) CURRENT->buffer) % K_64)>>9;
2182 direct = transfer_size(ssize,max_sector,max_size) - sector_t;
2183
2184
2185
2186
2187
2188
2189
2190 if ((indirect - sector_t) * 2 > (direct - sector_t) * 3 &&
2191 *errors < DP->max_errors.read_track &&
2192
2193 ( ( !probing || (DP->read_track &
2194 (1 <<DRS->probed_format))))){
2195 max_size = CURRENT->nr_sectors;
2196 } else {
2197 current_addr = CURRENT->buffer;
2198 raw_cmd.length = current_count_sectors << 9;
2199 return 2;
2200 }
2201 }
2202
2203 if ( CT(COMMAND) == FD_READ )
2204 max_size = max_sector;
2205
2206
2207 if (buffer_track != raw_cmd.track ||
2208 buffer_drive !=current_drive ||
2209 sector_t < buffer_min ||
2210 ((CT(COMMAND) == FD_READ ||
2211 (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize ))&&
2212 max_sector > 2 * max_buffer_sectors + buffer_min &&
2213 max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
2214 ){
2215 buffer_track = -1;
2216 buffer_drive = current_drive;
2217 buffer_max = buffer_min = aligned_sector_t;
2218 }
2219 current_addr = floppy_track_buffer +((aligned_sector_t-buffer_min )<<9);
2220
2221 if ( CT(COMMAND) == FD_WRITE ){
2222
2223
2224
2225
2226 #ifdef SANITY
2227 if (sector_t != aligned_sector_t && buffer_track == -1 )
2228 DPRINT("internal error offset !=0 on write\n");
2229 #endif
2230 buffer_track = raw_cmd.track;
2231 buffer_drive = current_drive;
2232 copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min);
2233 } else
2234 transfer_size(ssize, max_sector,
2235 2*max_buffer_sectors+buffer_min-aligned_sector_t);
2236
2237
2238 raw_cmd.length = sector_t+current_count_sectors-aligned_sector_t;
2239 raw_cmd.length = ((raw_cmd.length -1)|(ssize-1))+1;
2240 raw_cmd.length <<= 9;
2241 #ifdef SANITY
2242 if ((raw_cmd.length < current_count_sectors << 9) ||
2243 (current_addr != CURRENT->buffer &&
2244 CT(COMMAND) == FD_WRITE &&
2245 (aligned_sector_t + (raw_cmd.length >> 9) > buffer_max ||
2246 aligned_sector_t < buffer_min )) ||
2247 raw_cmd.length % ( 128 << SIZECODE ) ||
2248 raw_cmd.length <= 0 || current_count_sectors <= 0){
2249 DPRINT2("fractionary current count b=%lx s=%lx\n",
2250 raw_cmd.length, current_count_sectors);
2251 if ( current_addr != CURRENT->buffer )
2252 printk("addr=%d, length=%ld\n",
2253 (current_addr - floppy_track_buffer ) >> 9,
2254 current_count_sectors);
2255 printk("st=%d ast=%d mse=%d msi=%d\n",
2256 sector_t, aligned_sector_t, max_sector, max_size);
2257 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2258 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2259 COMMAND, SECTOR, HEAD, TRACK);
2260 printk("buffer drive=%d\n", buffer_drive);
2261 printk("buffer track=%d\n", buffer_track);
2262 printk("buffer_min=%d\n", buffer_min );
2263 printk("buffer_max=%d\n", buffer_max );
2264 return 0;
2265 }
2266
2267 if (current_addr != CURRENT->buffer ){
2268 if (current_addr < floppy_track_buffer ||
2269 current_count_sectors < 0 ||
2270 raw_cmd.length < 0 ||
2271 current_addr + raw_cmd.length >
2272 floppy_track_buffer + (max_buffer_sectors << 10)){
2273 DPRINT("buffer overrun in schedule dma\n");
2274 printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2275 sector_t, buffer_min,
2276 raw_cmd.length >> 9 );
2277 printk("current_count_sectors=%ld\n",
2278 current_count_sectors);
2279 if ( CT(COMMAND) == FD_READ )
2280 printk("read\n");
2281 if ( CT(COMMAND) == FD_READ )
2282 printk("write\n");
2283 return 0;
2284 }
2285 } else if (raw_cmd.length > CURRENT->nr_sectors << 9 ||
2286 current_count_sectors > CURRENT->nr_sectors){
2287 DPRINT("buffer overrun in direct transfer\n");
2288 return 0;
2289 } else if ( raw_cmd.length < current_count_sectors << 9 ){
2290 DPRINT("more sectors than bytes\n");
2291 printk("bytes=%ld\n", raw_cmd.length >> 9 );
2292 printk("sectors=%ld\n", current_count_sectors);
2293 }
2294 #endif
2295 return 2;
2296 }
2297
2298 static struct cont_t rw_cont={
2299 rw_interrupt,
2300 redo_fd_request,
2301 bad_flp_intr,
2302 request_done };
2303
2304 static void redo_fd_request(void)
2305 {
2306 #define REPEAT {request_done(0); continue; }
2307 int device;
2308 int tmp;
2309
2310 if (current_drive < N_DRIVE)
2311 floppy_off(current_drive);
2312
2313 if (CURRENT && CURRENT->dev < 0) return;
2314
2315 cont = &rw_cont;
2316 while(1){
2317 if (!CURRENT) {
2318 CLEAR_INTR;
2319 unlock_fdc();
2320 return;
2321 }
2322 if (MAJOR(CURRENT->dev) != MAJOR_NR)
2323 panic(DEVICE_NAME ": request list destroyed");
2324 if (CURRENT->bh && !CURRENT->bh->b_lock)
2325 panic(DEVICE_NAME ": block not locked");
2326
2327 device = CURRENT->dev;
2328 set_fdc( DRIVE(device));
2329
2330 timer_table[FLOPPY_TIMER].expires = jiffies + DP->timeout;
2331 timer_active |= 1 << FLOPPY_TIMER;
2332 raw_cmd.flags=0;
2333 start_motor();
2334 if(test_bit( DRIVE(device), &fake_change) ||
2335 test_bit( DRIVE(device), &changed_floppies)){
2336 DPRINT("disk absent or changed during operation\n");
2337 REPEAT;
2338 }
2339 set_floppy(device);
2340 if (!floppy) {
2341 if (!probing){
2342 DRS->probed_format = 0;
2343 if ( next_valid_format() ){
2344 DPRINT("no autodetectable formats\n");
2345 floppy = NULL;
2346 REPEAT;
2347 }
2348 }
2349 probing = 1;
2350 floppy = floppy_type+DP->autodetect[DRS->probed_format];
2351 } else
2352 probing = 0;
2353 errors = & (CURRENT->errors);
2354 tmp = make_raw_rw_request();
2355 if ( tmp < 2 ){
2356 request_done(tmp);
2357 continue;
2358 }
2359
2360 floppy_tq.routine = (void *)(void *) floppy_start;
2361 queue_task(&floppy_tq, &tq_timer);
2362 #ifdef DEBUGT
2363 debugt("queue fd request");
2364 #endif
2365 return;
2366 }
2367 #undef REPEAT
2368 }
2369
2370 void do_fd_request(void)
2371 {
2372 if (fdc_busy)
2373
2374
2375 return;
2376
2377 floppy_grab_irq_and_dma();
2378 fdc_busy=1;
2379 redo_fd_request();
2380 }
2381
2382
2383
2384
2385
2386
2387 static void reset_intr(void)
2388 {
2389 printk("weird, reset interrupt called\n");
2390 }
2391
2392 static struct cont_t reset_cont={
2393 reset_intr,
2394 success_and_wakeup,
2395 generic_failure,
2396 generic_done };
2397
2398 static int user_reset_fdc(int drive, int arg, int interruptible)
2399 {
2400 int result;
2401
2402 result=0;
2403 LOCK_FDC(drive,interruptible);
2404 switch(arg){
2405 case FD_RESET_ALWAYS:
2406 FDCS->reset=1;
2407 break;
2408 case FD_RESET_IF_RAWCMD:
2409 if(FDCS->rawcmd == 2 )
2410 reset_fdc_info(1);
2411 break;
2412 }
2413 if ( FDCS->reset ){
2414 cont = &reset_cont;
2415 timer_table[FLOPPY_TIMER].expires = jiffies + 5;
2416 timer_active |= 1 << FLOPPY_TIMER;
2417 CALL(result=wait_til_done(reset_fdc,interruptible));
2418 }
2419 if ( UDRS->track == PROVEN_ABSENT )
2420 UDRS->track = NEED_2_RECAL;
2421 redo_fd_request();
2422 return result;
2423 }
2424
2425
2426
2427
2428
2429 static int fd_copyout(void *param, volatile void *address, int size)
2430 {
2431 int i;
2432
2433 i = verify_area(VERIFY_WRITE,param,size);
2434 if (i)
2435 return i;
2436 memcpy_tofs(param,(void *) address, size);
2437 return 0;
2438 }
2439
2440 #define COPYOUT(x) (fd_copyout( (void *)param, &(x), sizeof(x)))
2441 #define COPYIN(x) (memcpy_fromfs( &(x), (void *) param, sizeof(x)),0)
2442
2443 static char *drive_name(int type, int drive )
2444 {
2445 struct floppy_struct *floppy;
2446
2447 if ( type )
2448 floppy = floppy_type + type;
2449 else {
2450 if ( UDP->native_format )
2451 floppy = floppy_type + UDP->native_format;
2452 else
2453 return "(null)";
2454 }
2455 if ( floppy->name )
2456 return floppy->name;
2457 else
2458 return "(null)";
2459 }
2460
2461
2462 static struct cont_t raw_cmd_cont={
2463 success_and_wakeup,
2464 failure_and_wakeup,
2465 generic_failure,
2466 generic_done };
2467
2468 static int raw_cmd_ioctl(int drive, void *param)
2469 {
2470 int i, count, ret;
2471
2472 if ( FDCS->rawcmd <= 1 )
2473 FDCS->rawcmd = 1;
2474 for ( i= 0; i < N_DRIVE; i++){
2475 if ( FDC(i) != fdc)
2476 continue;
2477 if ( i == drive ){
2478 if ( drive_state[i].fd_ref > 1 ){
2479 FDCS->rawcmd = 2;
2480 break;
2481 }
2482 } else if ( drive_state[i].fd_ref ){
2483 FDCS->rawcmd = 2;
2484 break;
2485 }
2486 }
2487
2488 if(FDCS->reset)
2489 return -EIO;
2490
2491 COPYIN(raw_cmd);
2492 raw_cmd.rate &= 0x03;
2493 count = raw_cmd.length;
2494 if (raw_cmd.flags & (FD_RAW_WRITE | FD_RAW_READ)){
2495 if(count > max_buffer_sectors * 1024 )
2496 return -ENOMEM;
2497 buffer_track = -1;
2498 }
2499 if ( raw_cmd.flags & FD_RAW_WRITE ){
2500 i = verify_area(VERIFY_READ, raw_cmd.data, count );
2501 if (i)
2502 return i;
2503 memcpy_fromfs(floppy_track_buffer, raw_cmd.data, count);
2504 }
2505
2506 current_addr = floppy_track_buffer;
2507 cont = &raw_cmd_cont;
2508 CALL(ret=wait_til_done(floppy_start,1));
2509 if( disk_change(current_drive) )
2510 raw_cmd.flags |= FD_RAW_DISK_CHANGE;
2511 else
2512 raw_cmd.flags &= ~FD_RAW_DISK_CHANGE;
2513 if(raw_cmd.flags & FD_RAW_NO_MOTOR_AFTER)
2514 motor_off_callback(drive);
2515
2516 if ( !ret && !FDCS->reset ){
2517 raw_cmd.reply_count = inr;
2518 for( i=0; i< raw_cmd.reply_count; i++)
2519 raw_cmd.reply[i] = reply_buffer[i];
2520 if ( raw_cmd.flags & ( FD_RAW_READ | FD_RAW_WRITE ))
2521 raw_cmd.length = get_dma_residue(FLOPPY_DMA);
2522 } else
2523 ret = -EIO;
2524 DRS->track = NO_TRACK;
2525 if ( ret )
2526 return ret;
2527
2528 if ( raw_cmd.flags & FD_RAW_READ ){
2529 i=fd_copyout( raw_cmd.data, floppy_track_buffer, count);
2530 if (i)
2531 return i;
2532 }
2533
2534 return COPYOUT(raw_cmd);
2535 }
2536
2537 static int invalidate_drive(int rdev)
2538 {
2539
2540 set_bit( DRIVE(rdev), &fake_change);
2541 redo_fd_request();
2542 check_disk_change(rdev);
2543 return 0;
2544 }
2545
2546 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
2547 unsigned long param)
2548 {
2549 #define IOCTL_MODE_BIT 8
2550 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
2551
2552 struct floppy_struct newparams;
2553 struct format_descr tmp_format_req;
2554 int i,device,drive,type,cnt;
2555 struct floppy_struct *this_floppy;
2556 char *name;
2557
2558 device = inode->i_rdev;
2559 switch (cmd) {
2560 RO_IOCTLS(device,param);
2561 }
2562 type = TYPE(device);
2563 drive = DRIVE(device);
2564 switch (cmd) {
2565 case FDGETDRVTYP:
2566 i=verify_area(VERIFY_WRITE,(void *) param,16);
2567 if (i)
2568 return i;
2569 name = drive_name(type,drive);
2570 for ( cnt=0; cnt<16; cnt++){
2571 put_fs_byte(name[cnt],
2572 ((char*)param)+cnt);
2573 if ( ! *name )
2574 break;
2575 }
2576 return 0;
2577 case FDGETMAXERRS:
2578 return COPYOUT(UDP->max_errors);
2579 case FDGETPRM:
2580 if (type)
2581 this_floppy = &floppy_type[type];
2582 else if ((this_floppy = current_type[drive]) ==
2583 NULL)
2584 return -ENODEV;
2585 return COPYOUT(this_floppy[0]);
2586 case FDPOLLDRVSTAT:
2587 check_disk_change(device);
2588
2589 case FDGETDRVSTAT:
2590 return COPYOUT(*UDRS);
2591 case FDGETFDCSTAT:
2592 return COPYOUT(*UFDCS);
2593 case FDGETDRVPRM:
2594 return COPYOUT(*UDP);
2595 case FDWERRORGET:
2596 return COPYOUT(*UDRWE);
2597 }
2598 if (!IOCTL_ALLOWED)
2599 return -EPERM;
2600 switch (cmd) {
2601 case FDWERRORCLR:
2602 UDRWE->write_errors = 0;
2603 UDRWE->first_error_sector = 0;
2604 UDRWE->first_error_generation = 0;
2605 UDRWE->last_error_sector = 0;
2606 UDRWE->last_error_generation = 0;
2607 UDRWE->badness = 0;
2608 return 0;
2609 case FDRAWCMD:
2610 if (type)
2611 return -EINVAL;
2612 LOCK_FDC(drive,1);
2613 set_floppy(device);
2614 CALL(i = raw_cmd_ioctl(drive, (void *) param));
2615 redo_fd_request();
2616 return i;
2617 case FDFMTTRK:
2618 if (UDRS->fd_ref != 1)
2619 return -EBUSY;
2620 if (UDRS->track == PROVEN_ABSENT)
2621 return -ENXIO;
2622 COPYIN(tmp_format_req);
2623 return do_format(device, &tmp_format_req);
2624 case FDSETMAXERRS:
2625 return COPYIN(UDP->max_errors);
2626 case FDFMTBEG:
2627 return 0;
2628 case FDCLRPRM:
2629 LOCK_FDC(drive,1);
2630 current_type[drive] = NULL;
2631 floppy_sizes[drive] = MAX_DISK_SIZE;
2632 UDRS->keep_data = 0;
2633 return invalidate_drive(device);
2634 case FDFMTEND:
2635 case FDFLUSH:
2636 LOCK_FDC(drive,1);
2637 return invalidate_drive(device);
2638 case FDSETPRM:
2639 case FDDEFPRM:
2640 COPYIN(newparams);
2641
2642 if(newparams.sect <= 0 ||
2643 newparams.head <= 0 ||
2644 newparams.track <= 0 ||
2645 newparams.track >
2646 UDP->tracks>>newparams.stretch)
2647 return -EINVAL;
2648 if ( type){
2649 if ( !suser() )
2650 return -EPERM;
2651 LOCK_FDC(-1,1);
2652 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2653 if (TYPE(drive_state[cnt].fd_device) == type &&
2654 drive_state[cnt].fd_ref)
2655 set_bit(drive, &fake_change);
2656 }
2657 floppy_type[type] = newparams;
2658 floppy_type[type].name="user format";
2659 for (cnt = type << 2 ;
2660 cnt < (type << 2 ) + 4 ;
2661 cnt++)
2662 floppy_sizes[cnt]=
2663 #ifdef HAVE_2_CONTROLLERS
2664 floppy_sizes[cnt+0x80]=
2665 #endif
2666 floppy_type[type].size>>1;
2667 redo_fd_request();
2668 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2669 if (TYPE(drive_state[cnt].fd_device) == type &&
2670 drive_state[cnt].fd_ref)
2671 check_disk_change(drive_state[cnt].
2672 fd_device);
2673 }
2674 return 0;
2675 }
2676
2677 LOCK_FDC(drive,1);
2678 if ( cmd != FDDEFPRM ){
2679
2680
2681 raw_cmd.flags = 0;
2682 start_motor();
2683 }
2684 user_params[drive] = newparams;
2685 if (buffer_drive == drive &&
2686 buffer_max > user_params[drive].sect)
2687 buffer_max=user_params[drive].sect;
2688 current_type[drive] = &user_params[drive];
2689 floppy_sizes[drive] = user_params[drive].size >> 1;
2690 if (cmd == FDDEFPRM)
2691 DRS->keep_data = -1;
2692 else
2693 DRS->keep_data = 1;
2694
2695
2696
2697
2698
2699 if (DRS->maxblock >
2700 user_params[drive].sect ||
2701 DRS->maxtrack )
2702 invalidate_drive(device);
2703 else
2704 redo_fd_request();
2705 return 0;
2706 case FDRESET:
2707 return user_reset_fdc( drive, (int)param, 1);
2708 case FDMSGON:
2709 UDP->flags |= FTD_MSG;
2710 return 0;
2711 case FDMSGOFF:
2712 UDP->flags &= ~FTD_MSG;
2713 return 0;
2714 case FDSETEMSGTRESH:
2715 UDP->max_errors.reporting =
2716 (unsigned short) (param & 0x0f);
2717 return 0;
2718 case FDTWADDLE:
2719 LOCK_FDC(drive,1);
2720 twaddle();
2721 redo_fd_request();
2722 }
2723 if ( ! suser() )
2724 return -EPERM;
2725 switch(cmd){
2726 case FDSETDRVPRM:
2727 return COPYIN(*UDP);
2728 default:
2729 return -EINVAL;
2730 }
2731 return 0;
2732 #undef IOCTL_ALLOWED
2733 }
2734
2735 #define CMOS_READ(addr) ({ \
2736 outb_p(addr,0x70); \
2737 inb_p(0x71); \
2738 })
2739
2740 static void set_base_type(int drive,int code)
2741 {
2742 if (code > 0 && code <= NUMBER(default_drive_params)) {
2743 memcpy((char *) UDP,
2744 (char *) (&default_drive_params[code].params),
2745 sizeof( struct floppy_drive_params ));
2746 printk("fd%d is %s", drive, default_drive_params[code].name);
2747 return;
2748 } else if (!code)
2749 printk("fd%d is not installed", drive);
2750 else
2751 printk("fd%d is unknown type %d",drive,code);
2752 }
2753
2754 static void config_types(void)
2755 {
2756 int drive;
2757
2758 for (drive=0; drive<N_DRIVE ; drive++){
2759
2760 memcpy((char *) UDP, (char *) (&default_drive_params->params),
2761 sizeof( struct floppy_drive_params ));
2762 }
2763 printk("Floppy drive(s): ");
2764 set_base_type(0, (CMOS_READ(0x10) >> 4) & 15);
2765 if (CMOS_READ(0x10) & 15) {
2766 printk(", ");
2767 set_base_type(1, CMOS_READ(0x10) & 15);
2768 }
2769 printk("\n");
2770 }
2771
2772 int floppy_is_wp( int minor)
2773 {
2774 check_disk_change(minor + (MAJOR_NR << 8));
2775 return ! ( drive_state[ DRIVE(minor) ].flags & FD_DISK_WRITABLE );
2776 }
2777
2778
2779 #define WRAPPER(op) \
2780 static int floppy_##op(struct inode * inode, struct file * filp, \
2781 char * buf, int count) \
2782 { \
2783 check_disk_change(inode->i_rdev); \
2784 if ( drive_state[DRIVE(inode->i_rdev)].track == PROVEN_ABSENT ) \
2785 return -ENXIO; \
2786 if ( test_bit(DRIVE(inode->i_rdev),&changed_floppies)) \
2787 return -ENXIO; \
2788 return block_##op(inode, filp, buf, count); \
2789 }
2790
2791 WRAPPER(read)
2792 WRAPPER(write)
2793
2794 static void floppy_release(struct inode * inode, struct file * filp)
2795 {
2796 int drive;
2797
2798 drive = DRIVE(inode->i_rdev);
2799
2800 fsync_dev(inode->i_rdev);
2801
2802 if (UDRS->fd_ref < 0)
2803 UDRS->fd_ref=0;
2804 else if (!UDRS->fd_ref--) {
2805 DPRINT("floppy_release with fd_ref == 0");
2806 UDRS->fd_ref = 0;
2807 }
2808 floppy_release_irq_and_dma();
2809 }
2810
2811
2812
2813
2814
2815
2816 #define RETERR(x) \
2817 do{floppy_release(inode,filp); \
2818 return -(x);}while(0)
2819
2820 static int floppy_open(struct inode * inode, struct file * filp)
2821 {
2822 int drive;
2823 int old_dev;
2824
2825 if (!filp) {
2826 DPRINT("Weird, open called with filp=0\n");
2827 return -EIO;
2828 }
2829
2830 drive = DRIVE(inode->i_rdev);
2831 if ( drive >= N_DRIVE || !( ALLOWED_DRIVE_MASK & ( 1 << drive)) )
2832 return -ENXIO;
2833
2834 if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
2835 return -ENXIO;
2836
2837 if ((filp->f_mode & 3) &&
2838 UDRS->track == PROVEN_ABSENT )
2839 return -ENXIO;
2840
2841 old_dev = UDRS->fd_device;
2842 if (UDRS->fd_ref && old_dev != inode->i_rdev)
2843 return -EBUSY;
2844
2845 if(UDRS->fd_ref == -1 ||
2846 (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
2847 return -EBUSY;
2848
2849 if (floppy_grab_irq_and_dma())
2850 return -EBUSY;
2851
2852 if (filp->f_flags & O_EXCL)
2853 UDRS->fd_ref = -1;
2854 else
2855 UDRS->fd_ref++;
2856
2857 UDRS->fd_device = inode->i_rdev;
2858
2859 if (old_dev && old_dev != inode->i_rdev) {
2860 if (buffer_drive == drive)
2861 buffer_track = -1;
2862 invalidate_buffers(old_dev);
2863 }
2864
2865
2866 if ((filp->f_mode & 2) || permission(inode,2))
2867 filp->f_mode |= IOCTL_MODE_BIT;
2868
2869 if (UFDCS->rawcmd == 1)
2870 UFDCS->rawcmd = 2;
2871
2872 if (filp->f_flags & O_NDELAY)
2873 return 0;
2874
2875 if (filp->f_mode && UDRS->track == PROVEN_ABSENT )
2876 RETERR(ENXIO);
2877
2878 if (user_reset_fdc(drive, FD_RESET_IF_NEEDED,0))
2879 RETERR(EIO);
2880
2881 if (filp->f_mode & 3) {
2882 UDRS->last_checked = 0;
2883 check_disk_change(inode->i_rdev);
2884 if (test_bit(drive,&changed_floppies))
2885 RETERR(ENXIO);
2886 }
2887
2888 if (filp->f_mode && UDRS->track == PROVEN_ABSENT )
2889 RETERR(ENXIO);
2890
2891 if ((filp->f_mode & 2) && !(UDRS->flags & FD_DISK_WRITABLE))
2892 RETERR(EROFS);
2893 return 0;
2894 #undef RETERR
2895 }
2896
2897
2898
2899
2900 static int check_floppy_change(dev_t dev)
2901 {
2902 int drive = DRIVE( dev );
2903
2904 if (MAJOR(dev) != MAJOR_NR) {
2905 DPRINT("floppy_changed: not a floppy\n");
2906 return 0;
2907 }
2908
2909 if(test_bit(drive, &changed_floppies))
2910 return 1;
2911
2912 if(UDRS->last_checked + UDP->checkfreq < jiffies){
2913 lock_fdc(drive,0);
2914 start_motor();
2915 redo_fd_request();
2916 }
2917
2918 if(test_bit(drive, &changed_floppies))
2919 return 1;
2920 if(test_bit(drive, &fake_change))
2921 return 1;
2922 return 0;
2923 }
2924
2925 static struct cont_t poll_cont={
2926 success_and_wakeup,
2927 floppy_ready,
2928 generic_failure,
2929 generic_done };
2930
2931
2932
2933
2934
2935
2936 static int floppy_revalidate(dev_t dev)
2937 {
2938 struct buffer_head * bh;
2939 int drive=DRIVE(dev);
2940 int cf;
2941
2942 cf = test_bit(drive, &changed_floppies);
2943 if(cf || test_bit(drive, &fake_change)){
2944 lock_fdc(drive,0);
2945 cf = test_bit(drive, &changed_floppies);
2946 if(! (cf || test_bit(drive, &fake_change))){
2947 redo_fd_request();
2948 return 0;
2949 }
2950 UDRS->maxblock = 0;
2951 UDRS->maxtrack = 0;
2952 if ( buffer_drive == drive)
2953 buffer_track = -1;
2954 clear_bit(drive, &fake_change);
2955 clear_bit(drive, &changed_floppies);
2956 if(cf){
2957 UDRS->generation++;
2958 if(!current_type[drive] && !TYPE(dev)){
2959
2960 int size = floppy_blocksizes[MINOR(dev)];
2961 if (!size)
2962 size = 1024;
2963 if (!(bh = getblk(dev,0,size))){
2964 redo_fd_request();
2965 return 1;
2966 }
2967 if ( bh && ! bh->b_uptodate)
2968 ll_rw_block(READ, 1, &bh);
2969 redo_fd_request();
2970 wait_on_buffer(bh);
2971 brelse(bh);
2972 return 0;
2973 } else {
2974
2975 raw_cmd.flags=FD_RAW_NEED_SEEK|FD_RAW_NEED_DISK;
2976 raw_cmd.track=0;
2977 raw_cmd.cmd_count=0;
2978 cont = &poll_cont;
2979 wait_til_done(floppy_ready,0);
2980 }
2981 }
2982 redo_fd_request();
2983 }
2984 return 0;
2985 }
2986
2987 static struct file_operations floppy_fops = {
2988 NULL,
2989 floppy_read,
2990 floppy_write,
2991 NULL,
2992 NULL,
2993 fd_ioctl,
2994 NULL,
2995 floppy_open,
2996 floppy_release,
2997 block_fsync,
2998 NULL,
2999 check_floppy_change,
3000 floppy_revalidate,
3001 };
3002
3003
3004
3005
3006
3007
3008
3009
3010 static char get_fdc_version(void)
3011 {
3012 int r;
3013
3014 output_byte(FD_DUMPREGS);
3015 if ( FDCS->reset )
3016 return FDC_NONE;
3017 if ( (r = result()) <= 0x00)
3018 return FDC_NONE;
3019 if ((r==1) && (reply_buffer[0] == 0x80)){
3020 printk("FDC %d is a 8272A\n",fdc);
3021 return FDC_8272A;
3022 }
3023 if (r != 10) {
3024 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
3025 return FDC_UNKNOWN;
3026 }
3027 output_byte(FD_VERSION);
3028 r = result();
3029 if ((r == 1) && (reply_buffer[0] == 0x80)){
3030 printk("FDC %d is a 82072\n",fdc);
3031 return FDC_82072;
3032 }
3033 if ((r != 1) || (reply_buffer[0] != 0x90)) {
3034 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
3035 return FDC_UNKNOWN;
3036 }
3037 output_byte(FD_UNLOCK);
3038 r = result();
3039 if ((r == 1) && (reply_buffer[0] == 0x80)){
3040 printk("FDC %d is a pre-1991 82077\n", fdc);
3041 return FDC_82077_ORIG;
3042 }
3043 if ((r != 1) || (reply_buffer[0] != 0x00)) {
3044 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
3045 return FDC_UNKNOWN;
3046 }
3047 printk("FDC %d is a post-1991 82077\n",fdc);
3048 return FDC_82077;
3049 }
3050
3051 void floppy_init(void)
3052 {
3053 int i;
3054
3055 sti();
3056
3057 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
3058 printk("Unable to get major %d for floppy\n",MAJOR_NR);
3059 return;
3060 }
3061
3062 for(i=0; i<256; i++)
3063 if ( TYPE(i))
3064 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
3065 else
3066 floppy_sizes[i] = MAX_DISK_SIZE;
3067
3068 blk_size[MAJOR_NR] = floppy_sizes;
3069 blksize_size[MAJOR_NR] = floppy_blocksizes;
3070 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3071 timer_table[FLOPPY_TIMER].fn = floppy_shutdown;
3072 timer_active &= ~(1 << FLOPPY_TIMER);
3073 config_types();
3074
3075 fdc_state[0].address = 0x3f0;
3076 #if N_FDC > 1
3077 fdc_state[1].address = 0x370;
3078 #endif
3079 for (i = 0 ; i < N_FDC ; i++) {
3080 fdc = i;
3081 FDCS->dtr = -1;
3082 FDCS->dor = 0;
3083 FDCS->reset = 0;
3084 FDCS->version = FDC_NONE;
3085 set_dor(fdc, ~0, 0xc );
3086 }
3087
3088
3089 for (i = 0; i < N_DRIVE ; i++) {
3090 current_drive = i;
3091 DRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE;
3092 DRS->generation = 0;
3093 DRS->keep_data = 0;
3094 DRS->fd_ref = 0;
3095 DRS->fd_device = 0;
3096 DRWE->write_errors = 0;
3097 DRWE->first_error_sector = 0;
3098 DRWE->first_error_generation = 0;
3099 DRWE->last_error_sector = 0;
3100 DRWE->last_error_generation = 0;
3101 DRWE->badness = 0;
3102 }
3103
3104 floppy_grab_irq_and_dma();
3105 for (i = 0 ; i < N_FDC ; i++) {
3106 fdc = i;
3107 FDCS->rawcmd = 2;
3108 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED,0))
3109 continue;
3110
3111 FDCS->version = get_fdc_version();
3112 if (FDCS->version == FDC_NONE)
3113 continue;
3114
3115
3116
3117
3118
3119 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
3120 user_reset_fdc(-1,FD_RESET_ALWAYS,0);
3121 }
3122 fdc=0;
3123 current_drive = 0;
3124 floppy_release_irq_and_dma();
3125 initialising=0;
3126 }
3127
3128 static int floppy_grab_irq_and_dma(void)
3129 {
3130 int i;
3131 cli();
3132 if (usage_count++){
3133 sti();
3134 return 0;
3135 }
3136 sti();
3137
3138 for(i=0; i< N_FDC; i++){
3139 fdc = i;
3140 reset_fdc_info(1);
3141 outb_p( FDCS->dor, FD_DOR);
3142 }
3143 set_dor(0, ~0, 8);
3144
3145 if (request_irq(FLOPPY_IRQ, floppy_interrupt, SA_INTERRUPT, "floppy")) {
3146 DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
3147 FLOPPY_IRQ);
3148 return -1;
3149 }
3150 if (request_dma(FLOPPY_DMA,"floppy")) {
3151 DPRINT1("Unable to grab DMA%d for the floppy driver\n",
3152 FLOPPY_DMA);
3153 free_irq(FLOPPY_IRQ);
3154 return -1;
3155 }
3156 enable_irq(FLOPPY_IRQ);
3157 return 0;
3158 }
3159
3160 static void floppy_release_irq_and_dma(void)
3161 {
3162 cli();
3163 if (--usage_count){
3164 sti();
3165 return;
3166 }
3167 sti();
3168 disable_dma(FLOPPY_DMA);
3169 free_dma(FLOPPY_DMA);
3170 disable_irq(FLOPPY_IRQ);
3171 free_irq(FLOPPY_IRQ);
3172 set_dor(0, ~0, 8);
3173 #if N_FDC > 1
3174 if(fdc.address != -1)
3175 set_dor(1, ~8, 0);
3176 #endif
3177 }