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