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