This source file includes following definitions.
- fd_select_side
- fd_select_drive
- fd_deselect
- fd_motor_off_timer
- check_change
- set_head_settle_flag
- get_head_settle_flag
- floppy_irq
- fd_error
- do_format
- do_fd_action
- fd_calibrate
- fd_calibrate_done
- fd_seek
- fd_seek_done
- fd_rwsec
- fd_readtrack_check
- fd_rwsec_done
- fd_writetrack
- fd_writetrack_done
- fd_times_out
- finish_fdc
- finish_fdc_done
- floppy_off
- check_floppy_change
- floppy_revalidate
- copy_buffer
- setup_req_params
- redo_fd_request
- do_fd_request
- invalidate_drive
- fd_ioctl
- fd_probe
- fd_test_drive_present
- config_types
- floppy_open
- floppy_release
- atari_floppy_init
- atari_floppy_setup
- init_module
- cleanup_module
- floppy_eject
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 #include <linux/module.h>
59
60 #include <linux/sched.h>
61 #include <linux/string.h>
62 #include <linux/fs.h>
63 #include <linux/fcntl.h>
64 #include <linux/kernel.h>
65 #include <linux/timer.h>
66 #include <linux/fd.h>
67 #include <linux/errno.h>
68 #include <linux/types.h>
69 #include <linux/delay.h>
70 #include <linux/mm.h>
71 #include <linux/malloc.h>
72
73 #include <asm/system.h>
74 #include <asm/bitops.h>
75 #include <asm/irq.h>
76 #include <asm/pgtable.h>
77
78 #include <asm/bootinfo.h>
79 #include <asm/atafd.h>
80 #include <asm/atafdreg.h>
81 #include <asm/atarihw.h>
82 #include <asm/atariints.h>
83 #include <asm/atari_stdma.h>
84
85 #define MAJOR_NR FLOPPY_MAJOR
86 #include <linux/blk.h>
87
88 #define FD_MAX_UNITS 2
89
90 #undef DEBUG
91
92
93 static struct atari_disk_type {
94 const char *name;
95 unsigned spt;
96 unsigned blocks;
97 unsigned fdc_speed;
98 unsigned stretch;
99 } disk_type[] = {
100 { "d360", 9, 720, 0, 0},
101 { "D360", 9, 720, 0, 1},
102 { "D720", 9,1440, 0, 0},
103 { "D820", 10,1640, 0, 0},
104
105 #define MAX_TYPE_DD 3
106 { "h1200",15,2400, 3, 0},
107 { "H1440",18,2880, 3, 0},
108 { "H1640",20,3280, 3, 0},
109
110 #define MAX_TYPE_HD 6
111 { "E2880",36,5760, 3, 0},
112 { "E3280",40,6560, 3, 0},
113
114 #define MAX_TYPE_ED 8
115
116 { "H1680",21,3360, 3, 0},
117 { "h410",10,820, 0, 1},
118 { "h1476",18,2952, 3, 0},
119 { "H1722",21,3444, 3, 0},
120 { "h420",10,840, 0, 1},
121 { "H830",10,1660, 0, 0},
122 { "h1494",18,2952, 3, 0},
123 { "H1743",21,3486, 3, 0},
124 { "h880",11,1760, 0, 0},
125 { "D1040",13,2080, 0, 0},
126 { "D1120",14,2240, 0, 0},
127 { "h1600",20,3200, 3, 0},
128 { "H1760",22,3520, 3, 0},
129 { "H1920",24,3840, 3, 0},
130 { "E3200",40,6400, 3, 0},
131 { "E3520",44,7040, 3, 0},
132 { "E3840",48,7680, 3, 0},
133 { "H1840",23,3680, 3, 0},
134 { "D800",10,1600, 0, 0},
135 };
136
137 static int StartDiskType[] = {
138 MAX_TYPE_DD,
139 MAX_TYPE_HD,
140 MAX_TYPE_ED
141 };
142
143 #define TYPE_DD 0
144 #define TYPE_HD 1
145 #define TYPE_ED 2
146
147 static int DriveType = TYPE_HD;
148
149
150 static struct {
151 int index;
152 unsigned drive_types;
153 } minor2disktype[] = {
154 { 0, TYPE_DD },
155 { 4, TYPE_HD },
156 { 1, TYPE_DD },
157 { 2, TYPE_DD },
158 { 1, TYPE_DD },
159 { 2, TYPE_DD },
160 { 5, TYPE_HD },
161 { 7, TYPE_ED },
162
163 { 8, TYPE_ED },
164 { 5, TYPE_HD },
165 { 9, TYPE_HD },
166 { 10, TYPE_DD },
167 { 3, TYPE_DD },
168 { 11, TYPE_HD },
169 { 12, TYPE_HD },
170 { 13, TYPE_DD },
171 { 14, TYPE_DD },
172 { 15, TYPE_HD },
173 { 16, TYPE_HD },
174 { 17, TYPE_DD },
175 { 18, TYPE_DD },
176 { 19, TYPE_DD },
177 { 20, TYPE_HD },
178 { 21, TYPE_HD },
179 { 22, TYPE_HD },
180 { 23, TYPE_ED },
181 { 24, TYPE_ED },
182 { 25, TYPE_ED },
183 { 26, TYPE_HD },
184 { 27, TYPE_DD },
185 { 6, TYPE_HD },
186 };
187
188 #define NUM_DISK_MINORS (sizeof(minor2disktype)/sizeof(*minor2disktype))
189
190
191
192
193
194 #define MAX_DISK_SIZE 3280
195
196 static int floppy_sizes[256];
197 static int floppy_blocksizes[256] = { 0, };
198
199
200 static struct atari_floppy_struct {
201 int connected;
202 int autoprobe;
203
204 struct atari_disk_type *disktype;
205
206 int track;
207
208 unsigned int steprate;
209 unsigned int wpstat;
210
211 int flags;
212 } unit[FD_MAX_UNITS];
213
214 #define UD unit[drive]
215 #define UDT unit[drive].disktype
216 #define SUD unit[SelectedDrive]
217 #define SUDT unit[SelectedDrive].disktype
218
219
220 #define FDC_READ(reg) ({ \
221 \
222 unsigned short __val; \
223 \
224 dma_wd.dma_mode_status = 0x80 | (reg); \
225 udelay(25); \
226 __val = dma_wd.fdc_acces_seccount; \
227 MFPDELAY(); \
228 \
229 __val & 0xff; \
230 })
231
232 #define FDC_WRITE(reg,val) \
233 do { \
234 \
235 \
236 dma_wd.dma_mode_status = 0x80 | (reg); \
237 udelay(25); \
238 dma_wd.fdc_acces_seccount = (val); \
239 MFPDELAY(); \
240 \
241 } while(0)
242
243
244
245
246
247
248
249
250
251 static int MaxSectors[] = {
252 11, 22, 44
253 };
254 static int BufferSize[] = {
255 15*512, 30*512, 60*512
256 };
257
258 #define MAX_SECTORS (MaxSectors[DriveType])
259 #define BUFFER_SIZE (BufferSize[DriveType])
260
261 unsigned char *DMABuffer;
262 static unsigned long PhysDMABuffer;
263
264 static int UseTrackbuffer = -1;
265
266 unsigned char *TrackBuffer;
267 static unsigned long PhysTrackBuffer;
268 static int BufferDrive, BufferSide, BufferTrack;
269 static int read_track;
270
271 #define SECTOR_BUFFER(sec) (TrackBuffer + ((sec)-1)*512)
272 #define IS_BUFFERED(drive,side,track) \
273 (BufferDrive == (drive) && BufferSide == (side) && BufferTrack == (track))
274
275
276
277
278
279
280 static int SelectedDrive = 0;
281 static int ReqCmd, ReqBlock;
282 static int ReqSide, ReqTrack, ReqSector, ReqCnt;
283 static int HeadSettleFlag = 0;
284 static unsigned char *ReqData, *ReqBuffer;
285 static int MotorOn = 0, MotorOffTrys;
286 static int IsFormatting = 0, FormatError;
287
288 static int UserSteprate[FD_MAX_UNITS] = { -1, -1 };
289
290
291 static volatile int fdc_busy = 0;
292 static struct wait_queue *fdc_wait = NULL;
293 static struct wait_queue *format_wait = NULL;
294
295 static unsigned int changed_floppies = 0xff, fake_change = 0;
296 #define CHECK_CHANGE_DELAY HZ/2
297
298 #define FD_MOTOR_OFF_DELAY (3*HZ)
299 #define FD_MOTOR_OFF_MAXTRY (10*20)
300
301 #define FLOPPY_TIMEOUT (6*HZ)
302 #define RECALIBRATE_ERRORS 4
303
304 #define MAX_ERRORS 8
305
306
307
308 #define START_MOTOR_OFF_TIMER(delay) \
309 do { \
310 motor_off_timer.expires = jiffies + (delay); \
311 add_timer( &motor_off_timer ); \
312 MotorOffTrys = 0; \
313 } while(0)
314
315 #define START_CHECK_CHANGE_TIMER(delay) \
316 do { \
317 timer_table[FLOPPY_TIMER].expires = jiffies + (delay); \
318 timer_active |= (1 << FLOPPY_TIMER); \
319 } while(0)
320
321 #define START_TIMEOUT() \
322 do { \
323 del_timer( &timeout_timer ); \
324 timeout_timer.expires = jiffies + FLOPPY_TIMEOUT; \
325 add_timer( &timeout_timer ); \
326 } while(0)
327
328 #define STOP_TIMEOUT() \
329 do { \
330 del_timer( &timeout_timer ); \
331 } while(0)
332
333
334
335
336
337
338
339 static int Probing = 0;
340
341
342
343
344 static int NeedSeek = 0;
345
346
347 #ifdef DEBUG
348 #define DPRINT(a) printk a
349 #else
350 #define DPRINT(a)
351 #endif
352
353
354
355 static void fd_select_side( int side );
356 static void fd_select_drive( int drive );
357 static void fd_deselect( void );
358 static void fd_motor_off_timer( unsigned long dummy );
359 static void check_change( void );
360 static __inline__ void set_head_settle_flag( void );
361 static __inline__ int get_head_settle_flag( void );
362 static void floppy_irq (int irq, struct pt_regs *fp, void *dummy);
363 static void fd_error( void );
364 static int do_format(kdev_t drive, struct atari_format_descr *desc);
365 static void do_fd_action( int drive );
366 static void fd_calibrate( void );
367 static void fd_calibrate_done( int status );
368 static void fd_seek( void );
369 static void fd_seek_done( int status );
370 static void fd_rwsec( void );
371 static void fd_readtrack_check( unsigned long dummy );
372 static void fd_rwsec_done( int status );
373 static void fd_writetrack( void );
374 static void fd_writetrack_done( int status );
375 static void fd_times_out( unsigned long dummy );
376 static void finish_fdc( void );
377 static void finish_fdc_done( int dummy );
378 static void floppy_off( unsigned int nr);
379 static __inline__ void copy_buffer( void *from, void *to);
380 static void setup_req_params( int drive );
381 static void redo_fd_request( void);
382 static int invalidate_drive(kdev_t rdev);
383 static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int
384 cmd, unsigned long param);
385 static void fd_probe( int drive );
386 static int fd_test_drive_present( int drive );
387 static void config_types( void );
388 static int floppy_open( struct inode *inode, struct file *filp );
389 static void floppy_release( struct inode * inode, struct file * filp );
390
391
392
393 static struct timer_list motor_off_timer =
394 { NULL, NULL, 0, 0, fd_motor_off_timer };
395 static struct timer_list readtrack_timer =
396 { NULL, NULL, 0, 0, fd_readtrack_check };
397
398 static struct timer_list timeout_timer =
399 { NULL, NULL, 0, 0, fd_times_out };
400
401
402
403
404
405 static void fd_select_side( int side )
406 {
407 unsigned long flags;
408
409 save_flags(flags);
410 cli();
411
412 sound_ym.rd_data_reg_sel = 14;
413 sound_ym.wd_data = (side == 0) ? sound_ym.rd_data_reg_sel | 0x01 :
414 sound_ym.rd_data_reg_sel & 0xfe;
415
416 restore_flags(flags);
417 }
418
419
420
421
422
423
424 static void fd_select_drive( int drive )
425 {
426 unsigned long flags;
427 unsigned char tmp;
428
429 if (drive == SelectedDrive)
430 return;
431
432 save_flags(flags);
433 cli();
434 sound_ym.rd_data_reg_sel = 14;
435 tmp = sound_ym.rd_data_reg_sel;
436 sound_ym.wd_data = (tmp | DSKDRVNONE) & ~(drive == 0 ? DSKDRV0 : DSKDRV1);
437 restore_flags(flags);
438
439
440 FDC_WRITE( FDCREG_TRACK, UD.track );
441 udelay(25);
442
443
444 if (UDT)
445 if (ATARIHW_PRESENT(FDCSPEED))
446 dma_wd.fdc_speed = UDT->fdc_speed;
447
448 SelectedDrive = drive;
449 }
450
451
452
453
454 static void fd_deselect( void )
455 {
456 unsigned long flags;
457
458 save_flags(flags);
459 cli();
460 sound_ym.rd_data_reg_sel=14;
461 sound_ym.wd_data = sound_ym.rd_data_reg_sel | 7;
462 SelectedDrive = -1;
463 restore_flags(flags);
464 }
465
466
467
468
469
470
471
472 static void fd_motor_off_timer( unsigned long dummy )
473 {
474
475 unsigned char status;
476 int delay;
477
478 del_timer( &motor_off_timer );
479
480 if (SelectedDrive < 0)
481
482 return;
483
484
485
486
487 if (stdma_islocked())
488 goto retry;
489
490 status = FDC_READ( FDCREG_STATUS );
491
492 if (!(status & 0x80)) {
493
494 MotorOn = 0;
495 fd_deselect();
496
497 return;
498 }
499
500
501 retry:
502
503
504
505
506
507
508 delay = (MotorOffTrys < FD_MOTOR_OFF_MAXTRY) ?
509 (++MotorOffTrys, HZ/20) : HZ/2;
510 START_MOTOR_OFF_TIMER( delay );
511 }
512
513
514
515
516
517
518 static void check_change( void )
519 {
520 static int drive = 0;
521
522 unsigned long flags;
523 unsigned char old_porta;
524 int stat;
525
526 if (++drive > 1 || !UD.connected)
527 drive = 0;
528
529 save_flags(flags);
530 cli();
531
532 if (!stdma_islocked()) {
533 sound_ym.rd_data_reg_sel = 14;
534 old_porta = sound_ym.rd_data_reg_sel;
535 sound_ym.wd_data = (old_porta | DSKDRVNONE) &
536 ~(drive == 0 ? DSKDRV0 : DSKDRV1);
537 stat = !!(FDC_READ( FDCREG_STATUS ) & FDCSTAT_WPROT);
538 sound_ym.wd_data = old_porta;
539
540 if (stat != UD.wpstat) {
541 DPRINT(( "wpstat[%d] = %d\n", drive, stat ));
542 UD.wpstat = stat;
543 set_bit (drive, &changed_floppies);
544 }
545 }
546 restore_flags(flags);
547
548 START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY );
549 }
550
551
552
553
554
555
556 static __inline__ void set_head_settle_flag( void )
557 {
558 HeadSettleFlag = FDCCMDADD_E;
559 }
560
561 static __inline__ int get_head_settle_flag( void )
562 {
563 int tmp = HeadSettleFlag;
564 HeadSettleFlag = 0;
565 return( tmp );
566 }
567
568
569
570
571
572
573 static void (*FloppyIRQHandler)( int status ) = NULL;
574
575 static void floppy_irq (int irq, struct pt_regs *fp, void *dummy)
576 {
577 unsigned char status;
578 void (*handler)( int );
579
580 handler = FloppyIRQHandler;
581 FloppyIRQHandler = NULL;
582
583 if (handler) {
584 nop();
585 status = FDC_READ( FDCREG_STATUS );
586 DPRINT(("FDC irq, status = %02x handler = %08lx\n",status,(unsigned long)handler));
587 handler( status );
588 }
589 else {
590 DPRINT(("FDC irq, no handler\n"));
591 }
592 }
593
594
595
596
597
598
599 static void fd_error( void )
600 {
601 if (IsFormatting) {
602 IsFormatting = 0;
603 FormatError = 1;
604 wake_up( &format_wait );
605 return;
606 }
607
608 if (!CURRENT) return;
609 CURRENT->errors++;
610 if (CURRENT->errors >= MAX_ERRORS) {
611 printk( "fd%d: too many errors.\n", SelectedDrive );
612 end_request( 0 );
613 }
614 else if (CURRENT->errors == RECALIBRATE_ERRORS) {
615 printk( "fd%d: recalibrating\n", SelectedDrive );
616 if (SelectedDrive != -1)
617 SUD.track = -1;
618 }
619 redo_fd_request();
620 }
621
622
623
624 #define SET_IRQ_HANDLER(proc) do { FloppyIRQHandler = (proc); } while(0)
625
626
627
628
629 #define FILL(n,val) \
630 do { \
631 memset( p, val, n ); \
632 p += n; \
633 } while(0)
634
635 static int do_format(kdev_t device, struct atari_format_descr *desc)
636 {
637 unsigned char *p;
638 int sect, nsect;
639 unsigned long flags;
640 int type, drive = MINOR(device) & 3;
641
642 DPRINT(("do_format( dr=%d tr=%d he=%d offs=%d )\n",
643 drive, desc->track, desc->head, desc->sect_offset ));
644
645 save_flags(flags);
646 cli();
647 while( fdc_busy ) sleep_on( &fdc_wait );
648 fdc_busy = 1;
649 stdma_lock(floppy_irq, NULL);
650 atari_turnon_irq( IRQ_MFP_FDC );
651 restore_flags(flags);
652
653 type = MINOR(device) >> 2;
654 if (type) {
655 if (--type >= NUM_DISK_MINORS ||
656 minor2disktype[type].drive_types > DriveType) {
657 redo_fd_request();
658 return -EINVAL;
659 }
660 type = minor2disktype[type].index;
661 UDT = &disk_type[type];
662 }
663
664 if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) {
665 redo_fd_request();
666 return -EINVAL;
667 }
668
669 nsect = UDT->spt;
670 p = TrackBuffer;
671
672
673 BufferDrive = -1;
674
675 del_timer( &motor_off_timer );
676
677 FILL( 60 * (nsect / 9), 0x4e );
678 for( sect = 0; sect < nsect; ++sect ) {
679 FILL( 12, 0 );
680 FILL( 3, 0xf5 );
681 *p++ = 0xfe;
682 *p++ = desc->track;
683 *p++ = desc->head;
684 *p++ = (nsect + sect - desc->sect_offset) % nsect + 1;
685 *p++ = 2;
686 *p++ = 0xf7;
687 FILL( 22, 0x4e );
688 FILL( 12, 0 );
689 FILL( 3, 0xf5 );
690 *p++ = 0xfb;
691 FILL( 512, 0xe5 );
692 *p++ = 0xf7;
693 FILL( 40, 0x4e );
694 }
695 FILL( TrackBuffer+BUFFER_SIZE-p, 0x4e );
696
697 IsFormatting = 1;
698 FormatError = 0;
699 ReqTrack = desc->track;
700 ReqSide = desc->head;
701 do_fd_action( drive );
702
703 sleep_on( &format_wait );
704
705 redo_fd_request();
706 return( FormatError ? -EIO : 0 );
707 }
708
709
710
711
712
713
714
715
716
717
718
719 static void do_fd_action( int drive )
720 {
721 DPRINT(("do_fd_action\n"));
722
723 if (UseTrackbuffer && !IsFormatting) {
724 repeat:
725 if (IS_BUFFERED( drive, ReqSide, ReqTrack )) {
726 if (ReqCmd == READ) {
727 copy_buffer( SECTOR_BUFFER(ReqSector), ReqData );
728 if (++ReqCnt < CURRENT->current_nr_sectors) {
729
730 setup_req_params( drive );
731 goto repeat;
732 }
733 else {
734
735 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
736 CURRENT->sector += CURRENT->current_nr_sectors;
737 end_request( 1 );
738 redo_fd_request();
739 return;
740 }
741 }
742 else {
743
744
745 copy_buffer( ReqData, SECTOR_BUFFER(ReqSector) );
746 }
747 }
748 }
749
750 if (SelectedDrive != drive)
751 fd_select_drive( drive );
752
753 if (UD.track == -1)
754 fd_calibrate();
755 else if (UD.track != ReqTrack << UDT->stretch)
756 fd_seek();
757 else if (IsFormatting)
758 fd_writetrack();
759 else
760 fd_rwsec();
761 }
762
763
764
765
766 static void fd_calibrate( void )
767 {
768 if (SUD.track >= 0) {
769 fd_calibrate_done( 0 );
770 return;
771 }
772
773 if (ATARIHW_PRESENT(FDCSPEED))
774 dma_wd.fdc_speed = 0; ;
775 DPRINT(("fd_calibrate\n"));
776 SET_IRQ_HANDLER( fd_calibrate_done );
777
778 FDC_WRITE( FDCREG_CMD, FDCCMD_RESTORE | SUD.steprate );
779
780 NeedSeek = 1;
781 MotorOn = 1;
782 START_TIMEOUT();
783
784 }
785
786
787 static void fd_calibrate_done( int status )
788 {
789 DPRINT(("fd_calibrate_done()\n"));
790 STOP_TIMEOUT();
791
792
793 if (ATARIHW_PRESENT(FDCSPEED))
794 dma_wd.fdc_speed = SUDT->fdc_speed;
795 if (status & FDCSTAT_RECNF) {
796 printk( "fd%d: restore failed\n", SelectedDrive );
797 fd_error();
798 }
799 else {
800 SUD.track = 0;
801 fd_seek();
802 }
803 }
804
805
806
807
808
809
810 static void fd_seek( void )
811 {
812 if (SUD.track == ReqTrack << SUDT->stretch) {
813 fd_seek_done( 0 );
814 return;
815 }
816
817 if (ATARIHW_PRESENT(FDCSPEED)) {
818 dma_wd.fdc_speed = 0;
819 MFPDELAY();
820 }
821
822 DPRINT(("fd_seek() to track %d\n",ReqTrack));
823 FDC_WRITE( FDCREG_DATA, ReqTrack << SUDT->stretch);
824 udelay(25);
825 SET_IRQ_HANDLER( fd_seek_done );
826 FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK | SUD.steprate );
827
828 MotorOn = 1;
829 set_head_settle_flag();
830 START_TIMEOUT();
831
832 }
833
834
835 static void fd_seek_done( int status )
836 {
837 DPRINT(("fd_seek_done()\n"));
838 STOP_TIMEOUT();
839
840
841 if (ATARIHW_PRESENT(FDCSPEED))
842 dma_wd.fdc_speed = SUDT->fdc_speed;
843 if (status & FDCSTAT_RECNF) {
844 printk( "fd%d: seek error (to track %d)\n",
845 SelectedDrive, ReqTrack );
846
847 SUD.track = -1;
848 fd_error();
849 }
850 else {
851 SUD.track = ReqTrack << SUDT->stretch;
852 NeedSeek = 0;
853 if (IsFormatting)
854 fd_writetrack();
855 else
856 fd_rwsec();
857 }
858 }
859
860
861
862
863
864
865 static int MultReadInProgress = 0;
866
867
868 static void fd_rwsec( void )
869 {
870 unsigned long paddr, flags;
871 unsigned int rwflag, old_motoron;
872 unsigned int track;
873
874 DPRINT(("fd_rwsec(), Sec=%d, Access=%c\n",ReqSector, ReqCmd == WRITE ? 'w' : 'r' ));
875 if (ReqCmd == WRITE) {
876 if (ATARIHW_PRESENT(EXTD_DMA)) {
877 paddr = (unsigned long)VTOP(ReqData);
878 }
879 else {
880 copy_buffer( ReqData, DMABuffer );
881 paddr = PhysDMABuffer;
882 }
883 dma_cache_maintenance( paddr, 512, 1 );
884 rwflag = 0x100;
885 }
886 else {
887 if (read_track)
888 paddr = PhysTrackBuffer;
889 else
890 paddr = ATARIHW_PRESENT(EXTD_DMA) ? VTOP(ReqData) : PhysDMABuffer;
891 rwflag = 0;
892 }
893
894 fd_select_side( ReqSide );
895
896
897 FDC_WRITE( FDCREG_SECTOR, read_track ? 1 : ReqSector );
898 MFPDELAY();
899
900 if (SUDT->stretch) {
901 track = FDC_READ( FDCREG_TRACK);
902 MFPDELAY();
903 FDC_WRITE( FDCREG_TRACK, track >> SUDT->stretch);
904 }
905 udelay(25);
906
907
908 save_flags(flags);
909 cli();
910 dma_wd.dma_lo = (unsigned char)paddr;
911 MFPDELAY();
912 paddr >>= 8;
913 dma_wd.dma_md = (unsigned char)paddr;
914 MFPDELAY();
915 paddr >>= 8;
916 if (ATARIHW_PRESENT(EXTD_DMA))
917 st_dma_ext_dmahi = (unsigned short)paddr;
918 else
919 dma_wd.dma_hi = (unsigned char)paddr;
920 MFPDELAY();
921 restore_flags(flags);
922
923
924 dma_wd.dma_mode_status = 0x90 | rwflag;
925 MFPDELAY();
926 dma_wd.dma_mode_status = 0x90 | (rwflag ^ 0x100);
927 MFPDELAY();
928 dma_wd.dma_mode_status = 0x90 | rwflag;
929 MFPDELAY();
930
931
932 dma_wd.fdc_acces_seccount = read_track ? SUDT->spt : 1;
933
934 udelay(25);
935
936
937 dma_wd.dma_mode_status = FDCSELREG_STP | rwflag;
938 udelay(25);
939 SET_IRQ_HANDLER( fd_rwsec_done );
940 dma_wd.fdc_acces_seccount =
941 (get_head_settle_flag() |
942 (rwflag ? FDCCMD_WRSEC : (FDCCMD_RDSEC | (read_track ? FDCCMDADD_M : 0))));
943
944 old_motoron = MotorOn;
945 MotorOn = 1;
946 NeedSeek = 1;
947
948
949 if (read_track) {
950
951
952
953
954
955 readtrack_timer.expires =
956 jiffies + HZ/5 + (old_motoron ? 0 : HZ);
957
958 add_timer( &readtrack_timer );
959 MultReadInProgress = 1;
960 }
961 START_TIMEOUT();
962 }
963
964
965 static void fd_readtrack_check( unsigned long dummy )
966 {
967 unsigned long flags, addr, addr2;
968
969 save_flags(flags);
970 cli();
971
972 del_timer( &readtrack_timer );
973
974 if (!MultReadInProgress) {
975
976
977
978
979
980
981 restore_flags(flags);
982 return;
983 }
984
985
986
987 addr = 0;
988 do {
989 addr2 = addr;
990 addr = dma_wd.dma_lo & 0xff;
991 MFPDELAY();
992 addr |= (dma_wd.dma_md & 0xff) << 8;
993 MFPDELAY();
994 if (ATARIHW_PRESENT( EXTD_DMA ))
995 addr |= (st_dma_ext_dmahi & 0xffff) << 16;
996 else
997 addr |= (dma_wd.dma_hi & 0xff) << 16;
998 MFPDELAY();
999 } while(addr != addr2);
1000
1001 if (addr >= PhysTrackBuffer + SUDT->spt*512) {
1002
1003
1004
1005 SET_IRQ_HANDLER( NULL );
1006 restore_flags(flags);
1007 DPRINT(("fd_readtrack_check(): done\n"));
1008 FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
1009 udelay(25);
1010
1011
1012
1013
1014 fd_rwsec_done( 0 );
1015 }
1016 else {
1017
1018 restore_flags(flags);
1019 DPRINT(("fd_readtrack_check(): not yet finished\n"));
1020 readtrack_timer.expires = jiffies + HZ/5/10;
1021 add_timer( &readtrack_timer );
1022 }
1023 }
1024
1025
1026 static void fd_rwsec_done( int status )
1027 {
1028 unsigned int track;
1029
1030 DPRINT(("fd_rwsec_done()\n"));
1031
1032 STOP_TIMEOUT();
1033
1034 if (read_track) {
1035 if (!MultReadInProgress)
1036 return;
1037 MultReadInProgress = 0;
1038 del_timer( &readtrack_timer );
1039 }
1040
1041
1042 if (SUDT->stretch) {
1043 track = FDC_READ( FDCREG_TRACK);
1044 MFPDELAY();
1045 FDC_WRITE( FDCREG_TRACK, track << SUDT->stretch);
1046 }
1047
1048 if (!UseTrackbuffer) {
1049 dma_wd.dma_mode_status = 0x90;
1050 MFPDELAY();
1051 if (!(dma_wd.dma_mode_status & 0x01)) {
1052 printk( "fd%d: DMA error\n", SelectedDrive );
1053 goto err_end;
1054 }
1055 }
1056 MFPDELAY();
1057
1058 if (ReqCmd == WRITE && (status & FDCSTAT_WPROT)) {
1059 printk( "fd%d: is write protected\n", SelectedDrive );
1060 goto err_end;
1061 }
1062 if ((status & FDCSTAT_RECNF) &&
1063
1064
1065 !(read_track && FDC_READ(FDCREG_SECTOR) > SUDT->spt)) {
1066 if (Probing) {
1067 if (SUDT > disk_type) {
1068
1069 SUDT--;
1070 floppy_sizes[SelectedDrive] = SUDT->blocks >> 1;
1071 }
1072 else {
1073 if (SUD.flags & FTD_MSG)
1074 printk( "fd%d: Auto-detected floppy type %s\n",
1075 SelectedDrive, SUDT->name );
1076 Probing=0;
1077 }
1078 } else {
1079
1080 if (SUD.autoprobe) {
1081 SUDT = disk_type + StartDiskType[DriveType];
1082 floppy_sizes[SelectedDrive] = SUDT->blocks >> 1;
1083 Probing = 1;
1084 }
1085 }
1086 if (Probing) {
1087 if (ATARIHW_PRESENT(FDCSPEED)) {
1088 dma_wd.fdc_speed = SUDT->fdc_speed;
1089 MFPDELAY();
1090 }
1091 setup_req_params( SelectedDrive );
1092 BufferDrive = -1;
1093 do_fd_action( SelectedDrive );
1094 return;
1095 }
1096
1097 printk( "fd%d: sector %d not found (side %d, track %d)\n",
1098 SelectedDrive, FDC_READ (FDCREG_SECTOR), ReqSide, ReqTrack );
1099 goto err_end;
1100 }
1101 if (status & FDCSTAT_CRC) {
1102 printk( "fd%d: CRC error (side %d, track %d, sector %d)\n",
1103 SelectedDrive, ReqSide, ReqTrack, FDC_READ (FDCREG_SECTOR) );
1104 goto err_end;
1105 }
1106 if (status & FDCSTAT_LOST) {
1107 printk( "fd%d: lost data (side %d, track %d, sector %d)\n",
1108 SelectedDrive, ReqSide, ReqTrack, FDC_READ (FDCREG_SECTOR) );
1109 goto err_end;
1110 }
1111
1112 Probing = 0;
1113
1114 if (ReqCmd == READ) {
1115 if (!read_track) {
1116 void *addr;
1117 addr = ATARIHW_PRESENT( EXTD_DMA ) ? ReqData : DMABuffer;
1118 dma_cache_maintenance( VTOP(addr), 512, 0 );
1119 if (!ATARIHW_PRESENT( EXTD_DMA ))
1120 copy_buffer (addr, ReqData);
1121 } else {
1122 dma_cache_maintenance( PhysTrackBuffer, MAX_SECTORS * 512, 0 );
1123 BufferDrive = SelectedDrive;
1124 BufferSide = ReqSide;
1125 BufferTrack = ReqTrack;
1126 copy_buffer (SECTOR_BUFFER (ReqSector), ReqData);
1127 }
1128 }
1129
1130 if (++ReqCnt < CURRENT->current_nr_sectors) {
1131
1132 setup_req_params( SelectedDrive );
1133 do_fd_action( SelectedDrive );
1134 }
1135 else {
1136
1137 CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
1138 CURRENT->sector += CURRENT->current_nr_sectors;
1139 end_request( 1 );
1140 redo_fd_request();
1141 }
1142 return;
1143
1144 err_end:
1145 BufferDrive = -1;
1146 fd_error();
1147 }
1148
1149
1150 static void fd_writetrack( void )
1151 {
1152 unsigned long paddr, flags;
1153 unsigned int track;
1154
1155 DPRINT(("fd_writetrack() Tr=%d Si=%d\n", ReqTrack, ReqSide ));
1156
1157 paddr = PhysTrackBuffer;
1158 dma_cache_maintenance( paddr, BUFFER_SIZE, 1 );
1159
1160 fd_select_side( ReqSide );
1161
1162
1163 if (SUDT->stretch) {
1164 track = FDC_READ( FDCREG_TRACK);
1165 MFPDELAY();
1166 FDC_WRITE(FDCREG_TRACK,track >> SUDT->stretch);
1167 }
1168 udelay(40);
1169
1170
1171 save_flags(flags);
1172 cli();
1173 dma_wd.dma_lo = (unsigned char)paddr;
1174 MFPDELAY();
1175 paddr >>= 8;
1176 dma_wd.dma_md = (unsigned char)paddr;
1177 MFPDELAY();
1178 paddr >>= 8;
1179 if (ATARIHW_PRESENT( EXTD_DMA ))
1180 st_dma_ext_dmahi = (unsigned short)paddr;
1181 else
1182 dma_wd.dma_hi = (unsigned char)paddr;
1183 MFPDELAY();
1184 restore_flags(flags);
1185
1186
1187 dma_wd.dma_mode_status = 0x190;
1188 MFPDELAY();
1189 dma_wd.dma_mode_status = 0x90;
1190 MFPDELAY();
1191 dma_wd.dma_mode_status = 0x190;
1192 MFPDELAY();
1193
1194
1195 dma_wd.fdc_acces_seccount = BUFFER_SIZE/512;
1196 udelay(40);
1197
1198
1199 dma_wd.dma_mode_status = FDCSELREG_STP | 0x100;
1200 udelay(40);
1201 SET_IRQ_HANDLER( fd_writetrack_done );
1202 dma_wd.fdc_acces_seccount = FDCCMD_WRTRA | get_head_settle_flag();
1203
1204 MotorOn = 1;
1205 START_TIMEOUT();
1206
1207 }
1208
1209
1210 static void fd_writetrack_done( int status )
1211 {
1212 DPRINT(("fd_writetrack_done()\n"));
1213
1214 STOP_TIMEOUT();
1215
1216 if (status & FDCSTAT_WPROT) {
1217 printk( "fd%d: is write protected\n", SelectedDrive );
1218 goto err_end;
1219 }
1220 if (status & FDCSTAT_LOST) {
1221 printk( "fd%d: lost data (side %d, track %d)\n",
1222 SelectedDrive, ReqSide, ReqTrack );
1223 goto err_end;
1224 }
1225
1226 wake_up( &format_wait );
1227 return;
1228
1229 err_end:
1230 fd_error();
1231 }
1232
1233 static void fd_times_out( unsigned long dummy )
1234 {
1235 atari_disable_irq( IRQ_MFP_FDC );
1236 if (!FloppyIRQHandler) goto end;
1237
1238
1239 SET_IRQ_HANDLER( NULL );
1240
1241
1242 if (UseTrackbuffer)
1243 del_timer( &readtrack_timer );
1244 FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
1245 udelay( 25 );
1246
1247 printk( "floppy timeout\n" );
1248 fd_error();
1249 end:
1250 atari_enable_irq( IRQ_MFP_FDC );
1251 }
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261 static void finish_fdc( void )
1262 {
1263 if (!NeedSeek) {
1264 finish_fdc_done( 0 );
1265 }
1266 else {
1267 DPRINT(("finish_fdc: dummy seek started\n"));
1268 FDC_WRITE (FDCREG_DATA, SUD.track);
1269 SET_IRQ_HANDLER( finish_fdc_done );
1270 FDC_WRITE (FDCREG_CMD, FDCCMD_SEEK);
1271 MotorOn = 1;
1272 START_TIMEOUT();
1273
1274
1275
1276 }
1277 }
1278
1279
1280 static void finish_fdc_done( int dummy )
1281 {
1282 unsigned long flags;
1283
1284 DPRINT(("finish_fdc_done entered\n"));
1285 STOP_TIMEOUT();
1286 NeedSeek = 0;
1287
1288 if ((timer_active & (1 << FLOPPY_TIMER)) &&
1289 timer_table[FLOPPY_TIMER].expires < jiffies + 5)
1290
1291
1292
1293 timer_table[FLOPPY_TIMER].expires = jiffies + 5;
1294 else
1295 START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY );
1296 del_timer( &motor_off_timer );
1297 START_MOTOR_OFF_TIMER( FD_MOTOR_OFF_DELAY );
1298
1299 save_flags(flags);
1300 cli();
1301 stdma_release();
1302 fdc_busy = 0;
1303 wake_up( &fdc_wait );
1304 restore_flags(flags);
1305
1306 DPRINT(("finish_fdc() finished\n"));
1307 }
1308
1309
1310
1311 static fd_ref[4] = { 0,0,0,0 };
1312 static fd_device[4] = { 0,0,0,0 };
1313
1314
1315
1316
1317
1318 #define CURRENT_DEVICE (CURRENT->rq_dev)
1319
1320
1321 #define CURRENT_ERRORS (CURRENT->errors)
1322
1323
1324
1325 static void floppy_off( unsigned int nr) {}
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343 static int check_floppy_change (kdev_t dev)
1344 {
1345 unsigned int drive = MINOR(dev) & 0x03;
1346
1347 if (MAJOR(dev) != MAJOR_NR) {
1348 printk("floppy_changed: not a floppy\n");
1349 return 0;
1350 }
1351
1352 if (test_bit (drive, &fake_change)) {
1353
1354 return 1;
1355 }
1356 if (test_bit (drive, &changed_floppies)) {
1357
1358 return 1;
1359 }
1360 if (UD.wpstat) {
1361
1362
1363
1364 return 1;
1365 }
1366
1367 return 0;
1368 }
1369
1370 static int floppy_revalidate (kdev_t dev)
1371 {
1372 int drive = MINOR(dev) & 3;
1373
1374 if (test_bit (drive, &changed_floppies) || test_bit (drive, &fake_change)
1375 || unit[drive].disktype == 0)
1376 {
1377 BufferDrive = -1;
1378 clear_bit (drive, &fake_change);
1379 clear_bit (drive, &changed_floppies);
1380 UDT = 0;
1381 }
1382 return 0;
1383 }
1384
1385 static __inline__ void copy_buffer(void *from, void *to)
1386 {
1387 ulong *p1 = (ulong *)from, *p2 = (ulong *)to;
1388 int cnt;
1389
1390 for( cnt = 512/4; cnt; cnt-- )
1391 *p2++ = *p1++;
1392 }
1393
1394
1395
1396
1397 static void setup_req_params( int drive )
1398 {
1399 int block = ReqBlock + ReqCnt;
1400
1401 ReqTrack = block / UDT->spt;
1402 ReqSector = block - ReqTrack * UDT->spt + 1;
1403 ReqSide = ReqTrack & 1;
1404 ReqTrack >>= 1;
1405 ReqData = ReqBuffer + 512 * ReqCnt;
1406
1407 if (UseTrackbuffer)
1408 read_track = (ReqCmd == READ && CURRENT_ERRORS == 0);
1409 else
1410 read_track = 0;
1411
1412 DPRINT(("Request params: Si=%d Tr=%d Se=%d Data=%08lx\n",ReqSide,
1413 ReqTrack, ReqSector, (unsigned long)ReqData ));
1414 }
1415
1416
1417 static void redo_fd_request(void)
1418 {
1419 int device, drive, type;
1420
1421 DPRINT(("redo_fd_request: CURRENT=%08lx CURRENT->dev=%04x CURRENT->sector=%ld\n",
1422 (unsigned long)CURRENT, CURRENT ? CURRENT->rq_dev : 0,
1423 CURRENT ? CURRENT->sector : 0 ));
1424
1425 IsFormatting = 0;
1426
1427 if (CURRENT && CURRENT->rq_status == RQ_INACTIVE){
1428 return;
1429 }
1430
1431 repeat:
1432
1433 if (!CURRENT)
1434 goto the_end;
1435
1436 if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
1437 panic(DEVICE_NAME ": request list destroyed");
1438
1439 if (CURRENT->bh && !buffer_locked(CURRENT->bh))
1440 panic(DEVICE_NAME ": block not locked");
1441
1442 device = MINOR(CURRENT_DEVICE);
1443 drive = device & 3;
1444 type = device >> 2;
1445
1446 if (!UD.connected) {
1447
1448 printk( "Unknown Device: fd%d\n", drive );
1449 end_request(0);
1450 goto repeat;
1451 }
1452
1453 if (type == 0) {
1454 if (!UDT) {
1455 Probing = 1;
1456 UDT = disk_type + StartDiskType[DriveType];
1457 floppy_sizes[drive] = UDT->blocks >> 1;
1458 UD.autoprobe = 1;
1459 }
1460 }
1461 else {
1462
1463 if (--type >= NUM_DISK_MINORS) {
1464 printk( "fd%d: invalid disk format", drive );
1465 end_request( 0 );
1466 goto repeat;
1467 }
1468 if (minor2disktype[type].drive_types > DriveType) {
1469 printk( "fd%d: unsupported disk format", drive );
1470 end_request( 0 );
1471 goto repeat;
1472 }
1473 type = minor2disktype[type].index;
1474 UDT = &disk_type[type];
1475 floppy_sizes[drive] = UDT->blocks >> 1;
1476 UD.autoprobe = 0;
1477 }
1478
1479 if (CURRENT->sector + 1 > UDT->blocks) {
1480 end_request(0);
1481 goto repeat;
1482 }
1483
1484
1485 del_timer( &motor_off_timer );
1486
1487 ReqCnt = 0;
1488 ReqCmd = CURRENT->cmd;
1489 ReqBlock = CURRENT->sector;
1490 ReqBuffer = CURRENT->buffer;
1491 setup_req_params( drive );
1492 do_fd_action( drive );
1493
1494 return;
1495
1496 the_end:
1497 finish_fdc();
1498 }
1499
1500
1501 void do_fd_request(void)
1502 {
1503 unsigned long flags;
1504
1505 DPRINT(("do_fd_request for pid %d\n",current->pid));
1506 while( fdc_busy ) sleep_on( &fdc_wait );
1507 fdc_busy = 1;
1508 stdma_lock(floppy_irq, NULL);
1509
1510 atari_disable_irq( IRQ_MFP_FDC );
1511 save_flags(flags);
1512
1513 redo_fd_request();
1514 restore_flags(flags);
1515 atari_enable_irq( IRQ_MFP_FDC );
1516 }
1517
1518
1519 static int
1520 invalidate_drive (kdev_t rdev)
1521 {
1522
1523 BufferDrive = -1;
1524 set_bit (MINOR(rdev) & 3, &fake_change);
1525 check_disk_change (rdev);
1526 return 0;
1527 }
1528
1529 static int fd_ioctl(struct inode *inode, struct file *filp,
1530 unsigned int cmd, unsigned long param)
1531 {
1532 #define IOCTL_MODE_BIT 8
1533 #define OPEN_WRITE_BIT 16
1534 #define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
1535 #define COPYIN(x) (memcpy_fromfs( &(x), (void *) param, sizeof(x)))
1536
1537 int drive, type, error;
1538 kdev_t device;
1539 struct atari_format_descr fmt_desc;
1540 struct atari_disk_type *dtp;
1541 struct floppy_struct getprm;
1542
1543 device = inode->i_rdev;
1544 switch (cmd) {
1545 RO_IOCTLS (device, param);
1546 }
1547 drive = MINOR (device);
1548 type = drive >> 2;
1549 drive &= 3;
1550 switch (cmd) {
1551 case FDGETPRM:
1552 if (type) {
1553 if (--type >= NUM_DISK_MINORS)
1554 return -ENODEV;
1555 if (minor2disktype[type].drive_types > DriveType)
1556 return -ENODEV;
1557 type = minor2disktype[type].index;
1558 dtp = &disk_type[type];
1559 }
1560 else {
1561 if (!UDT)
1562 return -ENXIO;
1563 else
1564 dtp = UDT;
1565 }
1566 error = verify_area(VERIFY_WRITE, (void *)param,
1567 sizeof(struct floppy_struct));
1568 if (error)
1569 return( error );
1570 memset((void *)&getprm, 0, sizeof(getprm));
1571 getprm.size = dtp->blocks;
1572 getprm.sect = dtp->spt;
1573 getprm.head = 2;
1574 getprm.track = dtp->blocks/dtp->spt/2;
1575 getprm.stretch = dtp->stretch;
1576 memcpy_tofs((void *)param, &getprm, sizeof(struct floppy_struct));
1577 return 0;
1578 }
1579 if (!IOCTL_ALLOWED)
1580 return -EPERM;
1581 switch (cmd) {
1582 case FDSETPRM:
1583 case FDDEFPRM:
1584 return -EINVAL;
1585 case FDMSGON:
1586 UD.flags |= FTD_MSG;
1587 return 0;
1588 case FDMSGOFF:
1589 UD.flags &= ~FTD_MSG;
1590 return 0;
1591 case FDSETEMSGTRESH:
1592 return -EINVAL;
1593 case FDFMTBEG:
1594 return 0;
1595 case FDFMTTRK:
1596 if (fd_ref[drive] != 1 && fd_ref[drive] != -1)
1597 return -EBUSY;
1598 if ((error = verify_area(VERIFY_READ, (void *)param,
1599 sizeof(struct atari_format_descr) )))
1600 return( error );
1601 COPYIN( fmt_desc );
1602 return do_format(device, &fmt_desc);
1603 case FDCLRPRM:
1604 UDT = NULL;
1605 floppy_sizes[drive] = MAX_DISK_SIZE;
1606 return invalidate_drive (device);
1607 case FDFMTEND:
1608 case FDFLUSH:
1609 return invalidate_drive (drive);
1610 }
1611 return -EINVAL;
1612 }
1613
1614
1615
1616
1617 static void fd_probe( int drive )
1618 {
1619 UD.connected = 0;
1620 UDT = NULL;
1621
1622 if (!fd_test_drive_present( drive ))
1623 return;
1624
1625 UD.connected = 1;
1626 UD.track = 0;
1627 switch( UserSteprate[drive] ) {
1628 case 2:
1629 UD.steprate = FDCSTEP_2;
1630 break;
1631 case 3:
1632 UD.steprate = FDCSTEP_3;
1633 break;
1634 case 6:
1635 UD.steprate = FDCSTEP_6;
1636 break;
1637 case 12:
1638 UD.steprate = FDCSTEP_12;
1639 break;
1640 default:
1641 if (ATARIHW_PRESENT( FDCSPEED ) || is_medusa)
1642 UD.steprate = FDCSTEP_3;
1643 else
1644 UD.steprate = FDCSTEP_6;
1645 break;
1646 }
1647 MotorOn = 1;
1648 }
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660 static int fd_test_drive_present( int drive )
1661 {
1662 unsigned long timeout;
1663 unsigned char status;
1664 int ok;
1665
1666 if (drive > 1) return( 0 );
1667 fd_select_drive( drive );
1668
1669
1670 atari_turnoff_irq( IRQ_MFP_FDC );
1671 FDC_WRITE (FDCREG_TRACK, 0xff00);
1672 FDC_WRITE( FDCREG_CMD, FDCCMD_RESTORE | FDCCMDADD_H | FDCSTEP_6 );
1673
1674 for( ok = 0, timeout = jiffies + 2*HZ+HZ/2; jiffies < timeout; ) {
1675 if (!(mfp.par_dt_reg & 0x20))
1676 break;
1677 }
1678
1679 status = FDC_READ( FDCREG_STATUS );
1680 ok = (status & FDCSTAT_TR00) != 0;
1681
1682
1683
1684 FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
1685 udelay(500);
1686 status = FDC_READ( FDCREG_STATUS );
1687 udelay(20);
1688
1689 if (ok) {
1690
1691 FDC_WRITE( FDCREG_DATA, 0 );
1692 FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK );
1693 while( mfp.par_dt_reg & 0x20 )
1694 ;
1695 status = FDC_READ( FDCREG_STATUS );
1696 }
1697
1698 atari_turnon_irq( IRQ_MFP_FDC );
1699 return( ok );
1700 }
1701
1702
1703
1704
1705
1706
1707 static void config_types( void )
1708 {
1709 int drive, cnt = 0;
1710
1711
1712 if (ATARIHW_PRESENT(FDCSPEED))
1713 dma_wd.fdc_speed = 0;
1714
1715 printk("Probing floppy drive(s):\n");
1716 for( drive = 0; drive < FD_MAX_UNITS; drive++ ) {
1717 fd_probe( drive );
1718 if (UD.connected) {
1719 printk("fd%d\n", drive);
1720 ++cnt;
1721 }
1722 }
1723
1724 if (FDC_READ( FDCREG_STATUS ) & FDCSTAT_BUSY) {
1725
1726
1727
1728
1729
1730
1731 FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
1732 udelay(500);
1733 FDC_READ( FDCREG_STATUS );
1734 udelay(20);
1735 }
1736
1737 if (cnt > 0) {
1738 START_MOTOR_OFF_TIMER( FD_MOTOR_OFF_DELAY );
1739 if (cnt == 1) fd_select_drive( 0 );
1740 START_CHECK_CHANGE_TIMER( CHECK_CHANGE_DELAY );
1741 }
1742 }
1743
1744
1745
1746
1747
1748
1749
1750 static int floppy_open( struct inode *inode, struct file *filp )
1751 {
1752 int drive, type;
1753 int old_dev;
1754
1755 if (!filp)
1756 {
1757 DPRINT (("Weird, open called with filp=0\n"));
1758 return -EIO;
1759 }
1760
1761 drive = MINOR (inode->i_rdev) & 3;
1762 type = MINOR(inode->i_rdev) >> 2;
1763 DPRINT(("fd_open: type=%d\n",type));
1764 if (type > NUM_DISK_MINORS)
1765 return -ENXIO;
1766
1767 old_dev = fd_device[drive];
1768
1769 if (fd_ref[drive])
1770 if (old_dev != inode->i_rdev)
1771 return -EBUSY;
1772
1773 if (fd_ref[drive] == -1 || (fd_ref[drive] && filp->f_flags & O_EXCL))
1774 return -EBUSY;
1775
1776 if (filp->f_flags & O_EXCL)
1777 fd_ref[drive] = -1;
1778 else
1779 fd_ref[drive]++;
1780
1781 fd_device[drive] = inode->i_rdev;
1782
1783 if (old_dev && old_dev != inode->i_rdev)
1784 invalidate_buffers(old_dev);
1785
1786
1787 if (filp->f_mode & 2 || permission (inode, 2) == 0)
1788 filp->f_mode |= IOCTL_MODE_BIT;
1789 if (filp->f_mode & 2)
1790 filp->f_mode |= OPEN_WRITE_BIT;
1791
1792 if (filp->f_flags & O_NDELAY)
1793 return 0;
1794
1795 if (filp->f_mode & 3) {
1796 check_disk_change( inode->i_rdev );
1797 if (filp->f_mode & 2) {
1798 if (UD.wpstat) {
1799 floppy_release(inode, filp);
1800 return -EROFS;
1801 }
1802 }
1803 }
1804
1805 return 0;
1806 }
1807
1808
1809 static void floppy_release( struct inode * inode, struct file * filp )
1810 {
1811 int drive;
1812
1813 drive = inode->i_rdev & 3;
1814
1815 if (!filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
1816
1817
1818 block_fsync (inode, filp);
1819
1820 if (fd_ref[drive] < 0)
1821 fd_ref[drive] = 0;
1822 else if (!fd_ref[drive]--)
1823 {
1824 printk("floppy_release with fd_ref == 0");
1825 fd_ref[drive] = 0;
1826 }
1827 }
1828
1829 static struct file_operations floppy_fops = {
1830 NULL,
1831 block_read,
1832 block_write,
1833 NULL,
1834 NULL,
1835 fd_ioctl,
1836 NULL,
1837 floppy_open,
1838 floppy_release,
1839 block_fsync,
1840 NULL,
1841 check_floppy_change,
1842 floppy_revalidate,
1843 };
1844
1845 int atari_floppy_init (void)
1846 {
1847 int i;
1848
1849 if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
1850 printk("Unable to get major %d for floppy\n",MAJOR_NR);
1851 return -EBUSY;
1852 }
1853
1854 if (UseTrackbuffer < 0)
1855
1856
1857
1858
1859 UseTrackbuffer = !is_medusa;
1860
1861
1862 SelectedDrive = -1;
1863 BufferDrive = -1;
1864
1865
1866 timer_table[FLOPPY_TIMER].fn = check_change;
1867 timer_active &= ~(1 << FLOPPY_TIMER);
1868
1869 DMABuffer = kmalloc(BUFFER_SIZE + 512, GFP_KERNEL | GFP_DMA);
1870 if (!DMABuffer) {
1871 printk("atari_floppy_init: cannot get dma buffer\n");
1872 unregister_blkdev(MAJOR_NR, "fd");
1873 return -ENOMEM;
1874 }
1875 TrackBuffer = DMABuffer + 512;
1876 PhysDMABuffer = (unsigned long) VTOP(DMABuffer);
1877 PhysTrackBuffer = (unsigned long) VTOP(TrackBuffer);
1878 BufferDrive = BufferSide = BufferTrack = -1;
1879
1880 for (i = 0; i < FD_MAX_UNITS; i++) {
1881 unit[i].track = -1;
1882 unit[i].flags = 0;
1883 }
1884
1885 for (i = 0; i < 256; i++)
1886 if ((i >> 2) > 0 && (i >> 2) <= NUM_DISK_MINORS) {
1887 int type = minor2disktype[(i >> 2) - 1].index;
1888 floppy_sizes[i] = disk_type[type].blocks >> 1;
1889 } else
1890 floppy_sizes[i] = MAX_DISK_SIZE;
1891
1892 blk_size[MAJOR_NR] = floppy_sizes;
1893 blksize_size[MAJOR_NR] = floppy_blocksizes;
1894 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1895
1896 printk("Atari floppy driver: max. %cD, %strack buffering\n",
1897 DriveType == 0 ? 'D' : DriveType == 1 ? 'H' : 'E',
1898 UseTrackbuffer ? "" : "no ");
1899 config_types();
1900
1901 return 0;
1902 }
1903
1904
1905 void atari_floppy_setup( char *str, int *ints )
1906 {
1907 int i;
1908
1909 if (ints[0] < 1) {
1910 printk( "ataflop_setup: no arguments!\n" );
1911 return;
1912 }
1913 else if (ints[0] > 2+FD_MAX_UNITS) {
1914 printk( "ataflop_setup: too many arguments\n" );
1915 }
1916
1917 if (ints[1] < 0 || ints[1] > 2)
1918 printk( "ataflop_setup: bad drive type\n" );
1919 else
1920 DriveType = ints[1];
1921
1922 if (ints[0] >= 2)
1923 UseTrackbuffer = (ints[2] > 0);
1924
1925 for( i = 3; i <= ints[0] && i-3 < FD_MAX_UNITS; ++i ) {
1926 if (ints[i] != 2 && ints[i] != 3 && ints[i] != 6 && ints[i] != 12)
1927 printk( "ataflop_setup: bad steprate\n" );
1928 else
1929 UserSteprate[i-3] = ints[i];
1930 }
1931 }
1932
1933 #ifdef MODULE
1934 int init_module (void)
1935 {
1936 return atari_floppy_init ();
1937 }
1938
1939 void cleanup_module (void)
1940 {
1941 unregister_blkdev(MAJOR_NR, "fd");
1942
1943 blk_dev[MAJOR_NR].request_fn = 0;
1944 timer_active &= ~(1 << FLOPPY_TIMER);
1945 timer_table[FLOPPY_TIMER].fn = 0;
1946 kfree (DMABuffer);
1947 }
1948 #else
1949
1950
1951
1952 void floppy_eject(void)
1953 {
1954 }
1955 #endif
1956