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 int direct, indirect;
2444
2445 indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
2446 sector_t;
2447
2448 max_size = minimum(buffer_chain_size(),
2449 (MAX_DMA_ADDRESS -
2450 ((unsigned long) CURRENT->buffer))>>9);
2451
2452 if (CROSS_64KB(CURRENT->buffer, max_size << 9))
2453 max_size = (K_64 - ((long) CURRENT->buffer) % K_64)>>9;
2454 direct = transfer_size(ssize,max_sector,max_size) - sector_t;
2455
2456
2457
2458
2459
2460
2461
2462 if (!direct ||
2463 (indirect * 2 > direct * 3 &&
2464 *errors < DP->max_errors.read_track &&
2465
2466 ((!probing || (DP->read_track&(1<<DRS->probed_format)))))){
2467 max_size = CURRENT->nr_sectors;
2468 } else {
2469 raw_cmd->kernel_data = CURRENT->buffer;
2470 raw_cmd->length = current_count_sectors << 9;
2471 if (raw_cmd->length == 0){
2472 DPRINT("zero dma transfer attempted from make_raw_request\n");
2473 DPRINT3("indirect=%d direct=%d sector_t=%d",
2474 indirect, direct, sector_t);
2475 return 0;
2476 }
2477 return 2;
2478 }
2479 }
2480
2481 if (CT(COMMAND) == FD_READ)
2482 max_size = max_sector;
2483
2484
2485 if (buffer_track != raw_cmd->track ||
2486 buffer_drive !=current_drive ||
2487 sector_t > buffer_max ||
2488 sector_t < buffer_min ||
2489 ((CT(COMMAND) == FD_READ ||
2490 (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize))&&
2491 max_sector > 2 * max_buffer_sectors + buffer_min &&
2492 max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
2493 ){
2494 buffer_track = -1;
2495 buffer_drive = current_drive;
2496 buffer_max = buffer_min = aligned_sector_t;
2497 }
2498 raw_cmd->kernel_data = floppy_track_buffer +
2499 ((aligned_sector_t-buffer_min)<<9);
2500
2501 if (CT(COMMAND) == FD_WRITE){
2502
2503
2504
2505
2506 #ifdef FLOPPY_SANITY_CHECK
2507 if (sector_t != aligned_sector_t && buffer_track == -1)
2508 DPRINT("internal error offset !=0 on write\n");
2509 #endif
2510 buffer_track = raw_cmd->track;
2511 buffer_drive = current_drive;
2512 copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min);
2513 } else
2514 transfer_size(ssize, max_sector,
2515 2*max_buffer_sectors+buffer_min-aligned_sector_t);
2516
2517
2518 raw_cmd->length = sector_t+current_count_sectors-aligned_sector_t;
2519 raw_cmd->length = ((raw_cmd->length -1)|(ssize-1))+1;
2520 raw_cmd->length <<= 9;
2521 #ifdef FLOPPY_SANITY_CHECK
2522 if ((raw_cmd->length < current_count_sectors << 9) ||
2523 (raw_cmd->kernel_data != CURRENT->buffer &&
2524 CT(COMMAND) == FD_WRITE &&
2525 (aligned_sector_t + (raw_cmd->length >> 9) > buffer_max ||
2526 aligned_sector_t < buffer_min)) ||
2527 raw_cmd->length % (128 << SIZECODE) ||
2528 raw_cmd->length <= 0 || current_count_sectors <= 0){
2529 DPRINT2("fractionary current count b=%lx s=%lx\n",
2530 raw_cmd->length, current_count_sectors);
2531 if (raw_cmd->kernel_data != CURRENT->buffer)
2532 printk("addr=%d, length=%ld\n",
2533 (int) ((raw_cmd->kernel_data -
2534 floppy_track_buffer) >> 9),
2535 current_count_sectors);
2536 printk("st=%d ast=%d mse=%d msi=%d\n",
2537 sector_t, aligned_sector_t, max_sector, max_size);
2538 printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
2539 printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
2540 COMMAND, SECTOR, HEAD, TRACK);
2541 printk("buffer drive=%d\n", buffer_drive);
2542 printk("buffer track=%d\n", buffer_track);
2543 printk("buffer_min=%d\n", buffer_min);
2544 printk("buffer_max=%d\n", buffer_max);
2545 return 0;
2546 }
2547
2548 if (raw_cmd->kernel_data != CURRENT->buffer){
2549 if (raw_cmd->kernel_data < floppy_track_buffer ||
2550 current_count_sectors < 0 ||
2551 raw_cmd->length < 0 ||
2552 raw_cmd->kernel_data + raw_cmd->length >
2553 floppy_track_buffer + (max_buffer_sectors << 10)){
2554 DPRINT("buffer overrun in schedule dma\n");
2555 printk("sector_t=%d buffer_min=%d current_count=%ld\n",
2556 sector_t, buffer_min,
2557 raw_cmd->length >> 9);
2558 printk("current_count_sectors=%ld\n",
2559 current_count_sectors);
2560 if (CT(COMMAND) == FD_READ)
2561 printk("read\n");
2562 if (CT(COMMAND) == FD_READ)
2563 printk("write\n");
2564 return 0;
2565 }
2566 } else if (raw_cmd->length > CURRENT->nr_sectors << 9 ||
2567 current_count_sectors > CURRENT->nr_sectors){
2568 DPRINT("buffer overrun in direct transfer\n");
2569 return 0;
2570 } else if (raw_cmd->length < current_count_sectors << 9){
2571 DPRINT("more sectors than bytes\n");
2572 printk("bytes=%ld\n", raw_cmd->length >> 9);
2573 printk("sectors=%ld\n", current_count_sectors);
2574 }
2575 if (raw_cmd->length == 0){
2576 DPRINT("zero dma transfer attempted from make_raw_request\n");
2577 return 0;
2578 }
2579 #endif
2580 return 2;
2581 }
2582
2583 static void redo_fd_request(void)
2584 {
2585 #define REPEAT {request_done(0); continue; }
2586 kdev_t device;
2587 int tmp;
2588
2589 lastredo = jiffies;
2590 if (current_drive < N_DRIVE)
2591 floppy_off(current_drive);
2592
2593 if (CURRENT && CURRENT->rq_status == RQ_INACTIVE){
2594 DPRINT("current not active!\n");
2595 return;
2596 }
2597
2598 while(1){
2599 if (!CURRENT) {
2600 CLEAR_INTR;
2601 unlock_fdc();
2602 return;
2603 }
2604 if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
2605 panic(DEVICE_NAME ": request list destroyed");
2606 if (CURRENT->bh && !CURRENT->bh->b_lock)
2607 panic(DEVICE_NAME ": block not locked");
2608
2609 device = CURRENT->rq_dev;
2610 set_fdc(DRIVE(device));
2611 reschedule_timeout(CURRENTD, "redo fd request", 0);
2612
2613 set_floppy(device);
2614 raw_cmd = & default_raw_cmd;
2615 raw_cmd->flags = 0;
2616 if (start_motor(redo_fd_request)) return;
2617 if (test_bit(current_drive, &fake_change) ||
2618 TESTF(FD_DISK_CHANGED)){
2619 DPRINT("disk absent or changed during operation\n");
2620 REPEAT;
2621 }
2622 if (!floppy) {
2623 if (!probing){
2624 DRS->probed_format = 0;
2625 if (next_valid_format()){
2626 DPRINT("no autodetectable formats\n");
2627 floppy = NULL;
2628 REPEAT;
2629 }
2630 }
2631 probing = 1;
2632 floppy = floppy_type+DP->autodetect[DRS->probed_format];
2633 } else
2634 probing = 0;
2635 errors = & (CURRENT->errors);
2636 tmp = make_raw_rw_request();
2637 if (tmp < 2){
2638 request_done(tmp);
2639 continue;
2640 }
2641
2642 if (TESTF(FD_NEED_TWADDLE))
2643 twaddle();
2644 floppy_tq.routine = (void *)(void *) floppy_start;
2645 queue_task(&floppy_tq, &tq_timer);
2646 #ifdef DEBUGT
2647 debugt("queue fd request");
2648 #endif
2649 return;
2650 }
2651 #undef REPEAT
2652 }
2653
2654 static struct cont_t rw_cont={
2655 rw_interrupt,
2656 redo_fd_request,
2657 bad_flp_intr,
2658 request_done };
2659
2660 static struct tq_struct request_tq =
2661 { 0, 0, (void *) (void *) redo_fd_request, 0 };
2662
2663 static void process_fd_request(void)
2664 {
2665 cont = &rw_cont;
2666 queue_task(&request_tq, &tq_timer);
2667 }
2668
2669 static void do_fd_request(void)
2670 {
2671 if (fdc_busy){
2672
2673
2674 is_alive("do fd request, old request running");
2675 return;
2676 }
2677 lock_fdc(MAXTIMEOUT,0);
2678 process_fd_request();
2679 is_alive("do fd request");
2680 }
2681
2682 static struct cont_t poll_cont={
2683 success_and_wakeup,
2684 floppy_ready,
2685 generic_failure,
2686 generic_done };
2687
2688 static int poll_drive(int interruptible, int flag)
2689 {
2690 int ret;
2691
2692 raw_cmd = &default_raw_cmd;
2693 raw_cmd->flags= flag;
2694 raw_cmd->track=0;
2695 raw_cmd->cmd_count=0;
2696 cont = &poll_cont;
2697 #ifdef DCL_DEBUG
2698 if (DP->flags & FD_DEBUG){
2699 DPRINT("setting NEWCHANGE in poll_drive\n");
2700 }
2701 #endif
2702 SETF(FD_DISK_NEWCHANGE);
2703 WAIT(floppy_ready);
2704 return ret;
2705 }
2706
2707
2708
2709
2710
2711
2712 static void reset_intr(void)
2713 {
2714 printk("weird, reset interrupt called\n");
2715 }
2716
2717 static struct cont_t reset_cont={
2718 reset_intr,
2719 success_and_wakeup,
2720 generic_failure,
2721 generic_done };
2722
2723 static int user_reset_fdc(int drive, int arg, int interruptible)
2724 {
2725 int ret;
2726
2727 ret=0;
2728 LOCK_FDC(drive,interruptible);
2729 if (arg == FD_RESET_ALWAYS)
2730 FDCS->reset=1;
2731 if (FDCS->reset){
2732 cont = &reset_cont;
2733 WAIT(reset_fdc);
2734 }
2735 process_fd_request();
2736 return ret;
2737 }
2738
2739
2740
2741
2742
2743 static int fd_copyout(void *param, const void *address, int size)
2744 {
2745 int ret;
2746
2747 ECALL(verify_area(VERIFY_WRITE,param,size));
2748 fd_cacheflush(address, size);
2749
2750
2751 memcpy_tofs(param,(void *) address, size);
2752 return 0;
2753 }
2754
2755 static int fd_copyin(void *param, void *address, int size)
2756 {
2757 int ret;
2758
2759 ECALL(verify_area(VERIFY_READ,param,size));
2760 memcpy_fromfs((void *) address, param, size);
2761 return 0;
2762 }
2763
2764 #define COPYOUT(x) ECALL(fd_copyout((void *)param, &(x), sizeof(x)))
2765 #define COPYIN(x) ECALL(fd_copyin((void *)param, &(x), sizeof(x)))
2766
2767 static inline const char *drive_name(int type, int drive)
2768 {
2769 struct floppy_struct *floppy;
2770
2771 if (type)
2772 floppy = floppy_type + type;
2773 else {
2774 if (UDP->native_format)
2775 floppy = floppy_type + UDP->native_format;
2776 else
2777 return "(null)";
2778 }
2779 if (floppy->name)
2780 return floppy->name;
2781 else
2782 return "(null)";
2783 }
2784
2785
2786
2787 static void raw_cmd_done(int flag)
2788 {
2789 int i;
2790
2791 if (!flag) {
2792 raw_cmd->flags = FD_RAW_FAILURE;
2793 raw_cmd->flags |= FD_RAW_HARDFAILURE;
2794 } else {
2795 raw_cmd->reply_count = inr;
2796 for (i=0; i< raw_cmd->reply_count; i++)
2797 raw_cmd->reply[i] = reply_buffer[i];
2798
2799 if (raw_cmd->flags & (FD_RAW_READ | FD_RAW_WRITE))
2800 raw_cmd->length = get_dma_residue(FLOPPY_DMA);
2801
2802 if ((raw_cmd->flags & FD_RAW_SOFTFAILURE) &&
2803 (!raw_cmd->reply_count || (raw_cmd->reply[0] & 0xc0)))
2804 raw_cmd->flags |= FD_RAW_FAILURE;
2805
2806 if (disk_change(current_drive))
2807 raw_cmd->flags |= FD_RAW_DISK_CHANGE;
2808 else
2809 raw_cmd->flags &= ~FD_RAW_DISK_CHANGE;
2810 if (raw_cmd->flags & FD_RAW_NO_MOTOR_AFTER)
2811 motor_off_callback(current_drive);
2812
2813 if (raw_cmd->next &&
2814 (!(raw_cmd->flags & FD_RAW_FAILURE) ||
2815 !(raw_cmd->flags & FD_RAW_STOP_IF_FAILURE)) &&
2816 ((raw_cmd->flags & FD_RAW_FAILURE) ||
2817 !(raw_cmd->flags &FD_RAW_STOP_IF_SUCCESS))) {
2818 raw_cmd = raw_cmd->next;
2819 return;
2820 }
2821 }
2822 generic_done(flag);
2823 }
2824
2825
2826 static struct cont_t raw_cmd_cont={
2827 success_and_wakeup,
2828 floppy_start,
2829 generic_failure,
2830 raw_cmd_done
2831 };
2832
2833 static inline int raw_cmd_copyout(int cmd, char *param,
2834 struct floppy_raw_cmd *ptr)
2835 {
2836 struct old_floppy_raw_cmd old_raw_cmd;
2837 int ret;
2838
2839 while(ptr) {
2840 if (cmd == OLDFDRAWCMD) {
2841 old_raw_cmd.flags = ptr->flags;
2842 old_raw_cmd.data = ptr->data;
2843 old_raw_cmd.length = ptr->length;
2844 old_raw_cmd.rate = ptr->rate;
2845 old_raw_cmd.reply_count = ptr->reply_count;
2846 memcpy(old_raw_cmd.reply, ptr->reply, 7);
2847 COPYOUT(old_raw_cmd);
2848 param += sizeof(old_raw_cmd);
2849 } else {
2850 COPYOUT(*ptr);
2851 param += sizeof(struct floppy_raw_cmd);
2852 }
2853
2854 if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length){
2855 if (ptr->length>=0 && ptr->length<=ptr->buffer_length)
2856 ECALL(fd_copyout(ptr->data,
2857 ptr->kernel_data,
2858 ptr->buffer_length -
2859 ptr->length));
2860 }
2861 ptr = ptr->next;
2862 }
2863 return 0;
2864 }
2865
2866
2867 static void raw_cmd_free(struct floppy_raw_cmd **ptr)
2868 {
2869 struct floppy_raw_cmd *next,*this;
2870
2871 this = *ptr;
2872 *ptr = 0;
2873 while(this) {
2874 if (this->buffer_length) {
2875 free_pages((unsigned long)this->kernel_data,
2876 __get_order(this->buffer_length));
2877 this->buffer_length = 0;
2878 }
2879 next = this->next;
2880 kfree(this);
2881 this = next;
2882 }
2883 }
2884
2885
2886 static inline int raw_cmd_copyin(int cmd, char *param,
2887 struct floppy_raw_cmd **rcmd)
2888 {
2889 struct floppy_raw_cmd *ptr;
2890 struct old_floppy_raw_cmd old_raw_cmd;
2891 int ret;
2892 int i;
2893
2894 *rcmd = 0;
2895 while(1) {
2896 ptr = (struct floppy_raw_cmd *)
2897 kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER);
2898 if (!ptr)
2899 return -ENOMEM;
2900 *rcmd = ptr;
2901 if (cmd == OLDFDRAWCMD){
2902 COPYIN(old_raw_cmd);
2903 ptr->flags = old_raw_cmd.flags;
2904 ptr->data = old_raw_cmd.data;
2905 ptr->length = old_raw_cmd.length;
2906 ptr->rate = old_raw_cmd.rate;
2907 ptr->cmd_count = old_raw_cmd.cmd_count;
2908 ptr->track = old_raw_cmd.track;
2909 ptr->phys_length = 0;
2910 ptr->next = 0;
2911 ptr->buffer_length = 0;
2912 memcpy(ptr->cmd, old_raw_cmd.cmd, 9);
2913 param += sizeof(struct old_floppy_raw_cmd);
2914 if (ptr->cmd_count > 9)
2915 return -EINVAL;
2916 } else {
2917 COPYIN(*ptr);
2918 ptr->next = 0;
2919 ptr->buffer_length = 0;
2920 param += sizeof(struct floppy_raw_cmd);
2921 if (ptr->cmd_count > 16)
2922 return -EINVAL;
2923 }
2924
2925 for (i=0; i< 16; i++)
2926 ptr->reply[i] = 0;
2927 ptr->resultcode = 0;
2928 ptr->kernel_data = 0;
2929
2930 if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
2931 if (ptr->length <= 0)
2932 return -EINVAL;
2933 ptr->kernel_data =(char*)dma_mem_alloc(ptr->length);
2934 if (!ptr->kernel_data)
2935 return -ENOMEM;
2936 ptr->buffer_length = ptr->length;
2937 }
2938 if ( ptr->flags & FD_RAW_READ )
2939 ECALL( verify_area( VERIFY_WRITE, ptr->data,
2940 ptr->length ));
2941 if (ptr->flags & FD_RAW_WRITE)
2942 ECALL(fd_copyin(ptr->data, ptr->kernel_data,
2943 ptr->length));
2944 rcmd = & (ptr->next);
2945 if (!(ptr->flags & FD_RAW_MORE))
2946 return 0;
2947 ptr->rate &= 0x03;
2948 }
2949 }
2950
2951
2952 static int raw_cmd_ioctl(int cmd, void *param)
2953 {
2954 int drive, ret, ret2;
2955 struct floppy_raw_cmd *my_raw_cmd;
2956
2957 if (FDCS->rawcmd <= 1)
2958 FDCS->rawcmd = 1;
2959 for (drive= 0; drive < N_DRIVE; drive++){
2960 if (FDC(drive) != fdc)
2961 continue;
2962 if (drive == current_drive){
2963 if (UDRS->fd_ref > 1){
2964 FDCS->rawcmd = 2;
2965 break;
2966 }
2967 } else if (UDRS->fd_ref){
2968 FDCS->rawcmd = 2;
2969 break;
2970 }
2971 }
2972
2973 if (FDCS->reset)
2974 return -EIO;
2975
2976 ret = raw_cmd_copyin(cmd, param, &my_raw_cmd);
2977 if (ret) {
2978 raw_cmd_free(&my_raw_cmd);
2979 return ret;
2980 }
2981
2982 raw_cmd = my_raw_cmd;
2983 cont = &raw_cmd_cont;
2984 ret=wait_til_done(floppy_start,1);
2985 #ifdef DCL_DEBUG
2986 if (DP->flags & FD_DEBUG){
2987 DPRINT("calling disk change from raw_cmd ioctl\n");
2988 }
2989 #endif
2990
2991 if (ret != -EINTR && FDCS->reset)
2992 ret = -EIO;
2993
2994 DRS->track = NO_TRACK;
2995
2996 ret2 = raw_cmd_copyout(cmd, param, my_raw_cmd);
2997 if (!ret)
2998 ret = ret2;
2999 raw_cmd_free(&my_raw_cmd);
3000 return ret;
3001 }
3002
3003 static int invalidate_drive(kdev_t rdev)
3004 {
3005
3006 set_bit(DRIVE(rdev), &fake_change);
3007 process_fd_request();
3008 check_disk_change(rdev);
3009 return 0;
3010 }
3011
3012
3013 static inline void clear_write_error(int drive)
3014 {
3015 CLEARSTRUCT(UDRWE);
3016 }
3017
3018 static inline int set_geometry(int cmd, struct floppy_struct *g,
3019 int drive, int type, int device)
3020 {
3021 int cnt;
3022
3023
3024 if (g->sect <= 0 ||
3025 g->head <= 0 ||
3026 g->track <= 0 ||
3027 g->track > UDP->tracks>>STRETCH(g) ||
3028
3029 (g->stretch&~(FD_STRETCH|FD_SWAPSIDES)) != 0)
3030 return -EINVAL;
3031 if (type){
3032 if (!suser())
3033 return -EPERM;
3034 LOCK_FDC(drive,1);
3035 for (cnt = 0; cnt < N_DRIVE; cnt++){
3036 if (TYPE(drive_state[cnt].fd_device) ==
3037 type &&
3038 drive_state[cnt].fd_ref)
3039 set_bit(drive, &fake_change);
3040 }
3041 floppy_type[type] = *g;
3042 floppy_type[type].name="user format";
3043 for (cnt = type << 2; cnt < (type << 2) + 4; cnt++)
3044 floppy_sizes[cnt]= floppy_sizes[cnt+0x80]=
3045 floppy_type[type].size>>1;
3046 process_fd_request();
3047 for (cnt = 0; cnt < N_DRIVE; cnt++){
3048 if (TYPE(drive_state[cnt].fd_device) == type &&
3049 drive_state[cnt].fd_ref)
3050 check_disk_change(drive_state[cnt].fd_device);
3051 }
3052 } else {
3053 LOCK_FDC(drive,1);
3054 if (cmd != FDDEFPRM)
3055
3056
3057 CALL(poll_drive(1,0));
3058 user_params[drive] = *g;
3059 if (buffer_drive == drive)
3060 SUPBOUND(buffer_max, user_params[drive].sect);
3061 current_type[drive] = &user_params[drive];
3062 floppy_sizes[drive] = user_params[drive].size >> 1;
3063 if (cmd == FDDEFPRM)
3064 DRS->keep_data = -1;
3065 else
3066 DRS->keep_data = 1;
3067
3068
3069
3070
3071
3072 if (DRS->maxblock > user_params[drive].sect || DRS->maxtrack)
3073 invalidate_drive(device);
3074 else
3075 process_fd_request();
3076 }
3077 return 0;
3078 }
3079
3080
3081 static struct translation_entry {
3082 int newcmd;
3083 int oldcmd;
3084 int oldsize;
3085
3086 } translation_table[]= {
3087 {FDCLRPRM, 0, 0},
3088 {FDSETPRM, 1, 28},
3089 {FDDEFPRM, 2, 28},
3090 {FDGETPRM, 3, 28},
3091 {FDMSGON, 4, 0},
3092 {FDMSGOFF, 5, 0},
3093 {FDFMTBEG, 6, 0},
3094 {FDFMTTRK, 7, 12},
3095 {FDFMTEND, 8, 0},
3096 {FDSETEMSGTRESH, 10, 0},
3097 {FDFLUSH, 11, 0},
3098 {FDSETMAXERRS, 12, 20},
3099 {OLDFDRAWCMD, 30, 0},
3100 {FDGETMAXERRS, 14, 20},
3101 {FDGETDRVTYP, 16, 16},
3102 {FDSETDRVPRM, 20, 88},
3103 {FDGETDRVPRM, 21, 88},
3104 {FDGETDRVSTAT, 22, 52},
3105 {FDPOLLDRVSTAT, 23, 52},
3106 {FDRESET, 24, 0},
3107 {FDGETFDCSTAT, 25, 40},
3108 {FDWERRORCLR, 27, 0},
3109 {FDWERRORGET, 28, 24},
3110 {FDRAWCMD, 0, 0},
3111 {FDTWADDLE, 40, 0} };
3112
3113 static inline int normalize_0x02xx_ioctl(int *cmd, int *size)
3114 {
3115 int i, orig_size, ocmd;
3116
3117 orig_size = IOC_SIZE(*cmd);
3118 ocmd = *cmd;
3119 for (i=0; i < ARRAY_SIZE(translation_table); i++) {
3120 if ((*cmd & 0xff3f) == (translation_table[i].newcmd & 0xff3f)){
3121 *cmd = translation_table[i].newcmd;
3122 if (!orig_size && IOC_SIZE(*cmd)) {
3123
3124 *size = IOC_SIZE(*cmd);
3125 DPRINT1("warning: obsolete ioctl 0x%x\n",ocmd);
3126 DPRINT("please recompile your program\n");
3127
3128
3129
3130
3131
3132
3133 } else {
3134 *size = orig_size;
3135 if (*size > IOC_SIZE(*cmd)) {
3136 printk("ioctl not yet supported\n");
3137 return -EFAULT;
3138 }
3139 }
3140 return 0;
3141 }
3142 }
3143 return -EINVAL;
3144 }
3145
3146 static inline int xlate_0x00xx_ioctl(int *cmd, int *size)
3147 {
3148 int i;
3149
3150
3151
3152
3153
3154
3155
3156
3157 for (i=0; i < ARRAY_SIZE(translation_table); i++) {
3158 if (*cmd == translation_table[i].oldcmd) {
3159 *size = translation_table[i].oldsize;
3160 *cmd = translation_table[i].newcmd;
3161 return 0;
3162 }
3163 }
3164 return -EINVAL;
3165 }
3166
3167 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
3168 unsigned long param)
3169 {
3170 #define IOCTL_MODE_BIT 8
3171 #define OPEN_WRITE_BIT 16
3172 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
3173 #define OUT(c,x) case c: outparam = (const char *) (x); break
3174 #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
3175
3176 int i,drive,type;
3177 kdev_t device;
3178 int ret;
3179 int size;
3180 union inparam {
3181 struct floppy_struct g;
3182 struct format_descr f;
3183 struct floppy_max_errors max_errors;
3184 struct floppy_drive_params dp;
3185 } inparam;
3186 const char *outparam;
3187
3188 device = inode->i_rdev;
3189 switch (cmd) {
3190 RO_IOCTLS(device,param);
3191 }
3192 type = TYPE(device);
3193 drive = DRIVE(device);
3194
3195
3196 if ((cmd & 0xff00) == 0x0200) {
3197 ECALL(normalize_0x02xx_ioctl(&cmd, &size));
3198 } else if ((cmd & 0xff00) == 0x0000) {
3199 ECALL(xlate_0x00xx_ioctl(&cmd, &size));
3200 } else
3201 return -EINVAL;
3202
3203
3204 if (((cmd & 0x80) && !suser()) ||
3205 ((cmd & 0x40) && !IOCTL_ALLOWED))
3206 return -EPERM;
3207
3208
3209 if (_IOC_DIR(cmd) & _IOC_WRITE)
3210 ECALL(verify_area(VERIFY_WRITE,(void *) param, size));
3211
3212
3213 CLEARSTRUCT(&inparam);
3214 if (_IOC_DIR(cmd) & _IOC_READ)
3215 ECALL(fd_copyin((void *)param, &inparam, size))
3216
3217 switch (cmd) {
3218 case FDCLRPRM:
3219 LOCK_FDC(drive,1);
3220 current_type[drive] = NULL;
3221 floppy_sizes[drive] = MAX_DISK_SIZE;
3222 UDRS->keep_data = 0;
3223 return invalidate_drive(device);
3224 case FDSETPRM:
3225 case FDDEFPRM:
3226 return set_geometry(cmd, & inparam.g,
3227 drive, type, device);
3228 case FDGETPRM:
3229 if (type)
3230 outparam = (char *) &floppy_type[type];
3231 else
3232 outparam = (char *) current_type[drive];
3233 if(!outparam)
3234 return -ENODEV;
3235 break;
3236
3237 case FDMSGON:
3238 UDP->flags |= FTD_MSG;
3239 return 0;
3240 case FDMSGOFF:
3241 UDP->flags &= ~FTD_MSG;
3242 return 0;
3243
3244 case FDFMTBEG:
3245 return 0;
3246 case FDFMTTRK:
3247 if (UDRS->fd_ref != 1)
3248 return -EBUSY;
3249 return do_format(device, &inparam.f);
3250 case FDFMTEND:
3251 case FDFLUSH:
3252 LOCK_FDC(drive,1);
3253 return invalidate_drive(device);
3254
3255 case FDSETEMSGTRESH:
3256 UDP->max_errors.reporting =
3257 (unsigned short) (param & 0x0f);
3258 return 0;
3259 OUT(FDGETMAXERRS, &UDP->max_errors);
3260 IN(FDSETMAXERRS, &UDP->max_errors, max_errors);
3261
3262 case FDGETDRVTYP:
3263 outparam = drive_name(type,drive);
3264 SUPBOUND(size,strlen(outparam));
3265 break;
3266
3267 IN(FDSETDRVPRM, UDP, dp);
3268 OUT(FDGETDRVPRM, UDP);
3269
3270 case FDPOLLDRVSTAT:
3271 LOCK_FDC(drive,1);
3272 CALL(poll_drive(1, FD_RAW_NEED_DISK));
3273 process_fd_request();
3274
3275 OUT(FDGETDRVSTAT, UDRS);
3276
3277 case FDRESET:
3278 return user_reset_fdc(drive, (int)param, 1);
3279
3280 OUT(FDGETFDCSTAT,UFDCS);
3281
3282 case FDWERRORCLR:
3283 CLEARSTRUCT(UDRWE);
3284 return 0;
3285 OUT(FDWERRORGET,UDRWE);
3286
3287 case OLDFDRAWCMD:
3288 case FDRAWCMD:
3289 if (type)
3290 return -EINVAL;
3291 LOCK_FDC(drive,1);
3292 set_floppy(device);
3293 CALL(i = raw_cmd_ioctl(cmd,(void *) param));
3294 process_fd_request();
3295 return i;
3296
3297 case FDTWADDLE:
3298 LOCK_FDC(drive,1);
3299 twaddle();
3300 process_fd_request();
3301 return 0;
3302
3303 default:
3304 return -EINVAL;
3305 }
3306
3307 if (_IOC_DIR(cmd) & _IOC_WRITE)
3308 return fd_copyout((void *)param, outparam, size);
3309 else
3310 return 0;
3311 #undef IOCTL_ALLOWED
3312 #undef OUT
3313 #undef IN
3314 }
3315
3316 static void config_types(void)
3317 {
3318 int first=1;
3319 int drive;
3320
3321
3322 drive=0;
3323 if (!UDP->cmos)
3324 UDP->cmos= FLOPPY0_TYPE;
3325 drive=1;
3326 if (!UDP->cmos && FLOPPY1_TYPE)
3327 UDP->cmos = FLOPPY1_TYPE;
3328
3329
3330
3331
3332 for (drive=0; drive < N_DRIVE; drive++){
3333 if (UDP->cmos >= 0 && UDP->cmos <= NUMBER(default_drive_params))
3334 memcpy((char *) UDP,
3335 (char *) (&default_drive_params[(int)UDP->cmos].params),
3336 sizeof(struct floppy_drive_params));
3337 if (UDP->cmos){
3338 if (first)
3339 printk("Floppy drive(s): ");
3340 else
3341 printk(", ");
3342 first=0;
3343 if (UDP->cmos > 0){
3344 allowed_drive_mask |= 1 << drive;
3345 printk("fd%d is %s", drive,
3346 default_drive_params[(int)UDP->cmos].name);
3347 } else
3348 printk("fd%d is unknown type %d",drive,
3349 UDP->cmos);
3350 }
3351 }
3352 if (!first)
3353 printk("\n");
3354 }
3355
3356 static int floppy_read(struct inode * inode, struct file * filp,
3357 char * buf, int count)
3358 {
3359 int drive = DRIVE(inode->i_rdev);
3360
3361 check_disk_change(inode->i_rdev);
3362 if (UTESTF(FD_DISK_CHANGED))
3363 return -ENXIO;
3364 return block_read(inode, filp, buf, count);
3365 }
3366
3367 static int floppy_write(struct inode * inode, struct file * filp,
3368 const char * buf, int count)
3369 {
3370 int block;
3371 int ret;
3372 int drive = DRIVE(inode->i_rdev);
3373
3374 if (!UDRS->maxblock)
3375 UDRS->maxblock=1;
3376 check_disk_change(inode->i_rdev);
3377 if (UTESTF(FD_DISK_CHANGED))
3378 return -ENXIO;
3379 if (!UTESTF(FD_DISK_WRITABLE))
3380 return -EROFS;
3381 block = (filp->f_pos + count) >> 9;
3382 INFBOUND(UDRS->maxblock, block);
3383 ret= block_write(inode, filp, buf, count);
3384 return ret;
3385 }
3386
3387 static void floppy_release(struct inode * inode, struct file * filp)
3388 {
3389 int drive;
3390
3391 drive = DRIVE(inode->i_rdev);
3392
3393 if (!filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
3394
3395
3396 block_fsync(inode,filp);
3397
3398 if (UDRS->fd_ref < 0)
3399 UDRS->fd_ref=0;
3400 else if (!UDRS->fd_ref--) {
3401 DPRINT("floppy_release with fd_ref == 0");
3402 UDRS->fd_ref = 0;
3403 }
3404 floppy_release_irq_and_dma();
3405 }
3406
3407
3408
3409
3410
3411
3412 #define RETERR(x) do{floppy_release(inode,filp); return -(x);}while(0)
3413
3414 static int floppy_open(struct inode * inode, struct file * filp)
3415 {
3416 int drive;
3417 int old_dev;
3418 int try;
3419 char *tmp;
3420
3421 if (!filp) {
3422 DPRINT("Weird, open called with filp=0\n");
3423 return -EIO;
3424 }
3425
3426 drive = DRIVE(inode->i_rdev);
3427 if (drive >= N_DRIVE ||
3428 !(allowed_drive_mask & (1 << drive)) ||
3429 fdc_state[FDC(drive)].version == FDC_NONE)
3430 return -ENXIO;
3431
3432 if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
3433 return -ENXIO;
3434 old_dev = UDRS->fd_device;
3435 if (UDRS->fd_ref && old_dev != MINOR(inode->i_rdev))
3436 return -EBUSY;
3437
3438 if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
3439 USETF(FD_DISK_CHANGED);
3440 USETF(FD_VERIFY);
3441 }
3442
3443 if (UDRS->fd_ref == -1 ||
3444 (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3445 return -EBUSY;
3446
3447 if (floppy_grab_irq_and_dma())
3448 return -EBUSY;
3449
3450 if (filp->f_flags & O_EXCL)
3451 UDRS->fd_ref = -1;
3452 else
3453 UDRS->fd_ref++;
3454
3455 if (!floppy_track_buffer){
3456
3457
3458 if ((UDP->cmos == 6) || (UDP->cmos == 5))
3459 try = 64;
3460 else
3461 try = 32;
3462
3463 tmp=(char *)dma_mem_alloc(1024 * try);
3464 if (!tmp) {
3465 try >>= 1;
3466 INFBOUND(try, 16);
3467 tmp= (char *)dma_mem_alloc(1024*try);
3468 }
3469 if (!tmp) {
3470 DPRINT("Unable to allocate DMA memory\n");
3471 RETERR(ENXIO);
3472 }
3473 if (floppy_track_buffer){
3474 free_pages((unsigned long)tmp,__get_order(try*1024));
3475 }else {
3476 floppy_track_buffer = tmp;
3477 max_buffer_sectors = try;
3478 }
3479 }
3480
3481 UDRS->fd_device = MINOR(inode->i_rdev);
3482
3483 if (old_dev && old_dev != inode->i_rdev) {
3484 if (buffer_drive == drive)
3485 buffer_track = -1;
3486 invalidate_buffers(old_dev);
3487 }
3488
3489
3490 if ((filp->f_mode & 2) || (permission(inode,2) == 0))
3491 filp->f_mode |= IOCTL_MODE_BIT;
3492 if (filp->f_mode & 2)
3493 filp->f_mode |= OPEN_WRITE_BIT;
3494
3495 if (UFDCS->rawcmd == 1)
3496 UFDCS->rawcmd = 2;
3497
3498 if (filp->f_flags & O_NDELAY)
3499 return 0;
3500 if (filp->f_mode & 3) {
3501 UDRS->last_checked = 0;
3502 check_disk_change(inode->i_rdev);
3503 if (UTESTF(FD_DISK_CHANGED))
3504 RETERR(ENXIO);
3505 }
3506 if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
3507 RETERR(EROFS);
3508 return 0;
3509 #undef RETERR
3510 }
3511
3512
3513
3514
3515 static int check_floppy_change(kdev_t dev)
3516 {
3517 int drive = DRIVE(dev);
3518
3519 if (MAJOR(dev) != MAJOR_NR) {
3520 DPRINT("floppy_changed: not a floppy\n");
3521 return 0;
3522 }
3523
3524 if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
3525 return 1;
3526
3527 if (UDRS->last_checked + UDP->checkfreq < jiffies){
3528 lock_fdc(drive,0);
3529 poll_drive(0,0);
3530 process_fd_request();
3531 }
3532
3533 if (UTESTF(FD_DISK_CHANGED) ||
3534 UTESTF(FD_VERIFY) ||
3535 test_bit(drive, &fake_change) ||
3536 (!TYPE(dev) && !current_type[drive]))
3537 return 1;
3538 return 0;
3539 }
3540
3541
3542
3543
3544
3545 static int floppy_revalidate(kdev_t dev)
3546 {
3547 #define NO_GEOM (!current_type[drive] && !TYPE(dev))
3548 struct buffer_head * bh;
3549 int drive=DRIVE(dev);
3550 int cf;
3551
3552 if (UTESTF(FD_DISK_CHANGED) ||
3553 UTESTF(FD_VERIFY) ||
3554 test_bit(drive, &fake_change) ||
3555 NO_GEOM){
3556 lock_fdc(drive,0);
3557 cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY);
3558 if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)){
3559 process_fd_request();
3560 return 0;
3561 }
3562 UDRS->maxblock = 0;
3563 UDRS->maxtrack = 0;
3564 if (buffer_drive == drive)
3565 buffer_track = -1;
3566 clear_bit(drive, &fake_change);
3567 UCLEARF(FD_DISK_CHANGED);
3568 if (cf)
3569 UDRS->generation++;
3570 if (NO_GEOM){
3571
3572 int size = floppy_blocksizes[MINOR(dev)];
3573 if (!size)
3574 size = 1024;
3575 if (!(bh = getblk(dev,0,size))){
3576 process_fd_request();
3577 return 1;
3578 }
3579 if (bh && !bh->b_uptodate)
3580 ll_rw_block(READ, 1, &bh);
3581 process_fd_request();
3582 wait_on_buffer(bh);
3583 brelse(bh);
3584 return 0;
3585 }
3586 if (cf)
3587 poll_drive(0, FD_RAW_NEED_DISK);
3588 process_fd_request();
3589 }
3590 return 0;
3591 }
3592
3593 static struct file_operations floppy_fops = {
3594 NULL,
3595 floppy_read,
3596 floppy_write,
3597 NULL,
3598 NULL,
3599 fd_ioctl,
3600 NULL,
3601 floppy_open,
3602 floppy_release,
3603 block_fsync,
3604 NULL,
3605 check_floppy_change,
3606 floppy_revalidate,
3607 };
3608
3609
3610
3611
3612
3613
3614
3615
3616 static char get_fdc_version(void)
3617 {
3618 int r;
3619
3620 output_byte(FD_DUMPREGS);
3621 if (FDCS->reset)
3622 return FDC_NONE;
3623 if ((r = result()) <= 0x00)
3624 return FDC_NONE;
3625 if ((r==1) && (reply_buffer[0] == 0x80)){
3626 printk("FDC %d is a 8272A\n",fdc);
3627 return FDC_8272A;
3628 }
3629 if (r != 10) {
3630 printk("FDC init: DUMPREGS: unexpected return of %d bytes.\n", r);
3631 return FDC_UNKNOWN;
3632 }
3633 output_byte(FD_VERSION);
3634 r = result();
3635 if ((r == 1) && (reply_buffer[0] == 0x80)){
3636 printk("FDC %d is a 82072\n",fdc);
3637 return FDC_82072;
3638 }
3639 if ((r != 1) || (reply_buffer[0] != 0x90)) {
3640 printk("FDC init: VERSION: unexpected return of %d bytes.\n", r);
3641 return FDC_UNKNOWN;
3642 }
3643 output_byte(FD_UNLOCK);
3644 r = result();
3645 if ((r == 1) && (reply_buffer[0] == 0x80)){
3646 printk("FDC %d is a pre-1991 82077\n", fdc);
3647 return FDC_82077_ORIG;
3648 }
3649 if ((r != 1) || (reply_buffer[0] != 0x00)) {
3650 printk("FDC init: UNLOCK: unexpected return of %d bytes.\n", r);
3651 return FDC_UNKNOWN;
3652 }
3653 printk("FDC %d is a post-1991 82077\n",fdc);
3654 return FDC_82077;
3655 }
3656
3657
3658
3659
3660
3661
3662 void floppy_invert_dcl(int *ints,int param)
3663 {
3664 int i;
3665
3666 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3667 if (param)
3668 default_drive_params[i].params.flags |= 0x80;
3669 else
3670 default_drive_params[i].params.flags &= ~0x80;
3671 }
3672 DPRINT("Configuring drives for inverted dcl\n");
3673 }
3674
3675 static void daring(int *ints,int param)
3676 {
3677 int i;
3678
3679 for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
3680 if (param){
3681 default_drive_params[i].params.select_delay = 0;
3682 default_drive_params[i].params.flags |= FD_SILENT_DCL_CLEAR;
3683 } else {
3684 default_drive_params[i].params.select_delay = 2*HZ/100;
3685 default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR;
3686 }
3687 }
3688 DPRINT1("Assuming %s floppy hardware\n", param ? "standard" : "broken");
3689 }
3690
3691 static void allow_drives(int *ints, int param)
3692 {
3693 allowed_drive_mask=param;
3694 DPRINT1("setting allowed_drive_mask to 0x%x\n", param);
3695 }
3696
3697 static void fdc2_adr(int *ints, int param)
3698 {
3699 FDC2 = param;
3700 if (param)
3701 DPRINT1("enabling second fdc at address 0x%3x\n", FDC2);
3702 else
3703 DPRINT("disabling second fdc\n");
3704 }
3705
3706 static void unex(int *ints,int param)
3707 {
3708 print_unex = param;
3709 DPRINT1("%sprinting messages for unexpected interrupts\n",
3710 param ? "" : "not ");
3711 }
3712
3713 static void set_cmos(int *ints, int dummy)
3714 {
3715 int current_drive=0;
3716
3717 if (ints[0] != 2){
3718 DPRINT("wrong number of parameter for cmos\n");
3719 return;
3720 }
3721 current_drive = ints[1];
3722 if (current_drive < 0 || current_drive >= 8){
3723 DPRINT("bad drive for set_cmos\n");
3724 return;
3725 }
3726 if (current_drive >= 4 && !FDC2)
3727 fdc2_adr(0, 0x370);
3728 if (ints[2] <= 0 || ints[2] >= NUMBER(default_drive_params)){
3729 DPRINT1("bad cmos code %d\n", ints[2]);
3730 return;
3731 }
3732 DP->cmos = ints[2];
3733 DPRINT1("setting cmos code to %d\n", ints[2]);
3734 }
3735
3736 static struct param_table {
3737 const char *name;
3738 void (*fn)(int *ints, int param);
3739 int def_param;
3740 } config_params[]={
3741 { "allowed_drive_mask", allow_drives, 0xff },
3742 { "all_drives", allow_drives, 0xff },
3743 { "asus_pci", allow_drives, 0x33 },
3744
3745 { "daring", daring, 1},
3746
3747 { "two_fdc", fdc2_adr, 0x370 },
3748 { "one_fdc", fdc2_adr, 0 },
3749
3750 { "thinkpad", floppy_invert_dcl, 1 },
3751
3752 { "cmos", set_cmos, 0 },
3753
3754 { "unexpected_interrupts", unex, 1 },
3755 { "no_unexpected_interrupts", unex, 0 },
3756 { "L40SX", unex, 0 } };
3757
3758 #define FLOPPY_SETUP
3759 void floppy_setup(char *str, int *ints)
3760 {
3761 int i;
3762 int param;
3763 if (str)
3764 for (i=0; i< ARRAY_SIZE(config_params); i++){
3765 if (strcmp(str,config_params[i].name) == 0){
3766 if (ints[0])
3767 param = ints[1];
3768 else
3769 param = config_params[i].def_param;
3770 config_params[i].fn(ints,param);
3771 return;
3772 }
3773 }
3774 if (str) {
3775 DPRINT1("unknown floppy option [%s]\n", str);
3776
3777 DPRINT("allowed options are:");
3778 for (i=0; i< ARRAY_SIZE(config_params); i++)
3779 printk(" %s",config_params[i].name);
3780 printk("\n");
3781 } else
3782 DPRINT("botched floppy option\n");
3783 DPRINT("Read linux/drivers/block/README.fd\n");
3784 }
3785
3786 int floppy_init(void)
3787 {
3788 int i,unit,drive;
3789 int have_no_fdc= -EIO;
3790
3791 raw_cmd = 0;
3792
3793 sti();
3794
3795 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
3796 printk("Unable to get major %d for floppy\n",MAJOR_NR);
3797 return -EBUSY;
3798 }
3799
3800 for (i=0; i<256; i++)
3801 if (TYPE(i))
3802 floppy_sizes[i] = floppy_type[TYPE(i)].size >> 1;
3803 else
3804 floppy_sizes[i] = MAX_DISK_SIZE;
3805
3806 blk_size[MAJOR_NR] = floppy_sizes;
3807 blksize_size[MAJOR_NR] = floppy_blocksizes;
3808 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
3809 reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
3810 config_types();
3811
3812 for (i = 0; i < N_FDC; i++) {
3813 fdc = i;
3814 CLEARSTRUCT(FDCS);
3815 FDCS->dtr = -1;
3816 FDCS->dor = 0x4;
3817 }
3818
3819 fdc_state[0].address = FDC1;
3820 #if N_FDC > 1
3821 fdc_state[1].address = FDC2;
3822 #endif
3823
3824 if (floppy_grab_irq_and_dma()){
3825 unregister_blkdev(MAJOR_NR,"fd");
3826 return -EBUSY;
3827 }
3828
3829
3830 for (drive = 0; drive < N_DRIVE; drive++) {
3831 CLEARSTRUCT(UDRS);
3832 CLEARSTRUCT(UDRWE);
3833 UDRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE | FD_DISK_CHANGED;
3834 floppy_track_buffer = NULL;
3835 max_buffer_sectors = 0;
3836 }
3837
3838 for (i = 0; i < N_FDC; i++) {
3839 fdc = i;
3840 FDCS->driver_version = FD_DRIVER_VERSION;
3841 for (unit=0; unit<4; unit++)
3842 FDCS->track[unit] = 0;
3843 if (FDCS->address == -1)
3844 continue;
3845 FDCS->rawcmd = 2;
3846 if (user_reset_fdc(-1,FD_RESET_ALWAYS,0)){
3847 FDCS->address = -1;
3848 continue;
3849 }
3850
3851 FDCS->version = get_fdc_version();
3852 if (FDCS->version == FDC_NONE){
3853 FDCS->address = -1;
3854 continue;
3855 }
3856
3857 request_region(FDCS->address, 6, "floppy");
3858 request_region(FDCS->address+7, 1, "floppy DIR");
3859
3860
3861
3862 have_no_fdc = 0;
3863
3864
3865
3866
3867 FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
3868 user_reset_fdc(-1,FD_RESET_ALWAYS,0);
3869 }
3870 fdc=0;
3871 del_timer(&fd_timeout);
3872 current_drive = 0;
3873 floppy_release_irq_and_dma();
3874 initialising=0;
3875 if (have_no_fdc) {
3876 DPRINT("no floppy controllers found\n");
3877 unregister_blkdev(MAJOR_NR,"fd");
3878 } else
3879 virtual_dma_init();
3880 return have_no_fdc;
3881 }
3882
3883 static int floppy_grab_irq_and_dma(void)
3884 {
3885 int i;
3886 cli();
3887 if (usage_count++){
3888 sti();
3889 return 0;
3890 }
3891 sti();
3892 MOD_INC_USE_COUNT;
3893 for (i=0; i< N_FDC; i++){
3894 if (FDCS->address != -1){
3895 fdc = i;
3896 reset_fdc_info(1);
3897 fd_outb(FDCS->dor, FD_DOR);
3898 }
3899 }
3900 set_dor(0, ~0, 8);
3901
3902 if (fd_request_irq()) {
3903 DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
3904 FLOPPY_IRQ);
3905 return -1;
3906 }
3907 if (fd_request_dma()) {
3908 DPRINT1("Unable to grab DMA%d for the floppy driver\n",
3909 FLOPPY_DMA);
3910 fd_free_irq();
3911 return -1;
3912 }
3913 for (fdc = 0; fdc < N_FDC; fdc++)
3914 if (FDCS->address != -1)
3915 fd_outb(FDCS->dor, FD_DOR);
3916 fdc = 0;
3917 fd_enable_irq();
3918 return 0;
3919 }
3920
3921 static void floppy_release_irq_and_dma(void)
3922 {
3923 #ifdef FLOPPY_SANITY_CHECK
3924 int drive;
3925 #endif
3926 long tmpsize;
3927 void *tmpaddr;
3928
3929 cli();
3930 if (--usage_count){
3931 sti();
3932 return;
3933 }
3934 sti();
3935 MOD_DEC_USE_COUNT;
3936 fd_disable_dma();
3937 fd_free_dma();
3938 fd_disable_irq();
3939 fd_free_irq();
3940
3941 set_dor(0, ~0, 8);
3942 #if N_FDC > 1
3943 set_dor(1, ~8, 0);
3944 #endif
3945 floppy_enable_hlt();
3946
3947 if (floppy_track_buffer && max_buffer_sectors) {
3948 tmpsize = max_buffer_sectors*1024;
3949 tmpaddr = (void *)floppy_track_buffer;
3950 floppy_track_buffer = 0;
3951 max_buffer_sectors = 0;
3952 free_pages((unsigned long)tmpaddr, __get_order(tmpsize));
3953 }
3954
3955 #ifdef FLOPPY_SANITY_CHECK
3956 for (drive=0; drive < N_FDC * 4; drive++)
3957 if (motor_off_timer[drive].next)
3958 printk("motor off timer %d still active\n", drive);
3959
3960 if (fd_timeout.next)
3961 printk("floppy timer still active:%s\n", timeout_message);
3962 if (fd_timer.next)
3963 printk("auxiliary floppy timer still active\n");
3964 if (floppy_tq.sync)
3965 printk("task queue still active\n");
3966 #endif
3967 }
3968
3969
3970 #ifdef MODULE
3971
3972 extern char *get_options(char *str, int *ints);
3973
3974 static void mod_setup(char *pattern, void (*setup)(char *, int *))
3975 {
3976 int i;
3977 char c;
3978 int j;
3979 int match;
3980 char buffer[100];
3981 int ints[11];
3982 int length = strlen(pattern)+1;
3983
3984 match=0;
3985 j=1;
3986
3987 for (i=current->mm->env_start; i< current->mm->env_end; i ++){
3988 c= get_fs_byte(i);
3989 if (match){
3990 if (j==99)
3991 c='\0';
3992 buffer[j] = c;
3993 if (!c || c == ' ' || c == '\t'){
3994 if (j){
3995 buffer[j] = '\0';
3996 setup(get_options(buffer,ints),ints);
3997 }
3998 j=0;
3999 } else
4000 j++;
4001 if (!c)
4002 break;
4003 continue;
4004 }
4005 if ((!j && !c) || (j && c == pattern[j-1]))
4006 j++;
4007 else
4008 j=0;
4009 if (j==length){
4010 match=1;
4011 j=0;
4012 }
4013 }
4014 }
4015
4016
4017 #ifdef __cplusplus
4018 extern "C" {
4019 #endif
4020 int init_module(void)
4021 {
4022 printk("inserting floppy driver for %s\n", kernel_version);
4023
4024 mod_setup("floppy=", floppy_setup);
4025
4026 return floppy_init();
4027 }
4028
4029 void cleanup_module(void)
4030 {
4031 int fdc;
4032
4033 for (fdc=0; fdc<2; fdc++)
4034 if (FDCS->address != -1){
4035 release_region(FDCS->address, 6);
4036 release_region(FDCS->address+7, 1);
4037 }
4038
4039 unregister_blkdev(MAJOR_NR, "fd");
4040
4041 blk_dev[MAJOR_NR].request_fn = 0;
4042 }
4043
4044 #ifdef __cplusplus
4045 }
4046 #endif
4047
4048 #endif