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,0x6C,"h880" },
318 { 2080,13,2,80,0,0x1C,0x01,0xCF,0x6C,"D1040" },
319 { 2240,14,2,80,0,0x1C,0x19,0xCF,0x6C,"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,0x6C,"H1920" },
323 { 6400,40,2,80,0,0x25,0x5B,0xCF,0x6C,"E3200" },
324 { 7040,44,2,80,0,0x25,0x5B,0xCF,0x6C,"E3520" },
325 { 7680,48,2,80,0,0x25,0x63,0xCF,0x6C,"E3840" },
326
327 { 3680,23,2,80,0,0x1C,0x10,0xCF,0x6C,"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(inb_p(FD_DIR) & 0x80){
503 UDRS->flags |= FD_VERIFY;
504
505 if(UDRS->maxblock ||
506 !(UDRS->flags & FD_DISK_NEWCHANGE)){
507
508 set_bit(drive,&changed_floppies);
509
510
511 if (UDRS->keep_data >= 0) {
512 if ((DP->flags & FTD_MSG) &&
513 current_type[drive] != NULL)
514 DPRINT("Disk type is undefined after "
515 "disk change\n");
516 current_type[drive] = NULL;
517 floppy_sizes[drive] = MAX_DISK_SIZE;
518 }
519 }
520 UDRS->flags |= FD_DISK_NEWCHANGE;
521 return 1;
522 } else {
523 UDRS->last_checked=jiffies;
524 UDRS->flags &= ~FD_DISK_NEWCHANGE;
525 return 0;
526 }
527 }
528
529
530 static int set_dor(int fdc, char mask, char data)
531 {
532 register unsigned char drive, unit, newdor,olddor;
533
534 cli();
535 olddor = FDCS->dor;
536 newdor = (olddor & mask) | data;
537 if ( newdor != olddor ){
538 unit = olddor & 0x3;
539 drive = REVDRIVE(fdc,unit);
540 if ( olddor & ( 0x10 << unit ))
541 disk_change(drive);
542 FDCS->dor = newdor;
543 outb_p( newdor, FD_DOR);
544 }
545 sti();
546 return olddor;
547 }
548
549 static void twaddle(void)
550 {
551 cli();
552 outb_p(FDCS->dor & ~(0x10<<UNIT(current_drive)),FD_DOR);
553 outb_p(FDCS->dor, FD_DOR);
554 sti();
555 }
556
557
558
559 static void reset_fdc_info(int mode)
560 {
561 int drive;
562
563 FDCS->spec1 = FDCS->spec2 = -1;
564 FDCS->need_configure = 1;
565 FDCS->perp_mode = 1;
566 FDCS->rawcmd = 0;
567 for ( drive = 0; drive < N_DRIVE; drive++)
568 if (FDC(drive) == fdc &&
569 UDRS->track != PROVEN_ABSENT &&
570 ( mode || UDRS->track != NEED_1_RECAL))
571 UDRS->track = NEED_2_RECAL;
572 }
573
574
575 static void set_fdc(int drive)
576 {
577 if ( drive >= 0 ){
578 fdc = FDC(drive);
579 current_drive = drive;
580 }
581 set_dor(fdc,~0,8);
582 #ifdef HAVE_2_CONTROLLERS
583 set_dor(1-fdc, ~8, 0);
584 #endif
585 if ( FDCS->rawcmd == 2 )
586 reset_fdc_info(1);
587 if( inb_p(FD_STATUS) != STATUS_READY )
588 FDCS->reset = 1;
589 }
590
591 static int usage_count = 0;
592
593 static int lock_fdc(int drive, int interruptible)
594 {
595
596 if(!usage_count){
597 printk("trying to lock fdc while usage count=0\n");
598 return -1;
599 }
600 floppy_grab_irq_and_dma();
601 cli();
602 while (fdc_busy && NO_SIGNAL)
603 interruptible_sleep_on(&fdc_wait);
604 if(fdc_busy){
605 sti();
606 return -EINTR;
607 }
608 fdc_busy = 1;
609 sti();
610 command_status = FD_COMMAND_NONE;
611 set_fdc(drive);
612 return 0;
613 }
614
615 #define LOCK_FDC(drive,interruptible) \
616 if(lock_fdc(drive,interruptible)) return -EINTR;
617
618
619 static inline void unlock_fdc(void)
620 {
621 if (!fdc_busy)
622 DPRINT("FDC access conflict!\n");
623
624 if ( DEVICE_INTR )
625 DPRINT1("device interrupt still active at FDC release: %p!\n",
626 DEVICE_INTR);
627 command_status = FD_COMMAND_NONE;
628 timer_active &= ~(1 << FLOPPY_TIMER);
629 fdc_busy = 0;
630 floppy_release_irq_and_dma();
631 wake_up(&fdc_wait);
632 }
633
634
635 static void motor_off_callback(unsigned long nr)
636 {
637 unsigned char mask = ~(0x10 << UNIT(nr));
638
639 set_dor( FDC(nr), mask, 0 );
640 }
641
642 static struct timer_list motor_off_timer[N_DRIVE] = {
643 { NULL, NULL, 0, 0, motor_off_callback },
644 { NULL, NULL, 0, 1, motor_off_callback },
645 { NULL, NULL, 0, 2, motor_off_callback },
646 { NULL, NULL, 0, 3, motor_off_callback }
647 #ifdef HAVE_2_CONTROLLERS
648 ,
649 { NULL, NULL, 0, 4, motor_off_callback },
650 { NULL, NULL, 0, 5, motor_off_callback },
651 { NULL, NULL, 0, 6, motor_off_callback },
652 { NULL, NULL, 0, 7, motor_off_callback }
653 #endif
654 };
655
656
657 static void floppy_off(unsigned int nr)
658 {
659 unsigned long volatile delta;
660
661 del_timer(motor_off_timer+nr);
662
663
664
665 if ( drive_params[nr].rps ){
666 delta = jiffies - drive_state[nr].first_read_date + HZ -
667 drive_params[nr].spindown_offset;
668 delta = (( delta * drive_params[nr].rps) % HZ ) /
669 drive_params[nr].rps;
670 motor_off_timer[nr].expires = drive_params[nr].spindown - delta;
671 }
672 add_timer(motor_off_timer+nr);
673 }
674
675
676
677
678
679
680 static void scandrives(void)
681 {
682 int i, drive, saved_drive;
683
684 saved_drive = current_drive % N_DRIVE;
685 for(i=0; i< N_DRIVE; i++){
686 drive = (saved_drive + i + 1 ) % N_DRIVE;
687 if ( UDRS->fd_ref == 0 )
688 continue;
689 set_fdc(drive);
690 if (!(FDCS->dor & (0x10 << UNIT(drive))) ||
691 ((FDCS->dor & 0x3) != UNIT(drive)))
692 UDRS->select_date = jiffies;
693 if(! (set_dor( fdc, ~3, UNIT(drive) | ( 0x10 << UNIT(drive))) &
694 (0x10 << UNIT(drive))))
695
696
697 set_dor( fdc, ~( 0x10 << UNIT(drive) ), 0 );
698 }
699 current_drive = saved_drive;
700 }
701
702 typedef void (*timeout_fn)(unsigned long);
703 static struct timer_list fd_timer ={ NULL, NULL, 0, 0, 0 };
704
705
706
707 static void fd_watchdog(void)
708 {
709 if ( disk_change(current_drive) ){
710 DPRINT("disk removed during i/o\n");
711 floppy_shutdown();
712 } else {
713 del_timer(&fd_timer);
714 fd_timer.function = (timeout_fn) fd_watchdog;
715 fd_timer.expires = 10;
716 add_timer(&fd_timer);
717 }
718 }
719
720 static void main_command_interrupt(void)
721 {
722 del_timer(&fd_timer);
723 cont->interrupt();
724 }
725
726
727 static int wait_for_completion(int nr, int delay, timeout_fn function)
728 {
729 if ( FDCS->reset ){
730 reset_fdc();
731
732
733 return 1;
734 }
735
736 if ( jiffies < delay ){
737 del_timer(&fd_timer);
738 fd_timer.function = function;
739 fd_timer.expires = delay - jiffies;
740 add_timer(&fd_timer);
741 return 1;
742 }
743 return 0;
744 }
745
746 static void setup_DMA(void)
747 {
748 #ifdef SANITY
749 if ((!CURRENT ||
750 CURRENT->buffer != current_addr ||
751 raw_cmd.length > 512 * CURRENT->nr_sectors) &&
752 (current_addr < floppy_track_buffer ||
753 current_addr + raw_cmd.length >
754 floppy_track_buffer + 1024 * max_buffer_sectors)){
755 printk("bad address. start=%p lg=%lx tb=%p\n",
756 current_addr, raw_cmd.length, floppy_track_buffer);
757 if ( CURRENT ){
758 printk("buffer=%p nr=%lx cnr=%lx\n",
759 CURRENT->buffer, CURRENT->nr_sectors,
760 CURRENT->current_nr_sectors);
761 }
762 cont->done(0);
763 FDCS->reset=1;
764 return;
765 }
766 if ((long) current_addr % 512 ){
767 printk("non aligned address: %p\n", current_addr );
768 cont->done(0);
769 FDCS->reset=1;
770 return;
771 }
772 if ( ( (long)current_addr & ~(64*1024-1) ) !=
773 ((long)(current_addr + raw_cmd.length-1) & ~(64*1024-1))){
774 printk("DMA crossing 64-K boundary %p-%p\n",
775 current_addr, current_addr + raw_cmd.length);
776 cont->done(0);
777 FDCS->reset=1;
778 return;
779 }
780
781 #endif
782 cli();
783 disable_dma(FLOPPY_DMA);
784 clear_dma_ff(FLOPPY_DMA);
785 set_dma_mode(FLOPPY_DMA,
786 (raw_cmd.flags & FD_RAW_READ)?
787 DMA_MODE_READ : DMA_MODE_WRITE);
788 set_dma_addr(FLOPPY_DMA, (long) current_addr);
789 set_dma_count(FLOPPY_DMA, raw_cmd.length);
790 enable_dma(FLOPPY_DMA);
791 sti();
792 }
793
794
795 static int output_byte(char byte)
796 {
797 int counter;
798 unsigned char status;
799
800 if (FDCS->reset)
801 return -1;
802 for(counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
803 status = inb_p(FD_STATUS) &(STATUS_READY|STATUS_DIR|STATUS_DMA);
804 if (!(status & STATUS_READY))
805 continue;
806 if (status == STATUS_READY){
807 outb_p(byte,FD_DATA);
808 return 0;
809 } else
810 break;
811 }
812 FDCS->reset = 1;
813 if ( !initialising )
814 DPRINT2("Unable to send byte %x to FDC. Status=%x\n",
815 byte, status);
816 return -1;
817 }
818 #define LAST_OUT(x) if(output_byte(x)){ reset_fdc();return;}
819
820
821 static int result(void)
822 {
823 int i = 0, counter, status;
824
825 if (FDCS->reset)
826 return -1;
827 for (counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
828 status = inb_p(FD_STATUS)&
829 (STATUS_DIR|STATUS_READY|STATUS_BUSY|STATUS_DMA);
830 if (!(status & STATUS_READY))
831 continue;
832 if (status == STATUS_READY)
833 return i;
834 if (status & STATUS_DMA )
835 break;
836 if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {
837 if (i >= MAX_REPLIES) {
838 DPRINT("floppy_stat reply overrun\n");
839 break;
840 }
841 reply_buffer[i++] = inb_p(FD_DATA);
842 }
843 }
844 FDCS->reset = 1;
845 if ( !initialising )
846 DPRINT3("Getstatus times out (%x) on fdc %d [%d]\n",
847 status, fdc, i);
848 return -1;
849 }
850
851
852
853
854 static inline void perpendicular_mode(void)
855 {
856 unsigned char perp_mode;
857
858 if (!floppy)
859 return;
860 if (floppy->rate & 0x40){
861 switch(raw_cmd.rate){
862 case 0:
863 perp_mode=2;
864 break;
865 case 3:
866 perp_mode=3;
867 break;
868 default:
869 DPRINT("Invalid data rate for perpendicular mode!\n");
870 cont->done(0);
871 FDCS->reset = 1;
872
873
874 return;
875 }
876 } else
877 perp_mode = 0;
878
879 if ( FDCS->perp_mode == perp_mode )
880 return;
881 if (FDCS->version >= FDC_82077_ORIG && FDCS->has_fifo) {
882 output_byte(FD_PERPENDICULAR);
883 output_byte(perp_mode);
884 FDCS->perp_mode = perp_mode;
885 } else if (perp_mode) {
886 DPRINT("perpendicular mode not supported by this FDC.\n");
887 }
888 }
889
890 #define NOMINAL_DTR 500
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911 static void fdc_specify(void)
912 {
913 unsigned char spec1, spec2;
914 int srt, hlt, hut;
915 unsigned long dtr = NOMINAL_DTR;
916 unsigned long scale_dtr = NOMINAL_DTR;
917 int hlt_max_code = 0x7f;
918 int hut_max_code = 0xf;
919
920 if (FDCS->need_configure && FDCS->has_fifo) {
921 if ( FDCS->reset )
922 return;
923
924
925 output_byte(FD_CONFIGURE);
926 output_byte(0);
927 output_byte(0x1A);
928 output_byte(0);
929 if ( FDCS->reset ){
930 FDCS->has_fifo=0;
931 return;
932 }
933 FDCS->need_configure = 0;
934
935 }
936
937 switch (raw_cmd.rate & 0x03) {
938 case 3:
939 dtr = 1000;
940 break;
941 case 1:
942 dtr = 300;
943 break;
944 case 2:
945 dtr = 250;
946 break;
947 }
948
949 if (FDCS->version >= FDC_82072) {
950 scale_dtr = dtr;
951 hlt_max_code = 0x00;
952 hut_max_code = 0x0;
953 }
954
955
956 srt = 16 - (DP->srt*scale_dtr/1000 + NOMINAL_DTR - 1)/NOMINAL_DTR;
957 if (srt > 0xf)
958 srt = 0xf;
959 else if (srt < 0)
960 srt = 0;
961
962 hlt = (DP->hlt*scale_dtr/2 + NOMINAL_DTR - 1)/NOMINAL_DTR;
963 if (hlt < 0x01)
964 hlt = 0x01;
965 else if (hlt > 0x7f)
966 hlt = hlt_max_code;
967
968 hut = (DP->hut*scale_dtr/16 + NOMINAL_DTR - 1)/NOMINAL_DTR;
969 if (hut < 0x1)
970 hut = 0x1;
971 else if (hut > 0xf)
972 hut = hut_max_code;
973
974 spec1 = (srt << 4) | hut;
975 spec2 = (hlt << 1);
976
977
978 if (FDCS->spec1 != spec1 || FDCS->spec2 != spec2) {
979
980 output_byte(FD_SPECIFY);
981 output_byte(FDCS->spec1 = spec1);
982 output_byte(FDCS->spec2 = spec2);
983 }
984 }
985
986
987
988
989
990 static void fdc_dtr(void)
991 {
992
993 if ( raw_cmd.rate == FDCS->dtr)
994 return;
995
996
997 outb_p(raw_cmd.rate, FD_DCR);
998
999
1000
1001
1002
1003
1004 udelay(5000);
1005 FDCS->dtr = raw_cmd.rate;
1006 }
1007
1008 static void tell_sector(void)
1009 {
1010 printk(": track %d, head %d, sector %d, size %d",
1011 R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
1012 }
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022 static int interpret_errors(void)
1023 {
1024 char bad;
1025
1026 if (inr!=7) {
1027 DPRINT("-- FDC reply error");
1028 FDCS->reset = 1;
1029 return 1;
1030 }
1031
1032
1033 switch ((ST0 & ST0_INTR)>>6) {
1034 case 1:
1035 bad = 1;
1036 if (ST1 & ST1_WP) {
1037 DPRINT("Drive is write protected\n");
1038 DRS->flags &= ~FD_DISK_WRITABLE;
1039 cont->done(0);
1040 bad = 2;
1041 } else if (ST1 & ST1_ND) {
1042 DRS->flags |= FD_NEED_TWADDLE;
1043 } else if (ST1 & ST1_OR) {
1044 if (DP->flags & FTD_MSG )
1045 DPRINT("Over/Underrun - retrying\n");
1046 bad = 0;
1047 }else if(*errors >= DP->max_errors.reporting){
1048 DPRINT("");
1049 if (ST0 & ST0_ECE) {
1050 printk("Recalibrate failed!");
1051 } else if (ST2 & ST2_CRC) {
1052 printk("data CRC error");
1053 tell_sector();
1054 } else if (ST1 & ST1_CRC) {
1055 printk("CRC error");
1056 tell_sector();
1057 } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
1058 if (!probing) {
1059 printk("sector not found");
1060 tell_sector();
1061 } else
1062 printk("probe failed...");
1063 } else if (ST2 & ST2_WC) {
1064 printk("wrong cylinder");
1065 } else if (ST2 & ST2_BC) {
1066 printk("bad cylinder");
1067 } else {
1068 printk("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", ST0, ST1, ST2);
1069 tell_sector();
1070 }
1071 printk("\n");
1072
1073 }
1074 if ( ST2 & ST2_WC || ST2 & ST2_BC)
1075
1076 DRS->track = NEED_2_RECAL;
1077 return bad;
1078 case 2:
1079 DPRINT("Invalid FDC command given!\n");
1080 cont->done(0);
1081 return 2;
1082 case 3:
1083 DPRINT("Abnormal termination caused by polling\n");
1084 cont->error();
1085 return 2;
1086 default:
1087 return 0;
1088 }
1089 }
1090
1091
1092
1093
1094
1095
1096 static void setup_rw_floppy(void)
1097 {
1098 int i,ready_date,r, flags,dflags;
1099 timeout_fn function;
1100
1101 flags = raw_cmd.flags;
1102 if ( flags & ( FD_RAW_READ | FD_RAW_WRITE))
1103 flags |= FD_RAW_INTR;
1104
1105 if ((flags & FD_RAW_SPIN) && !(flags & FD_RAW_NO_MOTOR)){
1106 ready_date = DRS->spinup_date + DP->spinup;
1107
1108
1109
1110
1111 if ( ready_date > jiffies + DP->select_delay){
1112 ready_date -= DP->select_delay;
1113 function = (timeout_fn) floppy_start;
1114 } else
1115 function = (timeout_fn) setup_rw_floppy;
1116
1117
1118 if (wait_for_completion(current_drive,ready_date,function))
1119 return;
1120 }
1121 dflags = DRS->flags;
1122
1123 if ( (flags & FD_RAW_READ) || (flags & FD_RAW_WRITE))
1124 setup_DMA();
1125
1126 if ( flags & FD_RAW_INTR )
1127 SET_INTR(main_command_interrupt);
1128
1129 r=0;
1130 for(i=0; i< raw_cmd.cmd_count; i++)
1131 r|=output_byte( raw_cmd.cmd[i] );
1132
1133 #ifdef DEBUGT
1134 debugt("rw_command: ");
1135 #endif
1136 if ( r ){
1137 reset_fdc();
1138 return;
1139 }
1140
1141 if ( ! ( flags & FD_RAW_INTR )){
1142 inr = result();
1143 cont->interrupt();
1144 } else if ( flags & FD_RAW_NEED_DISK )
1145 fd_watchdog();
1146 }
1147
1148 #ifdef SILENT_DC_CLEAR
1149 static int blind_seek;
1150 #endif
1151
1152
1153
1154
1155
1156 static void seek_interrupt(void)
1157 {
1158 #ifdef DEBUGT
1159 debugt("seek interrupt:");
1160 #endif
1161 #ifdef SILENT_DC_CLEAR
1162 set_dor(fdc, ~0, (0x10 << UNIT(current_drive)));
1163 #endif
1164 if (inr != 2 || (ST0 & 0xF8) != 0x20 ) {
1165 DPRINT("seek failed\n");
1166 DRS->track = NEED_2_RECAL;
1167 cont->error();
1168 cont->redo();
1169 return;
1170 }
1171 if (DRS->track >= 0 && DRS->track != ST1
1172 #ifdef SILENT_DC_CLEAR
1173 && !blind_seek
1174 #endif
1175 )
1176 DRS->flags &= ~FD_DISK_NEWCHANGE;
1177 DRS->track = ST1;
1178 seek_floppy();
1179 }
1180
1181 static void check_wp(void)
1182 {
1183 if (DRS->flags & FD_VERIFY) {
1184
1185 output_byte( FD_GETSTATUS );
1186 output_byte( UNIT(current_drive) );
1187 if ( result() != 1 ){
1188 FDCS->reset = 1;
1189 return;
1190 }
1191 DRS->flags &= ~(FD_VERIFY | FD_DISK_WRITABLE | FD_NEED_TWADDLE);
1192
1193 if (!( ST3 & 0x40))
1194 DRS->flags |= FD_DISK_WRITABLE;
1195 }
1196 }
1197
1198 static void seek_floppy(void)
1199 {
1200 int track;
1201
1202 #ifdef SILENT_DC_CLEAR
1203 blind_seek=0;
1204 #endif
1205 disk_change(current_drive);
1206 if ((raw_cmd.flags & FD_RAW_NEED_DISK) &&
1207 test_bit(current_drive,&changed_floppies)){
1208
1209
1210
1211
1212 cont->done(0);
1213 cont->redo();
1214 return;
1215 }
1216 if ( DRS->track <= NEED_1_RECAL ){
1217 recalibrate_floppy();
1218 return;
1219 } else if ((DRS->flags & FD_DISK_NEWCHANGE) &&
1220 (raw_cmd.flags & FD_RAW_NEED_DISK) &&
1221 (DRS->track <= NO_TRACK || DRS->track == raw_cmd.track)) {
1222
1223
1224 if ( raw_cmd.track )
1225 track = raw_cmd.track - 1;
1226 else {
1227 #ifdef SILENT_DC_CLEAR
1228 set_dor(fdc, ~ (0x10 << UNIT(current_drive)), 0);
1229 blind_seek = 1;
1230 #endif
1231 track = 1;
1232 }
1233 } else {
1234 check_wp();
1235 if (raw_cmd.track != DRS->track)
1236 track = raw_cmd.track;
1237 else {
1238 setup_rw_floppy();
1239 return;
1240 }
1241 }
1242
1243 #ifndef SILENT_DC_CLEAR
1244 if ( !track && DRS->track >= 0 && DRS->track < 80 ){
1245 DRS->flags &= ~FD_DISK_NEWCHANGE;
1246
1247
1248 recalibrate_floppy();
1249 } else
1250 #endif
1251 {
1252 SET_INTR(seek_interrupt);
1253 output_byte(FD_SEEK);
1254 output_byte(UNIT(current_drive));
1255 LAST_OUT(track);
1256 #ifdef DEBUGT
1257 debugt("seek command:");
1258 #endif
1259 }
1260 }
1261
1262 static void recal_interrupt(void)
1263 {
1264 #ifdef DEBUGT
1265 debugt("recal interrupt:");
1266 #endif
1267 if (inr !=2 )
1268 FDCS->reset = 1;
1269 else if (ST0 & ST0_ECE) {
1270 switch(DRS->track){
1271 case PROVEN_ABSENT:
1272 #ifdef DEBUGT
1273 debugt("recal interrupt proven absent:");
1274 #endif
1275
1276 case NEED_1_RECAL:
1277 #ifdef DEBUGT
1278 debugt("recal interrupt need 1 recal:");
1279 #endif
1280
1281
1282
1283
1284 cont->error();
1285 cont->redo();
1286 return;
1287 case NEED_2_RECAL:
1288 #ifdef DEBUGT
1289 debugt("recal interrupt need 2 recal:");
1290 #endif
1291
1292
1293
1294
1295
1296 DRS->flags &= ~FD_DISK_NEWCHANGE;
1297
1298 default:
1299 #ifdef DEBUGT
1300 debugt("recal interrupt default:");
1301 #endif
1302
1303
1304
1305
1306
1307 DRS->track = NEED_1_RECAL;
1308 break;
1309 }
1310 } else
1311 DRS->track = ST1;
1312 seek_floppy();
1313 }
1314
1315
1316
1317
1318
1319 static void unexpected_floppy_interrupt(void)
1320 {
1321 int i;
1322 if ( initialising )
1323 return;
1324 DPRINT("unexpected interrupt\n");
1325 if ( inr >= 0 )
1326 for(i=0; i<inr; i++)
1327 printk("%d %x\n", i, reply_buffer[i] );
1328 while(1){
1329 output_byte(FD_SENSEI);
1330 inr=result();
1331 if ( inr != 2 )
1332 break;
1333 printk("sensei\n");
1334 for(i=0; i<inr; i++)
1335 printk("%d %x\n", i, reply_buffer[i] );
1336 }
1337 FDCS->reset = 1;
1338 }
1339
1340 struct tq_struct floppy_tq =
1341 { 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
1342
1343
1344 static void floppy_interrupt(int unused)
1345 {
1346 void (*handler)(void) = DEVICE_INTR;
1347
1348 CLEAR_INTR;
1349 if ( fdc >= N_FDC ){
1350 printk("floppy interrupt on bizarre fdc\n");
1351 return;
1352 }
1353 inr = result();
1354 if (!handler){
1355 unexpected_floppy_interrupt();
1356 return;
1357 }
1358 if ( inr == 0 ){
1359 do {
1360 output_byte(FD_SENSEI);
1361 inr = result();
1362 } while ( (ST0 & 0x83) != UNIT(current_drive) && inr == 2);
1363 }
1364 floppy_tq.routine = (void *)(void *) handler;
1365 queue_task_irq(&floppy_tq, &tq_timer);
1366 }
1367
1368 static void recalibrate_floppy(void)
1369 {
1370 #ifdef DEBUGT
1371 debugt("recalibrate floppy:");
1372 #endif
1373 SET_INTR(recal_interrupt);
1374 output_byte(FD_RECALIBRATE);
1375 LAST_OUT(UNIT(current_drive));
1376 }
1377
1378
1379
1380
1381 static void reset_interrupt(void)
1382 {
1383 #ifdef DEBUGT
1384 debugt("reset interrupt:");
1385 #endif
1386 fdc_specify();
1387 result();
1388 if ( FDCS->reset )
1389 cont->error();
1390 cont->redo();
1391 }
1392
1393
1394
1395
1396
1397 static void reset_fdc(void)
1398 {
1399 SET_INTR(reset_interrupt);
1400 FDCS->reset = 0;
1401 reset_fdc_info(0);
1402 if ( FDCS->version >= FDC_82077 )
1403 outb_p(0x80 | ( FDCS->dtr &3), FD_STATUS);
1404 else {
1405 outb_p(FDCS->dor & ~0x04, FD_DOR);
1406 udelay(FD_RESET_DELAY);
1407 outb(FDCS->dor, FD_DOR);
1408 }
1409 }
1410
1411 static void empty(void)
1412 {
1413 }
1414
1415 void show_floppy(void)
1416 {
1417 int i;
1418
1419 printk("\n");
1420 printk("floppy driver state\n");
1421 printk("-------------------\n");
1422 for(i=0; i<N_FDC; i++){
1423 printk("dor %d = %x\n", i, fdc_state[i].dor );
1424 outb_p(fdc_state[i].address+2, fdc_state[i].dor);
1425 udelay(1000);
1426 }
1427 printk("status=%x\n", inb_p(FD_STATUS));
1428 printk("fdc_busy=%d\n", fdc_busy);
1429 if( DEVICE_INTR)
1430 printk("DEVICE_INTR=%p\n", DEVICE_INTR);
1431 if(floppy_tq.sync)
1432 printk("floppy_tq.routine=%p\n", floppy_tq.routine);
1433 if(fd_timer.prev)
1434 printk("fd_timer.function=%p\n", fd_timer.function);
1435 if( timer_active & (1 << FLOPPY_TIMER)){
1436 printk("timer_table=%p\n",timer_table[FLOPPY_TIMER].fn);
1437 printk("expires=%ld\n",timer_table[FLOPPY_TIMER].expires);
1438 printk("now=%ld\n",jiffies);
1439 }
1440 printk("cont=%p\n", cont);
1441 printk("CURRENT=%p\n", CURRENT);
1442 printk("command_status=%d\n", command_status);
1443 printk("\n");
1444 }
1445
1446 static void floppy_shutdown(void)
1447 {
1448 CLEAR_INTR;
1449 floppy_tq.routine = (void *)(void *) empty;
1450 del_timer( &fd_timer);
1451
1452 disable_dma(FLOPPY_DMA);
1453
1454
1455 if(!initialising)
1456 DPRINT("floppy timeout\n");
1457 FDCS->reset = 1;
1458 cont->done(0);
1459 cont->redo();
1460 }
1461
1462
1463 static void start_motor(void)
1464 {
1465 int mask, data;
1466
1467 mask = 0xfc;
1468 data = UNIT(current_drive);
1469 if ( (FDCS->dor & 0x03) != UNIT(current_drive) )
1470
1471 DRS->select_date = jiffies;
1472
1473 if (!(raw_cmd.flags & FD_RAW_NO_MOTOR)){
1474 if(!(FDCS->dor & ( 0x10 << UNIT(current_drive) ) )){
1475 set_debugt();
1476
1477 DRS->first_read_date = 0;
1478
1479 DRS->spinup_date = jiffies;
1480 data |= (0x10 << UNIT(current_drive));
1481 }
1482 } else
1483 if (FDCS->dor & ( 0x10 << UNIT(current_drive) ) )
1484 mask &= ~(0x10 << UNIT(current_drive));
1485
1486
1487 del_timer(motor_off_timer + current_drive);
1488 set_dor( fdc, mask, data);
1489 if( raw_cmd.flags & FD_RAW_NO_MOTOR)
1490 return;
1491
1492 if(disk_change(current_drive))
1493 twaddle();
1494
1495
1496 return;
1497 }
1498
1499 static void floppy_ready(void)
1500 {
1501 CHECK_RESET;
1502 start_motor();
1503
1504
1505 if(wait_for_completion(current_drive,
1506 DRS->select_date+DP->select_delay,
1507 (timeout_fn) floppy_ready))
1508 return;
1509 fdc_dtr();
1510 if ( raw_cmd.flags & FD_RAW_NEED_SEEK ){
1511 perpendicular_mode();
1512 fdc_specify();
1513 seek_floppy();
1514 } else
1515 setup_rw_floppy();
1516 }
1517
1518 static void floppy_start(void)
1519 {
1520 timer_table[FLOPPY_TIMER].expires = jiffies + DP->timeout;
1521 timer_active |= 1 << FLOPPY_TIMER;
1522 scandrives();
1523 floppy_ready();
1524 }
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540 static void do_wakeup(void)
1541 {
1542 timer_active &= ~(1 << FLOPPY_TIMER);
1543 cont = 0;
1544 command_status += 2;
1545 wake_up(&command_done);
1546 }
1547
1548 static struct cont_t wakeup_cont={
1549 empty,
1550 do_wakeup,
1551 empty,
1552 (done_f)empty
1553 };
1554
1555 static int wait_til_done( void (*handler)(void ), int interruptible )
1556 {
1557 int ret;
1558
1559 floppy_tq.routine = (void *)(void *) handler;
1560 queue_task(&floppy_tq, &tq_timer);
1561
1562 cli();
1563 while(command_status < 2 && NO_SIGNAL)
1564 if (current->pid)
1565 interruptible_sleep_on(&command_done);
1566 else {
1567 sti();
1568 run_task_queue(&tq_timer);
1569 cli();
1570 }
1571 if(command_status < 2){
1572 sti();
1573 floppy_shutdown();
1574 redo_fd_request();
1575 return -EINTR;
1576 }
1577 sti();
1578
1579 if ( FDCS->reset )
1580 command_status = FD_COMMAND_ERROR;
1581 if ( command_status == FD_COMMAND_OKAY )
1582 ret=0;
1583 else
1584 ret=-EIO;
1585 command_status = FD_COMMAND_NONE;
1586 return ret;
1587 }
1588
1589 static void generic_done(int result)
1590 {
1591 command_status = result;
1592 cont = &wakeup_cont;
1593 }
1594
1595 static void generic_success(void)
1596 {
1597 generic_done(1);
1598 }
1599
1600 static void generic_failure(void)
1601 {
1602 generic_done(0);
1603 }
1604
1605 static void success_and_wakeup(void)
1606 {
1607 generic_success();
1608 do_wakeup();
1609 }
1610
1611 static void failure_and_wakeup(void)
1612 {
1613 generic_failure();
1614 do_wakeup();
1615 }
1616
1617
1618
1619
1620
1621
1622 static int next_valid_format(void)
1623 {
1624 int probed_format;
1625 while(1){
1626 probed_format = DRS->probed_format;
1627 if ( probed_format > N_DRIVE ||
1628 ! DP->autodetect[probed_format] ){
1629 DRS->probed_format = 0;
1630 return 1;
1631 }
1632 if ( floppy_type[DP->autodetect[probed_format]].sect ){
1633 DRS->probed_format = probed_format;
1634 return 0;
1635 }
1636 probed_format++;
1637 }
1638 }
1639
1640 static void bad_flp_intr(void)
1641 {
1642 if ( probing ){
1643 DRS->probed_format++;
1644 if ( !next_valid_format())
1645 return;
1646 }
1647 (*errors)++;
1648 if (*errors > DRWE->badness)
1649 DRWE->badness = *errors;
1650 if (*errors > DP->max_errors.abort)
1651 cont->done(0);
1652 if (*errors > DP->max_errors.reset)
1653 FDCS->reset = 1;
1654 else if (*errors > DP->max_errors.recal)
1655 DRS->track = NEED_2_RECAL;
1656 }
1657
1658 static void set_floppy(int device)
1659 {
1660 if (TYPE(device))
1661 floppy = TYPE(device) + floppy_type;
1662 else
1663 floppy = current_type[ DRIVE(device) ];
1664 }
1665
1666
1667
1668
1669
1670 static void format_interrupt(void)
1671 {
1672 switch (interpret_errors()){
1673 case 1:
1674 cont->error();
1675 case 2:
1676 break;
1677 case 0:
1678 cont->done(1);
1679 }
1680 cont->redo();
1681 }
1682
1683 #define CODE2SIZE (ssize = ( ( 1 << SIZECODE ) + 3 ) >> 2)
1684 #define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80 ) >>1))
1685 #define CT(x) ( (x) | 0x40 )
1686 static void setup_format_params(void)
1687 {
1688 struct fparm {
1689 unsigned char track,head,sect,size;
1690 } *here = (struct fparm *)floppy_track_buffer;
1691 int il,n;
1692 int count,head_shift,track_shift;
1693
1694 raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
1695 FD_RAW_NEED_SEEK;
1696 raw_cmd.rate = floppy->rate & 0x3;
1697 raw_cmd.cmd_count = NR_F;
1698 COMMAND = FM_MODE(floppy,FD_FORMAT);
1699 DR_SELECT = UNIT(current_drive) + ( format_req.head << 2 );
1700 F_SIZECODE = FD_SIZECODE(floppy);
1701 F_SECT_PER_TRACK = floppy->sect << 2 >> F_SIZECODE;
1702 F_GAP = floppy->fmt_gap;
1703 F_FILL = FD_FILL_BYTE;
1704
1705 current_addr = floppy_track_buffer;
1706 raw_cmd.length = 4 * F_SECT_PER_TRACK;
1707
1708
1709 head_shift = (F_SECT_PER_TRACK + 5) / 6;
1710
1711
1712 track_shift = 2 * head_shift + 1;
1713
1714
1715 n = (track_shift * format_req.track + head_shift * format_req.head )
1716 % F_SECT_PER_TRACK;
1717
1718
1719 il = 1;
1720 if (floppy->sect > DP->interleave_sect && F_SIZECODE == 2)
1721 il++;
1722
1723
1724 for (count = 0; count < F_SECT_PER_TRACK; ++count) {
1725 here[count].track = format_req.track;
1726 here[count].head = format_req.head;
1727 here[count].sect = 0;
1728 here[count].size = F_SIZECODE;
1729 }
1730
1731 for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
1732 here[n].sect = count;
1733 n = (n+il) % F_SECT_PER_TRACK;
1734 if (here[n].sect) {
1735 ++n;
1736 if (n>= F_SECT_PER_TRACK) {
1737 n-=F_SECT_PER_TRACK;
1738 while (here[n].sect) ++n;
1739 }
1740 }
1741 }
1742 }
1743
1744 static void redo_format(void)
1745 {
1746 raw_cmd.track = format_req.track << floppy->stretch;
1747 buffer_track = -1;
1748 setup_format_params();
1749 clear_bit(current_drive, &changed_floppies);
1750 floppy_start();
1751 #ifdef DEBUGT
1752 debugt("queue format request");
1753 #endif
1754 }
1755
1756 static struct cont_t format_cont={
1757 format_interrupt,
1758 redo_format,
1759 bad_flp_intr,
1760 generic_done };
1761
1762 static int do_format(int device, struct format_descr *tmp_format_req)
1763 {
1764 int okay;
1765
1766 LOCK_FDC(DRIVE(device),1);
1767 set_floppy(device);
1768 if (!floppy ||
1769 tmp_format_req->track >= floppy->track ||
1770 tmp_format_req->head >= floppy->head){
1771 redo_fd_request();
1772 return -EINVAL;
1773 }
1774 format_req = *tmp_format_req;
1775 format_errors = 0;
1776 cont = &format_cont;
1777 errors = &format_errors;
1778 CALL(okay=wait_til_done(redo_format,1));
1779 redo_fd_request();
1780 return okay;
1781 }
1782
1783
1784
1785
1786
1787
1788
1789
1790 static void request_done(int uptodate)
1791 {
1792 int block;
1793
1794 probing = 0;
1795 timer_active &= ~(1 << FLOPPY_TIMER);
1796
1797 if (!CURRENT){
1798 DPRINT("request list destroyed in floppy request done\n");
1799 return;
1800 }
1801 if (uptodate){
1802
1803
1804 block = current_count_sectors + CURRENT->sector;
1805 if (block > DRS->maxblock)
1806 DRS->maxblock=block;
1807 if ( block > floppy->sect)
1808 DRS->maxtrack = 1;
1809
1810
1811 while (current_count_sectors && CURRENT &&
1812 current_count_sectors >= CURRENT->current_nr_sectors ){
1813 current_count_sectors -= CURRENT->current_nr_sectors;
1814 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
1815 CURRENT->sector += CURRENT->current_nr_sectors;
1816 end_request(1);
1817 }
1818 if ( current_count_sectors && CURRENT){
1819
1820 CURRENT->buffer += current_count_sectors <<9;
1821 CURRENT->current_nr_sectors -= current_count_sectors;
1822 CURRENT->nr_sectors -= current_count_sectors;
1823 CURRENT->sector += current_count_sectors;
1824 return;
1825 }
1826
1827 if ( current_count_sectors && ! CURRENT )
1828 DPRINT("request list destroyed in floppy request done\n");
1829
1830 } else {
1831 if(CURRENT->cmd == WRITE) {
1832
1833 DRWE->write_errors++;
1834 if(DRWE->write_errors == 1) {
1835 DRWE->first_error_sector = CURRENT->sector;
1836 DRWE->first_error_generation = DRS->generation;
1837 }
1838 DRWE->last_error_sector = CURRENT->sector;
1839 DRWE->last_error_generation = DRS->generation;
1840 }
1841 end_request(0);
1842 }
1843 }
1844
1845
1846 static void rw_interrupt(void)
1847 {
1848 int nr_sectors, ssize;
1849
1850 if ( ! DRS->first_read_date )
1851 DRS->first_read_date = jiffies;
1852
1853 nr_sectors = 0;
1854 CODE2SIZE;
1855 nr_sectors = ((R_TRACK-TRACK)*floppy->head+R_HEAD-HEAD) *
1856 floppy->sect + ((R_SECTOR-SECTOR) << SIZECODE >> 2) -
1857 (sector_t % floppy->sect) % ssize;
1858
1859 #ifdef SANITY
1860 if ( nr_sectors > current_count_sectors + ssize -
1861 (current_count_sectors + sector_t) % ssize +
1862 sector_t % ssize){
1863 DPRINT2("long rw: %x instead of %lx\n",
1864 nr_sectors, current_count_sectors);
1865 printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
1866 printk("rh=%d h=%d\n", R_HEAD, HEAD);
1867 printk("rt=%d t=%d\n", R_TRACK, TRACK);
1868 printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
1869 sector_t, ssize);
1870 }
1871 #endif
1872 if ( nr_sectors < 0 )
1873 nr_sectors = 0;
1874 if ( nr_sectors < current_count_sectors )
1875 current_count_sectors = nr_sectors;
1876
1877 switch (interpret_errors()){
1878 case 2:
1879 cont->redo();
1880 return;
1881 case 1:
1882 if ( !current_count_sectors){
1883 cont->error();
1884 cont->redo();
1885 return;
1886 }
1887 break;
1888 case 0:
1889 if ( !current_count_sectors){
1890 cont->redo();
1891 return;
1892 }
1893 current_type[current_drive] = floppy;
1894 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
1895 floppy->size >> 1;
1896 break;
1897 }
1898
1899 if (probing) {
1900 if (DP->flags & FTD_MSG)
1901 DPRINT2("Auto-detected floppy type %s in fd%d\n",
1902 floppy->name,current_drive);
1903 current_type[current_drive] = floppy;
1904 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
1905 floppy->size >> 1;
1906 probing = 0;
1907 }
1908
1909 if ( CT(COMMAND) != FD_READ || current_addr == CURRENT->buffer ){
1910
1911 cont->done(1);
1912 } else if ( CT(COMMAND) == FD_READ){
1913 buffer_track = raw_cmd.track;
1914 buffer_drive = current_drive;
1915 if ( nr_sectors + sector_t > buffer_max )
1916 buffer_max = nr_sectors + sector_t;
1917 }
1918 cont->redo();
1919 }
1920
1921
1922 static int buffer_chain_size(void)
1923 {
1924 struct buffer_head *bh;
1925 int size;
1926 char *base;
1927
1928 base = CURRENT->buffer;
1929 size = CURRENT->current_nr_sectors << 9;
1930 bh = CURRENT->bh;
1931
1932 #ifdef SANITY
1933 if ( !bh ){
1934 DPRINT("null request in buffer_chain_size\n");
1935 return size >> 9;
1936 }
1937 #endif
1938
1939 bh = bh->b_reqnext;
1940 while ( bh && bh->b_data == base + size ){
1941 size += bh->b_size;
1942 bh = bh->b_reqnext;
1943 }
1944 return size >> 9;
1945 }
1946
1947
1948 static int transfer_size(int ssize, int max_sector, int max_size)
1949 {
1950 if ( max_sector > sector_t + max_size)
1951 max_sector = sector_t + max_size;
1952
1953
1954 max_sector -= (max_sector % floppy->sect ) % ssize;
1955
1956
1957 current_count_sectors = max_sector - sector_t ;
1958
1959 return max_sector;
1960 }
1961
1962
1963
1964
1965 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
1966 {
1967 int remaining;
1968 struct buffer_head *bh;
1969 char *buffer, *dma_buffer;
1970 int size;
1971
1972 if ( max_sector > max_sector_2 )
1973 max_sector = max_sector_2;
1974
1975 max_sector = transfer_size(ssize, max_sector, CURRENT->nr_sectors);
1976
1977 if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
1978 buffer_max > sector_t + CURRENT->nr_sectors){
1979 current_count_sectors = buffer_max - sector_t;
1980 if ( current_count_sectors > CURRENT->nr_sectors )
1981 current_count_sectors = CURRENT->nr_sectors;
1982 }
1983 remaining = current_count_sectors << 9;
1984 #ifdef SANITY
1985 if ((remaining >> 9) > CURRENT->nr_sectors &&
1986 CT(COMMAND) == FD_WRITE ){
1987 DPRINT("in copy buffer\n");
1988 printk("current_count_sectors=%ld\n", current_count_sectors);
1989 printk("remaining=%d\n", remaining >> 9);
1990 printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
1991 printk("CURRENT->current_nr_sectors=%ld\n",
1992 CURRENT->current_nr_sectors);
1993 printk("max_sector=%d\n", max_sector);
1994 printk("ssize=%d\n", ssize);
1995 }
1996 #endif
1997
1998 if ( max_sector > buffer_max )
1999 buffer_max = max_sector;
2000
2001 dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
2002
2003 bh = CURRENT->bh;
2004 size = CURRENT->current_nr_sectors << 9;
2005 buffer = CURRENT->buffer;
2006
2007 while ( remaining > 0){
2008 if ( size > remaining )
2009 size = remaining;
2010 #ifdef SANITY
2011 if (!bh){
2012 DPRINT("bh=null in copy buffer before copy\n");
2013 break;
2014 }
2015 if (dma_buffer + size >
2016 floppy_track_buffer + (max_buffer_sectors << 10) ||
2017 dma_buffer < floppy_track_buffer ){
2018 DPRINT1("buffer overrun in copy buffer %d\n",
2019 (floppy_track_buffer - dma_buffer) >>9);
2020 printk("sector_t=%d buffer_min=%d\n",
2021 sector_t, buffer_min);
2022 printk("current_count_sectors=%ld\n",
2023 current_count_sectors);
2024 if ( CT(COMMAND) == FD_READ )
2025 printk("read\n");
2026 if ( CT(COMMAND) == FD_READ )
2027 printk("write\n");
2028 break;
2029 }
2030 if ( ((int)buffer) % 512 )
2031 DPRINT1("%p buffer not aligned\n", buffer);
2032 #endif
2033 if ( CT(COMMAND) == FD_READ )
2034 memcpy( buffer, dma_buffer, size);
2035 else
2036 memcpy( dma_buffer, buffer, size);
2037 remaining -= size;
2038 if ( !remaining)
2039 break;
2040
2041 dma_buffer += size;
2042 bh = bh->b_reqnext;
2043 #ifdef SANITY
2044 if ( !bh){
2045 DPRINT("bh=null in copy buffer after copy\n");
2046 break;
2047 }
2048 #endif
2049 size = bh->b_size;
2050 buffer = bh->b_data;
2051 }
2052 #ifdef SANITY
2053 if ( remaining ){
2054 if ( remaining > 0 )
2055 max_sector -= remaining >> 9;
2056 DPRINT1("weirdness: remaining %d\n", remaining>>9);
2057 }
2058 #endif
2059 }
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071 static int make_raw_rw_request(void)
2072 {
2073 int aligned_sector_t;
2074 int max_sector, max_size, tracksize, ssize;
2075
2076 current_drive = DRIVE(CURRENT->dev);
2077
2078 raw_cmd.flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
2079 FD_RAW_NEED_SEEK;
2080 raw_cmd.cmd_count = NR_RW;
2081 if (CURRENT->cmd == READ){
2082 raw_cmd.flags |= FD_RAW_READ;
2083 COMMAND = FM_MODE(floppy,FD_READ);
2084 } else if (CURRENT->cmd == WRITE){
2085 raw_cmd.flags |= FD_RAW_WRITE;
2086 COMMAND = FM_MODE(floppy,FD_WRITE);
2087 } else {
2088 DPRINT("make_raw_rw_request: unknown command\n");
2089 return 0;
2090 }
2091
2092 max_sector = floppy->sect * floppy->head;
2093 TRACK = CURRENT->sector / max_sector;
2094 sector_t = CURRENT->sector % max_sector;
2095 if ( floppy->track && TRACK >= floppy->track )
2096 return 0;
2097 HEAD = sector_t / floppy->sect;
2098
2099 if ( (DRS->flags & FD_NEED_TWADDLE) && sector_t < floppy->sect )
2100 max_sector = floppy->sect;
2101
2102
2103 if ( (floppy->rate & FD_2M ) && (!TRACK) && (!HEAD)){
2104 max_sector = 2 * floppy->sect / 3;
2105 if (sector_t >= max_sector){
2106 current_count_sectors = (floppy->sect - sector_t);
2107 if ( current_count_sectors > CURRENT->nr_sectors )
2108 current_count_sectors = CURRENT->nr_sectors;
2109 return 1;
2110 }
2111 SIZECODE = 2;
2112 } else
2113 SIZECODE = FD_SIZECODE(floppy);
2114 raw_cmd.rate = floppy->rate & 3;
2115 if ((floppy->rate & FD_2M) &&
2116 (TRACK || HEAD ) &&
2117 raw_cmd.rate == 2)
2118 raw_cmd.rate = 1;
2119
2120 if ( SIZECODE )
2121 SIZECODE2 = 0xff;
2122 else
2123 SIZECODE2 = 0x80;
2124 raw_cmd.track = TRACK << floppy->stretch;
2125 DR_SELECT = UNIT(current_drive) + ( HEAD << 2 );
2126 GAP = floppy->gap;
2127 CODE2SIZE;
2128 SECT_PER_TRACK = floppy->sect << 2 >> SIZECODE;
2129 SECTOR = ((sector_t % floppy->sect) << 2 >> SIZECODE) + 1;
2130 tracksize = floppy->sect - floppy->sect % ssize;
2131 if ( tracksize < floppy->sect ){
2132 SECT_PER_TRACK ++;
2133 if ( tracksize <= sector_t % floppy->sect)
2134 SECTOR--;
2135 while ( tracksize <= sector_t % floppy->sect){
2136 while( tracksize + ssize > floppy->sect ){
2137 SIZECODE--;
2138 ssize >>= 1;
2139 }
2140 SECTOR++; SECT_PER_TRACK ++;
2141 tracksize += ssize;
2142 }
2143 max_sector = HEAD * floppy->sect + tracksize;
2144 } else if ( !TRACK && !HEAD && !( floppy->rate & FD_2M ) && probing)
2145 max_sector = floppy->sect;
2146
2147 aligned_sector_t = sector_t - ( sector_t % floppy->sect ) % ssize;
2148 max_size = CURRENT->nr_sectors;
2149 if ((raw_cmd.track == buffer_track) && (current_drive == buffer_drive) &&
2150 (sector_t >= buffer_min) && (sector_t < buffer_max)) {
2151
2152 if (CT(COMMAND) == FD_READ) {
2153 copy_buffer(1, max_sector, buffer_max);
2154 return 1;
2155 }
2156 } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
2157 if (CT(COMMAND) == FD_WRITE){
2158 if(sector_t + CURRENT->nr_sectors > ssize &&
2159 sector_t + CURRENT->nr_sectors < ssize + ssize)
2160 max_size = ssize + ssize;
2161 else
2162 max_size = ssize;
2163 }
2164 raw_cmd.flags &= ~FD_RAW_WRITE;
2165 raw_cmd.flags |= FD_RAW_READ;
2166 COMMAND = FM_MODE(floppy,FD_READ);
2167 } else if ((long)CURRENT->buffer <= LAST_DMA_ADDR ) {
2168 int direct, indirect;
2169
2170 indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
2171 sector_t;
2172
2173 max_size = buffer_chain_size();
2174 if ( max_size > ( LAST_DMA_ADDR - ((long) CURRENT->buffer))>>9)
2175 max_size=(LAST_DMA_ADDR - ((long)CURRENT->buffer))>>9;
2176
2177 if ( ((max_size << 9) + ((long) CURRENT->buffer)) / K_64 !=
2178 ((long) CURRENT->buffer ) / K_64 )
2179 max_size = ( K_64 - ((long) CURRENT->buffer) % K_64)>>9;
2180 direct = transfer_size(ssize,max_sector,max_size) - sector_t;
2181
2182
2183
2184
2185
2186
2187
2188 if ((indirect - sector_t) * 2 > (direct - sector_t) * 3 &&
2189 *errors < DP->max_errors.read_track &&
2190
2191 ( ( !probing || (DP->read_track &
2192 (1 <<DRS->probed_format))))){
2193 max_size = CURRENT->nr_sectors;
2194 } else {
2195 current_addr = CURRENT->buffer;
2196 raw_cmd.length = current_count_sectors << 9;
2197 return 2;
2198 }
2199 }
2200
2201 if ( CT(COMMAND) == FD_READ )
2202 max_size = max_sector;
2203
2204
2205 if (buffer_track != raw_cmd.track ||
2206 buffer_drive !=current_drive ||
2207 sector_t < buffer_min ||
2208 ((CT(COMMAND) == FD_READ ||
2209 (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize ))&&
2210 max_sector > 2 * max_buffer_sectors + buffer_min &&
2211 max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
2212 ){
2213 buffer_track = -1;
2214 buffer_drive = current_drive;
2215 buffer_max = buffer_min = aligned_sector_t;
2216 }
2217 current_addr = floppy_track_buffer +((aligned_sector_t-buffer_min )<<9);
2218
2219 if ( CT(COMMAND) == FD_WRITE ){
2220
2221
2222
2223
2224 #ifdef SANITY
2225 if (sector_t != aligned_sector_t && buffer_track == -1 )
2226 DPRINT("internal error offset !=0 on write\n");
2227 #endif
2228 buffer_track = raw_cmd.track;
2229 buffer_drive = current_drive;
2230 copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min);
2231 } else
2232 transfer_size(ssize, max_sector,
2233 2*max_buffer_sectors+buffer_min-aligned_sector_t);
2234
2235
2236 raw_cmd.length = sector_t+current_count_sectors-aligned_sector_t;
2237 raw_cmd.length = ((raw_cmd.length -1)|(ssize-1))+1;
2238 raw_cmd.length <<= 9;
2239 #ifdef SANITY
2240 if ((raw_cmd.length < current_count_sectors << 9) ||
2241 (current_addr != CURRENT->buffer &&
2242 CT(COMMAND) == FD_WRITE &&
2243 (aligned_sector_t + (raw_cmd.length >> 9) > buffer_max ||
2244 aligned_sector_t < buffer_min )) ||
2245 raw_cmd.length % ( 128 << SIZECODE ) ||
2246 raw_cmd.length <= 0 || current_count_sectors <= 0){
2247 DPRINT2("fractionary current count b=%lx s=%lx\n",
2248 raw_cmd.length, current_count_sectors);
2249 if ( current_addr != CURRENT->buffer )
2250 printk("addr=%d, length=%ld\n",
2251 (current_addr - floppy_track_buffer ) >> 9,
2252 current_count_sectors);
2253 printk("st=%d ast=%d mse=%d msi=%d\n",
2254 sector_t, aligned_sector_t, max_sector, max_size);
2255 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2256 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2257 COMMAND, SECTOR, HEAD, TRACK);
2258 printk("buffer drive=%d\n", buffer_drive);
2259 printk("buffer track=%d\n", buffer_track);
2260 printk("buffer_min=%d\n", buffer_min );
2261 printk("buffer_max=%d\n", buffer_max );
2262 return 0;
2263 }
2264
2265 if (current_addr != CURRENT->buffer ){
2266 if (current_addr < floppy_track_buffer ||
2267 current_count_sectors < 0 ||
2268 raw_cmd.length < 0 ||
2269 current_addr + raw_cmd.length >
2270 floppy_track_buffer + (max_buffer_sectors << 10)){
2271 DPRINT("buffer overrun in schedule dma\n");
2272 printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2273 sector_t, buffer_min,
2274 raw_cmd.length >> 9 );
2275 printk("current_count_sectors=%ld\n",
2276 current_count_sectors);
2277 if ( CT(COMMAND) == FD_READ )
2278 printk("read\n");
2279 if ( CT(COMMAND) == FD_READ )
2280 printk("write\n");
2281 return 0;
2282 }
2283 } else if (raw_cmd.length > CURRENT->nr_sectors << 9 ||
2284 current_count_sectors > CURRENT->nr_sectors){
2285 DPRINT("buffer overrun in direct transfer\n");
2286 return 0;
2287 } else if ( raw_cmd.length < current_count_sectors << 9 ){
2288 DPRINT("more sectors than bytes\n");
2289 printk("bytes=%ld\n", raw_cmd.length >> 9 );
2290 printk("sectors=%ld\n", current_count_sectors);
2291 }
2292 #endif
2293 return 2;
2294 }
2295
2296 static struct cont_t rw_cont={
2297 rw_interrupt,
2298 redo_fd_request,
2299 bad_flp_intr,
2300 request_done };
2301
2302 static void redo_fd_request(void)
2303 {
2304 #define REPEAT {request_done(0); continue; }
2305 int device;
2306 int tmp;
2307
2308 if (current_drive < N_DRIVE)
2309 floppy_off(current_drive);
2310
2311 if (CURRENT && CURRENT->dev < 0) return;
2312
2313 cont = &rw_cont;
2314 while(1){
2315 if (!CURRENT) {
2316 CLEAR_INTR;
2317 unlock_fdc();
2318 return;
2319 }
2320 if (MAJOR(CURRENT->dev) != MAJOR_NR)
2321 panic(DEVICE_NAME ": request list destroyed");
2322 if (CURRENT->bh && !CURRENT->bh->b_lock)
2323 panic(DEVICE_NAME ": block not locked");
2324
2325 device = CURRENT->dev;
2326 set_fdc( DRIVE(device));
2327
2328 timer_table[FLOPPY_TIMER].expires = jiffies + DP->timeout;
2329 timer_active |= 1 << FLOPPY_TIMER;
2330 raw_cmd.flags=0;
2331 start_motor();
2332 if(test_bit( DRIVE(device), &fake_change) ||
2333 test_bit( DRIVE(device), &changed_floppies)){
2334 DPRINT("disk absent or changed during operation\n");
2335 REPEAT;
2336 }
2337 set_floppy(device);
2338 if (!floppy) {
2339 if (!probing){
2340 DRS->probed_format = 0;
2341 if ( next_valid_format() ){
2342 DPRINT("no autodetectable formats\n");
2343 floppy = NULL;
2344 REPEAT;
2345 }
2346 }
2347 probing = 1;
2348 floppy = floppy_type+DP->autodetect[DRS->probed_format];
2349 } else
2350 probing = 0;
2351 errors = & (CURRENT->errors);
2352 tmp = make_raw_rw_request();
2353 if ( tmp < 2 ){
2354 request_done(tmp);
2355 continue;
2356 }
2357
2358 if ( DRS->flags & FD_NEED_TWADDLE )
2359 twaddle();
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( inb_p(FD_DIR) & 0x80 )
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] = 2;
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 if (!(bh = getblk(dev,0,1024))){
2961 redo_fd_request();
2962 return 1;
2963 }
2964 if ( bh && ! bh->b_uptodate)
2965 ll_rw_block(READ, 1, &bh);
2966 redo_fd_request();
2967 wait_on_buffer(bh);
2968 brelse(bh);
2969 return 0;
2970 } else {
2971
2972 raw_cmd.flags=FD_RAW_NEED_SEEK|FD_RAW_NEED_DISK;
2973 raw_cmd.track=0;
2974 raw_cmd.cmd_count=0;
2975 cont = &poll_cont;
2976 wait_til_done(floppy_ready,0);
2977 }
2978 }
2979 redo_fd_request();
2980 }
2981 return 0;
2982 }
2983
2984 static struct file_operations floppy_fops = {
2985 NULL,
2986 floppy_read,
2987 floppy_write,
2988 NULL,
2989 NULL,
2990 fd_ioctl,
2991 NULL,
2992 floppy_open,
2993 floppy_release,
2994 block_fsync,
2995 NULL,
2996 check_floppy_change,
2997 floppy_revalidate,
2998 };
2999
3000
3001
3002
3003
3004
3005
3006
3007 static char get_fdc_version(void)
3008 {
3009 int r;
3010
3011 output_byte(FD_DUMPREGS);
3012 if ( FDCS->reset )
3013 return FDC_NONE;
3014 if ( (r = result()) <= 0x00)
3015 return FDC_NONE;
3016 if ((r==1) && (reply_buffer[0] == 0x80)){
3017 printk("FDC %d is a 8272A\n",fdc);
3018 return FDC_8272A;
3019 }
3020 if (r != 10) {
3021 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
3022 return FDC_UNKNOWN;
3023 }
3024 output_byte(FD_VERSION);
3025 r = result();
3026 if ((r == 1) && (reply_buffer[0] == 0x80)){
3027 printk("FDC %d is a 82072\n",fdc);
3028 return FDC_82072;
3029 }
3030 if ((r != 1) || (reply_buffer[0] != 0x90)) {
3031 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
3032 return FDC_UNKNOWN;
3033 }
3034 output_byte(FD_UNLOCK);
3035 r = result();
3036 if ((r == 1) && (reply_buffer[0] == 0x80)){
3037 printk("FDC %d is a pre-1991 82077\n", fdc);
3038 return FDC_82077_ORIG;
3039 }
3040 if ((r != 1) || (reply_buffer[0] != 0x00)) {
3041 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
3042 return FDC_UNKNOWN;
3043 }
3044 printk("FDC %d is a post-1991 82077\n",fdc);
3045 return FDC_82077;
3046 }
3047
3048 void floppy_init(void)
3049 {
3050 int i;
3051
3052 sti();
3053
3054 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
3055 printk("Unable to get major %d for floppy\n",MAJOR_NR);
3056 return;
3057 }
3058
3059 for(i=0; i<256; i++)
3060 if ( TYPE(i))
3061 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
3062 else
3063 floppy_sizes[i] = MAX_DISK_SIZE;
3064
3065 blk_size[MAJOR_NR] = floppy_sizes;
3066 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3067 timer_table[FLOPPY_TIMER].fn = floppy_shutdown;
3068 timer_active &= ~(1 << FLOPPY_TIMER);
3069 config_types();
3070
3071 fdc_state[0].address = 0x3f0;
3072 #if N_FDC > 1
3073 fdc_state[1].address = 0x370;
3074 #endif
3075 for (i = 0 ; i < N_FDC ; i++) {
3076 fdc = i;
3077 FDCS->dtr = -1;
3078 FDCS->dor = 0;
3079 FDCS->reset = 0;
3080 FDCS->version = FDC_NONE;
3081 set_dor(fdc, ~0, 0xc );
3082 }
3083
3084
3085 for (i = 0; i < N_DRIVE ; i++) {
3086 current_drive = i;
3087 DRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE;
3088 DRS->generation = 0;
3089 DRS->keep_data = 0;
3090 DRS->fd_ref = 0;
3091 DRS->fd_device = 0;
3092 DRWE->write_errors = 0;
3093 DRWE->first_error_sector = 0;
3094 DRWE->first_error_generation = 0;
3095 DRWE->last_error_sector = 0;
3096 DRWE->last_error_generation = 0;
3097 DRWE->badness = 0;
3098 }
3099
3100 floppy_grab_irq_and_dma();
3101 for (i = 0 ; i < N_FDC ; i++) {
3102 fdc = i;
3103 FDCS->rawcmd = 2;
3104 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED,0))
3105 continue;
3106
3107 FDCS->version = get_fdc_version();
3108 if (FDCS->version == FDC_NONE)
3109 continue;
3110
3111
3112
3113
3114
3115 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
3116 user_reset_fdc(-1,FD_RESET_ALWAYS,0);
3117 }
3118 fdc=0;
3119 current_drive = 0;
3120 floppy_release_irq_and_dma();
3121 initialising=0;
3122 }
3123
3124 static int floppy_grab_irq_and_dma(void)
3125 {
3126 cli();
3127 if (usage_count++){
3128 sti();
3129 return 0;
3130 }
3131 sti();
3132 if (request_irq(FLOPPY_IRQ, floppy_interrupt, SA_INTERRUPT, "floppy")) {
3133 DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
3134 FLOPPY_IRQ);
3135 return -1;
3136 }
3137 if (request_dma(FLOPPY_DMA,"floppy")) {
3138 DPRINT1("Unable to grab DMA%d for the floppy driver\n",
3139 FLOPPY_DMA);
3140 free_irq(FLOPPY_IRQ);
3141 return -1;
3142 }
3143 enable_irq(FLOPPY_IRQ);
3144 return 0;
3145 }
3146
3147 static void floppy_release_irq_and_dma(void)
3148 {
3149 cli();
3150 if (--usage_count){
3151 sti();
3152 return;
3153 }
3154 sti();
3155 disable_dma(FLOPPY_DMA);
3156 free_dma(FLOPPY_DMA);
3157 disable_irq(FLOPPY_IRQ);
3158 free_irq(FLOPPY_IRQ);
3159 #ifdef HAVE_2_CONTROLLERS
3160
3161
3162 set_dor(0, ~0, 8 );
3163 set_dor(1, ~8, 0 );
3164 #endif
3165 }