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 10
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 (!floppy)
1093 return;
1094 if (floppy->rate & 0x40){
1095 switch(raw_cmd->rate){
1096 case 0:
1097 perp_mode=2;
1098 break;
1099 case 3:
1100 perp_mode=3;
1101 break;
1102 default:
1103 DPRINT("Invalid data rate for perpendicular mode!\n");
1104 cont->done(0);
1105 FDCS->reset = 1;
1106
1107
1108 return;
1109 }
1110 } else
1111 perp_mode = 0;
1112
1113 if (FDCS->perp_mode == perp_mode)
1114 return;
1115 if (FDCS->version >= FDC_82077_ORIG && FDCS->has_fifo) {
1116 output_byte(FD_PERPENDICULAR);
1117 output_byte(perp_mode);
1118 FDCS->perp_mode = perp_mode;
1119 } else if (perp_mode) {
1120 DPRINT("perpendicular mode not supported by this FDC.\n");
1121 }
1122 }
1123
1124 #define NOMINAL_DTR 500
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145 static void fdc_specify(void)
1146 {
1147 unsigned char spec1, spec2;
1148 int srt, hlt, hut;
1149 unsigned long dtr = NOMINAL_DTR;
1150 unsigned long scale_dtr = NOMINAL_DTR;
1151 int hlt_max_code = 0x7f;
1152 int hut_max_code = 0xf;
1153
1154 if (FDCS->need_configure && FDCS->has_fifo) {
1155 if (FDCS->reset)
1156 return;
1157
1158
1159 output_byte(FD_CONFIGURE);
1160 output_byte(0);
1161 output_byte(0x2A);
1162 output_byte(0);
1163 if (FDCS->reset){
1164 FDCS->has_fifo=0;
1165 return;
1166 }
1167 FDCS->need_configure = 0;
1168
1169 }
1170
1171 switch (raw_cmd->rate & 0x03) {
1172 case 3:
1173 dtr = 1000;
1174 break;
1175 case 1:
1176 dtr = 300;
1177 break;
1178 case 2:
1179 dtr = 250;
1180 break;
1181 }
1182
1183 if (FDCS->version >= FDC_82072) {
1184 scale_dtr = dtr;
1185 hlt_max_code = 0x00;
1186 hut_max_code = 0x0;
1187 }
1188
1189
1190 srt = 16 - (DP->srt*scale_dtr/1000 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1191 SUPBOUND(srt, 0xf);
1192 INFBOUND(srt, 0);
1193
1194 hlt = (DP->hlt*scale_dtr/2 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1195 if (hlt < 0x01)
1196 hlt = 0x01;
1197 else if (hlt > 0x7f)
1198 hlt = hlt_max_code;
1199
1200 hut = (DP->hut*scale_dtr/16 + NOMINAL_DTR - 1)/NOMINAL_DTR;
1201 if (hut < 0x1)
1202 hut = 0x1;
1203 else if (hut > 0xf)
1204 hut = hut_max_code;
1205
1206 spec1 = (srt << 4) | hut;
1207 spec2 = (hlt << 1);
1208
1209
1210 if (FDCS->spec1 != spec1 || FDCS->spec2 != spec2) {
1211
1212 output_byte(FD_SPECIFY);
1213 output_byte(FDCS->spec1 = spec1);
1214 output_byte(FDCS->spec2 = spec2);
1215 }
1216 }
1217
1218
1219
1220
1221
1222 static int fdc_dtr(void)
1223 {
1224
1225 if (raw_cmd->rate == FDCS->dtr)
1226 return 0;
1227
1228
1229 fd_outb(raw_cmd->rate, FD_DCR);
1230
1231
1232
1233
1234
1235
1236 FDCS->dtr = raw_cmd->rate;
1237 return(wait_for_completion(jiffies+2*HZ/100,
1238 (timeout_fn) floppy_ready));
1239 }
1240
1241 static void tell_sector(void)
1242 {
1243 printk(": track %d, head %d, sector %d, size %d",
1244 R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
1245 }
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255 static int interpret_errors(void)
1256 {
1257 char bad;
1258
1259 if (inr!=7) {
1260 DPRINT("-- FDC reply error");
1261 FDCS->reset = 1;
1262 return 1;
1263 }
1264
1265
1266 switch (ST0 & ST0_INTR) {
1267 case 0x40:
1268 bad = 1;
1269 if (ST1 & ST1_WP) {
1270 DPRINT("Drive is write protected\n");
1271 CLEARF(FD_DISK_WRITABLE);
1272 cont->done(0);
1273 bad = 2;
1274 } else if (ST1 & ST1_ND) {
1275 SETF(FD_NEED_TWADDLE);
1276 } else if (ST1 & ST1_OR) {
1277 if (DP->flags & FTD_MSG)
1278 DPRINT("Over/Underrun - retrying\n");
1279 bad = 0;
1280 }else if (*errors >= DP->max_errors.reporting){
1281 DPRINT("");
1282 if (ST0 & ST0_ECE) {
1283 printk("Recalibrate failed!");
1284 } else if (ST2 & ST2_CRC) {
1285 printk("data CRC error");
1286 tell_sector();
1287 } else if (ST1 & ST1_CRC) {
1288 printk("CRC error");
1289 tell_sector();
1290 } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
1291 if (!probing) {
1292 printk("sector not found");
1293 tell_sector();
1294 } else
1295 printk("probe failed...");
1296 } else if (ST2 & ST2_WC) {
1297 printk("wrong cylinder");
1298 } else if (ST2 & ST2_BC) {
1299 printk("bad cylinder");
1300 } else {
1301 printk("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", ST0, ST1, ST2);
1302 tell_sector();
1303 }
1304 printk("\n");
1305
1306 }
1307 if (ST2 & ST2_WC || ST2 & ST2_BC)
1308
1309 DRS->track = NEED_2_RECAL;
1310 return bad;
1311 case 0x80:
1312 DPRINT("Invalid FDC command given!\n");
1313 cont->done(0);
1314 return 2;
1315 case 0xc0:
1316 DPRINT("Abnormal termination caused by polling\n");
1317 cont->error();
1318 return 2;
1319 default:
1320 return 0;
1321 }
1322 }
1323
1324
1325
1326
1327
1328
1329 static void setup_rw_floppy(void)
1330 {
1331 int i,ready_date,r, flags,dflags;
1332 timeout_fn function;
1333
1334 flags = raw_cmd->flags;
1335 if (flags & (FD_RAW_READ | FD_RAW_WRITE))
1336 flags |= FD_RAW_INTR;
1337
1338 if ((flags & FD_RAW_SPIN) && !(flags & FD_RAW_NO_MOTOR)){
1339 ready_date = DRS->spinup_date + DP->spinup;
1340
1341
1342
1343
1344 if (ready_date > jiffies + DP->select_delay){
1345 ready_date -= DP->select_delay;
1346 function = (timeout_fn) floppy_start;
1347 } else
1348 function = (timeout_fn) setup_rw_floppy;
1349
1350
1351 if (wait_for_completion(ready_date,function))
1352 return;
1353 }
1354 dflags = DRS->flags;
1355
1356 if ((flags & FD_RAW_READ) || (flags & FD_RAW_WRITE))
1357 setup_DMA();
1358
1359 if (flags & FD_RAW_INTR)
1360 SET_INTR(main_command_interrupt);
1361
1362 r=0;
1363 for (i=0; i< raw_cmd->cmd_count; i++)
1364 r|=output_byte(raw_cmd->cmd[i]);
1365
1366 #ifdef DEBUGT
1367 debugt("rw_command: ");
1368 #endif
1369 if (r){
1370 reset_fdc();
1371 return;
1372 }
1373
1374 if (!(flags & FD_RAW_INTR)){
1375 inr = result();
1376 cont->interrupt();
1377 } else if (flags & FD_RAW_NEED_DISK)
1378 fd_watchdog();
1379 }
1380
1381 static int blind_seek;
1382
1383
1384
1385
1386
1387 static void seek_interrupt(void)
1388 {
1389 #ifdef DEBUGT
1390 debugt("seek interrupt:");
1391 #endif
1392 if (inr != 2 || (ST0 & 0xF8) != 0x20) {
1393 DPRINT("seek failed\n");
1394 DRS->track = NEED_2_RECAL;
1395 cont->error();
1396 cont->redo();
1397 return;
1398 }
1399 if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek){
1400 #ifdef DCL_DEBUG
1401 if (DP->flags & FD_DEBUG){
1402 DPRINT("clearing NEWCHANGE flag because of effective seek\n");
1403 DPRINT1("jiffies=%ld\n", jiffies);
1404 }
1405 #endif
1406 CLEARF(FD_DISK_NEWCHANGE);
1407 DRS->select_date = jiffies;
1408 }
1409 DRS->track = ST1;
1410 floppy_ready();
1411 }
1412
1413 static void check_wp(void)
1414 {
1415 if (TESTF(FD_VERIFY)) {
1416
1417 output_byte(FD_GETSTATUS);
1418 output_byte(UNIT(current_drive));
1419 if (result() != 1){
1420 FDCS->reset = 1;
1421 return;
1422 }
1423 CLEARF(FD_VERIFY);
1424 CLEARF(FD_NEED_TWADDLE);
1425 #ifdef DCL_DEBUG
1426 if (DP->flags & FD_DEBUG){
1427 DPRINT("checking whether disk is write protected\n");
1428 DPRINT1("wp=%x\n",ST3 & 0x40);
1429 }
1430 #endif
1431 if (!(ST3 & 0x40))
1432 SETF(FD_DISK_WRITABLE);
1433 else
1434 CLEARF(FD_DISK_WRITABLE);
1435 }
1436 }
1437
1438 static void seek_floppy(void)
1439 {
1440 int track;
1441
1442 blind_seek=0;
1443
1444 #ifdef DCL_DEBUG
1445 if (DP->flags & FD_DEBUG){
1446 DPRINT("calling disk change from seek\n");
1447 }
1448 #endif
1449
1450 if (!TESTF(FD_DISK_NEWCHANGE) &&
1451 disk_change(current_drive) &&
1452 (raw_cmd->flags & FD_RAW_NEED_DISK)){
1453
1454
1455
1456
1457 SETF(FD_DISK_CHANGED);
1458 cont->done(0);
1459 cont->redo();
1460 return;
1461 }
1462 if (DRS->track <= NEED_1_RECAL){
1463 recalibrate_floppy();
1464 return;
1465 } else if (TESTF(FD_DISK_NEWCHANGE) &&
1466 (raw_cmd->flags & FD_RAW_NEED_DISK) &&
1467 (DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) {
1468
1469
1470 if (raw_cmd->track)
1471 track = raw_cmd->track - 1;
1472 else {
1473 if (DP->flags & FD_SILENT_DCL_CLEAR){
1474 set_dor(fdc, ~(0x10 << UNIT(current_drive)), 0);
1475 blind_seek = 1;
1476 raw_cmd->flags |= FD_RAW_NEED_SEEK;
1477 }
1478 track = 1;
1479 }
1480 } else {
1481 check_wp();
1482 if (raw_cmd->track != DRS->track &&
1483 (raw_cmd->flags & FD_RAW_NEED_SEEK))
1484 track = raw_cmd->track;
1485 else {
1486 setup_rw_floppy();
1487 return;
1488 }
1489 }
1490
1491 SET_INTR(seek_interrupt);
1492 output_byte(FD_SEEK);
1493 output_byte(UNIT(current_drive));
1494 LAST_OUT(track);
1495 #ifdef DEBUGT
1496 debugt("seek command:");
1497 #endif
1498 }
1499
1500 static void recal_interrupt(void)
1501 {
1502 #ifdef DEBUGT
1503 debugt("recal interrupt:");
1504 #endif
1505 if (inr !=2)
1506 FDCS->reset = 1;
1507 else if (ST0 & ST0_ECE) {
1508 switch(DRS->track){
1509 case NEED_1_RECAL:
1510 #ifdef DEBUGT
1511 debugt("recal interrupt need 1 recal:");
1512 #endif
1513
1514
1515
1516
1517 cont->error();
1518 cont->redo();
1519 return;
1520 case NEED_2_RECAL:
1521 #ifdef DEBUGT
1522 debugt("recal interrupt need 2 recal:");
1523 #endif
1524
1525
1526
1527
1528
1529
1530 #ifdef DCL_DEBUG
1531 if (DP->flags & FD_DEBUG){
1532 DPRINT("clearing NEWCHANGE flag because of second recalibrate\n");
1533 }
1534 #endif
1535
1536 CLEARF(FD_DISK_NEWCHANGE);
1537 DRS->select_date = jiffies;
1538
1539 default:
1540 #ifdef DEBUGT
1541 debugt("recal interrupt default:");
1542 #endif
1543
1544
1545
1546
1547
1548
1549 DRS->track = NEED_1_RECAL;
1550 break;
1551 }
1552 } else
1553 DRS->track = ST1;
1554 floppy_ready();
1555 }
1556
1557
1558
1559
1560
1561 static void unexpected_floppy_interrupt(void)
1562 {
1563 int i;
1564 if (initialising)
1565 return;
1566 if (print_unex){
1567 DPRINT("unexpected interrupt\n");
1568 if (inr >= 0)
1569 for (i=0; i<inr; i++)
1570 printk("%d %x\n", i, reply_buffer[i]);
1571 }
1572 while(1){
1573 output_byte(FD_SENSEI);
1574 inr=result();
1575 if (inr != 2)
1576 break;
1577 if (print_unex){
1578 printk("sensei\n");
1579 for (i=0; i<inr; i++)
1580 printk("%d %x\n", i, reply_buffer[i]);
1581 }
1582 }
1583 FDCS->reset = 1;
1584 }
1585
1586 static struct tq_struct floppy_tq =
1587 { 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
1588
1589
1590 static void floppy_interrupt(int irq, struct pt_regs * regs)
1591 {
1592 void (*handler)(void) = DEVICE_INTR;
1593
1594 lasthandler = handler;
1595 interruptjiffies = jiffies;
1596
1597 floppy_enable_hlt();
1598 CLEAR_INTR;
1599 if (fdc >= N_FDC || FDCS->address == -1){
1600
1601 printk("DOR0=%x\n", fdc_state[0].dor);
1602 printk("floppy interrupt on bizarre fdc %d\n",fdc);
1603 printk("handler=%p\n", handler);
1604 is_alive("bizarre fdc");
1605 return;
1606 }
1607 inr = result();
1608 if (!handler){
1609 unexpected_floppy_interrupt();
1610 is_alive("unexpected");
1611 return;
1612 }
1613 if (inr == 0){
1614 do {
1615 output_byte(FD_SENSEI);
1616 inr = result();
1617 } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2);
1618 }
1619 floppy_tq.routine = (void *)(void *) handler;
1620 queue_task_irq(&floppy_tq, &tq_timer);
1621 is_alive("normal interrupt end");
1622 }
1623
1624 static void recalibrate_floppy(void)
1625 {
1626 #ifdef DEBUGT
1627 debugt("recalibrate floppy:");
1628 #endif
1629 SET_INTR(recal_interrupt);
1630 output_byte(FD_RECALIBRATE);
1631 LAST_OUT(UNIT(current_drive));
1632 }
1633
1634
1635
1636
1637 static void reset_interrupt(void)
1638 {
1639 #ifdef DEBUGT
1640 debugt("reset interrupt:");
1641 #endif
1642
1643 result();
1644 if (FDCS->reset) {
1645 printk("reset set in interrupt, calling %p\n", cont->error);
1646 cont->error();
1647 }
1648 cont->redo();
1649 }
1650
1651
1652
1653
1654
1655 static void reset_fdc(void)
1656 {
1657 SET_INTR(reset_interrupt);
1658 FDCS->reset = 0;
1659 reset_fdc_info(0);
1660 if (FDCS->version >= FDC_82077)
1661 fd_outb(0x80 | (FDCS->dtr &3), FD_STATUS);
1662 else {
1663 fd_outb(FDCS->dor & ~0x04, FD_DOR);
1664 udelay(FD_RESET_DELAY);
1665 outb(FDCS->dor, FD_DOR);
1666 }
1667 }
1668
1669 static void empty(void)
1670 {
1671 }
1672
1673 void show_floppy(void)
1674 {
1675 int i;
1676
1677 printk("\n");
1678 printk("floppy driver state\n");
1679 printk("-------------------\n");
1680 printk("now=%ld last interrupt=%d last called handler=%p\n",
1681 jiffies, interruptjiffies, lasthandler);
1682
1683
1684 #ifdef FLOPPY_SANITY_CHECK
1685 printk("timeout_message=%s\n", timeout_message);
1686 printk("last output bytes:\n");
1687 for (i=0; i < OLOGSIZE; i++)
1688 printk("%2x %2x %ld\n",
1689 output_log[(i+output_log_pos) % OLOGSIZE].data,
1690 output_log[(i+output_log_pos) % OLOGSIZE].status,
1691 output_log[(i+output_log_pos) % OLOGSIZE].jiffies);
1692 printk("last result at %d\n", resultjiffies);
1693 printk("last redo_fd_request at %d\n", lastredo);
1694 for (i=0; i<resultsize; i++){
1695 printk("%2x ", reply_buffer[i]);
1696 }
1697 printk("\n");
1698 #endif
1699
1700 printk("status=%x\n", fd_inb(FD_STATUS));
1701 printk("fdc_busy=%d\n", fdc_busy);
1702 if (DEVICE_INTR)
1703 printk("DEVICE_INTR=%p\n", DEVICE_INTR);
1704 if (floppy_tq.sync)
1705 printk("floppy_tq.routine=%p\n", floppy_tq.routine);
1706 if (fd_timer.prev)
1707 printk("fd_timer.function=%p\n", fd_timer.function);
1708 if (fd_timeout.prev){
1709 printk("timer_table=%p\n",fd_timeout.function);
1710 printk("expires=%ld\n",fd_timeout.expires-jiffies);
1711 printk("now=%ld\n",jiffies);
1712 }
1713 printk("cont=%p\n", cont);
1714 printk("CURRENT=%p\n", CURRENT);
1715 printk("command_status=%d\n", command_status);
1716 printk("\n");
1717 }
1718
1719 static void floppy_shutdown(void)
1720 {
1721 if (!initialising)
1722 show_floppy();
1723 CLEAR_INTR;
1724 floppy_tq.routine = (void *)(void *) empty;
1725 del_timer(&fd_timer);
1726 sti();
1727
1728 floppy_enable_hlt();
1729 fd_disable_dma();
1730
1731
1732 if (!initialising)
1733 DPRINT("floppy timeout\n");
1734 FDCS->reset = 1;
1735 if (cont){
1736 cont->done(0);
1737 cont->redo();
1738 } else {
1739 printk("no cont in shutdown!\n");
1740 process_fd_request();
1741 }
1742 is_alive("floppy shutdown");
1743 }
1744
1745
1746
1747 static int start_motor(void (*function)(void) )
1748 {
1749 int mask, data;
1750
1751 mask = 0xfc;
1752 data = UNIT(current_drive);
1753 if (!(raw_cmd->flags & FD_RAW_NO_MOTOR)){
1754 if (!(FDCS->dor & (0x10 << UNIT(current_drive)))){
1755 set_debugt();
1756
1757 DRS->first_read_date = 0;
1758
1759 DRS->spinup_date = jiffies;
1760 data |= (0x10 << UNIT(current_drive));
1761 }
1762 } else
1763 if (FDCS->dor & (0x10 << UNIT(current_drive)))
1764 mask &= ~(0x10 << UNIT(current_drive));
1765
1766
1767 del_timer(motor_off_timer + current_drive);
1768 set_dor(fdc, mask, data);
1769
1770
1771 return(wait_for_completion(DRS->select_date+DP->select_delay,
1772 (timeout_fn) function));
1773 }
1774
1775 static void floppy_ready(void)
1776 {
1777 CHECK_RESET;
1778 if (start_motor(floppy_ready)) return;
1779 if (fdc_dtr()) return;
1780
1781 #ifdef DCL_DEBUG
1782 if (DP->flags & FD_DEBUG){
1783 DPRINT("calling disk change from floppy_ready\n");
1784 }
1785 #endif
1786
1787 if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) &&
1788 disk_change(current_drive) &&
1789 !DP->select_delay)
1790 twaddle();
1791
1792
1793 if (raw_cmd->flags & (FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK)){
1794 perpendicular_mode();
1795 fdc_specify();
1796 seek_floppy();
1797 } else
1798 setup_rw_floppy();
1799 }
1800
1801 static void floppy_start(void)
1802 {
1803 reschedule_timeout(CURRENTD, "floppy start", 0);
1804
1805 scandrives();
1806 #ifdef DCL_DEBUG
1807 if (DP->flags & FD_DEBUG){
1808 DPRINT("setting NEWCHANGE in floppy_start\n");
1809 }
1810 #endif
1811 SETF(FD_DISK_NEWCHANGE);
1812 floppy_ready();
1813 }
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829 static void do_wakeup(void)
1830 {
1831 reschedule_timeout(MAXTIMEOUT, "do wakeup", 0);
1832 cont = 0;
1833 command_status += 2;
1834 wake_up(&command_done);
1835 }
1836
1837 static struct cont_t wakeup_cont={
1838 empty,
1839 do_wakeup,
1840 empty,
1841 (done_f)empty
1842 };
1843
1844 static int wait_til_done(void (*handler)(void), int interruptible)
1845 {
1846 int ret;
1847
1848 floppy_tq.routine = (void *)(void *) handler;
1849 queue_task(&floppy_tq, &tq_timer);
1850
1851 cli();
1852 while(command_status < 2 && NO_SIGNAL){
1853 is_alive("wait_til_done");
1854 if (interruptible)
1855 interruptible_sleep_on(&command_done);
1856 else
1857 sleep_on(&command_done);
1858 }
1859 if (command_status < 2){
1860 floppy_shutdown();
1861 sti();
1862 process_fd_request();
1863 return -EINTR;
1864 }
1865 sti();
1866
1867 if (FDCS->reset)
1868 command_status = FD_COMMAND_ERROR;
1869 if (command_status == FD_COMMAND_OKAY)
1870 ret=0;
1871 else
1872 ret=-EIO;
1873 command_status = FD_COMMAND_NONE;
1874 return ret;
1875 }
1876
1877 static void generic_done(int result)
1878 {
1879 command_status = result;
1880 cont = &wakeup_cont;
1881 }
1882
1883 static void generic_success(void)
1884 {
1885 cont->done(1);
1886 }
1887
1888 static void generic_failure(void)
1889 {
1890 cont->done(0);
1891 }
1892
1893 static void success_and_wakeup(void)
1894 {
1895 generic_success();
1896 cont->redo();
1897 }
1898
1899
1900
1901
1902
1903
1904
1905 static int next_valid_format(void)
1906 {
1907 int probed_format;
1908
1909 probed_format = DRS->probed_format;
1910 while(1){
1911 if (probed_format >= 8 ||
1912 !DP->autodetect[probed_format]){
1913 DRS->probed_format = 0;
1914 return 1;
1915 }
1916 if (floppy_type[DP->autodetect[probed_format]].sect){
1917 DRS->probed_format = probed_format;
1918 return 0;
1919 }
1920 probed_format++;
1921 }
1922 }
1923
1924 static void bad_flp_intr(void)
1925 {
1926 if (probing){
1927 DRS->probed_format++;
1928 if (!next_valid_format())
1929 return;
1930 }
1931 (*errors)++;
1932 INFBOUND(DRWE->badness, *errors);
1933 if (*errors > DP->max_errors.abort)
1934 cont->done(0);
1935 if (*errors > DP->max_errors.reset)
1936 FDCS->reset = 1;
1937 else if (*errors > DP->max_errors.recal)
1938 DRS->track = NEED_2_RECAL;
1939 }
1940
1941 static void set_floppy(kdev_t device)
1942 {
1943 if (TYPE(device))
1944 floppy = TYPE(device) + floppy_type;
1945 else
1946 floppy = current_type[ DRIVE(device) ];
1947 }
1948
1949
1950
1951
1952
1953 static void format_interrupt(void)
1954 {
1955 switch (interpret_errors()){
1956 case 1:
1957 cont->error();
1958 case 2:
1959 break;
1960 case 0:
1961 cont->done(1);
1962 }
1963 cont->redo();
1964 }
1965
1966 #define CODE2SIZE (ssize = ((1 << SIZECODE) + 3) >> 2)
1967 #define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80) >>1))
1968 #define CT(x) ((x) | 0x40)
1969 static void setup_format_params(int track)
1970 {
1971 struct fparm {
1972 unsigned char track,head,sect,size;
1973 } *here = (struct fparm *)floppy_track_buffer;
1974 int il,n;
1975 int count,head_shift,track_shift;
1976
1977 raw_cmd = &default_raw_cmd;
1978 raw_cmd->track = track;
1979
1980 raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
1981 FD_RAW_NEED_SEEK;
1982 raw_cmd->rate = floppy->rate & 0x3;
1983 raw_cmd->cmd_count = NR_F;
1984 COMMAND = FM_MODE(floppy,FD_FORMAT);
1985 DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,format_req.head);
1986 F_SIZECODE = FD_SIZECODE(floppy);
1987 F_SECT_PER_TRACK = floppy->sect << 2 >> F_SIZECODE;
1988 F_GAP = floppy->fmt_gap;
1989 F_FILL = FD_FILL_BYTE;
1990
1991 raw_cmd->kernel_data = floppy_track_buffer;
1992 raw_cmd->length = 4 * F_SECT_PER_TRACK;
1993
1994
1995 head_shift = (F_SECT_PER_TRACK + 5) / 6;
1996
1997
1998 track_shift = 2 * head_shift + 3;
1999
2000
2001 n = (track_shift * format_req.track + head_shift * format_req.head)
2002 % F_SECT_PER_TRACK;
2003
2004
2005 il = 1;
2006 if (floppy->sect > DP->interleave_sect && F_SIZECODE == 2)
2007 il++;
2008
2009
2010 for (count = 0; count < F_SECT_PER_TRACK; ++count) {
2011 here[count].track = format_req.track;
2012 here[count].head = format_req.head;
2013 here[count].sect = 0;
2014 here[count].size = F_SIZECODE;
2015 }
2016
2017 for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
2018 here[n].sect = count;
2019 n = (n+il) % F_SECT_PER_TRACK;
2020 if (here[n].sect) {
2021 ++n;
2022 if (n>= F_SECT_PER_TRACK) {
2023 n-=F_SECT_PER_TRACK;
2024 while (here[n].sect) ++n;
2025 }
2026 }
2027 }
2028 }
2029
2030 static void redo_format(void)
2031 {
2032 buffer_track = -1;
2033 setup_format_params(format_req.track << STRETCH(floppy));
2034 floppy_start();
2035 #ifdef DEBUGT
2036 debugt("queue format request");
2037 #endif
2038 }
2039
2040 static struct cont_t format_cont={
2041 format_interrupt,
2042 redo_format,
2043 bad_flp_intr,
2044 generic_done };
2045
2046 static int do_format(kdev_t device, struct format_descr *tmp_format_req)
2047 {
2048 int ret;
2049 int drive=DRIVE(device);
2050
2051 LOCK_FDC(drive,1);
2052 set_floppy(device);
2053 if (!floppy ||
2054 floppy->track > DP->tracks ||
2055 tmp_format_req->track >= floppy->track ||
2056 tmp_format_req->head >= floppy->head ||
2057 (floppy->sect << 2) % (1 << FD_SIZECODE(floppy)) ||
2058 !floppy->fmt_gap) {
2059 process_fd_request();
2060 return -EINVAL;
2061 }
2062 format_req = *tmp_format_req;
2063 format_errors = 0;
2064 cont = &format_cont;
2065 errors = &format_errors;
2066 IWAIT(redo_format);
2067 process_fd_request();
2068 return ret;
2069 }
2070
2071
2072
2073
2074
2075
2076
2077
2078 static void request_done(int uptodate)
2079 {
2080 int block;
2081
2082 probing = 0;
2083 reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
2084
2085 if (!CURRENT){
2086 DPRINT("request list destroyed in floppy request done\n");
2087 return;
2088 }
2089 if (uptodate){
2090
2091
2092 block = current_count_sectors + CURRENT->sector;
2093 INFBOUND(DRS->maxblock, block);
2094 if (block > floppy->sect)
2095 DRS->maxtrack = 1;
2096
2097
2098 while (current_count_sectors && CURRENT &&
2099 current_count_sectors >= CURRENT->current_nr_sectors){
2100 current_count_sectors -= CURRENT->current_nr_sectors;
2101 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
2102 CURRENT->sector += CURRENT->current_nr_sectors;
2103 end_request(1);
2104 }
2105 if (current_count_sectors && CURRENT){
2106
2107 CURRENT->buffer += current_count_sectors <<9;
2108 CURRENT->current_nr_sectors -= current_count_sectors;
2109 CURRENT->nr_sectors -= current_count_sectors;
2110 CURRENT->sector += current_count_sectors;
2111 return;
2112 }
2113
2114 if (current_count_sectors && !CURRENT)
2115 DPRINT("request list destroyed in floppy request done\n");
2116
2117 } else {
2118 if (CURRENT->cmd == WRITE) {
2119
2120 DRWE->write_errors++;
2121 if (DRWE->write_errors == 1) {
2122 DRWE->first_error_sector = CURRENT->sector;
2123 DRWE->first_error_generation = DRS->generation;
2124 }
2125 DRWE->last_error_sector = CURRENT->sector;
2126 DRWE->last_error_generation = DRS->generation;
2127 }
2128 end_request(0);
2129 }
2130 }
2131
2132
2133 static void rw_interrupt(void)
2134 {
2135 int nr_sectors, ssize;
2136
2137 if (!DRS->first_read_date)
2138 DRS->first_read_date = jiffies;
2139
2140 nr_sectors = 0;
2141 CODE2SIZE;
2142 nr_sectors = ((R_TRACK-TRACK)*floppy->head+R_HEAD-HEAD) *
2143 floppy->sect + ((R_SECTOR-SECTOR) << SIZECODE >> 2) -
2144 (sector_t % floppy->sect) % ssize;
2145
2146 #ifdef FLOPPY_SANITY_CHECK
2147 if (nr_sectors > current_count_sectors + ssize -
2148 (current_count_sectors + sector_t) % ssize +
2149 sector_t % ssize){
2150 DPRINT2("long rw: %x instead of %lx\n",
2151 nr_sectors, current_count_sectors);
2152 printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
2153 printk("rh=%d h=%d\n", R_HEAD, HEAD);
2154 printk("rt=%d t=%d\n", R_TRACK, TRACK);
2155 printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
2156 sector_t, ssize);
2157 }
2158 #endif
2159 INFBOUND(nr_sectors,0);
2160 SUPBOUND(current_count_sectors, nr_sectors);
2161
2162 switch (interpret_errors()){
2163 case 2:
2164 cont->redo();
2165 return;
2166 case 1:
2167 if (!current_count_sectors){
2168 cont->error();
2169 cont->redo();
2170 return;
2171 }
2172 break;
2173 case 0:
2174 if (!current_count_sectors){
2175 cont->redo();
2176 return;
2177 }
2178 current_type[current_drive] = floppy;
2179 floppy_sizes[TOMINOR(current_drive) ]= floppy->size>>1;
2180 break;
2181 }
2182
2183 if (probing) {
2184 if (DP->flags & FTD_MSG)
2185 DPRINT2("Auto-detected floppy type %s in fd%d\n",
2186 floppy->name,current_drive);
2187 current_type[current_drive] = floppy;
2188 floppy_sizes[TOMINOR(current_drive)] = floppy->size >> 1;
2189 probing = 0;
2190 }
2191
2192 if (CT(COMMAND) != FD_READ ||
2193 raw_cmd->kernel_data == CURRENT->buffer){
2194
2195 cont->done(1);
2196 } else if (CT(COMMAND) == FD_READ){
2197 buffer_track = raw_cmd->track;
2198 buffer_drive = current_drive;
2199 INFBOUND(buffer_max, nr_sectors + sector_t);
2200 }
2201 cont->redo();
2202 }
2203
2204
2205 static int buffer_chain_size(void)
2206 {
2207 struct buffer_head *bh;
2208 int size;
2209 char *base;
2210
2211 base = CURRENT->buffer;
2212 size = CURRENT->current_nr_sectors << 9;
2213 bh = CURRENT->bh;
2214
2215 if (bh){
2216 bh = bh->b_reqnext;
2217 while (bh && bh->b_data == base + size){
2218 size += bh->b_size;
2219 bh = bh->b_reqnext;
2220 }
2221 }
2222 return size >> 9;
2223 }
2224
2225
2226 static int transfer_size(int ssize, int max_sector, int max_size)
2227 {
2228 SUPBOUND(max_sector, sector_t + max_size);
2229
2230
2231 max_sector -= (max_sector % floppy->sect) % ssize;
2232
2233
2234 current_count_sectors = max_sector - sector_t ;
2235
2236 return max_sector;
2237 }
2238
2239
2240
2241
2242 static void copy_buffer(int ssize, int max_sector, int max_sector_2)
2243 {
2244 int remaining;
2245 struct buffer_head *bh;
2246 char *buffer, *dma_buffer;
2247 int size;
2248
2249 max_sector = transfer_size(ssize,
2250 minimum(max_sector, max_sector_2),
2251 CURRENT->nr_sectors);
2252
2253 if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
2254 buffer_max > sector_t + CURRENT->nr_sectors)
2255 current_count_sectors = minimum(buffer_max - sector_t,
2256 CURRENT->nr_sectors);
2257
2258 remaining = current_count_sectors << 9;
2259 #ifdef FLOPPY_SANITY_CHECK
2260 if ((remaining >> 9) > CURRENT->nr_sectors &&
2261 CT(COMMAND) == FD_WRITE){
2262 DPRINT("in copy buffer\n");
2263 printk("current_count_sectors=%ld\n", current_count_sectors);
2264 printk("remaining=%d\n", remaining >> 9);
2265 printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
2266 printk("CURRENT->current_nr_sectors=%ld\n",
2267 CURRENT->current_nr_sectors);
2268 printk("max_sector=%d\n", max_sector);
2269 printk("ssize=%d\n", ssize);
2270 }
2271 #endif
2272
2273 buffer_max = maximum(max_sector, buffer_max);
2274
2275 dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
2276
2277 bh = CURRENT->bh;
2278 size = CURRENT->current_nr_sectors << 9;
2279 buffer = CURRENT->buffer;
2280
2281 while (remaining > 0){
2282 SUPBOUND(size, remaining);
2283 #ifdef FLOPPY_SANITY_CHECK
2284 if (dma_buffer + size >
2285 floppy_track_buffer + (max_buffer_sectors << 10) ||
2286 dma_buffer < floppy_track_buffer){
2287 DPRINT1("buffer overrun in copy buffer %d\n",
2288 (int) ((floppy_track_buffer - dma_buffer) >>9));
2289 printk("sector_t=%d buffer_min=%d\n",
2290 sector_t, buffer_min);
2291 printk("current_count_sectors=%ld\n",
2292 current_count_sectors);
2293 if (CT(COMMAND) == FD_READ)
2294 printk("read\n");
2295 if (CT(COMMAND) == FD_READ)
2296 printk("write\n");
2297 break;
2298 }
2299 if (((unsigned long)buffer) % 512)
2300 DPRINT1("%p buffer not aligned\n", buffer);
2301 #endif
2302 if (CT(COMMAND) == FD_READ) {
2303 fd_cacheflush(dma_buffer, size);
2304 memcpy(buffer, dma_buffer, size);
2305 } else {
2306 memcpy(dma_buffer, buffer, size);
2307 fd_cacheflush(dma_buffer, size);
2308 }
2309 remaining -= size;
2310 if (!remaining)
2311 break;
2312
2313 dma_buffer += size;
2314 bh = bh->b_reqnext;
2315 #ifdef FLOPPY_SANITY_CHECK
2316 if (!bh){
2317 DPRINT("bh=null in copy buffer after copy\n");
2318 break;
2319 }
2320 #endif
2321 size = bh->b_size;
2322 buffer = bh->b_data;
2323 }
2324 #ifdef FLOPPY_SANITY_CHECK
2325 if (remaining){
2326 if (remaining > 0)
2327 max_sector -= remaining >> 9;
2328 DPRINT1("weirdness: remaining %d\n", remaining>>9);
2329 }
2330 #endif
2331 }
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343 static int make_raw_rw_request(void)
2344 {
2345 int aligned_sector_t;
2346 int max_sector, max_size, tracksize, ssize;
2347
2348 set_fdc(DRIVE(CURRENT->rq_dev));
2349
2350 raw_cmd = &default_raw_cmd;
2351 raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
2352 FD_RAW_NEED_SEEK;
2353 raw_cmd->cmd_count = NR_RW;
2354 if (CURRENT->cmd == READ){
2355 raw_cmd->flags |= FD_RAW_READ;
2356 COMMAND = FM_MODE(floppy,FD_READ);
2357 } else if (CURRENT->cmd == WRITE){
2358 raw_cmd->flags |= FD_RAW_WRITE;
2359 COMMAND = FM_MODE(floppy,FD_WRITE);
2360 } else {
2361 DPRINT("make_raw_rw_request: unknown command\n");
2362 return 0;
2363 }
2364
2365 max_sector = floppy->sect * floppy->head;
2366
2367 TRACK = CURRENT->sector / max_sector;
2368 sector_t = CURRENT->sector % max_sector;
2369 if (floppy->track && TRACK >= floppy->track)
2370 return 0;
2371 HEAD = sector_t / floppy->sect;
2372
2373 if (((floppy->stretch & FD_SWAPSIDES) || TESTF(FD_NEED_TWADDLE)) &&
2374 sector_t < floppy->sect)
2375 max_sector = floppy->sect;
2376
2377
2378 if ((floppy->rate & FD_2M) && (!TRACK) && (!HEAD)){
2379 max_sector = 2 * floppy->sect / 3;
2380 if (sector_t >= max_sector){
2381 current_count_sectors = minimum(floppy->sect - sector_t,
2382 CURRENT->nr_sectors);
2383 return 1;
2384 }
2385 SIZECODE = 2;
2386 } else
2387 SIZECODE = FD_SIZECODE(floppy);
2388 raw_cmd->rate = floppy->rate & 3;
2389 if ((floppy->rate & FD_2M) &&
2390 (TRACK || HEAD) &&
2391 raw_cmd->rate == 2)
2392 raw_cmd->rate = 1;
2393
2394 if (SIZECODE)
2395 SIZECODE2 = 0xff;
2396 else
2397 SIZECODE2 = 0x80;
2398 raw_cmd->track = TRACK << STRETCH(floppy);
2399 DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,HEAD);
2400 GAP = floppy->gap;
2401 CODE2SIZE;
2402 SECT_PER_TRACK = floppy->sect << 2 >> SIZECODE;
2403 SECTOR = ((sector_t % floppy->sect) << 2 >> SIZECODE) + 1;
2404 tracksize = floppy->sect - floppy->sect % ssize;
2405 if (tracksize < floppy->sect){
2406 SECT_PER_TRACK ++;
2407 if (tracksize <= sector_t % floppy->sect)
2408 SECTOR--;
2409 while (tracksize <= sector_t % floppy->sect){
2410 while(tracksize + ssize > floppy->sect){
2411 SIZECODE--;
2412 ssize >>= 1;
2413 }
2414 SECTOR++; SECT_PER_TRACK ++;
2415 tracksize += ssize;
2416 }
2417 max_sector = HEAD * floppy->sect + tracksize;
2418 } else if (!TRACK && !HEAD && !(floppy->rate & FD_2M) && probing)
2419 max_sector = floppy->sect;
2420
2421 aligned_sector_t = sector_t - (sector_t % floppy->sect) % ssize;
2422 max_size = CURRENT->nr_sectors;
2423 if ((raw_cmd->track == buffer_track) &&
2424 (current_drive == buffer_drive) &&
2425 (sector_t >= buffer_min) && (sector_t < buffer_max)) {
2426
2427 if (CT(COMMAND) == FD_READ) {
2428 copy_buffer(1, max_sector, buffer_max);
2429 return 1;
2430 }
2431 } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
2432 if (CT(COMMAND) == FD_WRITE){
2433 if (sector_t + CURRENT->nr_sectors > ssize &&
2434 sector_t + CURRENT->nr_sectors < ssize + ssize)
2435 max_size = ssize + ssize;
2436 else
2437 max_size = ssize;
2438 }
2439 raw_cmd->flags &= ~FD_RAW_WRITE;
2440 raw_cmd->flags |= FD_RAW_READ;
2441 COMMAND = FM_MODE(floppy,FD_READ);
2442 } else if ((unsigned long)CURRENT->buffer < MAX_DMA_ADDRESS) {
2443 unsigned long dma_limit;
2444 int direct, indirect;
2445
2446 indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
2447 sector_t;
2448
2449
2450
2451
2452
2453 max_size = buffer_chain_size();
2454 dma_limit = (MAX_DMA_ADDRESS - ((unsigned long) CURRENT->buffer)) >> 9;
2455 if ((unsigned long) max_size > dma_limit) {
2456 max_size = dma_limit;
2457 }
2458
2459 if (CROSS_64KB(CURRENT->buffer, max_size << 9))
2460 max_size = (K_64 - ((long) CURRENT->buffer) % K_64)>>9;
2461 direct = transfer_size(ssize,max_sector,max_size) - sector_t;
2462
2463
2464
2465
2466
2467
2468
2469 if (!direct ||
2470 (indirect * 2 > direct * 3 &&
2471 *errors < DP->max_errors.read_track &&
2472
2473 ((!probing || (DP->read_track&(1<<DRS->probed_format)))))){
2474 max_size = CURRENT->nr_sectors;
2475 } else {
2476 raw_cmd->kernel_data = CURRENT->buffer;
2477 raw_cmd->length = current_count_sectors << 9;
2478 if (raw_cmd->length == 0){
2479 DPRINT("zero dma transfer attempted from make_raw_request\n");
2480 DPRINT3("indirect=%d direct=%d sector_t=%d",
2481 indirect, direct, sector_t);
2482 return 0;
2483 }
2484 return 2;
2485 }
2486 }
2487
2488 if (CT(COMMAND) == FD_READ)
2489 max_size = max_sector;
2490
2491
2492 if (buffer_track != raw_cmd->track ||
2493 buffer_drive !=current_drive ||
2494 sector_t > buffer_max ||
2495 sector_t < buffer_min ||
2496 ((CT(COMMAND) == FD_READ ||
2497 (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize))&&
2498 max_sector > 2 * max_buffer_sectors + buffer_min &&
2499 max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
2500 ){
2501 buffer_track = -1;
2502 buffer_drive = current_drive;
2503 buffer_max = buffer_min = aligned_sector_t;
2504 }
2505 raw_cmd->kernel_data = floppy_track_buffer +
2506 ((aligned_sector_t-buffer_min)<<9);
2507
2508 if (CT(COMMAND) == FD_WRITE){
2509
2510
2511
2512
2513 #ifdef FLOPPY_SANITY_CHECK
2514 if (sector_t != aligned_sector_t && buffer_track == -1)
2515 DPRINT("internal error offset !=0 on write\n");
2516 #endif
2517 buffer_track = raw_cmd->track;
2518 buffer_drive = current_drive;
2519 copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min);
2520 } else
2521 transfer_size(ssize, max_sector,
2522 2*max_buffer_sectors+buffer_min-aligned_sector_t);
2523
2524
2525 raw_cmd->length = sector_t+current_count_sectors-aligned_sector_t;
2526 raw_cmd->length = ((raw_cmd->length -1)|(ssize-1))+1;
2527 raw_cmd->length <<= 9;
2528 #ifdef FLOPPY_SANITY_CHECK
2529 if ((raw_cmd->length < current_count_sectors << 9) ||
2530 (raw_cmd->kernel_data != CURRENT->buffer &&
2531 CT(COMMAND) == FD_WRITE &&
2532 (aligned_sector_t + (raw_cmd->length >> 9) > buffer_max ||
2533 aligned_sector_t < buffer_min)) ||
2534 raw_cmd->length % (128 << SIZECODE) ||
2535 raw_cmd->length <= 0 || current_count_sectors <= 0){
2536 DPRINT2("fractionary current count b=%lx s=%lx\n",
2537 raw_cmd->length, current_count_sectors);
2538 if (raw_cmd->kernel_data != CURRENT->buffer)
2539 printk("addr=%d, length=%ld\n",
2540 (int) ((raw_cmd->kernel_data -
2541 floppy_track_buffer) >> 9),
2542 current_count_sectors);
2543 printk("st=%d ast=%d mse=%d msi=%d\n",
2544 sector_t, aligned_sector_t, max_sector, max_size);
2545 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2546 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2547 COMMAND, SECTOR, HEAD, TRACK);
2548 printk("buffer drive=%d\n", buffer_drive);
2549 printk("buffer track=%d\n", buffer_track);
2550 printk("buffer_min=%d\n", buffer_min);
2551 printk("buffer_max=%d\n", buffer_max);
2552 return 0;
2553 }
2554
2555 if (raw_cmd->kernel_data != CURRENT->buffer){
2556 if (raw_cmd->kernel_data < floppy_track_buffer ||
2557 current_count_sectors < 0 ||
2558 raw_cmd->length < 0 ||
2559 raw_cmd->kernel_data + raw_cmd->length >
2560 floppy_track_buffer + (max_buffer_sectors << 10)){
2561 DPRINT("buffer overrun in schedule dma\n");
2562 printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2563 sector_t, buffer_min,
2564 raw_cmd->length >> 9);
2565 printk("current_count_sectors=%ld\n",
2566 current_count_sectors);
2567 if (CT(COMMAND) == FD_READ)
2568 printk("read\n");
2569 if (CT(COMMAND) == FD_READ)
2570 printk("write\n");
2571 return 0;
2572 }
2573 } else if (raw_cmd->length > CURRENT->nr_sectors << 9 ||
2574 current_count_sectors > CURRENT->nr_sectors){
2575 DPRINT("buffer overrun in direct transfer\n");
2576 return 0;
2577 } else if (raw_cmd->length < current_count_sectors << 9){
2578 DPRINT("more sectors than bytes\n");
2579 printk("bytes=%ld\n", raw_cmd->length >> 9);
2580 printk("sectors=%ld\n", current_count_sectors);
2581 }
2582 if (raw_cmd->length == 0){
2583 DPRINT("zero dma transfer attempted from make_raw_request\n");
2584 return 0;
2585 }
2586 #endif
2587 return 2;
2588 }
2589
2590 static void redo_fd_request(void)
2591 {
2592 #define REPEAT {request_done(0); continue; }
2593 kdev_t device;
2594 int tmp;
2595
2596 lastredo = jiffies;
2597 if (current_drive < N_DRIVE)
2598 floppy_off(current_drive);
2599
2600 if (CURRENT && CURRENT->rq_status == RQ_INACTIVE){
2601 DPRINT("current not active!\n");
2602 return;
2603 }
2604
2605 while(1){
2606 if (!CURRENT) {
2607 CLEAR_INTR;
2608 unlock_fdc();
2609 return;
2610 }
2611 if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
2612 panic(DEVICE_NAME ": request list destroyed");
2613 if (CURRENT->bh && !CURRENT->bh->b_lock)
2614 panic(DEVICE_NAME ": block not locked");
2615
2616 device = CURRENT->rq_dev;
2617 set_fdc(DRIVE(device));
2618 reschedule_timeout(CURRENTD, "redo fd request", 0);
2619
2620 set_floppy(device);
2621 raw_cmd = & default_raw_cmd;
2622 raw_cmd->flags = 0;
2623 if (start_motor(redo_fd_request)) return;
2624 if (test_bit(current_drive, &fake_change) ||
2625 TESTF(FD_DISK_CHANGED)){
2626 DPRINT("disk absent or changed during operation\n");
2627 REPEAT;
2628 }
2629 if (!floppy) {
2630 if (!probing){
2631 DRS->probed_format = 0;
2632 if (next_valid_format()){
2633 DPRINT("no autodetectable formats\n");
2634 floppy = NULL;
2635 REPEAT;
2636 }
2637 }
2638 probing = 1;
2639 floppy = floppy_type+DP->autodetect[DRS->probed_format];
2640 } else
2641 probing = 0;
2642 errors = & (CURRENT->errors);
2643 tmp = make_raw_rw_request();
2644 if (tmp < 2){
2645 request_done(tmp);
2646 continue;
2647 }
2648
2649 if (TESTF(FD_NEED_TWADDLE))
2650 twaddle();
2651 floppy_tq.routine = (void *)(void *) floppy_start;
2652 queue_task(&floppy_tq, &tq_timer);
2653 #ifdef DEBUGT
2654 debugt("queue fd request");
2655 #endif
2656 return;
2657 }
2658 #undef REPEAT
2659 }
2660
2661 static struct cont_t rw_cont={
2662 rw_interrupt,
2663 redo_fd_request,
2664 bad_flp_intr,
2665 request_done };
2666
2667 static struct tq_struct request_tq =
2668 { 0, 0, (void *) (void *) redo_fd_request, 0 };
2669
2670 static void process_fd_request(void)
2671 {
2672 cont = &rw_cont;
2673 queue_task(&request_tq, &tq_timer);
2674 }
2675
2676 static void do_fd_request(void)
2677 {
2678 if (fdc_busy){
2679
2680
2681 is_alive("do fd request, old request running");
2682 return;
2683 }
2684 lock_fdc(MAXTIMEOUT,0);
2685 process_fd_request();
2686 is_alive("do fd request");
2687 }
2688
2689 static struct cont_t poll_cont={
2690 success_and_wakeup,
2691 floppy_ready,
2692 generic_failure,
2693 generic_done };
2694
2695 static int poll_drive(int interruptible, int flag)
2696 {
2697 int ret;
2698
2699 raw_cmd = &default_raw_cmd;
2700 raw_cmd->flags= flag;
2701 raw_cmd->track=0;
2702 raw_cmd->cmd_count=0;
2703 cont = &poll_cont;
2704 #ifdef DCL_DEBUG
2705 if (DP->flags & FD_DEBUG){
2706 DPRINT("setting NEWCHANGE in poll_drive\n");
2707 }
2708 #endif
2709 SETF(FD_DISK_NEWCHANGE);
2710 WAIT(floppy_ready);
2711 return ret;
2712 }
2713
2714
2715
2716
2717
2718
2719 static void reset_intr(void)
2720 {
2721 printk("weird, reset interrupt called\n");
2722 }
2723
2724 static struct cont_t reset_cont={
2725 reset_intr,
2726 success_and_wakeup,
2727 generic_failure,
2728 generic_done };
2729
2730 static int user_reset_fdc(int drive, int arg, int interruptible)
2731 {
2732 int ret;
2733
2734 ret=0;
2735 LOCK_FDC(drive,interruptible);
2736 if (arg == FD_RESET_ALWAYS)
2737 FDCS->reset=1;
2738 if (FDCS->reset){
2739 cont = &reset_cont;
2740 WAIT(reset_fdc);
2741 }
2742 process_fd_request();
2743 return ret;
2744 }
2745
2746
2747
2748
2749
2750 static int fd_copyout(void *param, const void *address, int size)
2751 {
2752 int ret;
2753
2754 ECALL(verify_area(VERIFY_WRITE,param,size));
2755 fd_cacheflush(address, size);
2756
2757
2758 memcpy_tofs(param,(void *) address, size);
2759 return 0;
2760 }
2761
2762 static int fd_copyin(void *param, void *address, int size)
2763 {
2764 int ret;
2765
2766 ECALL(verify_area(VERIFY_READ,param,size));
2767 memcpy_fromfs((void *) address, param, size);
2768 return 0;
2769 }
2770
2771 #define COPYOUT(x) ECALL(fd_copyout((void *)param, &(x), sizeof(x)))
2772 #define COPYIN(x) ECALL(fd_copyin((void *)param, &(x), sizeof(x)))
2773
2774 static inline const char *drive_name(int type, int drive)
2775 {
2776 struct floppy_struct *floppy;
2777
2778 if (type)
2779 floppy = floppy_type + type;
2780 else {
2781 if (UDP->native_format)
2782 floppy = floppy_type + UDP->native_format;
2783 else
2784 return "(null)";
2785 }
2786 if (floppy->name)
2787 return floppy->name;
2788 else
2789 return "(null)";
2790 }
2791
2792
2793
2794 static void raw_cmd_done(int flag)
2795 {
2796 int i;
2797
2798 if (!flag) {
2799 raw_cmd->flags = FD_RAW_FAILURE;
2800 raw_cmd->flags |= FD_RAW_HARDFAILURE;
2801 } else {
2802 raw_cmd->reply_count = inr;
2803 for (i=0; i< raw_cmd->reply_count; i++)
2804 raw_cmd->reply[i] = reply_buffer[i];
2805
2806 if (raw_cmd->flags & (FD_RAW_READ | FD_RAW_WRITE))
2807 raw_cmd->length = get_dma_residue(FLOPPY_DMA);
2808
2809 if ((raw_cmd->flags & FD_RAW_SOFTFAILURE) &&
2810 (!raw_cmd->reply_count || (raw_cmd->reply[0] & 0xc0)))
2811 raw_cmd->flags |= FD_RAW_FAILURE;
2812
2813 if (disk_change(current_drive))
2814 raw_cmd->flags |= FD_RAW_DISK_CHANGE;
2815 else
2816 raw_cmd->flags &= ~FD_RAW_DISK_CHANGE;
2817 if (raw_cmd->flags & FD_RAW_NO_MOTOR_AFTER)
2818 motor_off_callback(current_drive);
2819
2820 if (raw_cmd->next &&
2821 (!(raw_cmd->flags & FD_RAW_FAILURE) ||
2822 !(raw_cmd->flags & FD_RAW_STOP_IF_FAILURE)) &&
2823 ((raw_cmd->flags & FD_RAW_FAILURE) ||
2824 !(raw_cmd->flags &FD_RAW_STOP_IF_SUCCESS))) {
2825 raw_cmd = raw_cmd->next;
2826 return;
2827 }
2828 }
2829 generic_done(flag);
2830 }
2831
2832
2833 static struct cont_t raw_cmd_cont={
2834 success_and_wakeup,
2835 floppy_start,
2836 generic_failure,
2837 raw_cmd_done
2838 };
2839
2840 static inline int raw_cmd_copyout(int cmd, char *param,
2841 struct floppy_raw_cmd *ptr)
2842 {
2843 struct old_floppy_raw_cmd old_raw_cmd;
2844 int ret;
2845
2846 while(ptr) {
2847 if (cmd == OLDFDRAWCMD) {
2848 old_raw_cmd.flags = ptr->flags;
2849 old_raw_cmd.data = ptr->data;
2850 old_raw_cmd.length = ptr->length;
2851 old_raw_cmd.rate = ptr->rate;
2852 old_raw_cmd.reply_count = ptr->reply_count;
2853 memcpy(old_raw_cmd.reply, ptr->reply, 7);
2854 COPYOUT(old_raw_cmd);
2855 param += sizeof(old_raw_cmd);
2856 } else {
2857 COPYOUT(*ptr);
2858 param += sizeof(struct floppy_raw_cmd);
2859 }
2860
2861 if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length){
2862 if (ptr->length>=0 && ptr->length<=ptr->buffer_length)
2863 ECALL(fd_copyout(ptr->data,
2864 ptr->kernel_data,
2865 ptr->buffer_length -
2866 ptr->length));
2867 }
2868 ptr = ptr->next;
2869 }
2870 return 0;
2871 }
2872
2873
2874 static void raw_cmd_free(struct floppy_raw_cmd **ptr)
2875 {
2876 struct floppy_raw_cmd *next,*this;
2877
2878 this = *ptr;
2879 *ptr = 0;
2880 while(this) {
2881 if (this->buffer_length) {
2882 free_pages((unsigned long)this->kernel_data,
2883 __get_order(this->buffer_length));
2884 this->buffer_length = 0;
2885 }
2886 next = this->next;
2887 kfree(this);
2888 this = next;
2889 }
2890 }
2891
2892
2893 static inline int raw_cmd_copyin(int cmd, char *param,
2894 struct floppy_raw_cmd **rcmd)
2895 {
2896 struct floppy_raw_cmd *ptr;
2897 struct old_floppy_raw_cmd old_raw_cmd;
2898 int ret;
2899 int i;
2900
2901 *rcmd = 0;
2902 while(1) {
2903 ptr = (struct floppy_raw_cmd *)
2904 kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER);
2905 if (!ptr)
2906 return -ENOMEM;
2907 *rcmd = ptr;
2908 if (cmd == OLDFDRAWCMD){
2909 COPYIN(old_raw_cmd);
2910 ptr->flags = old_raw_cmd.flags;
2911 ptr->data = old_raw_cmd.data;
2912 ptr->length = old_raw_cmd.length;
2913 ptr->rate = old_raw_cmd.rate;
2914 ptr->cmd_count = old_raw_cmd.cmd_count;
2915 ptr->track = old_raw_cmd.track;
2916 ptr->phys_length = 0;
2917 ptr->next = 0;
2918 ptr->buffer_length = 0;
2919 memcpy(ptr->cmd, old_raw_cmd.cmd, 9);
2920 param += sizeof(struct old_floppy_raw_cmd);
2921 if (ptr->cmd_count > 9)
2922 return -EINVAL;
2923 } else {
2924 COPYIN(*ptr);
2925 ptr->next = 0;
2926 ptr->buffer_length = 0;
2927 param += sizeof(struct floppy_raw_cmd);
2928 if (ptr->cmd_count > 16)
2929 return -EINVAL;
2930 }
2931
2932 for (i=0; i< 16; i++)
2933 ptr->reply[i] = 0;
2934 ptr->resultcode = 0;
2935 ptr->kernel_data = 0;
2936
2937 if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
2938 if (ptr->length <= 0)
2939 return -EINVAL;
2940 ptr->kernel_data =(char*)dma_mem_alloc(ptr->length);
2941 if (!ptr->kernel_data)
2942 return -ENOMEM;
2943 ptr->buffer_length = ptr->length;
2944 }
2945 if ( ptr->flags & FD_RAW_READ )
2946 ECALL( verify_area( VERIFY_WRITE, ptr->data,
2947 ptr->length ));
2948 if (ptr->flags & FD_RAW_WRITE)
2949 ECALL(fd_copyin(ptr->data, ptr->kernel_data,
2950 ptr->length));
2951 rcmd = & (ptr->next);
2952 if (!(ptr->flags & FD_RAW_MORE))
2953 return 0;
2954 ptr->rate &= 0x03;
2955 }
2956 }
2957
2958
2959 static int raw_cmd_ioctl(int cmd, void *param)
2960 {
2961 int drive, ret, ret2;
2962 struct floppy_raw_cmd *my_raw_cmd;
2963
2964 if (FDCS->rawcmd <= 1)
2965 FDCS->rawcmd = 1;
2966 for (drive= 0; drive < N_DRIVE; drive++){
2967 if (FDC(drive) != fdc)
2968 continue;
2969 if (drive == current_drive){
2970 if (UDRS->fd_ref > 1){
2971 FDCS->rawcmd = 2;
2972 break;
2973 }
2974 } else if (UDRS->fd_ref){
2975 FDCS->rawcmd = 2;
2976 break;
2977 }
2978 }
2979
2980 if (FDCS->reset)
2981 return -EIO;
2982
2983 ret = raw_cmd_copyin(cmd, param, &my_raw_cmd);
2984 if (ret) {
2985 raw_cmd_free(&my_raw_cmd);
2986 return ret;
2987 }
2988
2989 raw_cmd = my_raw_cmd;
2990 cont = &raw_cmd_cont;
2991 ret=wait_til_done(floppy_start,1);
2992 #ifdef DCL_DEBUG
2993 if (DP->flags & FD_DEBUG){
2994 DPRINT("calling disk change from raw_cmd ioctl\n");
2995 }
2996 #endif
2997
2998 if (ret != -EINTR && FDCS->reset)
2999 ret = -EIO;
3000
3001 DRS->track = NO_TRACK;
3002
3003 ret2 = raw_cmd_copyout(cmd, param, my_raw_cmd);
3004 if (!ret)
3005 ret = ret2;
3006 raw_cmd_free(&my_raw_cmd);
3007 return ret;
3008 }
3009
3010 static int invalidate_drive(kdev_t rdev)
3011 {
3012
3013 set_bit(DRIVE(rdev), &fake_change);
3014 process_fd_request();
3015 check_disk_change(rdev);
3016 return 0;
3017 }
3018
3019
3020 static inline void clear_write_error(int drive)
3021 {
3022 CLEARSTRUCT(UDRWE);
3023 }
3024
3025 static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
3026 int drive, int type, int device)
3027 {
3028 int cnt;
3029
3030
3031 if (g->sect <= 0 ||
3032 g->head <= 0 ||
3033 g->track <= 0 ||
3034 g->track > UDP->tracks>>STRETCH(g) ||
3035
3036 (g->stretch&~(FD_STRETCH|FD_SWAPSIDES)) != 0)
3037 return -EINVAL;
3038 if (type){
3039 if (!suser())
3040 return -EPERM;
3041 LOCK_FDC(drive,1);
3042 for (cnt = 0; cnt < N_DRIVE; cnt++){
3043 if (TYPE(drive_state[cnt].fd_device) == type &&
3044 drive_state[cnt].fd_ref)
3045 set_bit(drive, &fake_change);
3046 }
3047 floppy_type[type] = *g;
3048 floppy_type[type].name="user format";
3049 for (cnt = type << 2; cnt < (type << 2) + 4; cnt++)
3050 floppy_sizes[cnt]= floppy_sizes[cnt+0x80]=
3051 floppy_type[type].size>>1;
3052 process_fd_request();
3053 for (cnt = 0; cnt < N_DRIVE; cnt++){
3054 if (TYPE(drive_state[cnt].fd_device) == type &&
3055 drive_state[cnt].fd_ref)
3056 check_disk_change(
3057 MKDEV(FLOPPY_MAJOR,
3058 drive_state[cnt].fd_device));
3059 }
3060 } else {
3061 LOCK_FDC(drive,1);
3062 if (cmd != FDDEFPRM)
3063
3064
3065 CALL(poll_drive(1,0));
3066 user_params[drive] = *g;
3067 if (buffer_drive == drive)
3068 SUPBOUND(buffer_max, user_params[drive].sect);
3069 current_type[drive] = &user_params[drive];
3070 floppy_sizes[drive] = user_params[drive].size >> 1;
3071 if (cmd == FDDEFPRM)
3072 DRS->keep_data = -1;
3073 else
3074 DRS->keep_data = 1;
3075
3076
3077
3078
3079
3080 if (DRS->maxblock > user_params[drive].sect || DRS->maxtrack)
3081 invalidate_drive(device);
3082 else
3083 process_fd_request();
3084 }
3085 return 0;
3086 }
3087
3088
3089 static struct translation_entry {
3090 int newcmd;
3091 int oldcmd;
3092 int oldsize;
3093
3094 } translation_table[]= {
3095 {FDCLRPRM, 0, 0},
3096 {FDSETPRM, 1, 28},
3097 {FDDEFPRM, 2, 28},
3098 {FDGETPRM, 3, 28},
3099 {FDMSGON, 4, 0},
3100 {FDMSGOFF, 5, 0},
3101 {FDFMTBEG, 6, 0},
3102 {FDFMTTRK, 7, 12},
3103 {FDFMTEND, 8, 0},
3104 {FDSETEMSGTRESH, 10, 0},
3105 {FDFLUSH, 11, 0},
3106 {FDSETMAXERRS, 12, 20},
3107 {OLDFDRAWCMD, 30, 0},
3108 {FDGETMAXERRS, 14, 20},
3109 {FDGETDRVTYP, 16, 16},
3110 {FDSETDRVPRM, 20, 88},
3111 {FDGETDRVPRM, 21, 88},
3112 {FDGETDRVSTAT, 22, 52},
3113 {FDPOLLDRVSTAT, 23, 52},
3114 {FDRESET, 24, 0},
3115 {FDGETFDCSTAT, 25, 40},
3116 {FDWERRORCLR, 27, 0},
3117 {FDWERRORGET, 28, 24},
3118 {FDRAWCMD, 0, 0},
3119 {FDTWADDLE, 40, 0} };
3120
3121 static inline int normalize_0x02xx_ioctl(int *cmd, int *size)
3122 {
3123 int i, orig_size, ocmd;
3124
3125 orig_size = _IOC_SIZE(*cmd);
3126 ocmd = *cmd;
3127 for (i=0; i < ARRAY_SIZE(translation_table); i++) {
3128 if ((*cmd & 0xff3f) == (translation_table[i].newcmd & 0xff3f)){
3129 *cmd = translation_table[i].newcmd;
3130 if (!orig_size && _IOC_SIZE(*cmd)) {
3131
3132 *size = _IOC_SIZE(*cmd);
3133 DPRINT1("warning: obsolete ioctl 0x%x\n",ocmd);
3134 DPRINT("please recompile your program\n");
3135
3136
3137
3138
3139
3140
3141 } else {
3142 *size = orig_size;
3143 if (*size > _IOC_SIZE(*cmd)) {
3144 printk("ioctl not yet supported\n");
3145 return -EFAULT;
3146 }
3147 }
3148 return 0;
3149 }
3150 }
3151 return -EINVAL;
3152 }
3153
3154 static inline int xlate_0x00xx_ioctl(int *cmd, int *size)
3155 {
3156 int i;
3157
3158
3159
3160
3161
3162
3163
3164
3165 for (i=0; i < ARRAY_SIZE(translation_table); i++) {
3166 if (*cmd == translation_table[i].oldcmd) {
3167 *size = translation_table[i].oldsize;
3168 *cmd = translation_table[i].newcmd;
3169 return 0;
3170 }
3171 }
3172 return -EINVAL;
3173 }
3174
3175 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
3176 unsigned long param)
3177 {
3178 #define IOCTL_MODE_BIT 8
3179 #define OPEN_WRITE_BIT 16
3180 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
3181 #define OUT(c,x) case c: outparam = (const char *) (x); break
3182 #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
3183
3184 int i,drive,type;
3185 kdev_t device;
3186 int ret;
3187 int size;
3188 union inparam {
3189 struct floppy_struct g;
3190 struct format_descr f;
3191 struct floppy_max_errors max_errors;
3192 struct floppy_drive_params dp;
3193 } inparam;
3194 const char *outparam;
3195
3196 device = inode->i_rdev;
3197 switch (cmd) {
3198 RO_IOCTLS(device,param);
3199 }
3200 type = TYPE(device);
3201 drive = DRIVE(device);
3202
3203
3204 if ((cmd & 0xff00) == 0x0200) {
3205 ECALL(normalize_0x02xx_ioctl(&cmd, &size));
3206 } else if ((cmd & 0xff00) == 0x0000) {
3207 ECALL(xlate_0x00xx_ioctl(&cmd, &size));
3208 } else
3209 return -EINVAL;
3210
3211
3212 if (((cmd & 0x80) && !suser()) ||
3213 ((cmd & 0x40) && !IOCTL_ALLOWED))
3214 return -EPERM;
3215
3216
3217 if (_IOC_DIR(cmd) & _IOC_READ)
3218 ECALL(verify_area(VERIFY_WRITE,(void *) param, size));
3219
3220
3221 CLEARSTRUCT(&inparam);
3222 if (_IOC_DIR(cmd) & _IOC_WRITE)
3223 ECALL(fd_copyin((void *)param, &inparam, size))
3224
3225 switch (cmd) {
3226 case FDCLRPRM:
3227 LOCK_FDC(drive,1);
3228 current_type[drive] = NULL;
3229 floppy_sizes[drive] = MAX_DISK_SIZE;
3230 UDRS->keep_data = 0;
3231 return invalidate_drive(device);
3232 case FDSETPRM:
3233 case FDDEFPRM:
3234 return set_geometry(cmd, & inparam.g,
3235 drive, type, device);
3236 case FDGETPRM:
3237 if (type)
3238 outparam = (char *) &floppy_type[type];
3239 else
3240 outparam = (char *) current_type[drive];
3241 if(!outparam)
3242 return -ENODEV;
3243 break;
3244
3245 case FDMSGON:
3246 UDP->flags |= FTD_MSG;
3247 return 0;
3248 case FDMSGOFF:
3249 UDP->flags &= ~FTD_MSG;
3250 return 0;
3251
3252 case FDFMTBEG:
3253 return 0;
3254 case FDFMTTRK:
3255 if (UDRS->fd_ref != 1)
3256 return -EBUSY;
3257 return do_format(device, &inparam.f);
3258 case FDFMTEND:
3259 case FDFLUSH:
3260 LOCK_FDC(drive,1);
3261 return invalidate_drive(device);
3262
3263 case FDSETEMSGTRESH:
3264 UDP->max_errors.reporting =
3265 (unsigned short) (param & 0x0f);
3266 return 0;
3267 OUT(FDGETMAXERRS, &UDP->max_errors);
3268 IN(FDSETMAXERRS, &UDP->max_errors, max_errors);
3269
3270 case FDGETDRVTYP:
3271 outparam = drive_name(type,drive);
3272 SUPBOUND(size,strlen(outparam)+1);
3273 break;
3274
3275 IN(FDSETDRVPRM, UDP, dp);
3276 OUT(FDGETDRVPRM, UDP);
3277
3278 case FDPOLLDRVSTAT:
3279 LOCK_FDC(drive,1);
3280 CALL(poll_drive(1, FD_RAW_NEED_DISK));
3281 process_fd_request();
3282
3283 OUT(FDGETDRVSTAT, UDRS);
3284
3285 case FDRESET:
3286 return user_reset_fdc(drive, (int)param, 1);
3287
3288 OUT(FDGETFDCSTAT,UFDCS);
3289
3290 case FDWERRORCLR:
3291 CLEARSTRUCT(UDRWE);
3292 return 0;
3293 OUT(FDWERRORGET,UDRWE);
3294
3295 case OLDFDRAWCMD:
3296 case FDRAWCMD:
3297 if (type)
3298 return -EINVAL;
3299 LOCK_FDC(drive,1);
3300 set_floppy(device);
3301 CALL(i = raw_cmd_ioctl(cmd,(void *) param));
3302 process_fd_request();
3303 return i;
3304
3305 case FDTWADDLE:
3306 LOCK_FDC(drive,1);
3307 twaddle();
3308 process_fd_request();
3309 return 0;
3310
3311 default:
3312 return -EINVAL;
3313 }
3314
3315 if (_IOC_DIR(cmd) & _IOC_READ)
3316 return fd_copyout((void *)param, outparam, size);
3317 else
3318 return 0;
3319 #undef IOCTL_ALLOWED
3320 #undef OUT
3321 #undef IN
3322 }
3323
3324 static void config_types(void)
3325 {
3326 int first=1;
3327 int drive;
3328
3329
3330 drive=0;
3331 if (!UDP->cmos)
3332 UDP->cmos= FLOPPY0_TYPE;
3333 drive=1;
3334 if (!UDP->cmos && FLOPPY1_TYPE)
3335 UDP->cmos = FLOPPY1_TYPE;
3336
3337
3338
3339
3340 for (drive=0; drive < N_DRIVE; drive++){
3341 if (UDP->cmos >= 0 && UDP->cmos <= NUMBER(default_drive_params))
3342 memcpy((char *) UDP,
3343 (char *) (&default_drive_params[(int)UDP->cmos].params),
3344 sizeof(struct floppy_drive_params));
3345 if (UDP->cmos){
3346 if (first)
3347 printk("Floppy drive(s): ");
3348 else
3349 printk(", ");
3350 first=0;
3351 if (UDP->cmos > 0){
3352 allowed_drive_mask |= 1 << drive;
3353 printk("fd%d is %s", drive,
3354 default_drive_params[(int)UDP->cmos].name);
3355 } else
3356 printk("fd%d is unknown type %d",drive,
3357 UDP->cmos);
3358 }
3359 }
3360 if (!first)
3361 printk("\n");
3362 }
3363
3364 static int floppy_read(struct inode * inode, struct file * filp,
3365 char * buf, int count)
3366 {
3367 int drive = DRIVE(inode->i_rdev);
3368
3369 check_disk_change(inode->i_rdev);
3370 if (UTESTF(FD_DISK_CHANGED))
3371 return -ENXIO;
3372 return block_read(inode, filp, buf, count);
3373 }
3374
3375 static int floppy_write(struct inode * inode, struct file * filp,
3376 const char * buf, int count)
3377 {
3378 int block;
3379 int ret;
3380 int drive = DRIVE(inode->i_rdev);
3381
3382 if (!UDRS->maxblock)
3383 UDRS->maxblock=1;
3384 check_disk_change(inode->i_rdev);
3385 if (UTESTF(FD_DISK_CHANGED))
3386 return -ENXIO;
3387 if (!UTESTF(FD_DISK_WRITABLE))
3388 return -EROFS;
3389 block = (filp->f_pos + count) >> 9;
3390 INFBOUND(UDRS->maxblock, block);
3391 ret= block_write(inode, filp, buf, count);
3392 return ret;
3393 }
3394
3395 static void floppy_release(struct inode * inode, struct file * filp)
3396 {
3397 int drive;
3398
3399 drive = DRIVE(inode->i_rdev);
3400
3401 if (!filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
3402
3403
3404 block_fsync(inode,filp);
3405
3406 if (UDRS->fd_ref < 0)
3407 UDRS->fd_ref=0;
3408 else if (!UDRS->fd_ref--) {
3409 DPRINT("floppy_release with fd_ref == 0");
3410 UDRS->fd_ref = 0;
3411 }
3412 floppy_release_irq_and_dma();
3413 }
3414
3415
3416
3417
3418
3419
3420 #define RETERR(x) do{floppy_release(inode,filp); return -(x);}while(0)
3421
3422 static int floppy_open(struct inode * inode, struct file * filp)
3423 {
3424 int drive;
3425 int old_dev;
3426 int try;
3427 char *tmp;
3428
3429 if (!filp) {
3430 DPRINT("Weird, open called with filp=0\n");
3431 return -EIO;
3432 }
3433
3434 drive = DRIVE(inode->i_rdev);
3435 if (drive >= N_DRIVE ||
3436 !(allowed_drive_mask & (1 << drive)) ||
3437 fdc_state[FDC(drive)].version == FDC_NONE)
3438 return -ENXIO;
3439
3440 if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
3441 return -ENXIO;
3442 old_dev = UDRS->fd_device;
3443 if (UDRS->fd_ref && old_dev != MINOR(inode->i_rdev))
3444 return -EBUSY;
3445
3446 if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
3447 USETF(FD_DISK_CHANGED);
3448 USETF(FD_VERIFY);
3449 }
3450
3451 if (UDRS->fd_ref == -1 ||
3452 (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3453 return -EBUSY;
3454
3455 if (floppy_grab_irq_and_dma())
3456 return -EBUSY;
3457
3458 if (filp->f_flags & O_EXCL)
3459 UDRS->fd_ref = -1;
3460 else
3461 UDRS->fd_ref++;
3462
3463 if (!floppy_track_buffer){
3464
3465
3466 if ((UDP->cmos == 6) || (UDP->cmos == 5))
3467 try = 64;
3468 else
3469 try = 32;
3470
3471 tmp=(char *)dma_mem_alloc(1024 * try);
3472 if (!tmp) {
3473 try >>= 1;
3474 INFBOUND(try, 16);
3475 tmp= (char *)dma_mem_alloc(1024*try);
3476 }
3477 if (!tmp) {
3478 DPRINT("Unable to allocate DMA memory\n");
3479 RETERR(ENXIO);
3480 }
3481 if (floppy_track_buffer){
3482 free_pages((unsigned long)tmp,__get_order(try*1024));
3483 }else {
3484 floppy_track_buffer = tmp;
3485 max_buffer_sectors = try;
3486 }
3487 }
3488
3489 UDRS->fd_device = MINOR(inode->i_rdev);
3490 if (old_dev != -1 && old_dev != MINOR(inode->i_rdev)) {
3491 if (buffer_drive == drive)
3492 buffer_track = -1;
3493 invalidate_buffers(MKDEV(FLOPPY_MAJOR,old_dev));
3494 }
3495
3496
3497 if ((filp->f_mode & 2) || (permission(inode,2) == 0))
3498 filp->f_mode |= IOCTL_MODE_BIT;
3499 if (filp->f_mode & 2)
3500 filp->f_mode |= OPEN_WRITE_BIT;
3501
3502 if (UFDCS->rawcmd == 1)
3503 UFDCS->rawcmd = 2;
3504
3505 if (filp->f_flags & O_NDELAY)
3506 return 0;
3507 if (filp->f_mode & 3) {
3508 UDRS->last_checked = 0;
3509 check_disk_change(inode->i_rdev);
3510 if (UTESTF(FD_DISK_CHANGED))
3511 RETERR(ENXIO);
3512 }
3513 if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
3514 RETERR(EROFS);
3515 return 0;
3516 #undef RETERR
3517 }
3518
3519
3520
3521
3522 static int check_floppy_change(kdev_t dev)
3523 {
3524 int drive = DRIVE(dev);
3525
3526 if (MAJOR(dev) != MAJOR_NR) {
3527 DPRINT("floppy_changed: not a floppy\n");
3528 return 0;
3529 }
3530
3531 if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
3532 return 1;
3533
3534 if (UDRS->last_checked + UDP->checkfreq < jiffies){
3535 lock_fdc(drive,0);
3536 poll_drive(0,0);
3537 process_fd_request();
3538 }
3539
3540 if (UTESTF(FD_DISK_CHANGED) ||
3541 UTESTF(FD_VERIFY) ||
3542 test_bit(drive, &fake_change) ||
3543 (!TYPE(dev) && !current_type[drive]))
3544 return 1;
3545 return 0;
3546 }
3547
3548
3549
3550
3551
3552 static int floppy_revalidate(kdev_t dev)
3553 {
3554 #define NO_GEOM (!current_type[drive] && !TYPE(dev))
3555 struct buffer_head * bh;
3556 int drive=DRIVE(dev);
3557 int cf;
3558
3559 if (UTESTF(FD_DISK_CHANGED) ||
3560 UTESTF(FD_VERIFY) ||
3561 test_bit(drive, &fake_change) ||
3562 NO_GEOM){
3563 lock_fdc(drive,0);
3564 cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY);
3565 if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)){
3566 process_fd_request();
3567 return 0;
3568 }
3569 UDRS->maxblock = 0;
3570 UDRS->maxtrack = 0;
3571 if (buffer_drive == drive)
3572 buffer_track = -1;
3573 clear_bit(drive, &fake_change);
3574 UCLEARF(FD_DISK_CHANGED);
3575 if (cf)
3576 UDRS->generation++;
3577 if (NO_GEOM){
3578
3579 int size = floppy_blocksizes[MINOR(dev)];
3580 if (!size)
3581 size = 1024;
3582 if (!(bh = getblk(dev,0,size))){
3583 process_fd_request();
3584 return 1;
3585 }
3586 if (bh && !bh->b_uptodate)
3587 ll_rw_block(READ, 1, &bh);
3588 process_fd_request();
3589 wait_on_buffer(bh);
3590 brelse(bh);
3591 return 0;
3592 }
3593 if (cf)
3594 poll_drive(0, FD_RAW_NEED_DISK);
3595 process_fd_request();
3596 }
3597 return 0;
3598 }
3599
3600 static struct file_operations floppy_fops = {
3601 NULL,
3602 floppy_read,
3603 floppy_write,
3604 NULL,
3605 NULL,
3606 fd_ioctl,
3607 NULL,
3608 floppy_open,
3609 floppy_release,
3610 block_fsync,
3611 NULL,
3612 check_floppy_change,
3613 floppy_revalidate,
3614 };
3615
3616
3617
3618
3619
3620
3621
3622
3623 static char get_fdc_version(void)
3624 {
3625 int r;
3626
3627 output_byte(FD_DUMPREGS);
3628 if (FDCS->reset)
3629 return FDC_NONE;
3630 if ((r = result()) <= 0x00)
3631 return FDC_NONE;
3632 if ((r==1) && (reply_buffer[0] == 0x80)){
3633 printk("FDC %d is a 8272A\n",fdc);
3634 return FDC_8272A;
3635 }
3636 if (r != 10) {
3637 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", 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 init: VERSION: unexpected return of %d bytes.\n", r);
3648 return FDC_UNKNOWN;
3649 }
3650 output_byte(FD_UNLOCK);
3651 r = result();
3652 if ((r == 1) && (reply_buffer[0] == 0x80)){
3653 printk("FDC %d is a pre-1991 82077\n", fdc);
3654 return FDC_82077_ORIG;
3655 }
3656 if ((r != 1) || (reply_buffer[0] != 0x00)) {
3657 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
3658 return FDC_UNKNOWN;
3659 }
3660 printk("FDC %d is a post-1991 82077\n",fdc);
3661 return FDC_82077;
3662 }
3663
3664
3665
3666
3667
3668
3669 void floppy_invert_dcl(int *ints,int param)
3670 {
3671 int i;
3672
3673 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3674 if (param)
3675 default_drive_params[i].params.flags |= 0x80;
3676 else
3677 default_drive_params[i].params.flags &= ~0x80;
3678 }
3679 DPRINT("Configuring drives for inverted dcl\n");
3680 }
3681
3682 static void daring(int *ints,int param)
3683 {
3684 int i;
3685
3686 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3687 if (param){
3688 default_drive_params[i].params.select_delay = 0;
3689 default_drive_params[i].params.flags |= FD_SILENT_DCL_CLEAR;
3690 } else {
3691 default_drive_params[i].params.select_delay = 2*HZ/100;
3692 default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR;
3693 }
3694 }
3695 DPRINT1("Assuming %s floppy hardware\n", param ? "standard" : "broken");
3696 }
3697
3698 static void allow_drives(int *ints, int param)
3699 {
3700 allowed_drive_mask=param;
3701 DPRINT1("setting allowed_drive_mask to 0x%x\n", param);
3702 }
3703
3704 static void fdc2_adr(int *ints, int param)
3705 {
3706 FDC2 = param;
3707 if (param)
3708 DPRINT1("enabling second fdc at address 0x%3x\n", FDC2);
3709 else
3710 DPRINT("disabling second fdc\n");
3711 }
3712
3713 static void unex(int *ints,int param)
3714 {
3715 print_unex = param;
3716 DPRINT1("%sprinting messages for unexpected interrupts\n",
3717 param ? "" : "not ");
3718 }
3719
3720 static void set_cmos(int *ints, int dummy)
3721 {
3722 int current_drive=0;
3723
3724 if (ints[0] != 2){
3725 DPRINT("wrong number of parameter for cmos\n");
3726 return;
3727 }
3728 current_drive = ints[1];
3729 if (current_drive < 0 || current_drive >= 8){
3730 DPRINT("bad drive for set_cmos\n");
3731 return;
3732 }
3733 if (current_drive >= 4 && !FDC2)
3734 fdc2_adr(0, 0x370);
3735 if (ints[2] <= 0 || ints[2] >= NUMBER(default_drive_params)){
3736 DPRINT1("bad cmos code %d\n", ints[2]);
3737 return;
3738 }
3739 DP->cmos = ints[2];
3740 DPRINT1("setting cmos code to %d\n", ints[2]);
3741 }
3742
3743 static struct param_table {
3744 const char *name;
3745 void (*fn)(int *ints, int param);
3746 int def_param;
3747 } config_params[]={
3748 { "allowed_drive_mask", allow_drives, 0xff },
3749 { "all_drives", allow_drives, 0xff },
3750 { "asus_pci", allow_drives, 0x33 },
3751
3752 { "daring", daring, 1},
3753
3754 { "two_fdc", fdc2_adr, 0x370 },
3755 { "one_fdc", fdc2_adr, 0 },
3756
3757 { "thinkpad", floppy_invert_dcl, 1 },
3758
3759 { "cmos", set_cmos, 0 },
3760
3761 { "unexpected_interrupts", unex, 1 },
3762 { "no_unexpected_interrupts", unex, 0 },
3763 { "L40SX", unex, 0 } };
3764
3765 #define FLOPPY_SETUP
3766 void floppy_setup(char *str, int *ints)
3767 {
3768 int i;
3769 int param;
3770 if (str)
3771 for (i=0; i< ARRAY_SIZE(config_params); i++){
3772 if (strcmp(str,config_params[i].name) == 0){
3773 if (ints[0])
3774 param = ints[1];
3775 else
3776 param = config_params[i].def_param;
3777 config_params[i].fn(ints,param);
3778 return;
3779 }
3780 }
3781 if (str) {
3782 DPRINT1("unknown floppy option [%s]\n", str);
3783
3784 DPRINT("allowed options are:");
3785 for (i=0; i< ARRAY_SIZE(config_params); i++)
3786 printk(" %s",config_params[i].name);
3787 printk("\n");
3788 } else
3789 DPRINT("botched floppy option\n");
3790 DPRINT("Read linux/drivers/block/README.fd\n");
3791 }
3792
3793 int floppy_init(void)
3794 {
3795 int i,unit,drive;
3796 int have_no_fdc= -EIO;
3797
3798 raw_cmd = 0;
3799
3800 sti();
3801
3802 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
3803 printk("Unable to get major %d for floppy\n",MAJOR_NR);
3804 return -EBUSY;
3805 }
3806
3807 for (i=0; i<256; i++)
3808 if (TYPE(i))
3809 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
3810 else
3811 floppy_sizes[i] = MAX_DISK_SIZE;
3812
3813 blk_size[MAJOR_NR] = floppy_sizes;
3814 blksize_size[MAJOR_NR] = floppy_blocksizes;
3815 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3816 reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
3817 config_types();
3818
3819 for (i = 0; i < N_FDC; i++) {
3820 fdc = i;
3821 CLEARSTRUCT(FDCS);
3822 FDCS->dtr = -1;
3823 FDCS->dor = 0x4;
3824 }
3825
3826 fdc_state[0].address = FDC1;
3827 #if N_FDC > 1
3828 fdc_state[1].address = FDC2;
3829 #endif
3830
3831 if (floppy_grab_irq_and_dma()){
3832 unregister_blkdev(MAJOR_NR,"fd");
3833 return -EBUSY;
3834 }
3835
3836
3837 for (drive = 0; drive < N_DRIVE; drive++) {
3838 CLEARSTRUCT(UDRS);
3839 CLEARSTRUCT(UDRWE);
3840 UDRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE | FD_DISK_CHANGED;
3841 UDRS->fd_device = -1;
3842 floppy_track_buffer = NULL;
3843 max_buffer_sectors = 0;
3844 }
3845
3846 for (i = 0; i < N_FDC; i++) {
3847 fdc = i;
3848 FDCS->driver_version = FD_DRIVER_VERSION;
3849 for (unit=0; unit<4; unit++)
3850 FDCS->track[unit] = 0;
3851 if (FDCS->address == -1)
3852 continue;
3853 FDCS->rawcmd = 2;
3854 if (user_reset_fdc(-1,FD_RESET_ALWAYS,0)){
3855 FDCS->address = -1;
3856 continue;
3857 }
3858
3859 FDCS->version = get_fdc_version();
3860 if (FDCS->version == FDC_NONE){
3861 FDCS->address = -1;
3862 continue;
3863 }
3864
3865 request_region(FDCS->address, 6, "floppy");
3866 request_region(FDCS->address+7, 1, "floppy DIR");
3867
3868
3869
3870 have_no_fdc = 0;
3871
3872
3873
3874
3875 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
3876 user_reset_fdc(-1,FD_RESET_ALWAYS,0);
3877 }
3878 fdc=0;
3879 del_timer(&fd_timeout);
3880 current_drive = 0;
3881 floppy_release_irq_and_dma();
3882 initialising=0;
3883 if (have_no_fdc) {
3884 DPRINT("no floppy controllers found\n");
3885 unregister_blkdev(MAJOR_NR,"fd");
3886 } else
3887 virtual_dma_init();
3888 return have_no_fdc;
3889 }
3890
3891 static int floppy_grab_irq_and_dma(void)
3892 {
3893 int i;
3894 cli();
3895 if (usage_count++){
3896 sti();
3897 return 0;
3898 }
3899 sti();
3900 MOD_INC_USE_COUNT;
3901 for (i=0; i< N_FDC; i++){
3902 if (FDCS->address != -1){
3903 fdc = i;
3904 reset_fdc_info(1);
3905 fd_outb(FDCS->dor, FD_DOR);
3906 }
3907 }
3908 set_dor(0, ~0, 8);
3909
3910 if (fd_request_irq()) {
3911 DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
3912 FLOPPY_IRQ);
3913 return -1;
3914 }
3915 if (fd_request_dma()) {
3916 DPRINT1("Unable to grab DMA%d for the floppy driver\n",
3917 FLOPPY_DMA);
3918 fd_free_irq();
3919 return -1;
3920 }
3921 for (fdc = 0; fdc < N_FDC; fdc++)
3922 if (FDCS->address != -1)
3923 fd_outb(FDCS->dor, FD_DOR);
3924 fdc = 0;
3925 fd_enable_irq();
3926 return 0;
3927 }
3928
3929 static void floppy_release_irq_and_dma(void)
3930 {
3931 #ifdef FLOPPY_SANITY_CHECK
3932 int drive;
3933 #endif
3934 long tmpsize;
3935 void *tmpaddr;
3936
3937 cli();
3938 if (--usage_count){
3939 sti();
3940 return;
3941 }
3942 sti();
3943 MOD_DEC_USE_COUNT;
3944 fd_disable_dma();
3945 fd_free_dma();
3946 fd_disable_irq();
3947 fd_free_irq();
3948
3949 set_dor(0, ~0, 8);
3950 #if N_FDC > 1
3951 set_dor(1, ~8, 0);
3952 #endif
3953 floppy_enable_hlt();
3954
3955 if (floppy_track_buffer && max_buffer_sectors) {
3956 tmpsize = max_buffer_sectors*1024;
3957 tmpaddr = (void *)floppy_track_buffer;
3958 floppy_track_buffer = 0;
3959 max_buffer_sectors = 0;
3960 free_pages((unsigned long)tmpaddr, __get_order(tmpsize));
3961 }
3962
3963 #ifdef FLOPPY_SANITY_CHECK
3964 for (drive=0; drive < N_FDC * 4; drive++)
3965 if (motor_off_timer[drive].next)
3966 printk("motor off timer %d still active\n", drive);
3967
3968 if (fd_timeout.next)
3969 printk("floppy timer still active:%s\n", timeout_message);
3970 if (fd_timer.next)
3971 printk("auxiliary floppy timer still active\n");
3972 if (floppy_tq.sync)
3973 printk("task queue still active\n");
3974 #endif
3975 }
3976
3977
3978 #ifdef MODULE
3979
3980 extern char *get_options(char *str, int *ints);
3981
3982 static void mod_setup(char *pattern, void (*setup)(char *, int *))
3983 {
3984 int i;
3985 char c;
3986 int j;
3987 int match;
3988 char buffer[100];
3989 int ints[11];
3990 int length = strlen(pattern)+1;
3991
3992 match=0;
3993 j=1;
3994
3995 for (i=current->mm->env_start; i< current->mm->env_end; i ++){
3996 c= get_fs_byte(i);
3997 if (match){
3998 if (j==99)
3999 c='\0';
4000 buffer[j] = c;
4001 if (!c || c == ' ' || c == '\t'){
4002 if (j){
4003 buffer[j] = '\0';
4004 setup(get_options(buffer,ints),ints);
4005 }
4006 j=0;
4007 } else
4008 j++;
4009 if (!c)
4010 break;
4011 continue;
4012 }
4013 if ((!j && !c) || (j && c == pattern[j-1]))
4014 j++;
4015 else
4016 j=0;
4017 if (j==length){
4018 match=1;
4019 j=0;
4020 }
4021 }
4022 }
4023
4024
4025 #ifdef __cplusplus
4026 extern "C" {
4027 #endif
4028 int init_module(void)
4029 {
4030 printk("inserting floppy driver for %s\n", kernel_version);
4031
4032 mod_setup("floppy=", floppy_setup);
4033
4034 return floppy_init();
4035 }
4036
4037 void cleanup_module(void)
4038 {
4039 int fdc;
4040
4041 for (fdc=0; fdc<2; fdc++)
4042 if (FDCS->address != -1){
4043 release_region(FDCS->address, 6);
4044 release_region(FDCS->address+7, 1);
4045 }
4046
4047 unregister_blkdev(MAJOR_NR, "fd");
4048
4049 blk_dev[MAJOR_NR].request_fn = 0;
4050 }
4051
4052 #ifdef __cplusplus
4053 }
4054 #endif
4055
4056 #endif