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