|
@@ -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
|