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