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