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