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