summaryrefslogtreecommitdiffstats
path: root/drivers/block/amiflop.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-12-16 12:57:51 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2020-12-16 12:57:51 -0800
commitac7ac4618cf25e0d5cd8eba83d5f600084b65b9a (patch)
treee5d28907ff72690a0463a2238b96202d751a535c /drivers/block/amiflop.c
parent48aba79bcf6ea05148dc82ad9c40713960b00396 (diff)
parentfa94ba8a7b22890e6a17b39b9359e114fe18cd59 (diff)
downloadlinux-stable-ac7ac4618cf25e0d5cd8eba83d5f600084b65b9a.tar.gz
linux-stable-ac7ac4618cf25e0d5cd8eba83d5f600084b65b9a.tar.bz2
linux-stable-ac7ac4618cf25e0d5cd8eba83d5f600084b65b9a.zip
Merge tag 'for-5.11/block-2020-12-14' of git://git.kernel.dk/linux-block
Pull block updates from Jens Axboe: "Another series of killing more code than what is being added, again thanks to Christoph's relentless cleanups and tech debt tackling. This contains: - blk-iocost improvements (Baolin Wang) - part0 iostat fix (Jeffle Xu) - Disable iopoll for split bios (Jeffle Xu) - block tracepoint cleanups (Christoph Hellwig) - Merging of struct block_device and hd_struct (Christoph Hellwig) - Rework/cleanup of how block device sizes are updated (Christoph Hellwig) - Simplification of gendisk lookup and removal of block device aliasing (Christoph Hellwig) - Block device ioctl cleanups (Christoph Hellwig) - Removal of bdget()/blkdev_get() as exported API (Christoph Hellwig) - Disk change rework, avoid ->revalidate_disk() (Christoph Hellwig) - sbitmap improvements (Pavel Begunkov) - Hybrid polling fix (Pavel Begunkov) - bvec iteration improvements (Pavel Begunkov) - Zone revalidation fixes (Damien Le Moal) - blk-throttle limit fix (Yu Kuai) - Various little fixes" * tag 'for-5.11/block-2020-12-14' of git://git.kernel.dk/linux-block: (126 commits) blk-mq: fix msec comment from micro to milli seconds blk-mq: update arg in comment of blk_mq_map_queue blk-mq: add helper allocating tagset->tags Revert "block: Fix a lockdep complaint triggered by request queue flushing" nvme-loop: use blk_mq_hctx_set_fq_lock_class to set loop's lock class blk-mq: add new API of blk_mq_hctx_set_fq_lock_class block: disable iopoll for split bio block: Improve blk_revalidate_disk_zones() checks sbitmap: simplify wrap check sbitmap: replace CAS with atomic and sbitmap: remove swap_lock sbitmap: optimise sbitmap_deferred_clear() blk-mq: skip hybrid polling if iopoll doesn't spin blk-iocost: Factor out the base vrate change into a separate function blk-iocost: Factor out the active iocgs' state check into a separate function blk-iocost: Move the usage ratio calculation to the correct place blk-iocost: Remove unnecessary advance declaration blk-iocost: Fix some typos in comments blktrace: fix up a kerneldoc comment block: remove the request_queue to argument request based tracepoints ...
Diffstat (limited to 'drivers/block/amiflop.c')
-rw-r--r--drivers/block/amiflop.c98
1 files changed, 55 insertions, 43 deletions
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 71c2b1564558..9e2d0c6a3877 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -201,7 +201,7 @@ struct amiga_floppy_struct {
int busy; /* true when drive is active */
int dirty; /* true when trackbuf is not on disk */
int status; /* current error code for unit */
- struct gendisk *gendisk;
+ struct gendisk *gendisk[2];
struct blk_mq_tag_set tag_set;
};
@@ -1669,6 +1669,11 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
return -EBUSY;
}
+ if (unit[drive].type->code == FD_NODRIVE) {
+ mutex_unlock(&amiflop_mutex);
+ return -ENXIO;
+ }
+
if (mode & (FMODE_READ|FMODE_WRITE)) {
bdev_check_media_change(bdev);
if (mode & FMODE_WRITE) {
@@ -1695,7 +1700,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
unit[drive].dtype=&data_types[system];
unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*
data_types[system].sects*unit[drive].type->sect_mult;
- set_capacity(unit[drive].gendisk, unit[drive].blocks);
+ set_capacity(unit[drive].gendisk[system], unit[drive].blocks);
printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive,
unit[drive].type->name, data_types[system].name);
@@ -1772,36 +1777,68 @@ static const struct blk_mq_ops amiflop_mq_ops = {
.queue_rq = amiflop_queue_rq,
};
-static struct gendisk *fd_alloc_disk(int drive)
+static int fd_alloc_disk(int drive, int system)
{
struct gendisk *disk;
disk = alloc_disk(1);
if (!disk)
goto out;
-
- disk->queue = blk_mq_init_sq_queue(&unit[drive].tag_set, &amiflop_mq_ops,
- 2, BLK_MQ_F_SHOULD_MERGE);
- if (IS_ERR(disk->queue)) {
- disk->queue = NULL;
+ disk->queue = blk_mq_init_queue(&unit[drive].tag_set);
+ if (IS_ERR(disk->queue))
goto out_put_disk;
- }
+ disk->major = FLOPPY_MAJOR;
+ disk->first_minor = drive + system;
+ disk->fops = &floppy_fops;
+ disk->events = DISK_EVENT_MEDIA_CHANGE;
+ if (system)
+ sprintf(disk->disk_name, "fd%d_msdos", drive);
+ else
+ sprintf(disk->disk_name, "fd%d", drive);
+ disk->private_data = &unit[drive];
+ set_capacity(disk, 880 * 2);
+
+ unit[drive].gendisk[system] = disk;
+ add_disk(disk);
+ return 0;
+
+out_put_disk:
+ disk->queue = NULL;
+ put_disk(disk);
+out:
+ return -ENOMEM;
+}
+
+static int fd_alloc_drive(int drive)
+{
unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL);
if (!unit[drive].trackbuf)
- goto out_cleanup_queue;
+ goto out;
- return disk;
+ memset(&unit[drive].tag_set, 0, sizeof(unit[drive].tag_set));
+ unit[drive].tag_set.ops = &amiflop_mq_ops;
+ unit[drive].tag_set.nr_hw_queues = 1;
+ unit[drive].tag_set.nr_maps = 1;
+ unit[drive].tag_set.queue_depth = 2;
+ unit[drive].tag_set.numa_node = NUMA_NO_NODE;
+ unit[drive].tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
+ if (blk_mq_alloc_tag_set(&unit[drive].tag_set))
+ goto out_cleanup_trackbuf;
-out_cleanup_queue:
- blk_cleanup_queue(disk->queue);
- disk->queue = NULL;
+ pr_cont(" fd%d", drive);
+
+ if (fd_alloc_disk(drive, 0) || fd_alloc_disk(drive, 1))
+ goto out_cleanup_tagset;
+ return 0;
+
+out_cleanup_tagset:
blk_mq_free_tag_set(&unit[drive].tag_set);
-out_put_disk:
- put_disk(disk);
+out_cleanup_trackbuf:
+ kfree(unit[drive].trackbuf);
out:
unit[drive].type->code = FD_NODRIVE;
- return NULL;
+ return -ENOMEM;
}
static int __init fd_probe_drives(void)
@@ -1812,29 +1849,16 @@ static int __init fd_probe_drives(void)
drives=0;
nomem=0;
for(drive=0;drive<FD_MAX_UNITS;drive++) {
- struct gendisk *disk;
fd_probe(drive);
if (unit[drive].type->code == FD_NODRIVE)
continue;
- disk = fd_alloc_disk(drive);
- if (!disk) {
+ if (fd_alloc_drive(drive) < 0) {
pr_cont(" no mem for fd%d", drive);
nomem = 1;
continue;
}
- unit[drive].gendisk = disk;
drives++;
-
- pr_cont(" fd%d",drive);
- disk->major = FLOPPY_MAJOR;
- disk->first_minor = drive;
- disk->fops = &floppy_fops;
- disk->events = DISK_EVENT_MEDIA_CHANGE;
- sprintf(disk->disk_name, "fd%d", drive);
- disk->private_data = &unit[drive];
- set_capacity(disk, 880*2);
- add_disk(disk);
}
if ((drives > 0) || (nomem == 0)) {
if (drives == 0)
@@ -1846,15 +1870,6 @@ static int __init fd_probe_drives(void)
return -ENOMEM;
}
-static struct kobject *floppy_find(dev_t dev, int *part, void *data)
-{
- int drive = *part & 3;
- if (unit[drive].type->code == FD_NODRIVE)
- return NULL;
- *part = 0;
- return get_disk_and_module(unit[drive].gendisk);
-}
-
static int __init amiga_floppy_probe(struct platform_device *pdev)
{
int i, ret;
@@ -1884,9 +1899,6 @@ static int __init amiga_floppy_probe(struct platform_device *pdev)
if (fd_probe_drives() < 1) /* No usable drives */
goto out_probe;
- blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
- floppy_find, NULL, NULL);
-
/* initialize variables */
timer_setup(&motor_on_timer, motor_on_callback, 0);
motor_on_timer.expires = 0;