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