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}; ...@@ -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/delay.h>
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/cdrom.h> /* for the eject ioctl */ #include <linux/cdrom.h> /* for the eject ioctl */
#include <linux/blkdev.h> #include <linux/blk-mq.h>
#include <linux/blkpg.h> #include <linux/blkpg.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mutex.h> #include <linux/mutex.h>
...@@ -236,6 +236,8 @@ struct pd_unit { ...@@ -236,6 +236,8 @@ struct pd_unit {
int alt_geom; int alt_geom;
char name[PD_NAMELEN]; /* pda, pdb, etc ... */ char name[PD_NAMELEN]; /* pda, pdb, etc ... */
struct gendisk *gd; struct gendisk *gd;
struct blk_mq_tag_set tag_set;
struct list_head rq_list;
}; };
static struct pd_unit pd[PD_UNITS]; static struct pd_unit pd[PD_UNITS];
...@@ -399,9 +401,17 @@ static int set_next_request(void) ...@@ -399,9 +401,17 @@ static int set_next_request(void)
if (++pd_queue == PD_UNITS) if (++pd_queue == PD_UNITS)
pd_queue = 0; pd_queue = 0;
if (q) { if (q) {
pd_req = blk_fetch_request(q); struct pd_unit *disk = q->queuedata;
if (pd_req)
break; 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); } while (pd_queue != old_pos);
...@@ -412,7 +422,6 @@ static void run_fsm(void) ...@@ -412,7 +422,6 @@ static void run_fsm(void)
{ {
while (1) { while (1) {
enum action res; enum action res;
unsigned long saved_flags;
int stop = 0; int stop = 0;
if (!phase) { if (!phase) {
...@@ -433,19 +442,24 @@ static void run_fsm(void) ...@@ -433,19 +442,24 @@ static void run_fsm(void)
} }
switch(res = phase()) { 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); pi_disconnect(pi_current);
pd_claimed = 0; pd_claimed = 0;
phase = NULL; phase = NULL;
spin_lock_irqsave(&pd_lock, saved_flags); spin_lock_irq(&pd_lock);
if (!__blk_end_request_cur(pd_req, if (!blk_update_request(pd_req, err,
res == Ok ? 0 : BLK_STS_IOERR)) { blk_rq_cur_bytes(pd_req))) {
if (!set_next_request()) __blk_mq_end_request(pd_req, err);
stop = 1; pd_req = NULL;
stop = !set_next_request();
} }
spin_unlock_irqrestore(&pd_lock, saved_flags); spin_unlock_irq(&pd_lock);
if (stop) if (stop)
return; return;
}
/* fall through */ /* fall through */
case Hold: case Hold:
schedule_fsm(); schedule_fsm();
...@@ -505,11 +519,17 @@ static int pd_next_buf(void) ...@@ -505,11 +519,17 @@ static int pd_next_buf(void)
if (pd_count) if (pd_count)
return 0; return 0;
spin_lock_irqsave(&pd_lock, saved_flags); 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))) {
pd_count = blk_rq_cur_sectors(pd_req); __blk_mq_end_request(pd_req, 0);
pd_buf = bio_data(pd_req->bio); 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); spin_unlock_irqrestore(&pd_lock, saved_flags);
return 0; return !pd_count;
} }
static unsigned long pd_timeout; static unsigned long pd_timeout;
...@@ -726,15 +746,21 @@ static enum action pd_identify(struct pd_unit *disk) ...@@ -726,15 +746,21 @@ static enum action pd_identify(struct pd_unit *disk)
/* end of io request engine */ /* 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) struct pd_unit *disk = hctx->queue->queuedata;
return;
pd_req = blk_fetch_request(q); spin_lock_irq(&pd_lock);
if (!pd_req) if (!pd_req) {
return; 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);
schedule_fsm(); run_fsm();
return BLK_STS_OK;
} }
static int pd_special_command(struct pd_unit *disk, static int pd_special_command(struct pd_unit *disk,
...@@ -847,23 +873,33 @@ static const struct block_device_operations pd_fops = { ...@@ -847,23 +873,33 @@ static const struct block_device_operations pd_fops = {
/* probing */ /* probing */
static const struct blk_mq_ops pd_mq_ops = {
.queue_rq = pd_queue_rq,
};
static void pd_probe_drive(struct pd_unit *disk) 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) if (!p)
return; return;
strcpy(p->disk_name, disk->name); strcpy(p->disk_name, disk->name);
p->fops = &pd_fops; p->fops = &pd_fops;
p->major = major; p->major = major;
p->first_minor = (disk - pd) << PD_BITS; p->first_minor = (disk - pd) << PD_BITS;
disk->gd = p; disk->gd = p;
p->private_data = disk; p->private_data = disk;
p->queue = blk_init_queue(do_pd_request, &pd_lock);
if (!p->queue) { p->queue = blk_mq_init_sq_queue(&disk->tag_set, &pd_mq_ops, 2,
disk->gd = NULL; BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING);
put_disk(p); if (IS_ERR(p->queue)) {
p->queue = NULL;
return; return;
} }
p->queue->queuedata = disk;
blk_queue_max_hw_sectors(p->queue, cluster); blk_queue_max_hw_sectors(p->queue, cluster);
blk_queue_bounce_limit(p->queue, BLK_BOUNCE_HIGH); blk_queue_bounce_limit(p->queue, BLK_BOUNCE_HIGH);
...@@ -895,6 +931,7 @@ static int pd_detect(void) ...@@ -895,6 +931,7 @@ static int pd_detect(void)
disk->standby = parm[D_SBY]; disk->standby = parm[D_SBY];
if (parm[D_PRT]) if (parm[D_PRT])
pd_drive_count++; pd_drive_count++;
INIT_LIST_HEAD(&disk->rq_list);
} }
par_drv = pi_register_driver(name); par_drv = pi_register_driver(name);
...@@ -972,6 +1009,7 @@ static void __exit pd_exit(void) ...@@ -972,6 +1009,7 @@ static void __exit pd_exit(void)
disk->gd = NULL; disk->gd = NULL;
del_gendisk(p); del_gendisk(p);
blk_cleanup_queue(p->queue); blk_cleanup_queue(p->queue);
blk_mq_free_tag_set(&disk->tag_set);
put_disk(p); put_disk(p);
pi_release(disk->pi); 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