Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

paride: convert pd to blk-mq

parent 89c6b165
Loading
Loading
Loading
Loading
+66 −28
Original line number Diff line number Diff line
@@ -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);
		}