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