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_max ||
2329 sector_t < buffer_min ||
2330 ((CT(COMMAND) == FD_READ ||
2331 (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize ))&&
2332 max_sector > 2 * max_buffer_sectors + buffer_min &&
2333 max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
2334 ){
2335 buffer_track = -1;
2336 buffer_drive = current_drive;
2337 buffer_max = buffer_min = aligned_sector_t;
2338 }
2339 current_addr = floppy_track_buffer +((aligned_sector_t-buffer_min )<<9);
2340
2341 if ( CT(COMMAND) == FD_WRITE ){
2342
2343
2344
2345
2346 #ifdef CONFIG_FLOPPY_SANITY
2347 if (sector_t != aligned_sector_t && buffer_track == -1 )
2348 DPRINT("internal error offset !=0 on write\n");
2349 #endif
2350 buffer_track = raw_cmd.track;
2351 buffer_drive = current_drive;
2352 copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min);
2353 } else
2354 transfer_size(ssize, max_sector,
2355 2*max_buffer_sectors+buffer_min-aligned_sector_t);
2356
2357
2358 raw_cmd.length = sector_t+current_count_sectors-aligned_sector_t;
2359 raw_cmd.length = ((raw_cmd.length -1)|(ssize-1))+1;
2360 raw_cmd.length <<= 9;
2361 #ifdef CONFIG_FLOPPY_SANITY
2362 if ((raw_cmd.length < current_count_sectors << 9) ||
2363 (current_addr != CURRENT->buffer &&
2364 CT(COMMAND) == FD_WRITE &&
2365 (aligned_sector_t + (raw_cmd.length >> 9) > buffer_max ||
2366 aligned_sector_t < buffer_min )) ||
2367 raw_cmd.length % ( 128 << SIZECODE ) ||
2368 raw_cmd.length <= 0 || current_count_sectors <= 0){
2369 DPRINT2("fractionary current count b=%lx s=%lx\n",
2370 raw_cmd.length, current_count_sectors);
2371 if ( current_addr != CURRENT->buffer )
2372 printk("addr=%d, length=%ld\n",
2373 (int) ((current_addr - floppy_track_buffer ) >> 9),
2374 current_count_sectors);
2375 printk("st=%d ast=%d mse=%d msi=%d\n",
2376 sector_t, aligned_sector_t, max_sector, max_size);
2377 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2378 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2379 COMMAND, SECTOR, HEAD, TRACK);
2380 printk("buffer drive=%d\n", buffer_drive);
2381 printk("buffer track=%d\n", buffer_track);
2382 printk("buffer_min=%d\n", buffer_min );
2383 printk("buffer_max=%d\n", buffer_max );
2384 return 0;
2385 }
2386
2387 if (current_addr != CURRENT->buffer ){
2388 if (current_addr < floppy_track_buffer ||
2389 current_count_sectors < 0 ||
2390 raw_cmd.length < 0 ||
2391 current_addr + raw_cmd.length >
2392 floppy_track_buffer + (max_buffer_sectors << 10)){
2393 DPRINT("buffer overrun in schedule dma\n");
2394 printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2395 sector_t, buffer_min,
2396 raw_cmd.length >> 9 );
2397 printk("current_count_sectors=%ld\n",
2398 current_count_sectors);
2399 if ( CT(COMMAND) == FD_READ )
2400 printk("read\n");
2401 if ( CT(COMMAND) == FD_READ )
2402 printk("write\n");
2403 return 0;
2404 }
2405 } else if (raw_cmd.length > CURRENT->nr_sectors << 9 ||
2406 current_count_sectors > CURRENT->nr_sectors){
2407 DPRINT("buffer overrun in direct transfer\n");
2408 return 0;
2409 } else if ( raw_cmd.length < current_count_sectors << 9 ){
2410 DPRINT("more sectors than bytes\n");
2411 printk("bytes=%ld\n", raw_cmd.length >> 9 );
2412 printk("sectors=%ld\n", current_count_sectors);
2413 }
2414 #endif
2415 return 2;
2416 }
2417
2418 static void redo_fd_request(void)
2419 {
2420 #define REPEAT {request_done(0); continue; }
2421 int device;
2422 int tmp;
2423 int error;
2424
2425 error = -1;
2426 if (current_drive < N_DRIVE)
2427 floppy_off(current_drive);
2428
2429 if (CURRENT && CURRENT->dev < 0) return;
2430
2431 while(1){
2432 if (!CURRENT) {
2433 CLEAR_INTR;
2434 unlock_fdc();
2435 return;
2436 }
2437 if (MAJOR(CURRENT->dev) != MAJOR_NR)
2438 panic(DEVICE_NAME ": request list destroyed");
2439 if (CURRENT->bh && !CURRENT->bh->b_lock)
2440 panic(DEVICE_NAME ": block not locked");
2441 #if 0
2442 if (!CURRENT->bh->b_count &&
2443 (CURRENT->errors || error == CURRENT->dev)){
2444 error=CURRENT->dev;
2445 DPRINT("skipping read ahead buffer\n");
2446 REPEAT;
2447 }
2448 #endif
2449 error=-1;
2450 device = CURRENT->dev;
2451 set_fdc( DRIVE(device));
2452
2453 del_timer(&fd_timeout);
2454 fd_timeout.expires = DP->timeout;
2455 add_timer(&fd_timeout);
2456
2457 set_floppy(device);
2458 if(start_motor(redo_fd_request)) return;
2459 if(test_bit(current_drive, &fake_change) ||
2460 TESTF(FD_DISK_CHANGED)){
2461 DPRINT("disk absent or changed during operation\n");
2462 REPEAT;
2463 }
2464 if (!floppy) {
2465 if (!probing){
2466 DRS->probed_format = 0;
2467 if ( next_valid_format() ){
2468 DPRINT("no autodetectable formats\n");
2469 floppy = NULL;
2470 REPEAT;
2471 }
2472 }
2473 probing = 1;
2474 floppy = floppy_type+DP->autodetect[DRS->probed_format];
2475 } else
2476 probing = 0;
2477 errors = & (CURRENT->errors);
2478 tmp = make_raw_rw_request();
2479 if ( tmp < 2 ){
2480 request_done(tmp);
2481 continue;
2482 }
2483
2484 if (TESTF(FD_NEED_TWADDLE))
2485 twaddle();
2486 floppy_tq.routine = (void *)(void *) floppy_start;
2487 queue_task(&floppy_tq, &tq_timer);
2488 #ifdef DEBUGT
2489 debugt("queue fd request");
2490 #endif
2491 return;
2492 }
2493 #undef REPEAT
2494 }
2495
2496 static struct cont_t rw_cont={
2497 rw_interrupt,
2498 redo_fd_request,
2499 bad_flp_intr,
2500 request_done };
2501
2502 struct tq_struct request_tq =
2503 { 0, 0, (void *) (void *) redo_fd_request, 0 };
2504
2505 static void process_fd_request(void)
2506 {
2507 cont = &rw_cont;
2508 queue_task(&request_tq, &tq_timer);
2509 }
2510
2511 static void do_fd_request(void)
2512 {
2513 if (fdc_busy)
2514
2515
2516 return;
2517
2518 floppy_grab_irq_and_dma();
2519 fdc_busy=1;
2520 process_fd_request();
2521 }
2522
2523 static struct cont_t poll_cont={
2524 success_and_wakeup,
2525 floppy_ready,
2526 generic_failure,
2527 generic_done };
2528
2529 static int poll_drive(int interruptible, int flag){
2530 int ret;
2531
2532 raw_cmd.flags= flag;
2533 raw_cmd.track=0;
2534 raw_cmd.cmd_count=0;
2535 cont = &poll_cont;
2536 #ifdef DCL_DEBUG
2537 if (DP->flags & FD_DEBUG){
2538 DPRINT("setting NEWCHANGE in poll_drive\n");
2539 }
2540 #endif
2541 SETF(FD_DISK_NEWCHANGE);
2542 WAIT(floppy_ready);
2543 return ret;
2544 }
2545
2546
2547
2548
2549
2550
2551 static void reset_intr(void)
2552 {
2553 printk("weird, reset interrupt called\n");
2554 }
2555
2556 static struct cont_t reset_cont={
2557 reset_intr,
2558 success_and_wakeup,
2559 generic_failure,
2560 generic_done };
2561
2562 static int user_reset_fdc(int drive, int arg, int interruptible)
2563 {
2564 int ret;
2565
2566 ret=0;
2567 if(arg == FD_RESET_IF_NEEDED && !FDCS->reset)
2568 return 0;
2569 LOCK_FDC(drive,interruptible);
2570 if(arg == FD_RESET_ALWAYS)
2571 FDCS->reset=1;
2572 if ( FDCS->reset ){
2573 cont = &reset_cont;
2574 del_timer(&fd_timeout);
2575 fd_timeout.expires = DP->timeout;
2576 add_timer(&fd_timeout);
2577 WAIT(reset_fdc);
2578 }
2579 process_fd_request();
2580 return ret;
2581 }
2582
2583
2584
2585
2586
2587 static int fd_copyout(void *param, volatile void *address, int size)
2588 {
2589 int i;
2590
2591 i = verify_area(VERIFY_WRITE,param,size);
2592 if (i)
2593 return i;
2594 memcpy_tofs(param,(void *) address, size);
2595 return 0;
2596 }
2597
2598 #define COPYOUT(x) (fd_copyout( (void *)param, &(x), sizeof(x)))
2599 #define COPYIN(x) (memcpy_fromfs( &(x), (void *) param, sizeof(x)),0)
2600
2601 static char *drive_name(int type, int drive )
2602 {
2603 struct floppy_struct *floppy;
2604
2605 if ( type )
2606 floppy = floppy_type + type;
2607 else {
2608 if ( UDP->native_format )
2609 floppy = floppy_type + UDP->native_format;
2610 else
2611 return "(null)";
2612 }
2613 if ( floppy->name )
2614 return floppy->name;
2615 else
2616 return "(null)";
2617 }
2618
2619
2620 static struct cont_t raw_cmd_cont={
2621 success_and_wakeup,
2622 failure_and_wakeup,
2623 generic_failure,
2624 generic_done };
2625
2626 static int raw_cmd_ioctl(void *param)
2627 {
2628 int i, drive, count, ret;
2629
2630 if ( FDCS->rawcmd <= 1 )
2631 FDCS->rawcmd = 1;
2632 for ( drive= 0; drive < N_DRIVE; drive++){
2633 if ( FDC(drive) != fdc)
2634 continue;
2635 if ( drive == current_drive ){
2636 if ( UDRS->fd_ref > 1 ){
2637 FDCS->rawcmd = 2;
2638 break;
2639 }
2640 } else if ( UDRS->fd_ref ){
2641 FDCS->rawcmd = 2;
2642 break;
2643 }
2644 }
2645
2646 if(FDCS->reset)
2647 return -EIO;
2648
2649 COPYIN(raw_cmd);
2650 raw_cmd.rate &= 0x03;
2651 count = raw_cmd.length;
2652 if (raw_cmd.flags & (FD_RAW_WRITE | FD_RAW_READ)){
2653 if(count > max_buffer_sectors * 1024 )
2654 return -ENOMEM;
2655 buffer_track = -1;
2656 }
2657 if ( raw_cmd.flags & FD_RAW_WRITE ){
2658 i = verify_area(VERIFY_READ, raw_cmd.data, count );
2659 if (i)
2660 return i;
2661 memcpy_fromfs(floppy_track_buffer, raw_cmd.data, count);
2662 }
2663
2664 current_addr = floppy_track_buffer;
2665 cont = &raw_cmd_cont;
2666 IWAIT(floppy_start);
2667 #ifdef DCL_DEBUG
2668 if (DP->flags & FD_DEBUG){
2669 DPRINT("calling disk change from raw_cmd ioctl\n");
2670 }
2671 #endif
2672 if( disk_change(current_drive) )
2673 raw_cmd.flags |= FD_RAW_DISK_CHANGE;
2674 else
2675 raw_cmd.flags &= ~FD_RAW_DISK_CHANGE;
2676 if(raw_cmd.flags & FD_RAW_NO_MOTOR_AFTER)
2677 motor_off_callback(current_drive);
2678
2679 if ( !ret && !FDCS->reset ){
2680 raw_cmd.reply_count = inr;
2681 for( i=0; i< raw_cmd.reply_count; i++)
2682 raw_cmd.reply[i] = reply_buffer[i];
2683 if ( raw_cmd.flags & ( FD_RAW_READ | FD_RAW_WRITE ))
2684 raw_cmd.length = get_dma_residue(FLOPPY_DMA);
2685 } else
2686 ret = -EIO;
2687 DRS->track = NO_TRACK;
2688 if ( ret )
2689 return ret;
2690
2691 if ( raw_cmd.flags & FD_RAW_READ ){
2692 i=fd_copyout( raw_cmd.data, floppy_track_buffer, count);
2693 if (i)
2694 return i;
2695 }
2696
2697 return COPYOUT(raw_cmd);
2698 }
2699
2700 static int invalidate_drive(int rdev)
2701 {
2702
2703 set_bit( DRIVE(rdev), &fake_change);
2704 process_fd_request();
2705 check_disk_change(rdev);
2706 return 0;
2707 }
2708
2709 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
2710 unsigned long param)
2711 {
2712 #define IOCTL_MODE_BIT 8
2713 #define OPEN_WRITE_BIT 16
2714 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
2715
2716 struct floppy_struct newparams;
2717 struct format_descr tmp_format_req;
2718 int i,device,drive,type,cnt;
2719 struct floppy_struct *this_floppy;
2720 char *name;
2721
2722 device = inode->i_rdev;
2723 switch (cmd) {
2724 RO_IOCTLS(device,param);
2725 }
2726 type = TYPE(device);
2727 drive = DRIVE(device);
2728 switch (cmd) {
2729 case FDGETDRVTYP:
2730 i=verify_area(VERIFY_WRITE,(void *) param,16);
2731 if (i)
2732 return i;
2733 name = drive_name(type,drive);
2734 for ( cnt=0; cnt<16; cnt++){
2735 put_fs_byte(name[cnt],
2736 ((char*)param)+cnt);
2737 if ( ! *name )
2738 break;
2739 }
2740 return 0;
2741 case FDGETMAXERRS:
2742 return COPYOUT(UDP->max_errors);
2743 case FDGETPRM:
2744 if (type)
2745 this_floppy = &floppy_type[type];
2746 else if ((this_floppy = current_type[drive]) ==
2747 NULL)
2748 return -ENODEV;
2749 return COPYOUT(this_floppy[0]);
2750 case FDPOLLDRVSTAT:
2751 LOCK_FDC(drive,1);
2752 CALL(poll_drive(1, FD_RAW_NEED_DISK));
2753 process_fd_request();
2754
2755 case FDGETDRVSTAT:
2756 return COPYOUT(*UDRS);
2757 case FDGETFDCSTAT:
2758 return COPYOUT(*UFDCS);
2759 case FDGETDRVPRM:
2760 return COPYOUT(*UDP);
2761 case FDWERRORGET:
2762 return COPYOUT(*UDRWE);
2763 }
2764 if (!IOCTL_ALLOWED)
2765 return -EPERM;
2766 switch (cmd) {
2767 case FDWERRORCLR:
2768 UDRWE->write_errors = 0;
2769 UDRWE->first_error_sector = 0;
2770 UDRWE->first_error_generation = 0;
2771 UDRWE->last_error_sector = 0;
2772 UDRWE->last_error_generation = 0;
2773 UDRWE->badness = 0;
2774 return 0;
2775 case FDRAWCMD:
2776 if (type)
2777 return -EINVAL;
2778 LOCK_FDC(drive,1);
2779 set_floppy(device);
2780 CALL(i = raw_cmd_ioctl((void *) param));
2781 process_fd_request();
2782 return i;
2783 case FDFMTTRK:
2784 if (UDRS->fd_ref != 1)
2785 return -EBUSY;
2786 COPYIN(tmp_format_req);
2787 return do_format(device, &tmp_format_req);
2788 case FDSETMAXERRS:
2789 return COPYIN(UDP->max_errors);
2790 case FDFMTBEG:
2791 return 0;
2792 case FDCLRPRM:
2793 LOCK_FDC(drive,1);
2794 current_type[drive] = NULL;
2795 floppy_sizes[drive] = MAX_DISK_SIZE;
2796 UDRS->keep_data = 0;
2797 return invalidate_drive(device);
2798 case FDFMTEND:
2799 case FDFLUSH:
2800 LOCK_FDC(drive,1);
2801 return invalidate_drive(device);
2802 case FDSETPRM:
2803 case FDDEFPRM:
2804 COPYIN(newparams);
2805
2806 if(newparams.sect <= 0 ||
2807 newparams.head <= 0 ||
2808 newparams.track <= 0 ||
2809 newparams.track >
2810 UDP->tracks>>newparams.stretch)
2811 return -EINVAL;
2812 if ( type){
2813 if ( !suser() )
2814 return -EPERM;
2815 LOCK_FDC(drive,1);
2816 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2817 if (TYPE(drive_state[cnt].fd_device) == type &&
2818 drive_state[cnt].fd_ref)
2819 set_bit(drive, &fake_change);
2820 }
2821 floppy_type[type] = newparams;
2822 floppy_type[type].name="user format";
2823 for (cnt = type << 2 ;
2824 cnt < (type << 2 ) + 4 ;
2825 cnt++)
2826 floppy_sizes[cnt]=
2827 floppy_sizes[cnt+0x80]=
2828 floppy_type[type].size>>1;
2829 process_fd_request();
2830 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2831 if (TYPE(drive_state[cnt].fd_device) == type &&
2832 drive_state[cnt].fd_ref)
2833 check_disk_change(drive_state[cnt].
2834 fd_device);
2835 }
2836 return 0;
2837 }
2838
2839 LOCK_FDC(drive,1);
2840 if ( cmd != FDDEFPRM )
2841
2842
2843 CALL(poll_drive(1,0));
2844 user_params[drive] = newparams;
2845 if (buffer_drive == drive &&
2846 buffer_max > user_params[drive].sect)
2847 buffer_max=user_params[drive].sect;
2848 current_type[drive] = &user_params[drive];
2849 floppy_sizes[drive] = user_params[drive].size >> 1;
2850 if (cmd == FDDEFPRM)
2851 DRS->keep_data = -1;
2852 else
2853 DRS->keep_data = 1;
2854
2855
2856
2857
2858
2859 if (DRS->maxblock >
2860 user_params[drive].sect ||
2861 DRS->maxtrack )
2862 invalidate_drive(device);
2863 else
2864 process_fd_request();
2865 return 0;
2866 case FDRESET:
2867 return user_reset_fdc( drive, (int)param, 1);
2868 case FDMSGON:
2869 UDP->flags |= FTD_MSG;
2870 return 0;
2871 case FDMSGOFF:
2872 UDP->flags &= ~FTD_MSG;
2873 return 0;
2874 case FDSETEMSGTRESH:
2875 UDP->max_errors.reporting =
2876 (unsigned short) (param & 0x0f);
2877 return 0;
2878 case FDTWADDLE:
2879 LOCK_FDC(drive,1);
2880 twaddle();
2881 process_fd_request();
2882 }
2883 if ( ! suser() )
2884 return -EPERM;
2885 switch(cmd){
2886 case FDSETDRVPRM:
2887 return COPYIN(*UDP);
2888 default:
2889 return -EINVAL;
2890 }
2891 return 0;
2892 #undef IOCTL_ALLOWED
2893 }
2894
2895 static void config_types(void)
2896 {
2897 int first=1;
2898 int drive;
2899
2900
2901 drive=0;
2902 if (!UDP->cmos )
2903 UDP->cmos= FLOPPY0_TYPE;
2904 drive=1;
2905 if (!UDP->cmos && FLOPPY1_TYPE)
2906 UDP->cmos = FLOPPY1_TYPE;
2907
2908
2909
2910
2911 for (drive=0; drive < N_DRIVE; drive++){
2912 if (UDP->cmos >= 0 && UDP->cmos <= NUMBER(default_drive_params))
2913 memcpy((char *) UDP,
2914 (char *) (&default_drive_params[(int)UDP->cmos].params),
2915 sizeof(struct floppy_drive_params));
2916 if (UDP->cmos){
2917 if (first)
2918 printk("Floppy drive(s): ");
2919 else
2920 printk(", ");
2921 first=0;
2922 if (UDP->cmos > 0 ){
2923 ALLOWED_DRIVE_MASK |= 1 << drive;
2924 printk("fd%d is %s", drive,
2925 default_drive_params[(int)UDP->cmos].name);
2926 } else
2927 printk("fd%d is unknown type %d",drive,
2928 UDP->cmos);
2929 }
2930 }
2931 if(!first)
2932 printk("\n");
2933 }
2934
2935 static int floppy_read(struct inode * inode, struct file * filp,
2936 char * buf, int count)
2937 {
2938 int drive = DRIVE(inode->i_rdev);
2939
2940 check_disk_change(inode->i_rdev);
2941 if (UTESTF(FD_DISK_CHANGED))
2942 return -ENXIO;
2943 return block_read(inode, filp, buf, count);
2944 }
2945
2946 static int floppy_write(struct inode * inode, struct file * filp,
2947 char * buf, int count)
2948 {
2949 int block;
2950 int ret;
2951 int drive = DRIVE(inode->i_rdev);
2952
2953 if(!UDRS->maxblock)
2954 UDRS->maxblock=1;
2955 check_disk_change(inode->i_rdev);
2956 if (UTESTF(FD_DISK_CHANGED))
2957 return -ENXIO;
2958 if(!UTESTF(FD_DISK_WRITABLE))
2959 return -EROFS;
2960 block = (filp->f_pos + count) >> 9;
2961 if(block > UDRS->maxblock)
2962 UDRS->maxblock = block;
2963 ret= block_write(inode, filp, buf, count);
2964 return ret;
2965 }
2966
2967 static void floppy_release(struct inode * inode, struct file * filp)
2968 {
2969 int drive;
2970
2971 drive = DRIVE(inode->i_rdev);
2972
2973 if( !filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
2974
2975
2976 block_fsync(inode,filp);
2977
2978 if (UDRS->fd_ref < 0)
2979 UDRS->fd_ref=0;
2980 else if (!UDRS->fd_ref--) {
2981 DPRINT("floppy_release with fd_ref == 0");
2982 UDRS->fd_ref = 0;
2983 }
2984 floppy_release_irq_and_dma();
2985 }
2986
2987
2988
2989
2990
2991
2992 #define RETERR(x) \
2993 do{floppy_release(inode,filp); \
2994 return -(x);}while(0)
2995
2996 static int floppy_open(struct inode * inode, struct file * filp)
2997 {
2998 int drive;
2999 int old_dev;
3000
3001 if (!filp) {
3002 DPRINT("Weird, open called with filp=0\n");
3003 return -EIO;
3004 }
3005
3006 drive = DRIVE(inode->i_rdev);
3007 if (drive >= N_DRIVE ||
3008 !( ALLOWED_DRIVE_MASK & ( 1 << drive)) ||
3009 fdc_state[FDC(drive)].version == FDC_NONE)
3010 return -ENXIO;
3011
3012 if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
3013 return -ENXIO;
3014 old_dev = UDRS->fd_device;
3015 if (UDRS->fd_ref && old_dev != inode->i_rdev)
3016 return -EBUSY;
3017
3018 if(!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
3019 USETF(FD_DISK_CHANGED);
3020 USETF(FD_VERIFY);
3021 }
3022
3023 if(UDRS->fd_ref == -1 ||
3024 (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3025 return -EBUSY;
3026
3027 if (floppy_grab_irq_and_dma())
3028 return -EBUSY;
3029
3030 if (filp->f_flags & O_EXCL)
3031 UDRS->fd_ref = -1;
3032 else
3033 UDRS->fd_ref++;
3034
3035 UDRS->fd_device = inode->i_rdev;
3036
3037 if (old_dev && old_dev != inode->i_rdev) {
3038 if (buffer_drive == drive)
3039 buffer_track = -1;
3040 invalidate_buffers(old_dev);
3041 }
3042
3043
3044 if ((filp->f_mode & 2) || (permission(inode,2) == 0))
3045 filp->f_mode |= IOCTL_MODE_BIT;
3046 if (filp->f_mode & 2)
3047 filp->f_mode |= OPEN_WRITE_BIT;
3048
3049 if (UFDCS->rawcmd == 1)
3050 UFDCS->rawcmd = 2;
3051
3052 if (filp->f_flags & O_NDELAY)
3053 return 0;
3054 if (filp->f_mode & 3) {
3055 UDRS->last_checked = 0;
3056 check_disk_change(inode->i_rdev);
3057 if (UTESTF(FD_DISK_CHANGED))
3058 RETERR(ENXIO);
3059 }
3060 if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
3061 RETERR(EROFS);
3062 return 0;
3063 #undef RETERR
3064 }
3065
3066
3067
3068
3069 static int check_floppy_change(dev_t dev)
3070 {
3071 int drive = DRIVE( dev );
3072
3073 if (MAJOR(dev) != MAJOR_NR) {
3074 DPRINT("floppy_changed: not a floppy\n");
3075 return 0;
3076 }
3077
3078 if (UTESTF(FD_DISK_CHANGED))
3079 return 1;
3080
3081 if(UDRS->last_checked + UDP->checkfreq < jiffies){
3082 lock_fdc(drive,0);
3083 poll_drive(0,0);
3084 process_fd_request();
3085 }
3086
3087 if(UTESTF(FD_DISK_CHANGED) ||
3088 test_bit(drive, &fake_change) ||
3089 (!TYPE(dev) && !current_type[drive]))
3090 return 1;
3091 return 0;
3092 }
3093
3094
3095
3096
3097
3098 static int floppy_revalidate(dev_t dev)
3099 {
3100 #define NO_GEOM (!current_type[drive] && !TYPE(dev))
3101 struct buffer_head * bh;
3102 int drive=DRIVE(dev);
3103 int cf;
3104
3105 if(UTESTF(FD_DISK_CHANGED) || test_bit(drive, &fake_change) || NO_GEOM){
3106 lock_fdc(drive,0);
3107 cf = UTESTF(FD_DISK_CHANGED);
3108 if(! (cf || test_bit(drive, &fake_change) || NO_GEOM)){
3109 process_fd_request();
3110 return 0;
3111 }
3112 UDRS->maxblock = 0;
3113 UDRS->maxtrack = 0;
3114 if ( buffer_drive == drive)
3115 buffer_track = -1;
3116 clear_bit(drive, &fake_change);
3117 UCLEARF(FD_DISK_CHANGED);
3118 if(cf)
3119 UDRS->generation++;
3120 if(NO_GEOM){
3121
3122 int size = floppy_blocksizes[MINOR(dev)];
3123 if (!size)
3124 size = 1024;
3125 if (!(bh = getblk(dev,0,size))){
3126 process_fd_request();
3127 return 1;
3128 }
3129 if ( bh && ! bh->b_uptodate)
3130 ll_rw_block(READ, 1, &bh);
3131 process_fd_request();
3132 wait_on_buffer(bh);
3133 brelse(bh);
3134 return 0;
3135 }
3136 if(cf)
3137 poll_drive(0, FD_RAW_NEED_DISK);
3138 process_fd_request();
3139 }
3140 return 0;
3141 }
3142
3143 static struct file_operations floppy_fops = {
3144 NULL,
3145 floppy_read,
3146 floppy_write,
3147 NULL,
3148 NULL,
3149 fd_ioctl,
3150 NULL,
3151 floppy_open,
3152 floppy_release,
3153 block_fsync,
3154 NULL,
3155 check_floppy_change,
3156 floppy_revalidate,
3157 };
3158
3159
3160
3161
3162
3163
3164
3165
3166 static char get_fdc_version(void)
3167 {
3168 int r;
3169
3170 output_byte(FD_DUMPREGS);
3171 if ( FDCS->reset )
3172 return FDC_NONE;
3173 if ( (r = result()) <= 0x00)
3174 return FDC_NONE;
3175 if ((r==1) && (reply_buffer[0] == 0x80)){
3176 printk("FDC %d is a 8272A\n",fdc);
3177 return FDC_8272A;
3178 }
3179 if (r != 10) {
3180 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
3181 return FDC_UNKNOWN;
3182 }
3183 output_byte(FD_VERSION);
3184 r = result();
3185 if ((r == 1) && (reply_buffer[0] == 0x80)){
3186 printk("FDC %d is a 82072\n",fdc);
3187 return FDC_82072;
3188 }
3189 if ((r != 1) || (reply_buffer[0] != 0x90)) {
3190 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
3191 return FDC_UNKNOWN;
3192 }
3193 output_byte(FD_UNLOCK);
3194 r = result();
3195 if ((r == 1) && (reply_buffer[0] == 0x80)){
3196 printk("FDC %d is a pre-1991 82077\n", fdc);
3197 return FDC_82077_ORIG;
3198 }
3199 if ((r != 1) || (reply_buffer[0] != 0x00)) {
3200 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
3201 return FDC_UNKNOWN;
3202 }
3203 printk("FDC %d is a post-1991 82077\n",fdc);
3204 return FDC_82077;
3205 }
3206
3207
3208
3209
3210
3211
3212 void floppy_invert_dcl(int *ints,int param)
3213 {
3214 int i;
3215
3216 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3217 if (param)
3218 default_drive_params[i].params.flags |= 0x80;
3219 else
3220 default_drive_params[i].params.flags &= ~0x80;
3221 }
3222 DPRINT("Configuring drives for inverted dcl\n");
3223 }
3224
3225 static void daring(int *ints,int param)
3226 {
3227 int i;
3228
3229 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3230 if (param){
3231 default_drive_params[i].params.select_delay = 0;
3232 default_drive_params[i].params.flags |= FD_SILENT_DCL_CLEAR;
3233 } else {
3234 default_drive_params[i].params.select_delay = 2*HZ/100;
3235 default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR;
3236 }
3237 }
3238 DPRINT1("Assuming %s floppy hardware\n", param ? "standard" : "broken");
3239 }
3240
3241 static void allow_drives(int *ints, int param)
3242 {
3243 ALLOWED_DRIVE_MASK=param;
3244 DPRINT1("setting allowed_drive_mask to 0x%x\n", param);
3245 }
3246
3247 static void fdc2_adr(int *ints, int param)
3248 {
3249 FDC2 = param;
3250 if(param)
3251 DPRINT1("enabling second fdc at address 0x%3x\n", FDC2);
3252 else
3253 DPRINT("disabling second fdc\n");
3254 }
3255
3256 static void unex(int *ints,int param)
3257 {
3258 print_unex = param;
3259 DPRINT1("%sprinting messages for unexpected interrupts\n",
3260 param ? "" : "not ");
3261 }
3262
3263 static void set_cmos(int *ints, int dummy)
3264 {
3265 int current_drive=0;
3266
3267 if ( ints[0] != 2 ){
3268 DPRINT("wrong number of parameter for cmos\n");
3269 return;
3270 }
3271 current_drive = ints[1];
3272 if (current_drive < 0 || current_drive >= 8 ){
3273 DPRINT("bad drive for set_cmos\n");
3274 return;
3275 }
3276 if(ints[2] <= 0 || ints[2] >= NUMBER(default_drive_params)){
3277 DPRINT1("bad cmos code %d\n", ints[2]);
3278 return;
3279 }
3280 DP->cmos = ints[2];
3281 DPRINT1("setting cmos code to %d\n", ints[2]);
3282 }
3283
3284 static struct param_table {
3285 char *name;
3286 void (*fn)(int *ints, int param);
3287 int def_param;
3288 } config_params[]={
3289 { "allowed_drive_mask", allow_drives, 0xff },
3290 { "all_drives", allow_drives, 0xff },
3291 { "asus_pci", allow_drives, 0x33 },
3292
3293 { "daring", daring, 1},
3294
3295 { "two_fdc", fdc2_adr, 0x370 },
3296 { "one_fdc", fdc2_adr, 0 },
3297
3298 { "thinkpad", floppy_invert_dcl, 1 },
3299
3300 { "cmos", set_cmos, 0 },
3301
3302 { "unexpected_interrupts", unex, 1 },
3303 { "no_unexpected_interrupts", unex, 0 },
3304 { "L40SX", unex, 0 } };
3305
3306 #define FLOPPY_SETUP
3307 void floppy_setup(char *str, int *ints)
3308 {
3309 int i;
3310 int param;
3311 if(!str)
3312 return;
3313 for(i=0; i< ARRAY_SIZE(config_params); i++){
3314 if (strcmp(str,config_params[i].name) == 0 ){
3315 if (ints[0] )
3316 param = ints[1];
3317 else
3318 param = config_params[i].def_param;
3319 config_params[i].fn(ints,param);
3320 return;
3321 }
3322 }
3323 DPRINT1("unknown floppy option %s\n", str);
3324 DPRINT("allowed options are:");
3325 for(i=0; i< ARRAY_SIZE(config_params); i++)
3326 printk(" %s",config_params[i].name);
3327 printk("\n");
3328 DPRINT("Read linux/drivers/block/README.fd\n");
3329 }
3330
3331 #ifdef FD_MODULE
3332 static
3333 #endif
3334 int new_floppy_init(void)
3335 {
3336 int i,drive;
3337 int have_no_fdc=0;
3338
3339 sti();
3340
3341 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
3342 printk("Unable to get major %d for floppy\n",MAJOR_NR);
3343 return -EBUSY;
3344 }
3345
3346 for(i=0; i<256; i++)
3347 if ( TYPE(i))
3348 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
3349 else
3350 floppy_sizes[i] = MAX_DISK_SIZE;
3351
3352 blk_size[MAJOR_NR] = floppy_sizes;
3353 blksize_size[MAJOR_NR] = floppy_blocksizes;
3354 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3355 del_timer(&fd_timeout);
3356 config_types();
3357
3358 fdc_state[0].address = FDC1;
3359 fdc_state[0].dor = 0;
3360 #if N_FDC > 1
3361 fdc_state[1].address = FDC2;
3362 fdc_state[1].dor = 0;
3363 #endif
3364
3365 for (i = 0 ; i < N_FDC ; i++) {
3366 fdc = i;
3367 FDCS->dtr = -1;
3368 FDCS->dor = 0x4;
3369 FDCS->reset = 0;
3370 FDCS->version = FDC_NONE;
3371 }
3372
3373 if(floppy_grab_irq_and_dma()){
3374 unregister_blkdev(MAJOR_NR,"fd");
3375 return -EBUSY;
3376 }
3377
3378
3379 for (drive = 0; drive < N_DRIVE ; drive++) {
3380 UDRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE | FD_DISK_CHANGED;
3381 UDRS->generation = 0;
3382 UDRS->keep_data = 0;
3383 UDRS->fd_ref = 0;
3384 UDRS->fd_device = 0;
3385 UDRWE->write_errors = 0;
3386 UDRWE->first_error_sector = 0;
3387 UDRWE->first_error_generation = 0;
3388 UDRWE->last_error_sector = 0;
3389 UDRWE->last_error_generation = 0;
3390 UDRWE->badness = 0;
3391 }
3392
3393 for (i = 0 ; i < N_FDC ; i++) {
3394 fdc = i;
3395 if (FDCS->address == -1 )
3396 continue;
3397 FDCS->rawcmd = 2;
3398 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED,0)){
3399 FDCS->address = -1;
3400 continue;
3401 }
3402
3403 FDCS->version = get_fdc_version();
3404 if (FDCS->version == FDC_NONE){
3405 FDCS->address = -1;
3406 continue;
3407 }
3408
3409 have_no_fdc = 0;
3410
3411
3412
3413
3414 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
3415 user_reset_fdc(-1,FD_RESET_ALWAYS,0);
3416 }
3417 fdc=0;
3418 current_drive = 0;
3419 floppy_release_irq_and_dma();
3420 initialising=0;
3421 if(have_no_fdc)
3422 unregister_blkdev(MAJOR_NR,"fd");
3423 return have_no_fdc;
3424 }
3425
3426
3427 void floppy_init(void)
3428 {
3429 new_floppy_init();
3430 }
3431
3432 static int floppy_grab_irq_and_dma(void)
3433 {
3434 int i;
3435 cli();
3436 if (usage_count++){
3437 sti();
3438 return 0;
3439 }
3440 sti();
3441 #ifdef FD_MODULE
3442 MOD_INC_USE_COUNT;
3443 #endif
3444 for(i=0; i< N_FDC; i++){
3445 if(FDCS->address != -1){
3446 fdc = i;
3447 reset_fdc_info(1);
3448 outb_p(FDCS->dor, FD_DOR);
3449 }
3450 }
3451 set_dor(0, ~0, 8);
3452
3453 if (request_irq(FLOPPY_IRQ, floppy_interrupt, SA_INTERRUPT, "floppy")) {
3454 DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
3455 FLOPPY_IRQ);
3456 return -1;
3457 }
3458 if (request_dma(FLOPPY_DMA,"floppy")) {
3459 DPRINT1("Unable to grab DMA%d for the floppy driver\n",
3460 FLOPPY_DMA);
3461 free_irq(FLOPPY_IRQ);
3462 return -1;
3463 }
3464 for(fdc = 0; fdc < N_FDC ; fdc++)
3465 if(FDCS->address != -1)
3466 outb_p(FDCS->dor, FD_DOR);
3467 fdc = 0;
3468 enable_irq(FLOPPY_IRQ);
3469 return 0;
3470 }
3471
3472 static void floppy_release_irq_and_dma(void)
3473 {
3474 #ifdef CONFIG_FLOPPY_SANITY
3475 int drive;
3476 #endif
3477 cli();
3478 if (--usage_count){
3479 sti();
3480 return;
3481 }
3482 sti();
3483 #ifdef FD_MODULE
3484 MOD_DEC_USE_COUNT;
3485 #endif
3486 disable_dma(FLOPPY_DMA);
3487 free_dma(FLOPPY_DMA);
3488 disable_irq(FLOPPY_IRQ);
3489 free_irq(FLOPPY_IRQ);
3490
3491 set_dor(0, ~0, 8);
3492 #if N_FDC > 1
3493 set_dor(1, ~8, 0);
3494 #endif
3495 floppy_enable_hlt();
3496 #ifdef CONFIG_FLOPPY_SANITY
3497 for(drive=0; drive < N_FDC * 4; drive++)
3498 if( motor_off_timer[drive].next )
3499 printk("motor off timer %d still active\n", drive);
3500
3501 if(fd_timeout.next)
3502 printk("floppy timer still active\n");
3503 if (fd_timer.next)
3504 printk("auxiliary floppy timer still active\n");
3505 if(floppy_tq.sync)
3506 printk("task queue still active\n");
3507 #endif
3508 }
3509