diff options
Diffstat (limited to 'drivers/block/swim.c')
| -rw-r--r-- | drivers/block/swim.c | 56 |
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, |
