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