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 #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
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(0x2A);
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 irq, struct pt_regs * regs)
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
1712 probed_format = DRS->probed_format;
1713 while(1){
1714 if ( probed_format >= 8 ||
1715 ! DP->autodetect[probed_format] ){
1716 DRS->probed_format = 0;
1717 return 1;
1718 }
1719 if ( floppy_type[DP->autodetect[probed_format]].sect ){
1720 DRS->probed_format = probed_format;
1721 return 0;
1722 }
1723 probed_format++;
1724 }
1725 }
1726
1727 static void bad_flp_intr(void)
1728 {
1729 if ( probing ){
1730 DRS->probed_format++;
1731 if ( !next_valid_format())
1732 return;
1733 }
1734 (*errors)++;
1735 if (*errors > DRWE->badness)
1736 DRWE->badness = *errors;
1737 if (*errors > DP->max_errors.abort)
1738 cont->done(0);
1739 if (*errors > DP->max_errors.reset)
1740 FDCS->reset = 1;
1741 else if (*errors > DP->max_errors.recal)
1742 DRS->track = NEED_2_RECAL;
1743 }
1744
1745 static void set_floppy(int device)
1746 {
1747 if (TYPE(device))
1748 floppy = TYPE(device) + floppy_type;
1749 else
1750 floppy = current_type[ DRIVE(device) ];
1751 }
1752
1753
1754
1755
1756
1757 static void format_interrupt(void)
1758 {
1759 switch (interpret_errors()){
1760 case 1:
1761 cont->error();
1762 case 2:
1763 break;
1764 case 0:
1765 cont->done(1);
1766 }
1767 cont->redo();
1768 }
1769
1770 #define CODE2SIZE (ssize = ( ( 1 << SIZECODE ) + 3 ) >> 2)
1771 #define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80 ) >>1))
1772 #define CT(x) ( (x) | 0x40 )
1773 static void setup_format_params(void)
1774 {
1775 struct fparm {
1776 unsigned char track,head,sect,size;
1777 } *here = (struct fparm *)floppy_track_buffer;
1778 int il,n;
1779 int count,head_shift,track_shift;
1780
1781 raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
1782 FD_RAW_NEED_SEEK;
1783 raw_cmd.rate = floppy->rate & 0x3;
1784 raw_cmd.cmd_count = NR_F;
1785 COMMAND = FM_MODE(floppy,FD_FORMAT);
1786 DR_SELECT = UNIT(current_drive) + ( format_req.head << 2 );
1787 F_SIZECODE = FD_SIZECODE(floppy);
1788 F_SECT_PER_TRACK = floppy->sect << 2 >> F_SIZECODE;
1789 F_GAP = floppy->fmt_gap;
1790 F_FILL = FD_FILL_BYTE;
1791
1792 current_addr = floppy_track_buffer;
1793 raw_cmd.length = 4 * F_SECT_PER_TRACK;
1794
1795
1796 head_shift = (F_SECT_PER_TRACK + 5) / 6;
1797
1798
1799 track_shift = 2 * head_shift + 1;
1800
1801
1802 n = (track_shift * format_req.track + head_shift * format_req.head )
1803 % F_SECT_PER_TRACK;
1804
1805
1806 il = 1;
1807 if (floppy->sect > DP->interleave_sect && F_SIZECODE == 2)
1808 il++;
1809
1810
1811 for (count = 0; count < F_SECT_PER_TRACK; ++count) {
1812 here[count].track = format_req.track;
1813 here[count].head = format_req.head;
1814 here[count].sect = 0;
1815 here[count].size = F_SIZECODE;
1816 }
1817
1818 for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
1819 here[n].sect = count;
1820 n = (n+il) % F_SECT_PER_TRACK;
1821 if (here[n].sect) {
1822 ++n;
1823 if (n>= F_SECT_PER_TRACK) {
1824 n-=F_SECT_PER_TRACK;
1825 while (here[n].sect) ++n;
1826 }
1827 }
1828 }
1829 }
1830
1831 static void redo_format(void)
1832 {
1833 raw_cmd.track = format_req.track << floppy->stretch;
1834 buffer_track = -1;
1835 setup_format_params();
1836 floppy_start();
1837 #ifdef DEBUGT
1838 debugt("queue format request");
1839 #endif
1840 }
1841
1842 static struct cont_t format_cont={
1843 format_interrupt,
1844 redo_format,
1845 bad_flp_intr,
1846 generic_done };
1847
1848 static int do_format(int device, struct format_descr *tmp_format_req)
1849 {
1850 int ret;
1851 int drive=DRIVE(device);
1852
1853 LOCK_FDC(drive,1);
1854 set_floppy(device);
1855 if (!floppy ||
1856 floppy->track > DP->tracks ||
1857 tmp_format_req->track >= floppy->track ||
1858 tmp_format_req->head >= floppy->head ||
1859 (floppy->sect << 2) % (1 << FD_SIZECODE(floppy)) ||
1860 !floppy->fmt_gap) {
1861 process_fd_request();
1862 return -EINVAL;
1863 }
1864 format_req = *tmp_format_req;
1865 format_errors = 0;
1866 cont = &format_cont;
1867 errors = &format_errors;
1868 IWAIT(redo_format);
1869 process_fd_request();
1870 return ret;
1871 }
1872
1873
1874
1875
1876
1877
1878
1879
1880 static void request_done(int uptodate)
1881 {
1882 int block;
1883
1884 probing = 0;
1885 del_timer(&fd_timeout);
1886
1887 if (!CURRENT){
1888 DPRINT("request list destroyed in floppy request done\n");
1889 return;
1890 }
1891 if (uptodate){
1892
1893
1894 block = current_count_sectors + CURRENT->sector;
1895 if (block > DRS->maxblock)
1896 DRS->maxblock=block;
1897 if ( block > floppy->sect)
1898 DRS->maxtrack = 1;
1899
1900
1901 while (current_count_sectors && CURRENT &&
1902 current_count_sectors >= CURRENT->current_nr_sectors ){
1903 current_count_sectors -= CURRENT->current_nr_sectors;
1904 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
1905 CURRENT->sector += CURRENT->current_nr_sectors;
1906 end_request(1);
1907 }
1908 if ( current_count_sectors && CURRENT){
1909
1910 CURRENT->buffer += current_count_sectors <<9;
1911 CURRENT->current_nr_sectors -= current_count_sectors;
1912 CURRENT->nr_sectors -= current_count_sectors;
1913 CURRENT->sector += current_count_sectors;
1914 return;
1915 }
1916
1917 if ( current_count_sectors && ! CURRENT )
1918 DPRINT("request list destroyed in floppy request done\n");
1919
1920 } else {
1921 if(CURRENT->cmd == WRITE) {
1922
1923 DRWE->write_errors++;
1924 if(DRWE->write_errors == 1) {
1925 DRWE->first_error_sector = CURRENT->sector;
1926 DRWE->first_error_generation = DRS->generation;
1927 }
1928 DRWE->last_error_sector = CURRENT->sector;
1929 DRWE->last_error_generation = DRS->generation;
1930 }
1931 end_request(0);
1932 }
1933 }
1934
1935
1936 static void rw_interrupt(void)
1937 {
1938 int nr_sectors, ssize;
1939
1940 if ( ! DRS->first_read_date )
1941 DRS->first_read_date = jiffies;
1942
1943 nr_sectors = 0;
1944 CODE2SIZE;
1945 nr_sectors = ((R_TRACK-TRACK)*floppy->head+R_HEAD-HEAD) *
1946 floppy->sect + ((R_SECTOR-SECTOR) << SIZECODE >> 2) -
1947 (sector_t % floppy->sect) % ssize;
1948
1949 #ifdef CONFIG_FLOPPY_SANITY
1950 if ( nr_sectors > current_count_sectors + ssize -
1951 (current_count_sectors + sector_t) % ssize +
1952 sector_t % ssize){
1953 DPRINT2("long rw: %x instead of %lx\n",
1954 nr_sectors, current_count_sectors);
1955 printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
1956 printk("rh=%d h=%d\n", R_HEAD, HEAD);
1957 printk("rt=%d t=%d\n", R_TRACK, TRACK);
1958 printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
1959 sector_t, ssize);
1960 }
1961 #endif
1962 if ( nr_sectors < 0 )
1963 nr_sectors = 0;
1964 if ( nr_sectors < current_count_sectors )
1965 current_count_sectors = nr_sectors;
1966
1967 switch (interpret_errors()){
1968 case 2:
1969 cont->redo();
1970 return;
1971 case 1:
1972 if ( !current_count_sectors){
1973 cont->error();
1974 cont->redo();
1975 return;
1976 }
1977 break;
1978 case 0:
1979 if ( !current_count_sectors){
1980 cont->redo();
1981 return;
1982 }
1983 current_type[current_drive] = floppy;
1984 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
1985 floppy->size >> 1;
1986 break;
1987 }
1988
1989 if (probing) {
1990 if (DP->flags & FTD_MSG)
1991 DPRINT2("Auto-detected floppy type %s in fd%d\n",
1992 floppy->name,current_drive);
1993 current_type[current_drive] = floppy;
1994 floppy_sizes[DRIVE(current_drive) + (FDC(current_drive) << 7)] =
1995 floppy->size >> 1;
1996 probing = 0;
1997 }
1998
1999 if ( CT(COMMAND) != FD_READ || current_addr == CURRENT->buffer ){
2000
2001 cont->done(1);
2002 } else if ( CT(COMMAND) == FD_READ){
2003 buffer_track = raw_cmd.track;
2004 buffer_drive = current_drive;
2005 if ( nr_sectors + sector_t > buffer_max )
2006 buffer_max = nr_sectors + sector_t;
2007 }
2008 cont->redo();
2009 }
2010
2011
2012 static int buffer_chain_size(void)
2013 {
2014 struct buffer_head *bh;
2015 int size;
2016 char *base;
2017
2018 base = CURRENT->buffer;
2019 size = CURRENT->current_nr_sectors << 9;
2020 bh = CURRENT->bh;
2021
2022 if (bh){
2023 bh = bh->b_reqnext;
2024 while ( bh && bh->b_data == base + size ){
2025 size += bh->b_size;
2026 bh = bh->b_reqnext;
2027 }
2028 }
2029 return size >> 9;
2030 }
2031
2032
2033 static int transfer_size(int ssize, int max_sector, int max_size)
2034 {
2035 if ( max_sector > sector_t + max_size)
2036 max_sector = sector_t + max_size;
2037
2038
2039 max_sector -= (max_sector % floppy->sect ) % ssize;
2040
2041
2042 current_count_sectors = max_sector - sector_t ;
2043
2044 return max_sector;
2045 }
2046
2047
2048
2049
2050 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
2051 {
2052 int remaining;
2053 struct buffer_head *bh;
2054 char *buffer, *dma_buffer;
2055 int size;
2056
2057 if ( max_sector > max_sector_2 )
2058 max_sector = max_sector_2;
2059
2060 max_sector = transfer_size(ssize, max_sector, CURRENT->nr_sectors);
2061
2062 if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
2063 buffer_max > sector_t + CURRENT->nr_sectors){
2064 current_count_sectors = buffer_max - sector_t;
2065 if ( current_count_sectors > CURRENT->nr_sectors )
2066 current_count_sectors = CURRENT->nr_sectors;
2067 }
2068 remaining = current_count_sectors << 9;
2069 #ifdef CONFIG_FLOPPY_SANITY
2070 if ((remaining >> 9) > CURRENT->nr_sectors &&
2071 CT(COMMAND) == FD_WRITE ){
2072 DPRINT("in copy buffer\n");
2073 printk("current_count_sectors=%ld\n", current_count_sectors);
2074 printk("remaining=%d\n", remaining >> 9);
2075 printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
2076 printk("CURRENT->current_nr_sectors=%ld\n",
2077 CURRENT->current_nr_sectors);
2078 printk("max_sector=%d\n", max_sector);
2079 printk("ssize=%d\n", ssize);
2080 }
2081 #endif
2082
2083 if ( max_sector > buffer_max )
2084 buffer_max = max_sector;
2085
2086 dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
2087
2088 bh = CURRENT->bh;
2089 size = CURRENT->current_nr_sectors << 9;
2090 buffer = CURRENT->buffer;
2091
2092 while ( remaining > 0){
2093 if ( size > remaining )
2094 size = remaining;
2095 #ifdef CONFIG_FLOPPY_SANITY
2096 if (dma_buffer + size >
2097 floppy_track_buffer + (max_buffer_sectors << 10) ||
2098 dma_buffer < floppy_track_buffer ){
2099 DPRINT1("buffer overrun in copy buffer %d\n",
2100 (int) ((floppy_track_buffer - dma_buffer) >>9));
2101 printk("sector_t=%d buffer_min=%d\n",
2102 sector_t, buffer_min);
2103 printk("current_count_sectors=%ld\n",
2104 current_count_sectors);
2105 if ( CT(COMMAND) == FD_READ )
2106 printk("read\n");
2107 if ( CT(COMMAND) == FD_READ )
2108 printk("write\n");
2109 break;
2110 }
2111 if ( ((unsigned long)buffer) % 512 )
2112 DPRINT1("%p buffer not aligned\n", buffer);
2113 #endif
2114 if ( CT(COMMAND) == FD_READ )
2115 memcpy( buffer, dma_buffer, size);
2116 else
2117 memcpy( dma_buffer, buffer, size);
2118 remaining -= size;
2119 if ( !remaining)
2120 break;
2121
2122 dma_buffer += size;
2123 bh = bh->b_reqnext;
2124 #ifdef CONFIG_FLOPPY_SANITY
2125 if ( !bh){
2126 DPRINT("bh=null in copy buffer after copy\n");
2127 break;
2128 }
2129 #endif
2130 size = bh->b_size;
2131 buffer = bh->b_data;
2132 }
2133 #ifdef CONFIG_FLOPPY_SANITY
2134 if ( remaining ){
2135 if ( remaining > 0 )
2136 max_sector -= remaining >> 9;
2137 DPRINT1("weirdness: remaining %d\n", remaining>>9);
2138 }
2139 #endif
2140 }
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152 static int make_raw_rw_request(void)
2153 {
2154 int aligned_sector_t;
2155 int max_sector, max_size, tracksize, ssize;
2156
2157 set_fdc(DRIVE(CURRENT->dev));
2158
2159 raw_cmd.flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
2160 FD_RAW_NEED_SEEK;
2161 raw_cmd.cmd_count = NR_RW;
2162 if (CURRENT->cmd == READ){
2163 raw_cmd.flags |= FD_RAW_READ;
2164 COMMAND = FM_MODE(floppy,FD_READ);
2165 } else if (CURRENT->cmd == WRITE){
2166 raw_cmd.flags |= FD_RAW_WRITE;
2167 COMMAND = FM_MODE(floppy,FD_WRITE);
2168 } else {
2169 DPRINT("make_raw_rw_request: unknown command\n");
2170 return 0;
2171 }
2172
2173 max_sector = floppy->sect * floppy->head;
2174 TRACK = CURRENT->sector / max_sector;
2175 sector_t = CURRENT->sector % max_sector;
2176 if ( floppy->track && TRACK >= floppy->track )
2177 return 0;
2178 HEAD = sector_t / floppy->sect;
2179
2180 if ( TESTF( FD_NEED_TWADDLE) && sector_t < floppy->sect )
2181 max_sector = floppy->sect;
2182
2183
2184 if ( (floppy->rate & FD_2M ) && (!TRACK) && (!HEAD)){
2185 max_sector = 2 * floppy->sect / 3;
2186 if (sector_t >= max_sector){
2187 current_count_sectors = (floppy->sect - sector_t);
2188 if ( current_count_sectors > CURRENT->nr_sectors )
2189 current_count_sectors = CURRENT->nr_sectors;
2190 return 1;
2191 }
2192 SIZECODE = 2;
2193 } else
2194 SIZECODE = FD_SIZECODE(floppy);
2195 raw_cmd.rate = floppy->rate & 3;
2196 if ((floppy->rate & FD_2M) &&
2197 (TRACK || HEAD ) &&
2198 raw_cmd.rate == 2)
2199 raw_cmd.rate = 1;
2200
2201 if ( SIZECODE )
2202 SIZECODE2 = 0xff;
2203 else
2204 SIZECODE2 = 0x80;
2205 raw_cmd.track = TRACK << floppy->stretch;
2206 DR_SELECT = UNIT(current_drive) + ( HEAD << 2 );
2207 GAP = floppy->gap;
2208 CODE2SIZE;
2209 SECT_PER_TRACK = floppy->sect << 2 >> SIZECODE;
2210 SECTOR = ((sector_t % floppy->sect) << 2 >> SIZECODE) + 1;
2211 tracksize = floppy->sect - floppy->sect % ssize;
2212 if ( tracksize < floppy->sect ){
2213 SECT_PER_TRACK ++;
2214 if ( tracksize <= sector_t % floppy->sect)
2215 SECTOR--;
2216 while ( tracksize <= sector_t % floppy->sect){
2217 while( tracksize + ssize > floppy->sect ){
2218 SIZECODE--;
2219 ssize >>= 1;
2220 }
2221 SECTOR++; SECT_PER_TRACK ++;
2222 tracksize += ssize;
2223 }
2224 max_sector = HEAD * floppy->sect + tracksize;
2225 } else if ( !TRACK && !HEAD && !( floppy->rate & FD_2M ) && probing)
2226 max_sector = floppy->sect;
2227
2228 aligned_sector_t = sector_t - ( sector_t % floppy->sect ) % ssize;
2229 max_size = CURRENT->nr_sectors;
2230 if ((raw_cmd.track == buffer_track) && (current_drive == buffer_drive) &&
2231 (sector_t >= buffer_min) && (sector_t < buffer_max)) {
2232
2233 if (CT(COMMAND) == FD_READ) {
2234 copy_buffer(1, max_sector, buffer_max);
2235 return 1;
2236 }
2237 } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
2238 if (CT(COMMAND) == FD_WRITE){
2239 if(sector_t + CURRENT->nr_sectors > ssize &&
2240 sector_t + CURRENT->nr_sectors < ssize + ssize)
2241 max_size = ssize + ssize;
2242 else
2243 max_size = ssize;
2244 }
2245 raw_cmd.flags &= ~FD_RAW_WRITE;
2246 raw_cmd.flags |= FD_RAW_READ;
2247 COMMAND = FM_MODE(floppy,FD_READ);
2248 } else if ((long)CURRENT->buffer <= LAST_DMA_ADDR ) {
2249 int direct, indirect;
2250
2251 indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
2252 sector_t;
2253
2254 max_size = buffer_chain_size();
2255 if ( max_size > ( LAST_DMA_ADDR - ((long) CURRENT->buffer))>>9)
2256 max_size=(LAST_DMA_ADDR - ((long)CURRENT->buffer))>>9;
2257
2258 if ( ((max_size << 9) + ((long) CURRENT->buffer)) / K_64 !=
2259 ((long) CURRENT->buffer ) / K_64 )
2260 max_size = ( K_64 - ((long) CURRENT->buffer) % K_64)>>9;
2261 direct = transfer_size(ssize,max_sector,max_size) - sector_t;
2262
2263
2264
2265
2266
2267
2268
2269 if ((indirect - sector_t) * 2 > (direct - sector_t) * 3 &&
2270 *errors < DP->max_errors.read_track &&
2271
2272 ( ( !probing || (DP->read_track &
2273 (1 <<DRS->probed_format))))){
2274 max_size = CURRENT->nr_sectors;
2275 } else {
2276 current_addr = CURRENT->buffer;
2277 raw_cmd.length = current_count_sectors << 9;
2278 return 2;
2279 }
2280 }
2281
2282 if ( CT(COMMAND) == FD_READ )
2283 max_size = max_sector;
2284
2285
2286 if (buffer_track != raw_cmd.track ||
2287 buffer_drive !=current_drive ||
2288 sector_t < buffer_min ||
2289 ((CT(COMMAND) == FD_READ ||
2290 (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize ))&&
2291 max_sector > 2 * max_buffer_sectors + buffer_min &&
2292 max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
2293 ){
2294 buffer_track = -1;
2295 buffer_drive = current_drive;
2296 buffer_max = buffer_min = aligned_sector_t;
2297 }
2298 current_addr = floppy_track_buffer +((aligned_sector_t-buffer_min )<<9);
2299
2300 if ( CT(COMMAND) == FD_WRITE ){
2301
2302
2303
2304
2305 #ifdef CONFIG_FLOPPY_SANITY
2306 if (sector_t != aligned_sector_t && buffer_track == -1 )
2307 DPRINT("internal error offset !=0 on write\n");
2308 #endif
2309 buffer_track = raw_cmd.track;
2310 buffer_drive = current_drive;
2311 copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min);
2312 } else
2313 transfer_size(ssize, max_sector,
2314 2*max_buffer_sectors+buffer_min-aligned_sector_t);
2315
2316
2317 raw_cmd.length = sector_t+current_count_sectors-aligned_sector_t;
2318 raw_cmd.length = ((raw_cmd.length -1)|(ssize-1))+1;
2319 raw_cmd.length <<= 9;
2320 #ifdef CONFIG_FLOPPY_SANITY
2321 if ((raw_cmd.length < current_count_sectors << 9) ||
2322 (current_addr != CURRENT->buffer &&
2323 CT(COMMAND) == FD_WRITE &&
2324 (aligned_sector_t + (raw_cmd.length >> 9) > buffer_max ||
2325 aligned_sector_t < buffer_min )) ||
2326 raw_cmd.length % ( 128 << SIZECODE ) ||
2327 raw_cmd.length <= 0 || current_count_sectors <= 0){
2328 DPRINT2("fractionary current count b=%lx s=%lx\n",
2329 raw_cmd.length, current_count_sectors);
2330 if ( current_addr != CURRENT->buffer )
2331 printk("addr=%d, length=%ld\n",
2332 (int) ((current_addr - floppy_track_buffer ) >> 9),
2333 current_count_sectors);
2334 printk("st=%d ast=%d mse=%d msi=%d\n",
2335 sector_t, aligned_sector_t, max_sector, max_size);
2336 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2337 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2338 COMMAND, SECTOR, HEAD, TRACK);
2339 printk("buffer drive=%d\n", buffer_drive);
2340 printk("buffer track=%d\n", buffer_track);
2341 printk("buffer_min=%d\n", buffer_min );
2342 printk("buffer_max=%d\n", buffer_max );
2343 return 0;
2344 }
2345
2346 if (current_addr != CURRENT->buffer ){
2347 if (current_addr < floppy_track_buffer ||
2348 current_count_sectors < 0 ||
2349 raw_cmd.length < 0 ||
2350 current_addr + raw_cmd.length >
2351 floppy_track_buffer + (max_buffer_sectors << 10)){
2352 DPRINT("buffer overrun in schedule dma\n");
2353 printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2354 sector_t, buffer_min,
2355 raw_cmd.length >> 9 );
2356 printk("current_count_sectors=%ld\n",
2357 current_count_sectors);
2358 if ( CT(COMMAND) == FD_READ )
2359 printk("read\n");
2360 if ( CT(COMMAND) == FD_READ )
2361 printk("write\n");
2362 return 0;
2363 }
2364 } else if (raw_cmd.length > CURRENT->nr_sectors << 9 ||
2365 current_count_sectors > CURRENT->nr_sectors){
2366 DPRINT("buffer overrun in direct transfer\n");
2367 return 0;
2368 } else if ( raw_cmd.length < current_count_sectors << 9 ){
2369 DPRINT("more sectors than bytes\n");
2370 printk("bytes=%ld\n", raw_cmd.length >> 9 );
2371 printk("sectors=%ld\n", current_count_sectors);
2372 }
2373 #endif
2374 return 2;
2375 }
2376
2377 static void redo_fd_request(void)
2378 {
2379 #define REPEAT {request_done(0); continue; }
2380 int device;
2381 int tmp;
2382 int error;
2383
2384 error = -1;
2385 if (current_drive < N_DRIVE)
2386 floppy_off(current_drive);
2387
2388 if (CURRENT && CURRENT->dev < 0) return;
2389
2390 while(1){
2391 if (!CURRENT) {
2392 CLEAR_INTR;
2393 unlock_fdc();
2394 return;
2395 }
2396 if (MAJOR(CURRENT->dev) != MAJOR_NR)
2397 panic(DEVICE_NAME ": request list destroyed");
2398 if (CURRENT->bh && !CURRENT->bh->b_lock)
2399 panic(DEVICE_NAME ": block not locked");
2400 #if 0
2401 if (!CURRENT->bh->b_count &&
2402 (CURRENT->errors || error == CURRENT->dev)){
2403 error=CURRENT->dev;
2404 DPRINT("skipping read ahead buffer\n");
2405 REPEAT;
2406 }
2407 #endif
2408 error=-1;
2409 device = CURRENT->dev;
2410 set_fdc( DRIVE(device));
2411
2412 del_timer(&fd_timeout);
2413 fd_timeout.expires = DP->timeout;
2414 add_timer(&fd_timeout);
2415
2416 set_floppy(device);
2417 if(start_motor(redo_fd_request)) return;
2418 if(test_bit(current_drive, &fake_change) ||
2419 TESTF(FD_DISK_CHANGED)){
2420 DPRINT("disk absent or changed during operation\n");
2421 REPEAT;
2422 }
2423 if (!floppy) {
2424 if (!probing){
2425 DRS->probed_format = 0;
2426 if ( next_valid_format() ){
2427 DPRINT("no autodetectable formats\n");
2428 floppy = NULL;
2429 REPEAT;
2430 }
2431 }
2432 probing = 1;
2433 floppy = floppy_type+DP->autodetect[DRS->probed_format];
2434 } else
2435 probing = 0;
2436 errors = & (CURRENT->errors);
2437 tmp = make_raw_rw_request();
2438 if ( tmp < 2 ){
2439 request_done(tmp);
2440 continue;
2441 }
2442
2443 if (TESTF(FD_NEED_TWADDLE))
2444 twaddle();
2445 floppy_tq.routine = (void *)(void *) floppy_start;
2446 queue_task(&floppy_tq, &tq_timer);
2447 #ifdef DEBUGT
2448 debugt("queue fd request");
2449 #endif
2450 return;
2451 }
2452 #undef REPEAT
2453 }
2454
2455 static struct cont_t rw_cont={
2456 rw_interrupt,
2457 redo_fd_request,
2458 bad_flp_intr,
2459 request_done };
2460
2461 struct tq_struct request_tq =
2462 { 0, 0, (void *) (void *) redo_fd_request, 0 };
2463
2464 static void process_fd_request(void)
2465 {
2466 cont = &rw_cont;
2467 queue_task(&request_tq, &tq_timer);
2468 }
2469
2470 static void do_fd_request(void)
2471 {
2472 if (fdc_busy)
2473
2474
2475 return;
2476
2477 floppy_grab_irq_and_dma();
2478 fdc_busy=1;
2479 process_fd_request();
2480 }
2481
2482 static struct cont_t poll_cont={
2483 success_and_wakeup,
2484 floppy_ready,
2485 generic_failure,
2486 generic_done };
2487
2488 static int poll_drive(int interruptible, int flag){
2489 int ret;
2490
2491 raw_cmd.flags= flag;
2492 raw_cmd.track=0;
2493 raw_cmd.cmd_count=0;
2494 cont = &poll_cont;
2495 #ifdef DCL_DEBUG
2496 if (DP->flags & FD_DEBUG){
2497 DPRINT("setting NEWCHANGE in poll_drive\n");
2498 }
2499 #endif
2500 SETF(FD_DISK_NEWCHANGE);
2501 WAIT(floppy_ready);
2502 return ret;
2503 }
2504
2505
2506
2507
2508
2509
2510 static void reset_intr(void)
2511 {
2512 printk("weird, reset interrupt called\n");
2513 }
2514
2515 static struct cont_t reset_cont={
2516 reset_intr,
2517 success_and_wakeup,
2518 generic_failure,
2519 generic_done };
2520
2521 static int user_reset_fdc(int drive, int arg, int interruptible)
2522 {
2523 int ret;
2524
2525 ret=0;
2526 if(arg == FD_RESET_IF_NEEDED && !FDCS->reset)
2527 return 0;
2528 LOCK_FDC(drive,interruptible);
2529 if(arg == FD_RESET_ALWAYS)
2530 FDCS->reset=1;
2531 if ( FDCS->reset ){
2532 cont = &reset_cont;
2533 del_timer(&fd_timeout);
2534 fd_timeout.expires = DP->timeout;
2535 add_timer(&fd_timeout);
2536 WAIT(reset_fdc);
2537 }
2538 process_fd_request();
2539 return ret;
2540 }
2541
2542
2543
2544
2545
2546 static int fd_copyout(void *param, volatile void *address, int size)
2547 {
2548 int i;
2549
2550 i = verify_area(VERIFY_WRITE,param,size);
2551 if (i)
2552 return i;
2553 memcpy_tofs(param,(void *) address, size);
2554 return 0;
2555 }
2556
2557 #define COPYOUT(x) (fd_copyout( (void *)param, &(x), sizeof(x)))
2558 #define COPYIN(x) (memcpy_fromfs( &(x), (void *) param, sizeof(x)),0)
2559
2560 static char *drive_name(int type, int drive )
2561 {
2562 struct floppy_struct *floppy;
2563
2564 if ( type )
2565 floppy = floppy_type + type;
2566 else {
2567 if ( UDP->native_format )
2568 floppy = floppy_type + UDP->native_format;
2569 else
2570 return "(null)";
2571 }
2572 if ( floppy->name )
2573 return floppy->name;
2574 else
2575 return "(null)";
2576 }
2577
2578
2579 static struct cont_t raw_cmd_cont={
2580 success_and_wakeup,
2581 failure_and_wakeup,
2582 generic_failure,
2583 generic_done };
2584
2585 static int raw_cmd_ioctl(void *param)
2586 {
2587 int i, drive, count, ret;
2588
2589 if ( FDCS->rawcmd <= 1 )
2590 FDCS->rawcmd = 1;
2591 for ( drive= 0; drive < N_DRIVE; drive++){
2592 if ( FDC(drive) != fdc)
2593 continue;
2594 if ( drive == current_drive ){
2595 if ( UDRS->fd_ref > 1 ){
2596 FDCS->rawcmd = 2;
2597 break;
2598 }
2599 } else if ( UDRS->fd_ref ){
2600 FDCS->rawcmd = 2;
2601 break;
2602 }
2603 }
2604
2605 if(FDCS->reset)
2606 return -EIO;
2607
2608 COPYIN(raw_cmd);
2609 raw_cmd.rate &= 0x03;
2610 count = raw_cmd.length;
2611 if (raw_cmd.flags & (FD_RAW_WRITE | FD_RAW_READ)){
2612 if(count > max_buffer_sectors * 1024 )
2613 return -ENOMEM;
2614 buffer_track = -1;
2615 }
2616 if ( raw_cmd.flags & FD_RAW_WRITE ){
2617 i = verify_area(VERIFY_READ, raw_cmd.data, count );
2618 if (i)
2619 return i;
2620 memcpy_fromfs(floppy_track_buffer, raw_cmd.data, count);
2621 }
2622
2623 current_addr = floppy_track_buffer;
2624 cont = &raw_cmd_cont;
2625 IWAIT(floppy_start);
2626 #ifdef DCL_DEBUG
2627 if (DP->flags & FD_DEBUG){
2628 DPRINT("calling disk change from raw_cmd ioctl\n");
2629 }
2630 #endif
2631 if( disk_change(current_drive) )
2632 raw_cmd.flags |= FD_RAW_DISK_CHANGE;
2633 else
2634 raw_cmd.flags &= ~FD_RAW_DISK_CHANGE;
2635 if(raw_cmd.flags & FD_RAW_NO_MOTOR_AFTER)
2636 motor_off_callback(current_drive);
2637
2638 if ( !ret && !FDCS->reset ){
2639 raw_cmd.reply_count = inr;
2640 for( i=0; i< raw_cmd.reply_count; i++)
2641 raw_cmd.reply[i] = reply_buffer[i];
2642 if ( raw_cmd.flags & ( FD_RAW_READ | FD_RAW_WRITE ))
2643 raw_cmd.length = get_dma_residue(FLOPPY_DMA);
2644 } else
2645 ret = -EIO;
2646 DRS->track = NO_TRACK;
2647 if ( ret )
2648 return ret;
2649
2650 if ( raw_cmd.flags & FD_RAW_READ ){
2651 i=fd_copyout( raw_cmd.data, floppy_track_buffer, count);
2652 if (i)
2653 return i;
2654 }
2655
2656 return COPYOUT(raw_cmd);
2657 }
2658
2659 static int invalidate_drive(int rdev)
2660 {
2661
2662 set_bit( DRIVE(rdev), &fake_change);
2663 process_fd_request();
2664 check_disk_change(rdev);
2665 return 0;
2666 }
2667
2668 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
2669 unsigned long param)
2670 {
2671 #define IOCTL_MODE_BIT 8
2672 #define OPEN_WRITE_BIT 16
2673 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
2674
2675 struct floppy_struct newparams;
2676 struct format_descr tmp_format_req;
2677 int i,device,drive,type,cnt;
2678 struct floppy_struct *this_floppy;
2679 char *name;
2680
2681 device = inode->i_rdev;
2682 switch (cmd) {
2683 RO_IOCTLS(device,param);
2684 }
2685 type = TYPE(device);
2686 drive = DRIVE(device);
2687 switch (cmd) {
2688 case FDGETDRVTYP:
2689 i=verify_area(VERIFY_WRITE,(void *) param,16);
2690 if (i)
2691 return i;
2692 name = drive_name(type,drive);
2693 for ( cnt=0; cnt<16; cnt++){
2694 put_fs_byte(name[cnt],
2695 ((char*)param)+cnt);
2696 if ( ! *name )
2697 break;
2698 }
2699 return 0;
2700 case FDGETMAXERRS:
2701 return COPYOUT(UDP->max_errors);
2702 case FDGETPRM:
2703 if (type)
2704 this_floppy = &floppy_type[type];
2705 else if ((this_floppy = current_type[drive]) ==
2706 NULL)
2707 return -ENODEV;
2708 return COPYOUT(this_floppy[0]);
2709 case FDPOLLDRVSTAT:
2710 LOCK_FDC(drive,1);
2711 CALL(poll_drive(1, FD_RAW_NEED_DISK));
2712 process_fd_request();
2713
2714 case FDGETDRVSTAT:
2715 return COPYOUT(*UDRS);
2716 case FDGETFDCSTAT:
2717 return COPYOUT(*UFDCS);
2718 case FDGETDRVPRM:
2719 return COPYOUT(*UDP);
2720 case FDWERRORGET:
2721 return COPYOUT(*UDRWE);
2722 }
2723 if (!IOCTL_ALLOWED)
2724 return -EPERM;
2725 switch (cmd) {
2726 case FDWERRORCLR:
2727 UDRWE->write_errors = 0;
2728 UDRWE->first_error_sector = 0;
2729 UDRWE->first_error_generation = 0;
2730 UDRWE->last_error_sector = 0;
2731 UDRWE->last_error_generation = 0;
2732 UDRWE->badness = 0;
2733 return 0;
2734 case FDRAWCMD:
2735 if (type)
2736 return -EINVAL;
2737 LOCK_FDC(drive,1);
2738 set_floppy(device);
2739 CALL(i = raw_cmd_ioctl((void *) param));
2740 process_fd_request();
2741 return i;
2742 case FDFMTTRK:
2743 if (UDRS->fd_ref != 1)
2744 return -EBUSY;
2745 COPYIN(tmp_format_req);
2746 return do_format(device, &tmp_format_req);
2747 case FDSETMAXERRS:
2748 return COPYIN(UDP->max_errors);
2749 case FDFMTBEG:
2750 return 0;
2751 case FDCLRPRM:
2752 LOCK_FDC(drive,1);
2753 current_type[drive] = NULL;
2754 floppy_sizes[drive] = MAX_DISK_SIZE;
2755 UDRS->keep_data = 0;
2756 return invalidate_drive(device);
2757 case FDFMTEND:
2758 case FDFLUSH:
2759 LOCK_FDC(drive,1);
2760 return invalidate_drive(device);
2761 case FDSETPRM:
2762 case FDDEFPRM:
2763 COPYIN(newparams);
2764
2765 if(newparams.sect <= 0 ||
2766 newparams.head <= 0 ||
2767 newparams.track <= 0 ||
2768 newparams.track >
2769 UDP->tracks>>newparams.stretch)
2770 return -EINVAL;
2771 if ( type){
2772 if ( !suser() )
2773 return -EPERM;
2774 LOCK_FDC(drive,1);
2775 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2776 if (TYPE(drive_state[cnt].fd_device) == type &&
2777 drive_state[cnt].fd_ref)
2778 set_bit(drive, &fake_change);
2779 }
2780 floppy_type[type] = newparams;
2781 floppy_type[type].name="user format";
2782 for (cnt = type << 2 ;
2783 cnt < (type << 2 ) + 4 ;
2784 cnt++)
2785 floppy_sizes[cnt]=
2786 #ifdef CONFIG_FLOPPY_2_FDC
2787 floppy_sizes[cnt+0x80]=
2788 #endif
2789 floppy_type[type].size>>1;
2790 process_fd_request();
2791 for ( cnt = 0; cnt < N_DRIVE; cnt++){
2792 if (TYPE(drive_state[cnt].fd_device) == type &&
2793 drive_state[cnt].fd_ref)
2794 check_disk_change(drive_state[cnt].
2795 fd_device);
2796 }
2797 return 0;
2798 }
2799
2800 LOCK_FDC(drive,1);
2801 if ( cmd != FDDEFPRM )
2802
2803
2804 CALL(poll_drive(1,0));
2805 user_params[drive] = newparams;
2806 if (buffer_drive == drive &&
2807 buffer_max > user_params[drive].sect)
2808 buffer_max=user_params[drive].sect;
2809 current_type[drive] = &user_params[drive];
2810 floppy_sizes[drive] = user_params[drive].size >> 1;
2811 if (cmd == FDDEFPRM)
2812 DRS->keep_data = -1;
2813 else
2814 DRS->keep_data = 1;
2815
2816
2817
2818
2819
2820 if (DRS->maxblock >
2821 user_params[drive].sect ||
2822 DRS->maxtrack )
2823 invalidate_drive(device);
2824 else
2825 process_fd_request();
2826 return 0;
2827 case FDRESET:
2828 return user_reset_fdc( drive, (int)param, 1);
2829 case FDMSGON:
2830 UDP->flags |= FTD_MSG;
2831 return 0;
2832 case FDMSGOFF:
2833 UDP->flags &= ~FTD_MSG;
2834 return 0;
2835 case FDSETEMSGTRESH:
2836 UDP->max_errors.reporting =
2837 (unsigned short) (param & 0x0f);
2838 return 0;
2839 case FDTWADDLE:
2840 LOCK_FDC(drive,1);
2841 twaddle();
2842 process_fd_request();
2843 }
2844 if ( ! suser() )
2845 return -EPERM;
2846 switch(cmd){
2847 case FDSETDRVPRM:
2848 return COPYIN(*UDP);
2849 default:
2850 return -EINVAL;
2851 }
2852 return 0;
2853 #undef IOCTL_ALLOWED
2854 }
2855
2856 static void set_base_type(int drive,int code)
2857 {
2858 if (code > 0 && code <= NUMBER(default_drive_params)) {
2859 memcpy((char *) UDP,
2860 (char *) (&default_drive_params[code].params),
2861 sizeof( struct floppy_drive_params ));
2862 printk("fd%d is %s", drive, default_drive_params[code].name);
2863 return;
2864 } else if (!code)
2865 printk("fd%d is not installed", drive);
2866 else
2867 printk("fd%d is unknown type %d",drive,code);
2868 }
2869
2870 static void config_types(void)
2871 {
2872 int drive;
2873
2874 for (drive=0; drive<N_DRIVE ; drive++){
2875
2876 memcpy((char *) UDP, (char *) (&default_drive_params->params),
2877 sizeof( struct floppy_drive_params ));
2878 }
2879 printk("Floppy drive(s): ");
2880 set_base_type(0, (CMOS_READ(0x10) >> 4) & 15);
2881 if (CMOS_READ(0x10) & 15) {
2882 printk(", ");
2883 set_base_type(1, CMOS_READ(0x10) & 15);
2884 }
2885 printk("\n");
2886 }
2887
2888 static int floppy_read(struct inode * inode, struct file * filp,
2889 char * buf, int count)
2890 {
2891 int drive = DRIVE(inode->i_rdev);
2892
2893 check_disk_change(inode->i_rdev);
2894 if (UTESTF(FD_DISK_CHANGED))
2895 return -ENXIO;
2896 return block_read(inode, filp, buf, count);
2897 }
2898
2899 static int floppy_write(struct inode * inode, struct file * filp,
2900 char * buf, int count)
2901 {
2902 int block;
2903 int ret;
2904 int drive = DRIVE(inode->i_rdev);
2905
2906 if(!UDRS->maxblock)
2907 UDRS->maxblock=1;
2908 check_disk_change(inode->i_rdev);
2909 if (UTESTF(FD_DISK_CHANGED))
2910 return -ENXIO;
2911 if(!UTESTF(FD_DISK_WRITABLE))
2912 return -EROFS;
2913 block = (filp->f_pos + count) >> 9;
2914 if(block > UDRS->maxblock)
2915 UDRS->maxblock = block;
2916 ret= block_write(inode, filp, buf, count);
2917 return ret;
2918 }
2919
2920 static void floppy_release(struct inode * inode, struct file * filp)
2921 {
2922 int drive;
2923
2924 drive = DRIVE(inode->i_rdev);
2925
2926 if( !filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
2927
2928
2929 block_fsync(inode,filp);
2930
2931 if (UDRS->fd_ref < 0)
2932 UDRS->fd_ref=0;
2933 else if (!UDRS->fd_ref--) {
2934 DPRINT("floppy_release with fd_ref == 0");
2935 UDRS->fd_ref = 0;
2936 }
2937 floppy_release_irq_and_dma();
2938 }
2939
2940
2941
2942
2943
2944
2945 #define RETERR(x) \
2946 do{floppy_release(inode,filp); \
2947 return -(x);}while(0)
2948
2949 static int floppy_open(struct inode * inode, struct file * filp)
2950 {
2951 int drive;
2952 int old_dev;
2953
2954 if (!filp) {
2955 DPRINT("Weird, open called with filp=0\n");
2956 return -EIO;
2957 }
2958
2959 drive = DRIVE(inode->i_rdev);
2960 if (drive >= N_DRIVE ||
2961 !( ALLOWED_DRIVE_MASK & ( 1 << drive)) ||
2962 fdc_state[FDC(drive)].version == FDC_NONE)
2963 return -ENXIO;
2964
2965 if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
2966 return -ENXIO;
2967 old_dev = UDRS->fd_device;
2968 if (UDRS->fd_ref && old_dev != inode->i_rdev)
2969 return -EBUSY;
2970
2971 if(!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
2972 USETF(FD_DISK_CHANGED);
2973 USETF(FD_VERIFY);
2974 }
2975
2976 if(UDRS->fd_ref == -1 ||
2977 (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
2978 return -EBUSY;
2979
2980 if (floppy_grab_irq_and_dma())
2981 return -EBUSY;
2982
2983 if (filp->f_flags & O_EXCL)
2984 UDRS->fd_ref = -1;
2985 else
2986 UDRS->fd_ref++;
2987
2988 UDRS->fd_device = inode->i_rdev;
2989
2990 if (old_dev && old_dev != inode->i_rdev) {
2991 if (buffer_drive == drive)
2992 buffer_track = -1;
2993 invalidate_buffers(old_dev);
2994 }
2995
2996
2997 if ((filp->f_mode & 2) || (permission(inode,2) == 0))
2998 filp->f_mode |= IOCTL_MODE_BIT;
2999 if (filp->f_mode & 2)
3000 filp->f_mode |= OPEN_WRITE_BIT;
3001
3002 if (UFDCS->rawcmd == 1)
3003 UFDCS->rawcmd = 2;
3004
3005 if (filp->f_flags & O_NDELAY)
3006 return 0;
3007 if (filp->f_mode & 3) {
3008 UDRS->last_checked = 0;
3009 check_disk_change(inode->i_rdev);
3010 if (UTESTF(FD_DISK_CHANGED))
3011 RETERR(ENXIO);
3012 }
3013 if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
3014 RETERR(EROFS);
3015 return 0;
3016 #undef RETERR
3017 }
3018
3019
3020
3021
3022 static int check_floppy_change(dev_t dev)
3023 {
3024 int drive = DRIVE( dev );
3025
3026 if (MAJOR(dev) != MAJOR_NR) {
3027 DPRINT("floppy_changed: not a floppy\n");
3028 return 0;
3029 }
3030
3031 if (UTESTF(FD_DISK_CHANGED))
3032 return 1;
3033
3034 if(UDRS->last_checked + UDP->checkfreq < jiffies){
3035 lock_fdc(drive,0);
3036 poll_drive(0,0);
3037 process_fd_request();
3038 }
3039
3040 if(UTESTF(FD_DISK_CHANGED) ||
3041 test_bit(drive, &fake_change) ||
3042 (!TYPE(dev) && !current_type[drive]))
3043 return 1;
3044 return 0;
3045 }
3046
3047
3048
3049
3050
3051 static int floppy_revalidate(dev_t dev)
3052 {
3053 #define NO_GEOM (!current_type[drive] && !TYPE(dev))
3054 struct buffer_head * bh;
3055 int drive=DRIVE(dev);
3056 int cf;
3057
3058 if(UTESTF(FD_DISK_CHANGED) || test_bit(drive, &fake_change) || NO_GEOM){
3059 lock_fdc(drive,0);
3060 cf = UTESTF(FD_DISK_CHANGED);
3061 if(! (cf || test_bit(drive, &fake_change) || NO_GEOM)){
3062 process_fd_request();
3063 return 0;
3064 }
3065 UDRS->maxblock = 0;
3066 UDRS->maxtrack = 0;
3067 if ( buffer_drive == drive)
3068 buffer_track = -1;
3069 clear_bit(drive, &fake_change);
3070 UCLEARF(FD_DISK_CHANGED);
3071 if(cf)
3072 UDRS->generation++;
3073 if(NO_GEOM){
3074
3075 int size = floppy_blocksizes[MINOR(dev)];
3076 if (!size)
3077 size = 1024;
3078 if (!(bh = getblk(dev,0,size))){
3079 process_fd_request();
3080 return 1;
3081 }
3082 if ( bh && ! bh->b_uptodate)
3083 ll_rw_block(READ, 1, &bh);
3084 process_fd_request();
3085 wait_on_buffer(bh);
3086 brelse(bh);
3087 return 0;
3088 }
3089 if(cf)
3090 poll_drive(0, FD_RAW_NEED_DISK);
3091 process_fd_request();
3092 }
3093 return 0;
3094 }
3095
3096 static struct file_operations floppy_fops = {
3097 NULL,
3098 floppy_read,
3099 floppy_write,
3100 NULL,
3101 NULL,
3102 fd_ioctl,
3103 NULL,
3104 floppy_open,
3105 floppy_release,
3106 block_fsync,
3107 NULL,
3108 check_floppy_change,
3109 floppy_revalidate,
3110 };
3111
3112
3113
3114
3115
3116
3117
3118
3119 static char get_fdc_version(void)
3120 {
3121 int r;
3122
3123 output_byte(FD_DUMPREGS);
3124 if ( FDCS->reset )
3125 return FDC_NONE;
3126 if ( (r = result()) <= 0x00)
3127 return FDC_NONE;
3128 if ((r==1) && (reply_buffer[0] == 0x80)){
3129 printk("FDC %d is a 8272A\n",fdc);
3130 return FDC_8272A;
3131 }
3132 if (r != 10) {
3133 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
3134 return FDC_UNKNOWN;
3135 }
3136 output_byte(FD_VERSION);
3137 r = result();
3138 if ((r == 1) && (reply_buffer[0] == 0x80)){
3139 printk("FDC %d is a 82072\n",fdc);
3140 return FDC_82072;
3141 }
3142 if ((r != 1) || (reply_buffer[0] != 0x90)) {
3143 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
3144 return FDC_UNKNOWN;
3145 }
3146 output_byte(FD_UNLOCK);
3147 r = result();
3148 if ((r == 1) && (reply_buffer[0] == 0x80)){
3149 printk("FDC %d is a pre-1991 82077\n", fdc);
3150 return FDC_82077_ORIG;
3151 }
3152 if ((r != 1) || (reply_buffer[0] != 0x00)) {
3153 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
3154 return FDC_UNKNOWN;
3155 }
3156 printk("FDC %d is a post-1991 82077\n",fdc);
3157 return FDC_82077;
3158 }
3159
3160 #ifndef FD_MODULE
3161
3162 static void invert_dcl(int *ints)
3163 {
3164 int i;
3165
3166 for (i=0; i < ARRAY_SIZE(default_drive_params); i++)
3167 default_drive_params[i].params.flags |= 0x80;
3168 DPRINT("Configuring drives for inverted dcl\n");
3169 }
3170
3171 static void allow_drives(int *ints)
3172 {
3173 if (ints[1] >= 1 ){
3174 ALLOWED_DRIVE_MASK=ints[1];
3175 DPRINT1("setting allowed_drive_mask to 0x%x\n", ints[1]);
3176 } else
3177 DPRINT("allowed_drive_mask needs a parameter\n");
3178 }
3179
3180 #ifdef CONFIG_FLOPPY_2_FDC
3181 static void twofdc(int *ints)
3182 {
3183 FDC2 = 0x370;
3184 DPRINT("enabling second fdc at address 0x370\n");
3185 }
3186 #endif
3187
3188 static struct param_table {
3189 char *name;
3190 void (*fn)(int *ints);
3191 } config_params[]={
3192 { "allowed_drive_mask", allow_drives },
3193 #ifdef CONFIG_FLOPPY_2_FDC
3194 { "two_fdc", twofdc },
3195 #endif
3196 { "thinkpad", invert_dcl } };
3197
3198 void floppy_setup(char *str, int *ints)
3199 {
3200 int i;
3201 for(i=0; i< ARRAY_SIZE(config_params); i++){
3202 if (strcmp(str,config_params[i].name) == 0 ){
3203 config_params[i].fn(ints);
3204 return;
3205 }
3206 }
3207 printk("unknown floppy parameter %s\n", str);
3208 }
3209 #endif
3210
3211 #ifdef FD_MODULE
3212 static
3213 #endif
3214 int new_floppy_init(void)
3215 {
3216 int i,drive;
3217 int have_no_fdc=0;
3218
3219 sti();
3220
3221 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
3222 printk("Unable to get major %d for floppy\n",MAJOR_NR);
3223 return -EBUSY;
3224 }
3225
3226 for(i=0; i<256; i++)
3227 if ( TYPE(i))
3228 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
3229 else
3230 floppy_sizes[i] = MAX_DISK_SIZE;
3231
3232 blk_size[MAJOR_NR] = floppy_sizes;
3233 blksize_size[MAJOR_NR] = floppy_blocksizes;
3234 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3235 del_timer(&fd_timeout);
3236 config_types();
3237
3238 fdc_state[0].address = FDC1;
3239 fdc_state[0].dor = 0;
3240 #if N_FDC > 1
3241 fdc_state[1].address = FDC2;
3242 fdc_state[1].dor = 0;
3243 #endif
3244
3245 for (i = 0 ; i < N_FDC ; i++) {
3246 fdc = i;
3247 FDCS->dtr = -1;
3248 FDCS->dor = 0x4;
3249 FDCS->reset = 0;
3250 FDCS->version = FDC_NONE;
3251 }
3252
3253 if(floppy_grab_irq_and_dma()){
3254 unregister_blkdev(MAJOR_NR,"fd");
3255 return -EBUSY;
3256 }
3257
3258
3259 for (drive = 0; drive < N_DRIVE ; drive++) {
3260 UDRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE | FD_DISK_CHANGED;
3261 UDRS->generation = 0;
3262 UDRS->keep_data = 0;
3263 UDRS->fd_ref = 0;
3264 UDRS->fd_device = 0;
3265 UDRWE->write_errors = 0;
3266 UDRWE->first_error_sector = 0;
3267 UDRWE->first_error_generation = 0;
3268 UDRWE->last_error_sector = 0;
3269 UDRWE->last_error_generation = 0;
3270 UDRWE->badness = 0;
3271 }
3272
3273 for (i = 0 ; i < N_FDC ; i++) {
3274 fdc = i;
3275 if (FDCS->address == -1 )
3276 continue;
3277 FDCS->rawcmd = 2;
3278 if(user_reset_fdc(-1,FD_RESET_IF_NEEDED,0)){
3279 FDCS->address = -1;
3280 continue;
3281 }
3282
3283 FDCS->version = get_fdc_version();
3284 if (FDCS->version == FDC_NONE){
3285 FDCS->address = -1;
3286 continue;
3287 }
3288
3289 have_no_fdc = 0;
3290
3291
3292
3293
3294 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
3295 user_reset_fdc(-1,FD_RESET_ALWAYS,0);
3296 }
3297 fdc=0;
3298 current_drive = 0;
3299 floppy_release_irq_and_dma();
3300 initialising=0;
3301 if(have_no_fdc)
3302 unregister_blkdev(MAJOR_NR,"fd");
3303 return have_no_fdc;
3304 }
3305
3306
3307 void floppy_init(void)
3308 {
3309 new_floppy_init();
3310 }
3311
3312 static int floppy_grab_irq_and_dma(void)
3313 {
3314 int i;
3315 cli();
3316 if (usage_count++){
3317 sti();
3318 return 0;
3319 }
3320 sti();
3321 #ifdef FD_MODULE
3322 MOD_INC_USE_COUNT;
3323 #endif
3324 for(i=0; i< N_FDC; i++){
3325 if(FDCS->address != -1){
3326 fdc = i;
3327 reset_fdc_info(1);
3328 outb_p(FDCS->dor, FD_DOR);
3329 }
3330 }
3331 set_dor(0, ~0, 8);
3332
3333 if (request_irq(FLOPPY_IRQ, floppy_interrupt, SA_INTERRUPT, "floppy")) {
3334 DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
3335 FLOPPY_IRQ);
3336 return -1;
3337 }
3338 if (request_dma(FLOPPY_DMA,"floppy")) {
3339 DPRINT1("Unable to grab DMA%d for the floppy driver\n",
3340 FLOPPY_DMA);
3341 free_irq(FLOPPY_IRQ);
3342 return -1;
3343 }
3344 for(fdc = 0; fdc < N_FDC ; fdc++)
3345 if(FDCS->address != -1)
3346 outb_p(FDCS->dor, FD_DOR);
3347 fdc = 0;
3348 enable_irq(FLOPPY_IRQ);
3349 return 0;
3350 }
3351
3352 static void floppy_release_irq_and_dma(void)
3353 {
3354 #ifdef CONFIG_FLOPPY_SANITY
3355 int drive;
3356 #endif
3357 cli();
3358 if (--usage_count){
3359 sti();
3360 return;
3361 }
3362 sti();
3363 #ifdef FD_MODULE
3364 MOD_DEC_USE_COUNT;
3365 #endif
3366 disable_dma(FLOPPY_DMA);
3367 free_dma(FLOPPY_DMA);
3368 disable_irq(FLOPPY_IRQ);
3369 free_irq(FLOPPY_IRQ);
3370
3371 set_dor(0, ~0, 8);
3372 #if N_FDC > 1
3373 set_dor(1, ~8, 0);
3374 #endif
3375
3376 #ifdef CONFIG_FLOPPY_SANITY
3377 for(drive=0; drive < N_FDC * 4; drive++)
3378 if( motor_off_timer[drive].next )
3379 printk("motor off timer %d still active\n", drive);
3380
3381 if(fd_timeout.next)
3382 printk("floppy timer still active\n");
3383 if (fd_timer.next)
3384 printk("auxiliary floppy timer still active\n");
3385 if(floppy_tq.sync)
3386 printk("task queue still active\n");
3387 #endif
3388 }
3389