forked from Minki/linux
floppy: convert to blk-mq
This driver likes to fetch requests from all over the place, so make queue_rq put requests on a list so that the logic stays the same. Tested with QEMU. Signed-off-by: Omar Sandoval <osandov@fb.com> Converted to blk_mq_init_sq_queue() and fixed a few spots where the tag_set leaked on cleanup. Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
6ec3938cff
commit
a9f38e1dec
@ -252,13 +252,13 @@ static int allowed_drive_mask = 0x33;
|
||||
|
||||
static int irqdma_allocated;
|
||||
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/blk-mq.h>
|
||||
#include <linux/blkpg.h>
|
||||
#include <linux/cdrom.h> /* for the compatibility eject ioctl */
|
||||
#include <linux/completion.h>
|
||||
|
||||
static LIST_HEAD(floppy_reqs);
|
||||
static struct request *current_req;
|
||||
static void do_fd_request(struct request_queue *q);
|
||||
static int set_next_request(void);
|
||||
|
||||
#ifndef fd_get_dma_residue
|
||||
@ -414,10 +414,10 @@ static struct floppy_drive_struct drive_state[N_DRIVE];
|
||||
static struct floppy_write_errors write_errors[N_DRIVE];
|
||||
static struct timer_list motor_off_timer[N_DRIVE];
|
||||
static struct gendisk *disks[N_DRIVE];
|
||||
static struct blk_mq_tag_set tag_sets[N_DRIVE];
|
||||
static struct block_device *opened_bdev[N_DRIVE];
|
||||
static DEFINE_MUTEX(open_lock);
|
||||
static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
|
||||
static int fdc_queue;
|
||||
|
||||
/*
|
||||
* This struct defines the different floppy types.
|
||||
@ -2216,8 +2216,9 @@ static void floppy_end_request(struct request *req, blk_status_t error)
|
||||
/* current_count_sectors can be zero if transfer failed */
|
||||
if (error)
|
||||
nr_sectors = blk_rq_cur_sectors(req);
|
||||
if (__blk_end_request(req, error, nr_sectors << 9))
|
||||
if (blk_update_request(req, error, nr_sectors << 9))
|
||||
return;
|
||||
__blk_mq_end_request(req, error);
|
||||
|
||||
/* We're done with the request */
|
||||
floppy_off(drive);
|
||||
@ -2797,27 +2798,14 @@ static int make_raw_rw_request(void)
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Round-robin between our available drives, doing one request from each
|
||||
*/
|
||||
static int set_next_request(void)
|
||||
{
|
||||
struct request_queue *q;
|
||||
int old_pos = fdc_queue;
|
||||
|
||||
do {
|
||||
q = disks[fdc_queue]->queue;
|
||||
if (++fdc_queue == N_DRIVE)
|
||||
fdc_queue = 0;
|
||||
if (q) {
|
||||
current_req = blk_fetch_request(q);
|
||||
if (current_req) {
|
||||
current_req->error_count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (fdc_queue != old_pos);
|
||||
|
||||
current_req = list_first_entry_or_null(&floppy_reqs, struct request,
|
||||
queuelist);
|
||||
if (current_req) {
|
||||
current_req->error_count = 0;
|
||||
list_del_init(¤t_req->queuelist);
|
||||
}
|
||||
return current_req != NULL;
|
||||
}
|
||||
|
||||
@ -2901,29 +2889,38 @@ static void process_fd_request(void)
|
||||
schedule_bh(redo_fd_request);
|
||||
}
|
||||
|
||||
static void do_fd_request(struct request_queue *q)
|
||||
static blk_status_t floppy_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||
const struct blk_mq_queue_data *bd)
|
||||
{
|
||||
blk_mq_start_request(bd->rq);
|
||||
|
||||
if (WARN(max_buffer_sectors == 0,
|
||||
"VFS: %s called on non-open device\n", __func__))
|
||||
return;
|
||||
return BLK_STS_IOERR;
|
||||
|
||||
if (WARN(atomic_read(&usage_count) == 0,
|
||||
"warning: usage count=0, current_req=%p sect=%ld flags=%llx\n",
|
||||
current_req, (long)blk_rq_pos(current_req),
|
||||
(unsigned long long) current_req->cmd_flags))
|
||||
return;
|
||||
return BLK_STS_IOERR;
|
||||
|
||||
spin_lock_irq(&floppy_lock);
|
||||
list_add_tail(&bd->rq->queuelist, &floppy_reqs);
|
||||
spin_unlock_irq(&floppy_lock);
|
||||
|
||||
if (test_and_set_bit(0, &fdc_busy)) {
|
||||
/* fdc busy, this new request will be treated when the
|
||||
current one is done */
|
||||
is_alive(__func__, "old request running");
|
||||
return;
|
||||
return BLK_STS_OK;
|
||||
}
|
||||
|
||||
command_status = FD_COMMAND_NONE;
|
||||
__reschedule_timeout(MAXTIMEOUT, "fd_request");
|
||||
set_fdc(0);
|
||||
process_fd_request();
|
||||
is_alive(__func__, "");
|
||||
return BLK_STS_OK;
|
||||
}
|
||||
|
||||
static const struct cont_t poll_cont = {
|
||||
@ -4486,6 +4483,10 @@ static struct platform_driver floppy_driver = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct blk_mq_ops floppy_mq_ops = {
|
||||
.queue_rq = floppy_queue_rq,
|
||||
};
|
||||
|
||||
static struct platform_device floppy_device[N_DRIVE];
|
||||
|
||||
static bool floppy_available(int drive)
|
||||
@ -4533,9 +4534,12 @@ static int __init do_floppy_init(void)
|
||||
goto out_put_disk;
|
||||
}
|
||||
|
||||
disks[drive]->queue = blk_init_queue(do_fd_request, &floppy_lock);
|
||||
if (!disks[drive]->queue) {
|
||||
err = -ENOMEM;
|
||||
disks[drive]->queue = blk_mq_init_sq_queue(&tag_sets[drive],
|
||||
&floppy_mq_ops, 2,
|
||||
BLK_MQ_F_SHOULD_MERGE);
|
||||
if (IS_ERR(disks[drive]->queue)) {
|
||||
err = PTR_ERR(disks[drive]->queue);
|
||||
disks[drive]->queue = NULL;
|
||||
goto out_put_disk;
|
||||
}
|
||||
|
||||
@ -4708,6 +4712,7 @@ out_put_disk:
|
||||
del_timer_sync(&motor_off_timer[drive]);
|
||||
blk_cleanup_queue(disks[drive]->queue);
|
||||
disks[drive]->queue = NULL;
|
||||
blk_mq_free_tag_set(&tag_sets[drive]);
|
||||
}
|
||||
put_disk(disks[drive]);
|
||||
}
|
||||
@ -4935,6 +4940,7 @@ static void __exit floppy_module_exit(void)
|
||||
platform_device_unregister(&floppy_device[drive]);
|
||||
}
|
||||
blk_cleanup_queue(disks[drive]->queue);
|
||||
blk_mq_free_tag_set(&tag_sets[drive]);
|
||||
|
||||
/*
|
||||
* These disks have not called add_disk(). Don't put down
|
||||
|
Loading…
Reference in New Issue
Block a user