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