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