This source file includes following definitions.
- ms_isr
- ms_delay
- try_fdc
- get_fdc
- rel_fdc
- fd_select
- fd_deselect
- motor_on_callback
- fd_motor_on
- fd_motor_off
- floppy_off
- fd_calibrate
- fd_seek
- fd_get_drive_id
- fd_block_done
- raw_read
- raw_write
- post_write
- post_write_callback
- scan_sync
- checksum
- decode
- amiga_read
- encode
- encode_block
- putsec
- amiga_write
- dos_crc
- dos_hdr_crc
- dos_data_crc
- dos_decode_byte
- dos_decode
- dbg
- dos_read
- dos_encode_byte
- dos_encode_block
- ms_putsec
- dos_write
- flush_track_callback
- non_int_flush_track
- get_track
- amiflop_rw_cur_segment
- amiflop_queue_rq
- fd_getgeo
- fd_locked_ioctl
- fd_ioctl
- fd_probe
- floppy_open
- floppy_release
- amiga_check_events
- fd_alloc_disk
- fd_probe_drives
- floppy_find
- amiga_floppy_probe
- amiga_floppy_init
- amiga_floppy_setup
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 #include <linux/module.h>
58 #include <linux/slab.h>
59
60 #include <linux/fd.h>
61 #include <linux/hdreg.h>
62 #include <linux/delay.h>
63 #include <linux/init.h>
64 #include <linux/mutex.h>
65 #include <linux/fs.h>
66 #include <linux/blk-mq.h>
67 #include <linux/elevator.h>
68 #include <linux/interrupt.h>
69 #include <linux/platform_device.h>
70
71 #include <asm/setup.h>
72 #include <linux/uaccess.h>
73 #include <asm/amigahw.h>
74 #include <asm/amigaints.h>
75 #include <asm/irq.h>
76
77 #undef DEBUG
78
79 #define RAW_IOCTL
80 #ifdef RAW_IOCTL
81 #define IOCTL_RAW_TRACK 0x5254524B
82 #endif
83
84
85
86
87
88
89
90
91
92 #define DSKRDY (0x1<<5)
93 #define DSKTRACK0 (0x1<<4)
94 #define DSKPROT (0x1<<3)
95 #define DSKCHANGE (0x1<<2)
96
97
98
99
100
101 #define DSKMOTOR (0x1<<7)
102 #define DSKSEL3 (0x1<<6)
103 #define DSKSEL2 (0x1<<5)
104 #define DSKSEL1 (0x1<<4)
105 #define DSKSEL0 (0x1<<3)
106 #define DSKSIDE (0x1<<2)
107 #define DSKDIREC (0x1<<1)
108 #define DSKSTEP (0x1)
109
110
111
112
113
114 #define DSKBYT (1<<15)
115 #define DMAON (1<<14)
116 #define DISKWRITE (1<<13)
117 #define WORDEQUAL (1<<12)
118
119
120
121
122
123
124 #ifndef SETCLR
125 #define ADK_SETCLR (1<<15)
126 #endif
127 #define ADK_PRECOMP1 (1<<14)
128 #define ADK_PRECOMP0 (1<<13)
129 #define ADK_MFMPREC (1<<12)
130 #define ADK_WORDSYNC (1<<10)
131 #define ADK_MSBSYNC (1<<9)
132 #define ADK_FAST (1<<8)
133
134
135
136
137
138 #define DSKLEN_DMAEN (1<<15)
139 #define DSKLEN_WRITE (1<<14)
140
141
142
143
144
145 #define DSKINDEX (0x1<<4)
146
147
148
149
150
151 #define MFM_SYNC 0x4489
152
153
154 #define FD_RECALIBRATE 0x07
155 #define FD_SEEK 0x0F
156 #define FD_READ 0xE6
157 #define FD_WRITE 0xC5
158 #define FD_SENSEI 0x08
159 #define FD_SPECIFY 0x03
160 #define FD_FORMAT 0x4D
161 #define FD_VERSION 0x10
162 #define FD_CONFIGURE 0x13
163 #define FD_PERPENDICULAR 0x12
164
165 #define FD_MAX_UNITS 4
166 #define FLOPPY_MAX_SECTORS 22
167
168 struct fd_data_type {
169 char *name;
170 int sects;
171 int (*read_fkt)(int);
172 void (*write_fkt)(int);
173 };
174
175 struct fd_drive_type {
176 unsigned long code;
177 char *name;
178 unsigned int tracks;
179 unsigned int heads;
180 unsigned int read_size;
181 unsigned int write_size;
182 unsigned int sect_mult;
183 unsigned int precomp1;
184 unsigned int precomp2;
185 unsigned int step_delay;
186 unsigned int settle_time;
187 unsigned int side_time;
188 };
189
190 struct amiga_floppy_struct {
191 struct fd_drive_type *type;
192 struct fd_data_type *dtype;
193 int track;
194 unsigned char *trackbuf;
195
196 int blocks;
197
198 int changed;
199 int disk;
200 int motor;
201 int busy;
202 int dirty;
203 int status;
204 struct gendisk *gendisk;
205 struct blk_mq_tag_set tag_set;
206 };
207
208
209
210
211 #define FD_OK 0
212 #define FD_ERROR -1
213 #define FD_NOUNIT 1
214 #define FD_UNITBUSY 2
215 #define FD_NOTACTIVE 3
216 #define FD_NOTREADY 4
217
218 #define MFM_NOSYNC 1
219 #define MFM_HEADER 2
220 #define MFM_DATA 3
221 #define MFM_TRACK 4
222
223
224
225
226 #define FD_NODRIVE 0x00000000
227 #define FD_DD_3 0xffffffff
228 #define FD_HD_3 0x55555555
229 #define FD_DD_5 0xaaaaaaaa
230
231 static DEFINE_MUTEX(amiflop_mutex);
232 static unsigned long int fd_def_df0 = FD_DD_3;
233
234 module_param(fd_def_df0, ulong, 0);
235 MODULE_LICENSE("GPL");
236
237
238
239
240 #define MOTOR_ON (ciab.prb &= ~DSKMOTOR)
241 #define MOTOR_OFF (ciab.prb |= DSKMOTOR)
242 #define SELECT(mask) (ciab.prb &= ~mask)
243 #define DESELECT(mask) (ciab.prb |= mask)
244 #define SELMASK(drive) (1 << (3 + (drive & 3)))
245
246 static struct fd_drive_type drive_types[] = {
247
248
249 { FD_DD_3, "DD 3.5", 80, 2, 14716, 13630, 1, 80,161, 3, 18, 1},
250 { FD_HD_3, "HD 3.5", 80, 2, 28344, 27258, 2, 80,161, 3, 18, 1},
251 { FD_DD_5, "DD 5.25", 40, 2, 14716, 13630, 1, 40, 81, 6, 30, 2},
252 { FD_NODRIVE, "No Drive", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
253 };
254 static int num_dr_types = ARRAY_SIZE(drive_types);
255
256 static int amiga_read(int), dos_read(int);
257 static void amiga_write(int), dos_write(int);
258 static struct fd_data_type data_types[] = {
259 { "Amiga", 11 , amiga_read, amiga_write},
260 { "MS-Dos", 9, dos_read, dos_write}
261 };
262
263
264 static struct amiga_floppy_struct unit[FD_MAX_UNITS];
265
266 static struct timer_list flush_track_timer[FD_MAX_UNITS];
267 static struct timer_list post_write_timer;
268 static unsigned long post_write_timer_drive;
269 static struct timer_list motor_on_timer;
270 static struct timer_list motor_off_timer[FD_MAX_UNITS];
271 static int on_attempts;
272
273
274
275 static volatile int fdc_busy = -1;
276 static volatile int fdc_nested;
277 static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
278
279 static DECLARE_COMPLETION(motor_on_completion);
280
281 static volatile int selected = -1;
282
283 static int writepending;
284 static int writefromint;
285 static char *raw_buf;
286
287 static DEFINE_SPINLOCK(amiflop_lock);
288
289 #define RAW_BUF_SIZE 30000
290
291
292
293
294
295
296 static volatile char block_flag;
297 static DECLARE_WAIT_QUEUE_HEAD(wait_fd_block);
298
299
300 static unsigned char mfmencode[16]={
301 0x2a, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15,
302 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55
303 };
304 static unsigned char mfmdecode[128];
305
306
307 static DECLARE_COMPLETION(ms_wait_completion);
308 #define MS_TICKS ((amiga_eclock+50)/1000)
309
310
311
312
313
314
315 #define MAX_ERRORS 12
316
317 #define custom amiga_custom
318
319
320 static int fd_ref[4] = { 0,0,0,0 };
321 static int fd_device[4] = { 0, 0, 0, 0 };
322
323
324
325
326
327
328
329
330
331 static irqreturn_t ms_isr(int irq, void *dummy)
332 {
333 complete(&ms_wait_completion);
334 return IRQ_HANDLED;
335 }
336
337
338
339 static void ms_delay(int ms)
340 {
341 int ticks;
342 static DEFINE_MUTEX(mutex);
343
344 if (ms > 0) {
345 mutex_lock(&mutex);
346 ticks = MS_TICKS*ms-1;
347 ciaa.tblo=ticks%256;
348 ciaa.tbhi=ticks/256;
349 ciaa.crb=0x19;
350 wait_for_completion(&ms_wait_completion);
351 mutex_unlock(&mutex);
352 }
353 }
354
355
356
357
358 static inline int try_fdc(int drive)
359 {
360 drive &= 3;
361 return ((fdc_busy < 0) || (fdc_busy == drive));
362 }
363
364 static void get_fdc(int drive)
365 {
366 unsigned long flags;
367
368 drive &= 3;
369 #ifdef DEBUG
370 printk("get_fdc: drive %d fdc_busy %d fdc_nested %d\n",drive,fdc_busy,fdc_nested);
371 #endif
372 local_irq_save(flags);
373 wait_event(fdc_wait, try_fdc(drive));
374 fdc_busy = drive;
375 fdc_nested++;
376 local_irq_restore(flags);
377 }
378
379 static inline void rel_fdc(void)
380 {
381 #ifdef DEBUG
382 if (fdc_nested == 0)
383 printk("fd: unmatched rel_fdc\n");
384 printk("rel_fdc: fdc_busy %d fdc_nested %d\n",fdc_busy,fdc_nested);
385 #endif
386 fdc_nested--;
387 if (fdc_nested == 0) {
388 fdc_busy = -1;
389 wake_up(&fdc_wait);
390 }
391 }
392
393 static void fd_select (int drive)
394 {
395 unsigned char prb = ~0;
396
397 drive&=3;
398 #ifdef DEBUG
399 printk("selecting %d\n",drive);
400 #endif
401 if (drive == selected)
402 return;
403 get_fdc(drive);
404 selected = drive;
405
406 if (unit[drive].track % 2 != 0)
407 prb &= ~DSKSIDE;
408 if (unit[drive].motor == 1)
409 prb &= ~DSKMOTOR;
410 ciab.prb |= (SELMASK(0)|SELMASK(1)|SELMASK(2)|SELMASK(3));
411 ciab.prb = prb;
412 prb &= ~SELMASK(drive);
413 ciab.prb = prb;
414 rel_fdc();
415 }
416
417 static void fd_deselect (int drive)
418 {
419 unsigned char prb;
420 unsigned long flags;
421
422 drive&=3;
423 #ifdef DEBUG
424 printk("deselecting %d\n",drive);
425 #endif
426 if (drive != selected) {
427 printk(KERN_WARNING "Deselecting drive %d while %d was selected!\n",drive,selected);
428 return;
429 }
430
431 get_fdc(drive);
432 local_irq_save(flags);
433
434 selected = -1;
435
436 prb = ciab.prb;
437 prb |= (SELMASK(0)|SELMASK(1)|SELMASK(2)|SELMASK(3));
438 ciab.prb = prb;
439
440 local_irq_restore (flags);
441 rel_fdc();
442
443 }
444
445 static void motor_on_callback(struct timer_list *unused)
446 {
447 if (!(ciaa.pra & DSKRDY) || --on_attempts == 0) {
448 complete_all(&motor_on_completion);
449 } else {
450 motor_on_timer.expires = jiffies + HZ/10;
451 add_timer(&motor_on_timer);
452 }
453 }
454
455 static int fd_motor_on(int nr)
456 {
457 nr &= 3;
458
459 del_timer(motor_off_timer + nr);
460
461 if (!unit[nr].motor) {
462 unit[nr].motor = 1;
463 fd_select(nr);
464
465 reinit_completion(&motor_on_completion);
466 mod_timer(&motor_on_timer, jiffies + HZ/2);
467
468 on_attempts = 10;
469 wait_for_completion(&motor_on_completion);
470 fd_deselect(nr);
471 }
472
473 if (on_attempts == 0) {
474 on_attempts = -1;
475 #if 0
476 printk (KERN_ERR "motor_on failed, turning motor off\n");
477 fd_motor_off (motor_off_timer + nr);
478 return 0;
479 #else
480 printk (KERN_WARNING "DSKRDY not set after 1.5 seconds - assuming drive is spinning notwithstanding\n");
481 #endif
482 }
483
484 return 1;
485 }
486
487 static void fd_motor_off(struct timer_list *timer)
488 {
489 unsigned long drive = ((unsigned long)timer -
490 (unsigned long)&motor_off_timer[0]) /
491 sizeof(motor_off_timer[0]);
492
493 drive&=3;
494 if (!try_fdc(drive)) {
495
496 timer->expires = jiffies + 1;
497 add_timer(timer);
498 return;
499 }
500 unit[drive].motor = 0;
501 fd_select(drive);
502 udelay (1);
503 fd_deselect(drive);
504 }
505
506 static void floppy_off (unsigned int nr)
507 {
508 int drive;
509
510 drive = nr & 3;
511 mod_timer(motor_off_timer + drive, jiffies + 3*HZ);
512 }
513
514 static int fd_calibrate(int drive)
515 {
516 unsigned char prb;
517 int n;
518
519 drive &= 3;
520 get_fdc(drive);
521 if (!fd_motor_on (drive))
522 return 0;
523 fd_select (drive);
524 prb = ciab.prb;
525 prb |= DSKSIDE;
526 prb &= ~DSKDIREC;
527 ciab.prb = prb;
528 for (n = unit[drive].type->tracks/2; n != 0; --n) {
529 if (ciaa.pra & DSKTRACK0)
530 break;
531 prb &= ~DSKSTEP;
532 ciab.prb = prb;
533 prb |= DSKSTEP;
534 udelay (2);
535 ciab.prb = prb;
536 ms_delay(unit[drive].type->step_delay);
537 }
538 ms_delay (unit[drive].type->settle_time);
539 prb |= DSKDIREC;
540 n = unit[drive].type->tracks + 20;
541 for (;;) {
542 prb &= ~DSKSTEP;
543 ciab.prb = prb;
544 prb |= DSKSTEP;
545 udelay (2);
546 ciab.prb = prb;
547 ms_delay(unit[drive].type->step_delay + 1);
548 if ((ciaa.pra & DSKTRACK0) == 0)
549 break;
550 if (--n == 0) {
551 printk (KERN_ERR "fd%d: calibrate failed, turning motor off\n", drive);
552 fd_motor_off (motor_off_timer + drive);
553 unit[drive].track = -1;
554 rel_fdc();
555 return 0;
556 }
557 }
558 unit[drive].track = 0;
559 ms_delay(unit[drive].type->settle_time);
560
561 rel_fdc();
562 fd_deselect(drive);
563 return 1;
564 }
565
566 static int fd_seek(int drive, int track)
567 {
568 unsigned char prb;
569 int cnt;
570
571 #ifdef DEBUG
572 printk("seeking drive %d to track %d\n",drive,track);
573 #endif
574 drive &= 3;
575 get_fdc(drive);
576 if (unit[drive].track == track) {
577 rel_fdc();
578 return 1;
579 }
580 if (!fd_motor_on(drive)) {
581 rel_fdc();
582 return 0;
583 }
584 if (unit[drive].track < 0 && !fd_calibrate(drive)) {
585 rel_fdc();
586 return 0;
587 }
588
589 fd_select (drive);
590 cnt = unit[drive].track/2 - track/2;
591 prb = ciab.prb;
592 prb |= DSKSIDE | DSKDIREC;
593 if (track % 2 != 0)
594 prb &= ~DSKSIDE;
595 if (cnt < 0) {
596 cnt = - cnt;
597 prb &= ~DSKDIREC;
598 }
599 ciab.prb = prb;
600 if (track % 2 != unit[drive].track % 2)
601 ms_delay (unit[drive].type->side_time);
602 unit[drive].track = track;
603 if (cnt == 0) {
604 rel_fdc();
605 fd_deselect(drive);
606 return 1;
607 }
608 do {
609 prb &= ~DSKSTEP;
610 ciab.prb = prb;
611 prb |= DSKSTEP;
612 udelay (1);
613 ciab.prb = prb;
614 ms_delay (unit[drive].type->step_delay);
615 } while (--cnt != 0);
616 ms_delay (unit[drive].type->settle_time);
617
618 rel_fdc();
619 fd_deselect(drive);
620 return 1;
621 }
622
623 static unsigned long fd_get_drive_id(int drive)
624 {
625 int i;
626 ulong id = 0;
627
628 drive&=3;
629 get_fdc(drive);
630
631 MOTOR_ON;
632 udelay(2);
633 SELECT(SELMASK(drive));
634 udelay(2);
635 DESELECT(SELMASK(drive));
636 udelay(2);
637 MOTOR_OFF;
638 udelay(2);
639 SELECT(SELMASK(drive));
640 udelay(2);
641 DESELECT(SELMASK(drive));
642 udelay(2);
643
644
645 for (i=0; i<32; i++) {
646 SELECT(SELMASK(drive));
647 udelay(2);
648
649
650 id <<= 1;
651 id |= (ciaa.pra & DSKRDY) ? 0 : 1;
652
653 DESELECT(SELMASK(drive));
654 }
655
656 rel_fdc();
657
658
659
660
661
662
663
664 if(drive == 0 && id == FD_NODRIVE)
665 {
666 id = fd_def_df0;
667 printk(KERN_NOTICE "fd: drive 0 didn't identify, setting default %08lx\n", (ulong)fd_def_df0);
668 }
669
670 return (id);
671 }
672
673 static irqreturn_t fd_block_done(int irq, void *dummy)
674 {
675 if (block_flag)
676 custom.dsklen = 0x4000;
677
678 if (block_flag == 2) {
679 writepending = 2;
680 post_write_timer.expires = jiffies + 1;
681 post_write_timer_drive = selected;
682 add_timer(&post_write_timer);
683 }
684 else {
685 block_flag = 0;
686 wake_up (&wait_fd_block);
687 }
688 return IRQ_HANDLED;
689 }
690
691 static void raw_read(int drive)
692 {
693 drive&=3;
694 get_fdc(drive);
695 wait_event(wait_fd_block, !block_flag);
696 fd_select(drive);
697
698 custom.adkcon = ADK_MSBSYNC;
699 custom.adkcon = ADK_SETCLR|ADK_WORDSYNC|ADK_FAST;
700
701 custom.dsksync = MFM_SYNC;
702
703 custom.dsklen = 0;
704 custom.dskptr = (u_char *)ZTWO_PADDR((u_char *)raw_buf);
705 custom.dsklen = unit[drive].type->read_size/sizeof(short) | DSKLEN_DMAEN;
706 custom.dsklen = unit[drive].type->read_size/sizeof(short) | DSKLEN_DMAEN;
707
708 block_flag = 1;
709
710 wait_event(wait_fd_block, !block_flag);
711
712 custom.dsklen = 0;
713 fd_deselect(drive);
714 rel_fdc();
715 }
716
717 static int raw_write(int drive)
718 {
719 ushort adk;
720
721 drive&=3;
722 get_fdc(drive);
723 if ((ciaa.pra & DSKPROT) == 0) {
724 rel_fdc();
725 return 0;
726 }
727 wait_event(wait_fd_block, !block_flag);
728 fd_select(drive);
729
730 custom.adkcon = ADK_PRECOMP1|ADK_PRECOMP0|ADK_WORDSYNC|ADK_MSBSYNC;
731
732 adk = ADK_SETCLR|ADK_FAST;
733 if ((ulong)unit[drive].track >= unit[drive].type->precomp2)
734 adk |= ADK_PRECOMP1;
735 else if ((ulong)unit[drive].track >= unit[drive].type->precomp1)
736 adk |= ADK_PRECOMP0;
737 custom.adkcon = adk;
738
739 custom.dsklen = DSKLEN_WRITE;
740 custom.dskptr = (u_char *)ZTWO_PADDR((u_char *)raw_buf);
741 custom.dsklen = unit[drive].type->write_size/sizeof(short) | DSKLEN_DMAEN|DSKLEN_WRITE;
742 custom.dsklen = unit[drive].type->write_size/sizeof(short) | DSKLEN_DMAEN|DSKLEN_WRITE;
743
744 block_flag = 2;
745 return 1;
746 }
747
748
749
750
751
752 static void post_write (unsigned long drive)
753 {
754 #ifdef DEBUG
755 printk("post_write for drive %ld\n",drive);
756 #endif
757 drive &= 3;
758 custom.dsklen = 0;
759 block_flag = 0;
760 writepending = 0;
761 writefromint = 0;
762 unit[drive].dirty = 0;
763 wake_up(&wait_fd_block);
764 fd_deselect(drive);
765 rel_fdc();
766 }
767
768 static void post_write_callback(struct timer_list *timer)
769 {
770 post_write(post_write_timer_drive);
771 }
772
773
774
775
776
777
778
779 static unsigned long scan_sync(unsigned long raw, unsigned long end)
780 {
781 ushort *ptr = (ushort *)raw, *endp = (ushort *)end;
782
783 while (ptr < endp && *ptr++ != 0x4489)
784 ;
785 if (ptr < endp) {
786 while (*ptr == 0x4489 && ptr < endp)
787 ptr++;
788 return (ulong)ptr;
789 }
790 return 0;
791 }
792
793 static inline unsigned long checksum(unsigned long *addr, int len)
794 {
795 unsigned long csum = 0;
796
797 len /= sizeof(*addr);
798 while (len-- > 0)
799 csum ^= *addr++;
800 csum = ((csum>>1) & 0x55555555) ^ (csum & 0x55555555);
801
802 return csum;
803 }
804
805 static unsigned long decode (unsigned long *data, unsigned long *raw,
806 int len)
807 {
808 ulong *odd, *even;
809
810
811 len >>= 2;
812 odd = raw;
813 even = odd + len;
814
815
816 raw += len * 2;
817
818 do {
819 *data++ = ((*odd++ & 0x55555555) << 1) | (*even++ & 0x55555555);
820 } while (--len != 0);
821
822 return (ulong)raw;
823 }
824
825 struct header {
826 unsigned char magic;
827 unsigned char track;
828 unsigned char sect;
829 unsigned char ord;
830 unsigned char labels[16];
831 unsigned long hdrchk;
832 unsigned long datachk;
833 };
834
835 static int amiga_read(int drive)
836 {
837 unsigned long raw;
838 unsigned long end;
839 int scnt;
840 unsigned long csum;
841 struct header hdr;
842
843 drive&=3;
844 raw = (long) raw_buf;
845 end = raw + unit[drive].type->read_size;
846
847 for (scnt = 0;scnt < unit[drive].dtype->sects * unit[drive].type->sect_mult; scnt++) {
848 if (!(raw = scan_sync(raw, end))) {
849 printk (KERN_INFO "can't find sync for sector %d\n", scnt);
850 return MFM_NOSYNC;
851 }
852
853 raw = decode ((ulong *)&hdr.magic, (ulong *)raw, 4);
854 raw = decode ((ulong *)&hdr.labels, (ulong *)raw, 16);
855 raw = decode ((ulong *)&hdr.hdrchk, (ulong *)raw, 4);
856 raw = decode ((ulong *)&hdr.datachk, (ulong *)raw, 4);
857 csum = checksum((ulong *)&hdr,
858 (char *)&hdr.hdrchk-(char *)&hdr);
859
860 #ifdef DEBUG
861 printk ("(%x,%d,%d,%d) (%lx,%lx,%lx,%lx) %lx %lx\n",
862 hdr.magic, hdr.track, hdr.sect, hdr.ord,
863 *(ulong *)&hdr.labels[0], *(ulong *)&hdr.labels[4],
864 *(ulong *)&hdr.labels[8], *(ulong *)&hdr.labels[12],
865 hdr.hdrchk, hdr.datachk);
866 #endif
867
868 if (hdr.hdrchk != csum) {
869 printk(KERN_INFO "MFM_HEADER: %08lx,%08lx\n", hdr.hdrchk, csum);
870 return MFM_HEADER;
871 }
872
873
874 if (hdr.track != unit[drive].track) {
875 printk(KERN_INFO "MFM_TRACK: %d, %d\n", hdr.track, unit[drive].track);
876 return MFM_TRACK;
877 }
878
879 raw = decode ((ulong *)(unit[drive].trackbuf + hdr.sect*512),
880 (ulong *)raw, 512);
881 csum = checksum((ulong *)(unit[drive].trackbuf + hdr.sect*512), 512);
882
883 if (hdr.datachk != csum) {
884 printk(KERN_INFO "MFM_DATA: (%x:%d:%d:%d) sc=%d %lx, %lx\n",
885 hdr.magic, hdr.track, hdr.sect, hdr.ord, scnt,
886 hdr.datachk, csum);
887 printk (KERN_INFO "data=(%lx,%lx,%lx,%lx)\n",
888 ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[0],
889 ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[1],
890 ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[2],
891 ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[3]);
892 return MFM_DATA;
893 }
894 }
895
896 return 0;
897 }
898
899 static void encode(unsigned long data, unsigned long *dest)
900 {
901 unsigned long data2;
902
903 data &= 0x55555555;
904 data2 = data ^ 0x55555555;
905 data |= ((data2 >> 1) | 0x80000000) & (data2 << 1);
906
907 if (*(dest - 1) & 0x00000001)
908 data &= 0x7FFFFFFF;
909
910 *dest = data;
911 }
912
913 static void encode_block(unsigned long *dest, unsigned long *src, int len)
914 {
915 int cnt, to_cnt = 0;
916 unsigned long data;
917
918
919 for (cnt = 0; cnt < len / 4; cnt++) {
920 data = src[cnt] >> 1;
921 encode(data, dest + to_cnt++);
922 }
923
924
925 for (cnt = 0; cnt < len / 4; cnt++) {
926 data = src[cnt];
927 encode(data, dest + to_cnt++);
928 }
929 }
930
931 static unsigned long *putsec(int disk, unsigned long *raw, int cnt)
932 {
933 struct header hdr;
934 int i;
935
936 disk&=3;
937 *raw = (raw[-1]&1) ? 0x2AAAAAAA : 0xAAAAAAAA;
938 raw++;
939 *raw++ = 0x44894489;
940
941 hdr.magic = 0xFF;
942 hdr.track = unit[disk].track;
943 hdr.sect = cnt;
944 hdr.ord = unit[disk].dtype->sects * unit[disk].type->sect_mult - cnt;
945 for (i = 0; i < 16; i++)
946 hdr.labels[i] = 0;
947 hdr.hdrchk = checksum((ulong *)&hdr,
948 (char *)&hdr.hdrchk-(char *)&hdr);
949 hdr.datachk = checksum((ulong *)(unit[disk].trackbuf+cnt*512), 512);
950
951 encode_block(raw, (ulong *)&hdr.magic, 4);
952 raw += 2;
953 encode_block(raw, (ulong *)&hdr.labels, 16);
954 raw += 8;
955 encode_block(raw, (ulong *)&hdr.hdrchk, 4);
956 raw += 2;
957 encode_block(raw, (ulong *)&hdr.datachk, 4);
958 raw += 2;
959 encode_block(raw, (ulong *)(unit[disk].trackbuf+cnt*512), 512);
960 raw += 256;
961
962 return raw;
963 }
964
965 static void amiga_write(int disk)
966 {
967 unsigned int cnt;
968 unsigned long *ptr = (unsigned long *)raw_buf;
969
970 disk&=3;
971
972 for (cnt = 0; cnt < 415 * unit[disk].type->sect_mult; cnt++)
973 *ptr++ = 0xaaaaaaaa;
974
975
976 for (cnt = 0; cnt < unit[disk].dtype->sects * unit[disk].type->sect_mult; cnt++)
977 ptr = putsec (disk, ptr, cnt);
978 *(ushort *)ptr = (ptr[-1]&1) ? 0x2AA8 : 0xAAA8;
979 }
980
981
982 struct dos_header {
983 unsigned char track,
984 side,
985 sec,
986 len_desc;
987 unsigned short crc;
988
989
990
991 unsigned char gap1[22];
992 };
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 static ushort dos_crc(void * data_a3, int data_d0, int data_d1, int data_d3)
1050 {
1051 static unsigned char CRCTable1[] = {
1052 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x81,0x91,0xa1,0xb1,0xc1,0xd1,0xe1,0xf1,
1053 0x12,0x02,0x32,0x22,0x52,0x42,0x72,0x62,0x93,0x83,0xb3,0xa3,0xd3,0xc3,0xf3,0xe3,
1054 0x24,0x34,0x04,0x14,0x64,0x74,0x44,0x54,0xa5,0xb5,0x85,0x95,0xe5,0xf5,0xc5,0xd5,
1055 0x36,0x26,0x16,0x06,0x76,0x66,0x56,0x46,0xb7,0xa7,0x97,0x87,0xf7,0xe7,0xd7,0xc7,
1056 0x48,0x58,0x68,0x78,0x08,0x18,0x28,0x38,0xc9,0xd9,0xe9,0xf9,0x89,0x99,0xa9,0xb9,
1057 0x5a,0x4a,0x7a,0x6a,0x1a,0x0a,0x3a,0x2a,0xdb,0xcb,0xfb,0xeb,0x9b,0x8b,0xbb,0xab,
1058 0x6c,0x7c,0x4c,0x5c,0x2c,0x3c,0x0c,0x1c,0xed,0xfd,0xcd,0xdd,0xad,0xbd,0x8d,0x9d,
1059 0x7e,0x6e,0x5e,0x4e,0x3e,0x2e,0x1e,0x0e,0xff,0xef,0xdf,0xcf,0xbf,0xaf,0x9f,0x8f,
1060 0x91,0x81,0xb1,0xa1,0xd1,0xc1,0xf1,0xe1,0x10,0x00,0x30,0x20,0x50,0x40,0x70,0x60,
1061 0x83,0x93,0xa3,0xb3,0xc3,0xd3,0xe3,0xf3,0x02,0x12,0x22,0x32,0x42,0x52,0x62,0x72,
1062 0xb5,0xa5,0x95,0x85,0xf5,0xe5,0xd5,0xc5,0x34,0x24,0x14,0x04,0x74,0x64,0x54,0x44,
1063 0xa7,0xb7,0x87,0x97,0xe7,0xf7,0xc7,0xd7,0x26,0x36,0x06,0x16,0x66,0x76,0x46,0x56,
1064 0xd9,0xc9,0xf9,0xe9,0x99,0x89,0xb9,0xa9,0x58,0x48,0x78,0x68,0x18,0x08,0x38,0x28,
1065 0xcb,0xdb,0xeb,0xfb,0x8b,0x9b,0xab,0xbb,0x4a,0x5a,0x6a,0x7a,0x0a,0x1a,0x2a,0x3a,
1066 0xfd,0xed,0xdd,0xcd,0xbd,0xad,0x9d,0x8d,0x7c,0x6c,0x5c,0x4c,0x3c,0x2c,0x1c,0x0c,
1067 0xef,0xff,0xcf,0xdf,0xaf,0xbf,0x8f,0x9f,0x6e,0x7e,0x4e,0x5e,0x2e,0x3e,0x0e,0x1e
1068 };
1069
1070 static unsigned char CRCTable2[] = {
1071 0x00,0x21,0x42,0x63,0x84,0xa5,0xc6,0xe7,0x08,0x29,0x4a,0x6b,0x8c,0xad,0xce,0xef,
1072 0x31,0x10,0x73,0x52,0xb5,0x94,0xf7,0xd6,0x39,0x18,0x7b,0x5a,0xbd,0x9c,0xff,0xde,
1073 0x62,0x43,0x20,0x01,0xe6,0xc7,0xa4,0x85,0x6a,0x4b,0x28,0x09,0xee,0xcf,0xac,0x8d,
1074 0x53,0x72,0x11,0x30,0xd7,0xf6,0x95,0xb4,0x5b,0x7a,0x19,0x38,0xdf,0xfe,0x9d,0xbc,
1075 0xc4,0xe5,0x86,0xa7,0x40,0x61,0x02,0x23,0xcc,0xed,0x8e,0xaf,0x48,0x69,0x0a,0x2b,
1076 0xf5,0xd4,0xb7,0x96,0x71,0x50,0x33,0x12,0xfd,0xdc,0xbf,0x9e,0x79,0x58,0x3b,0x1a,
1077 0xa6,0x87,0xe4,0xc5,0x22,0x03,0x60,0x41,0xae,0x8f,0xec,0xcd,0x2a,0x0b,0x68,0x49,
1078 0x97,0xb6,0xd5,0xf4,0x13,0x32,0x51,0x70,0x9f,0xbe,0xdd,0xfc,0x1b,0x3a,0x59,0x78,
1079 0x88,0xa9,0xca,0xeb,0x0c,0x2d,0x4e,0x6f,0x80,0xa1,0xc2,0xe3,0x04,0x25,0x46,0x67,
1080 0xb9,0x98,0xfb,0xda,0x3d,0x1c,0x7f,0x5e,0xb1,0x90,0xf3,0xd2,0x35,0x14,0x77,0x56,
1081 0xea,0xcb,0xa8,0x89,0x6e,0x4f,0x2c,0x0d,0xe2,0xc3,0xa0,0x81,0x66,0x47,0x24,0x05,
1082 0xdb,0xfa,0x99,0xb8,0x5f,0x7e,0x1d,0x3c,0xd3,0xf2,0x91,0xb0,0x57,0x76,0x15,0x34,
1083 0x4c,0x6d,0x0e,0x2f,0xc8,0xe9,0x8a,0xab,0x44,0x65,0x06,0x27,0xc0,0xe1,0x82,0xa3,
1084 0x7d,0x5c,0x3f,0x1e,0xf9,0xd8,0xbb,0x9a,0x75,0x54,0x37,0x16,0xf1,0xd0,0xb3,0x92,
1085 0x2e,0x0f,0x6c,0x4d,0xaa,0x8b,0xe8,0xc9,0x26,0x07,0x64,0x45,0xa2,0x83,0xe0,0xc1,
1086 0x1f,0x3e,0x5d,0x7c,0x9b,0xba,0xd9,0xf8,0x17,0x36,0x55,0x74,0x93,0xb2,0xd1,0xf0
1087 };
1088
1089
1090 register int i;
1091 register unsigned char *CRCT1, *CRCT2, *data, c, crch, crcl;
1092
1093 CRCT1=CRCTable1;
1094 CRCT2=CRCTable2;
1095 data=data_a3;
1096 crcl=data_d1;
1097 crch=data_d0;
1098 for (i=data_d3; i>=0; i--) {
1099 c = (*data++) ^ crch;
1100 crch = CRCT1[c] ^ crcl;
1101 crcl = CRCT2[c];
1102 }
1103 return (crch<<8)|crcl;
1104 }
1105
1106 static inline ushort dos_hdr_crc (struct dos_header *hdr)
1107 {
1108 return dos_crc(&(hdr->track), 0xb2, 0x30, 3);
1109 }
1110
1111 static inline ushort dos_data_crc(unsigned char *data)
1112 {
1113 return dos_crc(data, 0xe2, 0x95 ,511);
1114 }
1115
1116 static inline unsigned char dos_decode_byte(ushort word)
1117 {
1118 register ushort w2;
1119 register unsigned char byte;
1120 register unsigned char *dec = mfmdecode;
1121
1122 w2=word;
1123 w2>>=8;
1124 w2&=127;
1125 byte = dec[w2];
1126 byte <<= 4;
1127 w2 = word & 127;
1128 byte |= dec[w2];
1129 return byte;
1130 }
1131
1132 static unsigned long dos_decode(unsigned char *data, unsigned short *raw, int len)
1133 {
1134 int i;
1135
1136 for (i = 0; i < len; i++)
1137 *data++=dos_decode_byte(*raw++);
1138 return ((ulong)raw);
1139 }
1140
1141 #ifdef DEBUG
1142 static void dbg(unsigned long ptr)
1143 {
1144 printk("raw data @%08lx: %08lx, %08lx ,%08lx, %08lx\n", ptr,
1145 ((ulong *)ptr)[0], ((ulong *)ptr)[1],
1146 ((ulong *)ptr)[2], ((ulong *)ptr)[3]);
1147 }
1148 #endif
1149
1150 static int dos_read(int drive)
1151 {
1152 unsigned long end;
1153 unsigned long raw;
1154 int scnt;
1155 unsigned short crc,data_crc[2];
1156 struct dos_header hdr;
1157
1158 drive&=3;
1159 raw = (long) raw_buf;
1160 end = raw + unit[drive].type->read_size;
1161
1162 for (scnt=0; scnt < unit[drive].dtype->sects * unit[drive].type->sect_mult; scnt++) {
1163 do {
1164 if (!(raw = scan_sync (raw, end))) {
1165 printk(KERN_INFO "dos_read: no hdr sync on "
1166 "track %d, unit %d for sector %d\n",
1167 unit[drive].track,drive,scnt);
1168 return MFM_NOSYNC;
1169 }
1170 #ifdef DEBUG
1171 dbg(raw);
1172 #endif
1173 } while (*((ushort *)raw)!=0x5554);
1174 raw+=2;
1175 raw = dos_decode((unsigned char *)&hdr,(ushort *) raw,8);
1176 crc = dos_hdr_crc(&hdr);
1177
1178 #ifdef DEBUG
1179 printk("(%3d,%d,%2d,%d) %x\n", hdr.track, hdr.side,
1180 hdr.sec, hdr.len_desc, hdr.crc);
1181 #endif
1182
1183 if (crc != hdr.crc) {
1184 printk(KERN_INFO "dos_read: MFM_HEADER %04x,%04x\n",
1185 hdr.crc, crc);
1186 return MFM_HEADER;
1187 }
1188 if (hdr.track != unit[drive].track/unit[drive].type->heads) {
1189 printk(KERN_INFO "dos_read: MFM_TRACK %d, %d\n",
1190 hdr.track,
1191 unit[drive].track/unit[drive].type->heads);
1192 return MFM_TRACK;
1193 }
1194
1195 if (hdr.side != unit[drive].track%unit[drive].type->heads) {
1196 printk(KERN_INFO "dos_read: MFM_SIDE %d, %d\n",
1197 hdr.side,
1198 unit[drive].track%unit[drive].type->heads);
1199 return MFM_TRACK;
1200 }
1201
1202 if (hdr.len_desc != 2) {
1203 printk(KERN_INFO "dos_read: unknown sector len "
1204 "descriptor %d\n", hdr.len_desc);
1205 return MFM_DATA;
1206 }
1207 #ifdef DEBUG
1208 printk("hdr accepted\n");
1209 #endif
1210 if (!(raw = scan_sync (raw, end))) {
1211 printk(KERN_INFO "dos_read: no data sync on track "
1212 "%d, unit %d for sector%d, disk sector %d\n",
1213 unit[drive].track, drive, scnt, hdr.sec);
1214 return MFM_NOSYNC;
1215 }
1216 #ifdef DEBUG
1217 dbg(raw);
1218 #endif
1219
1220 if (*((ushort *)raw)!=0x5545) {
1221 printk(KERN_INFO "dos_read: no data mark after "
1222 "sync (%d,%d,%d,%d) sc=%d\n",
1223 hdr.track,hdr.side,hdr.sec,hdr.len_desc,scnt);
1224 return MFM_NOSYNC;
1225 }
1226
1227 raw+=2;
1228 raw = dos_decode((unsigned char *)(unit[drive].trackbuf + (hdr.sec - 1) * 512), (ushort *) raw, 512);
1229 raw = dos_decode((unsigned char *)data_crc,(ushort *) raw,4);
1230 crc = dos_data_crc(unit[drive].trackbuf + (hdr.sec - 1) * 512);
1231
1232 if (crc != data_crc[0]) {
1233 printk(KERN_INFO "dos_read: MFM_DATA (%d,%d,%d,%d) "
1234 "sc=%d, %x %x\n", hdr.track, hdr.side,
1235 hdr.sec, hdr.len_desc, scnt,data_crc[0], crc);
1236 printk(KERN_INFO "data=(%lx,%lx,%lx,%lx,...)\n",
1237 ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[0],
1238 ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[1],
1239 ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[2],
1240 ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[3]);
1241 return MFM_DATA;
1242 }
1243 }
1244 return 0;
1245 }
1246
1247 static inline ushort dos_encode_byte(unsigned char byte)
1248 {
1249 register unsigned char *enc, b2, b1;
1250 register ushort word;
1251
1252 enc=mfmencode;
1253 b1=byte;
1254 b2=b1>>4;
1255 b1&=15;
1256 word=enc[b2] <<8 | enc [b1];
1257 return (word|((word&(256|64)) ? 0: 128));
1258 }
1259
1260 static void dos_encode_block(ushort *dest, unsigned char *src, int len)
1261 {
1262 int i;
1263
1264 for (i = 0; i < len; i++) {
1265 *dest=dos_encode_byte(*src++);
1266 *dest|=((dest[-1]&1)||(*dest&0x4000))? 0: 0x8000;
1267 dest++;
1268 }
1269 }
1270
1271 static unsigned long *ms_putsec(int drive, unsigned long *raw, int cnt)
1272 {
1273 static struct dos_header hdr={0,0,0,2,0,
1274 {78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78}};
1275 int i;
1276 static ushort crc[2]={0,0x4e4e};
1277
1278 drive&=3;
1279
1280
1281 for(i=0;i<6;i++)
1282 *raw++=0xaaaaaaaa;
1283
1284 *raw++=0x44894489;
1285 *raw++=0x44895554;
1286
1287
1288 hdr.track=unit[drive].track/unit[drive].type->heads;
1289 hdr.side=unit[drive].track%unit[drive].type->heads;
1290 hdr.sec=cnt+1;
1291 hdr.crc=dos_hdr_crc(&hdr);
1292
1293
1294 dos_encode_block((ushort *)raw,(unsigned char *) &hdr.track,28);
1295 raw+=14;
1296
1297
1298 for(i=0;i<6;i++)
1299 *raw++=0xaaaaaaaa;
1300
1301
1302 *raw++=0x44894489;
1303 *raw++=0x44895545;
1304
1305
1306 dos_encode_block((ushort *)raw,
1307 (unsigned char *)unit[drive].trackbuf+cnt*512,512);
1308 raw+=256;
1309
1310
1311 crc[0]=dos_data_crc(unit[drive].trackbuf+cnt*512);
1312 dos_encode_block((ushort *) raw,(unsigned char *)crc,4);
1313 raw+=2;
1314
1315
1316 for(i=0;i<38;i++)
1317 *raw++=0x92549254;
1318
1319 return raw;
1320 }
1321
1322 static void dos_write(int disk)
1323 {
1324 int cnt;
1325 unsigned long raw = (unsigned long) raw_buf;
1326 unsigned long *ptr=(unsigned long *)raw;
1327
1328 disk&=3;
1329
1330 for (cnt=0;cnt<425;cnt++)
1331 *ptr++=0x92549254;
1332
1333
1334 if (unit[disk].type->sect_mult==2)
1335 for(cnt=0;cnt<473;cnt++)
1336 *ptr++=0x92549254;
1337
1338
1339 for (cnt=0;cnt<20;cnt++)
1340 *ptr++=0x92549254;
1341 for (cnt=0;cnt<6;cnt++)
1342 *ptr++=0xaaaaaaaa;
1343 *ptr++=0x52245224;
1344 *ptr++=0x52245552;
1345 for (cnt=0;cnt<20;cnt++)
1346 *ptr++=0x92549254;
1347
1348
1349 for(cnt = 0; cnt < unit[disk].dtype->sects * unit[disk].type->sect_mult; cnt++)
1350 ptr=ms_putsec(disk,ptr,cnt);
1351
1352 *(ushort *)ptr = 0xaaa8;
1353 }
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365 static void flush_track_callback(struct timer_list *timer)
1366 {
1367 unsigned long nr = ((unsigned long)timer -
1368 (unsigned long)&flush_track_timer[0]) /
1369 sizeof(flush_track_timer[0]);
1370
1371 nr&=3;
1372 writefromint = 1;
1373 if (!try_fdc(nr)) {
1374
1375 flush_track_timer[nr].expires = jiffies + 1;
1376 add_timer(flush_track_timer + nr);
1377 return;
1378 }
1379 get_fdc(nr);
1380 (*unit[nr].dtype->write_fkt)(nr);
1381 if (!raw_write(nr)) {
1382 printk (KERN_NOTICE "floppy disk write protected\n");
1383 writefromint = 0;
1384 writepending = 0;
1385 }
1386 rel_fdc();
1387 }
1388
1389 static int non_int_flush_track (unsigned long nr)
1390 {
1391 unsigned long flags;
1392
1393 nr&=3;
1394 writefromint = 0;
1395 del_timer(&post_write_timer);
1396 get_fdc(nr);
1397 if (!fd_motor_on(nr)) {
1398 writepending = 0;
1399 rel_fdc();
1400 return 0;
1401 }
1402 local_irq_save(flags);
1403 if (writepending != 2) {
1404 local_irq_restore(flags);
1405 (*unit[nr].dtype->write_fkt)(nr);
1406 if (!raw_write(nr)) {
1407 printk (KERN_NOTICE "floppy disk write protected "
1408 "in write!\n");
1409 writepending = 0;
1410 return 0;
1411 }
1412 wait_event(wait_fd_block, block_flag != 2);
1413 }
1414 else {
1415 local_irq_restore(flags);
1416 ms_delay(2);
1417 post_write(nr);
1418 }
1419 rel_fdc();
1420 return 1;
1421 }
1422
1423 static int get_track(int drive, int track)
1424 {
1425 int error, errcnt;
1426
1427 drive&=3;
1428 if (unit[drive].track == track)
1429 return 0;
1430 get_fdc(drive);
1431 if (!fd_motor_on(drive)) {
1432 rel_fdc();
1433 return -1;
1434 }
1435
1436 if (unit[drive].dirty == 1) {
1437 del_timer (flush_track_timer + drive);
1438 non_int_flush_track (drive);
1439 }
1440 errcnt = 0;
1441 while (errcnt < MAX_ERRORS) {
1442 if (!fd_seek(drive, track))
1443 return -1;
1444 raw_read(drive);
1445 error = (*unit[drive].dtype->read_fkt)(drive);
1446 if (error == 0) {
1447 rel_fdc();
1448 return 0;
1449 }
1450
1451 unit[drive].track = -1;
1452 errcnt++;
1453 }
1454 rel_fdc();
1455 return -1;
1456 }
1457
1458 static blk_status_t amiflop_rw_cur_segment(struct amiga_floppy_struct *floppy,
1459 struct request *rq)
1460 {
1461 int drive = floppy - unit;
1462 unsigned int cnt, block, track, sector;
1463 char *data;
1464
1465 for (cnt = 0; cnt < blk_rq_cur_sectors(rq); cnt++) {
1466 #ifdef DEBUG
1467 printk("fd: sector %ld + %d requested for %s\n",
1468 blk_rq_pos(rq), cnt,
1469 (rq_data_dir(rq) == READ) ? "read" : "write");
1470 #endif
1471 block = blk_rq_pos(rq) + cnt;
1472 track = block / (floppy->dtype->sects * floppy->type->sect_mult);
1473 sector = block % (floppy->dtype->sects * floppy->type->sect_mult);
1474 data = bio_data(rq->bio) + 512 * cnt;
1475 #ifdef DEBUG
1476 printk("access to track %d, sector %d, with buffer at "
1477 "0x%08lx\n", track, sector, data);
1478 #endif
1479
1480 if (get_track(drive, track) == -1)
1481 return BLK_STS_IOERR;
1482
1483 if (rq_data_dir(rq) == READ) {
1484 memcpy(data, floppy->trackbuf + sector * 512, 512);
1485 } else {
1486 memcpy(floppy->trackbuf + sector * 512, data, 512);
1487
1488
1489 if (!fd_motor_on(drive))
1490 return BLK_STS_IOERR;
1491
1492
1493
1494
1495 floppy->dirty = 1;
1496
1497 mod_timer (flush_track_timer + drive, jiffies + 1);
1498 }
1499 }
1500
1501 return BLK_STS_OK;
1502 }
1503
1504 static blk_status_t amiflop_queue_rq(struct blk_mq_hw_ctx *hctx,
1505 const struct blk_mq_queue_data *bd)
1506 {
1507 struct request *rq = bd->rq;
1508 struct amiga_floppy_struct *floppy = rq->rq_disk->private_data;
1509 blk_status_t err;
1510
1511 if (!spin_trylock_irq(&amiflop_lock))
1512 return BLK_STS_DEV_RESOURCE;
1513
1514 blk_mq_start_request(rq);
1515
1516 do {
1517 err = amiflop_rw_cur_segment(floppy, rq);
1518 } while (blk_update_request(rq, err, blk_rq_cur_bytes(rq)));
1519 blk_mq_end_request(rq, err);
1520
1521 spin_unlock_irq(&amiflop_lock);
1522 return BLK_STS_OK;
1523 }
1524
1525 static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1526 {
1527 int drive = MINOR(bdev->bd_dev) & 3;
1528
1529 geo->heads = unit[drive].type->heads;
1530 geo->sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
1531 geo->cylinders = unit[drive].type->tracks;
1532 return 0;
1533 }
1534
1535 static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
1536 unsigned int cmd, unsigned long param)
1537 {
1538 struct amiga_floppy_struct *p = bdev->bd_disk->private_data;
1539 int drive = p - unit;
1540 static struct floppy_struct getprm;
1541 void __user *argp = (void __user *)param;
1542
1543 switch(cmd){
1544 case FDFMTBEG:
1545 get_fdc(drive);
1546 if (fd_ref[drive] > 1) {
1547 rel_fdc();
1548 return -EBUSY;
1549 }
1550 fsync_bdev(bdev);
1551 if (fd_motor_on(drive) == 0) {
1552 rel_fdc();
1553 return -ENODEV;
1554 }
1555 if (fd_calibrate(drive) == 0) {
1556 rel_fdc();
1557 return -ENXIO;
1558 }
1559 floppy_off(drive);
1560 rel_fdc();
1561 break;
1562 case FDFMTTRK:
1563 if (param < p->type->tracks * p->type->heads)
1564 {
1565 get_fdc(drive);
1566 if (fd_seek(drive,param) != 0){
1567 memset(p->trackbuf, FD_FILL_BYTE,
1568 p->dtype->sects * p->type->sect_mult * 512);
1569 non_int_flush_track(drive);
1570 }
1571 floppy_off(drive);
1572 rel_fdc();
1573 }
1574 else
1575 return -EINVAL;
1576 break;
1577 case FDFMTEND:
1578 floppy_off(drive);
1579 invalidate_bdev(bdev);
1580 break;
1581 case FDGETPRM:
1582 memset((void *)&getprm, 0, sizeof (getprm));
1583 getprm.track=p->type->tracks;
1584 getprm.head=p->type->heads;
1585 getprm.sect=p->dtype->sects * p->type->sect_mult;
1586 getprm.size=p->blocks;
1587 if (copy_to_user(argp, &getprm, sizeof(struct floppy_struct)))
1588 return -EFAULT;
1589 break;
1590 case FDSETPRM:
1591 case FDDEFPRM:
1592 return -EINVAL;
1593 case FDFLUSH:
1594 del_timer (flush_track_timer + drive);
1595 non_int_flush_track(drive);
1596 break;
1597 #ifdef RAW_IOCTL
1598 case IOCTL_RAW_TRACK:
1599 if (copy_to_user(argp, raw_buf, p->type->read_size))
1600 return -EFAULT;
1601 else
1602 return p->type->read_size;
1603 #endif
1604 default:
1605 return -ENOSYS;
1606 }
1607 return 0;
1608 }
1609
1610 static int fd_ioctl(struct block_device *bdev, fmode_t mode,
1611 unsigned int cmd, unsigned long param)
1612 {
1613 int ret;
1614
1615 mutex_lock(&amiflop_mutex);
1616 ret = fd_locked_ioctl(bdev, mode, cmd, param);
1617 mutex_unlock(&amiflop_mutex);
1618
1619 return ret;
1620 }
1621
1622 static void fd_probe(int dev)
1623 {
1624 unsigned long code;
1625 int type;
1626 int drive;
1627
1628 drive = dev & 3;
1629 code = fd_get_drive_id(drive);
1630
1631
1632 for (type = 0; type < num_dr_types; type++)
1633 if (drive_types[type].code == code)
1634 break;
1635
1636 if (type >= num_dr_types) {
1637 printk(KERN_WARNING "fd_probe: unsupported drive type "
1638 "%08lx found\n", code);
1639 unit[drive].type = &drive_types[num_dr_types-1];
1640 return;
1641 }
1642
1643 unit[drive].type = drive_types + type;
1644 unit[drive].track = -1;
1645
1646 unit[drive].disk = -1;
1647 unit[drive].motor = 0;
1648 unit[drive].busy = 0;
1649 unit[drive].status = -1;
1650 }
1651
1652
1653
1654
1655
1656
1657 static int floppy_open(struct block_device *bdev, fmode_t mode)
1658 {
1659 int drive = MINOR(bdev->bd_dev) & 3;
1660 int system = (MINOR(bdev->bd_dev) & 4) >> 2;
1661 int old_dev;
1662 unsigned long flags;
1663
1664 mutex_lock(&amiflop_mutex);
1665 old_dev = fd_device[drive];
1666
1667 if (fd_ref[drive] && old_dev != system) {
1668 mutex_unlock(&amiflop_mutex);
1669 return -EBUSY;
1670 }
1671
1672 if (mode & (FMODE_READ|FMODE_WRITE)) {
1673 check_disk_change(bdev);
1674 if (mode & FMODE_WRITE) {
1675 int wrprot;
1676
1677 get_fdc(drive);
1678 fd_select (drive);
1679 wrprot = !(ciaa.pra & DSKPROT);
1680 fd_deselect (drive);
1681 rel_fdc();
1682
1683 if (wrprot) {
1684 mutex_unlock(&amiflop_mutex);
1685 return -EROFS;
1686 }
1687 }
1688 }
1689
1690 local_irq_save(flags);
1691 fd_ref[drive]++;
1692 fd_device[drive] = system;
1693 local_irq_restore(flags);
1694
1695 unit[drive].dtype=&data_types[system];
1696 unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*
1697 data_types[system].sects*unit[drive].type->sect_mult;
1698 set_capacity(unit[drive].gendisk, unit[drive].blocks);
1699
1700 printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive,
1701 unit[drive].type->name, data_types[system].name);
1702
1703 mutex_unlock(&amiflop_mutex);
1704 return 0;
1705 }
1706
1707 static void floppy_release(struct gendisk *disk, fmode_t mode)
1708 {
1709 struct amiga_floppy_struct *p = disk->private_data;
1710 int drive = p - unit;
1711
1712 mutex_lock(&amiflop_mutex);
1713 if (unit[drive].dirty == 1) {
1714 del_timer (flush_track_timer + drive);
1715 non_int_flush_track (drive);
1716 }
1717
1718 if (!fd_ref[drive]--) {
1719 printk(KERN_CRIT "floppy_release with fd_ref == 0");
1720 fd_ref[drive] = 0;
1721 }
1722 #ifdef MODULE
1723 floppy_off (drive);
1724 #endif
1725 mutex_unlock(&amiflop_mutex);
1726 }
1727
1728
1729
1730
1731
1732
1733
1734 static unsigned amiga_check_events(struct gendisk *disk, unsigned int clearing)
1735 {
1736 struct amiga_floppy_struct *p = disk->private_data;
1737 int drive = p - unit;
1738 int changed;
1739 static int first_time = 1;
1740
1741 if (first_time)
1742 changed = first_time--;
1743 else {
1744 get_fdc(drive);
1745 fd_select (drive);
1746 changed = !(ciaa.pra & DSKCHANGE);
1747 fd_deselect (drive);
1748 rel_fdc();
1749 }
1750
1751 if (changed) {
1752 fd_probe(drive);
1753 p->track = -1;
1754 p->dirty = 0;
1755 writepending = 0;
1756 writefromint = 0;
1757 return DISK_EVENT_MEDIA_CHANGE;
1758 }
1759 return 0;
1760 }
1761
1762 static const struct block_device_operations floppy_fops = {
1763 .owner = THIS_MODULE,
1764 .open = floppy_open,
1765 .release = floppy_release,
1766 .ioctl = fd_ioctl,
1767 .getgeo = fd_getgeo,
1768 .check_events = amiga_check_events,
1769 };
1770
1771 static const struct blk_mq_ops amiflop_mq_ops = {
1772 .queue_rq = amiflop_queue_rq,
1773 };
1774
1775 static struct gendisk *fd_alloc_disk(int drive)
1776 {
1777 struct gendisk *disk;
1778
1779 disk = alloc_disk(1);
1780 if (!disk)
1781 goto out;
1782
1783 disk->queue = blk_mq_init_sq_queue(&unit[drive].tag_set, &amiflop_mq_ops,
1784 2, BLK_MQ_F_SHOULD_MERGE);
1785 if (IS_ERR(disk->queue)) {
1786 disk->queue = NULL;
1787 goto out_put_disk;
1788 }
1789
1790 unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL);
1791 if (!unit[drive].trackbuf)
1792 goto out_cleanup_queue;
1793
1794 return disk;
1795
1796 out_cleanup_queue:
1797 blk_cleanup_queue(disk->queue);
1798 disk->queue = NULL;
1799 blk_mq_free_tag_set(&unit[drive].tag_set);
1800 out_put_disk:
1801 put_disk(disk);
1802 out:
1803 unit[drive].type->code = FD_NODRIVE;
1804 return NULL;
1805 }
1806
1807 static int __init fd_probe_drives(void)
1808 {
1809 int drive,drives,nomem;
1810
1811 pr_info("FD: probing units\nfound");
1812 drives=0;
1813 nomem=0;
1814 for(drive=0;drive<FD_MAX_UNITS;drive++) {
1815 struct gendisk *disk;
1816 fd_probe(drive);
1817 if (unit[drive].type->code == FD_NODRIVE)
1818 continue;
1819
1820 disk = fd_alloc_disk(drive);
1821 if (!disk) {
1822 pr_cont(" no mem for fd%d", drive);
1823 nomem = 1;
1824 continue;
1825 }
1826 unit[drive].gendisk = disk;
1827 drives++;
1828
1829 pr_cont(" fd%d",drive);
1830 disk->major = FLOPPY_MAJOR;
1831 disk->first_minor = drive;
1832 disk->fops = &floppy_fops;
1833 disk->events = DISK_EVENT_MEDIA_CHANGE;
1834 sprintf(disk->disk_name, "fd%d", drive);
1835 disk->private_data = &unit[drive];
1836 set_capacity(disk, 880*2);
1837 add_disk(disk);
1838 }
1839 if ((drives > 0) || (nomem == 0)) {
1840 if (drives == 0)
1841 pr_cont(" no drives");
1842 pr_cont("\n");
1843 return drives;
1844 }
1845 pr_cont("\n");
1846 return -ENOMEM;
1847 }
1848
1849 static struct kobject *floppy_find(dev_t dev, int *part, void *data)
1850 {
1851 int drive = *part & 3;
1852 if (unit[drive].type->code == FD_NODRIVE)
1853 return NULL;
1854 *part = 0;
1855 return get_disk_and_module(unit[drive].gendisk);
1856 }
1857
1858 static int __init amiga_floppy_probe(struct platform_device *pdev)
1859 {
1860 int i, ret;
1861
1862 if (register_blkdev(FLOPPY_MAJOR,"fd"))
1863 return -EBUSY;
1864
1865 ret = -ENOMEM;
1866 raw_buf = amiga_chip_alloc(RAW_BUF_SIZE, "Floppy");
1867 if (!raw_buf) {
1868 printk("fd: cannot get chip mem buffer\n");
1869 goto out_blkdev;
1870 }
1871
1872 ret = -EBUSY;
1873 if (request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) {
1874 printk("fd: cannot get irq for dma\n");
1875 goto out_irq;
1876 }
1877
1878 if (request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL)) {
1879 printk("fd: cannot get irq for timer\n");
1880 goto out_irq2;
1881 }
1882
1883 ret = -ENODEV;
1884 if (fd_probe_drives() < 1)
1885 goto out_probe;
1886
1887 blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
1888 floppy_find, NULL, NULL);
1889
1890
1891 timer_setup(&motor_on_timer, motor_on_callback, 0);
1892 motor_on_timer.expires = 0;
1893 for (i = 0; i < FD_MAX_UNITS; i++) {
1894 timer_setup(&motor_off_timer[i], fd_motor_off, 0);
1895 motor_off_timer[i].expires = 0;
1896 timer_setup(&flush_track_timer[i], flush_track_callback, 0);
1897 flush_track_timer[i].expires = 0;
1898
1899 unit[i].track = -1;
1900 }
1901
1902 timer_setup(&post_write_timer, post_write_callback, 0);
1903 post_write_timer.expires = 0;
1904
1905 for (i = 0; i < 128; i++)
1906 mfmdecode[i]=255;
1907 for (i = 0; i < 16; i++)
1908 mfmdecode[mfmencode[i]]=i;
1909
1910
1911 custom.dmacon = DMAF_SETCLR | DMAF_DISK;
1912
1913
1914 ciaa.crb = 8;
1915 return 0;
1916
1917 out_probe:
1918 free_irq(IRQ_AMIGA_CIAA_TB, NULL);
1919 out_irq2:
1920 free_irq(IRQ_AMIGA_DSKBLK, NULL);
1921 out_irq:
1922 amiga_chip_free(raw_buf);
1923 out_blkdev:
1924 unregister_blkdev(FLOPPY_MAJOR,"fd");
1925 return ret;
1926 }
1927
1928 static struct platform_driver amiga_floppy_driver = {
1929 .driver = {
1930 .name = "amiga-floppy",
1931 },
1932 };
1933
1934 static int __init amiga_floppy_init(void)
1935 {
1936 return platform_driver_probe(&amiga_floppy_driver, amiga_floppy_probe);
1937 }
1938
1939 module_init(amiga_floppy_init);
1940
1941 #ifndef MODULE
1942 static int __init amiga_floppy_setup (char *str)
1943 {
1944 int n;
1945 if (!MACH_IS_AMIGA)
1946 return 0;
1947 if (!get_option(&str, &n))
1948 return 0;
1949 printk (KERN_INFO "amiflop: Setting default df0 to %x\n", n);
1950 fd_def_df0 = n;
1951 return 1;
1952 }
1953
1954 __setup("floppy=", amiga_floppy_setup);
1955 #endif
1956
1957 MODULE_ALIAS("platform:amiga-floppy");