From: Igor Mitsyanko <i.mitsyanko@gmail.com>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, aliguori@us.ibm.com,
i.mitsyanko@gmail.com, sw@weilnetz.de,
peter.crosthwaite@xilinx.com, blauwirbel@gmail.com,
paul@codesourcery.com, stefanha@redhat.com, pbonzini@redhat.com,
afaerber@suse.de
Subject: [Qemu-devel] [RFC 5/7] sd.c: introduce async read operation
Date: Fri, 10 May 2013 20:10:23 +0400 [thread overview]
Message-ID: <1368202225-45798-6-git-send-email-i.mitsyanko@gmail.com> (raw)
In-Reply-To: <1368202225-45798-1-git-send-email-i.mitsyanko@gmail.com>
It will only be used if start bit and databusy callbacks were initialized
by user of SD card model.
Signed-off-by: Igor Mitsyanko <i.mitsyanko@gmail.com>
---
hw/sd/sd.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 77 insertions(+), 8 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index a0bbbaa..659ec56 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -685,6 +685,44 @@ static void sd_lock_command(SDState *sd)
sd->card_status &= ~CARD_IS_LOCKED;
}
+static void sd_bdrv_read_done(void *opaque, int ret)
+{
+ SDState *sd = opaque;
+ uint32_t io_len, offset;
+ uint64_t end_sector;
+
+ DPRINTF("sd_bdrv_read_done ret = %d, \n", ret);
+ sd->aiocb = NULL;
+
+ if (ret != 0) {
+ return;
+ }
+
+ if (sd->state != sd_sendingdata_state) {
+ DPRINTF("Transfer was aborted\n");
+ return;
+ }
+
+ io_len = (sd->ocr & (1 << 30)) ? 512 : sd->blk_len;
+ end_sector = (sd->data_start + io_len - 1) >> BDRV_SECTOR_BITS;
+ offset = (sd->data_start + sd->transf_cnt) & ~BDRV_SECTOR_MASK;
+
+ if (end_sector >
+ (sd->data_start + sd->transf_cnt) >> BDRV_SECTOR_BITS) {
+ memcpy(sd->data, sd->buf + offset, BDRV_SECTOR_SIZE - offset);
+ sd->transf_cnt += BDRV_SECTOR_SIZE - offset;
+ sd->aiocb = bdrv_aio_readv(sd->bdrv, end_sector, &sd->qiov, 1,
+ sd_bdrv_read_done, sd);
+ return;
+ } else {
+ memcpy(sd->data + sd->transf_cnt, sd->buf + offset,
+ io_len - sd->transf_cnt);
+ sd->transf_cnt += io_len - sd->transf_cnt;
+ }
+
+ qemu_irq_raise(sd->start_bit_cb);
+}
+
static sd_rsp_type_t sd_normal_command(SDState *sd,
SDRequest req)
{
@@ -891,8 +929,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
sd->data_start = req.arg;
sd->data_offset = 0;
- if (sd->data_start + sd->blk_len > sd->size)
+ if (sd->data_start + sd->blk_len > sd->size) {
sd->card_status |= ADDRESS_ERROR;
+ } else if (sd->iov.iov_base) {
+ sd->aiocb = bdrv_aio_readv(sd->bdrv,
+ sd->data_start >> BDRV_SECTOR_BITS,
+ &sd->qiov, 1, sd_bdrv_read_done, sd);
+ }
return sd_r0;
default:
@@ -904,6 +947,11 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
switch (sd->state) {
case sd_sendingdata_state:
sd->state = sd_transfer_state;
+ sd->transf_cnt = 0;
+ if (sd->aiocb) {
+ bdrv_aio_cancel(sd->aiocb);
+ sd->aiocb = NULL;
+ }
return sd_r1b;
case sd_receivingdata_state:
@@ -969,8 +1017,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
sd->data_start = addr;
sd->data_offset = 0;
- if (sd->data_start + sd->blk_len > sd->size)
+ if (sd->data_start + sd->blk_len > sd->size) {
sd->card_status |= ADDRESS_ERROR;
+ } else {
+ sd->aiocb = bdrv_aio_readv(sd->bdrv,
+ sd->data_start >> BDRV_SECTOR_BITS,
+ &sd->qiov, 1, sd_bdrv_read_done, sd);
+ }
return sd_r1;
default:
@@ -985,8 +1038,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
sd->data_start = addr;
sd->data_offset = 0;
- if (sd->data_start + sd->blk_len > sd->size)
+ if (sd->data_start + sd->blk_len > sd->size) {
sd->card_status |= ADDRESS_ERROR;
+ } else {
+ sd->aiocb = bdrv_aio_readv(sd->bdrv,
+ sd->data_start >> BDRV_SECTOR_BITS,
+ &sd->qiov, 1, sd_bdrv_read_done, sd);
+ }
return sd_r1;
default:
@@ -1706,16 +1764,21 @@ uint8_t sd_read_data(SDState *sd)
break;
case 11: /* CMD11: READ_DAT_UNTIL_STOP */
- if (sd->data_offset == 0)
+ if (sd->data_offset == 0 && sd->iov.iov_base == NULL) {
BLK_READ_BLOCK(sd->data_start, io_len);
+ }
ret = sd->data[sd->data_offset ++];
if (sd->data_offset >= io_len) {
sd->data_start += io_len;
sd->data_offset = 0;
+ sd->transf_cnt = 0;
if (sd->data_start + io_len > sd->size) {
sd->card_status |= ADDRESS_ERROR;
- break;
+ } else if (sd->iov.iov_base) {
+ sd->aiocb = bdrv_aio_readv(sd->bdrv,
+ sd->data_start >> BDRV_SECTOR_BITS,
+ &sd->qiov, 1, sd_bdrv_read_done, sd);
}
}
break;
@@ -1728,8 +1791,9 @@ uint8_t sd_read_data(SDState *sd)
break;
case 17: /* CMD17: READ_SINGLE_BLOCK */
- if (sd->data_offset == 0)
+ if (sd->data_offset == 0 && sd->iov.iov_base == NULL) {
BLK_READ_BLOCK(sd->data_start, io_len);
+ }
ret = sd->data[sd->data_offset ++];
if (sd->data_offset >= io_len)
@@ -1737,16 +1801,21 @@ uint8_t sd_read_data(SDState *sd)
break;
case 18: /* CMD18: READ_MULTIPLE_BLOCK */
- if (sd->data_offset == 0)
+ if (sd->data_offset == 0 && sd->iov.iov_base == NULL) {
BLK_READ_BLOCK(sd->data_start, io_len);
+ }
ret = sd->data[sd->data_offset ++];
if (sd->data_offset >= io_len) {
sd->data_start += io_len;
sd->data_offset = 0;
+ sd->transf_cnt = 0;
if (sd->data_start + io_len > sd->size) {
sd->card_status |= ADDRESS_ERROR;
- break;
+ } else if (sd->iov.iov_base) {
+ sd->aiocb = bdrv_aio_readv(sd->bdrv,
+ sd->data_start >> BDRV_SECTOR_BITS,
+ &sd->qiov, 1, sd_bdrv_read_done, sd);
}
}
break;
--
1.8.1.4
next prev parent reply other threads:[~2013-05-10 16:10 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-10 16:10 [Qemu-devel] [RFC 0/7] Convert SD card model to AIO Igor Mitsyanko
2013-05-10 16:10 ` [Qemu-devel] [RFC 1/7] sd.c: introduce AIO related members in SD state Igor Mitsyanko
2013-05-10 16:10 ` [Qemu-devel] [RFC 2/7] sd.c: introduce variable for trekking valid data Igor Mitsyanko
2013-06-14 11:49 ` Peter Maydell
2013-06-17 12:30 ` Stefan Hajnoczi
2013-06-17 14:03 ` Paolo Bonzini
2013-05-10 16:10 ` [Qemu-devel] [RFC 3/7] sd.c: introduce "start bit" and "busy deasserted" callbacks Igor Mitsyanko
2013-06-14 11:51 ` Peter Maydell
2013-05-10 16:10 ` [Qemu-devel] [RFC 4/7] sd.c: use callbacks as a flag to use async IO Igor Mitsyanko
2013-05-10 16:10 ` Igor Mitsyanko [this message]
2013-05-13 12:10 ` [Qemu-devel] [RFC 5/7] sd.c: introduce async read operation Stefan Hajnoczi
2013-05-10 16:10 ` [Qemu-devel] [RFC 6/7] sd.c: introduce async write interface Igor Mitsyanko
2013-06-14 12:09 ` Peter Maydell
2013-05-10 16:10 ` [Qemu-devel] [RFC 7/7] pl181.c: convert to async IO SD card interface Igor Mitsyanko
2013-06-14 12:05 ` Peter Maydell
2013-05-13 12:13 ` [Qemu-devel] [RFC 0/7] Convert SD card model to AIO Stefan Hajnoczi
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=1368202225-45798-6-git-send-email-i.mitsyanko@gmail.com \
--to=i.mitsyanko@gmail.com \
--cc=afaerber@suse.de \
--cc=aliguori@us.ibm.com \
--cc=blauwirbel@gmail.com \
--cc=paul@codesourcery.com \
--cc=pbonzini@redhat.com \
--cc=peter.crosthwaite@xilinx.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--cc=sw@weilnetz.de \
/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;
as well as URLs for NNTP newsgroup(s).