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