Commit 99fe8b02 authored by Jens Axboe's avatar Jens Axboe

paride: convert pd to blk-mq

Tested-by: default avatarOndrej Zary <linux@rainbow-software.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 89c6b165
......@@ -151,7 +151,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
#include <linux/delay.h>
#include <linux/hdreg.h>
#include <linux/cdrom.h> /* for the eject ioctl */
#include <linux/blkdev.h>
#include <linux/blk-mq.h>
#include <linux/blkpg.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
......@@ -236,6 +236,8 @@ struct pd_unit {
int alt_geom;
char name[PD_NAMELEN]; /* pda, pdb, etc ... */
struct gendisk *gd;
struct blk_mq_tag_set tag_set;
struct list_head rq_list;
};
static struct pd_unit pd[PD_UNITS];
......@@ -399,8 +401,16 @@ static int set_next_request(void)
if (++pd_queue == PD_UNITS)
pd_queue = 0;
if (q) {
pd_req = blk_fetch_request(q);
if (pd_req)
struct pd_unit *disk = q->queuedata;
if (list_empty(&disk->rq_list))
continue;
pd_req = list_first_entry(&disk->rq_list,
struct request,
queuelist);
list_del_init(&pd_req->queuelist);
blk_mq_start_request(pd_req);
break;
}
} while (pd_queue != old_pos);
......@@ -412,7 +422,6 @@ static void run_fsm(void)
{
while (1) {
enum action res;
unsigned long saved_flags;
int stop = 0;
if (!phase) {
......@@ -433,19 +442,24 @@ static void run_fsm(void)
}
switch(res = phase()) {
case Ok: case Fail:
case Ok: case Fail: {
blk_status_t err;
err = res == Ok ? 0 : BLK_STS_IOERR;
pi_disconnect(pi_current);
pd_claimed = 0;
phase = NULL;
spin_lock_irqsave(&pd_lock, saved_flags);
if (!__blk_end_request_cur(pd_req,
res == Ok ? 0 : BLK_STS_IOERR)) {
if (!set_next_request())
stop = 1;
}
spin_unlock_irqrestore(&pd_lock, saved_flags);
spin_lock_irq(&pd_lock);
if (!blk_update_request(pd_req, err,
blk_rq_cur_bytes(pd_req))) {
__blk_mq_end_request(pd_req, err);
pd_req = NULL;
stop = !set_next_request();
}
spin_unlock_irq(&pd_lock);
if (stop)
return;
}
/* fall through */
case Hold:
schedule_fsm();
......@@ -505,11 +519,17 @@ static int pd_next_buf(void)
if (pd_count)
return 0;
spin_lock_irqsave(&pd_lock, saved_flags);
__blk_end_request_cur(pd_req, 0);
if (!blk_update_request(pd_req, 0, blk_rq_cur_bytes(pd_req))) {
__blk_mq_end_request(pd_req, 0);
pd_req = NULL;
pd_count = 0;
pd_buf = NULL;
} else {
pd_count = blk_rq_cur_sectors(pd_req);
pd_buf = bio_data(pd_req->bio);
}
spin_unlock_irqrestore(&pd_lock, saved_flags);
return 0;
return !pd_count;
}
static unsigned long pd_timeout;
......@@ -726,15 +746,21 @@ static enum action pd_identify(struct pd_unit *disk)
/* end of io request engine */
static void do_pd_request(struct request_queue * q)
static blk_status_t pd_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *bd)
{
if (pd_req)
return;
pd_req = blk_fetch_request(q);
if (!pd_req)
return;
struct pd_unit *disk = hctx->queue->queuedata;
schedule_fsm();
spin_lock_irq(&pd_lock);
if (!pd_req) {
pd_req = bd->rq;
blk_mq_start_request(pd_req);
} else
list_add_tail(&bd->rq->queuelist, &disk->rq_list);
spin_unlock_irq(&pd_lock);
run_fsm();
return BLK_STS_OK;
}
static int pd_special_command(struct pd_unit *disk,
......@@ -847,23 +873,33 @@ static const struct block_device_operations pd_fops = {
/* probing */
static const struct blk_mq_ops pd_mq_ops = {
.queue_rq = pd_queue_rq,
};
static void pd_probe_drive(struct pd_unit *disk)
{
struct gendisk *p = alloc_disk(1 << PD_BITS);
struct gendisk *p;
p = alloc_disk(1 << PD_BITS);
if (!p)
return;
strcpy(p->disk_name, disk->name);
p->fops = &pd_fops;
p->major = major;
p->first_minor = (disk - pd) << PD_BITS;
disk->gd = p;
p->private_data = disk;
p->queue = blk_init_queue(do_pd_request, &pd_lock);
if (!p->queue) {
disk->gd = NULL;
put_disk(p);
p->queue = blk_mq_init_sq_queue(&disk->tag_set, &pd_mq_ops, 2,
BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING);
if (IS_ERR(p->queue)) {
p->queue = NULL;
return;
}
p->queue->queuedata = disk;
blk_queue_max_hw_sectors(p->queue, cluster);
blk_queue_bounce_limit(p->queue, BLK_BOUNCE_HIGH);
......@@ -895,6 +931,7 @@ static int pd_detect(void)
disk->standby = parm[D_SBY];
if (parm[D_PRT])
pd_drive_count++;
INIT_LIST_HEAD(&disk->rq_list);
}
par_drv = pi_register_driver(name);
......@@ -972,6 +1009,7 @@ static void __exit pd_exit(void)
disk->gd = NULL;
del_gendisk(p);
blk_cleanup_queue(p->queue);
blk_mq_free_tag_set(&disk->tag_set);
put_disk(p);
pi_release(disk->pi);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment