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