Commit d0be1227 authored by Jens Axboe's avatar Jens Axboe

mspro_block: convert to blk-mq

Straight forward conversion, there's room for improvement.
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Tested-by: default avatarMing Lei <ming.lei@redhat.com>
Reviewed-by: default avatarOmar Sandoval <osandov@fb.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent db1142a8
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* *
*/ */
#include <linux/blkdev.h> #include <linux/blk-mq.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/kthread.h> #include <linux/kthread.h>
...@@ -142,6 +142,7 @@ struct mspro_block_data { ...@@ -142,6 +142,7 @@ struct mspro_block_data {
struct gendisk *disk; struct gendisk *disk;
struct request_queue *queue; struct request_queue *queue;
struct request *block_req; struct request *block_req;
struct blk_mq_tag_set tag_set;
spinlock_t q_lock; spinlock_t q_lock;
unsigned short page_size; unsigned short page_size;
...@@ -152,7 +153,6 @@ struct mspro_block_data { ...@@ -152,7 +153,6 @@ struct mspro_block_data {
unsigned char system; unsigned char system;
unsigned char read_only:1, unsigned char read_only:1,
eject:1, eject:1,
has_request:1,
data_dir:1, data_dir:1,
active:1; active:1;
unsigned char transfer_cmd; unsigned char transfer_cmd;
...@@ -694,13 +694,12 @@ static void h_mspro_block_setup_cmd(struct memstick_dev *card, u64 offset, ...@@ -694,13 +694,12 @@ static void h_mspro_block_setup_cmd(struct memstick_dev *card, u64 offset,
/*** Data transfer ***/ /*** Data transfer ***/
static int mspro_block_issue_req(struct memstick_dev *card, int chunk) static int mspro_block_issue_req(struct memstick_dev *card, bool chunk)
{ {
struct mspro_block_data *msb = memstick_get_drvdata(card); struct mspro_block_data *msb = memstick_get_drvdata(card);
u64 t_off; u64 t_off;
unsigned int count; unsigned int count;
try_again:
while (chunk) { while (chunk) {
msb->current_page = 0; msb->current_page = 0;
msb->current_seg = 0; msb->current_seg = 0;
...@@ -709,9 +708,17 @@ static int mspro_block_issue_req(struct memstick_dev *card, int chunk) ...@@ -709,9 +708,17 @@ static int mspro_block_issue_req(struct memstick_dev *card, int chunk)
msb->req_sg); msb->req_sg);
if (!msb->seg_count) { if (!msb->seg_count) {
chunk = __blk_end_request_cur(msb->block_req, unsigned int bytes = blk_rq_cur_bytes(msb->block_req);
BLK_STS_RESOURCE);
continue; chunk = blk_update_request(msb->block_req,
BLK_STS_RESOURCE,
bytes);
if (chunk)
continue;
__blk_mq_end_request(msb->block_req,
BLK_STS_RESOURCE);
msb->block_req = NULL;
break;
} }
t_off = blk_rq_pos(msb->block_req); t_off = blk_rq_pos(msb->block_req);
...@@ -729,30 +736,22 @@ static int mspro_block_issue_req(struct memstick_dev *card, int chunk) ...@@ -729,30 +736,22 @@ static int mspro_block_issue_req(struct memstick_dev *card, int chunk)
return 0; return 0;
} }
dev_dbg(&card->dev, "blk_fetch\n"); return 1;
msb->block_req = blk_fetch_request(msb->queue);
if (!msb->block_req) {
dev_dbg(&card->dev, "issue end\n");
return -EAGAIN;
}
dev_dbg(&card->dev, "trying again\n");
chunk = 1;
goto try_again;
} }
static int mspro_block_complete_req(struct memstick_dev *card, int error) static int mspro_block_complete_req(struct memstick_dev *card, int error)
{ {
struct mspro_block_data *msb = memstick_get_drvdata(card); struct mspro_block_data *msb = memstick_get_drvdata(card);
int chunk, cnt; int cnt;
bool chunk;
unsigned int t_len = 0; unsigned int t_len = 0;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&msb->q_lock, flags); spin_lock_irqsave(&msb->q_lock, flags);
dev_dbg(&card->dev, "complete %d, %d\n", msb->has_request ? 1 : 0, dev_dbg(&card->dev, "complete %d, %d\n", msb->block_req ? 1 : 0,
error); error);
if (msb->has_request) { if (msb->block_req) {
/* Nothing to do - not really an error */ /* Nothing to do - not really an error */
if (error == -EAGAIN) if (error == -EAGAIN)
error = 0; error = 0;
...@@ -777,15 +776,17 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error) ...@@ -777,15 +776,17 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error)
if (error && !t_len) if (error && !t_len)
t_len = blk_rq_cur_bytes(msb->block_req); t_len = blk_rq_cur_bytes(msb->block_req);
chunk = __blk_end_request(msb->block_req, chunk = blk_update_request(msb->block_req,
errno_to_blk_status(error), t_len); errno_to_blk_status(error), t_len);
if (chunk) {
error = mspro_block_issue_req(card, chunk); error = mspro_block_issue_req(card, chunk);
if (!error)
if (!error) goto out;
goto out; } else {
else __blk_mq_end_request(msb->block_req,
msb->has_request = 0; errno_to_blk_status(error));
msb->block_req = NULL;
}
} else { } else {
if (!error) if (!error)
error = -EAGAIN; error = -EAGAIN;
...@@ -806,8 +807,8 @@ static void mspro_block_stop(struct memstick_dev *card) ...@@ -806,8 +807,8 @@ static void mspro_block_stop(struct memstick_dev *card)
while (1) { while (1) {
spin_lock_irqsave(&msb->q_lock, flags); spin_lock_irqsave(&msb->q_lock, flags);
if (!msb->has_request) { if (!msb->block_req) {
blk_stop_queue(msb->queue); blk_mq_stop_hw_queues(msb->queue);
rc = 1; rc = 1;
} }
spin_unlock_irqrestore(&msb->q_lock, flags); spin_unlock_irqrestore(&msb->q_lock, flags);
...@@ -822,32 +823,37 @@ static void mspro_block_stop(struct memstick_dev *card) ...@@ -822,32 +823,37 @@ static void mspro_block_stop(struct memstick_dev *card)
static void mspro_block_start(struct memstick_dev *card) static void mspro_block_start(struct memstick_dev *card)
{ {
struct mspro_block_data *msb = memstick_get_drvdata(card); struct mspro_block_data *msb = memstick_get_drvdata(card);
unsigned long flags;
spin_lock_irqsave(&msb->q_lock, flags); blk_mq_start_hw_queues(msb->queue);
blk_start_queue(msb->queue);
spin_unlock_irqrestore(&msb->q_lock, flags);
} }
static void mspro_block_submit_req(struct request_queue *q) static blk_status_t mspro_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *bd)
{ {
struct memstick_dev *card = q->queuedata; struct memstick_dev *card = hctx->queue->queuedata;
struct mspro_block_data *msb = memstick_get_drvdata(card); struct mspro_block_data *msb = memstick_get_drvdata(card);
struct request *req = NULL;
if (msb->has_request) spin_lock_irq(&msb->q_lock);
return;
if (msb->eject) { if (msb->block_req) {
while ((req = blk_fetch_request(q)) != NULL) spin_unlock_irq(&msb->q_lock);
__blk_end_request_all(req, BLK_STS_IOERR); return BLK_STS_DEV_RESOURCE;
}
return; if (msb->eject) {
spin_unlock_irq(&msb->q_lock);
blk_mq_start_request(bd->rq);
return BLK_STS_IOERR;
} }
msb->has_request = 1; msb->block_req = bd->rq;
if (mspro_block_issue_req(card, 0)) blk_mq_start_request(bd->rq);
msb->has_request = 0;
if (mspro_block_issue_req(card, true))
msb->block_req = NULL;
spin_unlock_irq(&msb->q_lock);
return BLK_STS_OK;
} }
/*** Initialization ***/ /*** Initialization ***/
...@@ -1167,6 +1173,10 @@ static int mspro_block_init_card(struct memstick_dev *card) ...@@ -1167,6 +1173,10 @@ static int mspro_block_init_card(struct memstick_dev *card)
} }
static const struct blk_mq_ops mspro_mq_ops = {
.queue_rq = mspro_queue_rq,
};
static int mspro_block_init_disk(struct memstick_dev *card) static int mspro_block_init_disk(struct memstick_dev *card)
{ {
struct mspro_block_data *msb = memstick_get_drvdata(card); struct mspro_block_data *msb = memstick_get_drvdata(card);
...@@ -1206,9 +1216,11 @@ static int mspro_block_init_disk(struct memstick_dev *card) ...@@ -1206,9 +1216,11 @@ static int mspro_block_init_disk(struct memstick_dev *card)
goto out_release_id; goto out_release_id;
} }
msb->queue = blk_init_queue(mspro_block_submit_req, &msb->q_lock); msb->queue = blk_mq_init_sq_queue(&msb->tag_set, &mspro_mq_ops, 2,
if (!msb->queue) { BLK_MQ_F_SHOULD_MERGE);
rc = -ENOMEM; if (IS_ERR(msb->queue)) {
rc = PTR_ERR(msb->queue);
msb->queue = NULL;
goto out_put_disk; goto out_put_disk;
} }
...@@ -1318,13 +1330,14 @@ static void mspro_block_remove(struct memstick_dev *card) ...@@ -1318,13 +1330,14 @@ static void mspro_block_remove(struct memstick_dev *card)
spin_lock_irqsave(&msb->q_lock, flags); spin_lock_irqsave(&msb->q_lock, flags);
msb->eject = 1; msb->eject = 1;
blk_start_queue(msb->queue);
spin_unlock_irqrestore(&msb->q_lock, flags); spin_unlock_irqrestore(&msb->q_lock, flags);
blk_mq_start_hw_queues(msb->queue);
del_gendisk(msb->disk); del_gendisk(msb->disk);
dev_dbg(&card->dev, "mspro block remove\n"); dev_dbg(&card->dev, "mspro block remove\n");
blk_cleanup_queue(msb->queue); blk_cleanup_queue(msb->queue);
blk_mq_free_tag_set(&msb->tag_set);
msb->queue = NULL; msb->queue = NULL;
sysfs_remove_group(&card->dev.kobj, &msb->attr_group); sysfs_remove_group(&card->dev.kobj, &msb->attr_group);
...@@ -1344,8 +1357,9 @@ static int mspro_block_suspend(struct memstick_dev *card, pm_message_t state) ...@@ -1344,8 +1357,9 @@ static int mspro_block_suspend(struct memstick_dev *card, pm_message_t state)
struct mspro_block_data *msb = memstick_get_drvdata(card); struct mspro_block_data *msb = memstick_get_drvdata(card);
unsigned long flags; unsigned long flags;
blk_mq_stop_hw_queues(msb->queue);
spin_lock_irqsave(&msb->q_lock, flags); spin_lock_irqsave(&msb->q_lock, flags);
blk_stop_queue(msb->queue);
msb->active = 0; msb->active = 0;
spin_unlock_irqrestore(&msb->q_lock, flags); spin_unlock_irqrestore(&msb->q_lock, flags);
...@@ -1355,7 +1369,6 @@ static int mspro_block_suspend(struct memstick_dev *card, pm_message_t state) ...@@ -1355,7 +1369,6 @@ static int mspro_block_suspend(struct memstick_dev *card, pm_message_t state)
static int mspro_block_resume(struct memstick_dev *card) static int mspro_block_resume(struct memstick_dev *card)
{ {
struct mspro_block_data *msb = memstick_get_drvdata(card); struct mspro_block_data *msb = memstick_get_drvdata(card);
unsigned long flags;
int rc = 0; int rc = 0;
#ifdef CONFIG_MEMSTICK_UNSAFE_RESUME #ifdef CONFIG_MEMSTICK_UNSAFE_RESUME
...@@ -1401,9 +1414,7 @@ static int mspro_block_resume(struct memstick_dev *card) ...@@ -1401,9 +1414,7 @@ static int mspro_block_resume(struct memstick_dev *card)
#endif /* CONFIG_MEMSTICK_UNSAFE_RESUME */ #endif /* CONFIG_MEMSTICK_UNSAFE_RESUME */
spin_lock_irqsave(&msb->q_lock, flags); blk_mq_start_hw_queues(msb->queue);
blk_start_queue(msb->queue);
spin_unlock_irqrestore(&msb->q_lock, flags);
return rc; return rc;
} }
......
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