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