Re: [Qemu-devel] [RFC PATCH v3 5/7] hw/sd/pl181: expose a SDBus and connect the SDCard to it

2018-02-22 Thread Peter Maydell
On 16 February 2018 at 02:29, Philippe Mathieu-Daudé  wrote:
> using the sdbus_*() API.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>
> RFC because how pl181_sdbus_create_inplace() doing class_init(SDBus) in
> realize(pl181) seems weird...

In the two other places where we set the set_inserted and set_readonly
methods for the SDBus class (pxa2xx_mmci.c and sdhci.c), we do it by
defining a subclass of TYPE_SD_BUS, whose class init function can then
set up the method pointers. Is there a reason not to do pl181 the
same way as those two examples?

thanks
-- PMM



Re: [Qemu-devel] [RFC PATCH v3 5/7] hw/sd/pl181: expose a SDBus and connect the SDCard to it

2018-02-22 Thread Philippe Mathieu-Daudé
ping? :)

On 02/15/2018 11:29 PM, Philippe Mathieu-Daudé wrote:
> using the sdbus_*() API.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
> 
> RFC because how pl181_sdbus_create_inplace() doing class_init(SDBus) in
> realize(pl181) seems weird...
> 
> from http://lists.nongnu.org/archive/html/qemu-devel/2018-02/msg01268.html:
> 
> I think you have to change that sd_set_cb() code now.
> If you look at sd_cardchange() it uses "is this SD card
> object on an SDBus" to determine whether to notify the
> controller via the old-API IRQ lines, or using the
> set_inserted() and set_readonly() callbacks on the SDBusClass.
> 
> This previous series intended to enforce a cleaner OOP design, adding a
> TYPE_SD_BUS_MASTER_INTERFACE TypeInfo:
> 
> http://lists.nongnu.org/archive/html/qemu-devel/2017-12/msg02322.html
> http://lists.nongnu.org/archive/html/qemu-devel/2017-12/msg02326.html
> http://lists.nongnu.org/archive/html/qemu-devel/2017-12/msg02327.html
> ---
> 
>  hw/sd/pl181.c | 59 
> ---
>  1 file changed, 44 insertions(+), 15 deletions(-)
> 
> diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
> index 3ba1f7dd23..97e85e4a64 100644
> --- a/hw/sd/pl181.c
> +++ b/hw/sd/pl181.c
> @@ -33,7 +33,7 @@ typedef struct PL181State {
>  SysBusDevice parent_obj;
>  
>  MemoryRegion iomem;
> -SDState *card;
> +SDBus sdbus;
>  uint32_t clock;
>  uint32_t power;
>  uint32_t cmdarg;
> @@ -179,7 +179,7 @@ static void pl181_send_command(PL181State *s)
>  request.cmd = s->cmd & PL181_CMD_INDEX;
>  request.arg = s->cmdarg;
>  DPRINTF("Command %d %08x\n", request.cmd, request.arg);
> -rlen = sd_do_command(s->card, &request, response);
> +rlen = sdbus_do_command(&s->sdbus, &request, response);
>  if (rlen < 0)
>  goto error;
>  if (s->cmd & PL181_CMD_RESPONSE) {
> @@ -223,12 +223,12 @@ static void pl181_fifo_run(PL181State *s)
>  int is_read;
>  
>  is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0;
> -if (s->datacnt != 0 && (!is_read || sd_data_ready(s->card))
> +if (s->datacnt != 0 && (!is_read || sdbus_data_ready(&s->sdbus))
>  && !s->linux_hack) {
>  if (is_read) {
>  n = 0;
>  while (s->datacnt && s->fifo_len < PL181_FIFO_LEN) {
> -value |= (uint32_t)sd_read_data(s->card) << (n * 8);
> +value |= (uint32_t)sdbus_read_data(&s->sdbus) << (n * 8);
>  s->datacnt--;
>  n++;
>  if (n == 4) {
> @@ -249,7 +249,7 @@ static void pl181_fifo_run(PL181State *s)
>  }
>  n--;
>  s->datacnt--;
> -sd_write_data(s->card, value & 0xff);
> +sdbus_write_data(&s->sdbus, value & 0xff);
>  value >>= 8;
>  }
>  }
> @@ -477,13 +477,6 @@ static void pl181_reset(DeviceState *d)
>  s->linux_hack = 0;
>  s->mask[0] = 0;
>  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]);
> -/* Since we're still using the legacy SD API the card is not plugged
> - * into any bus, and we must reset it manually.
> - */
> -device_reset(DEVICE(s->card));
>  }
>  
>  static void pl181_init(Object *obj)
> @@ -499,16 +492,52 @@ static void pl181_init(Object *obj)
>  qdev_init_gpio_out(dev, s->cardstatus, 2);
>  }
>  
> +static void pl181_set_readonly(DeviceState *dev, bool level)
> +{
> +PL181State *s = (PL181State *)dev;
> +
> +qemu_set_irq(s->cardstatus[0], level);
> +}
> +
> +static void pl181_set_inserted(DeviceState *dev, bool level)
> +{
> +PL181State *s = (PL181State *)dev;
> +
> +qemu_set_irq(s->cardstatus[1], level);
> +}
> +
> +static void pl181_sdbus_create_inplace(SDBus *sdbus, DeviceState *dev)
> +{
> +SDBusClass *sbc;
> +
> +qbus_create_inplace(sdbus, sizeof(SDBus), TYPE_SD_BUS, dev, "sd-bus");
> +
> +/* pl181_sdbus_class_init */
> +sbc = SD_BUS_GET_CLASS(sdbus);
> +sbc->set_inserted = pl181_set_inserted;
> +sbc->set_readonly = pl181_set_readonly;
> +}
> +
>  static void pl181_realize(DeviceState *dev, Error **errp)
>  {
>  PL181State *s = PL181(dev);
> +DeviceState *carddev;
>  DriveInfo *dinfo;
> +Error *err = NULL;
> +
> +pl181_sdbus_create_inplace(&s->sdbus, dev);
>  
> +/* Create and plug in the sd card */
>  /* FIXME use a qdev drive property instead of drive_get_next() */
>  dinfo = drive_get_next(IF_SD);
> -s->card = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, false);
> -if (s->card == NULL) {
> -error_setg(errp, "sd_init failed");
> +carddev = qdev_create(&s->sdbus.qbus, TYPE_SD_CARD);
> +if (dinfo) {
> +qdev_prop_set_drive(carddev, "drive", blk_by_legacy_dinfo(dinfo), 
> &err);
> +}
> +object_property_set_bool(OBJECT(carddev), true

[Qemu-devel] [RFC PATCH v3 5/7] hw/sd/pl181: expose a SDBus and connect the SDCard to it

2018-02-15 Thread Philippe Mathieu-Daudé
using the sdbus_*() API.

Signed-off-by: Philippe Mathieu-Daudé 
---

RFC because how pl181_sdbus_create_inplace() doing class_init(SDBus) in
realize(pl181) seems weird...

from http://lists.nongnu.org/archive/html/qemu-devel/2018-02/msg01268.html:

I think you have to change that sd_set_cb() code now.
If you look at sd_cardchange() it uses "is this SD card
object on an SDBus" to determine whether to notify the
controller via the old-API IRQ lines, or using the
set_inserted() and set_readonly() callbacks on the SDBusClass.

This previous series intended to enforce a cleaner OOP design, adding a
TYPE_SD_BUS_MASTER_INTERFACE TypeInfo:

http://lists.nongnu.org/archive/html/qemu-devel/2017-12/msg02322.html
http://lists.nongnu.org/archive/html/qemu-devel/2017-12/msg02326.html
http://lists.nongnu.org/archive/html/qemu-devel/2017-12/msg02327.html
---

 hw/sd/pl181.c | 59 ---
 1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
index 3ba1f7dd23..97e85e4a64 100644
--- a/hw/sd/pl181.c
+++ b/hw/sd/pl181.c
@@ -33,7 +33,7 @@ typedef struct PL181State {
 SysBusDevice parent_obj;
 
 MemoryRegion iomem;
-SDState *card;
+SDBus sdbus;
 uint32_t clock;
 uint32_t power;
 uint32_t cmdarg;
@@ -179,7 +179,7 @@ static void pl181_send_command(PL181State *s)
 request.cmd = s->cmd & PL181_CMD_INDEX;
 request.arg = s->cmdarg;
 DPRINTF("Command %d %08x\n", request.cmd, request.arg);
-rlen = sd_do_command(s->card, &request, response);
+rlen = sdbus_do_command(&s->sdbus, &request, response);
 if (rlen < 0)
 goto error;
 if (s->cmd & PL181_CMD_RESPONSE) {
@@ -223,12 +223,12 @@ static void pl181_fifo_run(PL181State *s)
 int is_read;
 
 is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0;
-if (s->datacnt != 0 && (!is_read || sd_data_ready(s->card))
+if (s->datacnt != 0 && (!is_read || sdbus_data_ready(&s->sdbus))
 && !s->linux_hack) {
 if (is_read) {
 n = 0;
 while (s->datacnt && s->fifo_len < PL181_FIFO_LEN) {
-value |= (uint32_t)sd_read_data(s->card) << (n * 8);
+value |= (uint32_t)sdbus_read_data(&s->sdbus) << (n * 8);
 s->datacnt--;
 n++;
 if (n == 4) {
@@ -249,7 +249,7 @@ static void pl181_fifo_run(PL181State *s)
 }
 n--;
 s->datacnt--;
-sd_write_data(s->card, value & 0xff);
+sdbus_write_data(&s->sdbus, value & 0xff);
 value >>= 8;
 }
 }
@@ -477,13 +477,6 @@ static void pl181_reset(DeviceState *d)
 s->linux_hack = 0;
 s->mask[0] = 0;
 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]);
-/* Since we're still using the legacy SD API the card is not plugged
- * into any bus, and we must reset it manually.
- */
-device_reset(DEVICE(s->card));
 }
 
 static void pl181_init(Object *obj)
@@ -499,16 +492,52 @@ static void pl181_init(Object *obj)
 qdev_init_gpio_out(dev, s->cardstatus, 2);
 }
 
+static void pl181_set_readonly(DeviceState *dev, bool level)
+{
+PL181State *s = (PL181State *)dev;
+
+qemu_set_irq(s->cardstatus[0], level);
+}
+
+static void pl181_set_inserted(DeviceState *dev, bool level)
+{
+PL181State *s = (PL181State *)dev;
+
+qemu_set_irq(s->cardstatus[1], level);
+}
+
+static void pl181_sdbus_create_inplace(SDBus *sdbus, DeviceState *dev)
+{
+SDBusClass *sbc;
+
+qbus_create_inplace(sdbus, sizeof(SDBus), TYPE_SD_BUS, dev, "sd-bus");
+
+/* pl181_sdbus_class_init */
+sbc = SD_BUS_GET_CLASS(sdbus);
+sbc->set_inserted = pl181_set_inserted;
+sbc->set_readonly = pl181_set_readonly;
+}
+
 static void pl181_realize(DeviceState *dev, Error **errp)
 {
 PL181State *s = PL181(dev);
+DeviceState *carddev;
 DriveInfo *dinfo;
+Error *err = NULL;
+
+pl181_sdbus_create_inplace(&s->sdbus, dev);
 
+/* Create and plug in the sd card */
 /* FIXME use a qdev drive property instead of drive_get_next() */
 dinfo = drive_get_next(IF_SD);
-s->card = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, false);
-if (s->card == NULL) {
-error_setg(errp, "sd_init failed");
+carddev = qdev_create(&s->sdbus.qbus, TYPE_SD_CARD);
+if (dinfo) {
+qdev_prop_set_drive(carddev, "drive", blk_by_legacy_dinfo(dinfo), 
&err);
+}
+object_property_set_bool(OBJECT(carddev), true, "realized", &err);
+if (err) {
+error_setg(errp, "failed to init SD card: %s", error_get_pretty(err));
+return;
 }
 }
 
-- 
2.16.1