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 #define SILENT_DC_CLEAR
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,0x6C,"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,0x6C,"h1600" },
321 { 3520,22,2,80,0,0x1C,0x08,0xCF,0x6C,"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,0x6C,"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 DRS->track = PROVEN_ABSENT;
1283 cont->done(0);
1284 cont->redo();
1285 return;
1286 case NEED_2_RECAL:
1287 #ifdef DEBUGT
1288 debugt("recal interrupt need 2 recal:");
1289 #endif
1290
1291
1292
1293
1294
1295 DRS->flags &= ~FD_DISK_NEWCHANGE;
1296
1297 default:
1298 #ifdef DEBUGT
1299 debugt("recal interrupt default:");
1300 #endif
1301
1302
1303
1304
1305
1306 DRS->track = NEED_1_RECAL;
1307 break;
1308 }
1309 } else
1310 DRS->track = ST1;
1311 seek_floppy();
1312 }
1313
1314
1315
1316
1317
1318 static void unexpected_floppy_interrupt(void)
1319 {
1320 int i;
1321 if ( initialising )
1322 return;
1323 DPRINT("unexpected interrupt\n");
1324 if ( inr >= 0 )
1325 for(i=0; i<inr; i++)
1326 printk("%d %x\n", i, reply_buffer[i] );
1327 while(1){
1328 output_byte(FD_SENSEI);
1329 inr=result();
1330 if ( inr != 2 )
1331 break;
1332 printk("sensei\n");
1333 for(i=0; i<inr; i++)
1334 printk("%d %x\n", i, reply_buffer[i] );
1335 }
1336 FDCS->reset = 1;
1337 }
1338
1339 struct tq_struct floppy_tq =
1340 { 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
1341
1342
1343 static void floppy_interrupt(int unused)
1344 {
1345 void (*handler)(void) = DEVICE_INTR;
1346
1347 CLEAR_INTR;
1348 if ( fdc >= N_FDC ){
1349 printk("floppy interrupt on bizarre fdc\n");
1350 return;
1351 }
1352 inr = result();
1353 if (!handler){
1354 unexpected_floppy_interrupt();
1355 return;
1356 }
1357 if ( inr == 0 ){
1358 do {
1359 output_byte(FD_SENSEI);
1360 inr = result();
1361 } while ( (ST0 & 0x83) != UNIT(current_drive) && inr == 2);
1362 }
1363 floppy_tq.routine = (void *)(void *) handler;
1364 queue_task_irq(&floppy_tq, &tq_timer);
1365 }
1366
1367 static void recalibrate_floppy(void)
1368 {
1369 #ifdef DEBUGT
1370 debugt("recalibrate floppy:");
1371 #endif
1372 SET_INTR(recal_interrupt);
1373 output_byte(FD_RECALIBRATE);
1374 LAST_OUT(UNIT(current_drive));
1375 }
1376
1377
1378
1379
1380 static void reset_interrupt(void)
1381 {
1382 #ifdef DEBUGT
1383 debugt("reset interrupt:");
1384 #endif
1385 fdc_specify();
1386 result();
1387 if ( FDCS->reset )
1388 cont->error();
1389 cont->redo();
1390 }
1391
1392
1393
1394
1395
1396 static void reset_fdc(void)
1397 {
1398 SET_INTR(reset_interrupt);
1399 FDCS->reset = 0;
1400 reset_fdc_info(0);
1401 if ( FDCS->version >= FDC_82077 )
1402 outb_p(0x80 | ( FDCS->dtr &3), FD_STATUS);
1403 else {
1404 outb_p(FDCS->dor & ~0x04, FD_DOR);
1405 udelay(FD_RESET_DELAY);
1406 outb(FDCS->dor, FD_DOR);
1407 }
1408 }
1409
1410 static void empty(void)
1411 {
1412 }
1413
1414 void show_floppy(void)
1415 {
1416 int i;
1417
1418 printk("\n");
1419 printk("floppy driver state\n");
1420 printk("-------------------\n");
1421 for(i=0; i<N_FDC; i++){
1422 printk("dor %d = %x\n", i, fdc_state[i].dor );
1423 outb_p(fdc_state[i].address+2, fdc_state[i].dor);
1424 udelay(1000);
1425 }
1426 printk("status=%x\n", inb_p(FD_STATUS));
1427 printk("fdc_busy=%d\n", fdc_busy);
1428 if( DEVICE_INTR)
1429 printk("DEVICE_INTR=%p\n", DEVICE_INTR);
1430 if(floppy_tq.sync)
1431 printk("floppy_tq.routine=%p\n", floppy_tq.routine);
1432 if(fd_timer.prev)
1433 printk("fd_timer.function=%p\n", fd_timer.function);
1434 if( timer_active & (1 << FLOPPY_TIMER)){
1435 printk("timer_table=%p\n",timer_table[FLOPPY_TIMER].fn);
1436 printk("expires=%ld\n",timer_table[FLOPPY_TIMER].expires);
1437 printk("now=%ld\n",jiffies);
1438 }
1439 printk("cont=%p\n", cont);
1440 printk("CURRENT=%p\n", CURRENT);
1441 printk("command_status=%d\n", command_status);
1442 printk("\n");
1443 }
1444
1445 static void floppy_shutdown(void)
1446 {
1447 CLEAR_INTR;
1448 floppy_tq.routine = (void *)(void *) empty;
1449 del_timer( &fd_timer);
1450
1451 disable_dma(FLOPPY_DMA);
1452
1453
1454 if(!initialising)
1455 DPRINT("floppy timeout\n");
1456 FDCS->reset = 1;
1457 cont->done(0);
1458 cont->redo();
1459 }
1460
1461
1462 static void start_motor(void)
1463 {
1464 int mask, data;
1465
1466 mask = 0xfc;
1467 data = UNIT(current_drive);
1468 if ( (FDCS->dor & 0x03) != UNIT(current_drive) )
1469
1470 DRS->select_date = jiffies;
1471
1472 if (!(raw_cmd.flags & FD_RAW_NO_MOTOR)){
1473 if(!(FDCS->dor & ( 0x10 << UNIT(current_drive) ) )){
1474 set_debugt();
1475
1476 DRS->first_read_date = 0;
1477
1478 DRS->spinup_date = jiffies;
1479 data |= (0x10 << UNIT(current_drive));
1480 }
1481 } else
1482 if (FDCS->dor & ( 0x10 << UNIT(current_drive) ) )
1483 mask &= ~(0x10 << UNIT(current_drive));
1484
1485
1486 del_timer(motor_off_timer + current_drive);
1487 set_dor( fdc, mask, data);
1488 if( raw_cmd.flags & FD_RAW_NO_MOTOR)
1489 return;
1490
1491 if(disk_change(current_drive))
1492 twaddle();
1493
1494
1495 return;
1496 }
1497
1498 static void floppy_ready(void)
1499 {
1500 CHECK_RESET;
1501 start_motor();
1502
1503
1504 if(wait_for_completion(current_drive,
1505 DRS->select_date+DP->select_delay,
1506 (timeout_fn) floppy_ready))
1507 return;
1508 fdc_dtr();
1509 if ( raw_cmd.flags & FD_RAW_NEED_SEEK ){
1510 perpendicular_mode();
1511 fdc_specify();
1512 seek_floppy();
1513 } else
1514 setup_rw_floppy();
1515 }
1516
1517 static void floppy_start(void)
1518 {
1519 timer_table[FLOPPY_TIMER].expires = jiffies + DP->timeout;
1520 timer_active |= 1 << FLOPPY_TIMER;
1521 scandrives();
1522 floppy_ready();
1523 }
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539 static void do_wakeup(void)
1540 {
1541 timer_active &= ~(1 << FLOPPY_TIMER);
1542 cont = 0;
1543 command_status += 2;
1544 wake_up(&command_done);
1545 }
1546
1547 static struct cont_t wakeup_cont={
1548 empty,
1549 do_wakeup,
1550 empty,
1551 (done_f)empty
1552 };
1553
1554 static int wait_til_done( void (*handler)(void ), int interruptible )
1555 {
1556 int ret;
1557
1558 floppy_tq.routine = (void *)(void *) handler;
1559 queue_task(&floppy_tq, &tq_timer);
1560
1561 cli();
1562 while(command_status < 2 && NO_SIGNAL)
1563 if (current->pid)
1564 interruptible_sleep_on(&command_done);
1565 else {
1566 sti();
1567 run_task_queue(&tq_timer);
1568 cli();
1569 }
1570 if(command_status < 2){
1571 sti();
1572 floppy_shutdown();
1573 redo_fd_request();
1574 return -EINTR;
1575 }
1576 sti();
1577
1578 if ( FDCS->reset )
1579 command_status = FD_COMMAND_ERROR;
1580 if ( command_status == FD_COMMAND_OKAY )
1581 ret=0;
1582 else
1583 ret=-EIO;
1584 command_status = FD_COMMAND_NONE;
1585 return ret;
1586 }
1587
1588 static void generic_done(int result)
1589 {
1590 command_status = result;
1591 cont = &wakeup_cont;
1592 }
1593
1594 static void generic_success(void)
1595 {
1596 generic_done(1);
1597 }
1598
1599 static void generic_failure(void)
1600 {
1601 generic_done(0);
1602 }
1603
1604 static void success_and_wakeup(void)
1605 {
1606 generic_success();
1607 do_wakeup();
1608 }
1609
1610 static void failure_and_wakeup(void)
1611 {
1612 generic_failure();
1613 do_wakeup();
1614 }
1615
1616
1617
1618
1619
1620
1621 static int next_valid_format(void)
1622 {
1623 int probed_format;
1624 while(1){
1625 probed_format = DRS->probed_format;
1626 if ( probed_format > N_DRIVE ||
1627 ! DP->autodetect[probed_format] ){
1628 DRS->probed_format = 0;
1629 return 1;
1630 }
1631 if ( floppy_type[DP->autodetect[probed_format]].sect ){
1632 DRS->probed_format = probed_format;
1633 return 0;
1634 }
1635 probed_format++;
1636 }
1637 }
1638
1639 static void bad_flp_intr(void)
1640 {
1641 if ( probing ){
1642 DRS->probed_format++;
1643 if ( !next_valid_format())
1644 return;
1645 }
1646 (*errors)++;
1647 if (*errors > DRWE->badness)
1648 DRWE->badness = *errors;
1649 if (*errors > DP->max_errors.abort)
1650 cont->done(0);
1651 if (*errors > DP->max_errors.reset)
1652 FDCS->reset = 1;
1653 else if (*errors > DP->max_errors.recal)
1654 DRS->track = NEED_2_RECAL;
1655 }
1656
1657 static void set_floppy(int device)
1658 {
1659 if (TYPE(device))
1660 floppy = TYPE(device) + floppy_type;
1661 else
1662 floppy = current_type[ DRIVE(device) ];
1663 }
1664
1665
1666
1667
1668
1669 static void format_interrupt(void)
1670 {
1671 switch (interpret_errors()){
1672 case 1:
1673 cont->error();
1674 case 2:
1675 break;
1676 case 0:
1677 cont->done(1);
1678 }
1679 cont->redo();
1680 }
1681
1682 #define CODE2SIZE (ssize = ( ( 1 << SIZECODE ) + 3 ) >> 2)
1683 #define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80 ) >>1))
1684 #define CT(x) ( (x) | 0x40 )
1685 static void setup_format_params(void)
1686 {
1687 struct fparm {
1688 unsigned char track,head,sect,size;
1689 } *here = (struct fparm *)floppy_track_buffer;
1690 int il,n;
1691 int count,head_shift,track_shift;
1692
1693 raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
1694 FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK;
1695 raw_cmd.rate = floppy->rate & 0x3;
1696 raw_cmd.cmd_count = NR_F;
1697 COMMAND = FM_MODE(floppy,FD_FORMAT);
1698 DR_SELECT = UNIT(current_drive) + ( format_req.head << 2 );
1699 F_SIZECODE = FD_SIZECODE(floppy);
1700 F_SECT_PER_TRACK = floppy->sect << 2 >> F_SIZECODE;
1701 F_GAP = floppy->fmt_gap;
1702 F_FILL = FD_FILL_BYTE;
1703
1704 current_addr = floppy_track_buffer;
1705 raw_cmd.length = 4 * F_SECT_PER_TRACK;
1706
1707
1708 head_shift = (F_SECT_PER_TRACK + 5) / 6;
1709
1710
1711 track_shift = 2 * head_shift + 1;
1712
1713
1714 n = (track_shift * format_req.track + head_shift * format_req.head )
1715 % F_SECT_PER_TRACK;
1716
1717
1718 il = 1;
1719 if (floppy->sect > DP->interleave_sect && F_SIZECODE == 2)
1720 il++;
1721
1722
1723 for (count = 0; count < F_SECT_PER_TRACK; ++count) {
1724 here[count].track = format_req.track;
1725 here[count].head = format_req.head;
1726 here[count].sect = 0;
1727 here[count].size = F_SIZECODE;
1728 }
1729
1730 for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
1731 here[n].sect = count;
1732 n = (n+il) % F_SECT_PER_TRACK;
1733 if (here[n].sect) {
1734 ++n;
1735 if (n>= F_SECT_PER_TRACK) {
1736 n-=F_SECT_PER_TRACK;
1737 while (here[n].sect) ++n;
1738 }
1739 }
1740 }
1741 }
1742
1743 static void redo_format(void)
1744 {
1745 raw_cmd.track = format_req.track << floppy->stretch;
1746 buffer_track = -1;
1747 setup_format_params();
1748 floppy_start();
1749 #ifdef DEBUGT
1750 debugt("queue format request");
1751 #endif
1752 }
1753
1754 static struct cont_t format_cont={
1755 format_interrupt,
1756 redo_format,
1757 bad_flp_intr,
1758 generic_done };
1759
1760 static int do_format(int device, struct format_descr *tmp_format_req)
1761 {
1762 int okay;
1763
1764 LOCK_FDC(DRIVE(device),1);
1765 set_floppy(device);
1766 if (!floppy ||
1767 tmp_format_req->track >= floppy->track ||
1768 tmp_format_req->head >= floppy->head){
1769 redo_fd_request();
1770 return -EINVAL;
1771 }
1772 format_req = *tmp_format_req;
1773 format_errors = 0;
1774 cont = &format_cont;
1775 errors = &format_errors;
1776 CALL(okay=wait_til_done(redo_format,1));
1777 redo_fd_request();
1778 return okay;
1779 }
1780
1781
1782
1783
1784
1785
1786
1787
1788 static void request_done(int uptodate)
1789 {
1790 int block;
1791
1792 probing = 0;
1793 timer_active &= ~(1 << FLOPPY_TIMER);
1794
1795 if (!CURRENT){
1796 DPRINT("request list destroyed in floppy request done\n");
1797 return;
1798 }
1799 if (uptodate){
1800
1801
1802 block = current_count_sectors + CURRENT->sector;
1803 if (block > DRS->maxblock)
1804 DRS->maxblock=block;
1805 if ( block > floppy->sect)
1806 DRS->maxtrack = 1;
1807
1808
1809 while (current_count_sectors && CURRENT &&
1810 current_count_sectors >= CURRENT->current_nr_sectors ){
1811 current_count_sectors -= CURRENT->current_nr_sectors;
1812 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
1813 CURRENT->sector += CURRENT->current_nr_sectors;
1814 end_request(1);
1815 }
1816 if ( current_count_sectors && CURRENT){
1817
1818 CURRENT->buffer += current_count_sectors <<9;
1819 CURRENT->current_nr_sectors -= current_count_sectors;
1820 CURRENT->nr_sectors -= current_count_sectors;
1821 CURRENT->sector += current_count_sectors;
1822 return;
1823 }
1824
1825 if ( current_count_sectors && ! CURRENT )
1826 DPRINT("request list destroyed in floppy request done\n");
1827
1828 } else {
1829 if(CURRENT->cmd == WRITE) {
1830
1831 DRWE->write_errors++;
1832 if(DRWE->write_errors == 1) {
1833 DRWE->first_error_sector = CURRENT->sector;
1834 DRWE->first_error_generation = DRS->generation;
1835 }
1836 DRWE->last_error_sector = CURRENT->sector;
1837 DRWE->last_error_generation = DRS->generation;
1838 }
1839 end_request(0);
1840 }
1841 }
1842
1843
1844 static void rw_interrupt(void)
1845 {
1846 int nr_sectors, ssize;
1847
1848 if ( ! DRS->first_read_date )
1849 DRS->first_read_date = jiffies;
1850
1851 nr_sectors = 0;
1852 CODE2SIZE;
1853 nr_sectors = ((R_TRACK-TRACK)*floppy->head+R_HEAD-HEAD) *
1854 floppy->sect + ((R_SECTOR-SECTOR) << SIZECODE >> 2) -
1855 (sector_t % floppy->sect) % ssize;
1856
1857 #ifdef SANITY
1858 if ( nr_sectors > current_count_sectors + ssize -
1859 (current_count_sectors + sector_t) % ssize +
1860 sector_t % ssize){
1861 DPRINT2("long rw: %x instead of %lx\n",
1862 nr_sectors, current_count_sectors);
1863 printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
1864 printk("rh=%d h=%d\n", R_HEAD, HEAD);
1865 printk("rt=%d t=%d\n", R_TRACK, TRACK);
1866 printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
1867 sector_t, ssize);
1868 }
1869 #endif
1870 if ( nr_sectors < 0 )
1871 nr_sectors = 0;
1872 if ( nr_sectors < current_count_sectors )
1873 current_count_sectors = nr_sectors;
1874
1875 switch (interpret_errors()){
1876 case 2:
1877 cont->redo();
1878 return;
1879 case 1:
1880 if ( !current_count_sectors){
1881 cont->error();
1882 cont->redo();
1883 return;
1884 }
1885 break;
1886 case 0:
1887 if ( !current_count_sectors){
1888 cont->redo();
1889 return;
1890 }
1891 current_type[current_drive] = floppy;
1892 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
1893 floppy->size >> 1;
1894 break;
1895 }
1896
1897 if (probing) {
1898 if (DP->flags & FTD_MSG)
1899 DPRINT2("Auto-detected floppy type %s in fd%d\n",
1900 floppy->name,current_drive);
1901 current_type[current_drive] = floppy;
1902 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
1903 floppy->size >> 1;
1904 probing = 0;
1905 }
1906
1907 if ( CT(COMMAND) != FD_READ || current_addr == CURRENT->buffer ){
1908
1909 cont->done(1);
1910 } else if ( CT(COMMAND) == FD_READ){
1911 buffer_track = raw_cmd.track;
1912 buffer_drive = current_drive;
1913 if ( nr_sectors + sector_t > buffer_max )
1914 buffer_max = nr_sectors + sector_t;
1915 }
1916 cont->redo();
1917 }
1918
1919
1920 static int buffer_chain_size(void)
1921 {
1922 struct buffer_head *bh;
1923 int size;
1924 char *base;
1925
1926 base = CURRENT->buffer;
1927 size = CURRENT->current_nr_sectors << 9;
1928 bh = CURRENT->bh;
1929
1930 #ifdef SANITY
1931 if ( !bh ){
1932 DPRINT("null request in buffer_chain_size\n");
1933 return size >> 9;
1934 }
1935 #endif
1936
1937 bh = bh->b_reqnext;
1938 while ( bh && bh->b_data == base + size ){
1939 size += bh->b_size;
1940 bh = bh->b_reqnext;
1941 }
1942 return size >> 9;
1943 }
1944
1945
1946 static int transfer_size(int ssize, int max_sector, int max_size)
1947 {
1948 if ( max_sector > sector_t + max_size)
1949 max_sector = sector_t + max_size;
1950
1951
1952 max_sector -= (max_sector % floppy->sect ) % ssize;
1953
1954
1955 current_count_sectors = max_sector - sector_t ;
1956
1957 return max_sector;
1958 }
1959
1960
1961
1962
1963 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
1964 {
1965 int remaining;
1966 struct buffer_head *bh;
1967 char *buffer, *dma_buffer;
1968 int size;
1969
1970 if ( max_sector > max_sector_2 )
1971 max_sector = max_sector_2;
1972
1973 max_sector = transfer_size(ssize, max_sector, CURRENT->nr_sectors);
1974
1975 if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
1976 buffer_max > sector_t + CURRENT->nr_sectors){
1977 current_count_sectors = buffer_max - sector_t;
1978 if ( current_count_sectors > CURRENT->nr_sectors )
1979 current_count_sectors = CURRENT->nr_sectors;
1980 }
1981 remaining = current_count_sectors << 9;
1982 #ifdef SANITY
1983 if ((remaining >> 9) > CURRENT->nr_sectors &&
1984 CT(COMMAND) == FD_WRITE ){
1985 DPRINT("in copy buffer\n");
1986 printk("current_count_sectors=%ld\n", current_count_sectors);
1987 printk("remaining=%d\n", remaining >> 9);
1988 printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
1989 printk("CURRENT->current_nr_sectors=%ld\n",
1990 CURRENT->current_nr_sectors);
1991 printk("max_sector=%d\n", max_sector);
1992 printk("ssize=%d\n", ssize);
1993 }
1994 #endif
1995
1996 if ( max_sector > buffer_max )
1997 buffer_max = max_sector;
1998
1999 dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
2000
2001 bh = CURRENT->bh;
2002 size = CURRENT->current_nr_sectors << 9;
2003 buffer = CURRENT->buffer;
2004
2005 while ( remaining > 0){
2006 if ( size > remaining )
2007 size = remaining;
2008 #ifdef SANITY
2009 if (!bh){
2010 DPRINT("bh=null in copy buffer before copy\n");
2011 break;
2012 }
2013 if (dma_buffer + size >
2014 floppy_track_buffer + (max_buffer_sectors << 10) ||
2015 dma_buffer < floppy_track_buffer ){
2016 DPRINT1("buffer overrun in copy buffer %d\n",
2017 (floppy_track_buffer - dma_buffer) >>9);
2018 printk("sector_t=%d buffer_min=%d\n",
2019 sector_t, buffer_min);
2020 printk("current_count_sectors=%ld\n",
2021 current_count_sectors);
2022 if ( CT(COMMAND) == FD_READ )
2023 printk("read\n");
2024 if ( CT(COMMAND) == FD_READ )
2025 printk("write\n");
2026 break;
2027 }
2028 if ( ((int)buffer) % 512 )
2029 DPRINT1("%p buffer not aligned\n", buffer);
2030 #endif
2031 if ( CT(COMMAND) == FD_READ )
2032 memcpy( buffer, dma_buffer, size);
2033 else
2034 memcpy( dma_buffer, buffer, size);
2035 remaining -= size;
2036 if ( !remaining)
2037 break;
2038
2039 dma_buffer += size;
2040 bh = bh->b_reqnext;
2041 #ifdef SANITY
2042 if ( !bh){
2043 DPRINT("bh=null in copy buffer after copy\n");
2044 break;
2045 }
2046 #endif
2047 size = bh->b_size;
2048 buffer = bh->b_data;
2049 }
2050 #ifdef SANITY
2051 if ( remaining ){
2052 if ( remaining > 0 )
2053 max_sector -= remaining >> 9;
2054 DPRINT1("weirdness: remaining %d\n", remaining>>9);
2055 }
2056 #endif
2057 }
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069 static int make_raw_rw_request(void)
2070 {
2071 int aligned_sector_t;
2072 int max_sector, max_size, tracksize, ssize;
2073
2074 current_drive = DRIVE(CURRENT->dev);
2075
2076 raw_cmd.flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
2077 FD_RAW_NEED_SEEK;
2078 raw_cmd.cmd_count = NR_RW;
2079 if (CURRENT->cmd == READ){
2080 raw_cmd.flags |= FD_RAW_READ;
2081 COMMAND = FM_MODE(floppy,FD_READ);
2082 } else if (CURRENT->cmd == WRITE){
2083 raw_cmd.flags |= FD_RAW_WRITE;
2084 COMMAND = FM_MODE(floppy,FD_WRITE);
2085 } else {
2086 DPRINT("make_raw_rw_request: unknown command\n");
2087 return 0;
2088 }
2089
2090 max_sector = floppy->sect * floppy->head;
2091 TRACK = CURRENT->sector / max_sector;
2092 sector_t = CURRENT->sector % max_sector;
2093 if ( floppy->track && TRACK >= floppy->track )
2094 return 0;
2095 HEAD = sector_t / floppy->sect;
2096
2097 if ( (DRS->flags & FD_NEED_TWADDLE) && sector_t < floppy->sect )
2098 max_sector = floppy->sect;
2099
2100
2101 if ( (floppy->rate & FD_2M ) && (!TRACK) && (!HEAD)){
2102 max_sector = 2 * floppy->sect / 3;
2103 if (sector_t >= max_sector){
2104 current_count_sectors = (floppy->sect - sector_t);
2105 if ( current_count_sectors > CURRENT->nr_sectors )
2106 current_count_sectors = CURRENT->nr_sectors;
2107 return 1;
2108 }
2109 SIZECODE = 2;
2110 } else
2111 SIZECODE = FD_SIZECODE(floppy);
2112 raw_cmd.rate = floppy->rate & 3;
2113 if ((floppy->rate & FD_2M) &&
2114 (TRACK || HEAD ) &&
2115 raw_cmd.rate == 2)
2116 raw_cmd.rate = 1;
2117
2118 if ( SIZECODE )
2119 SIZECODE2 = 0xff;
2120 else
2121 SIZECODE2 = 0x80;
2122 raw_cmd.track = TRACK << floppy->stretch;
2123 DR_SELECT = UNIT(current_drive) + ( HEAD << 2 );
2124 GAP = floppy->gap;
2125 CODE2SIZE;
2126 SECT_PER_TRACK = floppy->sect << 2 >> SIZECODE;
2127 SECTOR = ((sector_t % floppy->sect) << 2 >> SIZECODE) + 1;
2128 tracksize = floppy->sect - floppy->sect % ssize;
2129 if ( tracksize < floppy->sect ){
2130 SECT_PER_TRACK ++;
2131 if ( tracksize <= sector_t % floppy->sect)
2132 SECTOR--;
2133 while ( tracksize <= sector_t % floppy->sect){
2134 while( tracksize + ssize > floppy->sect ){
2135 SIZECODE--;
2136 ssize >>= 1;
2137 }
2138 SECTOR++; SECT_PER_TRACK ++;
2139 tracksize += ssize;
2140 }
2141 max_sector = HEAD * floppy->sect + tracksize;
2142 } else if ( !TRACK && !HEAD && !( floppy->rate & FD_2M ) && probing)
2143 max_sector = floppy->sect;
2144
2145 aligned_sector_t = sector_t - ( sector_t % floppy->sect ) % ssize;
2146 max_size = CURRENT->nr_sectors;
2147 if ((raw_cmd.track == buffer_track) && (current_drive == buffer_drive) &&
2148 (sector_t >= buffer_min) && (sector_t < buffer_max)) {
2149
2150 if (CT(COMMAND) == FD_READ) {
2151 copy_buffer(1, max_sector, buffer_max);
2152 return 1;
2153 }
2154 } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
2155 if (CT(COMMAND) == FD_WRITE){
2156 if(sector_t + CURRENT->nr_sectors > ssize &&
2157 sector_t + CURRENT->nr_sectors < ssize + ssize)
2158 max_size = ssize + ssize;
2159 else
2160 max_size = ssize;
2161 }
2162 raw_cmd.flags &= ~FD_RAW_WRITE;
2163 raw_cmd.flags |= FD_RAW_READ;
2164 COMMAND = FM_MODE(floppy,FD_READ);
2165 } else if ((long)CURRENT->buffer <= LAST_DMA_ADDR ) {
2166 int direct, indirect;
2167
2168 indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
2169 sector_t;
2170
2171 max_size = buffer_chain_size();
2172 if ( max_size > ( LAST_DMA_ADDR - ((long) CURRENT->buffer))>>9)
2173 max_size=(LAST_DMA_ADDR - ((long)CURRENT->buffer))>>9;
2174
2175 if ( ((max_size << 9) + ((long) CURRENT->buffer)) / K_64 !=
2176 ((long) CURRENT->buffer ) / K_64 )
2177 max_size = ( K_64 - ((long) CURRENT->buffer) % K_64)>>9;
2178 direct = transfer_size(ssize,max_sector,max_size) - sector_t;
2179
2180
2181
2182
2183
2184
2185
2186 if ((indirect - sector_t) * 2 > (direct - sector_t) * 3 &&
2187 *errors < DP->max_errors.read_track &&
2188
2189 ( ( !probing || (DP->read_track &
2190 (1 <<DRS->probed_format))))){
2191 max_size = CURRENT->nr_sectors;
2192 } else {
2193 current_addr = CURRENT->buffer;
2194 raw_cmd.length = current_count_sectors << 9;
2195 return 2;
2196 }
2197 }
2198
2199 if ( CT(COMMAND) == FD_READ )
2200 max_size = max_sector;
2201
2202
2203 if (buffer_track != raw_cmd.track ||
2204 buffer_drive !=current_drive ||
2205 sector_t < buffer_min ||
2206 ((CT(COMMAND) == FD_READ ||
2207 (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize ))&&
2208 max_sector > 2 * max_buffer_sectors + buffer_min &&
2209 max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
2210 ){
2211 buffer_track = -1;
2212 buffer_drive = current_drive;
2213 buffer_max = buffer_min = aligned_sector_t;
2214 }
2215 current_addr = floppy_track_buffer +((aligned_sector_t-buffer_min )<<9);
2216
2217 if ( CT(COMMAND) == FD_WRITE ){
2218
2219
2220
2221
2222 #ifdef SANITY
2223 if (sector_t != aligned_sector_t && buffer_track == -1 )
2224 DPRINT("internal error offset !=0 on write\n");
2225 #endif
2226 buffer_track = raw_cmd.track;
2227 buffer_drive = current_drive;
2228 copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min);
2229 } else
2230 transfer_size(ssize, max_sector,
2231 2*max_buffer_sectors+buffer_min-aligned_sector_t);
2232
2233
2234 raw_cmd.length = sector_t+current_count_sectors-aligned_sector_t;
2235 raw_cmd.length = ((raw_cmd.length -1)|(ssize-1))+1;
2236 raw_cmd.length <<= 9;
2237 #ifdef SANITY
2238 if ((raw_cmd.length < current_count_sectors << 9) ||
2239 (current_addr != CURRENT->buffer &&
2240 CT(COMMAND) == FD_WRITE &&
2241 (aligned_sector_t + (raw_cmd.length >> 9) > buffer_max ||
2242 aligned_sector_t < buffer_min )) ||
2243 raw_cmd.length % ( 128 << SIZECODE ) ||
2244 raw_cmd.length <= 0 || current_count_sectors <= 0){
2245 DPRINT2("fractionary current count b=%lx s=%lx\n",
2246 raw_cmd.length, current_count_sectors);
2247 if ( current_addr != CURRENT->buffer )
2248 printk("addr=%d, length=%ld\n",
2249 (current_addr - floppy_track_buffer ) >> 9,
2250 current_count_sectors);
2251 printk("st=%d ast=%d mse=%d msi=%d\n",
2252 sector_t, aligned_sector_t, max_sector, max_size);
2253 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2254 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2255 COMMAND, SECTOR, HEAD, TRACK);
2256 printk("buffer drive=%d\n", buffer_drive);
2257 printk("buffer track=%d\n", buffer_track);
2258 printk("buffer_min=%d\n", buffer_min );
2259 printk("buffer_max=%d\n", buffer_max );
2260 return 0;
2261 }
2262
2263 if (current_addr != CURRENT->buffer ){
2264 if (current_addr < floppy_track_buffer ||
2265 current_count_sectors < 0 ||
2266 raw_cmd.length < 0 ||
2267 current_addr + raw_cmd.length >
2268 floppy_track_buffer + (max_buffer_sectors << 10)){
2269 DPRINT("buffer overrun in schedule dma\n");
2270 printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2271 sector_t, buffer_min,
2272 raw_cmd.length >> 9 );
2273 printk("current_count_sectors=%ld\n",
2274 current_count_sectors);
2275 if ( CT(COMMAND) == FD_READ )
2276 printk("read\n");
2277 if ( CT(COMMAND) == FD_READ )
2278 printk("write\n");
2279 return 0;
2280 }
2281 } else if (raw_cmd.length > CURRENT->nr_sectors << 9 ||
2282 current_count_sectors > CURRENT->nr_sectors){
2283 DPRINT("buffer overrun in direct transfer\n");
2284 return 0;
2285 } else if ( raw_cmd.length < current_count_sectors << 9 ){
2286 DPRINT("more sectors than bytes\n");
2287 printk("bytes=%ld\n", raw_cmd.length >> 9 );
2288 printk("sectors=%ld\n", current_count_sectors);
2289 }
2290 #endif
2291 return 2;
2292 }
2293
2294 static struct cont_t rw_cont={
2295 rw_interrupt,
2296 redo_fd_request,
2297 bad_flp_intr,
2298 request_done };
2299
2300 static void redo_fd_request(void)
2301 {
2302 #define REPEAT {request_done(0); continue; }
2303 int device;
2304 int tmp;
2305
2306 if (current_drive < N_DRIVE)
2307 floppy_off(current_drive);
2308
2309 if (CURRENT && CURRENT->dev < 0) return;
2310
2311 cont = &rw_cont;
2312 while(1){
2313 if (!CURRENT) {
2314 CLEAR_INTR;
2315 unlock_fdc();
2316 return;
2317 }
2318 if (MAJOR(CURRENT->dev) != MAJOR_NR)
2319 panic(DEVICE_NAME ": request list destroyed");
2320 if (CURRENT->bh && !CURRENT->bh->b_lock)
2321 panic(DEVICE_NAME ": block not locked");
2322
2323 device = CURRENT->dev;
2324 set_fdc( DRIVE(device));
2325
2326 timer_table[FLOPPY_TIMER].expires = jiffies + DP->timeout;
2327 timer_active |= 1 << FLOPPY_TIMER;
2328 raw_cmd.flags=0;
2329 start_motor();
2330 if(test_bit( DRIVE(device), &fake_change) ||
2331 test_bit( DRIVE(device), &changed_floppies)){
2332 DPRINT("disk absent or changed during operation\n");
2333 REPEAT;
2334 }
2335 set_floppy(device);
2336 if (!floppy) {
2337 if (!probing){
2338 DRS->probed_format = 0;
2339 if ( next_valid_format() ){
2340 DPRINT("no autodetectable formats\n");
2341 floppy = NULL;
2342 REPEAT;
2343 }
2344 }
2345 probing = 1;
2346 floppy = floppy_type+DP->autodetect[DRS->probed_format];
2347 } else
2348 probing = 0;
2349 errors = & (CURRENT->errors);
2350 tmp = make_raw_rw_request();
2351 if ( tmp < 2 ){
2352 request_done(tmp);
2353 continue;
2354 }
2355
2356 if ( DRS->flags & FD_NEED_TWADDLE )
2357 twaddle();
2358 floppy_tq.routine = (void *)(void *) floppy_start;
2359 queue_task(&floppy_tq, &tq_timer);
2360 #ifdef DEBUGT
2361 debugt("queue fd request");
2362 #endif
2363 return;
2364 }
2365 #undef REPEAT
2366 }
2367
2368 void do_fd_request(void)
2369 {
2370 if (fdc_busy)
2371
2372
2373 return;
2374
2375 floppy_grab_irq_and_dma();
2376 fdc_busy=1;
2377 redo_fd_request();
2378 }
2379
2380
2381
2382
2383
2384
2385 static void reset_intr(void)
2386 {
2387 printk("weird, reset interrupt called\n");
2388 }
2389
2390 static struct cont_t reset_cont={
2391 reset_intr,
2392 success_and_wakeup,
2393 generic_failure,
2394 generic_done };
2395
2396 static int user_reset_fdc(int drive, int arg, int interruptible)
2397 {
2398 int result;
2399
2400 result=0;
2401 LOCK_FDC(drive,interruptible);
2402 switch(arg){
2403 case FD_RESET_ALWAYS:
2404 FDCS->reset=1;
2405 break;
2406 case FD_RESET_IF_RAWCMD:
2407 if(FDCS->rawcmd == 2 )
2408 reset_fdc_info(1);
2409 break;
2410 }
2411 if ( FDCS->reset ){
2412 cont = &reset_cont;
2413 timer_table[FLOPPY_TIMER].expires = jiffies + 5;
2414 timer_active |= 1 << FLOPPY_TIMER;
2415 CALL(result=wait_til_done(reset_fdc,interruptible));
2416 }
2417 if ( UDRS->track == PROVEN_ABSENT )
2418 UDRS->track = NEED_2_RECAL;
2419 redo_fd_request();
2420 return result;
2421 }
2422
2423
2424
2425
2426
2427 static int fd_copyout(void *param, volatile void *address, int size)
2428 {
2429 int i;
2430
2431 i = verify_area(VERIFY_WRITE,param,size);
2432 if (i)
2433 return i;
2434 memcpy_tofs(param,(void *) address, size);
2435 return 0;
2436 }
2437
2438 #define COPYOUT(x) (fd_copyout( (void *)param, &(x), sizeof(x)))
2439 #define COPYIN(x) (memcpy_fromfs( &(x), (void *) param, sizeof(x)),0)
2440
2441 static char *drive_name(int type, int drive )
2442 {
2443 struct floppy_struct *floppy;
2444
2445 if ( type )
2446 floppy = floppy_type + type;
2447 else {
2448 if ( UDP->native_format )
2449 floppy = floppy_type + UDP->native_format;
2450 else
2451 return "(null)";
2452 }
2453 if ( floppy->name )
2454 return floppy->name;
2455 else
2456 return "(null)";
2457 }
2458
2459
2460 static struct cont_t raw_cmd_cont={
2461 success_and_wakeup,
2462 failure_and_wakeup,
2463 generic_failure,
2464 generic_done };
2465
2466 static int raw_cmd_ioctl(int drive, void *param)
2467 {
2468 int i, count, ret;
2469
2470 if ( FDCS->rawcmd <= 1 )
2471 FDCS->rawcmd = 1;
2472 for ( i= 0; i < N_DRIVE; i++){
2473 if ( FDC(i) != fdc)
2474 continue;
2475 if ( i == drive ){
2476 if ( drive_state[i].fd_ref > 1 ){
2477 FDCS->rawcmd = 2;
2478 break;
2479 }
2480 } else if ( drive_state[i].fd_ref ){
2481 FDCS->rawcmd = 2;
2482 break;
2483 }
2484 }
2485
2486 if(FDCS->reset)
2487 return -EIO;
2488
2489 COPYIN(raw_cmd);
2490 raw_cmd.rate &= 0x03;
2491 count = raw_cmd.length;
2492 if (raw_cmd.flags & (FD_RAW_WRITE | FD_RAW_READ)){
2493 if(count > max_buffer_sectors * 1024 )
2494 return -ENOMEM;
2495 buffer_track = -1;
2496 }
2497 if ( raw_cmd.flags & FD_RAW_WRITE ){
2498 i = verify_area(VERIFY_READ, raw_cmd.data, count );
2499 if (i)
2500 return i;
2501 memcpy_fromfs(floppy_track_buffer, raw_cmd.data, count);
2502 }
2503
2504 current_addr = floppy_track_buffer;
2505 cont = &raw_cmd_cont;
2506 CALL(ret=wait_til_done(floppy_start,1));
2507 if( inb_p(FD_DIR) & 0x80 )
2508 raw_cmd.flags |= FD_RAW_DISK_CHANGE;
2509 else
2510 raw_cmd.flags &= ~FD_RAW_DISK_CHANGE;
2511 if(raw_cmd.flags & FD_RAW_NO_MOTOR_AFTER)
2512 motor_off_callback(drive);
2513
2514 if ( !ret && !FDCS->reset ){
2515 raw_cmd.reply_count = inr;
2516 for( i=0; i< raw_cmd.reply_count; i++)
2517 raw_cmd.reply[i] = reply_buffer[i];
2518 if ( raw_cmd.flags & ( FD_RAW_READ | FD_RAW_WRITE ))
2519 raw_cmd.length = get_dma_residue(FLOPPY_DMA);
2520 } else
2521 ret = -EIO;
2522 DRS->track = NO_TRACK;
2523 if ( ret )
2524 return ret;
2525
2526 if ( raw_cmd.flags & FD_RAW_READ ){
2527 i=fd_copyout( raw_cmd.data, floppy_track_buffer, count);
2528 if (i)
2529 return i;
2530 }
2531
2532 return COPYOUT(raw_cmd);
2533 }
2534
2535 static int invalidate_drive(int rdev)
2536 {
2537
2538 set_bit( DRIVE(rdev), &fake_change);
2539 redo_fd_request();
2540 check_disk_change(rdev);
2541 return 0;
2542 }
2543
2544 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
2545 unsigned long param)
2546 {
2547 #define IOCTL_MODE_BIT 8
2548 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
2549
2550 struct floppy_struct newparams;
2551 struct format_descr tmp_format_req;
2552 int i,device,drive,type,cnt;
2553 struct floppy_struct *this_floppy;
2554 char *name;
2555
2556 device = inode->i_rdev;
2557 switch (cmd) {
2558 RO_IOCTLS(device,param);
2559 }
2560 type = TYPE(device);
2561 drive = DRIVE(device);
2562 switch (cmd) {
2563 case FDGETDRVTYP:
2564 i=verify_area(VERIFY_WRITE,(void *) param,16);
2565 if (i)
2566 return i;
2567 name = drive_name(type,drive);
2568 for ( cnt=0; cnt<16; cnt++){
2569 put_fs_byte(name[cnt],
2570 ((char*)param)+cnt);
2571 if ( ! *name )
2572 break;
2573 }
2574 return 0;
2575 case FDGETMAXERRS:
2576 return COPYOUT(UDP->max_errors);
2577 case FDGETPRM:
2578 if (type)
2579 this_floppy = &floppy_type[type];
2580 else if ((this_floppy = current_type[drive]) ==
2581 NULL)
2582 return -ENODEV;
2583 return COPYOUT(this_floppy[0]);
2584 case FDPOLLDRVSTAT:
2585 check_disk_change(device);
2586
2587 case FDGETDRVSTAT:
2588 return COPYOUT(*UDRS);
2589 case FDGETFDCSTAT:
2590 return COPYOUT(*UFDCS);
2591 case FDGETDRVPRM:
2592 return COPYOUT(*UDP);
2593 case FDWERRORGET:
2594 return COPYOUT(*UDRWE);
2595 }
2596 if (!IOCTL_ALLOWED)
2597 return -EPERM;
2598 switch (cmd) {
2599 case FDWERRORCLR:
2600 UDRWE->write_errors = 0;
2601 UDRWE->first_error_sector = 0;
2602 UDRWE->first_error_generation = 0;
2603 UDRWE->last_error_sector = 0;
2604 UDRWE->last_error_generation = 0;
2605 UDRWE->badness = 0;
2606 return 0;
2607 case FDRAWCMD:
2608 if (type)
2609 return -EINVAL;
2610 LOCK_FDC(drive,1);
2611 set_floppy(device);
2612 CALL(i = raw_cmd_ioctl(drive, (void *) param));
2613 redo_fd_request();
2614 return i;
2615 case FDFMTTRK:
2616 if (UDRS->fd_ref != 1)
2617 return -EBUSY;
2618 if (UDRS->track == PROVEN_ABSENT)
2619 return -ENXIO;
2620 COPYIN(tmp_format_req);
2621 return do_format(device, &tmp_format_req);
2622 case FDSETMAXERRS:
2623 return COPYIN(UDP->max_errors);
2624 case FDFMTBEG:
2625 return 0;
2626 case FDCLRPRM:
2627 LOCK_FDC(drive,1);
2628 current_type[drive] = NULL;
2629 floppy_sizes[drive] = 2;
2630 UDRS->keep_data = 0;
2631 return invalidate_drive(device);
2632 case FDFMTEND:
2633 case FDFLUSH:
2634 LOCK_FDC(drive,1);
2635 return invalidate_drive(device);
2636 case FDSETPRM:
2637 case FDDEFPRM:
2638 COPYIN(newparams);
2639
2640 if(newparams.sect <= 0 ||
2641 newparams.head <= 0 ||
2642 newparams.track <= 0 ||
2643 newparams.track >
2644 UDP->tracks>>newparams.stretch)
2645 return -EINVAL;
2646 if ( type){
2647 if ( !suser() )
2648 return -EPERM;
2649 LOCK_FDC(-1,1);
2650 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2651 if (TYPE(drive_state[cnt].fd_device) == type &&
2652 drive_state[cnt].fd_ref)
2653 set_bit(drive, &fake_change);
2654 }
2655 floppy_type[type] = newparams;
2656 floppy_type[type].name="user format";
2657 for (cnt = type << 2 ;
2658 cnt < (type << 2 ) + 4 ;
2659 cnt++)
2660 floppy_sizes[cnt]=
2661 #ifdef HAVE_2_CONTROLLERS
2662 floppy_sizes[cnt+0x80]=
2663 #endif
2664 floppy_type[type].size>>1;
2665 redo_fd_request();
2666 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2667 if (TYPE(drive_state[cnt].fd_device) == type &&
2668 drive_state[cnt].fd_ref)
2669 check_disk_change(drive_state[cnt].
2670 fd_device);
2671 }
2672 return 0;
2673 }
2674
2675 LOCK_FDC(drive,1);
2676 if ( cmd != FDDEFPRM ){
2677
2678
2679 raw_cmd.flags = 0;
2680 start_motor();
2681 }
2682 user_params[drive] = newparams;
2683 if (buffer_drive == drive &&
2684 buffer_max > user_params[drive].sect)
2685 buffer_max=user_params[drive].sect;
2686 current_type[drive] = &user_params[drive];
2687 floppy_sizes[drive] = user_params[drive].size >> 1;
2688 if (cmd == FDDEFPRM)
2689 DRS->keep_data = -1;
2690 else
2691 DRS->keep_data = 1;
2692
2693
2694
2695
2696
2697 if (DRS->maxblock >
2698 user_params[drive].sect ||
2699 DRS->maxtrack )
2700 invalidate_drive(device);
2701 else
2702 redo_fd_request();
2703 return 0;
2704 case FDRESET:
2705 return user_reset_fdc( drive, (int)param, 1);
2706 case FDMSGON:
2707 UDP->flags |= FTD_MSG;
2708 return 0;
2709 case FDMSGOFF:
2710 UDP->flags &= ~FTD_MSG;
2711 return 0;
2712 case FDSETEMSGTRESH:
2713 UDP->max_errors.reporting =
2714 (unsigned short) (param & 0x0f);
2715 return 0;
2716 case FDTWADDLE:
2717 LOCK_FDC(drive,1);
2718 twaddle();
2719 redo_fd_request();
2720 }
2721 if ( ! suser() )
2722 return -EPERM;
2723 switch(cmd){
2724 case FDSETDRVPRM:
2725 return COPYIN(*UDP);
2726 default:
2727 return -EINVAL;
2728 }
2729 return 0;
2730 #undef IOCTL_ALLOWED
2731 }
2732
2733 #define CMOS_READ(addr) ({ \
2734 outb_p(addr,0x70); \
2735 inb_p(0x71); \
2736 })
2737
2738 static void set_base_type(int drive,int code)
2739 {
2740 if (code > 0 && code <= NUMBER(default_drive_params)) {
2741 memcpy((char *) UDP,
2742 (char *) (&default_drive_params[code].params),
2743 sizeof( struct floppy_drive_params ));
2744 printk("fd%d is %s", drive, default_drive_params[code].name);
2745 return;
2746 } else if (!code)
2747 printk("fd%d is not installed", drive);
2748 else
2749 printk("fd%d is unknown type %d",drive,code);
2750 }
2751
2752 static void config_types(void)
2753 {
2754 int drive;
2755
2756 for (drive=0; drive<N_DRIVE ; drive++){
2757
2758 memcpy((char *) UDP, (char *) (&default_drive_params->params),
2759 sizeof( struct floppy_drive_params ));
2760 }
2761 printk("Floppy drive(s): ");
2762 set_base_type(0, (CMOS_READ(0x10) >> 4) & 15);
2763 if (CMOS_READ(0x10) & 15) {
2764 printk(", ");
2765 set_base_type(1, CMOS_READ(0x10) & 15);
2766 }
2767 printk("\n");
2768 }
2769
2770 int floppy_is_wp( int minor)
2771 {
2772 check_disk_change(minor + (MAJOR_NR << 8));
2773 return ! ( drive_state[ DRIVE(minor) ].flags & FD_DISK_WRITABLE );
2774 }
2775
2776
2777 #define WRAPPER(op) \
2778 static int floppy_##op(struct inode * inode, struct file * filp, \
2779 char * buf, int count) \
2780 { \
2781 check_disk_change(inode->i_rdev); \
2782 if ( drive_state[DRIVE(inode->i_rdev)].track == PROVEN_ABSENT ) \
2783 return -ENXIO; \
2784 if ( test_bit(DRIVE(inode->i_rdev),&changed_floppies)) \
2785 return -ENXIO; \
2786 return block_##op(inode, filp, buf, count); \
2787 }
2788
2789 WRAPPER(read)
2790 WRAPPER(write)
2791
2792 static void floppy_release(struct inode * inode, struct file * filp)
2793 {
2794 int drive;
2795
2796 drive = DRIVE(inode->i_rdev);
2797
2798 fsync_dev(inode->i_rdev);
2799
2800 if (UDRS->fd_ref < 0)
2801 UDRS->fd_ref=0;
2802 else if (!UDRS->fd_ref--) {
2803 DPRINT("floppy_release with fd_ref == 0");
2804 UDRS->fd_ref = 0;
2805 }
2806 floppy_release_irq_and_dma();
2807 }
2808
2809
2810
2811
2812
2813
2814 #define RETERR(x) \
2815 do{floppy_release(inode,filp); \
2816 return -(x);}while(0)
2817
2818 static int floppy_open(struct inode * inode, struct file * filp)
2819 {
2820 int drive;
2821 int old_dev;
2822
2823 if (!filp) {
2824 DPRINT("Weird, open called with filp=0\n");
2825 return -EIO;
2826 }
2827
2828 drive = DRIVE(inode->i_rdev);
2829 if ( drive >= N_DRIVE || !( ALLOWED_DRIVE_MASK & ( 1 << drive)) )
2830 return -ENXIO;
2831
2832 if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
2833 return -ENXIO;
2834
2835 if ((filp->f_mode & 3) &&
2836 UDRS->track == PROVEN_ABSENT )
2837 return -ENXIO;
2838
2839 old_dev = UDRS->fd_device;
2840 if (UDRS->fd_ref && old_dev != inode->i_rdev)
2841 return -EBUSY;
2842
2843 if(UDRS->fd_ref == -1 ||
2844 (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
2845 return -EBUSY;
2846
2847 if (floppy_grab_irq_and_dma())
2848 return -EBUSY;
2849
2850 if(filp->f_flags & O_EXCL)
2851 UDRS->fd_ref = -1;
2852 else
2853 UDRS->fd_ref++;
2854
2855 UDRS->fd_device = inode->i_rdev;
2856
2857 if (old_dev && old_dev != inode->i_rdev) {
2858 if (buffer_drive == drive)
2859 buffer_track = -1;
2860 invalidate_buffers(old_dev);
2861 }
2862
2863
2864 if ((filp->f_mode & 2) || permission(inode,2))
2865 filp->f_mode |= IOCTL_MODE_BIT;
2866
2867 if (UFDCS->rawcmd == 1)
2868 UFDCS->rawcmd = 2;
2869
2870 if (filp->f_flags & O_NDELAY)
2871 return 0;
2872
2873 if (filp->f_mode && UDRS->track == PROVEN_ABSENT )
2874 RETERR(ENXIO);
2875
2876 if (user_reset_fdc(drive, FD_RESET_IF_NEEDED,0))
2877 RETERR(EIO);
2878
2879 if (filp->f_mode & 3) {
2880 UDRS->last_checked = 0;
2881 check_disk_change(inode->i_rdev);
2882 if (test_bit(drive,&changed_floppies))
2883 RETERR(ENXIO);
2884 }
2885
2886 if (filp->f_mode && UDRS->track == PROVEN_ABSENT )
2887 RETERR(ENXIO);
2888
2889 if ((filp->f_mode & 2) && !(UDRS->flags & FD_DISK_WRITABLE))
2890 RETERR(EROFS);
2891 return 0;
2892 #undef RETERR
2893 }
2894
2895
2896
2897
2898 static int check_floppy_change(dev_t dev)
2899 {
2900 int drive = DRIVE( dev );
2901
2902 if (MAJOR(dev) != MAJOR_NR) {
2903 DPRINT("floppy_changed: not a floppy\n");
2904 return 0;
2905 }
2906
2907 if(test_bit(drive, &changed_floppies))
2908 return 1;
2909
2910 if(UDRS->last_checked + UDP->checkfreq < jiffies){
2911 lock_fdc(drive,0);
2912 start_motor();
2913 redo_fd_request();
2914 }
2915
2916 if(test_bit(drive, &changed_floppies))
2917 return 1;
2918 if(test_bit(drive, &fake_change))
2919 return 1;
2920 return 0;
2921 }
2922
2923 static struct cont_t poll_cont={
2924 success_and_wakeup,
2925 floppy_ready,
2926 generic_failure,
2927 generic_done };
2928
2929
2930
2931
2932
2933
2934 static int floppy_revalidate(dev_t dev)
2935 {
2936 struct buffer_head * bh;
2937 int drive=DRIVE(dev);
2938 int cf;
2939
2940 cf = test_bit(drive, &changed_floppies);
2941 if(cf || test_bit(drive, &fake_change)){
2942 lock_fdc(drive,0);
2943 cf = test_bit(drive, &changed_floppies);
2944 if(! (cf || test_bit(drive, &fake_change))){
2945 redo_fd_request();
2946 return 0;
2947 }
2948 UDRS->maxblock = 0;
2949 UDRS->maxtrack = 0;
2950 if ( buffer_drive == drive)
2951 buffer_track = -1;
2952 clear_bit(drive, &fake_change);
2953 clear_bit(drive, &changed_floppies);
2954 if(cf){
2955 UDRS->generation++;
2956 if(!current_type[drive] && !TYPE(dev)){
2957
2958 if (!(bh = getblk(dev,0,1024))){
2959 redo_fd_request();
2960 return 1;
2961 }
2962 if ( bh && ! bh->b_uptodate)
2963 ll_rw_block(READ, 1, &bh);
2964 redo_fd_request();
2965 wait_on_buffer(bh);
2966 brelse(bh);
2967 return 0;
2968 } else {
2969
2970 raw_cmd.flags=FD_RAW_NEED_SEEK|FD_RAW_NEED_DISK;
2971 raw_cmd.track=0;
2972 raw_cmd.cmd_count=0;
2973 cont = &poll_cont;
2974 wait_til_done(floppy_ready,0);
2975 }
2976 }
2977 redo_fd_request();
2978 }
2979 return 0;
2980 }
2981
2982 static struct file_operations floppy_fops = {
2983 NULL,
2984 floppy_read,
2985 floppy_write,
2986 NULL,
2987 NULL,
2988 fd_ioctl,
2989 NULL,
2990 floppy_open,
2991 floppy_release,
2992 block_fsync,
2993 NULL,
2994 check_floppy_change,
2995 floppy_revalidate,
2996 };
2997
2998
2999
3000
3001
3002
3003
3004
3005 static char get_fdc_version(void)
3006 {
3007 int r;
3008
3009 output_byte(FD_DUMPREGS);
3010 if ( FDCS->reset )
3011 return FDC_NONE;
3012 if ( (r = result()) <= 0x00)
3013 return FDC_NONE;
3014 if ((r==1) && (reply_buffer[0] == 0x80)){
3015 printk("FDC %d is a 8272A\n",fdc);
3016 return FDC_8272A;
3017 }
3018 if (r != 10) {
3019 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
3020 return FDC_UNKNOWN;
3021 }
3022 output_byte(FD_VERSION);
3023 r = result();
3024 if ((r == 1) && (reply_buffer[0] == 0x80)){
3025 printk("FDC %d is a 82072\n",fdc);
3026 return FDC_82072;
3027 }
3028 if ((r != 1) || (reply_buffer[0] != 0x90)) {
3029 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
3030 return FDC_UNKNOWN;
3031 }
3032 output_byte(FD_UNLOCK);
3033 r = result();
3034 if ((r == 1) && (reply_buffer[0] == 0x80)){
3035 printk("FDC %d is a pre-1991 82077\n", fdc);
3036 return FDC_82077_ORIG;
3037 }
3038 if ((r != 1) || (reply_buffer[0] != 0x00)) {
3039 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
3040 return FDC_UNKNOWN;
3041 }
3042 printk("FDC %d is a post-1991 82077\n",fdc);
3043 return FDC_82077;
3044 }
3045
3046 void floppy_init(void)
3047 {
3048 int i;
3049
3050 sti();
3051
3052 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
3053 printk("Unable to get major %d for floppy\n",MAJOR_NR);
3054 return;
3055 }
3056
3057 for(i=0; i<256; i++)
3058 if ( TYPE(i))
3059 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
3060 else
3061 floppy_sizes[i] = MAX_DISK_SIZE;
3062
3063 blk_size[MAJOR_NR] = floppy_sizes;
3064 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3065 timer_table[FLOPPY_TIMER].fn = floppy_shutdown;
3066 timer_active &= ~(1 << FLOPPY_TIMER);
3067 config_types();
3068
3069 fdc_state[0].address = 0x3f0;
3070 #if N_FDC > 1
3071 fdc_state[1].address = 0x370;
3072 #endif
3073 for (i = 0 ; i < N_FDC ; i++) {
3074 fdc = i;
3075 FDCS->dtr = -1;
3076 FDCS->dor = 0;
3077 FDCS->reset = 0;
3078 FDCS->version = FDC_NONE;
3079 set_dor(fdc, ~0, 0xc );
3080 }
3081
3082
3083 for (i = 0; i < N_DRIVE ; i++) {
3084 current_drive = i;
3085 DRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE;
3086 DRS->generation = 0;
3087 DRS->keep_data = 0;
3088 DRS->fd_ref = 0;
3089 DRS->fd_device = 0;
3090 DRWE->write_errors = 0;
3091 DRWE->first_error_sector = 0;
3092 DRWE->first_error_generation = 0;
3093 DRWE->last_error_sector = 0;
3094 DRWE->last_error_generation = 0;
3095 DRWE->badness = 0;
3096 }
3097
3098 floppy_grab_irq_and_dma();
3099 for (i = 0 ; i < N_FDC ; i++) {
3100 fdc = i;
3101 FDCS->rawcmd = 2;
3102 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED,0))
3103 continue;
3104
3105 FDCS->version = get_fdc_version();
3106 if (FDCS->version == FDC_NONE)
3107 continue;
3108
3109
3110
3111
3112
3113 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
3114 user_reset_fdc(-1,FD_RESET_ALWAYS,0);
3115 }
3116 fdc=0;
3117 current_drive = 0;
3118 floppy_release_irq_and_dma();
3119 initialising=0;
3120 }
3121
3122 static int floppy_grab_irq_and_dma(void)
3123 {
3124 cli();
3125 if (usage_count++){
3126 sti();
3127 return 0;
3128 }
3129 sti();
3130 if (request_irq(FLOPPY_IRQ, floppy_interrupt, SA_INTERRUPT, "floppy")) {
3131 DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
3132 FLOPPY_IRQ);
3133 return -1;
3134 }
3135 if (request_dma(FLOPPY_DMA,"floppy")) {
3136 DPRINT1("Unable to grab DMA%d for the floppy driver\n",
3137 FLOPPY_DMA);
3138 free_irq(FLOPPY_IRQ);
3139 return -1;
3140 }
3141 enable_irq(FLOPPY_IRQ);
3142 return 0;
3143 }
3144
3145 static void floppy_release_irq_and_dma(void)
3146 {
3147 cli();
3148 if (--usage_count){
3149 sti();
3150 return;
3151 }
3152 sti();
3153 disable_dma(FLOPPY_DMA);
3154 free_dma(FLOPPY_DMA);
3155 disable_irq(FLOPPY_IRQ);
3156 free_irq(FLOPPY_IRQ);
3157 #ifdef HAVE_2_CONTROLLERS
3158
3159
3160 set_dor(0, ~0, 8 );
3161 set_dor(1, ~8, 0 );
3162 #endif
3163 }