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