cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

amiflop.c (51520B)


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