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