diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-25 21:05:15 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-25 21:05:15 -0700 |
commit | 8fba70b0850a0163f1018a122200ec11b854135c (patch) | |
tree | 390ae1ce5cdb36c96fb850e35eb65648d5e4a51d /drivers/block/swim.c | |
parent | c6dc3e711a28b6b4c5e63f2bca34a5cfd35e9a22 (diff) | |
parent | 4412efecf7fda3b8f9f18feed7938f2281f5ccbc (diff) |
Merge tag 'for-linus-20180425' of git://git.kernel.dk/linux-block
Pull block updates from Jens Axboe:
"I ended up sitting on this about a week longer than I wanted to, since
we were hashing out details with a timeout change. I've now killed
that patch, so we can flush the existing queue in due time.
This contains:
- Fix for an old regression, where entering the queue can be
disturbed by a signal to the process. This can cause spurious EIO.
Fix from Alan Jenkins.
- cdrom information leak fix from Dan.
- Trivial helper for testing queue FUA from Dave Chinner, part of his
O_DIRECT FUA series.
- Series of swim fixes from Finn that actually makes it work again.
- Loop O_DIRECT corruption fix, which caused data corruption in
production for us. From me.
- BFQ crash fix from me.
- bcache maintainer update. Michael no longer has the time to do it,
Coly has stepped up to serve as the new maintainer.
- blkcg locking fixes from Jiang Biao.
- Revert of a change from this merge window from Ming, that causes an
issue on some hardware.
- Minor clarification doc addition from Linus Walleij"
* tag 'for-linus-20180425' of git://git.kernel.dk/linux-block: (22 commits)
Revert "blk-mq: remove code for dealing with remapping queue"
block: mq: Add some minor doc for core structs
bcache: mark Coly Li as bcache maintainer
MAINTAINERS: Remove me as maintainer of bcache
blkcg: init root blkcg_gq under lock
blkcg: small fix on comment in blkcg_init_queue
blkcg: don't hold blkcg lock when deactivating policy
block: add blk_queue_fua() helper function
cdrom: information leak in cdrom_ioctl_media_changed()
bfq-iosched: ensure to clear bic/bfqq pointers when preparing request
blk-mq: start request gstate with gen 1
block/swim: Select appropriate drive on device open
block/swim: Fix IO error at end of medium
block/swim: Check drive type
block/swim: Rename macros to avoid inconsistent inverted logic
block/swim: Don't log an error message for an invalid ioctl
block/swim: Remove extra put_disk() call from error path
block/swim: Fix array bounds check
m68k/mac: Don't remap SWIM MMIO region
loop: handle short DIO reads
...
Diffstat (limited to 'drivers/block/swim.c')
-rw-r--r-- | drivers/block/swim.c | 49 |
1 files changed, 22 insertions, 27 deletions
diff --git a/drivers/block/swim.c b/drivers/block/swim.c index 64e066eba72e..0e31884a9519 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -110,7 +110,7 @@ struct iwm { /* Select values for swim_select and swim_readbit */ #define READ_DATA_0 0x074 -#define TWOMEG_DRIVE 0x075 +#define ONEMEG_DRIVE 0x075 #define SINGLE_SIDED 0x076 #define DRIVE_PRESENT 0x077 #define DISK_IN 0x170 @@ -118,9 +118,9 @@ struct iwm { #define TRACK_ZERO 0x172 #define TACHO 0x173 #define READ_DATA_1 0x174 -#define MFM_MODE 0x175 +#define GCR_MODE 0x175 #define SEEK_COMPLETE 0x176 -#define ONEMEG_MEDIA 0x177 +#define TWOMEG_MEDIA 0x177 /* Bits in handshake register */ @@ -612,7 +612,6 @@ static void setup_medium(struct floppy_state *fs) struct floppy_struct *g; fs->disk_in = 1; fs->write_protected = swim_readbit(base, WRITE_PROT); - fs->type = swim_readbit(base, ONEMEG_MEDIA); if (swim_track00(base)) printk(KERN_ERR @@ -620,6 +619,9 @@ static void setup_medium(struct floppy_state *fs) swim_track00(base); + fs->type = swim_readbit(base, TWOMEG_MEDIA) ? + HD_MEDIA : DD_MEDIA; + fs->head_number = swim_readbit(base, SINGLE_SIDED) ? 1 : 2; get_floppy_geometry(fs, 0, &g); fs->total_secs = g->size; fs->secpercyl = g->head * g->sect; @@ -646,7 +648,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) swim_write(base, setup, S_IBM_DRIVE | S_FCLK_DIV2); udelay(10); - swim_drive(base, INTERNAL_DRIVE); + swim_drive(base, fs->location); swim_motor(base, ON); swim_action(base, SETMFM); if (fs->ejected) @@ -656,6 +658,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) goto out; } + set_capacity(fs->disk, fs->total_secs); + if (mode & FMODE_NDELAY) return 0; @@ -727,14 +731,9 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode, if (copy_to_user((void __user *) param, (void *) &floppy_type, sizeof(struct floppy_struct))) return -EFAULT; - break; - - default: - printk(KERN_DEBUG "SWIM floppy_ioctl: unknown cmd %d\n", - cmd); - return -ENOSYS; + return 0; } - return 0; + return -ENOTTY; } static int floppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) @@ -795,7 +794,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) struct swim_priv *swd = data; int drive = (*part & 3); - if (drive > swd->floppy_count) + if (drive >= swd->floppy_count) return NULL; *part = 0; @@ -813,10 +812,9 @@ static int swim_add_floppy(struct swim_priv *swd, enum drive_location location) swim_motor(base, OFF); - if (swim_readbit(base, SINGLE_SIDED)) - fs->head_number = 1; - else - fs->head_number = 2; + fs->type = HD_MEDIA; + fs->head_number = 2; + fs->ref_count = 0; fs->ejected = 1; @@ -834,10 +832,12 @@ static int swim_floppy_init(struct swim_priv *swd) /* scan floppy drives */ swim_drive(base, INTERNAL_DRIVE); - if (swim_readbit(base, DRIVE_PRESENT)) + if (swim_readbit(base, DRIVE_PRESENT) && + !swim_readbit(base, ONEMEG_DRIVE)) swim_add_floppy(swd, INTERNAL_DRIVE); swim_drive(base, EXTERNAL_DRIVE); - if (swim_readbit(base, DRIVE_PRESENT)) + if (swim_readbit(base, DRIVE_PRESENT) && + !swim_readbit(base, ONEMEG_DRIVE)) swim_add_floppy(swd, EXTERNAL_DRIVE); /* register floppy drives */ @@ -861,7 +861,6 @@ static int swim_floppy_init(struct swim_priv *swd) &swd->lock); if (!swd->unit[drive].disk->queue) { err = -ENOMEM; - put_disk(swd->unit[drive].disk); goto exit_put_disks; } blk_queue_bounce_limit(swd->unit[drive].disk->queue, @@ -911,7 +910,7 @@ static int swim_probe(struct platform_device *dev) goto out; } - swim_base = ioremap(res->start, resource_size(res)); + swim_base = (struct swim __iomem *)res->start; if (!swim_base) { ret = -ENOMEM; goto out_release_io; @@ -923,7 +922,7 @@ static int swim_probe(struct platform_device *dev) if (!get_swim_mode(swim_base)) { printk(KERN_INFO "SWIM device not found !\n"); ret = -ENODEV; - goto out_iounmap; + goto out_release_io; } /* set platform driver data */ @@ -931,7 +930,7 @@ static int swim_probe(struct platform_device *dev) swd = kzalloc(sizeof(struct swim_priv), GFP_KERNEL); if (!swd) { ret = -ENOMEM; - goto out_iounmap; + goto out_release_io; } platform_set_drvdata(dev, swd); @@ -945,8 +944,6 @@ static int swim_probe(struct platform_device *dev) out_kfree: kfree(swd); -out_iounmap: - iounmap(swim_base); out_release_io: release_mem_region(res->start, resource_size(res)); out: @@ -974,8 +971,6 @@ static int swim_remove(struct platform_device *dev) for (drive = 0; drive < swd->floppy_count; drive++) floppy_eject(&swd->unit[drive]); - iounmap(swd->base); - res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (res) release_mem_region(res->start, resource_size(res)); |