mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: unsik Kim <donari75@gmail.com>
To: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Cc: Tejun Heo <tj@kernel.org>, linux-kernel@vger.kernel.org
Subject: Re: [PATCH][RESEND] mg_disk: fix issue with data integrity on error  in mg_write()
Date: Fri, 3 Jul 2009 10:50:19 +0900	[thread overview]
Message-ID: <57afda040907021850w107d7734u962e4d86efb2b266@mail.gmail.com> (raw)
In-Reply-To: <200906282015.00854.bzolnier@gmail.com>

2009/6/29 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>:
> From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
> Subject: [PATCH] mg_disk: fix issue with data integrity on error in mg_write()
>
> We cannot acknowledge the sector write before checking its status
> (which is done on the next loop iteration) and we also need to do
> the final status register check after writing the last sector.

Right. Current mg_disk polling driver doesn't check status register
(should be ready status) after writing last sector. Thanks.


>  static void mg_write(struct request *req)
>  {
> -       u32 j;
>        struct mg_host *host = req->rq_disk->private_data;
> +       bool rem;
>
>        if (mg_out(host, blk_rq_pos(req), blk_rq_sectors(req),
>                   MG_CMD_WR, NULL) != MG_ERR_NONE) {
> @@ -512,27 +527,37 @@ static void mg_write(struct request *req
>        MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
>               blk_rq_sectors(req), blk_rq_pos(req), req->buffer);
>
> -       do {
> -               u16 *buff = (u16 *)req->buffer;
> +       if (mg_wait(host, ATA_DRQ,
> +                   MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
> +               mg_bad_rw_intr(host);
> +               return;
> +       }
> +
> +       mg_write_one(host, req);
> +
> +       outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
>
> -       if (mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
> +       do {
> +               if (blk_rq_sectors(req) > 1 &&
> +                    mg_wait(host, ATA_DRQ,
> +                            MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
>                        mg_bad_rw_intr(host);
>                        return;
>                }
> -               for (j = 0; j < MG_SECTOR_SIZE >> 1; j++)
> -                       outw(*buff++, (unsigned long)host->dev_base +
> -                                     MG_BUFF_OFFSET + (j << 1));
>
> -               outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
> -                               MG_REG_COMMAND);
> -       } while (mg_end_request(host, 0, MG_SECTOR_SIZE));
> +               rem = mg_end_request(host, 0, MG_SECTOR_SIZE);
> +               if (rem)
> +                       mg_write_one(host, req);
> +
> +               outb(MG_CMD_WR_CONF,
> +                    (unsigned long)host->dev_base + MG_REG_COMMAND);
> +       } while (rem);
>  }

I think checking ready status after do-while loop is enough.

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

	if (mg_out(host, blk_rq_pos(req), blk_rq_sectors(req),
		   MG_CMD_WR, NULL) != MG_ERR_NONE) {
		mg_bad_rw_intr(host);
		return;
	}

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

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

		if (mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_WR_DRQ) !=
				MG_ERR_NONE) {
			mg_bad_rw_intr(host);
			return;
		}
		for (j = 0; j < MG_SECTOR_SIZE >> 1; j++)
			outw(*buff++, (unsigned long)host->dev_base +
				      MG_BUFF_OFFSET + (j << 1));

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

+	if (mg_wait(host, MG_STAT_READY, MG_TMAX_WAIT_WR_DRQ) !=
+			MG_ERR_NONE)
+		mg_bad_rw_intr(host);
}

---
Regards,
unsik Kim <donari75@gmail.com>

  reply	other threads:[~2009-07-03  1:50 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-28 18:14 Bartlomiej Zolnierkiewicz
2009-07-03  1:50 ` unsik Kim [this message]
2009-07-03 13:16   ` Bartlomiej Zolnierkiewicz
2009-07-23  4:21     ` [PATCH] mg_disk: Add missing ready status check on mg_write() unsik Kim
2009-07-24 10:41       ` Bartlomiej Zolnierkiewicz
2009-07-23 11:15         ` unsik Kim
2009-07-27 20:48       ` Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=57afda040907021850w107d7734u962e4d86efb2b266@mail.gmail.com \
    --to=donari75@gmail.com \
    --cc=bzolnier@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®