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