[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 3/7] sd.c: introduce "start bit" and "busy deasserted"
From: |
Igor Mitsyanko |
Subject: |
[Qemu-devel] [RFC 3/7] sd.c: introduce "start bit" and "busy deasserted" callbacks |
Date: |
Fri, 10 May 2013 20:10:21 +0400 |
Start bit callback models arrival of first bit of data on card's DAT line.
Busy deasserted callback models releasing of DAT0 line by card when it
transitions from a programming state to a writing data state.
Both of them will be used for async IO later.
Signed-off-by: Igor Mitsyanko <address@hidden>
---
hw/sd/omap_mmc.c | 6 +++---
hw/sd/pl181.c | 2 +-
hw/sd/pxa2xx_mmci.c | 2 +-
hw/sd/sd.c | 24 +++++++++++++++++++++---
hw/sd/sdhci.c | 4 ++--
include/hw/sd.h | 3 ++-
6 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
index d4079cd..94580bb 100644
--- a/hw/sd/omap_mmc.c
+++ b/hw/sd/omap_mmc.c
@@ -620,7 +620,7 @@ struct omap_mmc_s *omap2_mmc_init(struct
omap_target_agent_s *ta,
s->card = sd_init(bd, 0);
s->cdet = qemu_allocate_irqs(omap_mmc_cover_cb, s, 1)[0];
- sd_set_cb(s->card, NULL, s->cdet);
+ sd_set_cb(s->card, NULL, s->cdet, NULL, NULL);
return s;
}
@@ -628,11 +628,11 @@ struct omap_mmc_s *omap2_mmc_init(struct
omap_target_agent_s *ta,
void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover)
{
if (s->cdet) {
- sd_set_cb(s->card, ro, s->cdet);
+ sd_set_cb(s->card, ro, s->cdet, NULL, NULL);
s->coverswitch = cover;
qemu_set_irq(cover, s->cdet_state);
} else
- sd_set_cb(s->card, ro, cover);
+ sd_set_cb(s->card, ro, cover, NULL, NULL);
}
void omap_mmc_enable(struct omap_mmc_s *s, int enable)
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
index 2527296..2caacc2 100644
--- a/hw/sd/pl181.c
+++ b/hw/sd/pl181.c
@@ -471,7 +471,7 @@ static void pl181_reset(DeviceState *d)
s->mask[1] = 0;
/* We can assume our GPIO outputs have been wired up now */
- sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1]);
+ sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1], NULL, NULL);
}
static int pl181_init(SysBusDevice *dev)
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
index 2db1cab..64a3050 100644
--- a/hw/sd/pxa2xx_mmci.c
+++ b/hw/sd/pxa2xx_mmci.c
@@ -549,5 +549,5 @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
qemu_irq coverswitch)
{
- sd_set_cb(s->card, readonly, coverswitch);
+ sd_set_cb(s->card, readonly, coverswitch, NULL, NULL);
}
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 775a55c..2e75201 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -108,6 +108,8 @@ struct SDState {
uint8_t data[512];
qemu_irq readonly_cb;
qemu_irq inserted_cb;
+ qemu_irq start_bit_cb;
+ qemu_irq datbusy_cb;
BlockDriverState *bdrv;
uint8_t *buf;
@@ -519,10 +521,13 @@ SDState *sd_init(BlockDriverState *bs, bool is_spi)
return sd;
}
-void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert)
+void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert,
+ qemu_irq startbit, qemu_irq endbusy)
{
sd->readonly_cb = readonly;
sd->inserted_cb = insert;
+ sd->start_bit_cb = startbit;
+ sd->datbusy_cb = endbusy;
qemu_set_irq(readonly, sd->bdrv ? bdrv_is_read_only(sd->bdrv) : 0);
qemu_set_irq(insert, sd->bdrv ? bdrv_is_inserted(sd->bdrv) : 0);
}
@@ -762,6 +767,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
sd->state = sd_sendingdata_state;
sd->data_start = 0;
sd->data_offset = 0;
+ qemu_irq_raise(sd->start_bit_cb);
return sd_r1;
default:
@@ -841,6 +847,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
memcpy(sd->data, sd->csd, 16);
sd->data_start = addr;
sd->data_offset = 0;
+ qemu_irq_raise(sd->start_bit_cb);
return sd_r1;
default:
@@ -863,6 +870,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
memcpy(sd->data, sd->cid, 16);
sd->data_start = addr;
sd->data_offset = 0;
+ qemu_irq_raise(sd->start_bit_cb);
return sd_r1;
default:
@@ -1111,6 +1119,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
*(uint32_t *) sd->data = sd_wpbits(sd, req.arg);
sd->data_start = addr;
sd->data_offset = 0;
+ qemu_irq_raise(sd->start_bit_cb);
return sd_r1b;
default:
@@ -1201,10 +1210,12 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
switch (sd->state) {
case sd_transfer_state:
sd->data_offset = 0;
- if (req.arg & 1)
+ if (req.arg & 1) {
sd->state = sd_sendingdata_state;
- else
+ qemu_irq_raise(sd->start_bit_cb);
+ } else {
sd->state = sd_receivingdata_state;
+ }
return sd_r1;
default:
@@ -1251,6 +1262,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
sd->state = sd_sendingdata_state;
sd->data_start = 0;
sd->data_offset = 0;
+ qemu_irq_raise(sd->start_bit_cb);
return sd_r1;
default:
@@ -1266,6 +1278,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
sd->state = sd_sendingdata_state;
sd->data_start = 0;
sd->data_offset = 0;
+ qemu_irq_raise(sd->start_bit_cb);
return sd_r1;
default:
@@ -1319,6 +1332,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
sd->state = sd_sendingdata_state;
sd->data_start = 0;
sd->data_offset = 0;
+ qemu_irq_raise(sd->start_bit_cb);
return sd_r1;
default:
@@ -1596,6 +1610,7 @@ void sd_write_data(SDState *sd, uint8_t value)
}
/* Bzzzzzzztt .... Operation complete. */
sd->state = sd_transfer_state;
+ qemu_irq_raise(sd->datbusy_cb);
}
break;
@@ -1620,6 +1635,7 @@ void sd_write_data(SDState *sd, uint8_t value)
}
/* Bzzzzzzztt .... Operation complete. */
sd->state = sd_transfer_state;
+ qemu_irq_raise(sd->datbusy_cb);
}
break;
@@ -1631,6 +1647,7 @@ void sd_write_data(SDState *sd, uint8_t value)
sd_lock_command(sd);
/* Bzzzzzzztt .... Operation complete. */
sd->state = sd_transfer_state;
+ qemu_irq_raise(sd->datbusy_cb);
}
break;
@@ -1639,6 +1656,7 @@ void sd_write_data(SDState *sd, uint8_t value)
if (sd->data_offset >= sd->blk_len) {
APP_WRITE_BLOCK(sd->data_start, sd->data_offset);
sd->state = sd_transfer_state;
+ qemu_irq_raise(sd->datbusy_cb);
}
break;
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 91dc9b0..bb33368 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -193,7 +193,7 @@ static void sdhci_reset(SDHCIState *s)
* initialization */
memset(&s->sdmasysad, 0, (uintptr_t)&s->capareg -
(uintptr_t)&s->sdmasysad);
- sd_set_cb(s->card, s->ro_cb, s->eject_cb);
+ sd_set_cb(s->card, s->ro_cb, s->eject_cb, NULL, NULL);
s->data_count = 0;
s->stopped_state = sdhc_not_stopped;
}
@@ -1168,7 +1168,7 @@ static void sdhci_initfn(Object *obj)
s->card = sd_init(di ? di->bdrv : NULL, 0);
s->eject_cb = qemu_allocate_irqs(sdhci_insert_eject_cb, s, 1)[0];
s->ro_cb = qemu_allocate_irqs(sdhci_card_readonly_cb, s, 1)[0];
- sd_set_cb(s->card, s->ro_cb, s->eject_cb);
+ sd_set_cb(s->card, s->ro_cb, s->eject_cb, NULL, NULL);
s->insert_timer = qemu_new_timer_ns(vm_clock, sdhci_raise_insertion_irq,
s);
s->transfer_timer = qemu_new_timer_ns(vm_clock, sdhci_do_data_transfer, s);
diff --git a/include/hw/sd.h b/include/hw/sd.h
index d9b97e4..a7024d4 100644
--- a/include/hw/sd.h
+++ b/include/hw/sd.h
@@ -73,7 +73,8 @@ int sd_do_command(SDState *sd, SDRequest *req,
uint8_t *response);
void sd_write_data(SDState *sd, uint8_t value);
uint8_t sd_read_data(SDState *sd);
-void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert);
+void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert,
+ qemu_irq startbit, qemu_irq endbusy);
bool sd_data_ready(SDState *sd);
void sd_enable(SDState *sd, bool enable);
--
1.8.1.4
- [Qemu-devel] [RFC 0/7] Convert SD card model to AIO, Igor Mitsyanko, 2013/05/10
- [Qemu-devel] [RFC 1/7] sd.c: introduce AIO related members in SD state, Igor Mitsyanko, 2013/05/10
- [Qemu-devel] [RFC 2/7] sd.c: introduce variable for trekking valid data, Igor Mitsyanko, 2013/05/10
- [Qemu-devel] [RFC 3/7] sd.c: introduce "start bit" and "busy deasserted" callbacks,
Igor Mitsyanko <=
- [Qemu-devel] [RFC 4/7] sd.c: use callbacks as a flag to use async IO, Igor Mitsyanko, 2013/05/10
- [Qemu-devel] [RFC 5/7] sd.c: introduce async read operation, Igor Mitsyanko, 2013/05/10
- [Qemu-devel] [RFC 6/7] sd.c: introduce async write interface, Igor Mitsyanko, 2013/05/10
- [Qemu-devel] [RFC 7/7] pl181.c: convert to async IO SD card interface, Igor Mitsyanko, 2013/05/10
- Re: [Qemu-devel] [RFC 0/7] Convert SD card model to AIO, Stefan Hajnoczi, 2013/05/13