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