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