amiflop.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:48k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/amiga/amiflop.c
  3.  *
  4.  *  Copyright (C) 1993  Greg Harp
  5.  *  Portions of this driver are based on code contributed by Brad Pepers
  6.  *  
  7.  *  revised 28.5.95 by Joerg Dorchain
  8.  *  - now no bugs(?) any more for both HD & DD
  9.  *  - added support for 40 Track 5.25" drives, 80-track hopefully behaves
  10.  *    like 3.5" dd (no way to test - are there any 5.25" drives out there
  11.  *    that work on an A4000?)
  12.  *  - wrote formatting routine (maybe dirty, but works)
  13.  *
  14.  *  june/july 1995 added ms-dos support by Joerg Dorchain
  15.  *  (portions based on messydos.device and various contributors)
  16.  *  - currently only 9 and 18 sector disks
  17.  *
  18.  *  - fixed a bug with the internal trackbuffer when using multiple 
  19.  *    disks the same time
  20.  *  - made formatting a bit safer
  21.  *  - added command line and machine based default for "silent" df0
  22.  *
  23.  *  december 1995 adapted for 1.2.13pl4 by Joerg Dorchain
  24.  *  - works but I think it's inefficient. (look in redo_fd_request)
  25.  *    But the changes were very efficient. (only three and a half lines)
  26.  *
  27.  *  january 1996 added special ioctl for tracking down read/write problems
  28.  *  - usage ioctl(d, RAW_TRACK, ptr); the raw track buffer (MFM-encoded data
  29.  *    is copied to area. (area should be large enough since no checking is
  30.  *    done - 30K is currently sufficient). return the actual size of the
  31.  *    trackbuffer
  32.  *  - replaced udelays() by a timer (CIAA timer B) for the waits 
  33.  *    needed for the disk mechanic.
  34.  *
  35.  *  february 1996 fixed error recovery and multiple disk access
  36.  *  - both got broken the first time I tampered with the driver :-(
  37.  *  - still not safe, but better than before
  38.  *
  39.  *  revised Marts 3rd, 1996 by Jes Sorensen for use in the 1.3.28 kernel.
  40.  *  - Minor changes to accept the kdev_t.
  41.  *  - Replaced some more udelays with ms_delays. Udelay is just a loop,
  42.  *    and so the delay will be different depending on the given
  43.  *    processor :-(
  44.  *  - The driver could use a major cleanup because of the new
  45.  *    major/minor handling that came with kdev_t. It seems to work for
  46.  *    the time being, but I can't guarantee that it will stay like
  47.  *    that when we start using 16 (24?) bit minors.
  48.  *
  49.  * restructured jan 1997 by Joerg Dorchain
  50.  * - Fixed Bug accessing multiple disks
  51.  * - some code cleanup
  52.  * - added trackbuffer for each drive to speed things up
  53.  * - fixed some race conditions (who finds the next may send it to me ;-)
  54.  */
  55. #include <linux/module.h>
  56. #include <linux/sched.h>
  57. #include <linux/fs.h>
  58. #include <linux/fcntl.h>
  59. #include <linux/kernel.h>
  60. #include <linux/timer.h>
  61. #include <linux/fd.h>
  62. #include <linux/hdreg.h>
  63. #include <linux/errno.h>
  64. #include <linux/types.h>
  65. #include <linux/delay.h>
  66. #include <linux/string.h>
  67. #include <linux/slab.h>
  68. #include <linux/init.h>
  69. #include <linux/amifdreg.h>
  70. #include <linux/amifd.h>
  71. #include <linux/ioport.h>
  72. #include <asm/setup.h>
  73. #include <asm/uaccess.h>
  74. #include <asm/amigahw.h>
  75. #include <asm/amigaints.h>
  76. #include <asm/irq.h>
  77. #define MAJOR_NR FLOPPY_MAJOR
  78. #include <linux/blk.h>
  79. #undef DEBUG /* print _LOTS_ of infos */
  80. #define RAW_IOCTL
  81. #ifdef RAW_IOCTL
  82. #define IOCTL_RAW_TRACK 0x5254524B  /* 'RTRK' */
  83. #endif
  84. /*
  85.  *  Defines
  86.  */
  87. /*
  88.  *  Error codes
  89.  */
  90. #define FD_OK 0 /* operation succeeded */
  91. #define FD_ERROR -1 /* general error (seek, read, write, etc) */
  92. #define FD_NOUNIT 1 /* unit does not exist */
  93. #define FD_UNITBUSY 2 /* unit already active */
  94. #define FD_NOTACTIVE 3 /* unit is not active */
  95. #define FD_NOTREADY 4 /* unit is not ready (motor not on/no disk) */
  96. #define MFM_NOSYNC 1
  97. #define MFM_HEADER 2
  98. #define MFM_DATA 3
  99. #define MFM_TRACK 4
  100. /*
  101.  *  Floppy ID values
  102.  */
  103. #define FD_NODRIVE 0x00000000  /* response when no unit is present */
  104. #define FD_DD_3  0xffffffff  /* double-density 3.5" (880K) drive */
  105. #define FD_HD_3  0x55555555  /* high-density 3.5" (1760K) drive */
  106. #define FD_DD_5  0xaaaaaaaa  /* double-density 5.25" (440K) drive */
  107. static long int fd_def_df0 = FD_DD_3;     /* default for df0 if it doesn't identify */
  108. MODULE_PARM(fd_def_df0,"l");
  109. MODULE_LICENSE("GPL");
  110. /*
  111.  *  Macros
  112.  */
  113. #define MOTOR_ON (ciab.prb &= ~DSKMOTOR)
  114. #define MOTOR_OFF (ciab.prb |= DSKMOTOR)
  115. #define SELECT(mask)    (ciab.prb &= ~mask)
  116. #define DESELECT(mask)  (ciab.prb |= mask)
  117. #define SELMASK(drive)  (1 << (3 + (drive & 3)))
  118. static struct fd_drive_type drive_types[] = {
  119. /*  code name    tr he   rdsz   wrsz sm pc1 pc2 sd  st st*/
  120. /*  warning: times are now in milliseconds (ms)                    */
  121. { FD_DD_3, "DD 3.5",  80, 2, 14716, 13630, 1, 80,161, 3, 18, 1},
  122. { FD_HD_3, "HD 3.5",  80, 2, 28344, 27258, 2, 80,161, 3, 18, 1},
  123. { FD_DD_5, "DD 5.25", 40, 2, 14716, 13630, 1, 40, 81, 6, 30, 2},
  124. { FD_NODRIVE, "No Drive", 0, 0,     0,     0, 0,  0,  0,  0,  0, 0}
  125. };
  126. static int num_dr_types = sizeof(drive_types) / sizeof(drive_types[0]);
  127. /* defaults for 3 1/2" HD-Disks */
  128. static int floppy_sizes[256]={880,880,880,880,720,720,720,720,};
  129. static int floppy_blocksizes[256];
  130. /* hardsector size assumed to be 512 */
  131. static int amiga_read(int), dos_read(int);
  132. static void amiga_write(int), dos_write(int);
  133. static struct fd_data_type data_types[] = {
  134. { "Amiga", 11 , amiga_read, amiga_write},
  135. { "MS-Dos", 9, dos_read, dos_write}
  136. };
  137. /* current info on each unit */
  138. static struct amiga_floppy_struct unit[FD_MAX_UNITS];
  139. static struct timer_list flush_track_timer[FD_MAX_UNITS];
  140. static struct timer_list post_write_timer;
  141. static struct timer_list motor_on_timer;
  142. static struct timer_list motor_off_timer[FD_MAX_UNITS];
  143. static int on_attempts;
  144. /* Synchronization of FDC access */
  145. /* request loop (trackbuffer) */
  146. static volatile int fdc_busy = -1;
  147. static volatile int fdc_nested;
  148. static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
  149.  
  150. static DECLARE_WAIT_QUEUE_HEAD(motor_wait);
  151. static volatile int selected = -1; /* currently selected drive */
  152. static int writepending;
  153. static int writefromint;
  154. static char *raw_buf;
  155. #define RAW_BUF_SIZE 30000  /* size of raw disk data */
  156. /*
  157.  * These are global variables, as that's the easiest way to give
  158.  * information to interrupts. They are the data used for the current
  159.  * request.
  160.  */
  161. static volatile char block_flag;
  162. static DECLARE_WAIT_QUEUE_HEAD(wait_fd_block);
  163. /* MS-Dos MFM Coding tables (should go quick and easy) */
  164. static unsigned char mfmencode[16]={
  165. 0x2a, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15,
  166. 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55
  167. };
  168. static unsigned char mfmdecode[128];
  169. /* floppy internal millisecond timer stuff */
  170. static volatile int ms_busy = -1;
  171. static DECLARE_WAIT_QUEUE_HEAD(ms_wait);
  172. #define MS_TICKS ((amiga_eclock+50)/1000)
  173. /*
  174.  * Note that MAX_ERRORS=X doesn't imply that we retry every bad read
  175.  * max X times - some types of errors increase the errorcount by 2 or
  176.  * even 3, so we might actually retry only X/2 times before giving up.
  177.  */
  178. #define MAX_ERRORS 12
  179. /* Prevent "aliased" accesses. */
  180. static int fd_ref[4] = { 0,0,0,0 };
  181. static int fd_device[4] = { 0,0,0,0 };
  182. /*
  183.  * Current device number. Taken either from the block header or from the
  184.  * format request descriptor.
  185.  */
  186. #define CURRENT_DEVICE (CURRENT->rq_dev)
  187. /* Current error count. */
  188. #define CURRENT_ERRORS (CURRENT->errors)
  189. /*
  190.  * Here come the actual hardware access and helper functions.
  191.  * They are not reentrant and single threaded because all drives
  192.  * share the same hardware and the same trackbuffer.
  193.  */
  194. /* Milliseconds timer */
  195. static void ms_isr(int irq, void *dummy, struct pt_regs *fp)
  196. {
  197. ms_busy = -1;
  198. wake_up(&ms_wait);
  199. }
  200. /* all waits are queued up 
  201.    A more generic routine would do a schedule a la timer.device */
  202. static void ms_delay(int ms)
  203. {
  204. unsigned long flags;
  205. int ticks;
  206. if (ms > 0) {
  207. save_flags(flags);
  208. cli();
  209. while (ms_busy == 0)
  210. sleep_on(&ms_wait);
  211. ms_busy = 0;
  212. restore_flags(flags);
  213. ticks = MS_TICKS*ms-1;
  214. ciaa.tblo=ticks%256;
  215. ciaa.tbhi=ticks/256;
  216. ciaa.crb=0x19; /*count eclock, force load, one-shoot, start */
  217. sleep_on(&ms_wait);
  218. }
  219. }
  220. /* Hardware semaphore */
  221. /* returns true when we would get the semaphore */
  222. static inline int try_fdc(int drive)
  223. {
  224. drive &= 3;
  225. return ((fdc_busy < 0) || (fdc_busy == drive));
  226. }
  227. static void get_fdc(int drive)
  228. {
  229. unsigned long flags;
  230. drive &= 3;
  231. #ifdef DEBUG
  232. printk("get_fdc: drive %d  fdc_busy %d  fdc_nested %dn",drive,fdc_busy,fdc_nested);
  233. #endif
  234. save_flags(flags);
  235. cli();
  236. while (!try_fdc(drive))
  237. sleep_on(&fdc_wait);
  238. fdc_busy = drive;
  239. fdc_nested++;
  240. restore_flags(flags);
  241. }
  242. static inline void rel_fdc(void)
  243. {
  244. #ifdef DEBUG
  245. if (fdc_nested == 0)
  246. printk("fd: unmatched rel_fdcn");
  247. printk("rel_fdc: fdc_busy %d fdc_nested %dn",fdc_busy,fdc_nested);
  248. #endif
  249. fdc_nested--;
  250. if (fdc_nested == 0) {
  251. fdc_busy = -1;
  252. wake_up(&fdc_wait);
  253. }
  254. }
  255. static void fd_select (int drive)
  256. {
  257. unsigned char prb = ~0;
  258. drive&=3;
  259. #ifdef DEBUG
  260. printk("selecting %dn",drive);
  261. #endif
  262. if (drive == selected)
  263. return;
  264. get_fdc(drive);
  265. selected = drive;
  266. if (unit[drive].track % 2 != 0)
  267. prb &= ~DSKSIDE;
  268. if (unit[drive].motor == 1)
  269. prb &= ~DSKMOTOR;
  270. ciab.prb |= (SELMASK(0)|SELMASK(1)|SELMASK(2)|SELMASK(3));
  271. ciab.prb = prb;
  272. prb &= ~SELMASK(drive);
  273. ciab.prb = prb;
  274. rel_fdc();
  275. }
  276. static void fd_deselect (int drive)
  277. {
  278. unsigned char prb;
  279. unsigned long flags;
  280. drive&=3;
  281. #ifdef DEBUG
  282. printk("deselecting %dn",drive);
  283. #endif
  284. if (drive != selected) {
  285. printk(KERN_WARNING "Deselecting drive %d while %d was selected!n",drive,selected);
  286. return;
  287. }
  288. get_fdc(drive);
  289. save_flags (flags);
  290. sti();
  291. selected = -1;
  292. prb = ciab.prb;
  293. prb |= (SELMASK(0)|SELMASK(1)|SELMASK(2)|SELMASK(3));
  294. ciab.prb = prb;
  295. restore_flags (flags);
  296. rel_fdc();
  297. }
  298. static void motor_on_callback(unsigned long nr)
  299. {
  300. if (!(ciaa.pra & DSKRDY) || --on_attempts == 0) {
  301. wake_up (&motor_wait);
  302. } else {
  303. motor_on_timer.expires = jiffies + HZ/10;
  304. add_timer(&motor_on_timer);
  305. }
  306. }
  307. static int fd_motor_on(int nr)
  308. {
  309. nr &= 3;
  310. del_timer(motor_off_timer + nr);
  311. if (!unit[nr].motor) {
  312. unit[nr].motor = 1;
  313. fd_select(nr);
  314. del_timer(&motor_on_timer);
  315. motor_on_timer.data = nr;
  316. motor_on_timer.expires = jiffies + HZ/2;
  317. add_timer(&motor_on_timer);
  318. on_attempts = 10;
  319. sleep_on (&motor_wait);
  320. fd_deselect(nr);
  321. }
  322. if (on_attempts == 0) {
  323. on_attempts = -1;
  324. #if 0
  325. printk (KERN_ERR "motor_on failed, turning motor offn");
  326. fd_motor_off (nr);
  327. return 0;
  328. #else
  329. printk (KERN_WARNING "DSKRDY not set after 1.5 seconds - assuming drive is spinning notwithstandingn");
  330. #endif
  331. }
  332. return 1;
  333. }
  334. static void fd_motor_off(unsigned long drive)
  335. {
  336. long calledfromint;
  337. #ifdef MODULE
  338. long decusecount;
  339. decusecount = drive & 0x40000000;
  340. #endif
  341. calledfromint = drive & 0x80000000;
  342. drive&=3;
  343. if (calledfromint && !try_fdc(drive)) {
  344. /* We would be blocked in an interrupt, so try again later */
  345. motor_off_timer[drive].expires = jiffies + 1;
  346. add_timer(motor_off_timer + drive);
  347. return;
  348. }
  349. unit[drive].motor = 0;
  350. fd_select(drive);
  351. udelay (1);
  352. fd_deselect(drive);
  353. #ifdef MODULE
  354. /*
  355.   this is the last interrupt for any drive access, happens after
  356.   release (from floppy_off). So we have to wait until now to decrease
  357.   the use count.
  358. */
  359. if (decusecount)
  360. MOD_DEC_USE_COUNT;
  361. #endif
  362. }
  363. static void floppy_off (unsigned int nr)
  364. {
  365. int drive;
  366. drive = nr & 3;
  367. del_timer(motor_off_timer + drive);
  368. motor_off_timer[drive].expires = jiffies + 3*HZ;
  369. /* called this way it is always from interrupt */
  370. motor_off_timer[drive].data = nr | 0x80000000;
  371. add_timer(motor_off_timer + nr);
  372. }
  373. static int fd_calibrate(int drive)
  374. {
  375. unsigned char prb;
  376. int n;
  377. drive &= 3;
  378. get_fdc(drive);
  379. if (!fd_motor_on (drive))
  380. return 0;
  381. fd_select (drive);
  382. prb = ciab.prb;
  383. prb |= DSKSIDE;
  384. prb &= ~DSKDIREC;
  385. ciab.prb = prb;
  386. for (n = unit[drive].type->tracks/2; n != 0; --n) {
  387. if (ciaa.pra & DSKTRACK0)
  388. break;
  389. prb &= ~DSKSTEP;
  390. ciab.prb = prb;
  391. prb |= DSKSTEP;
  392. udelay (2);
  393. ciab.prb = prb;
  394. ms_delay(unit[drive].type->step_delay);
  395. }
  396. ms_delay (unit[drive].type->settle_time);
  397. prb |= DSKDIREC;
  398. n = unit[drive].type->tracks + 20;
  399. for (;;) {
  400. prb &= ~DSKSTEP;
  401. ciab.prb = prb;
  402. prb |= DSKSTEP;
  403. udelay (2);
  404. ciab.prb = prb;
  405. ms_delay(unit[drive].type->step_delay + 1);
  406. if ((ciaa.pra & DSKTRACK0) == 0)
  407. break;
  408. if (--n == 0) {
  409. printk (KERN_ERR "fd%d: calibrate failed, turning motor offn", drive);
  410. fd_motor_off (drive);
  411. unit[drive].track = -1;
  412. rel_fdc();
  413. return 0;
  414. }
  415. }
  416. unit[drive].track = 0;
  417. ms_delay(unit[drive].type->settle_time);
  418. rel_fdc();
  419. fd_deselect(drive);
  420. return 1;
  421. }
  422. static int fd_seek(int drive, int track)
  423. {
  424. unsigned char prb;
  425. int cnt;
  426. #ifdef DEBUG
  427. printk("seeking drive %d to track %dn",drive,track);
  428. #endif
  429. drive &= 3;
  430. get_fdc(drive);
  431. if (unit[drive].track == track) {
  432. rel_fdc();
  433. return 1;
  434. }
  435. if (!fd_motor_on(drive)) {
  436. rel_fdc();
  437. return 0;
  438. }
  439. if (unit[drive].track < 0 && !fd_calibrate(drive)) {
  440. rel_fdc();
  441. return 0;
  442. }
  443. fd_select (drive);
  444. cnt = unit[drive].track/2 - track/2;
  445. prb = ciab.prb;
  446. prb |= DSKSIDE | DSKDIREC;
  447. if (track % 2 != 0)
  448. prb &= ~DSKSIDE;
  449. if (cnt < 0) {
  450. cnt = - cnt;
  451. prb &= ~DSKDIREC;
  452. }
  453. ciab.prb = prb;
  454. if (track % 2 != unit[drive].track % 2)
  455. ms_delay (unit[drive].type->side_time);
  456. unit[drive].track = track;
  457. if (cnt == 0) {
  458. rel_fdc();
  459. fd_deselect(drive);
  460. return 1;
  461. }
  462. do {
  463. prb &= ~DSKSTEP;
  464. ciab.prb = prb;
  465. prb |= DSKSTEP;
  466. udelay (1);
  467. ciab.prb = prb;
  468. ms_delay (unit[drive].type->step_delay);
  469. } while (--cnt != 0);
  470. ms_delay (unit[drive].type->settle_time);
  471. rel_fdc();
  472. fd_deselect(drive);
  473. return 1;
  474. }
  475. static unsigned long fd_get_drive_id(int drive)
  476. {
  477. int i;
  478. ulong id = 0;
  479.    drive&=3;
  480.    get_fdc(drive);
  481. /* set up for ID */
  482. MOTOR_ON;
  483. udelay(2);
  484. SELECT(SELMASK(drive));
  485. udelay(2);
  486. DESELECT(SELMASK(drive));
  487. udelay(2);
  488. MOTOR_OFF;
  489. udelay(2);
  490. SELECT(SELMASK(drive));
  491. udelay(2);
  492. DESELECT(SELMASK(drive));
  493. udelay(2);
  494. /* loop and read disk ID */
  495. for (i=0; i<32; i++) {
  496. SELECT(SELMASK(drive));
  497. udelay(2);
  498. /* read and store value of DSKRDY */
  499. id <<= 1;
  500. id |= (ciaa.pra & DSKRDY) ? 0 : 1; /* cia regs are low-active! */
  501. DESELECT(SELMASK(drive));
  502. }
  503. rel_fdc();
  504.         /*
  505.          * RB: At least A500/A2000's df0: don't identify themselves.
  506.          * As every (real) Amiga has at least a 3.5" DD drive as df0:
  507.          * we default to that if df0: doesn't identify as a certain
  508.          * type.
  509.          */
  510.         if(drive == 0 && id == FD_NODRIVE)
  511. {
  512.                 id = fd_def_df0;
  513.                 printk(KERN_NOTICE "fd: drive 0 didn't identify, setting default %08lxn", (ulong)fd_def_df0);
  514. }
  515. /* return the ID value */
  516. return (id);
  517. }
  518. static void fd_block_done(int irq, void *dummy, struct pt_regs *fp)
  519. {
  520. if (block_flag)
  521. custom.dsklen = 0x4000;
  522. if (block_flag == 2) { /* writing */
  523. writepending = 2;
  524. post_write_timer.expires = jiffies + 1; /* at least 2 ms */
  525. post_write_timer.data = selected;
  526. add_timer(&post_write_timer);
  527. }
  528. else {                /* reading */
  529. block_flag = 0;
  530. wake_up (&wait_fd_block);
  531. }
  532. }
  533. static void raw_read(int drive)
  534. {
  535. drive&=3;
  536. get_fdc(drive);
  537. while (block_flag)
  538. sleep_on(&wait_fd_block);
  539. fd_select(drive);
  540. /* setup adkcon bits correctly */
  541. custom.adkcon = ADK_MSBSYNC;
  542. custom.adkcon = ADK_SETCLR|ADK_WORDSYNC|ADK_FAST;
  543. custom.dsksync = MFM_SYNC;
  544. custom.dsklen = 0;
  545. custom.dskptr = (u_char *)ZTWO_PADDR((u_char *)raw_buf);
  546. custom.dsklen = unit[drive].type->read_size/sizeof(short) | DSKLEN_DMAEN;
  547. custom.dsklen = unit[drive].type->read_size/sizeof(short) | DSKLEN_DMAEN;
  548. block_flag = 1;
  549. while (block_flag)
  550. sleep_on (&wait_fd_block);
  551. custom.dsklen = 0;
  552. fd_deselect(drive);
  553. rel_fdc();
  554. }
  555. static int raw_write(int drive)
  556. {
  557. ushort adk;
  558. drive&=3;
  559. get_fdc(drive); /* corresponds to rel_fdc() in post_write() */
  560. if ((ciaa.pra & DSKPROT) == 0) {
  561. rel_fdc();
  562. return 0;
  563. }
  564. while (block_flag)
  565. sleep_on(&wait_fd_block);
  566. fd_select(drive);
  567. /* clear adkcon bits */
  568. custom.adkcon = ADK_PRECOMP1|ADK_PRECOMP0|ADK_WORDSYNC|ADK_MSBSYNC;
  569. /* set appropriate adkcon bits */
  570. adk = ADK_SETCLR|ADK_FAST;
  571. if ((ulong)unit[drive].track >= unit[drive].type->precomp2)
  572. adk |= ADK_PRECOMP1;
  573. else if ((ulong)unit[drive].track >= unit[drive].type->precomp1)
  574. adk |= ADK_PRECOMP0;
  575. custom.adkcon = adk;
  576. custom.dsklen = DSKLEN_WRITE;
  577. custom.dskptr = (u_char *)ZTWO_PADDR((u_char *)raw_buf);
  578. custom.dsklen = unit[drive].type->write_size/sizeof(short) | DSKLEN_DMAEN|DSKLEN_WRITE;
  579. custom.dsklen = unit[drive].type->write_size/sizeof(short) | DSKLEN_DMAEN|DSKLEN_WRITE;
  580. block_flag = 2;
  581. return 1;
  582. }
  583. /*
  584.  * to be called at least 2ms after the write has finished but before any
  585.  * other access to the hardware.
  586.  */
  587. static void post_write (unsigned long drive)
  588. {
  589. #ifdef DEBUG
  590. printk("post_write for drive %ldn",drive);
  591. #endif
  592. drive &= 3;
  593. custom.dsklen = 0;
  594. block_flag = 0;
  595. writepending = 0;
  596. writefromint = 0;
  597. unit[drive].dirty = 0;
  598. wake_up(&wait_fd_block);
  599. fd_deselect(drive);
  600. rel_fdc(); /* corresponds to get_fdc() in raw_write */
  601. }
  602. /*
  603.  * The following functions are to convert the block contents into raw data
  604.  * written to disk and vice versa.
  605.  * (Add other formats here ;-))
  606.  */
  607. static unsigned long scan_sync(unsigned long raw, unsigned long end)
  608. {
  609. ushort *ptr = (ushort *)raw, *endp = (ushort *)end;
  610. while (ptr < endp && *ptr++ != 0x4489)
  611. ;
  612. if (ptr < endp) {
  613. while (*ptr == 0x4489 && ptr < endp)
  614. ptr++;
  615. return (ulong)ptr;
  616. }
  617. return 0;
  618. }
  619. static inline unsigned long checksum(unsigned long *addr, int len)
  620. {
  621. unsigned long csum = 0;
  622. len /= sizeof(*addr);
  623. while (len-- > 0)
  624. csum ^= *addr++;
  625. csum = ((csum>>1) & 0x55555555)  ^  (csum & 0x55555555);
  626. return csum;
  627. }
  628. static unsigned long decode (unsigned long *data, unsigned long *raw,
  629.      int len)
  630. {
  631. ulong *odd, *even;
  632. /* convert length from bytes to longwords */
  633. len >>= 2;
  634. odd = raw;
  635. even = odd + len;
  636. /* prepare return pointer */
  637. raw += len * 2;
  638. do {
  639. *data++ = ((*odd++ & 0x55555555) << 1) | (*even++ & 0x55555555);
  640. } while (--len != 0);
  641. return (ulong)raw;
  642. }
  643. struct header {
  644. unsigned char magic;
  645. unsigned char track;
  646. unsigned char sect;
  647. unsigned char ord;
  648. unsigned char labels[16];
  649. unsigned long hdrchk;
  650. unsigned long datachk;
  651. };
  652. static int amiga_read(int drive)
  653. {
  654. unsigned long raw;
  655. unsigned long end;
  656. int scnt;
  657. unsigned long csum;
  658. struct header hdr;
  659. drive&=3;
  660. raw = (long) raw_buf;
  661. end = raw + unit[drive].type->read_size;
  662. for (scnt = 0;scnt < unit[drive].dtype->sects * unit[drive].type->sect_mult; scnt++) {
  663. if (!(raw = scan_sync(raw, end))) {
  664. printk (KERN_INFO "can't find sync for sector %dn", scnt);
  665. return MFM_NOSYNC;
  666. }
  667. raw = decode ((ulong *)&hdr.magic, (ulong *)raw, 4);
  668. raw = decode ((ulong *)&hdr.labels, (ulong *)raw, 16);
  669. raw = decode ((ulong *)&hdr.hdrchk, (ulong *)raw, 4);
  670. raw = decode ((ulong *)&hdr.datachk, (ulong *)raw, 4);
  671. csum = checksum((ulong *)&hdr,
  672. (char *)&hdr.hdrchk-(char *)&hdr);
  673. #ifdef DEBUG
  674. printk ("(%x,%d,%d,%d) (%lx,%lx,%lx,%lx) %lx %lxn",
  675. hdr.magic, hdr.track, hdr.sect, hdr.ord,
  676. *(ulong *)&hdr.labels[0], *(ulong *)&hdr.labels[4],
  677. *(ulong *)&hdr.labels[8], *(ulong *)&hdr.labels[12],
  678. hdr.hdrchk, hdr.datachk);
  679. #endif
  680. if (hdr.hdrchk != csum) {
  681. printk(KERN_INFO "MFM_HEADER: %08lx,%08lxn", hdr.hdrchk, csum);
  682. return MFM_HEADER;
  683. }
  684. /* verify track */
  685. if (hdr.track != unit[drive].track) {
  686. printk(KERN_INFO "MFM_TRACK: %d, %dn", hdr.track, unit[drive].track);
  687. return MFM_TRACK;
  688. }
  689. raw = decode ((ulong *)(unit[drive].trackbuf + hdr.sect*512),
  690.       (ulong *)raw, 512);
  691. csum = checksum((ulong *)(unit[drive].trackbuf + hdr.sect*512), 512);
  692. if (hdr.datachk != csum) {
  693. printk(KERN_INFO "MFM_DATA: (%x:%d:%d:%d) sc=%d %lx, %lxn",
  694.        hdr.magic, hdr.track, hdr.sect, hdr.ord, scnt,
  695.        hdr.datachk, csum);
  696. printk (KERN_INFO "data=(%lx,%lx,%lx,%lx)n",
  697. ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[0],
  698. ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[1],
  699. ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[2],
  700. ((ulong *)(unit[drive].trackbuf+hdr.sect*512))[3]);
  701. return MFM_DATA;
  702. }
  703. }
  704. return 0;
  705. }
  706. static void encode(unsigned long data, unsigned long *dest)
  707. {
  708. unsigned long data2;
  709. data &= 0x55555555;
  710. data2 = data ^ 0x55555555;
  711. data |= ((data2 >> 1) | 0x80000000) & (data2 << 1);
  712. if (*(dest - 1) & 0x00000001)
  713. data &= 0x7FFFFFFF;
  714. *dest = data;
  715. }
  716. static void encode_block(unsigned long *dest, unsigned long *src, int len)
  717. {
  718. int cnt, to_cnt = 0;
  719. unsigned long data;
  720. /* odd bits */
  721. for (cnt = 0; cnt < len / 4; cnt++) {
  722. data = src[cnt] >> 1;
  723. encode(data, dest + to_cnt++);
  724. }
  725. /* even bits */
  726. for (cnt = 0; cnt < len / 4; cnt++) {
  727. data = src[cnt];
  728. encode(data, dest + to_cnt++);
  729. }
  730. }
  731. static unsigned long *putsec(int disk, unsigned long *raw, int cnt)
  732. {
  733. struct header hdr;
  734. int i;
  735. disk&=3;
  736. *raw = (raw[-1]&1) ? 0x2AAAAAAA : 0xAAAAAAAA;
  737. raw++;
  738. *raw++ = 0x44894489;
  739. hdr.magic = 0xFF;
  740. hdr.track = unit[disk].track;
  741. hdr.sect = cnt;
  742. hdr.ord = unit[disk].dtype->sects * unit[disk].type->sect_mult - cnt;
  743. for (i = 0; i < 16; i++)
  744. hdr.labels[i] = 0;
  745. hdr.hdrchk = checksum((ulong *)&hdr,
  746.       (char *)&hdr.hdrchk-(char *)&hdr);
  747. hdr.datachk = checksum((ulong *)(unit[disk].trackbuf+cnt*512), 512);
  748. encode_block(raw, (ulong *)&hdr.magic, 4);
  749. raw += 2;
  750. encode_block(raw, (ulong *)&hdr.labels, 16);
  751. raw += 8;
  752. encode_block(raw, (ulong *)&hdr.hdrchk, 4);
  753. raw += 2;
  754. encode_block(raw, (ulong *)&hdr.datachk, 4);
  755. raw += 2;
  756. encode_block(raw, (ulong *)(unit[disk].trackbuf+cnt*512), 512);
  757. raw += 256;
  758. return raw;
  759. }
  760. static void amiga_write(int disk)
  761. {
  762. unsigned int cnt;
  763. unsigned long *ptr = (unsigned long *)raw_buf;
  764. disk&=3;
  765. /* gap space */
  766. for (cnt = 0; cnt < 415 * unit[disk].type->sect_mult; cnt++)
  767. *ptr++ = 0xaaaaaaaa;
  768. /* sectors */
  769. for (cnt = 0; cnt < unit[disk].dtype->sects * unit[disk].type->sect_mult; cnt++)
  770. ptr = putsec (disk, ptr, cnt);
  771. *(ushort *)ptr = (ptr[-1]&1) ? 0x2AA8 : 0xAAA8;
  772. }
  773. struct dos_header {
  774. unsigned char track,   /* 0-80 */
  775. side,    /* 0-1 */
  776. sec,     /* 0-...*/
  777. len_desc;/* 2 */
  778. unsigned short crc;     /* on 68000 we got an alignment problem, 
  779.    but this compiler solves it  by adding silently 
  780.    adding a pad byte so data won't fit
  781.    and this took about 3h to discover.... */
  782. unsigned char gap1[22];     /* for longword-alignedness (0x4e) */
  783. };
  784. /* crc routines are borrowed from the messydos-handler  */
  785. /* excerpt from the messydos-device           
  786. ; The CRC is computed not only over the actual data, but including
  787. ; the SYNC mark (3 * $a1) and the 'ID/DATA - Address Mark' ($fe/$fb).
  788. ; As we don't read or encode these fields into our buffers, we have to
  789. ; preload the registers containing the CRC with the values they would have
  790. ; after stepping over these fields.
  791. ;
  792. ; How CRCs "really" work:
  793. ;
  794. ; First, you should regard a bitstring as a series of coefficients of
  795. ; polynomials. We calculate with these polynomials in modulo-2
  796. ; arithmetic, in which both add and subtract are done the same as
  797. ; exclusive-or. Now, we modify our data (a very long polynomial) in
  798. ; such a way that it becomes divisible by the CCITT-standard 16-bit
  799. ;  16   12   5
  800. ; polynomial: x  + x + x + 1, represented by $11021. The easiest
  801. ; way to do this would be to multiply (using proper arithmetic) our
  802. ; datablock with $11021. So we have:
  803. ;   data * $11021  =
  804. ;   data * ($10000 + $1021)      =
  805. ;   data * $10000 + data * $1021
  806. ; The left part of this is simple: Just add two 0 bytes. But then
  807. ; the right part (data $1021) remains difficult and even could have
  808. ; a carry into the left part. The solution is to use a modified
  809. ; multiplication, which has a result that is not correct, but with
  810. ; a difference of any multiple of $11021. We then only need to keep
  811. ; the 16 least significant bits of the result.
  812. ;
  813. ; The following algorithm does this for us:
  814. ;
  815. ;   unsigned char *data, c, crclo, crchi;
  816. ;   while (not done) {
  817. ; c = *data++ + crchi;
  818. ; crchi = (@ c) >> 8 + crclo;
  819. ; crclo = @ c;
  820. ;   }
  821. ;
  822. ; Remember, + is done with EOR, the @ operator is in two tables (high
  823. ; and low byte separately), which is calculated as
  824. ;
  825. ;      $1021 * (c & $F0)
  826. ;  xor $1021 * (c & $0F)
  827. ;  xor $1021 * (c >> 4)         (* is regular multiplication)
  828. ;
  829. ;
  830. ; Anyway, the end result is the same as the remainder of the division of
  831. ; the data by $11021. I am afraid I need to study theory a bit more...
  832. my only works was to code this from manx to C....
  833. */
  834. static ushort dos_crc(void * data_a3, int data_d0, int data_d1, int data_d3)
  835. {
  836. static unsigned char CRCTable1[] = {
  837. 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x81,0x91,0xa1,0xb1,0xc1,0xd1,0xe1,0xf1,
  838. 0x12,0x02,0x32,0x22,0x52,0x42,0x72,0x62,0x93,0x83,0xb3,0xa3,0xd3,0xc3,0xf3,0xe3,
  839. 0x24,0x34,0x04,0x14,0x64,0x74,0x44,0x54,0xa5,0xb5,0x85,0x95,0xe5,0xf5,0xc5,0xd5,
  840. 0x36,0x26,0x16,0x06,0x76,0x66,0x56,0x46,0xb7,0xa7,0x97,0x87,0xf7,0xe7,0xd7,0xc7,
  841. 0x48,0x58,0x68,0x78,0x08,0x18,0x28,0x38,0xc9,0xd9,0xe9,0xf9,0x89,0x99,0xa9,0xb9,
  842. 0x5a,0x4a,0x7a,0x6a,0x1a,0x0a,0x3a,0x2a,0xdb,0xcb,0xfb,0xeb,0x9b,0x8b,0xbb,0xab,
  843. 0x6c,0x7c,0x4c,0x5c,0x2c,0x3c,0x0c,0x1c,0xed,0xfd,0xcd,0xdd,0xad,0xbd,0x8d,0x9d,
  844. 0x7e,0x6e,0x5e,0x4e,0x3e,0x2e,0x1e,0x0e,0xff,0xef,0xdf,0xcf,0xbf,0xaf,0x9f,0x8f,
  845. 0x91,0x81,0xb1,0xa1,0xd1,0xc1,0xf1,0xe1,0x10,0x00,0x30,0x20,0x50,0x40,0x70,0x60,
  846. 0x83,0x93,0xa3,0xb3,0xc3,0xd3,0xe3,0xf3,0x02,0x12,0x22,0x32,0x42,0x52,0x62,0x72,
  847. 0xb5,0xa5,0x95,0x85,0xf5,0xe5,0xd5,0xc5,0x34,0x24,0x14,0x04,0x74,0x64,0x54,0x44,
  848. 0xa7,0xb7,0x87,0x97,0xe7,0xf7,0xc7,0xd7,0x26,0x36,0x06,0x16,0x66,0x76,0x46,0x56,
  849. 0xd9,0xc9,0xf9,0xe9,0x99,0x89,0xb9,0xa9,0x58,0x48,0x78,0x68,0x18,0x08,0x38,0x28,
  850. 0xcb,0xdb,0xeb,0xfb,0x8b,0x9b,0xab,0xbb,0x4a,0x5a,0x6a,0x7a,0x0a,0x1a,0x2a,0x3a,
  851. 0xfd,0xed,0xdd,0xcd,0xbd,0xad,0x9d,0x8d,0x7c,0x6c,0x5c,0x4c,0x3c,0x2c,0x1c,0x0c,
  852. 0xef,0xff,0xcf,0xdf,0xaf,0xbf,0x8f,0x9f,0x6e,0x7e,0x4e,0x5e,0x2e,0x3e,0x0e,0x1e
  853. };
  854. static unsigned char CRCTable2[] = {
  855. 0x00,0x21,0x42,0x63,0x84,0xa5,0xc6,0xe7,0x08,0x29,0x4a,0x6b,0x8c,0xad,0xce,0xef,
  856. 0x31,0x10,0x73,0x52,0xb5,0x94,0xf7,0xd6,0x39,0x18,0x7b,0x5a,0xbd,0x9c,0xff,0xde,
  857. 0x62,0x43,0x20,0x01,0xe6,0xc7,0xa4,0x85,0x6a,0x4b,0x28,0x09,0xee,0xcf,0xac,0x8d,
  858. 0x53,0x72,0x11,0x30,0xd7,0xf6,0x95,0xb4,0x5b,0x7a,0x19,0x38,0xdf,0xfe,0x9d,0xbc,
  859. 0xc4,0xe5,0x86,0xa7,0x40,0x61,0x02,0x23,0xcc,0xed,0x8e,0xaf,0x48,0x69,0x0a,0x2b,
  860. 0xf5,0xd4,0xb7,0x96,0x71,0x50,0x33,0x12,0xfd,0xdc,0xbf,0x9e,0x79,0x58,0x3b,0x1a,
  861. 0xa6,0x87,0xe4,0xc5,0x22,0x03,0x60,0x41,0xae,0x8f,0xec,0xcd,0x2a,0x0b,0x68,0x49,
  862. 0x97,0xb6,0xd5,0xf4,0x13,0x32,0x51,0x70,0x9f,0xbe,0xdd,0xfc,0x1b,0x3a,0x59,0x78,
  863. 0x88,0xa9,0xca,0xeb,0x0c,0x2d,0x4e,0x6f,0x80,0xa1,0xc2,0xe3,0x04,0x25,0x46,0x67,
  864. 0xb9,0x98,0xfb,0xda,0x3d,0x1c,0x7f,0x5e,0xb1,0x90,0xf3,0xd2,0x35,0x14,0x77,0x56,
  865. 0xea,0xcb,0xa8,0x89,0x6e,0x4f,0x2c,0x0d,0xe2,0xc3,0xa0,0x81,0x66,0x47,0x24,0x05,
  866. 0xdb,0xfa,0x99,0xb8,0x5f,0x7e,0x1d,0x3c,0xd3,0xf2,0x91,0xb0,0x57,0x76,0x15,0x34,
  867. 0x4c,0x6d,0x0e,0x2f,0xc8,0xe9,0x8a,0xab,0x44,0x65,0x06,0x27,0xc0,0xe1,0x82,0xa3,
  868. 0x7d,0x5c,0x3f,0x1e,0xf9,0xd8,0xbb,0x9a,0x75,0x54,0x37,0x16,0xf1,0xd0,0xb3,0x92,
  869. 0x2e,0x0f,0x6c,0x4d,0xaa,0x8b,0xe8,0xc9,0x26,0x07,0x64,0x45,0xa2,0x83,0xe0,0xc1,
  870. 0x1f,0x3e,0x5d,0x7c,0x9b,0xba,0xd9,0xf8,0x17,0x36,0x55,0x74,0x93,0xb2,0xd1,0xf0
  871. };
  872. /* look at the asm-code - what looks in C a bit strange is almost as good as handmade */
  873. register int i;
  874. register unsigned char *CRCT1, *CRCT2, *data, c, crch, crcl;
  875. CRCT1=CRCTable1;
  876. CRCT2=CRCTable2;
  877. data=data_a3;
  878. crcl=data_d1;
  879. crch=data_d0;
  880. for (i=data_d3; i>=0; i--) {
  881. c = (*data++) ^ crch;
  882. crch = CRCT1[c] ^ crcl;
  883. crcl = CRCT2[c];
  884. }
  885. return (crch<<8)|crcl;
  886. }
  887. static inline ushort dos_hdr_crc (struct dos_header *hdr)
  888. {
  889. return dos_crc(&(hdr->track), 0xb2, 0x30, 3); /* precomputed magic */
  890. }
  891. static inline ushort dos_data_crc(unsigned char *data)
  892. {
  893. return dos_crc(data, 0xe2, 0x95 ,511); /* precomputed magic */
  894. }
  895. static inline unsigned char dos_decode_byte(ushort word)
  896. {
  897. register ushort w2;
  898. register unsigned char byte;
  899. register unsigned char *dec = mfmdecode;
  900. w2=word;
  901. w2>>=8;
  902. w2&=127;
  903. byte = dec[w2];
  904. byte <<= 4;
  905. w2 = word & 127;
  906. byte |= dec[w2];
  907. return byte;
  908. }
  909. static unsigned long dos_decode(unsigned char *data, unsigned short *raw, int len)
  910. {
  911. int i;
  912. for (i = 0; i < len; i++)
  913. *data++=dos_decode_byte(*raw++);
  914. return ((ulong)raw);
  915. }
  916. #ifdef DEBUG
  917. static void dbg(unsigned long ptr)
  918. {
  919. printk("raw data @%08lx: %08lx, %08lx ,%08lx, %08lxn", ptr,
  920.        ((ulong *)ptr)[0], ((ulong *)ptr)[1],
  921.        ((ulong *)ptr)[2], ((ulong *)ptr)[3]);
  922. }
  923. #endif
  924. static int dos_read(int drive)
  925. {
  926. unsigned long end;
  927. unsigned long raw;
  928. int scnt;
  929. unsigned short crc,data_crc[2];
  930. struct dos_header hdr;
  931. drive&=3;
  932. raw = (long) raw_buf;
  933. end = raw + unit[drive].type->read_size;
  934. for (scnt=0; scnt < unit[drive].dtype->sects * unit[drive].type->sect_mult; scnt++) {
  935. do { /* search for the right sync of each sec-hdr */
  936. if (!(raw = scan_sync (raw, end))) {
  937. printk(KERN_INFO "dos_read: no hdr sync on "
  938.        "track %d, unit %d for sector %dn",
  939.        unit[drive].track,drive,scnt);
  940. return MFM_NOSYNC;
  941. }
  942. #ifdef DEBUG
  943. dbg(raw);
  944. #endif
  945. } while (*((ushort *)raw)!=0x5554); /* loop usually only once done */
  946. raw+=2; /* skip over headermark */
  947. raw = dos_decode((unsigned char *)&hdr,(ushort *) raw,8);
  948. crc = dos_hdr_crc(&hdr);
  949. #ifdef DEBUG
  950. printk("(%3d,%d,%2d,%d) %xn", hdr.track, hdr.side,
  951.        hdr.sec, hdr.len_desc, hdr.crc);
  952. #endif
  953. if (crc != hdr.crc) {
  954. printk(KERN_INFO "dos_read: MFM_HEADER %04x,%04xn",
  955.        hdr.crc, crc);
  956. return MFM_HEADER;
  957. }
  958. if (hdr.track != unit[drive].track/unit[drive].type->heads) {
  959. printk(KERN_INFO "dos_read: MFM_TRACK %d, %dn",
  960.        hdr.track,
  961.        unit[drive].track/unit[drive].type->heads);
  962. return MFM_TRACK;
  963. }
  964. if (hdr.side != unit[drive].track%unit[drive].type->heads) {
  965. printk(KERN_INFO "dos_read: MFM_SIDE %d, %dn",
  966.        hdr.side,
  967.        unit[drive].track%unit[drive].type->heads);
  968. return MFM_TRACK;
  969. }
  970. if (hdr.len_desc != 2) {
  971. printk(KERN_INFO "dos_read: unknown sector len "
  972.        "descriptor %dn", hdr.len_desc);
  973. return MFM_DATA;
  974. }
  975. #ifdef DEBUG
  976. printk("hdr acceptedn");
  977. #endif
  978. if (!(raw = scan_sync (raw, end))) {
  979. printk(KERN_INFO "dos_read: no data sync on track "
  980.        "%d, unit %d for sector%d, disk sector %dn",
  981.        unit[drive].track, drive, scnt, hdr.sec);
  982. return MFM_NOSYNC;
  983. }
  984. #ifdef DEBUG
  985. dbg(raw);
  986. #endif
  987. if (*((ushort *)raw)!=0x5545) {
  988. printk(KERN_INFO "dos_read: no data mark after "
  989.        "sync (%d,%d,%d,%d) sc=%dn",
  990.        hdr.track,hdr.side,hdr.sec,hdr.len_desc,scnt);
  991. return MFM_NOSYNC;
  992. }
  993. raw+=2;  /* skip data mark (included in checksum) */
  994. raw = dos_decode((unsigned char *)(unit[drive].trackbuf + (hdr.sec - 1) * 512), (ushort *) raw, 512);
  995. raw = dos_decode((unsigned char  *)data_crc,(ushort *) raw,4);
  996. crc = dos_data_crc(unit[drive].trackbuf + (hdr.sec - 1) * 512);
  997. if (crc != data_crc[0]) {
  998. printk(KERN_INFO "dos_read: MFM_DATA (%d,%d,%d,%d) "
  999.        "sc=%d, %x %xn", hdr.track, hdr.side,
  1000.        hdr.sec, hdr.len_desc, scnt,data_crc[0], crc);
  1001. printk(KERN_INFO "data=(%lx,%lx,%lx,%lx,...)n",
  1002.        ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[0],
  1003.        ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[1],
  1004.        ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[2],
  1005.        ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[3]);
  1006. return MFM_DATA;
  1007. }
  1008. }
  1009. return 0;
  1010. }
  1011. static inline ushort dos_encode_byte(unsigned char byte)
  1012. {
  1013. register unsigned char *enc, b2, b1;
  1014. register ushort word;
  1015. enc=mfmencode;
  1016. b1=byte;
  1017. b2=b1>>4;
  1018. b1&=15;
  1019. word=enc[b2] <<8 | enc [b1];
  1020. return (word|((word&(256|64)) ? 0: 128));
  1021. }
  1022. static void dos_encode_block(ushort *dest, unsigned char *src, int len)
  1023. {
  1024. int i;
  1025. for (i = 0; i < len; i++) {
  1026. *dest=dos_encode_byte(*src++);
  1027. *dest|=((dest[-1]&1)||(*dest&0x4000))? 0: 0x8000;
  1028. dest++;
  1029. }
  1030. }
  1031. static unsigned long *ms_putsec(int drive, unsigned long *raw, int cnt)
  1032. {
  1033. static struct dos_header hdr={0,0,0,2,0,
  1034.   {78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78}};
  1035. int i;
  1036. static ushort crc[2]={0,0x4e4e};
  1037. drive&=3;
  1038. /* id gap 1 */
  1039. /* the MFM word before is always 9254 */
  1040. for(i=0;i<6;i++)
  1041. *raw++=0xaaaaaaaa;
  1042. /* 3 sync + 1 headermark */
  1043. *raw++=0x44894489;
  1044. *raw++=0x44895554;
  1045. /* fill in the variable parts of the header */
  1046. hdr.track=unit[drive].track/unit[drive].type->heads;
  1047. hdr.side=unit[drive].track%unit[drive].type->heads;
  1048. hdr.sec=cnt+1;
  1049. hdr.crc=dos_hdr_crc(&hdr);
  1050. /* header (without "magic") and id gap 2*/
  1051. dos_encode_block((ushort *)raw,(unsigned char *) &hdr.track,28);
  1052. raw+=14;
  1053. /*id gap 3 */
  1054. for(i=0;i<6;i++)
  1055. *raw++=0xaaaaaaaa;
  1056. /* 3 syncs and 1 datamark */
  1057. *raw++=0x44894489;
  1058. *raw++=0x44895545;
  1059. /* data */
  1060. dos_encode_block((ushort *)raw,
  1061.  (unsigned char *)unit[drive].trackbuf+cnt*512,512);
  1062. raw+=256;
  1063. /*data crc + jd's special gap (long words :-/) */
  1064. crc[0]=dos_data_crc(unit[drive].trackbuf+cnt*512);
  1065. dos_encode_block((ushort *) raw,(unsigned char *)crc,4);
  1066. raw+=2;
  1067. /* data gap */
  1068. for(i=0;i<38;i++)
  1069. *raw++=0x92549254;
  1070. return raw; /* wrote 652 MFM words */
  1071. }
  1072. static void dos_write(int disk)
  1073. {
  1074. int cnt;
  1075. unsigned long raw = (unsigned long) raw_buf;
  1076. unsigned long *ptr=(unsigned long *)raw;
  1077. disk&=3;
  1078. /* really gap4 + indexgap , but we write it first and round it up */
  1079. for (cnt=0;cnt<425;cnt++)
  1080. *ptr++=0x92549254;
  1081. /* the following is just guessed */
  1082. if (unit[disk].type->sect_mult==2)  /* check for HD-Disks */
  1083. for(cnt=0;cnt<473;cnt++)
  1084. *ptr++=0x92549254;
  1085. /* now the index marks...*/
  1086. for (cnt=0;cnt<20;cnt++)
  1087. *ptr++=0x92549254;
  1088. for (cnt=0;cnt<6;cnt++)
  1089. *ptr++=0xaaaaaaaa;
  1090. *ptr++=0x52245224;
  1091. *ptr++=0x52245552;
  1092. for (cnt=0;cnt<20;cnt++)
  1093. *ptr++=0x92549254;
  1094. /* sectors */
  1095. for(cnt = 0; cnt < unit[disk].dtype->sects * unit[disk].type->sect_mult; cnt++)
  1096. ptr=ms_putsec(disk,ptr,cnt);
  1097. *(ushort *)ptr = 0xaaa8; /* MFM word before is always 0x9254 */
  1098. }
  1099. /*
  1100.  * Here comes the high level stuff (i.e. the filesystem interface)
  1101.  * and helper functions.
  1102.  * Normally this should be the only part that has to be adapted to
  1103.  * different kernel versions.
  1104.  */
  1105. /* FIXME: this assumes the drive is still spinning -
  1106.  * which is only true if we complete writing a track within three seconds
  1107.  */
  1108. static void flush_track_callback(unsigned long nr)
  1109. {
  1110. nr&=3;
  1111. writefromint = 1;
  1112. if (!try_fdc(nr)) {
  1113. /* we might block in an interrupt, so try again later */
  1114. flush_track_timer[nr].expires = jiffies + 1;
  1115. add_timer(flush_track_timer + nr);
  1116. return;
  1117. }
  1118. get_fdc(nr);
  1119. (*unit[nr].dtype->write_fkt)(nr);
  1120. if (!raw_write(nr)) {
  1121. printk (KERN_NOTICE "floppy disk write protectedn");
  1122. writefromint = 0;
  1123. writepending = 0;
  1124. }
  1125. rel_fdc();
  1126. }
  1127. static int non_int_flush_track (unsigned long nr)
  1128. {
  1129. unsigned long flags;
  1130. nr&=3;
  1131. writefromint = 0;
  1132. del_timer(&post_write_timer);
  1133. get_fdc(nr);
  1134. if (!fd_motor_on(nr)) {
  1135. writepending = 0;
  1136. rel_fdc();
  1137. return 0;
  1138. }
  1139. save_flags(flags);
  1140. cli();
  1141. if (writepending != 2) {
  1142. restore_flags(flags);
  1143. (*unit[nr].dtype->write_fkt)(nr);
  1144. if (!raw_write(nr)) {
  1145. printk (KERN_NOTICE "floppy disk write protected "
  1146. "in write!n");
  1147. writepending = 0;
  1148. return 0;
  1149. }
  1150. while (block_flag == 2)
  1151. sleep_on (&wait_fd_block);
  1152. }
  1153. else {
  1154. restore_flags(flags);
  1155. ms_delay(2); /* 2 ms post_write delay */
  1156. post_write(nr);
  1157. }
  1158. rel_fdc();
  1159. return 1;
  1160. }
  1161. static int get_track(int drive, int track)
  1162. {
  1163. int error, errcnt;
  1164. drive&=3;
  1165. if (unit[drive].track == track)
  1166. return 0;
  1167. get_fdc(drive);
  1168. if (!fd_motor_on(drive)) {
  1169. rel_fdc();
  1170. return -1;
  1171. }
  1172. if (unit[drive].dirty == 1) {
  1173. del_timer (flush_track_timer + drive);
  1174. non_int_flush_track (drive);
  1175. }
  1176. errcnt = 0;
  1177. while (errcnt < MAX_ERRORS) {
  1178. if (!fd_seek(drive, track))
  1179. return -1;
  1180. raw_read(drive);
  1181. error = (*unit[drive].dtype->read_fkt)(drive);
  1182. if (error == 0) {
  1183. rel_fdc();
  1184. return 0;
  1185. }
  1186. /* Read Error Handling: recalibrate and try again */
  1187. unit[drive].track = -1;
  1188. errcnt++;
  1189. }
  1190. rel_fdc();
  1191. return -1;
  1192. }
  1193. static void redo_fd_request(void)
  1194. {
  1195. unsigned int cnt, block, track, sector;
  1196. int device, drive;
  1197. struct amiga_floppy_struct *floppy;
  1198. char *data;
  1199. unsigned long flags;
  1200. if (!QUEUE_EMPTY && CURRENT->rq_status == RQ_INACTIVE){
  1201. return;
  1202. }
  1203.  repeat:
  1204. if (QUEUE_EMPTY) {
  1205. /* Nothing left to do */
  1206. return;
  1207. }
  1208. if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
  1209. panic(DEVICE_NAME ": request list destroyed");
  1210. if (CURRENT->bh && !buffer_locked(CURRENT->bh))
  1211. panic(DEVICE_NAME ": block not locked");
  1212. device = MINOR(CURRENT_DEVICE);
  1213. if (device < 8) {
  1214. /* manual selection */
  1215. drive = device & 3;
  1216. floppy = unit + drive;
  1217. } else {
  1218. /* Auto-detection */
  1219. #ifdef DEBUG
  1220. printk("redo_fd_request: can't handle auto detectn");
  1221. printk("redo_fd_request: default to normaln");
  1222. #endif
  1223. drive = device & 3;
  1224. floppy = unit + drive;
  1225. }
  1226. /* Here someone could investigate to be more efficient */
  1227. for (cnt = 0; cnt < CURRENT->current_nr_sectors; cnt++) { 
  1228. #ifdef DEBUG
  1229. printk("fd: sector %ld + %d requested for %sn",
  1230.        CURRENT->sector,cnt,
  1231.        (CURRENT->cmd==READ)?"read":"write");
  1232. #endif
  1233. block = CURRENT->sector + cnt;
  1234. if ((int)block > floppy->blocks) {
  1235. end_request(0);
  1236. goto repeat;
  1237. }
  1238. track = block / (floppy->dtype->sects * floppy->type->sect_mult);
  1239. sector = block % (floppy->dtype->sects * floppy->type->sect_mult);
  1240. data = CURRENT->buffer + 512 * cnt;
  1241. #ifdef DEBUG
  1242. printk("access to track %d, sector %d, with buffer at "
  1243.        "0x%08lxn", track, sector, data);
  1244. #endif
  1245. if ((CURRENT->cmd != READ) && (CURRENT->cmd != WRITE)) {
  1246. printk(KERN_WARNING "do_fd_request: unknown commandn");
  1247. end_request(0);
  1248. goto repeat;
  1249. }
  1250. if (get_track(drive, track) == -1) {
  1251. end_request(0);
  1252. goto repeat;
  1253. }
  1254. switch (CURRENT->cmd) {
  1255. case READ:
  1256. memcpy(data, unit[drive].trackbuf + sector * 512, 512);
  1257. break;
  1258. case WRITE:
  1259. memcpy(unit[drive].trackbuf + sector * 512, data, 512);
  1260. /* keep the drive spinning while writes are scheduled */
  1261. if (!fd_motor_on(drive)) {
  1262. end_request(0);
  1263. goto repeat;
  1264. }
  1265. /*
  1266.  * setup a callback to write the track buffer
  1267.  * after a short (1 tick) delay.
  1268.  */
  1269. save_flags (flags);
  1270. cli();
  1271. unit[drive].dirty = 1;
  1272.         /* reset the timer */
  1273.         del_timer (flush_track_timer + drive);
  1274.     
  1275. flush_track_timer[drive].expires = jiffies + 1;
  1276. add_timer (flush_track_timer + drive);
  1277. restore_flags (flags);
  1278. break;
  1279. }
  1280. }
  1281. CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
  1282. CURRENT->sector += CURRENT->current_nr_sectors;
  1283. end_request(1);
  1284. goto repeat;
  1285. }
  1286. static void do_fd_request(request_queue_t * q)
  1287. {
  1288. redo_fd_request();
  1289. }
  1290. static int fd_ioctl(struct inode *inode, struct file *filp,
  1291.     unsigned int cmd, unsigned long param)
  1292. {
  1293. int drive = inode->i_rdev & 3;
  1294. static struct floppy_struct getprm;
  1295. switch(cmd){
  1296. case HDIO_GETGEO:
  1297. {
  1298. struct hd_geometry loc;
  1299. loc.heads = unit[drive].type->heads;
  1300. loc.sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
  1301. loc.cylinders = unit[drive].type->tracks;
  1302. loc.start = 0;
  1303. if (copy_to_user((void *)param, (void *)&loc,
  1304.  sizeof(struct hd_geometry)))
  1305. return -EFAULT;
  1306. break;
  1307. }
  1308. case FDFMTBEG:
  1309. get_fdc(drive);
  1310. if (fd_ref[drive] > 1) {
  1311. rel_fdc();
  1312. return -EBUSY;
  1313. }
  1314. fsync_dev(inode->i_rdev);
  1315. if (fd_motor_on(drive) == 0) {
  1316. rel_fdc();
  1317. return -ENODEV;
  1318. }
  1319. if (fd_calibrate(drive) == 0) {
  1320. rel_fdc();
  1321. return -ENXIO;
  1322. }
  1323. floppy_off(drive);
  1324. rel_fdc();
  1325. break;
  1326. case FDFMTTRK:
  1327. if (param < unit[drive].type->tracks * unit[drive].type->heads)
  1328. {
  1329. get_fdc(drive);
  1330. if (fd_seek(drive,param) != 0){
  1331. memset(unit[drive].trackbuf, FD_FILL_BYTE,
  1332.        unit[drive].dtype->sects * unit[drive].type->sect_mult * 512);
  1333. non_int_flush_track(drive);
  1334. }
  1335. floppy_off(drive);
  1336. rel_fdc();
  1337. }
  1338. else
  1339. return -EINVAL;
  1340. break;
  1341. case FDFMTEND:
  1342. floppy_off(drive);
  1343. invalidate_device(inode->i_rdev, 0);
  1344. break;
  1345. case FDGETPRM:
  1346. memset((void *)&getprm, 0, sizeof (getprm));
  1347. getprm.track=unit[drive].type->tracks;
  1348. getprm.head=unit[drive].type->heads;
  1349. getprm.sect=unit[drive].dtype->sects * unit[drive].type->sect_mult;
  1350. getprm.size=unit[drive].blocks;
  1351. if (copy_to_user((void *)param,
  1352.  (void *)&getprm,
  1353.  sizeof(struct floppy_struct)))
  1354. return -EFAULT;
  1355. break;
  1356. case BLKGETSIZE:
  1357. return put_user(unit[drive].blocks,(unsigned long *)param);
  1358. break;
  1359. case BLKGETSIZE64:
  1360. return put_user((u64)unit[drive].blocks << 9, (u64 *)param);
  1361. break;
  1362. case FDSETPRM:
  1363. case FDDEFPRM:
  1364. return -EINVAL;
  1365. case FDFLUSH: /* unconditionally, even if not needed */
  1366. del_timer (flush_track_timer + drive);
  1367. non_int_flush_track(drive);
  1368. break;
  1369. #ifdef RAW_IOCTL
  1370. case IOCTL_RAW_TRACK:
  1371. if (copy_to_user((void *)param, raw_buf,
  1372.  unit[drive].type->read_size))
  1373. return -EFAULT;
  1374. else
  1375. return unit[drive].type->read_size;
  1376. #endif
  1377. default:
  1378. printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.",
  1379.        cmd, drive);
  1380. return -ENOSYS;
  1381. }
  1382. return 0;
  1383. }
  1384. static void fd_probe(int dev)
  1385. {
  1386. unsigned long code;
  1387. int type;
  1388. int drive;
  1389. drive = dev & 3;
  1390. code = fd_get_drive_id(drive);
  1391. /* get drive type */
  1392. for (type = 0; type < num_dr_types; type++)
  1393. if (drive_types[type].code == code)
  1394. break;
  1395. if (type >= num_dr_types) {
  1396. printk(KERN_WARNING "fd_probe: unsupported drive type "
  1397.        "%08lx foundn", code);
  1398. unit[drive].type = &drive_types[num_dr_types-1]; /* FD_NODRIVE */
  1399. return;
  1400. }
  1401. unit[drive].type = drive_types + type;
  1402. unit[drive].track = -1;
  1403. unit[drive].disk = -1;
  1404. unit[drive].motor = 0;
  1405. unit[drive].busy = 0;
  1406. unit[drive].status = -1;
  1407. }
  1408. /*
  1409.  * floppy_open check for aliasing (/dev/fd0 can be the same as
  1410.  * /dev/PS0 etc), and disallows simultaneous access to the same
  1411.  * drive with different device numbers.
  1412.  */
  1413. static int floppy_open(struct inode *inode, struct file *filp)
  1414. {
  1415. int drive;
  1416. int old_dev;
  1417. int system;
  1418. unsigned long flags;
  1419. drive = MINOR(inode->i_rdev) & 3;
  1420. old_dev = fd_device[drive];
  1421. if (fd_ref[drive])
  1422. if (old_dev != inode->i_rdev)
  1423. return -EBUSY;
  1424. if (unit[drive].type->code == FD_NODRIVE)
  1425. return -ENODEV;
  1426. if (filp && filp->f_mode & 3) {
  1427. check_disk_change(inode->i_rdev);
  1428. if (filp->f_mode & 2 ) {
  1429. int wrprot;
  1430. get_fdc(drive);
  1431. fd_select (drive);
  1432. wrprot = !(ciaa.pra & DSKPROT);
  1433. fd_deselect (drive);
  1434. rel_fdc();
  1435. if (wrprot)
  1436. return -EROFS;
  1437. }
  1438. }
  1439. save_flags(flags);
  1440. cli();
  1441. fd_ref[drive]++;
  1442. fd_device[drive] = inode->i_rdev;
  1443. #ifdef MODULE
  1444. if (unit[drive].motor == 0)
  1445. MOD_INC_USE_COUNT;
  1446. #endif
  1447. restore_flags(flags);
  1448. if (old_dev && old_dev != inode->i_rdev)
  1449. invalidate_buffers(old_dev);
  1450. system=(inode->i_rdev & 4)>>2;
  1451. unit[drive].dtype=&data_types[system];
  1452. unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*
  1453. data_types[system].sects*unit[drive].type->sect_mult;
  1454. floppy_sizes[MINOR(inode->i_rdev)] = unit[drive].blocks >> 1;
  1455. printk(KERN_INFO "fd%d: accessing %s-disk with %s-layoutn",drive,
  1456.        unit[drive].type->name, data_types[system].name);
  1457. return 0;
  1458. }
  1459. static int floppy_release(struct inode * inode, struct file * filp)
  1460. {
  1461. int drive = MINOR(inode->i_rdev) & 3;
  1462. if (unit[drive].dirty == 1) {
  1463. del_timer (flush_track_timer + drive);
  1464. non_int_flush_track (drive);
  1465. }
  1466.   
  1467. if (!fd_ref[drive]--) {
  1468. printk(KERN_CRIT "floppy_release with fd_ref == 0");
  1469. fd_ref[drive] = 0;
  1470. }
  1471. #ifdef MODULE
  1472. /* the mod_use counter is handled this way */
  1473. floppy_off (drive | 0x40000000);
  1474. #endif
  1475. return 0;
  1476. }
  1477. /*
  1478.  * floppy-change is never called from an interrupt, so we can relax a bit
  1479.  * here, sleep etc. Note that floppy-on tries to set current_DOR to point
  1480.  * to the desired drive, but it will probably not survive the sleep if
  1481.  * several floppies are used at the same time: thus the loop.
  1482.  */
  1483. static int amiga_floppy_change(kdev_t dev)
  1484. {
  1485. int drive = MINOR(dev) & 3;
  1486. int changed;
  1487. static int first_time = 1;
  1488. if (MAJOR(dev) != MAJOR_NR) {
  1489. printk(KERN_CRIT "floppy_change: not a floppyn");
  1490. return 0;
  1491. }
  1492. if (first_time)
  1493. changed = first_time--;
  1494. else {
  1495. get_fdc(drive);
  1496. fd_select (drive);
  1497. changed = !(ciaa.pra & DSKCHANGE);
  1498. fd_deselect (drive);
  1499. rel_fdc();
  1500. }
  1501. if (changed) {
  1502. fd_probe(drive);
  1503. unit[drive].track = -1;
  1504. unit[drive].dirty = 0;
  1505. writepending = 0; /* if this was true before, too bad! */
  1506. writefromint = 0;
  1507. return 1;
  1508. }
  1509. return 0;
  1510. }
  1511. static struct block_device_operations floppy_fops = {
  1512. owner: THIS_MODULE,
  1513. open: floppy_open,
  1514. release: floppy_release,
  1515. ioctl: fd_ioctl,
  1516. check_media_change: amiga_floppy_change,
  1517. };
  1518. void __init amiga_floppy_setup (char *str, int *ints)
  1519. {
  1520. printk (KERN_INFO "amiflop: Setting default df0 to %xn", ints[1]);
  1521. fd_def_df0 = ints[1];
  1522. }
  1523. static int __init fd_probe_drives(void)
  1524. {
  1525. int drive,drives,nomem;
  1526. printk(KERN_INFO "FD: probing unitsn" KERN_INFO "found ");
  1527. drives=0;
  1528. nomem=0;
  1529. for(drive=0;drive<FD_MAX_UNITS;drive++) {
  1530. fd_probe(drive);
  1531. if (unit[drive].type->code != FD_NODRIVE) {
  1532. drives++;
  1533. if ((unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL)) == NULL) {
  1534. printk("no mem for ");
  1535. unit[drive].type = &drive_types[num_dr_types - 1]; /* FD_NODRIVE */
  1536. drives--;
  1537. nomem = 1;
  1538. }
  1539. printk("fd%d ",drive);
  1540. }
  1541. }
  1542. if ((drives > 0) || (nomem == 0)) {
  1543. if (drives == 0)
  1544. printk("no drives");
  1545. printk("n");
  1546. return drives;
  1547. }
  1548. printk("n");
  1549. return -ENOMEM;
  1550. }
  1551. int __init amiga_floppy_init(void)
  1552. {
  1553. int i;
  1554. if (!AMIGAHW_PRESENT(AMI_FLOPPY))
  1555. return -ENXIO;
  1556. if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
  1557. printk("fd: Unable to get major %d for floppyn",MAJOR_NR);
  1558. return -EBUSY;
  1559. }
  1560. /*
  1561.  *  We request DSKPTR, DSKLEN and DSKDATA only, because the other
  1562.  *  floppy registers are too spreaded over the custom register space
  1563.  */
  1564. if (!request_mem_region(CUSTOM_PHYSADDR+0x20, 8, "amiflop [Paula]")) {
  1565. printk("fd: cannot get floppy registersn");
  1566. unregister_blkdev(MAJOR_NR,"fd");
  1567. return -EBUSY;
  1568. }
  1569. if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) ==
  1570.     NULL) {
  1571. printk("fd: cannot get chip mem buffern");
  1572. release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
  1573. unregister_blkdev(MAJOR_NR,"fd");
  1574. return -ENOMEM;
  1575. }
  1576. if (request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) {
  1577. printk("fd: cannot get irq for dman");
  1578. amiga_chip_free(raw_buf);
  1579. release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
  1580. unregister_blkdev(MAJOR_NR,"fd");
  1581. return -EBUSY;
  1582. }
  1583. if (request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL)) {
  1584. printk("fd: cannot get irq for timern");
  1585. free_irq(IRQ_AMIGA_DSKBLK, NULL);
  1586. amiga_chip_free(raw_buf);
  1587. release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
  1588. unregister_blkdev(MAJOR_NR,"fd");
  1589. return -EBUSY;
  1590. }
  1591. if (fd_probe_drives() < 1) { /* No usable drives */
  1592. free_irq(IRQ_AMIGA_CIAA_TB, NULL);
  1593. free_irq(IRQ_AMIGA_DSKBLK, NULL);
  1594. amiga_chip_free(raw_buf);
  1595. release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
  1596. unregister_blkdev(MAJOR_NR,"fd");
  1597. return -ENXIO;
  1598. }
  1599. /* initialize variables */
  1600. init_timer(&motor_on_timer);
  1601. motor_on_timer.expires = 0;
  1602. motor_on_timer.data = 0;
  1603. motor_on_timer.function = motor_on_callback;
  1604. for (i = 0; i < FD_MAX_UNITS; i++) {
  1605. init_timer(&motor_off_timer[i]);
  1606. motor_off_timer[i].expires = 0;
  1607. motor_off_timer[i].data = i|0x80000000;
  1608. motor_off_timer[i].function = fd_motor_off;
  1609. init_timer(&flush_track_timer[i]);
  1610. flush_track_timer[i].expires = 0;
  1611. flush_track_timer[i].data = i;
  1612. flush_track_timer[i].function = flush_track_callback;
  1613. unit[i].track = -1;
  1614. }
  1615. init_timer(&post_write_timer);
  1616. post_write_timer.expires = 0;
  1617. post_write_timer.data = 0;
  1618. post_write_timer.function = post_write;
  1619.   
  1620. blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
  1621. blksize_size[MAJOR_NR] = floppy_blocksizes;
  1622. blk_size[MAJOR_NR] = floppy_sizes;
  1623. for (i = 0; i < 128; i++)
  1624. mfmdecode[i]=255;
  1625. for (i = 0; i < 16; i++)
  1626. mfmdecode[mfmencode[i]]=i;
  1627. /* make sure that disk DMA is enabled */
  1628. custom.dmacon = DMAF_SETCLR | DMAF_DISK;
  1629. /* init ms timer */
  1630. ciaa.crb = 8; /* one-shot, stop */
  1631. (void)do_floppy; /* avoid warning about unused variable */
  1632. return 0;
  1633. }
  1634. #ifdef MODULE
  1635. #include <linux/version.h>
  1636. int init_module(void)
  1637. {
  1638. if (!MACH_IS_AMIGA)
  1639. return -ENXIO;
  1640. return amiga_floppy_init();
  1641. }
  1642. void cleanup_module(void)
  1643. {
  1644. int i;
  1645. for( i = 0; i < FD_MAX_UNITS; i++)
  1646. if (unit[i].type->code != FD_NODRIVE)
  1647. kfree(unit[i].trackbuf);
  1648. free_irq(IRQ_AMIGA_CIAA_TB, NULL);
  1649. free_irq(IRQ_AMIGA_DSKBLK, NULL);
  1650. custom.dmacon = DMAF_DISK; /* disable DMA */
  1651. amiga_chip_free(raw_buf);
  1652. blk_size[MAJOR_NR] = NULL;
  1653. blksize_size[MAJOR_NR] = NULL;
  1654. blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
  1655. release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
  1656. unregister_blkdev(MAJOR_NR, "fd");
  1657. }
  1658. #endif