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