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