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

swim.c (20062B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Driver for SWIM (Sander Woz Integrated Machine) floppy controller
      4 *
      5 * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
      6 *
      7 * based on Alastair Bridgewater SWIM analysis, 2001
      8 * based on SWIM3 driver (c) Paul Mackerras, 1996
      9 * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
     10 *
     11 * 2004-08-21 (lv) - Initial implementation
     12 * 2008-10-30 (lv) - Port to 2.6
     13 */
     14
     15#include <linux/module.h>
     16#include <linux/fd.h>
     17#include <linux/slab.h>
     18#include <linux/blk-mq.h>
     19#include <linux/major.h>
     20#include <linux/mutex.h>
     21#include <linux/hdreg.h>
     22#include <linux/kernel.h>
     23#include <linux/delay.h>
     24#include <linux/platform_device.h>
     25
     26#include <asm/mac_via.h>
     27
     28#define CARDNAME "swim"
     29
     30struct sector_header {
     31	unsigned char side;
     32	unsigned char track;
     33	unsigned char sector;
     34	unsigned char size;
     35	unsigned char crc0;
     36	unsigned char crc1;
     37} __attribute__((packed));
     38
     39#define DRIVER_VERSION "Version 0.2 (2008-10-30)"
     40
     41#define REG(x)	unsigned char x, x ## _pad[0x200 - 1];
     42
     43struct swim {
     44	REG(write_data)
     45	REG(write_mark)
     46	REG(write_CRC)
     47	REG(write_parameter)
     48	REG(write_phase)
     49	REG(write_setup)
     50	REG(write_mode0)
     51	REG(write_mode1)
     52
     53	REG(read_data)
     54	REG(read_mark)
     55	REG(read_error)
     56	REG(read_parameter)
     57	REG(read_phase)
     58	REG(read_setup)
     59	REG(read_status)
     60	REG(read_handshake)
     61} __attribute__((packed));
     62
     63#define swim_write(base, reg, v) 	out_8(&(base)->write_##reg, (v))
     64#define swim_read(base, reg)		in_8(&(base)->read_##reg)
     65
     66/* IWM registers */
     67
     68struct iwm {
     69	REG(ph0L)
     70	REG(ph0H)
     71	REG(ph1L)
     72	REG(ph1H)
     73	REG(ph2L)
     74	REG(ph2H)
     75	REG(ph3L)
     76	REG(ph3H)
     77	REG(mtrOff)
     78	REG(mtrOn)
     79	REG(intDrive)
     80	REG(extDrive)
     81	REG(q6L)
     82	REG(q6H)
     83	REG(q7L)
     84	REG(q7H)
     85} __attribute__((packed));
     86
     87#define iwm_write(base, reg, v) 	out_8(&(base)->reg, (v))
     88#define iwm_read(base, reg)		in_8(&(base)->reg)
     89
     90/* bits in phase register */
     91
     92#define SEEK_POSITIVE	0x070
     93#define SEEK_NEGATIVE	0x074
     94#define STEP		0x071
     95#define MOTOR_ON	0x072
     96#define MOTOR_OFF	0x076
     97#define INDEX		0x073
     98#define EJECT		0x077
     99#define SETMFM		0x171
    100#define SETGCR		0x175
    101
    102#define RELAX		0x033
    103#define LSTRB		0x008
    104
    105#define CA_MASK		0x077
    106
    107/* Select values for swim_select and swim_readbit */
    108
    109#define READ_DATA_0	0x074
    110#define ONEMEG_DRIVE	0x075
    111#define SINGLE_SIDED	0x076
    112#define DRIVE_PRESENT	0x077
    113#define DISK_IN		0x170
    114#define WRITE_PROT	0x171
    115#define TRACK_ZERO	0x172
    116#define TACHO		0x173
    117#define READ_DATA_1	0x174
    118#define GCR_MODE	0x175
    119#define SEEK_COMPLETE	0x176
    120#define TWOMEG_MEDIA	0x177
    121
    122/* Bits in handshake register */
    123
    124#define MARK_BYTE	0x01
    125#define CRC_ZERO	0x02
    126#define RDDATA		0x04
    127#define SENSE		0x08
    128#define MOTEN		0x10
    129#define ERROR		0x20
    130#define DAT2BYTE	0x40
    131#define DAT1BYTE	0x80
    132
    133/* bits in setup register */
    134
    135#define S_INV_WDATA	0x01
    136#define S_3_5_SELECT	0x02
    137#define S_GCR		0x04
    138#define S_FCLK_DIV2	0x08
    139#define S_ERROR_CORR	0x10
    140#define S_IBM_DRIVE	0x20
    141#define S_GCR_WRITE	0x40
    142#define S_TIMEOUT	0x80
    143
    144/* bits in mode register */
    145
    146#define CLFIFO		0x01
    147#define ENBL1		0x02
    148#define ENBL2		0x04
    149#define ACTION		0x08
    150#define WRITE_MODE	0x10
    151#define HEDSEL		0x20
    152#define MOTON		0x80
    153
    154/*----------------------------------------------------------------------------*/
    155
    156enum drive_location {
    157	INTERNAL_DRIVE = 0x02,
    158	EXTERNAL_DRIVE = 0x04,
    159};
    160
    161enum media_type {
    162	DD_MEDIA,
    163	HD_MEDIA,
    164};
    165
    166struct floppy_state {
    167
    168	/* physical properties */
    169
    170	enum drive_location location;	/* internal or external drive */
    171	int		 head_number;	/* single- or double-sided drive */
    172
    173	/* media */
    174
    175	int		 disk_in;
    176	int		 ejected;
    177	enum media_type	 type;
    178	int		 write_protected;
    179
    180	int		 total_secs;
    181	int		 secpercyl;
    182	int		 secpertrack;
    183
    184	/* in-use information */
    185
    186	int		track;
    187	int		ref_count;
    188	bool registered;
    189
    190	struct gendisk *disk;
    191	struct blk_mq_tag_set tag_set;
    192
    193	/* parent controller */
    194
    195	struct swim_priv *swd;
    196};
    197
    198enum motor_action {
    199	OFF,
    200	ON,
    201};
    202
    203enum head {
    204	LOWER_HEAD = 0,
    205	UPPER_HEAD = 1,
    206};
    207
    208#define FD_MAX_UNIT	2
    209
    210struct swim_priv {
    211	struct swim __iomem *base;
    212	spinlock_t lock;
    213	int floppy_count;
    214	struct floppy_state unit[FD_MAX_UNIT];
    215};
    216
    217extern int swim_read_sector_header(struct swim __iomem *base,
    218				   struct sector_header *header);
    219extern int swim_read_sector_data(struct swim __iomem *base,
    220				 unsigned char *data);
    221
    222static DEFINE_MUTEX(swim_mutex);
    223static inline void set_swim_mode(struct swim __iomem *base, int enable)
    224{
    225	struct iwm __iomem *iwm_base;
    226	unsigned long flags;
    227
    228	if (!enable) {
    229		swim_write(base, mode0, 0xf8);
    230		return;
    231	}
    232
    233	iwm_base = (struct iwm __iomem *)base;
    234	local_irq_save(flags);
    235
    236	iwm_read(iwm_base, q7L);
    237	iwm_read(iwm_base, mtrOff);
    238	iwm_read(iwm_base, q6H);
    239
    240	iwm_write(iwm_base, q7H, 0x57);
    241	iwm_write(iwm_base, q7H, 0x17);
    242	iwm_write(iwm_base, q7H, 0x57);
    243	iwm_write(iwm_base, q7H, 0x57);
    244
    245	local_irq_restore(flags);
    246}
    247
    248static inline int get_swim_mode(struct swim __iomem *base)
    249{
    250	unsigned long flags;
    251
    252	local_irq_save(flags);
    253
    254	swim_write(base, phase, 0xf5);
    255	if (swim_read(base, phase) != 0xf5)
    256		goto is_iwm;
    257	swim_write(base, phase, 0xf6);
    258	if (swim_read(base, phase) != 0xf6)
    259		goto is_iwm;
    260	swim_write(base, phase, 0xf7);
    261	if (swim_read(base, phase) != 0xf7)
    262		goto is_iwm;
    263	local_irq_restore(flags);
    264	return 1;
    265is_iwm:
    266	local_irq_restore(flags);
    267	return 0;
    268}
    269
    270static inline void swim_select(struct swim __iomem *base, int sel)
    271{
    272	swim_write(base, phase, RELAX);
    273
    274	via1_set_head(sel & 0x100);
    275
    276	swim_write(base, phase, sel & CA_MASK);
    277}
    278
    279static inline void swim_action(struct swim __iomem *base, int action)
    280{
    281	unsigned long flags;
    282
    283	local_irq_save(flags);
    284
    285	swim_select(base, action);
    286	udelay(1);
    287	swim_write(base, phase, (LSTRB<<4) | LSTRB);
    288	udelay(1);
    289	swim_write(base, phase, (LSTRB<<4) | ((~LSTRB) & 0x0F));
    290	udelay(1);
    291
    292	local_irq_restore(flags);
    293}
    294
    295static inline int swim_readbit(struct swim __iomem *base, int bit)
    296{
    297	int stat;
    298
    299	swim_select(base, bit);
    300
    301	udelay(10);
    302
    303	stat = swim_read(base, handshake);
    304
    305	return (stat & SENSE) == 0;
    306}
    307
    308static inline void swim_drive(struct swim __iomem *base,
    309			      enum drive_location location)
    310{
    311	if (location == INTERNAL_DRIVE) {
    312		swim_write(base, mode0, EXTERNAL_DRIVE); /* clear drive 1 bit */
    313		swim_write(base, mode1, INTERNAL_DRIVE); /* set drive 0 bit */
    314	} else if (location == EXTERNAL_DRIVE) {
    315		swim_write(base, mode0, INTERNAL_DRIVE); /* clear drive 0 bit */
    316		swim_write(base, mode1, EXTERNAL_DRIVE); /* set drive 1 bit */
    317	}
    318}
    319
    320static inline void swim_motor(struct swim __iomem *base,
    321			      enum motor_action action)
    322{
    323	if (action == ON) {
    324		int i;
    325
    326		swim_action(base, MOTOR_ON);
    327
    328		for (i = 0; i < 2*HZ; i++) {
    329			swim_select(base, RELAX);
    330			if (swim_readbit(base, MOTOR_ON))
    331				break;
    332			set_current_state(TASK_INTERRUPTIBLE);
    333			schedule_timeout(1);
    334		}
    335	} else if (action == OFF) {
    336		swim_action(base, MOTOR_OFF);
    337		swim_select(base, RELAX);
    338	}
    339}
    340
    341static inline void swim_eject(struct swim __iomem *base)
    342{
    343	int i;
    344
    345	swim_action(base, EJECT);
    346
    347	for (i = 0; i < 2*HZ; i++) {
    348		swim_select(base, RELAX);
    349		if (!swim_readbit(base, DISK_IN))
    350			break;
    351		set_current_state(TASK_INTERRUPTIBLE);
    352		schedule_timeout(1);
    353	}
    354	swim_select(base, RELAX);
    355}
    356
    357static inline void swim_head(struct swim __iomem *base, enum head head)
    358{
    359	/* wait drive is ready */
    360
    361	if (head == UPPER_HEAD)
    362		swim_select(base, READ_DATA_1);
    363	else if (head == LOWER_HEAD)
    364		swim_select(base, READ_DATA_0);
    365}
    366
    367static inline int swim_step(struct swim __iomem *base)
    368{
    369	int wait;
    370
    371	swim_action(base, STEP);
    372
    373	for (wait = 0; wait < HZ; wait++) {
    374
    375		set_current_state(TASK_INTERRUPTIBLE);
    376		schedule_timeout(1);
    377
    378		swim_select(base, RELAX);
    379		if (!swim_readbit(base, STEP))
    380			return 0;
    381	}
    382	return -1;
    383}
    384
    385static inline int swim_track00(struct swim __iomem *base)
    386{
    387	int try;
    388
    389	swim_action(base, SEEK_NEGATIVE);
    390
    391	for (try = 0; try < 100; try++) {
    392
    393		swim_select(base, RELAX);
    394		if (swim_readbit(base, TRACK_ZERO))
    395			break;
    396
    397		if (swim_step(base))
    398			return -1;
    399	}
    400
    401	if (swim_readbit(base, TRACK_ZERO))
    402		return 0;
    403
    404	return -1;
    405}
    406
    407static inline int swim_seek(struct swim __iomem *base, int step)
    408{
    409	if (step == 0)
    410		return 0;
    411
    412	if (step < 0) {
    413		swim_action(base, SEEK_NEGATIVE);
    414		step = -step;
    415	} else
    416		swim_action(base, SEEK_POSITIVE);
    417
    418	for ( ; step > 0; step--) {
    419		if (swim_step(base))
    420			return -1;
    421	}
    422
    423	return 0;
    424}
    425
    426static inline int swim_track(struct floppy_state *fs,  int track)
    427{
    428	struct swim __iomem *base = fs->swd->base;
    429	int ret;
    430
    431	ret = swim_seek(base, track - fs->track);
    432
    433	if (ret == 0)
    434		fs->track = track;
    435	else {
    436		swim_track00(base);
    437		fs->track = 0;
    438	}
    439
    440	return ret;
    441}
    442
    443static int floppy_eject(struct floppy_state *fs)
    444{
    445	struct swim __iomem *base = fs->swd->base;
    446
    447	swim_drive(base, fs->location);
    448	swim_motor(base, OFF);
    449	swim_eject(base);
    450
    451	fs->disk_in = 0;
    452	fs->ejected = 1;
    453
    454	return 0;
    455}
    456
    457static inline int swim_read_sector(struct floppy_state *fs,
    458				   int side, int track,
    459				   int sector, unsigned char *buffer)
    460{
    461	struct swim __iomem *base = fs->swd->base;
    462	unsigned long flags;
    463	struct sector_header header;
    464	int ret = -1;
    465	short i;
    466
    467	swim_track(fs, track);
    468
    469	swim_write(base, mode1, MOTON);
    470	swim_head(base, side);
    471	swim_write(base, mode0, side);
    472
    473	local_irq_save(flags);
    474	for (i = 0; i < 36; i++) {
    475		ret = swim_read_sector_header(base, &header);
    476		if (!ret && (header.sector == sector)) {
    477			/* found */
    478
    479			ret = swim_read_sector_data(base, buffer);
    480			break;
    481		}
    482	}
    483	local_irq_restore(flags);
    484
    485	swim_write(base, mode0, MOTON);
    486
    487	if ((header.side != side)  || (header.track != track) ||
    488	     (header.sector != sector))
    489		return 0;
    490
    491	return ret;
    492}
    493
    494static blk_status_t floppy_read_sectors(struct floppy_state *fs,
    495			       int req_sector, int sectors_nb,
    496			       unsigned char *buffer)
    497{
    498	struct swim __iomem *base = fs->swd->base;
    499	int ret;
    500	int side, track, sector;
    501	int i, try;
    502
    503
    504	swim_drive(base, fs->location);
    505	for (i = req_sector; i < req_sector + sectors_nb; i++) {
    506		int x;
    507		track = i / fs->secpercyl;
    508		x = i % fs->secpercyl;
    509		side = x / fs->secpertrack;
    510		sector = x % fs->secpertrack + 1;
    511
    512		try = 5;
    513		do {
    514			ret = swim_read_sector(fs, side, track, sector,
    515						buffer);
    516			if (try-- == 0)
    517				return BLK_STS_IOERR;
    518		} while (ret != 512);
    519
    520		buffer += ret;
    521	}
    522
    523	return 0;
    524}
    525
    526static blk_status_t swim_queue_rq(struct blk_mq_hw_ctx *hctx,
    527				  const struct blk_mq_queue_data *bd)
    528{
    529	struct floppy_state *fs = hctx->queue->queuedata;
    530	struct swim_priv *swd = fs->swd;
    531	struct request *req = bd->rq;
    532	blk_status_t err;
    533
    534	if (!spin_trylock_irq(&swd->lock))
    535		return BLK_STS_DEV_RESOURCE;
    536
    537	blk_mq_start_request(req);
    538
    539	if (!fs->disk_in || rq_data_dir(req) == WRITE) {
    540		err = BLK_STS_IOERR;
    541		goto out;
    542	}
    543
    544	do {
    545		err = floppy_read_sectors(fs, blk_rq_pos(req),
    546					  blk_rq_cur_sectors(req),
    547					  bio_data(req->bio));
    548	} while (blk_update_request(req, err, blk_rq_cur_bytes(req)));
    549	__blk_mq_end_request(req, err);
    550
    551	err = BLK_STS_OK;
    552out:
    553	spin_unlock_irq(&swd->lock);
    554	return err;
    555
    556}
    557
    558static struct floppy_struct floppy_type[4] = {
    559	{    0,  0, 0,  0, 0, 0x00, 0x00, 0x00, 0x00, NULL }, /* no testing   */
    560	{  720,  9, 1, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 360KB SS 3.5"*/
    561	{ 1440,  9, 2, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 720KB 3.5"   */
    562	{ 2880, 18, 2, 80, 0, 0x1B, 0x00, 0xCF, 0x6C, NULL }, /* 1.44MB 3.5"  */
    563};
    564
    565static int get_floppy_geometry(struct floppy_state *fs, int type,
    566			       struct floppy_struct **g)
    567{
    568	if (type >= ARRAY_SIZE(floppy_type))
    569		return -EINVAL;
    570
    571	if (type)
    572		*g = &floppy_type[type];
    573	else if (fs->type == HD_MEDIA) /* High-Density media */
    574		*g = &floppy_type[3];
    575	else if (fs->head_number == 2) /* double-sided */
    576		*g = &floppy_type[2];
    577	else
    578		*g = &floppy_type[1];
    579
    580	return 0;
    581}
    582
    583static void setup_medium(struct floppy_state *fs)
    584{
    585	struct swim __iomem *base = fs->swd->base;
    586
    587	if (swim_readbit(base, DISK_IN)) {
    588		struct floppy_struct *g;
    589		fs->disk_in = 1;
    590		fs->write_protected = swim_readbit(base, WRITE_PROT);
    591
    592		if (swim_track00(base))
    593			printk(KERN_ERR
    594				"SWIM: cannot move floppy head to track 0\n");
    595
    596		swim_track00(base);
    597
    598		fs->type = swim_readbit(base, TWOMEG_MEDIA) ?
    599			HD_MEDIA : DD_MEDIA;
    600		fs->head_number = swim_readbit(base, SINGLE_SIDED) ? 1 : 2;
    601		get_floppy_geometry(fs, 0, &g);
    602		fs->total_secs = g->size;
    603		fs->secpercyl = g->head * g->sect;
    604		fs->secpertrack = g->sect;
    605		fs->track = 0;
    606	} else {
    607		fs->disk_in = 0;
    608	}
    609}
    610
    611static int floppy_open(struct block_device *bdev, fmode_t mode)
    612{
    613	struct floppy_state *fs = bdev->bd_disk->private_data;
    614	struct swim __iomem *base = fs->swd->base;
    615	int err;
    616
    617	if (fs->ref_count == -1 || (fs->ref_count && mode & FMODE_EXCL))
    618		return -EBUSY;
    619
    620	if (mode & FMODE_EXCL)
    621		fs->ref_count = -1;
    622	else
    623		fs->ref_count++;
    624
    625	swim_write(base, setup, S_IBM_DRIVE  | S_FCLK_DIV2);
    626	udelay(10);
    627	swim_drive(base, fs->location);
    628	swim_motor(base, ON);
    629	swim_action(base, SETMFM);
    630	if (fs->ejected)
    631		setup_medium(fs);
    632	if (!fs->disk_in) {
    633		err = -ENXIO;
    634		goto out;
    635	}
    636
    637	set_capacity(fs->disk, fs->total_secs);
    638
    639	if (mode & FMODE_NDELAY)
    640		return 0;
    641
    642	if (mode & (FMODE_READ|FMODE_WRITE)) {
    643		if (bdev_check_media_change(bdev) && fs->disk_in)
    644			fs->ejected = 0;
    645		if ((mode & FMODE_WRITE) && fs->write_protected) {
    646			err = -EROFS;
    647			goto out;
    648		}
    649	}
    650	return 0;
    651out:
    652	if (fs->ref_count < 0)
    653		fs->ref_count = 0;
    654	else if (fs->ref_count > 0)
    655		--fs->ref_count;
    656
    657	if (fs->ref_count == 0)
    658		swim_motor(base, OFF);
    659	return err;
    660}
    661
    662static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode)
    663{
    664	int ret;
    665
    666	mutex_lock(&swim_mutex);
    667	ret = floppy_open(bdev, mode);
    668	mutex_unlock(&swim_mutex);
    669
    670	return ret;
    671}
    672
    673static void floppy_release(struct gendisk *disk, fmode_t mode)
    674{
    675	struct floppy_state *fs = disk->private_data;
    676	struct swim __iomem *base = fs->swd->base;
    677
    678	mutex_lock(&swim_mutex);
    679	if (fs->ref_count < 0)
    680		fs->ref_count = 0;
    681	else if (fs->ref_count > 0)
    682		--fs->ref_count;
    683
    684	if (fs->ref_count == 0)
    685		swim_motor(base, OFF);
    686	mutex_unlock(&swim_mutex);
    687}
    688
    689static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
    690			unsigned int cmd, unsigned long param)
    691{
    692	struct floppy_state *fs = bdev->bd_disk->private_data;
    693	int err;
    694
    695	if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
    696			return -EPERM;
    697
    698	switch (cmd) {
    699	case FDEJECT:
    700		if (fs->ref_count != 1)
    701			return -EBUSY;
    702		mutex_lock(&swim_mutex);
    703		err = floppy_eject(fs);
    704		mutex_unlock(&swim_mutex);
    705		return err;
    706
    707	case FDGETPRM:
    708		if (copy_to_user((void __user *) param, (void *) &floppy_type,
    709				 sizeof(struct floppy_struct)))
    710			return -EFAULT;
    711		return 0;
    712	}
    713	return -ENOTTY;
    714}
    715
    716static int floppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
    717{
    718	struct floppy_state *fs = bdev->bd_disk->private_data;
    719	struct floppy_struct *g;
    720	int ret;
    721
    722	ret = get_floppy_geometry(fs, 0, &g);
    723	if (ret)
    724		return ret;
    725
    726	geo->heads = g->head;
    727	geo->sectors = g->sect;
    728	geo->cylinders = g->track;
    729
    730	return 0;
    731}
    732
    733static unsigned int floppy_check_events(struct gendisk *disk,
    734					unsigned int clearing)
    735{
    736	struct floppy_state *fs = disk->private_data;
    737
    738	return fs->ejected ? DISK_EVENT_MEDIA_CHANGE : 0;
    739}
    740
    741static const struct block_device_operations floppy_fops = {
    742	.owner		 = THIS_MODULE,
    743	.open		 = floppy_unlocked_open,
    744	.release	 = floppy_release,
    745	.ioctl		 = floppy_ioctl,
    746	.getgeo		 = floppy_getgeo,
    747	.check_events	 = floppy_check_events,
    748};
    749
    750static int swim_add_floppy(struct swim_priv *swd, enum drive_location location)
    751{
    752	struct floppy_state *fs = &swd->unit[swd->floppy_count];
    753	struct swim __iomem *base = swd->base;
    754
    755	fs->location = location;
    756
    757	swim_drive(base, location);
    758
    759	swim_motor(base, OFF);
    760
    761	fs->type = HD_MEDIA;
    762	fs->head_number = 2;
    763
    764	fs->ref_count = 0;
    765	fs->ejected = 1;
    766
    767	swd->floppy_count++;
    768
    769	return 0;
    770}
    771
    772static const struct blk_mq_ops swim_mq_ops = {
    773	.queue_rq = swim_queue_rq,
    774};
    775
    776static void swim_cleanup_floppy_disk(struct floppy_state *fs)
    777{
    778	struct gendisk *disk = fs->disk;
    779
    780	if (!disk)
    781		return;
    782
    783	if (fs->registered)
    784		del_gendisk(fs->disk);
    785
    786	blk_cleanup_disk(disk);
    787	blk_mq_free_tag_set(&fs->tag_set);
    788}
    789
    790static int swim_floppy_init(struct swim_priv *swd)
    791{
    792	int err;
    793	int drive;
    794	struct swim __iomem *base = swd->base;
    795
    796	/* scan floppy drives */
    797
    798	swim_drive(base, INTERNAL_DRIVE);
    799	if (swim_readbit(base, DRIVE_PRESENT) &&
    800	    !swim_readbit(base, ONEMEG_DRIVE))
    801		swim_add_floppy(swd, INTERNAL_DRIVE);
    802	swim_drive(base, EXTERNAL_DRIVE);
    803	if (swim_readbit(base, DRIVE_PRESENT) &&
    804	    !swim_readbit(base, ONEMEG_DRIVE))
    805		swim_add_floppy(swd, EXTERNAL_DRIVE);
    806
    807	/* register floppy drives */
    808
    809	err = register_blkdev(FLOPPY_MAJOR, "fd");
    810	if (err) {
    811		printk(KERN_ERR "Unable to get major %d for SWIM floppy\n",
    812		       FLOPPY_MAJOR);
    813		return -EBUSY;
    814	}
    815
    816	spin_lock_init(&swd->lock);
    817
    818	for (drive = 0; drive < swd->floppy_count; drive++) {
    819		err = blk_mq_alloc_sq_tag_set(&swd->unit[drive].tag_set,
    820				&swim_mq_ops, 2, BLK_MQ_F_SHOULD_MERGE);
    821		if (err)
    822			goto exit_put_disks;
    823
    824		swd->unit[drive].disk =
    825			blk_mq_alloc_disk(&swd->unit[drive].tag_set,
    826					  &swd->unit[drive]);
    827		if (IS_ERR(swd->unit[drive].disk)) {
    828			blk_mq_free_tag_set(&swd->unit[drive].tag_set);
    829			err = PTR_ERR(swd->unit[drive].disk);
    830			goto exit_put_disks;
    831		}
    832
    833		swd->unit[drive].swd = swd;
    834	}
    835
    836	for (drive = 0; drive < swd->floppy_count; drive++) {
    837		swd->unit[drive].disk->flags = GENHD_FL_REMOVABLE;
    838		swd->unit[drive].disk->major = FLOPPY_MAJOR;
    839		swd->unit[drive].disk->first_minor = drive;
    840		swd->unit[drive].disk->minors = 1;
    841		sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive);
    842		swd->unit[drive].disk->fops = &floppy_fops;
    843		swd->unit[drive].disk->flags |= GENHD_FL_NO_PART;
    844		swd->unit[drive].disk->events = DISK_EVENT_MEDIA_CHANGE;
    845		swd->unit[drive].disk->private_data = &swd->unit[drive];
    846		set_capacity(swd->unit[drive].disk, 2880);
    847		err = add_disk(swd->unit[drive].disk);
    848		if (err)
    849			goto exit_put_disks;
    850		swd->unit[drive].registered = true;
    851	}
    852
    853	return 0;
    854
    855exit_put_disks:
    856	unregister_blkdev(FLOPPY_MAJOR, "fd");
    857	do {
    858		swim_cleanup_floppy_disk(&swd->unit[drive]);
    859	} while (drive--);
    860	return err;
    861}
    862
    863static int swim_probe(struct platform_device *dev)
    864{
    865	struct resource *res;
    866	struct swim __iomem *swim_base;
    867	struct swim_priv *swd;
    868	int ret;
    869
    870	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
    871	if (!res) {
    872		ret = -ENODEV;
    873		goto out;
    874	}
    875
    876	if (!request_mem_region(res->start, resource_size(res), CARDNAME)) {
    877		ret = -EBUSY;
    878		goto out;
    879	}
    880
    881	swim_base = (struct swim __iomem *)res->start;
    882	if (!swim_base) {
    883		ret = -ENOMEM;
    884		goto out_release_io;
    885	}
    886
    887	/* probe device */
    888
    889	set_swim_mode(swim_base, 1);
    890	if (!get_swim_mode(swim_base)) {
    891		printk(KERN_INFO "SWIM device not found !\n");
    892		ret = -ENODEV;
    893		goto out_release_io;
    894	}
    895
    896	/* set platform driver data */
    897
    898	swd = kzalloc(sizeof(struct swim_priv), GFP_KERNEL);
    899	if (!swd) {
    900		ret = -ENOMEM;
    901		goto out_release_io;
    902	}
    903	platform_set_drvdata(dev, swd);
    904
    905	swd->base = swim_base;
    906
    907	ret = swim_floppy_init(swd);
    908	if (ret)
    909		goto out_kfree;
    910
    911	return 0;
    912
    913out_kfree:
    914	kfree(swd);
    915out_release_io:
    916	release_mem_region(res->start, resource_size(res));
    917out:
    918	return ret;
    919}
    920
    921static int swim_remove(struct platform_device *dev)
    922{
    923	struct swim_priv *swd = platform_get_drvdata(dev);
    924	int drive;
    925	struct resource *res;
    926
    927	for (drive = 0; drive < swd->floppy_count; drive++)
    928		swim_cleanup_floppy_disk(&swd->unit[drive]);
    929
    930	unregister_blkdev(FLOPPY_MAJOR, "fd");
    931
    932	/* eject floppies */
    933
    934	for (drive = 0; drive < swd->floppy_count; drive++)
    935		floppy_eject(&swd->unit[drive]);
    936
    937	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
    938	if (res)
    939		release_mem_region(res->start, resource_size(res));
    940
    941	kfree(swd);
    942
    943	return 0;
    944}
    945
    946static struct platform_driver swim_driver = {
    947	.probe  = swim_probe,
    948	.remove = swim_remove,
    949	.driver   = {
    950		.name	= CARDNAME,
    951	},
    952};
    953
    954static int __init swim_init(void)
    955{
    956	printk(KERN_INFO "SWIM floppy driver %s\n", DRIVER_VERSION);
    957
    958	return platform_driver_register(&swim_driver);
    959}
    960module_init(swim_init);
    961
    962static void __exit swim_exit(void)
    963{
    964	platform_driver_unregister(&swim_driver);
    965}
    966module_exit(swim_exit);
    967
    968MODULE_DESCRIPTION("Driver for SWIM floppy controller");
    969MODULE_LICENSE("GPL");
    970MODULE_AUTHOR("Laurent Vivier <laurent@lvivier.info>");
    971MODULE_ALIAS_BLOCKDEV_MAJOR(FLOPPY_MAJOR);