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 ((!CURRENT ||
848 CURRENT->buffer != current_addr ||
849 raw_cmd.length > 512 * CURRENT->nr_sectors) &&
850 (current_addr < floppy_track_buffer ||
851 current_addr + raw_cmd.length >
852 floppy_track_buffer + 1024 * max_buffer_sectors)){
853 printk("bad address. start=%p lg=%lx tb=%p\n",
854 current_addr, raw_cmd.length, floppy_track_buffer);
855 if ( CURRENT ){
856 printk("buffer=%p nr=%lx cnr=%lx\n",
857 CURRENT->buffer, CURRENT->nr_sectors,
858 CURRENT->current_nr_sectors);
859 }
860 cont->done(0);
861 FDCS->reset=1;
862 return;
863 }
864 if ((long) current_addr % 512 ){
865 printk("non aligned address: %p\n", current_addr );
866 cont->done(0);
867 FDCS->reset=1;
868 return;
869 }
870 if ( ( (long)current_addr & ~(64*1024-1) ) !=
871 ((long)(current_addr + raw_cmd.length-1) & ~(64*1024-1))){
872 printk("DMA crossing 64-K boundary %p-%p\n",
873 current_addr, current_addr + raw_cmd.length);
874 cont->done(0);
875 FDCS->reset=1;
876 return;
877 }
878
879 #endif
880 cli();
881 disable_dma(FLOPPY_DMA);
882 clear_dma_ff(FLOPPY_DMA);
883 set_dma_mode(FLOPPY_DMA,
884 (raw_cmd.flags & FD_RAW_READ)?
885 DMA_MODE_READ : DMA_MODE_WRITE);
886 set_dma_addr(FLOPPY_DMA, (long) current_addr);
887 set_dma_count(FLOPPY_DMA, raw_cmd.length);
888 enable_dma(FLOPPY_DMA);
889 sti();
890 floppy_disable_hlt();
891 }
892
893
894 static int output_byte(char byte)
895 {
896 int counter;
897 unsigned char status;
898
899 if (FDCS->reset)
900 return -1;
901 for(counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
902 status = inb_p(FD_STATUS) &(STATUS_READY|STATUS_DIR|STATUS_DMA);
903 if (!(status & STATUS_READY))
904 continue;
905 if (status == STATUS_READY){
906 outb_p(byte,FD_DATA);
907 return 0;
908 } else
909 break;
910 }
911 FDCS->reset = 1;
912 if ( !initialising )
913 DPRINT2("Unable to send byte %x to FDC. Status=%x\n",
914 byte, status);
915 return -1;
916 }
917 #define LAST_OUT(x) if(output_byte(x)){ reset_fdc();return;}
918
919
920 static int result(void)
921 {
922 int i = 0, counter, status;
923
924 if (FDCS->reset)
925 return -1;
926 for (counter = 0 ; counter < 10000 && !FDCS->reset ; counter++) {
927 status = inb_p(FD_STATUS)&
928 (STATUS_DIR|STATUS_READY|STATUS_BUSY|STATUS_DMA);
929 if (!(status & STATUS_READY))
930 continue;
931 if (status == STATUS_READY)
932 return i;
933 if (status & STATUS_DMA )
934 break;
935 if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {
936 if (i >= MAX_REPLIES) {
937 DPRINT("floppy_stat reply overrun\n");
938 break;
939 }
940 reply_buffer[i++] = inb_p(FD_DATA);
941 }
942 }
943 FDCS->reset = 1;
944 if ( !initialising )
945 DPRINT3("Getstatus times out (%x) on fdc %d [%d]\n",
946 status, fdc, i);
947 return -1;
948 }
949
950
951
952
953 static inline void perpendicular_mode(void)
954 {
955 unsigned char perp_mode;
956
957 if (!floppy)
958 return;
959 if (floppy->rate & 0x40){
960 switch(raw_cmd.rate){
961 case 0:
962 perp_mode=2;
963 break;
964 case 3:
965 perp_mode=3;
966 break;
967 default:
968 DPRINT("Invalid data rate for perpendicular mode!\n");
969 cont->done(0);
970 FDCS->reset = 1;
971
972
973 return;
974 }
975 } else
976 perp_mode = 0;
977
978 if ( FDCS->perp_mode == perp_mode )
979 return;
980 if (FDCS->version >= FDC_82077_ORIG && FDCS->has_fifo) {
981 output_byte(FD_PERPENDICULAR);
982 output_byte(perp_mode);
983 FDCS->perp_mode = perp_mode;
984 } else if (perp_mode) {
985 DPRINT("perpendicular mode not supported by this FDC.\n");
986 }
987 }
988
989 #define NOMINAL_DTR 500
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010 static void fdc_specify(void)
1011 {
1012 unsigned char spec1, spec2;
1013 int srt, hlt, hut;
1014 unsigned long dtr = NOMINAL_DTR;
1015 unsigned long scale_dtr = NOMINAL_DTR;
1016 int hlt_max_code = 0x7f;
1017 int hut_max_code = 0xf;
1018
1019 if (FDCS->need_configure && FDCS->has_fifo) {
1020 if ( FDCS->reset )
1021 return;
1022
1023
1024 output_byte(FD_CONFIGURE);
1025 output_byte(0);
1026 output_byte(0x2A);
1027 output_byte(0);
1028 if ( FDCS->reset ){
1029 FDCS->has_fifo=0;
1030 return;
1031 }
1032 FDCS->need_configure = 0;
1033
1034 }
1035
1036 switch (raw_cmd.rate & 0x03) {
1037 case 3:
1038 dtr = 1000;
1039 break;
1040 case 1:
1041 dtr = 300;
1042 break;
1043 case 2:
1044 dtr = 250;
1045 break;
1046 }
1047
1048 if (FDCS->version >= FDC_82072) {
1049 scale_dtr = dtr;
1050 hlt_max_code = 0x00;
1051 hut_max_code = 0x0;
1052 }
1053
1054
1055 srt = 16 - (DP->srt*scale_dtr/1000 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1056 if (srt > 0xf)
1057 srt = 0xf;
1058 else if (srt < 0)
1059 srt = 0;
1060
1061 hlt = (DP->hlt*scale_dtr/2 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1062 if (hlt < 0x01)
1063 hlt = 0x01;
1064 else if (hlt > 0x7f)
1065 hlt = hlt_max_code;
1066
1067 hut = (DP->hut*scale_dtr/16 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1068 if (hut < 0x1)
1069 hut = 0x1;
1070 else if (hut > 0xf)
1071 hut = hut_max_code;
1072
1073 spec1 = (srt << 4) | hut;
1074 spec2 = (hlt << 1);
1075
1076
1077 if (FDCS->spec1 != spec1 || FDCS->spec2 != spec2) {
1078
1079 output_byte(FD_SPECIFY);
1080 output_byte(FDCS->spec1 = spec1);
1081 output_byte(FDCS->spec2 = spec2);
1082 }
1083 }
1084
1085
1086
1087
1088
1089 static int fdc_dtr(void)
1090 {
1091
1092 if ( raw_cmd.rate == FDCS->dtr)
1093 return 0;
1094
1095
1096 outb_p(raw_cmd.rate, FD_DCR);
1097
1098
1099
1100
1101
1102
1103 FDCS->dtr = raw_cmd.rate;
1104 return(wait_for_completion(jiffies+2,
1105 (timeout_fn) floppy_ready));
1106 }
1107
1108 static void tell_sector(void)
1109 {
1110 printk(": track %d, head %d, sector %d, size %d",
1111 R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
1112 }
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122 static int interpret_errors(void)
1123 {
1124 char bad;
1125
1126 if (inr!=7) {
1127 DPRINT("-- FDC reply error");
1128 FDCS->reset = 1;
1129 return 1;
1130 }
1131
1132
1133 switch ((ST0 & ST0_INTR)>>6) {
1134 case 1:
1135 bad = 1;
1136 if (ST1 & ST1_WP) {
1137 DPRINT("Drive is write protected\n");
1138 CLEARF(FD_DISK_WRITABLE);
1139 cont->done(0);
1140 bad = 2;
1141 } else if (ST1 & ST1_ND) {
1142 SETF(FD_NEED_TWADDLE);
1143 } else if (ST1 & ST1_OR) {
1144 if (DP->flags & FTD_MSG )
1145 DPRINT("Over/Underrun - retrying\n");
1146 bad = 0;
1147 }else if(*errors >= DP->max_errors.reporting){
1148 DPRINT("");
1149 if (ST0 & ST0_ECE) {
1150 printk("Recalibrate failed!");
1151 } else if (ST2 & ST2_CRC) {
1152 printk("data CRC error");
1153 tell_sector();
1154 } else if (ST1 & ST1_CRC) {
1155 printk("CRC error");
1156 tell_sector();
1157 } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
1158 if (!probing) {
1159 printk("sector not found");
1160 tell_sector();
1161 } else
1162 printk("probe failed...");
1163 } else if (ST2 & ST2_WC) {
1164 printk("wrong cylinder");
1165 } else if (ST2 & ST2_BC) {
1166 printk("bad cylinder");
1167 } else {
1168 printk("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", ST0, ST1, ST2);
1169 tell_sector();
1170 }
1171 printk("\n");
1172
1173 }
1174 if ( ST2 & ST2_WC || ST2 & ST2_BC)
1175
1176 DRS->track = NEED_2_RECAL;
1177 return bad;
1178 case 2:
1179 DPRINT("Invalid FDC command given!\n");
1180 cont->done(0);
1181 return 2;
1182 case 3:
1183 DPRINT("Abnormal termination caused by polling\n");
1184 cont->error();
1185 return 2;
1186 default:
1187 return 0;
1188 }
1189 }
1190
1191
1192
1193
1194
1195
1196 static void setup_rw_floppy(void)
1197 {
1198 int i,ready_date,r, flags,dflags;
1199 timeout_fn function;
1200
1201 flags = raw_cmd.flags;
1202 if ( flags & ( FD_RAW_READ | FD_RAW_WRITE))
1203 flags |= FD_RAW_INTR;
1204
1205 if ((flags & FD_RAW_SPIN) && !(flags & FD_RAW_NO_MOTOR)){
1206 ready_date = DRS->spinup_date + DP->spinup;
1207
1208
1209
1210
1211 if ( ready_date > jiffies + DP->select_delay){
1212 ready_date -= DP->select_delay;
1213 function = (timeout_fn) floppy_start;
1214 } else
1215 function = (timeout_fn) setup_rw_floppy;
1216
1217
1218 if (wait_for_completion(ready_date,function))
1219 return;
1220 }
1221 dflags = DRS->flags;
1222
1223 if ( (flags & FD_RAW_READ) || (flags & FD_RAW_WRITE))
1224 setup_DMA();
1225
1226 if ( flags & FD_RAW_INTR )
1227 SET_INTR(main_command_interrupt);
1228
1229 r=0;
1230 for(i=0; i< raw_cmd.cmd_count; i++)
1231 r|=output_byte( raw_cmd.cmd[i] );
1232
1233 #ifdef DEBUGT
1234 debugt("rw_command: ");
1235 #endif
1236 if ( r ){
1237 reset_fdc();
1238 return;
1239 }
1240
1241 if ( ! ( flags & FD_RAW_INTR )){
1242 inr = result();
1243 cont->interrupt();
1244 } else if ( flags & FD_RAW_NEED_DISK )
1245 fd_watchdog();
1246 }
1247
1248 static int blind_seek;
1249
1250
1251
1252
1253
1254 static void seek_interrupt(void)
1255 {
1256 #ifdef DEBUGT
1257 debugt("seek interrupt:");
1258 #endif
1259 if (inr != 2 || (ST0 & 0xF8) != 0x20 ) {
1260 DPRINT("seek failed\n");
1261 DRS->track = NEED_2_RECAL;
1262 cont->error();
1263 cont->redo();
1264 return;
1265 }
1266 if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek){
1267 #ifdef DCL_DEBUG
1268 if (DP->flags & FD_DEBUG){
1269 DPRINT("clearing NEWCHANGE flag because of effective seek\n");
1270 DPRINT1("jiffies=%ld\n", jiffies);
1271 }
1272 #endif
1273 CLEARF(FD_DISK_NEWCHANGE);
1274 DRS->select_date = jiffies;
1275 }
1276 DRS->track = ST1;
1277 floppy_ready();
1278 }
1279
1280 static void check_wp(void)
1281 {
1282 if (TESTF(FD_VERIFY)) {
1283
1284 output_byte( FD_GETSTATUS );
1285 output_byte( UNIT(current_drive) );
1286 if ( result() != 1 ){
1287 FDCS->reset = 1;
1288 return;
1289 }
1290 CLEARF(FD_VERIFY);
1291 CLEARF(FD_NEED_TWADDLE);
1292 #ifdef DCL_DEBUG
1293 if (DP->flags & FD_DEBUG){
1294 DPRINT("checking whether disk is write protected\n");
1295 DPRINT1("wp=%x\n",ST3 & 0x40);
1296 }
1297 #endif
1298 if (!( ST3 & 0x40))
1299 SETF(FD_DISK_WRITABLE);
1300 else
1301 CLEARF(FD_DISK_WRITABLE);
1302 }
1303 }
1304
1305 static void seek_floppy(void)
1306 {
1307 int track;
1308
1309 blind_seek=0;
1310
1311 #ifdef DCL_DEBUG
1312 if (DP->flags & FD_DEBUG){
1313 DPRINT("calling disk change from seek\n");
1314 }
1315 #endif
1316
1317 if (!TESTF(FD_DISK_NEWCHANGE) &&
1318 disk_change(current_drive) &&
1319 (raw_cmd.flags & FD_RAW_NEED_DISK)){
1320
1321
1322
1323
1324 SETF(FD_DISK_CHANGED);
1325 cont->done(0);
1326 cont->redo();
1327 return;
1328 }
1329 if ( DRS->track <= NEED_1_RECAL ){
1330 recalibrate_floppy();
1331 return;
1332 } else if (TESTF(FD_DISK_NEWCHANGE) &&
1333 (raw_cmd.flags & FD_RAW_NEED_DISK) &&
1334 (DRS->track <= NO_TRACK || DRS->track == raw_cmd.track)) {
1335
1336
1337 if ( raw_cmd.track )
1338 track = raw_cmd.track - 1;
1339 else {
1340 if(DP->flags & FD_SILENT_DCL_CLEAR){
1341 set_dor(fdc, ~(0x10 << UNIT(current_drive)), 0);
1342 blind_seek = 1;
1343 raw_cmd.flags |= FD_RAW_NEED_SEEK;
1344 }
1345 track = 1;
1346 }
1347 } else {
1348 check_wp();
1349 if (raw_cmd.track != DRS->track &&
1350 (raw_cmd.flags & FD_RAW_NEED_SEEK))
1351 track = raw_cmd.track;
1352 else {
1353 setup_rw_floppy();
1354 return;
1355 }
1356 }
1357
1358 SET_INTR(seek_interrupt);
1359 output_byte(FD_SEEK);
1360 output_byte(UNIT(current_drive));
1361 LAST_OUT(track);
1362 #ifdef DEBUGT
1363 debugt("seek command:");
1364 #endif
1365 }
1366
1367 static void recal_interrupt(void)
1368 {
1369 #ifdef DEBUGT
1370 debugt("recal interrupt:");
1371 #endif
1372 if (inr !=2 )
1373 FDCS->reset = 1;
1374 else if (ST0 & ST0_ECE) {
1375 switch(DRS->track){
1376 case NEED_1_RECAL:
1377 #ifdef DEBUGT
1378 debugt("recal interrupt need 1 recal:");
1379 #endif
1380
1381
1382
1383
1384 cont->error();
1385 cont->redo();
1386 return;
1387 case NEED_2_RECAL:
1388 #ifdef DEBUGT
1389 debugt("recal interrupt need 2 recal:");
1390 #endif
1391
1392
1393
1394
1395
1396 #ifdef DCL_DEBUG
1397 if (DP->flags & FD_DEBUG){
1398 DPRINT("clearing NEWCHANGE flag because of second recalibrate\n");
1399 }
1400 #endif
1401
1402 CLEARF(FD_DISK_NEWCHANGE);
1403 DRS->select_date = jiffies;
1404
1405 default:
1406 #ifdef DEBUGT
1407 debugt("recal interrupt default:");
1408 #endif
1409
1410
1411
1412
1413
1414 DRS->track = NEED_1_RECAL;
1415 break;
1416 }
1417 } else
1418 DRS->track = ST1;
1419 floppy_ready();
1420 }
1421
1422
1423
1424
1425
1426 static void unexpected_floppy_interrupt(void)
1427 {
1428 int i;
1429 if ( initialising )
1430 return;
1431 if(print_unex){
1432 DPRINT("unexpected interrupt\n");
1433 if ( inr >= 0 )
1434 for(i=0; i<inr; i++)
1435 printk("%d %x\n", i, reply_buffer[i] );
1436 }
1437 while(1){
1438 output_byte(FD_SENSEI);
1439 inr=result();
1440 if ( inr != 2 )
1441 break;
1442 if(print_unex){
1443 printk("sensei\n");
1444 for(i=0; i<inr; i++)
1445 printk("%d %x\n", i, reply_buffer[i] );
1446 }
1447 }
1448 FDCS->reset = 1;
1449 }
1450
1451 struct tq_struct floppy_tq =
1452 { 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
1453
1454
1455 static void floppy_interrupt(int irq, struct pt_regs * regs)
1456 {
1457 void (*handler)(void) = DEVICE_INTR;
1458
1459 floppy_enable_hlt();
1460 CLEAR_INTR;
1461 if ( fdc >= N_FDC || FDCS->address == -1){
1462
1463 printk("DOR0=%x\n", fdc_state[0].dor);
1464 printk("floppy interrupt on bizarre fdc %d\n",fdc);
1465 printk("handler=%p\n", handler);
1466 return;
1467 }
1468 inr = result();
1469 if (!handler){
1470 unexpected_floppy_interrupt();
1471 return;
1472 }
1473 if ( inr == 0 ){
1474 do {
1475 output_byte(FD_SENSEI);
1476 inr = result();
1477 } while ( (ST0 & 0x83) != UNIT(current_drive) && inr == 2);
1478 }
1479 floppy_tq.routine = (void *)(void *) handler;
1480 queue_task_irq(&floppy_tq, &tq_timer);
1481 }
1482
1483 static void recalibrate_floppy(void)
1484 {
1485 #ifdef DEBUGT
1486 debugt("recalibrate floppy:");
1487 #endif
1488 SET_INTR(recal_interrupt);
1489 output_byte(FD_RECALIBRATE);
1490 LAST_OUT(UNIT(current_drive));
1491 }
1492
1493
1494
1495
1496 static void reset_interrupt(void)
1497 {
1498 #ifdef DEBUGT
1499 debugt("reset interrupt:");
1500 #endif
1501 fdc_specify();
1502 result();
1503 if ( FDCS->reset )
1504 cont->error();
1505 cont->redo();
1506 }
1507
1508
1509
1510
1511
1512 static void reset_fdc(void)
1513 {
1514 SET_INTR(reset_interrupt);
1515 FDCS->reset = 0;
1516 reset_fdc_info(0);
1517 if ( FDCS->version >= FDC_82077 )
1518 outb_p(0x80 | ( FDCS->dtr &3), FD_STATUS);
1519 else {
1520 outb_p(FDCS->dor & ~0x04, FD_DOR);
1521 udelay(FD_RESET_DELAY);
1522 outb(FDCS->dor, FD_DOR);
1523 }
1524 }
1525
1526 static void empty(void)
1527 {
1528 }
1529
1530 void show_floppy(void)
1531 {
1532 int i;
1533
1534 printk("\n");
1535 printk("floppy driver state\n");
1536 printk("-------------------\n");
1537 for(i=0; i<N_FDC; i++){
1538 if(FDCS->address != -1){
1539 printk("dor %d = %x\n", i, fdc_state[i].dor );
1540 outb_p(fdc_state[i].address+2, fdc_state[i].dor);
1541 udelay(1000);
1542 }
1543 }
1544 printk("status=%x\n", inb_p(FD_STATUS));
1545 printk("fdc_busy=%d\n", fdc_busy);
1546 if( DEVICE_INTR)
1547 printk("DEVICE_INTR=%p\n", DEVICE_INTR);
1548 if(floppy_tq.sync)
1549 printk("floppy_tq.routine=%p\n", floppy_tq.routine);
1550 if(fd_timer.prev)
1551 printk("fd_timer.function=%p\n", fd_timer.function);
1552 if(fd_timeout.prev){
1553 printk("timer_table=%p\n",fd_timeout.function);
1554 printk("expires=%ld\n",fd_timeout.expires);
1555 printk("now=%ld\n",jiffies);
1556 }
1557 printk("cont=%p\n", cont);
1558 printk("CURRENT=%p\n", CURRENT);
1559 printk("command_status=%d\n", command_status);
1560 printk("\n");
1561 }
1562
1563 static void floppy_shutdown(void)
1564 {
1565 CLEAR_INTR;
1566 floppy_tq.routine = (void *)(void *) empty;
1567 del_timer( &fd_timer);
1568
1569 floppy_enable_hlt();
1570 disable_dma(FLOPPY_DMA);
1571
1572
1573 if(!initialising)
1574 DPRINT("floppy timeout\n");
1575 FDCS->reset = 1;
1576 cont->done(0);
1577 cont->redo();
1578 }
1579
1580
1581
1582 static int start_motor( void (*function)(void) )
1583 {
1584 int mask, data;
1585
1586 mask = 0xfc;
1587 data = UNIT(current_drive);
1588 if (!(raw_cmd.flags & FD_RAW_NO_MOTOR)){
1589 if(!(FDCS->dor & ( 0x10 << UNIT(current_drive) ) )){
1590 set_debugt();
1591
1592 DRS->first_read_date = 0;
1593
1594 DRS->spinup_date = jiffies;
1595 data |= (0x10 << UNIT(current_drive));
1596 }
1597 } else
1598 if (FDCS->dor & ( 0x10 << UNIT(current_drive) ) )
1599 mask &= ~(0x10 << UNIT(current_drive));
1600
1601
1602 del_timer(motor_off_timer + current_drive);
1603 set_dor( fdc, mask, data);
1604
1605
1606 return(wait_for_completion(DRS->select_date+DP->select_delay,
1607 (timeout_fn) function));
1608 }
1609
1610 static void floppy_ready(void)
1611 {
1612 CHECK_RESET;
1613 if(start_motor(floppy_ready)) return;
1614 if(fdc_dtr()) return;
1615
1616 #ifdef DCL_DEBUG
1617 if (DP->flags & FD_DEBUG){
1618 DPRINT("calling disk change from floppy_ready\n");
1619 }
1620 #endif
1621
1622 if(!(raw_cmd.flags & FD_RAW_NO_MOTOR) &&
1623 disk_change(current_drive) &&
1624 !DP->select_delay)
1625 twaddle();
1626
1627
1628 if ( raw_cmd.flags & (FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK)){
1629 perpendicular_mode();
1630 fdc_specify();
1631 seek_floppy();
1632 } else
1633 setup_rw_floppy();
1634 }
1635
1636 static void floppy_start(void)
1637 {
1638 del_timer(&fd_timeout);
1639 fd_timeout.expires = DP->timeout;
1640 add_timer(&fd_timeout);
1641
1642 scandrives();
1643 #ifdef DCL_DEBUG
1644 if (DP->flags & FD_DEBUG){
1645 DPRINT("setting NEWCHANGE in floppy_start\n");
1646 }
1647 #endif
1648 SETF(FD_DISK_NEWCHANGE);
1649 floppy_ready();
1650 }
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666 static void do_wakeup(void)
1667 {
1668 del_timer(&fd_timeout);
1669 cont = 0;
1670 command_status += 2;
1671 wake_up(&command_done);
1672 }
1673
1674 static struct cont_t wakeup_cont={
1675 empty,
1676 do_wakeup,
1677 empty,
1678 (done_f)empty
1679 };
1680
1681 static int wait_til_done( void (*handler)(void ), int interruptible )
1682 {
1683 int ret;
1684
1685 floppy_tq.routine = (void *)(void *) handler;
1686 queue_task(&floppy_tq, &tq_timer);
1687
1688 cli();
1689 while(command_status < 2 && NO_SIGNAL)
1690 if (current->pid)
1691 interruptible_sleep_on(&command_done);
1692 else {
1693 sti();
1694 run_task_queue(&tq_timer);
1695 cli();
1696 }
1697 if(command_status < 2){
1698 sti();
1699 floppy_shutdown();
1700 process_fd_request();
1701 return -EINTR;
1702 }
1703 sti();
1704
1705 if ( FDCS->reset )
1706 command_status = FD_COMMAND_ERROR;
1707 if ( command_status == FD_COMMAND_OKAY )
1708 ret=0;
1709 else
1710 ret=-EIO;
1711 command_status = FD_COMMAND_NONE;
1712 return ret;
1713 }
1714
1715 static void generic_done(int result)
1716 {
1717 command_status = result;
1718 cont = &wakeup_cont;
1719 }
1720
1721 static void generic_success(void)
1722 {
1723 generic_done(1);
1724 }
1725
1726 static void generic_failure(void)
1727 {
1728 generic_done(0);
1729 }
1730
1731 static void success_and_wakeup(void)
1732 {
1733 generic_success();
1734 do_wakeup();
1735 }
1736
1737 static void failure_and_wakeup(void)
1738 {
1739 generic_failure();
1740 do_wakeup();
1741 }
1742
1743
1744
1745
1746
1747
1748 static int next_valid_format(void)
1749 {
1750 int probed_format;
1751
1752 probed_format = DRS->probed_format;
1753 while(1){
1754 if ( probed_format >= 8 ||
1755 ! DP->autodetect[probed_format] ){
1756 DRS->probed_format = 0;
1757 return 1;
1758 }
1759 if ( floppy_type[DP->autodetect[probed_format]].sect ){
1760 DRS->probed_format = probed_format;
1761 return 0;
1762 }
1763 probed_format++;
1764 }
1765 }
1766
1767 static void bad_flp_intr(void)
1768 {
1769 if ( probing ){
1770 DRS->probed_format++;
1771 if ( !next_valid_format())
1772 return;
1773 }
1774 (*errors)++;
1775 if (*errors > DRWE->badness)
1776 DRWE->badness = *errors;
1777 if (*errors > DP->max_errors.abort)
1778 cont->done(0);
1779 if (*errors > DP->max_errors.reset)
1780 FDCS->reset = 1;
1781 else if (*errors > DP->max_errors.recal)
1782 DRS->track = NEED_2_RECAL;
1783 }
1784
1785 static void set_floppy(int device)
1786 {
1787 if (TYPE(device))
1788 floppy = TYPE(device) + floppy_type;
1789 else
1790 floppy = current_type[ DRIVE(device) ];
1791 }
1792
1793
1794
1795
1796
1797 static void format_interrupt(void)
1798 {
1799 switch (interpret_errors()){
1800 case 1:
1801 cont->error();
1802 case 2:
1803 break;
1804 case 0:
1805 cont->done(1);
1806 }
1807 cont->redo();
1808 }
1809
1810 #define CODE2SIZE (ssize = ( ( 1 << SIZECODE ) + 3 ) >> 2)
1811 #define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80 ) >>1))
1812 #define CT(x) ( (x) | 0x40 )
1813 static void setup_format_params(void)
1814 {
1815 struct fparm {
1816 unsigned char track,head,sect,size;
1817 } *here = (struct fparm *)floppy_track_buffer;
1818 int il,n;
1819 int count,head_shift,track_shift;
1820
1821 raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
1822 FD_RAW_NEED_SEEK;
1823 raw_cmd.rate = floppy->rate & 0x3;
1824 raw_cmd.cmd_count = NR_F;
1825 COMMAND = FM_MODE(floppy,FD_FORMAT);
1826 DR_SELECT = UNIT(current_drive) + ( format_req.head << 2 );
1827 F_SIZECODE = FD_SIZECODE(floppy);
1828 F_SECT_PER_TRACK = floppy->sect << 2 >> F_SIZECODE;
1829 F_GAP = floppy->fmt_gap;
1830 F_FILL = FD_FILL_BYTE;
1831
1832 current_addr = floppy_track_buffer;
1833 raw_cmd.length = 4 * F_SECT_PER_TRACK;
1834
1835
1836 head_shift = (F_SECT_PER_TRACK + 5) / 6;
1837
1838
1839 track_shift = 2 * head_shift + 1;
1840
1841
1842 n = (track_shift * format_req.track + head_shift * format_req.head )
1843 % F_SECT_PER_TRACK;
1844
1845
1846 il = 1;
1847 if (floppy->sect > DP->interleave_sect && F_SIZECODE == 2)
1848 il++;
1849
1850
1851 for (count = 0; count < F_SECT_PER_TRACK; ++count) {
1852 here[count].track = format_req.track;
1853 here[count].head = format_req.head;
1854 here[count].sect = 0;
1855 here[count].size = F_SIZECODE;
1856 }
1857
1858 for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
1859 here[n].sect = count;
1860 n = (n+il) % F_SECT_PER_TRACK;
1861 if (here[n].sect) {
1862 ++n;
1863 if (n>= F_SECT_PER_TRACK) {
1864 n-=F_SECT_PER_TRACK;
1865 while (here[n].sect) ++n;
1866 }
1867 }
1868 }
1869 }
1870
1871 static void redo_format(void)
1872 {
1873 raw_cmd.track = format_req.track << floppy->stretch;
1874 buffer_track = -1;
1875 setup_format_params();
1876 floppy_start();
1877 #ifdef DEBUGT
1878 debugt("queue format request");
1879 #endif
1880 }
1881
1882 static struct cont_t format_cont={
1883 format_interrupt,
1884 redo_format,
1885 bad_flp_intr,
1886 generic_done };
1887
1888 static int do_format(int device, struct format_descr *tmp_format_req)
1889 {
1890 int ret;
1891 int drive=DRIVE(device);
1892
1893 LOCK_FDC(drive,1);
1894 set_floppy(device);
1895 if (!floppy ||
1896 floppy->track > DP->tracks ||
1897 tmp_format_req->track >= floppy->track ||
1898 tmp_format_req->head >= floppy->head ||
1899 (floppy->sect << 2) % (1 << FD_SIZECODE(floppy)) ||
1900 !floppy->fmt_gap) {
1901 process_fd_request();
1902 return -EINVAL;
1903 }
1904 format_req = *tmp_format_req;
1905 format_errors = 0;
1906 cont = &format_cont;
1907 errors = &format_errors;
1908 IWAIT(redo_format);
1909 process_fd_request();
1910 return ret;
1911 }
1912
1913
1914
1915
1916
1917
1918
1919
1920 static void request_done(int uptodate)
1921 {
1922 int block;
1923
1924 probing = 0;
1925 del_timer(&fd_timeout);
1926
1927 if (!CURRENT){
1928 DPRINT("request list destroyed in floppy request done\n");
1929 return;
1930 }
1931 if (uptodate){
1932
1933
1934 block = current_count_sectors + CURRENT->sector;
1935 if (block > DRS->maxblock)
1936 DRS->maxblock=block;
1937 if ( block > floppy->sect)
1938 DRS->maxtrack = 1;
1939
1940
1941 while (current_count_sectors && CURRENT &&
1942 current_count_sectors >= CURRENT->current_nr_sectors ){
1943 current_count_sectors -= CURRENT->current_nr_sectors;
1944 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
1945 CURRENT->sector += CURRENT->current_nr_sectors;
1946 end_request(1);
1947 }
1948 if ( current_count_sectors && CURRENT){
1949
1950 CURRENT->buffer += current_count_sectors <<9;
1951 CURRENT->current_nr_sectors -= current_count_sectors;
1952 CURRENT->nr_sectors -= current_count_sectors;
1953 CURRENT->sector += current_count_sectors;
1954 return;
1955 }
1956
1957 if ( current_count_sectors && ! CURRENT )
1958 DPRINT("request list destroyed in floppy request done\n");
1959
1960 } else {
1961 if(CURRENT->cmd == WRITE) {
1962
1963 DRWE->write_errors++;
1964 if(DRWE->write_errors == 1) {
1965 DRWE->first_error_sector = CURRENT->sector;
1966 DRWE->first_error_generation = DRS->generation;
1967 }
1968 DRWE->last_error_sector = CURRENT->sector;
1969 DRWE->last_error_generation = DRS->generation;
1970 }
1971 end_request(0);
1972 }
1973 }
1974
1975
1976 static void rw_interrupt(void)
1977 {
1978 int nr_sectors, ssize;
1979
1980 if ( ! DRS->first_read_date )
1981 DRS->first_read_date = jiffies;
1982
1983 nr_sectors = 0;
1984 CODE2SIZE;
1985 nr_sectors = ((R_TRACK-TRACK)*floppy->head+R_HEAD-HEAD) *
1986 floppy->sect + ((R_SECTOR-SECTOR) << SIZECODE >> 2) -
1987 (sector_t % floppy->sect) % ssize;
1988
1989 #ifdef CONFIG_FLOPPY_SANITY
1990 if ( nr_sectors > current_count_sectors + ssize -
1991 (current_count_sectors + sector_t) % ssize +
1992 sector_t % ssize){
1993 DPRINT2("long rw: %x instead of %lx\n",
1994 nr_sectors, current_count_sectors);
1995 printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
1996 printk("rh=%d h=%d\n", R_HEAD, HEAD);
1997 printk("rt=%d t=%d\n", R_TRACK, TRACK);
1998 printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
1999 sector_t, ssize);
2000 }
2001 #endif
2002 if ( nr_sectors < 0 )
2003 nr_sectors = 0;
2004 if ( nr_sectors < current_count_sectors )
2005 current_count_sectors = nr_sectors;
2006
2007 switch (interpret_errors()){
2008 case 2:
2009 cont->redo();
2010 return;
2011 case 1:
2012 if ( !current_count_sectors){
2013 cont->error();
2014 cont->redo();
2015 return;
2016 }
2017 break;
2018 case 0:
2019 if ( !current_count_sectors){
2020 cont->redo();
2021 return;
2022 }
2023 current_type[current_drive] = floppy;
2024 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
2025 floppy->size >> 1;
2026 break;
2027 }
2028
2029 if (probing) {
2030 if (DP->flags & FTD_MSG)
2031 DPRINT2("Auto-detected floppy type %s in fd%d\n",
2032 floppy->name,current_drive);
2033 current_type[current_drive] = floppy;
2034 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
2035 floppy->size >> 1;
2036 probing = 0;
2037 }
2038
2039 if ( CT(COMMAND) != FD_READ || current_addr == CURRENT->buffer ){
2040
2041 cont->done(1);
2042 } else if ( CT(COMMAND) == FD_READ){
2043 buffer_track = raw_cmd.track;
2044 buffer_drive = current_drive;
2045 if ( nr_sectors + sector_t > buffer_max )
2046 buffer_max = nr_sectors + sector_t;
2047 }
2048 cont->redo();
2049 }
2050
2051
2052 static int buffer_chain_size(void)
2053 {
2054 struct buffer_head *bh;
2055 int size;
2056 char *base;
2057
2058 base = CURRENT->buffer;
2059 size = CURRENT->current_nr_sectors << 9;
2060 bh = CURRENT->bh;
2061
2062 if (bh){
2063 bh = bh->b_reqnext;
2064 while ( bh && bh->b_data == base + size ){
2065 size += bh->b_size;
2066 bh = bh->b_reqnext;
2067 }
2068 }
2069 return size >> 9;
2070 }
2071
2072
2073 static int transfer_size(int ssize, int max_sector, int max_size)
2074 {
2075 if ( max_sector > sector_t + max_size)
2076 max_sector = sector_t + max_size;
2077
2078
2079 max_sector -= (max_sector % floppy->sect ) % ssize;
2080
2081
2082 current_count_sectors = max_sector - sector_t ;
2083
2084 return max_sector;
2085 }
2086
2087
2088
2089
2090 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
2091 {
2092 int remaining;
2093 struct buffer_head *bh;
2094 char *buffer, *dma_buffer;
2095 int size;
2096
2097 if ( max_sector > max_sector_2 )
2098 max_sector = max_sector_2;
2099
2100 max_sector = transfer_size(ssize, max_sector, CURRENT->nr_sectors);
2101
2102 if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
2103 buffer_max > sector_t + CURRENT->nr_sectors){
2104 current_count_sectors = buffer_max - sector_t;
2105 if ( current_count_sectors > CURRENT->nr_sectors )
2106 current_count_sectors = CURRENT->nr_sectors;
2107 }
2108 remaining = current_count_sectors << 9;
2109 #ifdef CONFIG_FLOPPY_SANITY
2110 if ((remaining >> 9) > CURRENT->nr_sectors &&
2111 CT(COMMAND) == FD_WRITE ){
2112 DPRINT("in copy buffer\n");
2113 printk("current_count_sectors=%ld\n", current_count_sectors);
2114 printk("remaining=%d\n", remaining >> 9);
2115 printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
2116 printk("CURRENT->current_nr_sectors=%ld\n",
2117 CURRENT->current_nr_sectors);
2118 printk("max_sector=%d\n", max_sector);
2119 printk("ssize=%d\n", ssize);
2120 }
2121 #endif
2122
2123 if ( max_sector > buffer_max )
2124 buffer_max = max_sector;
2125
2126 dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
2127
2128 bh = CURRENT->bh;
2129 size = CURRENT->current_nr_sectors << 9;
2130 buffer = CURRENT->buffer;
2131
2132 while ( remaining > 0){
2133 if ( size > remaining )
2134 size = remaining;
2135 #ifdef CONFIG_FLOPPY_SANITY
2136 if (dma_buffer + size >
2137 floppy_track_buffer + (max_buffer_sectors << 10) ||
2138 dma_buffer < floppy_track_buffer ){
2139 DPRINT1("buffer overrun in copy buffer %d\n",
2140 (int) ((floppy_track_buffer - dma_buffer) >>9));
2141 printk("sector_t=%d buffer_min=%d\n",
2142 sector_t, buffer_min);
2143 printk("current_count_sectors=%ld\n",
2144 current_count_sectors);
2145 if ( CT(COMMAND) == FD_READ )
2146 printk("read\n");
2147 if ( CT(COMMAND) == FD_READ )
2148 printk("write\n");
2149 break;
2150 }
2151 if ( ((unsigned long)buffer) % 512 )
2152 DPRINT1("%p buffer not aligned\n", buffer);
2153 #endif
2154 if ( CT(COMMAND) == FD_READ )
2155 memcpy( buffer, dma_buffer, size);
2156 else
2157 memcpy( dma_buffer, buffer, size);
2158 remaining -= size;
2159 if ( !remaining)
2160 break;
2161
2162 dma_buffer += size;
2163 bh = bh->b_reqnext;
2164 #ifdef CONFIG_FLOPPY_SANITY
2165 if ( !bh){
2166 DPRINT("bh=null in copy buffer after copy\n");
2167 break;
2168 }
2169 #endif
2170 size = bh->b_size;
2171 buffer = bh->b_data;
2172 }
2173 #ifdef CONFIG_FLOPPY_SANITY
2174 if ( remaining ){
2175 if ( remaining > 0 )
2176 max_sector -= remaining >> 9;
2177 DPRINT1("weirdness: remaining %d\n", remaining>>9);
2178 }
2179 #endif
2180 }
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192 static int make_raw_rw_request(void)
2193 {
2194 int aligned_sector_t;
2195 int max_sector, max_size, tracksize, ssize;
2196
2197 set_fdc(DRIVE(CURRENT->dev));
2198
2199 raw_cmd.flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
2200 FD_RAW_NEED_SEEK;
2201 raw_cmd.cmd_count = NR_RW;
2202 if (CURRENT->cmd == READ){
2203 raw_cmd.flags |= FD_RAW_READ;
2204 COMMAND = FM_MODE(floppy,FD_READ);
2205 } else if (CURRENT->cmd == WRITE){
2206 raw_cmd.flags |= FD_RAW_WRITE;
2207 COMMAND = FM_MODE(floppy,FD_WRITE);
2208 } else {
2209 DPRINT("make_raw_rw_request: unknown command\n");
2210 return 0;
2211 }
2212
2213 max_sector = floppy->sect * floppy->head;
2214 TRACK = CURRENT->sector / max_sector;
2215 sector_t = CURRENT->sector % max_sector;
2216 if ( floppy->track && TRACK >= floppy->track )
2217 return 0;
2218 HEAD = sector_t / floppy->sect;
2219
2220 if ( TESTF( FD_NEED_TWADDLE) && sector_t < floppy->sect )
2221 max_sector = floppy->sect;
2222
2223
2224 if ( (floppy->rate & FD_2M ) && (!TRACK) && (!HEAD)){
2225 max_sector = 2 * floppy->sect / 3;
2226 if (sector_t >= max_sector){
2227 current_count_sectors = (floppy->sect - sector_t);
2228 if ( current_count_sectors > CURRENT->nr_sectors )
2229 current_count_sectors = CURRENT->nr_sectors;
2230 return 1;
2231 }
2232 SIZECODE = 2;
2233 } else
2234 SIZECODE = FD_SIZECODE(floppy);
2235 raw_cmd.rate = floppy->rate & 3;
2236 if ((floppy->rate & FD_2M) &&
2237 (TRACK || HEAD ) &&
2238 raw_cmd.rate == 2)
2239 raw_cmd.rate = 1;
2240
2241 if ( SIZECODE )
2242 SIZECODE2 = 0xff;
2243 else
2244 SIZECODE2 = 0x80;
2245 raw_cmd.track = TRACK << floppy->stretch;
2246 DR_SELECT = UNIT(current_drive) + ( HEAD << 2 );
2247 GAP = floppy->gap;
2248 CODE2SIZE;
2249 SECT_PER_TRACK = floppy->sect << 2 >> SIZECODE;
2250 SECTOR = ((sector_t % floppy->sect) << 2 >> SIZECODE) + 1;
2251 tracksize = floppy->sect - floppy->sect % ssize;
2252 if ( tracksize < floppy->sect ){
2253 SECT_PER_TRACK ++;
2254 if ( tracksize <= sector_t % floppy->sect)
2255 SECTOR--;
2256 while ( tracksize <= sector_t % floppy->sect){
2257 while( tracksize + ssize > floppy->sect ){
2258 SIZECODE--;
2259 ssize >>= 1;
2260 }
2261 SECTOR++; SECT_PER_TRACK ++;
2262 tracksize += ssize;
2263 }
2264 max_sector = HEAD * floppy->sect + tracksize;
2265 } else if ( !TRACK && !HEAD && !( floppy->rate & FD_2M ) && probing)
2266 max_sector = floppy->sect;
2267
2268 aligned_sector_t = sector_t - ( sector_t % floppy->sect ) % ssize;
2269 max_size = CURRENT->nr_sectors;
2270 if ((raw_cmd.track == buffer_track) && (current_drive == buffer_drive) &&
2271 (sector_t >= buffer_min) && (sector_t < buffer_max)) {
2272
2273 if (CT(COMMAND) == FD_READ) {
2274 copy_buffer(1, max_sector, buffer_max);
2275 return 1;
2276 }
2277 } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
2278 if (CT(COMMAND) == FD_WRITE){
2279 if(sector_t + CURRENT->nr_sectors > ssize &&
2280 sector_t + CURRENT->nr_sectors < ssize + ssize)
2281 max_size = ssize + ssize;
2282 else
2283 max_size = ssize;
2284 }
2285 raw_cmd.flags &= ~FD_RAW_WRITE;
2286 raw_cmd.flags |= FD_RAW_READ;
2287 COMMAND = FM_MODE(floppy,FD_READ);
2288 } else if ((long)CURRENT->buffer <= LAST_DMA_ADDR ) {
2289 int direct, indirect;
2290
2291 indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
2292 sector_t;
2293
2294 max_size = buffer_chain_size();
2295 if ( max_size > ( LAST_DMA_ADDR - ((long) CURRENT->buffer))>>9)
2296 max_size=(LAST_DMA_ADDR - ((long)CURRENT->buffer))>>9;
2297
2298 if ( ((max_size << 9) + ((long) CURRENT->buffer)) / K_64 !=
2299 ((long) CURRENT->buffer ) / K_64 )
2300 max_size = ( K_64 - ((long) CURRENT->buffer) % K_64)>>9;
2301 direct = transfer_size(ssize,max_sector,max_size) - sector_t;
2302
2303
2304
2305
2306
2307
2308
2309 if ((indirect - sector_t) * 2 > (direct - sector_t) * 3 &&
2310 *errors < DP->max_errors.read_track &&
2311
2312 ( ( !probing || (DP->read_track &
2313 (1 <<DRS->probed_format))))){
2314 max_size = CURRENT->nr_sectors;
2315 } else {
2316 current_addr = CURRENT->buffer;
2317 raw_cmd.length = current_count_sectors << 9;
2318 return 2;
2319 }
2320 }
2321
2322 if ( CT(COMMAND) == FD_READ )
2323 max_size = max_sector;
2324
2325
2326 if (buffer_track != raw_cmd.track ||
2327 buffer_drive !=current_drive ||
2328 sector_t < buffer_min ||
2329 ((CT(COMMAND) == FD_READ ||
2330 (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize ))&&
2331 max_sector > 2 * max_buffer_sectors + buffer_min &&
2332 max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
2333 ){
2334 buffer_track = -1;
2335 buffer_drive = current_drive;
2336 buffer_max = buffer_min = aligned_sector_t;
2337 }
2338 current_addr = floppy_track_buffer +((aligned_sector_t-buffer_min )<<9);
2339
2340 if ( CT(COMMAND) == FD_WRITE ){
2341
2342
2343
2344
2345 #ifdef CONFIG_FLOPPY_SANITY
2346 if (sector_t != aligned_sector_t && buffer_track == -1 )
2347 DPRINT("internal error offset !=0 on write\n");
2348 #endif
2349 buffer_track = raw_cmd.track;
2350 buffer_drive = current_drive;
2351 copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min);
2352 } else
2353 transfer_size(ssize, max_sector,
2354 2*max_buffer_sectors+buffer_min-aligned_sector_t);
2355
2356
2357 raw_cmd.length = sector_t+current_count_sectors-aligned_sector_t;
2358 raw_cmd.length = ((raw_cmd.length -1)|(ssize-1))+1;
2359 raw_cmd.length <<= 9;
2360 #ifdef CONFIG_FLOPPY_SANITY
2361 if ((raw_cmd.length < current_count_sectors << 9) ||
2362 (current_addr != CURRENT->buffer &&
2363 CT(COMMAND) == FD_WRITE &&
2364 (aligned_sector_t + (raw_cmd.length >> 9) > buffer_max ||
2365 aligned_sector_t < buffer_min )) ||
2366 raw_cmd.length % ( 128 << SIZECODE ) ||
2367 raw_cmd.length <= 0 || current_count_sectors <= 0){
2368 DPRINT2("fractionary current count b=%lx s=%lx\n",
2369 raw_cmd.length, current_count_sectors);
2370 if ( current_addr != CURRENT->buffer )
2371 printk("addr=%d, length=%ld\n",
2372 (int) ((current_addr - floppy_track_buffer ) >> 9),
2373 current_count_sectors);
2374 printk("st=%d ast=%d mse=%d msi=%d\n",
2375 sector_t, aligned_sector_t, max_sector, max_size);
2376 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2377 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2378 COMMAND, SECTOR, HEAD, TRACK);
2379 printk("buffer drive=%d\n", buffer_drive);
2380 printk("buffer track=%d\n", buffer_track);
2381 printk("buffer_min=%d\n", buffer_min );
2382 printk("buffer_max=%d\n", buffer_max );
2383 return 0;
2384 }
2385
2386 if (current_addr != CURRENT->buffer ){
2387 if (current_addr < floppy_track_buffer ||
2388 current_count_sectors < 0 ||
2389 raw_cmd.length < 0 ||
2390 current_addr + raw_cmd.length >
2391 floppy_track_buffer + (max_buffer_sectors << 10)){
2392 DPRINT("buffer overrun in schedule dma\n");
2393 printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2394 sector_t, buffer_min,
2395 raw_cmd.length >> 9 );
2396 printk("current_count_sectors=%ld\n",
2397 current_count_sectors);
2398 if ( CT(COMMAND) == FD_READ )
2399 printk("read\n");
2400 if ( CT(COMMAND) == FD_READ )
2401 printk("write\n");
2402 return 0;
2403 }
2404 } else if (raw_cmd.length > CURRENT->nr_sectors << 9 ||
2405 current_count_sectors > CURRENT->nr_sectors){
2406 DPRINT("buffer overrun in direct transfer\n");
2407 return 0;
2408 } else if ( raw_cmd.length < current_count_sectors << 9 ){
2409 DPRINT("more sectors than bytes\n");
2410 printk("bytes=%ld\n", raw_cmd.length >> 9 );
2411 printk("sectors=%ld\n", current_count_sectors);
2412 }
2413 #endif
2414 return 2;
2415 }
2416
2417 static void redo_fd_request(void)
2418 {
2419 #define REPEAT {request_done(0); continue; }
2420 int device;
2421 int tmp;
2422 int error;
2423
2424 error = -1;
2425 if (current_drive < N_DRIVE)
2426 floppy_off(current_drive);
2427
2428 if (CURRENT && CURRENT->dev < 0) return;
2429
2430 while(1){
2431 if (!CURRENT) {
2432 CLEAR_INTR;
2433 unlock_fdc();
2434 return;
2435 }
2436 if (MAJOR(CURRENT->dev) != MAJOR_NR)
2437 panic(DEVICE_NAME ": request list destroyed");
2438 if (CURRENT->bh && !CURRENT->bh->b_lock)
2439 panic(DEVICE_NAME ": block not locked");
2440 #if 0
2441 if (!CURRENT->bh->b_count &&
2442 (CURRENT->errors || error == CURRENT->dev)){
2443 error=CURRENT->dev;
2444 DPRINT("skipping read ahead buffer\n");
2445 REPEAT;
2446 }
2447 #endif
2448 error=-1;
2449 device = CURRENT->dev;
2450 set_fdc( DRIVE(device));
2451
2452 del_timer(&fd_timeout);
2453 fd_timeout.expires = DP->timeout;
2454 add_timer(&fd_timeout);
2455
2456 set_floppy(device);
2457 if(start_motor(redo_fd_request)) return;
2458 if(test_bit(current_drive, &fake_change) ||
2459 TESTF(FD_DISK_CHANGED)){
2460 DPRINT("disk absent or changed during operation\n");
2461 REPEAT;
2462 }
2463 if (!floppy) {
2464 if (!probing){
2465 DRS->probed_format = 0;
2466 if ( next_valid_format() ){
2467 DPRINT("no autodetectable formats\n");
2468 floppy = NULL;
2469 REPEAT;
2470 }
2471 }
2472 probing = 1;
2473 floppy = floppy_type+DP->autodetect[DRS->probed_format];
2474 } else
2475 probing = 0;
2476 errors = & (CURRENT->errors);
2477 tmp = make_raw_rw_request();
2478 if ( tmp < 2 ){
2479 request_done(tmp);
2480 continue;
2481 }
2482
2483 if (TESTF(FD_NEED_TWADDLE))
2484 twaddle();
2485 floppy_tq.routine = (void *)(void *) floppy_start;
2486 queue_task(&floppy_tq, &tq_timer);
2487 #ifdef DEBUGT
2488 debugt("queue fd request");
2489 #endif
2490 return;
2491 }
2492 #undef REPEAT
2493 }
2494
2495 static struct cont_t rw_cont={
2496 rw_interrupt,
2497 redo_fd_request,
2498 bad_flp_intr,
2499 request_done };
2500
2501 struct tq_struct request_tq =
2502 { 0, 0, (void *) (void *) redo_fd_request, 0 };
2503
2504 static void process_fd_request(void)
2505 {
2506 cont = &rw_cont;
2507 queue_task(&request_tq, &tq_timer);
2508 }
2509
2510 static void do_fd_request(void)
2511 {
2512 if (fdc_busy)
2513
2514
2515 return;
2516
2517 floppy_grab_irq_and_dma();
2518 fdc_busy=1;
2519 process_fd_request();
2520 }
2521
2522 static struct cont_t poll_cont={
2523 success_and_wakeup,
2524 floppy_ready,
2525 generic_failure,
2526 generic_done };
2527
2528 static int poll_drive(int interruptible, int flag){
2529 int ret;
2530
2531 raw_cmd.flags= flag;
2532 raw_cmd.track=0;
2533 raw_cmd.cmd_count=0;
2534 cont = &poll_cont;
2535 #ifdef DCL_DEBUG
2536 if (DP->flags & FD_DEBUG){
2537 DPRINT("setting NEWCHANGE in poll_drive\n");
2538 }
2539 #endif
2540 SETF(FD_DISK_NEWCHANGE);
2541 WAIT(floppy_ready);
2542 return ret;
2543 }
2544
2545
2546
2547
2548
2549
2550 static void reset_intr(void)
2551 {
2552 printk("weird, reset interrupt called\n");
2553 }
2554
2555 static struct cont_t reset_cont={
2556 reset_intr,
2557 success_and_wakeup,
2558 generic_failure,
2559 generic_done };
2560
2561 static int user_reset_fdc(int drive, int arg, int interruptible)
2562 {
2563 int ret;
2564
2565 ret=0;
2566 if(arg == FD_RESET_IF_NEEDED && !FDCS->reset)
2567 return 0;
2568 LOCK_FDC(drive,interruptible);
2569 if(arg == FD_RESET_ALWAYS)
2570 FDCS->reset=1;
2571 if ( FDCS->reset ){
2572 cont = &reset_cont;
2573 del_timer(&fd_timeout);
2574 fd_timeout.expires = DP->timeout;
2575 add_timer(&fd_timeout);
2576 WAIT(reset_fdc);
2577 }
2578 process_fd_request();
2579 return ret;
2580 }
2581
2582
2583
2584
2585
2586 static int fd_copyout(void *param, volatile void *address, int size)
2587 {
2588 int i;
2589
2590 i = verify_area(VERIFY_WRITE,param,size);
2591 if (i)
2592 return i;
2593 memcpy_tofs(param,(void *) address, size);
2594 return 0;
2595 }
2596
2597 #define COPYOUT(x) (fd_copyout( (void *)param, &(x), sizeof(x)))
2598 #define COPYIN(x) (memcpy_fromfs( &(x), (void *) param, sizeof(x)),0)
2599
2600 static char *drive_name(int type, int drive )
2601 {
2602 struct floppy_struct *floppy;
2603
2604 if ( type )
2605 floppy = floppy_type + type;
2606 else {
2607 if ( UDP->native_format )
2608 floppy = floppy_type + UDP->native_format;
2609 else
2610 return "(null)";
2611 }
2612 if ( floppy->name )
2613 return floppy->name;
2614 else
2615 return "(null)";
2616 }
2617
2618
2619 static struct cont_t raw_cmd_cont={
2620 success_and_wakeup,
2621 failure_and_wakeup,
2622 generic_failure,
2623 generic_done };
2624
2625 static int raw_cmd_ioctl(void *param)
2626 {
2627 int i, drive, count, ret;
2628
2629 if ( FDCS->rawcmd <= 1 )
2630 FDCS->rawcmd = 1;
2631 for ( drive= 0; drive < N_DRIVE; drive++){
2632 if ( FDC(drive) != fdc)
2633 continue;
2634 if ( drive == current_drive ){
2635 if ( UDRS->fd_ref > 1 ){
2636 FDCS->rawcmd = 2;
2637 break;
2638 }
2639 } else if ( UDRS->fd_ref ){
2640 FDCS->rawcmd = 2;
2641 break;
2642 }
2643 }
2644
2645 if(FDCS->reset)
2646 return -EIO;
2647
2648 COPYIN(raw_cmd);
2649 raw_cmd.rate &= 0x03;
2650 count = raw_cmd.length;
2651 if (raw_cmd.flags & (FD_RAW_WRITE | FD_RAW_READ)){
2652 if(count > max_buffer_sectors * 1024 )
2653 return -ENOMEM;
2654 buffer_track = -1;
2655 }
2656 if ( raw_cmd.flags & FD_RAW_WRITE ){
2657 i = verify_area(VERIFY_READ, raw_cmd.data, count );
2658 if (i)
2659 return i;
2660 memcpy_fromfs(floppy_track_buffer, raw_cmd.data, count);
2661 }
2662
2663 current_addr = floppy_track_buffer;
2664 cont = &raw_cmd_cont;
2665 IWAIT(floppy_start);
2666 #ifdef DCL_DEBUG
2667 if (DP->flags & FD_DEBUG){
2668 DPRINT("calling disk change from raw_cmd ioctl\n");
2669 }
2670 #endif
2671 if( disk_change(current_drive) )
2672 raw_cmd.flags |= FD_RAW_DISK_CHANGE;
2673 else
2674 raw_cmd.flags &= ~FD_RAW_DISK_CHANGE;
2675 if(raw_cmd.flags & FD_RAW_NO_MOTOR_AFTER)
2676 motor_off_callback(current_drive);
2677
2678 if ( !ret && !FDCS->reset ){
2679 raw_cmd.reply_count = inr;
2680 for( i=0; i< raw_cmd.reply_count; i++)
2681 raw_cmd.reply[i] = reply_buffer[i];
2682 if ( raw_cmd.flags & ( FD_RAW_READ | FD_RAW_WRITE ))
2683 raw_cmd.length = get_dma_residue(FLOPPY_DMA);
2684 } else
2685 ret = -EIO;
2686 DRS->track = NO_TRACK;
2687 if ( ret )
2688 return ret;
2689
2690 if ( raw_cmd.flags & FD_RAW_READ ){
2691 i=fd_copyout( raw_cmd.data, floppy_track_buffer, count);
2692 if (i)
2693 return i;
2694 }
2695
2696 return COPYOUT(raw_cmd);
2697 }
2698
2699 static int invalidate_drive(int rdev)
2700 {
2701
2702 set_bit( DRIVE(rdev), &fake_change);
2703 process_fd_request();
2704 check_disk_change(rdev);
2705 return 0;
2706 }
2707
2708 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
2709 unsigned long param)
2710 {
2711 #define IOCTL_MODE_BIT 8
2712 #define OPEN_WRITE_BIT 16
2713 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
2714
2715 struct floppy_struct newparams;
2716 struct format_descr tmp_format_req;
2717 int i,device,drive,type,cnt;
2718 struct floppy_struct *this_floppy;
2719 char *name;
2720
2721 device = inode->i_rdev;
2722 switch (cmd) {
2723 RO_IOCTLS(device,param);
2724 }
2725 type = TYPE(device);
2726 drive = DRIVE(device);
2727 switch (cmd) {
2728 case FDGETDRVTYP:
2729 i=verify_area(VERIFY_WRITE,(void *) param,16);
2730 if (i)
2731 return i;
2732 name = drive_name(type,drive);
2733 for ( cnt=0; cnt<16; cnt++){
2734 put_fs_byte(name[cnt],
2735 ((char*)param)+cnt);
2736 if ( ! *name )
2737 break;
2738 }
2739 return 0;
2740 case FDGETMAXERRS:
2741 return COPYOUT(UDP->max_errors);
2742 case FDGETPRM:
2743 if (type)
2744 this_floppy = &floppy_type[type];
2745 else if ((this_floppy = current_type[drive]) ==
2746 NULL)
2747 return -ENODEV;
2748 return COPYOUT(this_floppy[0]);
2749 case FDPOLLDRVSTAT:
2750 LOCK_FDC(drive,1);
2751 CALL(poll_drive(1, FD_RAW_NEED_DISK));
2752 process_fd_request();
2753
2754 case FDGETDRVSTAT:
2755 return COPYOUT(*UDRS);
2756 case FDGETFDCSTAT:
2757 return COPYOUT(*UFDCS);
2758 case FDGETDRVPRM:
2759 return COPYOUT(*UDP);
2760 case FDWERRORGET:
2761 return COPYOUT(*UDRWE);
2762 }
2763 if (!IOCTL_ALLOWED)
2764 return -EPERM;
2765 switch (cmd) {
2766 case FDWERRORCLR:
2767 UDRWE->write_errors = 0;
2768 UDRWE->first_error_sector = 0;
2769 UDRWE->first_error_generation = 0;
2770 UDRWE->last_error_sector = 0;
2771 UDRWE->last_error_generation = 0;
2772 UDRWE->badness = 0;
2773 return 0;
2774 case FDRAWCMD:
2775 if (type)
2776 return -EINVAL;
2777 LOCK_FDC(drive,1);
2778 set_floppy(device);
2779 CALL(i = raw_cmd_ioctl((void *) param));
2780 process_fd_request();
2781 return i;
2782 case FDFMTTRK:
2783 if (UDRS->fd_ref != 1)
2784 return -EBUSY;
2785 COPYIN(tmp_format_req);
2786 return do_format(device, &tmp_format_req);
2787 case FDSETMAXERRS:
2788 return COPYIN(UDP->max_errors);
2789 case FDFMTBEG:
2790 return 0;
2791 case FDCLRPRM:
2792 LOCK_FDC(drive,1);
2793 current_type[drive] = NULL;
2794 floppy_sizes[drive] = MAX_DISK_SIZE;
2795 UDRS->keep_data = 0;
2796 return invalidate_drive(device);
2797 case FDFMTEND:
2798 case FDFLUSH:
2799 LOCK_FDC(drive,1);
2800 return invalidate_drive(device);
2801 case FDSETPRM:
2802 case FDDEFPRM:
2803 COPYIN(newparams);
2804
2805 if(newparams.sect <= 0 ||
2806 newparams.head <= 0 ||
2807 newparams.track <= 0 ||
2808 newparams.track >
2809 UDP->tracks>>newparams.stretch)
2810 return -EINVAL;
2811 if ( type){
2812 if ( !suser() )
2813 return -EPERM;
2814 LOCK_FDC(drive,1);
2815 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2816 if (TYPE(drive_state[cnt].fd_device) == type &&
2817 drive_state[cnt].fd_ref)
2818 set_bit(drive, &fake_change);
2819 }
2820 floppy_type[type] = newparams;
2821 floppy_type[type].name="user format";
2822 for (cnt = type << 2 ;
2823 cnt < (type << 2 ) + 4 ;
2824 cnt++)
2825 floppy_sizes[cnt]=
2826 floppy_sizes[cnt+0x80]=
2827 floppy_type[type].size>>1;
2828 process_fd_request();
2829 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2830 if (TYPE(drive_state[cnt].fd_device) == type &&
2831 drive_state[cnt].fd_ref)
2832 check_disk_change(drive_state[cnt].
2833 fd_device);
2834 }
2835 return 0;
2836 }
2837
2838 LOCK_FDC(drive,1);
2839 if ( cmd != FDDEFPRM )
2840
2841
2842 CALL(poll_drive(1,0));
2843 user_params[drive] = newparams;
2844 if (buffer_drive == drive &&
2845 buffer_max > user_params[drive].sect)
2846 buffer_max=user_params[drive].sect;
2847 current_type[drive] = &user_params[drive];
2848 floppy_sizes[drive] = user_params[drive].size >> 1;
2849 if (cmd == FDDEFPRM)
2850 DRS->keep_data = -1;
2851 else
2852 DRS->keep_data = 1;
2853
2854
2855
2856
2857
2858 if (DRS->maxblock >
2859 user_params[drive].sect ||
2860 DRS->maxtrack )
2861 invalidate_drive(device);
2862 else
2863 process_fd_request();
2864 return 0;
2865 case FDRESET:
2866 return user_reset_fdc( drive, (int)param, 1);
2867 case FDMSGON:
2868 UDP->flags |= FTD_MSG;
2869 return 0;
2870 case FDMSGOFF:
2871 UDP->flags &= ~FTD_MSG;
2872 return 0;
2873 case FDSETEMSGTRESH:
2874 UDP->max_errors.reporting =
2875 (unsigned short) (param & 0x0f);
2876 return 0;
2877 case FDTWADDLE:
2878 LOCK_FDC(drive,1);
2879 twaddle();
2880 process_fd_request();
2881 }
2882 if ( ! suser() )
2883 return -EPERM;
2884 switch(cmd){
2885 case FDSETDRVPRM:
2886 return COPYIN(*UDP);
2887 default:
2888 return -EINVAL;
2889 }
2890 return 0;
2891 #undef IOCTL_ALLOWED
2892 }
2893
2894 static void config_types(void)
2895 {
2896 int first=1;
2897 int drive;
2898
2899
2900 drive=0;
2901 if (!UDP->cmos )
2902 UDP->cmos= FLOPPY0_TYPE;
2903 drive=1;
2904 if (!UDP->cmos && FLOPPY1_TYPE)
2905 UDP->cmos = FLOPPY1_TYPE;
2906
2907
2908
2909
2910 for (drive=0; drive < N_DRIVE; drive++){
2911 if (UDP->cmos >= 0 && UDP->cmos <= NUMBER(default_drive_params))
2912 memcpy((char *) UDP,
2913 (char *) (&default_drive_params[(int)UDP->cmos].params),
2914 sizeof(struct floppy_drive_params));
2915 if (UDP->cmos){
2916 if (first)
2917 printk("Floppy drive(s): ");
2918 else
2919 printk(", ");
2920 first=0;
2921 if (UDP->cmos > 0 ){
2922 ALLOWED_DRIVE_MASK |= 1 << drive;
2923 printk("fd%d is %s", drive,
2924 default_drive_params[(int)UDP->cmos].name);
2925 } else
2926 printk("fd%d is unknown type %d",drive,
2927 UDP->cmos);
2928 }
2929 }
2930 if(!first)
2931 printk("\n");
2932 }
2933
2934 static int floppy_read(struct inode * inode, struct file * filp,
2935 char * buf, int count)
2936 {
2937 int drive = DRIVE(inode->i_rdev);
2938
2939 check_disk_change(inode->i_rdev);
2940 if (UTESTF(FD_DISK_CHANGED))
2941 return -ENXIO;
2942 return block_read(inode, filp, buf, count);
2943 }
2944
2945 static int floppy_write(struct inode * inode, struct file * filp,
2946 char * buf, int count)
2947 {
2948 int block;
2949 int ret;
2950 int drive = DRIVE(inode->i_rdev);
2951
2952 if(!UDRS->maxblock)
2953 UDRS->maxblock=1;
2954 check_disk_change(inode->i_rdev);
2955 if (UTESTF(FD_DISK_CHANGED))
2956 return -ENXIO;
2957 if(!UTESTF(FD_DISK_WRITABLE))
2958 return -EROFS;
2959 block = (filp->f_pos + count) >> 9;
2960 if(block > UDRS->maxblock)
2961 UDRS->maxblock = block;
2962 ret= block_write(inode, filp, buf, count);
2963 return ret;
2964 }
2965
2966 static void floppy_release(struct inode * inode, struct file * filp)
2967 {
2968 int drive;
2969
2970 drive = DRIVE(inode->i_rdev);
2971
2972 if( !filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
2973
2974
2975 block_fsync(inode,filp);
2976
2977 if (UDRS->fd_ref < 0)
2978 UDRS->fd_ref=0;
2979 else if (!UDRS->fd_ref--) {
2980 DPRINT("floppy_release with fd_ref == 0");
2981 UDRS->fd_ref = 0;
2982 }
2983 floppy_release_irq_and_dma();
2984 }
2985
2986
2987
2988
2989
2990
2991 #define RETERR(x) \
2992 do{floppy_release(inode,filp); \
2993 return -(x);}while(0)
2994
2995 static int floppy_open(struct inode * inode, struct file * filp)
2996 {
2997 int drive;
2998 int old_dev;
2999
3000 if (!filp) {
3001 DPRINT("Weird, open called with filp=0\n");
3002 return -EIO;
3003 }
3004
3005 drive = DRIVE(inode->i_rdev);
3006 if (drive >= N_DRIVE ||
3007 !( ALLOWED_DRIVE_MASK & ( 1 << drive)) ||
3008 fdc_state[FDC(drive)].version == FDC_NONE)
3009 return -ENXIO;
3010
3011 if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
3012 return -ENXIO;
3013 old_dev = UDRS->fd_device;
3014 if (UDRS->fd_ref && old_dev != inode->i_rdev)
3015 return -EBUSY;
3016
3017 if(!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
3018 USETF(FD_DISK_CHANGED);
3019 USETF(FD_VERIFY);
3020 }
3021
3022 if(UDRS->fd_ref == -1 ||
3023 (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3024 return -EBUSY;
3025
3026 if (floppy_grab_irq_and_dma())
3027 return -EBUSY;
3028
3029 if (filp->f_flags & O_EXCL)
3030 UDRS->fd_ref = -1;
3031 else
3032 UDRS->fd_ref++;
3033
3034 UDRS->fd_device = inode->i_rdev;
3035
3036 if (old_dev && old_dev != inode->i_rdev) {
3037 if (buffer_drive == drive)
3038 buffer_track = -1;
3039 invalidate_buffers(old_dev);
3040 }
3041
3042
3043 if ((filp->f_mode & 2) || (permission(inode,2) == 0))
3044 filp->f_mode |= IOCTL_MODE_BIT;
3045 if (filp->f_mode & 2)
3046 filp->f_mode |= OPEN_WRITE_BIT;
3047
3048 if (UFDCS->rawcmd == 1)
3049 UFDCS->rawcmd = 2;
3050
3051 if (filp->f_flags & O_NDELAY)
3052 return 0;
3053 if (filp->f_mode & 3) {
3054 UDRS->last_checked = 0;
3055 check_disk_change(inode->i_rdev);
3056 if (UTESTF(FD_DISK_CHANGED))
3057 RETERR(ENXIO);
3058 }
3059 if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
3060 RETERR(EROFS);
3061 return 0;
3062 #undef RETERR
3063 }
3064
3065
3066
3067
3068 static int check_floppy_change(dev_t dev)
3069 {
3070 int drive = DRIVE( dev );
3071
3072 if (MAJOR(dev) != MAJOR_NR) {
3073 DPRINT("floppy_changed: not a floppy\n");
3074 return 0;
3075 }
3076
3077 if (UTESTF(FD_DISK_CHANGED))
3078 return 1;
3079
3080 if(UDRS->last_checked + UDP->checkfreq < jiffies){
3081 lock_fdc(drive,0);
3082 poll_drive(0,0);
3083 process_fd_request();
3084 }
3085
3086 if(UTESTF(FD_DISK_CHANGED) ||
3087 test_bit(drive, &fake_change) ||
3088 (!TYPE(dev) && !current_type[drive]))
3089 return 1;
3090 return 0;
3091 }
3092
3093
3094
3095
3096
3097 static int floppy_revalidate(dev_t dev)
3098 {
3099 #define NO_GEOM (!current_type[drive] && !TYPE(dev))
3100 struct buffer_head * bh;
3101 int drive=DRIVE(dev);
3102 int cf;
3103
3104 if(UTESTF(FD_DISK_CHANGED) || test_bit(drive, &fake_change) || NO_GEOM){
3105 lock_fdc(drive,0);
3106 cf = UTESTF(FD_DISK_CHANGED);
3107 if(! (cf || test_bit(drive, &fake_change) || NO_GEOM)){
3108 process_fd_request();
3109 return 0;
3110 }
3111 UDRS->maxblock = 0;
3112 UDRS->maxtrack = 0;
3113 if ( buffer_drive == drive)
3114 buffer_track = -1;
3115 clear_bit(drive, &fake_change);
3116 UCLEARF(FD_DISK_CHANGED);
3117 if(cf)
3118 UDRS->generation++;
3119 if(NO_GEOM){
3120
3121 int size = floppy_blocksizes[MINOR(dev)];
3122 if (!size)
3123 size = 1024;
3124 if (!(bh = getblk(dev,0,size))){
3125 process_fd_request();
3126 return 1;
3127 }
3128 if ( bh && ! bh->b_uptodate)
3129 ll_rw_block(READ, 1, &bh);
3130 process_fd_request();
3131 wait_on_buffer(bh);
3132 brelse(bh);
3133 return 0;
3134 }
3135 if(cf)
3136 poll_drive(0, FD_RAW_NEED_DISK);
3137 process_fd_request();
3138 }
3139 return 0;
3140 }
3141
3142 static struct file_operations floppy_fops = {
3143 NULL,
3144 floppy_read,
3145 floppy_write,
3146 NULL,
3147 NULL,
3148 fd_ioctl,
3149 NULL,
3150 floppy_open,
3151 floppy_release,
3152 block_fsync,
3153 NULL,
3154 check_floppy_change,
3155 floppy_revalidate,
3156 };
3157
3158
3159
3160
3161
3162
3163
3164
3165 static char get_fdc_version(void)
3166 {
3167 int r;
3168
3169 output_byte(FD_DUMPREGS);
3170 if ( FDCS->reset )
3171 return FDC_NONE;
3172 if ( (r = result()) <= 0x00)
3173 return FDC_NONE;
3174 if ((r==1) && (reply_buffer[0] == 0x80)){
3175 printk("FDC %d is a 8272A\n",fdc);
3176 return FDC_8272A;
3177 }
3178 if (r != 10) {
3179 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
3180 return FDC_UNKNOWN;
3181 }
3182 output_byte(FD_VERSION);
3183 r = result();
3184 if ((r == 1) && (reply_buffer[0] == 0x80)){
3185 printk("FDC %d is a 82072\n",fdc);
3186 return FDC_82072;
3187 }
3188 if ((r != 1) || (reply_buffer[0] != 0x90)) {
3189 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
3190 return FDC_UNKNOWN;
3191 }
3192 output_byte(FD_UNLOCK);
3193 r = result();
3194 if ((r == 1) && (reply_buffer[0] == 0x80)){
3195 printk("FDC %d is a pre-1991 82077\n", fdc);
3196 return FDC_82077_ORIG;
3197 }
3198 if ((r != 1) || (reply_buffer[0] != 0x00)) {
3199 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
3200 return FDC_UNKNOWN;
3201 }
3202 printk("FDC %d is a post-1991 82077\n",fdc);
3203 return FDC_82077;
3204 }
3205
3206
3207
3208
3209
3210
3211 void floppy_invert_dcl(int *ints,int param)
3212 {
3213 int i;
3214
3215 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3216 if (param)
3217 default_drive_params[i].params.flags |= 0x80;
3218 else
3219 default_drive_params[i].params.flags &= ~0x80;
3220 }
3221 DPRINT("Configuring drives for inverted dcl\n");
3222 }
3223
3224 static void daring(int *ints,int param)
3225 {
3226 int i;
3227
3228 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3229 if (param){
3230 default_drive_params[i].params.select_delay = 0;
3231 default_drive_params[i].params.flags |= FD_SILENT_DCL_CLEAR;
3232 } else {
3233 default_drive_params[i].params.select_delay = 2*HZ/100;
3234 default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR;
3235 }
3236 }
3237 DPRINT1("Assuming %s floppy hardware\n", param ? "standard" : "broken");
3238 }
3239
3240 static void allow_drives(int *ints, int param)
3241 {
3242 ALLOWED_DRIVE_MASK=param;
3243 DPRINT1("setting allowed_drive_mask to 0x%x\n", param);
3244 }
3245
3246 static void fdc2_adr(int *ints, int param)
3247 {
3248 FDC2 = param;
3249 if(param)
3250 DPRINT1("enabling second fdc at address 0x%3x\n", FDC2);
3251 else
3252 DPRINT("disabling second fdc\n");
3253 }
3254
3255 static void unex(int *ints,int param)
3256 {
3257 print_unex = param;
3258 DPRINT1("%sprinting messages for unexpected interrupts\n",
3259 param ? "" : "not ");
3260 }
3261
3262 static void set_cmos(int *ints, int dummy)
3263 {
3264 int current_drive=0;
3265
3266 if ( ints[0] != 2 ){
3267 DPRINT("wrong number of parameter for cmos\n");
3268 return;
3269 }
3270 current_drive = ints[1];
3271 if (current_drive < 0 || current_drive >= 8 ){
3272 DPRINT("bad drive for set_cmos\n");
3273 return;
3274 }
3275 if(ints[2] <= 0 || ints[2] >= NUMBER(default_drive_params)){
3276 DPRINT1("bad cmos code %d\n", ints[2]);
3277 return;
3278 }
3279 DP->cmos = ints[2];
3280 DPRINT1("setting cmos code to %d\n", ints[2]);
3281 }
3282
3283 static struct param_table {
3284 char *name;
3285 void (*fn)(int *ints, int param);
3286 int def_param;
3287 } config_params[]={
3288 { "allowed_drive_mask", allow_drives, 0xff },
3289 { "all_drives", allow_drives, 0xff },
3290 { "asus_pci", allow_drives, 0x33 },
3291
3292 { "daring", daring, 1},
3293
3294 { "two_fdc", fdc2_adr, 0x370 },
3295 { "one_fdc", fdc2_adr, 0 },
3296
3297 { "thinkpad", floppy_invert_dcl, 1 },
3298
3299 { "cmos", set_cmos, 0 },
3300
3301 { "unexpected_interrupts", unex, 1 },
3302 { "no_unexpected_interrupts", unex, 0 },
3303 { "L40SX", unex, 0 } };
3304
3305 #define FLOPPY_SETUP
3306 void floppy_setup(char *str, int *ints)
3307 {
3308 int i;
3309 int param;
3310 if(!str)
3311 return;
3312 for(i=0; i< ARRAY_SIZE(config_params); i++){
3313 if (strcmp(str,config_params[i].name) == 0 ){
3314 if (ints[0] )
3315 param = ints[1];
3316 else
3317 param = config_params[i].def_param;
3318 config_params[i].fn(ints,param);
3319 return;
3320 }
3321 }
3322 DPRINT1("unknown floppy option %s\n", str);
3323 DPRINT("allowed options are:");
3324 for(i=0; i< ARRAY_SIZE(config_params); i++)
3325 printk(" %s",config_params[i].name);
3326 printk("\n");
3327 DPRINT("Read linux/drivers/block/README.fd\n");
3328 }
3329
3330 #ifdef FD_MODULE
3331 static
3332 #endif
3333 int new_floppy_init(void)
3334 {
3335 int i,drive;
3336 int have_no_fdc=0;
3337
3338 sti();
3339
3340 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
3341 printk("Unable to get major %d for floppy\n",MAJOR_NR);
3342 return -EBUSY;
3343 }
3344
3345 for(i=0; i<256; i++)
3346 if ( TYPE(i))
3347 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
3348 else
3349 floppy_sizes[i] = MAX_DISK_SIZE;
3350
3351 blk_size[MAJOR_NR] = floppy_sizes;
3352 blksize_size[MAJOR_NR] = floppy_blocksizes;
3353 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3354 del_timer(&fd_timeout);
3355 config_types();
3356
3357 fdc_state[0].address = FDC1;
3358 fdc_state[0].dor = 0;
3359 #if N_FDC > 1
3360 fdc_state[1].address = FDC2;
3361 fdc_state[1].dor = 0;
3362 #endif
3363
3364 for (i = 0 ; i < N_FDC ; i++) {
3365 fdc = i;
3366 FDCS->dtr = -1;
3367 FDCS->dor = 0x4;
3368 FDCS->reset = 0;
3369 FDCS->version = FDC_NONE;
3370 }
3371
3372 if(floppy_grab_irq_and_dma()){
3373 unregister_blkdev(MAJOR_NR,"fd");
3374 return -EBUSY;
3375 }
3376
3377
3378 for (drive = 0; drive < N_DRIVE ; drive++) {
3379 UDRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE | FD_DISK_CHANGED;
3380 UDRS->generation = 0;
3381 UDRS->keep_data = 0;
3382 UDRS->fd_ref = 0;
3383 UDRS->fd_device = 0;
3384 UDRWE->write_errors = 0;
3385 UDRWE->first_error_sector = 0;
3386 UDRWE->first_error_generation = 0;
3387 UDRWE->last_error_sector = 0;
3388 UDRWE->last_error_generation = 0;
3389 UDRWE->badness = 0;
3390 }
3391
3392 for (i = 0 ; i < N_FDC ; i++) {
3393 fdc = i;
3394 if (FDCS->address == -1 )
3395 continue;
3396 FDCS->rawcmd = 2;
3397 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED,0)){
3398 FDCS->address = -1;
3399 continue;
3400 }
3401
3402 FDCS->version = get_fdc_version();
3403 if (FDCS->version == FDC_NONE){
3404 FDCS->address = -1;
3405 continue;
3406 }
3407
3408 have_no_fdc = 0;
3409
3410
3411
3412
3413 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
3414 user_reset_fdc(-1,FD_RESET_ALWAYS,0);
3415 }
3416 fdc=0;
3417 current_drive = 0;
3418 floppy_release_irq_and_dma();
3419 initialising=0;
3420 if(have_no_fdc)
3421 unregister_blkdev(MAJOR_NR,"fd");
3422 return have_no_fdc;
3423 }
3424
3425
3426 void floppy_init(void)
3427 {
3428 new_floppy_init();
3429 }
3430
3431 static int floppy_grab_irq_and_dma(void)
3432 {
3433 int i;
3434 cli();
3435 if (usage_count++){
3436 sti();
3437 return 0;
3438 }
3439 sti();
3440 #ifdef FD_MODULE
3441 MOD_INC_USE_COUNT;
3442 #endif
3443 for(i=0; i< N_FDC; i++){
3444 if(FDCS->address != -1){
3445 fdc = i;
3446 reset_fdc_info(1);
3447 outb_p(FDCS->dor, FD_DOR);
3448 }
3449 }
3450 set_dor(0, ~0, 8);
3451
3452 if (request_irq(FLOPPY_IRQ, floppy_interrupt, SA_INTERRUPT, "floppy")) {
3453 DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
3454 FLOPPY_IRQ);
3455 return -1;
3456 }
3457 if (request_dma(FLOPPY_DMA,"floppy")) {
3458 DPRINT1("Unable to grab DMA%d for the floppy driver\n",
3459 FLOPPY_DMA);
3460 free_irq(FLOPPY_IRQ);
3461 return -1;
3462 }
3463 for(fdc = 0; fdc < N_FDC ; fdc++)
3464 if(FDCS->address != -1)
3465 outb_p(FDCS->dor, FD_DOR);
3466 fdc = 0;
3467 enable_irq(FLOPPY_IRQ);
3468 return 0;
3469 }
3470
3471 static void floppy_release_irq_and_dma(void)
3472 {
3473 #ifdef CONFIG_FLOPPY_SANITY
3474 int drive;
3475 #endif
3476 cli();
3477 if (--usage_count){
3478 sti();
3479 return;
3480 }
3481 sti();
3482 #ifdef FD_MODULE
3483 MOD_DEC_USE_COUNT;
3484 #endif
3485 disable_dma(FLOPPY_DMA);
3486 free_dma(FLOPPY_DMA);
3487 disable_irq(FLOPPY_IRQ);
3488 free_irq(FLOPPY_IRQ);
3489
3490 set_dor(0, ~0, 8);
3491 #if N_FDC > 1
3492 set_dor(1, ~8, 0);
3493 #endif
3494 floppy_enable_hlt();
3495 #ifdef CONFIG_FLOPPY_SANITY
3496 for(drive=0; drive < N_FDC * 4; drive++)
3497 if( motor_off_timer[drive].next )
3498 printk("motor off timer %d still active\n", drive);
3499
3500 if(fd_timeout.next)
3501 printk("floppy timer still active\n");
3502 if (fd_timer.next)
3503 printk("auxiliary floppy timer still active\n");
3504 if(floppy_tq.sync)
3505 printk("task queue still active\n");
3506 #endif
3507 }
3508