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