aboutsummaryrefslogtreecommitdiff
path: root/drivers/block/swim.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/swim.c')
-rw-r--r--drivers/block/swim.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
index 8f569e3df89..6b44bbe528b 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -18,13 +18,14 @@
#include <linux/module.h>
#include <linux/fd.h>
+#include <linux/slab.h>
#include <linux/blkdev.h>
+#include <linux/mutex.h>
#include <linux/hdreg.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
-#include <asm/macintosh.h>
#include <asm/mac_via.h>
#define CARDNAME "swim"
@@ -220,6 +221,7 @@ extern int swim_read_sector_header(struct swim __iomem *base,
extern int swim_read_sector_data(struct swim __iomem *base,
unsigned char *data);
+static DEFINE_MUTEX(swim_mutex);
static inline void set_swim_mode(struct swim __iomem *base, int enable)
{
struct iwm __iomem *iwm_base;
@@ -547,7 +549,7 @@ static void redo_fd_request(struct request_queue *q)
case READ:
err = floppy_read_sectors(fs, blk_rq_pos(req),
blk_rq_cur_sectors(req),
- req->buffer);
+ bio_data(req->bio));
break;
}
done:
@@ -660,11 +662,23 @@ out:
return err;
}
-static int floppy_release(struct gendisk *disk, fmode_t mode)
+static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode)
+{
+ int ret;
+
+ mutex_lock(&swim_mutex);
+ ret = floppy_open(bdev, mode);
+ mutex_unlock(&swim_mutex);
+
+ return ret;
+}
+
+static void floppy_release(struct gendisk *disk, fmode_t mode)
{
struct floppy_state *fs = disk->private_data;
struct swim __iomem *base = fs->swd->base;
+ mutex_lock(&swim_mutex);
if (fs->ref_count < 0)
fs->ref_count = 0;
else if (fs->ref_count > 0)
@@ -672,8 +686,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
if (fs->ref_count == 0)
swim_motor(base, OFF);
-
- return 0;
+ mutex_unlock(&swim_mutex);
}
static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
@@ -689,7 +702,9 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
case FDEJECT:
if (fs->ref_count != 1)
return -EBUSY;
+ mutex_lock(&swim_mutex);
err = floppy_eject(fs);
+ mutex_unlock(&swim_mutex);
return err;
case FDGETPRM:
@@ -723,11 +738,12 @@ static int floppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
return 0;
}
-static int floppy_check_change(struct gendisk *disk)
+static unsigned int floppy_check_events(struct gendisk *disk,
+ unsigned int clearing)
{
struct floppy_state *fs = disk->private_data;
- return fs->ejected;
+ return fs->ejected ? DISK_EVENT_MEDIA_CHANGE : 0;
}
static int floppy_revalidate(struct gendisk *disk)
@@ -750,11 +766,11 @@ static int floppy_revalidate(struct gendisk *disk)
static const struct block_device_operations floppy_fops = {
.owner = THIS_MODULE,
- .open = floppy_open,
+ .open = floppy_unlocked_open,
.release = floppy_release,
- .locked_ioctl = floppy_ioctl,
+ .ioctl = floppy_ioctl,
.getgeo = floppy_getgeo,
- .media_changed = floppy_check_change,
+ .check_events = floppy_check_events,
.revalidate_disk = floppy_revalidate,
};
@@ -770,8 +786,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
return get_disk(swd->unit[drive].disk);
}
-static int __devinit swim_add_floppy(struct swim_priv *swd,
- enum drive_location location)
+static int swim_add_floppy(struct swim_priv *swd, enum drive_location location)
{
struct floppy_state *fs = &swd->unit[swd->floppy_count];
struct swim __iomem *base = swd->base;
@@ -794,7 +809,7 @@ static int __devinit swim_add_floppy(struct swim_priv *swd,
return 0;
}
-static int __devinit swim_floppy_init(struct swim_priv *swd)
+static int swim_floppy_init(struct swim_priv *swd)
{
int err;
int drive;
@@ -827,6 +842,7 @@ static int __devinit swim_floppy_init(struct swim_priv *swd)
swd->unit[drive].swd = swd;
}
+ spin_lock_init(&swd->lock);
swd->queue = blk_init_queue(do_fd_request, &swd->lock);
if (!swd->queue) {
err = -ENOMEM;
@@ -857,14 +873,14 @@ exit_put_disks:
return err;
}
-static int __devinit swim_probe(struct platform_device *dev)
+static int swim_probe(struct platform_device *dev)
{
struct resource *res;
struct swim __iomem *swim_base;
struct swim_priv *swd;
int ret;
- res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs");
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENODEV;
goto out;
@@ -877,7 +893,7 @@ static int __devinit swim_probe(struct platform_device *dev)
swim_base = ioremap(res->start, resource_size(res));
if (!swim_base) {
- return -ENOMEM;
+ ret = -ENOMEM;
goto out_release_io;
}
@@ -908,7 +924,6 @@ static int __devinit swim_probe(struct platform_device *dev)
return 0;
out_kfree:
- platform_set_drvdata(dev, NULL);
kfree(swd);
out_iounmap:
iounmap(swim_base);
@@ -918,7 +933,7 @@ out:
return ret;
}
-static int __devexit swim_remove(struct platform_device *dev)
+static int swim_remove(struct platform_device *dev)
{
struct swim_priv *swd = platform_get_drvdata(dev);
int drive;
@@ -942,11 +957,10 @@ static int __devexit swim_remove(struct platform_device *dev)
iounmap(swd->base);
- res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs");
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (res)
release_mem_region(res->start, resource_size(res));
- platform_set_drvdata(dev, NULL);
kfree(swd);
return 0;
@@ -954,7 +968,7 @@ static int __devexit swim_remove(struct platform_device *dev)
static struct platform_driver swim_driver = {
.probe = swim_probe,
- .remove = __devexit_p(swim_remove),
+ .remove = swim_remove,
.driver = {
.name = CARDNAME,
.owner = THIS_MODULE,