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