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

Commit a03bb5a3 authored by Tejun Heo's avatar Tejun Heo Committed by Jens Axboe
Browse files

mg_disk: clean up request completion paths



mg_disk implements its own partial completion.  Convert to standard
block layer partial completion.

[ Impact: cleanup ]

Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Cc: unsik Kim <donari75@gmail.com>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent eec94620
Loading
Loading
Loading
Loading
+33 −84
Original line number Original line Diff line number Diff line
@@ -503,95 +503,68 @@ static unsigned int mg_out(struct mg_host *host,


static void mg_read(struct request *req)
static void mg_read(struct request *req)
{
{
	u32 remains, j;
	u32 j;
	struct mg_host *host = req->rq_disk->private_data;
	struct mg_host *host = req->rq_disk->private_data;


	remains = req->nr_sectors;

	if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, NULL) !=
	if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, NULL) !=
			MG_ERR_NONE)
			MG_ERR_NONE)
		mg_bad_rw_intr(host);
		mg_bad_rw_intr(host);


	MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
	MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
			remains, req->sector, req->buffer);
	       req->nr_sectors, req->sector, req->buffer);

	do {
		u16 *buff = (u16 *)req->buffer;


	while (remains) {
		if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
		if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
					MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) {
					MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) {
			mg_bad_rw_intr(host);
			mg_bad_rw_intr(host);
			return;
			return;
		}
		}
		for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) {
		for (j = 0; j < MG_SECTOR_SIZE >> 1; j++)
			*(u16 *)req->buffer =
			*buff++ = inw((unsigned long)host->dev_base +
				inw((unsigned long)host->dev_base +
				      MG_BUFF_OFFSET + (j << 1));
				      MG_BUFF_OFFSET + (j << 1));
			req->buffer += 2;
		}

		req->sector++;
		req->errors = 0;
		remains = --req->nr_sectors;
		--req->current_nr_sectors;

		if (req->current_nr_sectors <= 0) {
			MG_DBG("remain : %d sects\n", remains);
			__blk_end_request_cur(req, 0);
			if (remains > 0)
				req = elv_next_request(host->breq);
		}


		outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base +
		outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base +
				MG_REG_COMMAND);
				MG_REG_COMMAND);
	}
	} while (__blk_end_request(req, 0, MG_SECTOR_SIZE));
}
}


static void mg_write(struct request *req)
static void mg_write(struct request *req)
{
{
	u32 remains, j;
	u32 j;
	struct mg_host *host = req->rq_disk->private_data;
	struct mg_host *host = req->rq_disk->private_data;


	remains = req->nr_sectors;

	if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, NULL) !=
	if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, NULL) !=
			MG_ERR_NONE) {
			MG_ERR_NONE) {
		mg_bad_rw_intr(host);
		mg_bad_rw_intr(host);
		return;
		return;
	}
	}



	MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
	MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
			remains, req->sector, req->buffer);
	       req->nr_sectors, req->sector, req->buffer);
	while (remains) {

	do {
		u16 *buff = (u16 *)req->buffer;

		if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
		if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ,
					MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
					MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
			mg_bad_rw_intr(host);
			mg_bad_rw_intr(host);
			return;
			return;
		}
		}
		for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) {
		for (j = 0; j < MG_SECTOR_SIZE >> 1; j++)
			outw(*(u16 *)req->buffer,
			outw(*buff++, (unsigned long)host->dev_base +
					(unsigned long)host->dev_base +
				      MG_BUFF_OFFSET + (j << 1));
				      MG_BUFF_OFFSET + (j << 1));
			req->buffer += 2;
		}
		req->sector++;
		remains = --req->nr_sectors;
		--req->current_nr_sectors;

		if (req->current_nr_sectors <= 0) {
			MG_DBG("remain : %d sects\n", remains);
			__blk_end_request_cur(req, 0);
			if (remains > 0)
				req = elv_next_request(host->breq);
		}


		outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
		outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
				MG_REG_COMMAND);
				MG_REG_COMMAND);
	}
	} while (__blk_end_request(req, 0, MG_SECTOR_SIZE));
}
}


static void mg_read_intr(struct mg_host *host)
static void mg_read_intr(struct mg_host *host)
{
{
	u32 i;
	u32 i;
	u16 *buff;
	struct request *req;
	struct request *req;


	/* check status */
	/* check status */
@@ -612,39 +585,24 @@ static void mg_read_intr(struct mg_host *host)
ok_to_read:
ok_to_read:
	/* get current segment of request */
	/* get current segment of request */
	req = elv_next_request(host->breq);
	req = elv_next_request(host->breq);
	buff = (u16 *)req->buffer;


	/* read 1 sector */
	/* read 1 sector */
	for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) {
	for (i = 0; i < MG_SECTOR_SIZE >> 1; i++)
		*(u16 *)req->buffer =
		*buff++ = inw((unsigned long)host->dev_base + MG_BUFF_OFFSET +
			inw((unsigned long)host->dev_base + MG_BUFF_OFFSET +
			      (i << 1));
			      (i << 1));
		req->buffer += 2;
	}


	/* manipulate request */
	MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n",
	MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n",
			req->sector, req->nr_sectors - 1, req->buffer);
			req->sector, req->nr_sectors - 1, req->buffer);


	req->sector++;
	/* send read confirm */
	req->errors = 0;
	outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
	i = --req->nr_sectors;
	--req->current_nr_sectors;

	/* let know if current segment done */
	if (req->current_nr_sectors <= 0)
		__blk_end_request_cur(req, 0);


	if (__blk_end_request(req, 0, MG_SECTOR_SIZE)) {
		/* set handler if read remains */
		/* set handler if read remains */
	if (i > 0) {
		host->mg_do_intr = mg_read_intr;
		host->mg_do_intr = mg_read_intr;
		mod_timer(&host->timer, jiffies + 3 * HZ);
		mod_timer(&host->timer, jiffies + 3 * HZ);
	}
	} else /* goto next request */

	/* send read confirm */
	outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);

	/* goto next request */
	if (!i)
		mg_request(host->breq);
		mg_request(host->breq);
}
}


@@ -653,6 +611,7 @@ static void mg_write_intr(struct mg_host *host)
	u32 i, j;
	u32 i, j;
	u16 *buff;
	u16 *buff;
	struct request *req;
	struct request *req;
	bool rem;


	/* get current segment of request */
	/* get current segment of request */
	req = elv_next_request(host->breq);
	req = elv_next_request(host->breq);
@@ -673,18 +632,8 @@ static void mg_write_intr(struct mg_host *host)
	return;
	return;


ok_to_write:
ok_to_write:
	/* manipulate request */
	if ((rem = __blk_end_request(req, 0, MG_SECTOR_SIZE))) {
	req->sector++;
	i = --req->nr_sectors;
	--req->current_nr_sectors;
	req->buffer += MG_SECTOR_SIZE;

	/* let know if current segment or all done */
	if (!i || (req->bio && req->current_nr_sectors <= 0))
		__blk_end_request_cur(req, 0);

		/* write 1 sector and set handler if remains */
		/* write 1 sector and set handler if remains */
	if (i > 0) {
		buff = (u16 *)req->buffer;
		buff = (u16 *)req->buffer;
		for (j = 0; j < MG_STORAGE_BUFFER_SIZE >> 1; j++) {
		for (j = 0; j < MG_STORAGE_BUFFER_SIZE >> 1; j++) {
			outw(*buff, (unsigned long)host->dev_base +
			outw(*buff, (unsigned long)host->dev_base +
@@ -700,7 +649,7 @@ static void mg_write_intr(struct mg_host *host)
	/* send write confirm */
	/* send write confirm */
	outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
	outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);


	if (!i)
	if (!rem)
		mg_request(host->breq);
		mg_request(host->breq);
}
}