ataflop.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:52k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  drivers/block/ataflop.c
  3.  *
  4.  *  Copyright (C) 1993  Greg Harp
  5.  *  Atari Support by Bjoern Brauel, Roman Hodek
  6.  *
  7.  *  Big cleanup Sep 11..14 1994 Roman Hodek:
  8.  *   - Driver now works interrupt driven
  9.  *   - Support for two drives; should work, but I cannot test that :-(
  10.  *   - Reading is done in whole tracks and buffered to speed up things
  11.  *   - Disk change detection and drive deselecting after motor-off
  12.  *     similar to TOS
  13.  *   - Autodetection of disk format (DD/HD); untested yet, because I
  14.  *     don't have an HD drive :-(
  15.  *
  16.  *  Fixes Nov 13 1994 Martin Schaller:
  17.  *   - Autodetection works now
  18.  *   - Support for 5 1/4'' disks
  19.  *   - Removed drive type (unknown on atari)
  20.  *   - Do seeks with 8 Mhz
  21.  *
  22.  *  Changes by Andreas Schwab:
  23.  *   - After errors in multiple read mode try again reading single sectors
  24.  *  (Feb 1995):
  25.  *   - Clean up error handling
  26.  *   - Set blk_size for proper size checking
  27.  *   - Initialize track register when testing presence of floppy
  28.  *   - Implement some ioctl's
  29.  *
  30.  *  Changes by Torsten Lang:
  31.  *   - When probing the floppies we should add the FDCCMDADD_H flag since
  32.  *     the FDC will otherwise wait forever when no disk is inserted...
  33.  *
  34.  * ++ Freddi Aschwanden (fa) 20.9.95 fixes for medusa:
  35.  *  - MFPDELAY() after each FDC access -> atari 
  36.  *  - more/other disk formats
  37.  *  - DMA to the block buffer directly if we have a 32bit DMA
  38.  *  - for medusa, the step rate is always 3ms
  39.  *  - on medusa, use only cache_push()
  40.  * Roman:
  41.  *  - Make disk format numbering independent from minors
  42.  *  - Let user set max. supported drive type (speeds up format
  43.  *    detection, saves buffer space)
  44.  *
  45.  * Roman 10/15/95:
  46.  *  - implement some more ioctls
  47.  *  - disk formatting
  48.  *  
  49.  * Andreas 95/12/12:
  50.  *  - increase gap size at start of track for HD/ED disks
  51.  *
  52.  * Michael (MSch) 11/07/96:
  53.  *  - implemented FDSETPRM and FDDEFPRM ioctl
  54.  *
  55.  * Andreas (97/03/19):
  56.  *  - implemented missing BLK* ioctls
  57.  *
  58.  *  Things left to do:
  59.  *   - Formatting
  60.  *   - Maybe a better strategy for disk change detection (does anyone
  61.  *     know one?)
  62.  */
  63. #include <linux/module.h>
  64. #include <linux/sched.h>
  65. #include <linux/string.h>
  66. #include <linux/fs.h>
  67. #include <linux/fcntl.h>
  68. #include <linux/kernel.h>
  69. #include <linux/timer.h>
  70. #include <linux/fd.h>
  71. #include <linux/errno.h>
  72. #include <linux/types.h>
  73. #include <linux/delay.h>
  74. #include <linux/mm.h>
  75. #include <linux/slab.h>
  76. #include <linux/init.h>
  77. #include <asm/setup.h>
  78. #include <asm/system.h>
  79. #include <asm/bitops.h>
  80. #include <asm/irq.h>
  81. #include <asm/pgtable.h>
  82. #include <asm/uaccess.h>
  83. #include <asm/atafd.h>
  84. #include <asm/atafdreg.h>
  85. #include <asm/atarihw.h>
  86. #include <asm/atariints.h>
  87. #include <asm/atari_stdma.h>
  88. #include <asm/atari_stram.h>
  89. #define MAJOR_NR FLOPPY_MAJOR
  90. #include <linux/blk.h>
  91. #include <linux/blkpg.h>
  92. #define FD_MAX_UNITS 2
  93. #undef DEBUG
  94. /* Disk types: DD, HD, ED */
  95. static struct atari_disk_type {
  96. const char *name;
  97. unsigned spt; /* sectors per track */
  98. unsigned blocks; /* total number of blocks */
  99. unsigned fdc_speed; /* fdc_speed setting */
  100. unsigned  stretch; /* track doubling ? */
  101. } disk_type[] = {
  102. { "d360",  9, 720, 0, 0}, /*  0: 360kB diskette */
  103. { "D360",  9, 720, 0, 1}, /*  1: 360kb in 720k or 1.2MB drive */
  104. { "D720",  9,1440, 0, 0}, /*  2: 720kb in 720k or 1.2MB drive */
  105. { "D820", 10,1640, 0, 0}, /*  3: DD disk with 82 tracks/10 sectors */
  106. /* formats above are probed for type DD */
  107. #define MAX_TYPE_DD 3
  108. { "h1200",15,2400, 3, 0}, /*  4: 1.2MB diskette */
  109. { "H1440",18,2880, 3, 0}, /*  5: 1.4 MB diskette (HD) */
  110. { "H1640",20,3280, 3, 0}, /*  6: 1.64MB diskette (fat HD) 82 tr 20 sec */
  111. /* formats above are probed for types DD and HD */
  112. #define MAX_TYPE_HD 6
  113. { "E2880",36,5760, 3, 0}, /*  7: 2.8 MB diskette (ED) */
  114. { "E3280",40,6560, 3, 0}, /*  8: 3.2 MB diskette (fat ED) 82 tr 40 sec */
  115. /* formats above are probed for types DD, HD and ED */
  116. #define MAX_TYPE_ED 8
  117. /* types below are never autoprobed */
  118. { "H1680",21,3360, 3, 0}, /*  9: 1.68MB diskette (fat HD) 80 tr 21 sec */
  119. { "h410",10,820, 0, 1}, /* 10: 410k diskette 41 tr 10 sec, stretch */
  120. { "h1476",18,2952, 3, 0}, /* 11: 1.48MB diskette 82 tr 18 sec */
  121. { "H1722",21,3444, 3, 0}, /* 12: 1.72MB diskette 82 tr 21 sec */
  122. { "h420",10,840, 0, 1}, /* 13: 420k diskette 42 tr 10 sec, stretch */
  123. { "H830",10,1660, 0, 0}, /* 14: 820k diskette 83 tr 10 sec */
  124. { "h1494",18,2952, 3, 0}, /* 15: 1.49MB diskette 83 tr 18 sec */
  125. { "H1743",21,3486, 3, 0}, /* 16: 1.74MB diskette 83 tr 21 sec */
  126. { "h880",11,1760, 0, 0}, /* 17: 880k diskette 80 tr 11 sec */
  127. { "D1040",13,2080, 0, 0}, /* 18: 1.04MB diskette 80 tr 13 sec */
  128. { "D1120",14,2240, 0, 0}, /* 19: 1.12MB diskette 80 tr 14 sec */
  129. { "h1600",20,3200, 3, 0}, /* 20: 1.60MB diskette 80 tr 20 sec */
  130. { "H1760",22,3520, 3, 0}, /* 21: 1.76MB diskette 80 tr 22 sec */
  131. { "H1920",24,3840, 3, 0}, /* 22: 1.92MB diskette 80 tr 24 sec */
  132. { "E3200",40,6400, 3, 0}, /* 23: 3.2MB diskette 80 tr 40 sec */
  133. { "E3520",44,7040, 3, 0}, /* 24: 3.52MB diskette 80 tr 44 sec */
  134. { "E3840",48,7680, 3, 0}, /* 25: 3.84MB diskette 80 tr 48 sec */
  135. { "H1840",23,3680, 3, 0}, /* 26: 1.84MB diskette 80 tr 23 sec */
  136. { "D800",10,1600, 0, 0}, /* 27: 800k diskette 80 tr 10 sec */
  137. };
  138. static int StartDiskType[] = {
  139. MAX_TYPE_DD,
  140. MAX_TYPE_HD,
  141. MAX_TYPE_ED
  142. };
  143. #define TYPE_DD 0
  144. #define TYPE_HD 1
  145. #define TYPE_ED 2
  146. static int DriveType = TYPE_HD;
  147. /* Array for translating minors into disk formats */
  148. static struct {
  149. int   index;
  150. unsigned drive_types;
  151. } minor2disktype[] = {
  152. {  0, TYPE_DD }, /*  1: d360 */
  153. {  4, TYPE_HD }, /*  2: h1200 */
  154. {  1, TYPE_DD }, /*  3: D360 */
  155. {  2, TYPE_DD }, /*  4: D720 */
  156. {  1, TYPE_DD }, /*  5: h360 = D360 */
  157. {  2, TYPE_DD }, /*  6: h720 = D720 */
  158. {  5, TYPE_HD }, /*  7: H1440 */
  159. {  7, TYPE_ED }, /*  8: E2880 */
  160. /* some PC formats :-) */
  161. {  8, TYPE_ED }, /*  9: E3280    <- was "CompaQ" == E2880 for PC */
  162. {  5, TYPE_HD }, /* 10: h1440 = H1440 */
  163. {  9, TYPE_HD }, /* 11: H1680 */
  164. { 10, TYPE_DD }, /* 12: h410  */
  165. {  3, TYPE_DD }, /* 13: H820     <- == D820, 82x10 */
  166. { 11, TYPE_HD }, /* 14: h1476 */
  167. { 12, TYPE_HD }, /* 15: H1722 */
  168. { 13, TYPE_DD }, /* 16: h420  */
  169. { 14, TYPE_DD }, /* 17: H830  */
  170. { 15, TYPE_HD }, /* 18: h1494 */
  171. { 16, TYPE_HD }, /* 19: H1743 */
  172. { 17, TYPE_DD }, /* 20: h880  */
  173. { 18, TYPE_DD }, /* 21: D1040 */
  174. { 19, TYPE_DD }, /* 22: D1120 */
  175. { 20, TYPE_HD }, /* 23: h1600 */
  176. { 21, TYPE_HD }, /* 24: H1760 */
  177. { 22, TYPE_HD }, /* 25: H1920 */
  178. { 23, TYPE_ED }, /* 26: E3200 */
  179. { 24, TYPE_ED }, /* 27: E3520 */
  180. { 25, TYPE_ED }, /* 28: E3840 */
  181. { 26, TYPE_HD }, /* 29: H1840 */
  182. { 27, TYPE_DD }, /* 30: D800  */
  183. {  6, TYPE_HD }, /* 31: H1640    <- was H1600 == h1600 for PC */
  184. };
  185. #define NUM_DISK_MINORS (sizeof(minor2disktype)/sizeof(*minor2disktype))
  186. /*
  187.  * Maximum disk size (in kilobytes). This default is used whenever the
  188.  * current disk size is unknown.
  189.  */
  190. #define MAX_DISK_SIZE 3280
  191. /*
  192.  * MSch: User-provided type information. 'drive' points to
  193.  * the respective entry of this array. Set by FDSETPRM ioctls.
  194.  */
  195. static struct atari_disk_type user_params[FD_MAX_UNITS];
  196. /*
  197.  * User-provided permanent type information. 'drive' points to
  198.  * the respective entry of this array.  Set by FDDEFPRM ioctls, 
  199.  * restored upon disk change by floppy_revalidate() if valid (as seen by
  200.  * default_params[].blocks > 0 - a bit in unit[].flags might be used for this?)
  201.  */
  202. static struct atari_disk_type default_params[FD_MAX_UNITS];
  203. static int floppy_sizes[256];
  204. static int floppy_blocksizes[256];
  205. /* current info on each unit */
  206. static struct atari_floppy_struct {
  207. int connected; /* !=0 : drive is connected */
  208. int autoprobe; /* !=0 : do autoprobe     */
  209. struct atari_disk_type *disktype; /* current type of disk */
  210. int track; /* current head position or -1 if
  211.    unknown */
  212. unsigned int steprate; /* steprate setting */
  213. unsigned int wpstat; /* current state of WP signal (for
  214.    disk change detection) */
  215. int flags; /* flags */
  216. } unit[FD_MAX_UNITS];
  217. #define UD unit[drive]
  218. #define UDT unit[drive].disktype
  219. #define SUD unit[SelectedDrive]
  220. #define SUDT unit[SelectedDrive].disktype
  221. #define FDC_READ(reg) ({
  222.     /* unsigned long __flags; */
  223.     unsigned short __val;
  224.     /* save_flags(__flags); cli(); */
  225.     dma_wd.dma_mode_status = 0x80 | (reg);
  226.     udelay(25);
  227.     __val = dma_wd.fdc_acces_seccount;
  228.     MFPDELAY();
  229.     /* restore_flags(__flags); */
  230.     __val & 0xff;
  231. })
  232. #define FDC_WRITE(reg,val)
  233.     do {
  234. /* unsigned long __flags; */
  235. /* save_flags(__flags); cli(); */
  236. dma_wd.dma_mode_status = 0x80 | (reg);
  237. udelay(25);
  238. dma_wd.fdc_acces_seccount = (val);
  239. MFPDELAY();
  240.         /* restore_flags(__flags); */
  241.     } while(0)
  242. /* Buffering variables:
  243.  * First, there is a DMA buffer in ST-RAM that is used for floppy DMA
  244.  * operations. Second, a track buffer is used to cache a whole track
  245.  * of the disk to save read operations. These are two separate buffers
  246.  * because that allows write operations without clearing the track buffer.
  247.  */
  248. static int MaxSectors[] = {
  249. 11, 22, 44
  250. };
  251. static int BufferSize[] = {
  252. 15*512, 30*512, 60*512
  253. };
  254. #define BUFFER_SIZE (BufferSize[DriveType])
  255. unsigned char *DMABuffer;   /* buffer for writes */
  256. static unsigned long PhysDMABuffer;   /* physical address */
  257. static int UseTrackbuffer = -1;   /* Do track buffering? */
  258. MODULE_PARM(UseTrackbuffer, "i");
  259. unsigned char *TrackBuffer;   /* buffer for reads */
  260. static unsigned long PhysTrackBuffer; /* physical address */
  261. static int BufferDrive, BufferSide, BufferTrack;
  262. static int read_track; /* non-zero if we are reading whole tracks */
  263. #define SECTOR_BUFFER(sec) (TrackBuffer + ((sec)-1)*512)
  264. #define IS_BUFFERED(drive,side,track) 
  265.     (BufferDrive == (drive) && BufferSide == (side) && BufferTrack == (track))
  266. /*
  267.  * These are global variables, as that's the easiest way to give
  268.  * information to interrupts. They are the data used for the current
  269.  * request.
  270.  */
  271. static int SelectedDrive = 0;
  272. static int ReqCmd, ReqBlock;
  273. static int ReqSide, ReqTrack, ReqSector, ReqCnt;
  274. static int HeadSettleFlag = 0;
  275. static unsigned char *ReqData, *ReqBuffer;
  276. static int MotorOn = 0, MotorOffTrys;
  277. static int IsFormatting = 0, FormatError;
  278. static int UserSteprate[FD_MAX_UNITS] = { -1, -1 };
  279. MODULE_PARM(UserSteprate, "1-" __MODULE_STRING(FD_MAX_UNITS) "i");
  280. /* Synchronization of FDC access. */
  281. static volatile int fdc_busy = 0;
  282. static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
  283. static DECLARE_WAIT_QUEUE_HEAD(format_wait);
  284. static unsigned long changed_floppies = 0xff, fake_change = 0;
  285. #define CHECK_CHANGE_DELAY HZ/2
  286. #define FD_MOTOR_OFF_DELAY (3*HZ)
  287. #define FD_MOTOR_OFF_MAXTRY (10*20)
  288. #define FLOPPY_TIMEOUT (6*HZ)
  289. #define RECALIBRATE_ERRORS 4 /* After this many errors the drive
  290.  * will be recalibrated. */
  291. #define MAX_ERRORS 8 /* After this many errors the driver
  292.  * will give up. */
  293. /*
  294.  * The driver is trying to determine the correct media format
  295.  * while Probing is set. fd_rwsec_done() clears it after a
  296.  * successful access.
  297.  */
  298. static int Probing = 0;
  299. /* This flag is set when a dummy seek is necessary to make the WP
  300.  * status bit accessible.
  301.  */
  302. static int NeedSeek = 0;
  303. #ifdef DEBUG
  304. #define DPRINT(a) printk a
  305. #else
  306. #define DPRINT(a)
  307. #endif
  308. /***************************** Prototypes *****************************/
  309. static void fd_select_side( int side );
  310. static void fd_select_drive( int drive );
  311. static void fd_deselect( void );
  312. static void fd_motor_off_timer( unsigned long dummy );
  313. static void check_change( void );
  314. static __inline__ void set_head_settle_flag( void );
  315. static __inline__ int get_head_settle_flag( void );
  316. static void floppy_irq (int irq, void *dummy, struct pt_regs *fp);
  317. static void fd_error( void );
  318. static int do_format(kdev_t drive, struct atari_format_descr *desc);
  319. static void do_fd_action( int drive );
  320. static void fd_calibrate( void );
  321. static void fd_calibrate_done( int status );
  322. static void fd_seek( void );
  323. static void fd_seek_done( int status );
  324. static void fd_rwsec( void );
  325. static void fd_readtrack_check( unsigned long dummy );
  326. static void fd_rwsec_done( int status );
  327. static void fd_rwsec_done1(int status);
  328. static void fd_writetrack( void );
  329. static void fd_writetrack_done( int status );
  330. static void fd_times_out( unsigned long dummy );
  331. static void finish_fdc( void );
  332. static void finish_fdc_done( int dummy );
  333. static void floppy_off( unsigned int nr);
  334. static __inline__ void copy_buffer( void *from, void *to);
  335. static void setup_req_params( int drive );
  336. static void redo_fd_request( void);
  337. static int invalidate_drive(kdev_t rdev);
  338. static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int
  339.                      cmd, unsigned long param);
  340. static void fd_probe( int drive );
  341. static int fd_test_drive_present( int drive );
  342. static void config_types( void );
  343. static int floppy_open( struct inode *inode, struct file *filp );
  344. static int floppy_release( struct inode * inode, struct file * filp );
  345. /************************* End of Prototypes **************************/
  346. static struct timer_list motor_off_timer =
  347. { function: fd_motor_off_timer };
  348. static struct timer_list readtrack_timer =
  349. { function: fd_readtrack_check };
  350. static struct timer_list timeout_timer =
  351. { function: fd_times_out };
  352. static struct timer_list fd_timer =
  353. { function: check_change };
  354. static inline void
  355. start_motor_off_timer(void)
  356. {
  357. mod_timer(&motor_off_timer, jiffies + FD_MOTOR_OFF_DELAY);
  358. MotorOffTrys = 0;
  359. }
  360. static inline void
  361. start_check_change_timer( void )
  362. {
  363. mod_timer(&fd_timer, jiffies + CHECK_CHANGE_DELAY);
  364. }
  365. static inline void
  366. start_timeout(void)
  367. {
  368. mod_timer(&timeout_timer, jiffies + FLOPPY_TIMEOUT);
  369. }
  370. static inline void
  371. stop_timeout(void)
  372. {
  373. del_timer(&timeout_timer);
  374. }
  375. /* Select the side to use. */
  376. static void fd_select_side( int side )
  377. {
  378. unsigned long flags;
  379. save_flags(flags);
  380. cli(); /* protect against various other ints mucking around with the PSG */
  381.   
  382. sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */
  383. sound_ym.wd_data = (side == 0) ? sound_ym.rd_data_reg_sel | 0x01 :
  384.                                  sound_ym.rd_data_reg_sel & 0xfe;
  385. restore_flags(flags);
  386. }
  387. /* Select a drive, update the FDC's track register and set the correct
  388.  * clock speed for this disk's type.
  389.  */
  390. static void fd_select_drive( int drive )
  391. {
  392. unsigned long flags;
  393. unsigned char tmp;
  394.   
  395. if (drive == SelectedDrive)
  396.   return;
  397. save_flags(flags);
  398. cli(); /* protect against various other ints mucking around with the PSG */
  399. sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */
  400. tmp = sound_ym.rd_data_reg_sel;
  401. sound_ym.wd_data = (tmp | DSKDRVNONE) & ~(drive == 0 ? DSKDRV0 : DSKDRV1);
  402. atari_dont_touch_floppy_select = 1;
  403. restore_flags(flags);
  404. /* restore track register to saved value */
  405. FDC_WRITE( FDCREG_TRACK, UD.track );
  406. udelay(25);
  407. /* select 8/16 MHz */
  408. if (UDT)
  409. if (ATARIHW_PRESENT(FDCSPEED))
  410. dma_wd.fdc_speed = UDT->fdc_speed;
  411. SelectedDrive = drive;
  412. }
  413. /* Deselect both drives. */
  414. static void fd_deselect( void )
  415. {
  416. unsigned long flags;
  417. save_flags(flags);
  418. cli(); /* protect against various other ints mucking around with the PSG */
  419. atari_dont_touch_floppy_select = 0;
  420. sound_ym.rd_data_reg_sel=14; /* Select PSG Port A */
  421. sound_ym.wd_data = (sound_ym.rd_data_reg_sel |
  422.     (MACH_IS_FALCON ? 3 : 7)); /* no drives selected */
  423. /* On Falcon, the drive B select line is used on the printer port, so
  424.  * leave it alone... */
  425. SelectedDrive = -1;
  426. restore_flags(flags);
  427. }
  428. /* This timer function deselects the drives when the FDC switched the
  429.  * motor off. The deselection cannot happen earlier because the FDC
  430.  * counts the index signals, which arrive only if one drive is selected.
  431.  */
  432. static void fd_motor_off_timer( unsigned long dummy )
  433. {
  434. unsigned char status;
  435. if (SelectedDrive < 0)
  436. /* no drive selected, needn't deselect anyone */
  437. return;
  438. if (stdma_islocked())
  439. goto retry;
  440. status = FDC_READ( FDCREG_STATUS );
  441. if (!(status & 0x80)) {
  442. /* motor already turned off by FDC -> deselect drives */
  443. MotorOn = 0;
  444. fd_deselect();
  445. return;
  446. }
  447. /* not yet off, try again */
  448.   retry:
  449. /* Test again later; if tested too often, it seems there is no disk
  450.  * in the drive and the FDC will leave the motor on forever (or,
  451.  * at least until a disk is inserted). So we'll test only twice
  452.  * per second from then on...
  453.  */
  454. mod_timer(&motor_off_timer,
  455.   jiffies + (MotorOffTrys++ < FD_MOTOR_OFF_MAXTRY ? HZ/20 : HZ/2));
  456. }
  457. /* This function is repeatedly called to detect disk changes (as good
  458.  * as possible) and keep track of the current state of the write protection.
  459.  */
  460. static void check_change( void )
  461. {
  462. static int    drive = 0;
  463. unsigned long flags;
  464. unsigned char old_porta;
  465. int   stat;
  466. if (++drive > 1 || !UD.connected)
  467. drive = 0;
  468. save_flags(flags);
  469. cli(); /* protect against various other ints mucking around with the PSG */
  470. if (!stdma_islocked()) {
  471. sound_ym.rd_data_reg_sel = 14;
  472. old_porta = sound_ym.rd_data_reg_sel;
  473. sound_ym.wd_data = (old_porta | DSKDRVNONE) &
  474.                ~(drive == 0 ? DSKDRV0 : DSKDRV1);
  475. stat = !!(FDC_READ( FDCREG_STATUS ) & FDCSTAT_WPROT);
  476. sound_ym.wd_data = old_porta;
  477. if (stat != UD.wpstat) {
  478. DPRINT(( "wpstat[%d] = %dn", drive, stat ));
  479. UD.wpstat = stat;
  480. set_bit (drive, &changed_floppies);
  481. }
  482. }
  483. restore_flags(flags);
  484. start_check_change_timer();
  485. }
  486.  
  487. /* Handling of the Head Settling Flag: This flag should be set after each
  488.  * seek operation, because we don't use seeks with verify.
  489.  */
  490. static __inline__ void set_head_settle_flag( void )
  491. {
  492. HeadSettleFlag = FDCCMDADD_E;
  493. }
  494. static __inline__ int get_head_settle_flag( void )
  495. {
  496. int tmp = HeadSettleFlag;
  497. HeadSettleFlag = 0;
  498. return( tmp );
  499. }
  500.   
  501.   
  502. /* General Interrupt Handling */
  503. static void (*FloppyIRQHandler)( int status ) = NULL;
  504. static void floppy_irq (int irq, void *dummy, struct pt_regs *fp)
  505. {
  506. unsigned char status;
  507. void (*handler)( int );
  508. handler = xchg(&FloppyIRQHandler, NULL);
  509. if (handler) {
  510. nop();
  511. status = FDC_READ( FDCREG_STATUS );
  512. DPRINT(("FDC irq, status = %02x handler = %08lxn",status,(unsigned long)handler));
  513. handler( status );
  514. }
  515. else {
  516. DPRINT(("FDC irq, no handlern"));
  517. }
  518. }
  519. /* Error handling: If some error happened, retry some times, then
  520.  * recalibrate, then try again, and fail after MAX_ERRORS.
  521.  */
  522. static void fd_error( void )
  523. {
  524. if (IsFormatting) {
  525. IsFormatting = 0;
  526. FormatError = 1;
  527. wake_up( &format_wait );
  528. return;
  529. }
  530. if (QUEUE_EMPTY) return;
  531. CURRENT->errors++;
  532. if (CURRENT->errors >= MAX_ERRORS) {
  533. printk(KERN_ERR "fd%d: too many errors.n", SelectedDrive );
  534. end_request( 0 );
  535. }
  536. else if (CURRENT->errors == RECALIBRATE_ERRORS) {
  537. printk(KERN_WARNING "fd%d: recalibratingn", SelectedDrive );
  538. if (SelectedDrive != -1)
  539. SUD.track = -1;
  540. }
  541. redo_fd_request();
  542. }
  543. #define SET_IRQ_HANDLER(proc) do { FloppyIRQHandler = (proc); } while(0)
  544. /* ---------- Formatting ---------- */
  545. #define FILL(n,val)
  546.     do {
  547. memset( p, val, n );
  548. p += n;
  549.     } while(0)
  550. static int do_format(kdev_t device, struct atari_format_descr *desc)
  551. {
  552. unsigned char *p;
  553. int sect, nsect;
  554. unsigned long flags;
  555. int type, drive = MINOR(device) & 3;
  556. DPRINT(("do_format( dr=%d tr=%d he=%d offs=%d )n",
  557. drive, desc->track, desc->head, desc->sect_offset ));
  558. save_flags(flags);
  559. cli();
  560. while( fdc_busy ) sleep_on( &fdc_wait );
  561. fdc_busy = 1;
  562. stdma_lock(floppy_irq, NULL);
  563. atari_turnon_irq( IRQ_MFP_FDC ); /* should be already, just to be sure */
  564. restore_flags(flags);
  565. type = MINOR(device) >> 2;
  566. if (type) {
  567. if (--type >= NUM_DISK_MINORS ||
  568.     minor2disktype[type].drive_types > DriveType) {
  569. redo_fd_request();
  570. return -EINVAL;
  571. }
  572. type = minor2disktype[type].index;
  573. UDT = &disk_type[type];
  574. }
  575. if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) {
  576. redo_fd_request();
  577. return -EINVAL;
  578. }
  579. nsect = UDT->spt;
  580. p = TrackBuffer;
  581. /* The track buffer is used for the raw track data, so its
  582.    contents become invalid! */
  583. BufferDrive = -1;
  584. /* stop deselect timer */
  585. del_timer( &motor_off_timer );
  586. FILL( 60 * (nsect / 9), 0x4e );
  587. for( sect = 0; sect < nsect; ++sect ) {
  588. FILL( 12, 0 );
  589. FILL( 3, 0xf5 );
  590. *p++ = 0xfe;
  591. *p++ = desc->track;
  592. *p++ = desc->head;
  593. *p++ = (nsect + sect - desc->sect_offset) % nsect + 1;
  594. *p++ = 2;
  595. *p++ = 0xf7;
  596. FILL( 22, 0x4e );
  597. FILL( 12, 0 );
  598. FILL( 3, 0xf5 );
  599. *p++ = 0xfb;
  600. FILL( 512, 0xe5 );
  601. *p++ = 0xf7;
  602. FILL( 40, 0x4e );
  603. }
  604. FILL( TrackBuffer+BUFFER_SIZE-p, 0x4e );
  605. IsFormatting = 1;
  606. FormatError = 0;
  607. ReqTrack = desc->track;
  608. ReqSide  = desc->head;
  609. do_fd_action( drive );
  610. sleep_on( &format_wait );
  611. redo_fd_request();
  612. return( FormatError ? -EIO : 0 );
  613. }
  614. /* do_fd_action() is the general procedure for a fd request: All
  615.  * required parameter settings (drive select, side select, track
  616.  * position) are checked and set if needed. For each of these
  617.  * parameters and the actual reading or writing exist two functions:
  618.  * one that starts the setting (or skips it if possible) and one
  619.  * callback for the "done" interrupt. Each done func calls the next
  620.  * set function to propagate the request down to fd_rwsec_done().
  621.  */
  622. static void do_fd_action( int drive )
  623. {
  624. DPRINT(("do_fd_actionn"));
  625. if (UseTrackbuffer && !IsFormatting) {
  626. repeat:
  627.     if (IS_BUFFERED( drive, ReqSide, ReqTrack )) {
  628. if (ReqCmd == READ) {
  629.     copy_buffer( SECTOR_BUFFER(ReqSector), ReqData );
  630.     if (++ReqCnt < CURRENT->current_nr_sectors) {
  631. /* read next sector */
  632. setup_req_params( drive );
  633. goto repeat;
  634.     }
  635.     else {
  636. /* all sectors finished */
  637. CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
  638. CURRENT->sector += CURRENT->current_nr_sectors;
  639. end_request( 1 );
  640. redo_fd_request();
  641. return;
  642.     }
  643. }
  644. else {
  645.     /* cmd == WRITE, pay attention to track buffer
  646.      * consistency! */
  647.     copy_buffer( ReqData, SECTOR_BUFFER(ReqSector) );
  648. }
  649.     }
  650. }
  651. if (SelectedDrive != drive)
  652. fd_select_drive( drive );
  653.     
  654. if (UD.track == -1)
  655. fd_calibrate();
  656. else if (UD.track != ReqTrack << UDT->stretch)
  657. fd_seek();
  658. else if (IsFormatting)
  659. fd_writetrack();
  660. else
  661. fd_rwsec();
  662. }
  663. /* Seek to track 0 if the current track is unknown */
  664. static void fd_calibrate( void )
  665. {
  666. if (SUD.track >= 0) {
  667. fd_calibrate_done( 0 );
  668. return;
  669. }
  670. if (ATARIHW_PRESENT(FDCSPEED))
  671. dma_wd.fdc_speed = 0;  /* always seek with 8 Mhz */;
  672. DPRINT(("fd_calibraten"));
  673. SET_IRQ_HANDLER( fd_calibrate_done );
  674. /* we can't verify, since the speed may be incorrect */
  675. FDC_WRITE( FDCREG_CMD, FDCCMD_RESTORE | SUD.steprate );
  676. NeedSeek = 1;
  677. MotorOn = 1;
  678. start_timeout();
  679. /* wait for IRQ */
  680. }
  681. static void fd_calibrate_done( int status )
  682. {
  683. DPRINT(("fd_calibrate_done()n"));
  684. stop_timeout();
  685.     
  686. /* set the correct speed now */
  687. if (ATARIHW_PRESENT(FDCSPEED))
  688. dma_wd.fdc_speed = SUDT->fdc_speed;
  689. if (status & FDCSTAT_RECNF) {
  690. printk(KERN_ERR "fd%d: restore failedn", SelectedDrive );
  691. fd_error();
  692. }
  693. else {
  694. SUD.track = 0;
  695. fd_seek();
  696. }
  697. }
  698.   
  699.   
  700. /* Seek the drive to the requested track. The drive must have been
  701.  * calibrated at some point before this.
  702.  */
  703.   
  704. static void fd_seek( void )
  705. {
  706. if (SUD.track == ReqTrack << SUDT->stretch) {
  707. fd_seek_done( 0 );
  708. return;
  709. }
  710. if (ATARIHW_PRESENT(FDCSPEED)) {
  711. dma_wd.fdc_speed = 0; /* always seek witch 8 Mhz */
  712. MFPDELAY();
  713. }
  714. DPRINT(("fd_seek() to track %dn",ReqTrack));
  715. FDC_WRITE( FDCREG_DATA, ReqTrack << SUDT->stretch);
  716. udelay(25);
  717. SET_IRQ_HANDLER( fd_seek_done );
  718. FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK | SUD.steprate );
  719. MotorOn = 1;
  720. set_head_settle_flag();
  721. start_timeout();
  722. /* wait for IRQ */
  723. }
  724. static void fd_seek_done( int status )
  725. {
  726. DPRINT(("fd_seek_done()n"));
  727. stop_timeout();
  728. /* set the correct speed */
  729. if (ATARIHW_PRESENT(FDCSPEED))
  730. dma_wd.fdc_speed = SUDT->fdc_speed;
  731. if (status & FDCSTAT_RECNF) {
  732. printk(KERN_ERR "fd%d: seek error (to track %d)n",
  733. SelectedDrive, ReqTrack );
  734. /* we don't know exactly which track we are on now! */
  735. SUD.track = -1;
  736. fd_error();
  737. }
  738. else {
  739. SUD.track = ReqTrack << SUDT->stretch;
  740. NeedSeek = 0;
  741. if (IsFormatting)
  742. fd_writetrack();
  743. else
  744. fd_rwsec();
  745. }
  746. }
  747. /* This does the actual reading/writing after positioning the head
  748.  * over the correct track.
  749.  */
  750. static int MultReadInProgress = 0;
  751. static void fd_rwsec( void )
  752. {
  753. unsigned long paddr, flags;
  754. unsigned int  rwflag, old_motoron;
  755. unsigned int track;
  756. DPRINT(("fd_rwsec(), Sec=%d, Access=%cn",ReqSector, ReqCmd == WRITE ? 'w' : 'r' ));
  757. if (ReqCmd == WRITE) {
  758. if (ATARIHW_PRESENT(EXTD_DMA)) {
  759. paddr = virt_to_phys(ReqData);
  760. }
  761. else {
  762. copy_buffer( ReqData, DMABuffer );
  763. paddr = PhysDMABuffer;
  764. }
  765. dma_cache_maintenance( paddr, 512, 1 );
  766. rwflag = 0x100;
  767. }
  768. else {
  769. if (read_track)
  770. paddr = PhysTrackBuffer;
  771. else
  772. paddr = ATARIHW_PRESENT(EXTD_DMA) ? 
  773. virt_to_phys(ReqData) : PhysDMABuffer;
  774. rwflag = 0;
  775. }
  776. fd_select_side( ReqSide );
  777.   
  778. /* Start sector of this operation */
  779. FDC_WRITE( FDCREG_SECTOR, read_track ? 1 : ReqSector );
  780. MFPDELAY();
  781. /* Cheat for track if stretch != 0 */
  782. if (SUDT->stretch) {
  783. track = FDC_READ( FDCREG_TRACK);
  784. MFPDELAY();
  785. FDC_WRITE( FDCREG_TRACK, track >> SUDT->stretch);
  786. }
  787. udelay(25);
  788.   
  789. /* Setup DMA */
  790. save_flags(flags);  
  791. cli();
  792. dma_wd.dma_lo = (unsigned char)paddr;
  793. MFPDELAY();
  794. paddr >>= 8;
  795. dma_wd.dma_md = (unsigned char)paddr;
  796. MFPDELAY();
  797. paddr >>= 8;
  798. if (ATARIHW_PRESENT(EXTD_DMA))
  799. st_dma_ext_dmahi = (unsigned short)paddr;
  800. else
  801. dma_wd.dma_hi = (unsigned char)paddr;
  802. MFPDELAY();
  803. restore_flags(flags);
  804.   
  805. /* Clear FIFO and switch DMA to correct mode */  
  806. dma_wd.dma_mode_status = 0x90 | rwflag;  
  807. MFPDELAY();
  808. dma_wd.dma_mode_status = 0x90 | (rwflag ^ 0x100);  
  809. MFPDELAY();
  810. dma_wd.dma_mode_status = 0x90 | rwflag;
  811. MFPDELAY();
  812.   
  813. /* How many sectors for DMA */
  814. dma_wd.fdc_acces_seccount = read_track ? SUDT->spt : 1;
  815.   
  816. udelay(25);  
  817.   
  818. /* Start operation */
  819. dma_wd.dma_mode_status = FDCSELREG_STP | rwflag;
  820. udelay(25);
  821. SET_IRQ_HANDLER( fd_rwsec_done );
  822. dma_wd.fdc_acces_seccount =
  823.   (get_head_settle_flag() |
  824.    (rwflag ? FDCCMD_WRSEC : (FDCCMD_RDSEC | (read_track ? FDCCMDADD_M : 0))));
  825. old_motoron = MotorOn;
  826. MotorOn = 1;
  827. NeedSeek = 1;
  828. /* wait for interrupt */
  829. if (read_track) {
  830. /* If reading a whole track, wait about one disk rotation and
  831.  * then check if all sectors are read. The FDC will even
  832.  * search for the first non-existent sector and need 1 sec to
  833.  * recognise that it isn't present :-(
  834.  */
  835. MultReadInProgress = 1;
  836. mod_timer(&readtrack_timer,
  837.   /* 1 rot. + 5 rot.s if motor was off  */
  838.   jiffies + HZ/5 + (old_motoron ? 0 : HZ));
  839. }
  840. start_timeout();
  841. }
  842.     
  843. static void fd_readtrack_check( unsigned long dummy )
  844. {
  845. unsigned long flags, addr, addr2;
  846. save_flags(flags);  
  847. cli();
  848. if (!MultReadInProgress) {
  849. /* This prevents a race condition that could arise if the
  850.  * interrupt is triggered while the calling of this timer
  851.  * callback function takes place. The IRQ function then has
  852.  * already cleared 'MultReadInProgress'  when flow of control
  853.  * gets here.
  854.  */
  855. restore_flags(flags);
  856. return;
  857. }
  858. /* get the current DMA address */
  859. /* ++ f.a. read twice to avoid being fooled by switcher */
  860. addr = 0;
  861. do {
  862. addr2 = addr;
  863. addr = dma_wd.dma_lo & 0xff;
  864. MFPDELAY();
  865. addr |= (dma_wd.dma_md & 0xff) << 8;
  866. MFPDELAY();
  867. if (ATARIHW_PRESENT( EXTD_DMA ))
  868. addr |= (st_dma_ext_dmahi & 0xffff) << 16;
  869. else
  870. addr |= (dma_wd.dma_hi & 0xff) << 16;
  871. MFPDELAY();
  872. } while(addr != addr2);
  873.   
  874. if (addr >= PhysTrackBuffer + SUDT->spt*512) {
  875. /* already read enough data, force an FDC interrupt to stop
  876.  * the read operation
  877.  */
  878. SET_IRQ_HANDLER( NULL );
  879. MultReadInProgress = 0;
  880. restore_flags(flags);
  881. DPRINT(("fd_readtrack_check(): donen"));
  882. FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
  883. udelay(25);
  884. /* No error until now -- the FDC would have interrupted
  885.  * otherwise!
  886.  */
  887. fd_rwsec_done1(0);
  888. }
  889. else {
  890. /* not yet finished, wait another tenth rotation */
  891. restore_flags(flags);
  892. DPRINT(("fd_readtrack_check(): not yet finishedn"));
  893. mod_timer(&readtrack_timer, jiffies + HZ/5/10);
  894. }
  895. }
  896. static void fd_rwsec_done( int status )
  897. {
  898. DPRINT(("fd_rwsec_done()n"));
  899. if (read_track) {
  900. del_timer(&readtrack_timer);
  901. if (!MultReadInProgress)
  902. return;
  903. MultReadInProgress = 0;
  904. }
  905. fd_rwsec_done1(status);
  906. }
  907. static void fd_rwsec_done1(int status)
  908. {
  909. unsigned int track;
  910. stop_timeout();
  911. /* Correct the track if stretch != 0 */
  912. if (SUDT->stretch) {
  913. track = FDC_READ( FDCREG_TRACK);
  914. MFPDELAY();
  915. FDC_WRITE( FDCREG_TRACK, track << SUDT->stretch);
  916. }
  917. if (!UseTrackbuffer) {
  918. dma_wd.dma_mode_status = 0x90;
  919. MFPDELAY();
  920. if (!(dma_wd.dma_mode_status & 0x01)) {
  921. printk(KERN_ERR "fd%d: DMA errorn", SelectedDrive );
  922. goto err_end;
  923. }
  924. }
  925. MFPDELAY();
  926. if (ReqCmd == WRITE && (status & FDCSTAT_WPROT)) {
  927. printk(KERN_NOTICE "fd%d: is write protectedn", SelectedDrive );
  928. goto err_end;
  929. }
  930. if ((status & FDCSTAT_RECNF) &&
  931.     /* RECNF is no error after a multiple read when the FDC
  932.        searched for a non-existent sector! */
  933.     !(read_track && FDC_READ(FDCREG_SECTOR) > SUDT->spt)) {
  934. if (Probing) {
  935. if (SUDT > disk_type) {
  936.     if (SUDT[-1].blocks > ReqBlock) {
  937. /* try another disk type */
  938. SUDT--;
  939. floppy_sizes[SelectedDrive] = SUDT->blocks >> 1;
  940.     } else
  941. Probing = 0;
  942. }
  943. else {
  944. if (SUD.flags & FTD_MSG)
  945. printk(KERN_INFO "fd%d: Auto-detected floppy type %sn",
  946.        SelectedDrive, SUDT->name );
  947. Probing=0;
  948. }
  949. } else {
  950. /* record not found, but not probing. Maybe stretch wrong ? Restart probing */
  951. if (SUD.autoprobe) {
  952. SUDT = disk_type + StartDiskType[DriveType];
  953. floppy_sizes[SelectedDrive] = SUDT->blocks >> 1;
  954. Probing = 1;
  955. }
  956. }
  957. if (Probing) {
  958. if (ATARIHW_PRESENT(FDCSPEED)) {
  959. dma_wd.fdc_speed = SUDT->fdc_speed;
  960. MFPDELAY();
  961. }
  962. setup_req_params( SelectedDrive );
  963. BufferDrive = -1;
  964. do_fd_action( SelectedDrive );
  965. return;
  966. }
  967. printk(KERN_ERR "fd%d: sector %d not found (side %d, track %d)n",
  968.        SelectedDrive, FDC_READ (FDCREG_SECTOR), ReqSide, ReqTrack );
  969. goto err_end;
  970. }
  971. if (status & FDCSTAT_CRC) {
  972. printk(KERN_ERR "fd%d: CRC error (side %d, track %d, sector %d)n",
  973.        SelectedDrive, ReqSide, ReqTrack, FDC_READ (FDCREG_SECTOR) );
  974. goto err_end;
  975. }
  976. if (status & FDCSTAT_LOST) {
  977. printk(KERN_ERR "fd%d: lost data (side %d, track %d, sector %d)n",
  978.        SelectedDrive, ReqSide, ReqTrack, FDC_READ (FDCREG_SECTOR) );
  979. goto err_end;
  980. }
  981. Probing = 0;
  982. if (ReqCmd == READ) {
  983. if (!read_track) {
  984. void *addr;
  985. addr = ATARIHW_PRESENT( EXTD_DMA ) ? ReqData : DMABuffer;
  986. dma_cache_maintenance( virt_to_phys(addr), 512, 0 );
  987. if (!ATARIHW_PRESENT( EXTD_DMA ))
  988. copy_buffer (addr, ReqData);
  989. } else {
  990. dma_cache_maintenance( PhysTrackBuffer, MaxSectors[DriveType] * 512, 0 );
  991. BufferDrive = SelectedDrive;
  992. BufferSide  = ReqSide;
  993. BufferTrack = ReqTrack;
  994. copy_buffer (SECTOR_BUFFER (ReqSector), ReqData);
  995. }
  996. }
  997.   
  998. if (++ReqCnt < CURRENT->current_nr_sectors) {
  999. /* read next sector */
  1000. setup_req_params( SelectedDrive );
  1001. do_fd_action( SelectedDrive );
  1002. }
  1003. else {
  1004. /* all sectors finished */
  1005. CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
  1006. CURRENT->sector += CURRENT->current_nr_sectors;
  1007. end_request( 1 );
  1008. redo_fd_request();
  1009. }
  1010. return;
  1011.   
  1012.   err_end:
  1013. BufferDrive = -1;
  1014. fd_error();
  1015. }
  1016. static void fd_writetrack( void )
  1017. {
  1018. unsigned long paddr, flags;
  1019. unsigned int track;
  1020. DPRINT(("fd_writetrack() Tr=%d Si=%dn", ReqTrack, ReqSide ));
  1021. paddr = PhysTrackBuffer;
  1022. dma_cache_maintenance( paddr, BUFFER_SIZE, 1 );
  1023. fd_select_side( ReqSide );
  1024.   
  1025. /* Cheat for track if stretch != 0 */
  1026. if (SUDT->stretch) {
  1027. track = FDC_READ( FDCREG_TRACK);
  1028. MFPDELAY();
  1029. FDC_WRITE(FDCREG_TRACK,track >> SUDT->stretch);
  1030. }
  1031. udelay(40);
  1032.   
  1033. /* Setup DMA */
  1034. save_flags(flags);  
  1035. cli();
  1036. dma_wd.dma_lo = (unsigned char)paddr;
  1037. MFPDELAY();
  1038. paddr >>= 8;
  1039. dma_wd.dma_md = (unsigned char)paddr;
  1040. MFPDELAY();
  1041. paddr >>= 8;
  1042. if (ATARIHW_PRESENT( EXTD_DMA ))
  1043. st_dma_ext_dmahi = (unsigned short)paddr;
  1044. else
  1045. dma_wd.dma_hi = (unsigned char)paddr;
  1046. MFPDELAY();
  1047. restore_flags(flags);
  1048.   
  1049. /* Clear FIFO and switch DMA to correct mode */  
  1050. dma_wd.dma_mode_status = 0x190;  
  1051. MFPDELAY();
  1052. dma_wd.dma_mode_status = 0x90;  
  1053. MFPDELAY();
  1054. dma_wd.dma_mode_status = 0x190;
  1055. MFPDELAY();
  1056.   
  1057. /* How many sectors for DMA */
  1058. dma_wd.fdc_acces_seccount = BUFFER_SIZE/512;
  1059. udelay(40);  
  1060.   
  1061. /* Start operation */
  1062. dma_wd.dma_mode_status = FDCSELREG_STP | 0x100;
  1063. udelay(40);
  1064. SET_IRQ_HANDLER( fd_writetrack_done );
  1065. dma_wd.fdc_acces_seccount = FDCCMD_WRTRA | get_head_settle_flag(); 
  1066. MotorOn = 1;
  1067. start_timeout();
  1068. /* wait for interrupt */
  1069. }
  1070. static void fd_writetrack_done( int status )
  1071. {
  1072. DPRINT(("fd_writetrack_done()n"));
  1073. stop_timeout();
  1074. if (status & FDCSTAT_WPROT) {
  1075. printk(KERN_NOTICE "fd%d: is write protectedn", SelectedDrive );
  1076. goto err_end;
  1077. }
  1078. if (status & FDCSTAT_LOST) {
  1079. printk(KERN_ERR "fd%d: lost data (side %d, track %d)n",
  1080. SelectedDrive, ReqSide, ReqTrack );
  1081. goto err_end;
  1082. }
  1083. wake_up( &format_wait );
  1084. return;
  1085.   err_end:
  1086. fd_error();
  1087. }
  1088. static void fd_times_out( unsigned long dummy )
  1089. {
  1090. atari_disable_irq( IRQ_MFP_FDC );
  1091. if (!FloppyIRQHandler) goto end; /* int occurred after timer was fired, but
  1092.   * before we came here... */
  1093. SET_IRQ_HANDLER( NULL );
  1094. /* If the timeout occurred while the readtrack_check timer was
  1095.  * active, we need to cancel it, else bad things will happen */
  1096. if (UseTrackbuffer)
  1097. del_timer( &readtrack_timer );
  1098. FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
  1099. udelay( 25 );
  1100. printk(KERN_ERR "floppy timeoutn" );
  1101. fd_error();
  1102.   end:
  1103. atari_enable_irq( IRQ_MFP_FDC );
  1104. }
  1105. /* The (noop) seek operation here is needed to make the WP bit in the
  1106.  * FDC status register accessible for check_change. If the last disk
  1107.  * operation would have been a RDSEC, this bit would always read as 0
  1108.  * no matter what :-( To save time, the seek goes to the track we're
  1109.  * already on.
  1110.  */
  1111. static void finish_fdc( void )
  1112. {
  1113. if (!NeedSeek) {
  1114. finish_fdc_done( 0 );
  1115. }
  1116. else {
  1117. DPRINT(("finish_fdc: dummy seek startedn"));
  1118. FDC_WRITE (FDCREG_DATA, SUD.track);
  1119. SET_IRQ_HANDLER( finish_fdc_done );
  1120. FDC_WRITE (FDCREG_CMD, FDCCMD_SEEK);
  1121. MotorOn = 1;
  1122. start_timeout();
  1123. /* we must wait for the IRQ here, because the ST-DMA
  1124.    is released immediately afterwards and the interrupt
  1125.    may be delivered to the wrong driver. */
  1126.   }
  1127. }
  1128. static void finish_fdc_done( int dummy )
  1129. {
  1130. unsigned long flags;
  1131. DPRINT(("finish_fdc_done enteredn"));
  1132. stop_timeout();
  1133. NeedSeek = 0;
  1134. if (timer_pending(&fd_timer) && time_before(fd_timer.expires, jiffies + 5))
  1135. /* If the check for a disk change is done too early after this
  1136.  * last seek command, the WP bit still reads wrong :-((
  1137.  */
  1138. mod_timer(&fd_timer, jiffies + 5);
  1139. else
  1140. start_check_change_timer();
  1141. start_motor_off_timer();
  1142. save_flags(flags);
  1143. cli();
  1144. stdma_release();
  1145. fdc_busy = 0;
  1146. wake_up( &fdc_wait );
  1147. restore_flags(flags);
  1148. DPRINT(("finish_fdc() finishedn"));
  1149. }
  1150. /* Prevent "aliased" accesses. */
  1151. static int fd_ref[4] = { 0,0,0,0 };
  1152. static int fd_device[4] = { 0,0,0,0 };
  1153. /*
  1154.  * Current device number. Taken either from the block header or from the
  1155.  * format request descriptor.
  1156.  */
  1157. #define CURRENT_DEVICE (CURRENT->rq_dev)
  1158. /* Current error count. */
  1159. #define CURRENT_ERRORS (CURRENT->errors)
  1160. /* dummy for blk.h */
  1161. static void floppy_off( unsigned int nr) {}
  1162. /* The detection of disk changes is a dark chapter in Atari history :-(
  1163.  * Because the "Drive ready" signal isn't present in the Atari
  1164.  * hardware, one has to rely on the "Write Protect". This works fine,
  1165.  * as long as no write protected disks are used. TOS solves this
  1166.  * problem by introducing tri-state logic ("maybe changed") and
  1167.  * looking at the serial number in block 0. This isn't possible for
  1168.  * Linux, since the floppy driver can't make assumptions about the
  1169.  * filesystem used on the disk and thus the contents of block 0. I've
  1170.  * chosen the method to always say "The disk was changed" if it is
  1171.  * unsure whether it was. This implies that every open or mount
  1172.  * invalidates the disk buffers if you work with write protected
  1173.  * disks. But at least this is better than working with incorrect data
  1174.  * due to unrecognised disk changes.
  1175.  */
  1176. static int check_floppy_change (kdev_t dev)
  1177. {
  1178. unsigned int drive = MINOR(dev) & 0x03;
  1179. if (MAJOR(dev) != MAJOR_NR) {
  1180. printk(KERN_ERR "floppy_changed: not a floppyn");
  1181. return 0;
  1182. }
  1183. if (test_bit (drive, &fake_change)) {
  1184. /* simulated change (e.g. after formatting) */
  1185. return 1;
  1186. }
  1187. if (test_bit (drive, &changed_floppies)) {
  1188. /* surely changed (the WP signal changed at least once) */
  1189. return 1;
  1190. }
  1191. if (UD.wpstat) {
  1192. /* WP is on -> could be changed: to be sure, buffers should be
  1193.  * invalidated...
  1194.  */
  1195. return 1;
  1196. }
  1197. return 0;
  1198. }
  1199. static int floppy_revalidate (kdev_t dev)
  1200. {
  1201. int drive = MINOR(dev) & 3;
  1202. if (test_bit(drive, &changed_floppies) ||
  1203.     test_bit(drive, &fake_change) ||
  1204.     unit[drive].disktype == 0) {
  1205. if (UD.flags & FTD_MSG)
  1206. printk(KERN_ERR "floppy: clear format %p!n", UDT);
  1207. BufferDrive = -1;
  1208. clear_bit(drive, &fake_change);
  1209. clear_bit(drive, &changed_floppies);
  1210. /* MSch: clearing geometry makes sense only for autoprobe
  1211.    formats, for 'permanent user-defined' parameter:
  1212.    restore default_params[] here if flagged valid! */
  1213. if (default_params[drive].blocks == 0)
  1214. UDT = 0;
  1215. else
  1216. UDT = &default_params[drive];
  1217. }
  1218. return 0;
  1219. }
  1220. static __inline__ void copy_buffer(void *from, void *to)
  1221. {
  1222. ulong *p1 = (ulong *)from, *p2 = (ulong *)to;
  1223. int cnt;
  1224. for( cnt = 512/4; cnt; cnt-- )
  1225. *p2++ = *p1++;
  1226. }
  1227. /* This sets up the global variables describing the current request. */
  1228. static void setup_req_params( int drive )
  1229. {
  1230. int block = ReqBlock + ReqCnt;
  1231. ReqTrack = block / UDT->spt;
  1232. ReqSector = block - ReqTrack * UDT->spt + 1;
  1233. ReqSide = ReqTrack & 1;
  1234. ReqTrack >>= 1;
  1235. ReqData = ReqBuffer + 512 * ReqCnt;
  1236. if (UseTrackbuffer)
  1237. read_track = (ReqCmd == READ && CURRENT_ERRORS == 0);
  1238. else
  1239. read_track = 0;
  1240. DPRINT(("Request params: Si=%d Tr=%d Se=%d Data=%08lxn",ReqSide,
  1241. ReqTrack, ReqSector, (unsigned long)ReqData ));
  1242. }
  1243. static void redo_fd_request(void)
  1244. {
  1245. int device, drive, type;
  1246.   
  1247. DPRINT(("redo_fd_request: CURRENT=%08lx CURRENT->dev=%04x CURRENT->sector=%ldn",
  1248. (unsigned long)CURRENT, !QUEUE_EMPTY ? CURRENT->rq_dev : 0,
  1249. !QUEUE_EMPTY ? CURRENT->sector : 0 ));
  1250. IsFormatting = 0;
  1251. if (!QUEUE_EMPTY && CURRENT->rq_status == RQ_INACTIVE){
  1252. return;
  1253. }
  1254. repeat:
  1255.     
  1256. if (QUEUE_EMPTY)
  1257. goto the_end;
  1258. if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
  1259. panic(DEVICE_NAME ": request list destroyed");
  1260. if (CURRENT->bh && !buffer_locked(CURRENT->bh))
  1261. panic(DEVICE_NAME ": block not locked");
  1262. device = MINOR(CURRENT_DEVICE);
  1263. drive = device & 3;
  1264. type = device >> 2;
  1265. if (!UD.connected) {
  1266. /* drive not connected */
  1267. printk(KERN_ERR "Unknown Device: fd%dn", drive );
  1268. end_request(0);
  1269. goto repeat;
  1270. }
  1271. if (type == 0) {
  1272. if (!UDT) {
  1273. Probing = 1;
  1274. UDT = disk_type + StartDiskType[DriveType];
  1275. floppy_sizes[drive] = UDT->blocks >> 1;
  1276. UD.autoprobe = 1;
  1277. }
  1278. else {
  1279. /* user supplied disk type */
  1280. if (--type >= NUM_DISK_MINORS) {
  1281. printk(KERN_WARNING "fd%d: invalid disk format", drive );
  1282. end_request( 0 );
  1283. goto repeat;
  1284. }
  1285. if (minor2disktype[type].drive_types > DriveType)  {
  1286. printk(KERN_WARNING "fd%d: unsupported disk format", drive );
  1287. end_request( 0 );
  1288. goto repeat;
  1289. }
  1290. type = minor2disktype[type].index;
  1291. UDT = &disk_type[type];
  1292. floppy_sizes[drive] = UDT->blocks >> 1;
  1293. UD.autoprobe = 0;
  1294. }
  1295. if (CURRENT->sector + 1 > UDT->blocks) {
  1296. end_request(0);
  1297. goto repeat;
  1298. }
  1299. /* stop deselect timer */
  1300. del_timer( &motor_off_timer );
  1301. ReqCnt = 0;
  1302. ReqCmd = CURRENT->cmd;
  1303. ReqBlock = CURRENT->sector;
  1304. ReqBuffer = CURRENT->buffer;
  1305. setup_req_params( drive );
  1306. do_fd_action( drive );
  1307. return;
  1308.   the_end:
  1309. finish_fdc();
  1310. }
  1311. void do_fd_request(request_queue_t * q)
  1312. {
  1313.   unsigned long flags;
  1314. DPRINT(("do_fd_request for pid %dn",current->pid));
  1315. while( fdc_busy ) sleep_on( &fdc_wait );
  1316. fdc_busy = 1;
  1317. stdma_lock(floppy_irq, NULL);
  1318. atari_disable_irq( IRQ_MFP_FDC );
  1319. save_flags(flags); /* The request function is called with ints
  1320. sti();  * disabled... so must save the IPL for later */ 
  1321. redo_fd_request();
  1322. restore_flags(flags);
  1323. atari_enable_irq( IRQ_MFP_FDC );
  1324. }
  1325. static int invalidate_drive(kdev_t rdev)
  1326. {
  1327. /* invalidate the buffer track to force a reread */
  1328. BufferDrive = -1;
  1329. set_bit(MINOR(rdev) & 3, &fake_change);
  1330. check_disk_change(rdev);
  1331. return 0;
  1332. }
  1333. static int fd_ioctl(struct inode *inode, struct file *filp,
  1334.     unsigned int cmd, unsigned long param)
  1335. {
  1336. int drive, type;
  1337. kdev_t device;
  1338. struct atari_format_descr fmt_desc;
  1339. struct atari_disk_type *dtp;
  1340. struct floppy_struct getprm;
  1341. int settype;
  1342. struct floppy_struct setprm;
  1343. device = inode->i_rdev;
  1344. switch (cmd) {
  1345. case BLKROSET:
  1346. case BLKROGET:
  1347. case BLKRASET:
  1348. case BLKRAGET:
  1349. case BLKFLSBUF:
  1350. return blk_ioctl(device, cmd, param);
  1351. }
  1352. drive = MINOR (device);
  1353. type  = drive >> 2;
  1354. drive &= 3;
  1355. switch (cmd) {
  1356. case FDGETPRM:
  1357. case BLKGETSIZE:
  1358. if (type) {
  1359. if (--type >= NUM_DISK_MINORS)
  1360. return -ENODEV;
  1361. if (minor2disktype[type].drive_types > DriveType)
  1362. return -ENODEV;
  1363. type = minor2disktype[type].index;
  1364. dtp = &disk_type[type];
  1365. if (UD.flags & FTD_MSG)
  1366.     printk (KERN_ERR "floppy%d: found dtp %p name %s!n",
  1367.         drive, dtp, dtp->name);
  1368. }
  1369. else {
  1370. if (!UDT)
  1371. return -ENXIO;
  1372. else
  1373. dtp = UDT;
  1374. }
  1375. if (cmd == BLKGETSIZE)
  1376. return put_user(dtp->blocks, (unsigned long *)param);
  1377. memset((void *)&getprm, 0, sizeof(getprm));
  1378. getprm.size = dtp->blocks;
  1379. getprm.sect = dtp->spt;
  1380. getprm.head = 2;
  1381. getprm.track = dtp->blocks/dtp->spt/2;
  1382. getprm.stretch = dtp->stretch;
  1383. if (copy_to_user((void *)param, &getprm, sizeof(getprm)))
  1384. return -EFAULT;
  1385. return 0;
  1386. }
  1387. switch (cmd) {
  1388. case FDSETPRM:
  1389. case FDDEFPRM:
  1390.         /* 
  1391.  * MSch 7/96: simple 'set geometry' case: just set the
  1392.  * 'default' device params (minor == 0).
  1393.  * Currently, the drive geometry is cleared after each
  1394.  * disk change and subsequent revalidate()! simple
  1395.  * implementation of FDDEFPRM: save geometry from a
  1396.  * FDDEFPRM call and restore it in floppy_revalidate() !
  1397.  */
  1398. /* get the parameters from user space */
  1399. if (fd_ref[drive] != 1 && fd_ref[drive] != -1)
  1400. return -EBUSY;
  1401. if (copy_from_user(&setprm, (void *) param, sizeof(setprm)))
  1402. return -EFAULT;
  1403. /* 
  1404.  * first of all: check for floppy change and revalidate, 
  1405.  * or the next access will revalidate - and clear UDT :-(
  1406.  */
  1407. if (check_floppy_change(device))
  1408.         floppy_revalidate(device);
  1409. if (UD.flags & FTD_MSG)
  1410.     printk (KERN_INFO "floppy%d: setting size %d spt %d str %d!n",
  1411. drive, setprm.size, setprm.sect, setprm.stretch);
  1412. /* what if type > 0 here? Overwrite specified entry ? */
  1413. if (type) {
  1414.         /* refuse to re-set a predefined type for now */
  1415. redo_fd_request();
  1416. return -EINVAL;
  1417. }
  1418. /* 
  1419.  * type == 0: first look for a matching entry in the type list,
  1420.  * and set the UD.disktype field to use the perdefined entry.
  1421.  * TODO: add user-defined format to head of autoprobe list ? 
  1422.  * Useful to include the user-type for future autodetection!
  1423.  */
  1424. for (settype = 0; settype < NUM_DISK_MINORS; settype++) {
  1425. int setidx = 0;
  1426. if (minor2disktype[settype].drive_types > DriveType) {
  1427. /* skip this one, invalid for drive ... */
  1428. continue;
  1429. }
  1430. setidx = minor2disktype[settype].index;
  1431. dtp = &disk_type[setidx];
  1432. /* found matching entry ?? */
  1433. if (   dtp->blocks  == setprm.size 
  1434.     && dtp->spt     == setprm.sect
  1435.     && dtp->stretch == setprm.stretch ) {
  1436. if (UD.flags & FTD_MSG)
  1437.     printk (KERN_INFO "floppy%d: setting %s %p!n",
  1438.         drive, dtp->name, dtp);
  1439. UDT = dtp;
  1440. floppy_sizes[drive] = UDT->blocks >> 1;
  1441. if (cmd == FDDEFPRM) {
  1442.   /* save settings as permanent default type */
  1443.   default_params[drive].name    = dtp->name;
  1444.   default_params[drive].spt     = dtp->spt;
  1445.   default_params[drive].blocks  = dtp->blocks;
  1446.   default_params[drive].fdc_speed = dtp->fdc_speed;
  1447.   default_params[drive].stretch = dtp->stretch;
  1448. }
  1449. return 0;
  1450. }
  1451. }
  1452. /* no matching disk type found above - setting user_params */
  1453.         if (cmd == FDDEFPRM) {
  1454. /* set permanent type */
  1455. dtp = &default_params[drive];
  1456. } else
  1457. /* set user type (reset by disk change!) */
  1458. dtp = &user_params[drive];
  1459. dtp->name   = "user format";
  1460. dtp->blocks = setprm.size;
  1461. dtp->spt    = setprm.sect;
  1462. if (setprm.sect > 14) 
  1463. dtp->fdc_speed = 3;
  1464. else
  1465. dtp->fdc_speed = 0;
  1466. dtp->stretch = setprm.stretch;
  1467. if (UD.flags & FTD_MSG)
  1468. printk (KERN_INFO "floppy%d: blk %d spt %d str %d!n",
  1469. drive, dtp->blocks, dtp->spt, dtp->stretch);
  1470. /* sanity check */
  1471. if (!dtp || setprm.track != dtp->blocks/dtp->spt/2 ||
  1472.     setprm.head != 2) {
  1473. redo_fd_request();
  1474. return -EINVAL;
  1475. }
  1476. UDT = dtp;
  1477. floppy_sizes[drive] = UDT->blocks >> 1;
  1478. return 0;
  1479. case FDMSGON:
  1480. UD.flags |= FTD_MSG;
  1481. return 0;
  1482. case FDMSGOFF:
  1483. UD.flags &= ~FTD_MSG;
  1484. return 0;
  1485. case FDSETEMSGTRESH:
  1486. return -EINVAL;
  1487. case FDFMTBEG:
  1488. return 0;
  1489. case FDFMTTRK:
  1490. if (fd_ref[drive] != 1 && fd_ref[drive] != -1)
  1491. return -EBUSY;
  1492. if (copy_from_user(&fmt_desc, (void *) param, sizeof(fmt_desc)))
  1493. return -EFAULT;
  1494. return do_format(device, &fmt_desc);
  1495. case FDCLRPRM:
  1496. UDT = NULL;
  1497. /* MSch: invalidate default_params */
  1498. default_params[drive].blocks  = 0;
  1499. floppy_sizes[drive] = MAX_DISK_SIZE;
  1500. return invalidate_drive (device);
  1501. case FDFMTEND:
  1502. case FDFLUSH:
  1503. return invalidate_drive(device);
  1504. }
  1505. return -EINVAL;
  1506. }
  1507. /* Initialize the 'unit' variable for drive 'drive' */
  1508. static void __init fd_probe( int drive )
  1509. {
  1510. UD.connected = 0;
  1511. UDT  = NULL;
  1512. if (!fd_test_drive_present( drive ))
  1513. return;
  1514. UD.connected = 1;
  1515. UD.track     = 0;
  1516. switch( UserSteprate[drive] ) {
  1517. case 2:
  1518. UD.steprate = FDCSTEP_2;
  1519. break;
  1520. case 3:
  1521. UD.steprate = FDCSTEP_3;
  1522. break;
  1523. case 6:
  1524. UD.steprate = FDCSTEP_6;
  1525. break;
  1526. case 12:
  1527. UD.steprate = FDCSTEP_12;
  1528. break;
  1529. default: /* should be -1 for "not set by user" */
  1530. if (ATARIHW_PRESENT( FDCSPEED ) || MACH_IS_MEDUSA)
  1531. UD.steprate = FDCSTEP_3;
  1532. else
  1533. UD.steprate = FDCSTEP_6;
  1534. break;
  1535. }
  1536. MotorOn = 1; /* from probe restore operation! */
  1537. }
  1538. /* This function tests the physical presence of a floppy drive (not
  1539.  * whether a disk is inserted). This is done by issuing a restore
  1540.  * command, waiting max. 2 seconds (that should be enough to move the
  1541.  * head across the whole disk) and looking at the state of the "TR00"
  1542.  * signal. This should now be raised if there is a drive connected
  1543.  * (and there is no hardware failure :-) Otherwise, the drive is
  1544.  * declared absent.
  1545.  */
  1546. static int __init fd_test_drive_present( int drive )
  1547. {
  1548. unsigned long timeout;
  1549. unsigned char status;
  1550. int ok;
  1551. if (drive >= (MACH_IS_FALCON ? 1 : 2)) return( 0 );
  1552. fd_select_drive( drive );
  1553. /* disable interrupt temporarily */
  1554. atari_turnoff_irq( IRQ_MFP_FDC );
  1555. FDC_WRITE (FDCREG_TRACK, 0xff00);
  1556. FDC_WRITE( FDCREG_CMD, FDCCMD_RESTORE | FDCCMDADD_H | FDCSTEP_6 );
  1557. timeout = jiffies + 2*HZ+HZ/2;
  1558. while (time_before(jiffies, timeout))
  1559. if (!(mfp.par_dt_reg & 0x20))
  1560. break;
  1561. status = FDC_READ( FDCREG_STATUS );
  1562. ok = (status & FDCSTAT_TR00) != 0;
  1563. /* force interrupt to abort restore operation (FDC would try
  1564.  * about 50 seconds!) */
  1565. FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
  1566. udelay(500);
  1567. status = FDC_READ( FDCREG_STATUS );
  1568. udelay(20);
  1569. if (ok) {
  1570. /* dummy seek command to make WP bit accessible */
  1571. FDC_WRITE( FDCREG_DATA, 0 );
  1572. FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK );
  1573. while( mfp.par_dt_reg & 0x20 )
  1574. ;
  1575. status = FDC_READ( FDCREG_STATUS );
  1576. }
  1577. atari_turnon_irq( IRQ_MFP_FDC );
  1578. return( ok );
  1579. }
  1580. /* Look how many and which kind of drives are connected. If there are
  1581.  * floppies, additionally start the disk-change and motor-off timers.
  1582.  */
  1583. static void __init config_types( void )
  1584. {
  1585. int drive, cnt = 0;
  1586. /* for probing drives, set the FDC speed to 8 MHz */
  1587. if (ATARIHW_PRESENT(FDCSPEED))
  1588. dma_wd.fdc_speed = 0;
  1589. printk(KERN_INFO "Probing floppy drive(s):n");
  1590. for( drive = 0; drive < FD_MAX_UNITS; drive++ ) {
  1591. fd_probe( drive );
  1592. if (UD.connected) {
  1593. printk(KERN_INFO "fd%dn", drive);
  1594. ++cnt;
  1595. }
  1596. }
  1597. if (FDC_READ( FDCREG_STATUS ) & FDCSTAT_BUSY) {
  1598. /* If FDC is still busy from probing, give it another FORCI
  1599.  * command to abort the operation. If this isn't done, the FDC
  1600.  * will interrupt later and its IRQ line stays low, because
  1601.  * the status register isn't read. And this will block any
  1602.  * interrupts on this IRQ line :-(
  1603.  */
  1604. FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );
  1605. udelay(500);
  1606. FDC_READ( FDCREG_STATUS );
  1607. udelay(20);
  1608. }
  1609. if (cnt > 0) {
  1610. start_motor_off_timer();
  1611. if (cnt == 1) fd_select_drive( 0 );
  1612. start_check_change_timer();
  1613. }
  1614. }
  1615. /*
  1616.  * floppy_open check for aliasing (/dev/fd0 can be the same as
  1617.  * /dev/PS0 etc), and disallows simultaneous access to the same
  1618.  * drive with different device numbers.
  1619.  */
  1620. static int floppy_open( struct inode *inode, struct file *filp )
  1621. {
  1622. int drive, type;
  1623. int old_dev;
  1624. if (!filp) {
  1625. DPRINT (("Weird, open called with filp=0n"));
  1626. return -EIO;
  1627. }
  1628. drive = MINOR(inode->i_rdev) & 3;
  1629. type  = MINOR(inode->i_rdev) >> 2;
  1630. DPRINT(("fd_open: type=%dn",type));
  1631. if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS)
  1632. return -ENXIO;
  1633. old_dev = fd_device[drive];
  1634. if (fd_ref[drive] && old_dev != MINOR(inode->i_rdev))
  1635. return -EBUSY;
  1636. if (fd_ref[drive] == -1 || (fd_ref[drive] && filp->f_flags & O_EXCL))
  1637. return -EBUSY;
  1638. if (filp->f_flags & O_EXCL)
  1639. fd_ref[drive] = -1;
  1640. else
  1641. fd_ref[drive]++;
  1642. fd_device[drive] = MINOR(inode->i_rdev);
  1643. if (old_dev && old_dev != MINOR(inode->i_rdev))
  1644. invalidate_buffers(MKDEV(FLOPPY_MAJOR, old_dev));
  1645. if (filp->f_flags & O_NDELAY)
  1646. return 0;
  1647. if (filp->f_mode & 3) {
  1648. check_disk_change(inode->i_rdev);
  1649. if (filp->f_mode & 2) {
  1650. if (UD.wpstat) {
  1651. floppy_release(inode, filp);
  1652. return -EROFS;
  1653. }
  1654. }
  1655. }
  1656. return 0;
  1657. }
  1658. static int floppy_release( struct inode * inode, struct file * filp )
  1659. {
  1660. int drive = MINOR(inode->i_rdev) & 3;
  1661. if (fd_ref[drive] < 0)
  1662. fd_ref[drive] = 0;
  1663. else if (!fd_ref[drive]--) {
  1664. printk(KERN_ERR "floppy_release with fd_ref == 0");
  1665. fd_ref[drive] = 0;
  1666. }
  1667. return 0;
  1668. }
  1669. static struct block_device_operations floppy_fops = {
  1670. owner: THIS_MODULE,
  1671. open: floppy_open,
  1672. release: floppy_release,
  1673. ioctl: fd_ioctl,
  1674. check_media_change: check_floppy_change,
  1675. revalidate: floppy_revalidate,
  1676. };
  1677. int __init atari_floppy_init (void)
  1678. {
  1679. int i;
  1680. if (!MACH_IS_ATARI)
  1681. /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */
  1682. return -ENXIO;
  1683. if (MACH_IS_HADES)
  1684. /* Hades doesn't have Atari-compatible floppy */
  1685. return -ENXIO;
  1686. if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
  1687. printk(KERN_ERR "Unable to get major %d for floppyn",MAJOR_NR);
  1688. return -EBUSY;
  1689. }
  1690. if (UseTrackbuffer < 0)
  1691. /* not set by user -> use default: for now, we turn
  1692.    track buffering off for all Medusas, though it
  1693.    could be used with ones that have a counter
  1694.    card. But the test is too hard :-( */
  1695. UseTrackbuffer = !MACH_IS_MEDUSA;
  1696. /* initialize variables */
  1697. SelectedDrive = -1;
  1698. BufferDrive = -1;
  1699. DMABuffer = atari_stram_alloc(BUFFER_SIZE+512, "ataflop");
  1700. if (!DMABuffer) {
  1701. printk(KERN_ERR "atari_floppy_init: cannot get dma buffern");
  1702. unregister_blkdev(MAJOR_NR, "fd");
  1703. return -ENOMEM;
  1704. }
  1705. TrackBuffer = DMABuffer + 512;
  1706. PhysDMABuffer = virt_to_phys(DMABuffer);
  1707. PhysTrackBuffer = virt_to_phys(TrackBuffer);
  1708. BufferDrive = BufferSide = BufferTrack = -1;
  1709. for (i = 0; i < FD_MAX_UNITS; i++) {
  1710. unit[i].track = -1;
  1711. unit[i].flags = 0;
  1712. }
  1713. for (i = 0; i < 256; i++)
  1714. if ((i >> 2) > 0 && (i >> 2) <= NUM_DISK_MINORS) {
  1715. int type = minor2disktype[(i >> 2) - 1].index;
  1716. floppy_sizes[i] = disk_type[type].blocks >> 1;
  1717. } else
  1718. floppy_sizes[i] = MAX_DISK_SIZE;
  1719. blk_size[MAJOR_NR] = floppy_sizes;
  1720. blksize_size[MAJOR_NR] = floppy_blocksizes;
  1721. blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
  1722. printk(KERN_INFO "Atari floppy driver: max. %cD, %strack bufferingn",
  1723.        DriveType == 0 ? 'D' : DriveType == 1 ? 'H' : 'E',
  1724.        UseTrackbuffer ? "" : "no ");
  1725. config_types();
  1726. (void)do_floppy; /* avoid warning about unused variable */
  1727. return 0;
  1728. }
  1729. void __init atari_floppy_setup( char *str, int *ints )
  1730. {
  1731. int i;
  1732. if (ints[0] < 1) {
  1733. printk(KERN_ERR "ataflop_setup: no arguments!n" );
  1734. return;
  1735. }
  1736. else if (ints[0] > 2+FD_MAX_UNITS) {
  1737. printk(KERN_ERR "ataflop_setup: too many argumentsn" );
  1738. }
  1739. if (ints[1] < 0 || ints[1] > 2)
  1740. printk(KERN_ERR "ataflop_setup: bad drive typen" );
  1741. else
  1742. DriveType = ints[1];
  1743. if (ints[0] >= 2)
  1744. UseTrackbuffer = (ints[2] > 0);
  1745. for( i = 3; i <= ints[0] && i-3 < FD_MAX_UNITS; ++i ) {
  1746. if (ints[i] != 2 && ints[i] != 3 && ints[i] != 6 && ints[i] != 12)
  1747. printk(KERN_ERR "ataflop_setup: bad stepraten" );
  1748. else
  1749. UserSteprate[i-3] = ints[i];
  1750. }
  1751. }
  1752. #ifdef MODULE
  1753. MODULE_LICENSE("GPL");
  1754. int init_module (void)
  1755. {
  1756. if (!MACH_IS_ATARI)
  1757. return -ENXIO;
  1758. return atari_floppy_init ();
  1759. }
  1760. void cleanup_module (void)
  1761. {
  1762. unregister_blkdev(MAJOR_NR, "fd");
  1763. blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
  1764. del_timer_sync(&fd_timer);
  1765. atari_stram_free( DMABuffer );
  1766. }
  1767. #endif