Commit 260bc9d8 authored by Peter Maydell's avatar Peter Maydell
Browse files

hw/sd/sd.c: QOMify



Turn the SD card into a QOM device.
This conversion only changes the device itself; the various
functions which are effectively methods on the device are not
touched at this point.

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarPeter Crosthwaite <crosthwaite.peter@gmail.com>
Reviewed-by: default avatarAlistair Francis <alistair.francis@xilinx.com>
Message-id: 1455646193-13238-3-git-send-email-peter.maydell@linaro.org
parent ac6de31a
Loading
Loading
Loading
Loading
+77 −22
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@
#include "sysemu/block-backend.h"
#include "hw/sd/sd.h"
#include "qemu/bitmap.h"
#include "hw/qdev-properties.h"
#include "qemu/error-report.h"

//#define DEBUG_SD 1

@@ -78,6 +80,8 @@ enum SDCardStates {
};

struct SDState {
    DeviceState parent_obj;

    uint32_t mode;    /* current card mode, one of SDCardModes */
    int32_t state;    /* current card state, one of SDCardStates */
    uint32_t ocr;
@@ -473,34 +477,26 @@ static const VMStateDescription sd_vmstate = {
    }
};

/* We do not model the chip select pin, so allow the board to select
   whether card should be in SSI or MMC/SD mode.  It is also up to the
   board to ensure that ssi transfers only occur when the chip select
   is asserted.  */
/* Legacy initialization function for use by non-qdevified callers */
SDState *sd_init(BlockBackend *blk, bool is_spi)
{
    SDState *sd;
    DeviceState *dev;
    Error *err = NULL;

    if (blk && blk_is_read_only(blk)) {
        fprintf(stderr, "sd_init: Cannot use read-only drive\n");
    dev = qdev_create(NULL, TYPE_SD_CARD);
    qdev_prop_set_drive(dev, "drive", blk, &err);
    if (err) {
        error_report("sd_init failed: %s", error_get_pretty(err));
        return NULL;
    }

    sd = (SDState *) g_malloc0(sizeof(SDState));
    sd->buf = blk_blockalign(blk, 512);
    sd->spi = is_spi;
    sd->enable = true;
    sd->blk = blk;
    sd_reset(sd);
    if (sd->blk) {
        /* Attach dev if not already attached.  (This call ignores an
         * error return code if sd->blk is already attached.) */
        /* FIXME ignoring blk_attach_dev() failure is dangerously brittle */
        blk_attach_dev(sd->blk, sd);
        blk_set_dev_ops(sd->blk, &sd_block_ops, sd);
    qdev_prop_set_bit(dev, "spi", is_spi);
    object_property_set_bool(OBJECT(dev), true, "realized", &err);
    if (err) {
        error_report("sd_init failed: %s", error_get_pretty(err));
        return NULL;
    }
    vmstate_register(NULL, -1, &sd_vmstate, sd);
    return sd;

    return SD_CARD(dev);
}

void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert)
@@ -1769,3 +1765,62 @@ void sd_enable(SDState *sd, bool enable)
{
    sd->enable = enable;
}

static void sd_instance_init(Object *obj)
{
    SDState *sd = SD_CARD(obj);

    sd->enable = true;
}

static void sd_realize(DeviceState *dev, Error **errp)
{
    SDState *sd = SD_CARD(dev);

    if (sd->blk && blk_is_read_only(sd->blk)) {
        error_setg(errp, "Cannot use read-only drive as SD card");
        return;
    }

    sd->buf = blk_blockalign(sd->blk, 512);

    if (sd->blk) {
        blk_set_dev_ops(sd->blk, &sd_block_ops, sd);
    }

    sd_reset(sd);
}

static Property sd_properties[] = {
    DEFINE_PROP_DRIVE("drive", SDState, blk),
    /* We do not model the chip select pin, so allow the board to select
     * whether card should be in SSI or MMC/SD mode.  It is also up to the
     * board to ensure that ssi transfers only occur when the chip select
     * is asserted.  */
    DEFINE_PROP_BOOL("spi", SDState, spi, false),
    DEFINE_PROP_END_OF_LIST()
};

static void sd_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = sd_realize;
    dc->props = sd_properties;
    dc->vmsd = &sd_vmstate;
}

static const TypeInfo sd_info = {
    .name = TYPE_SD_CARD,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(SDState),
    .class_init = sd_class_init,
    .instance_init = sd_instance_init,
};

static void sd_register_types(void)
{
    type_register_static(&sd_info);
}

type_init(sd_register_types)
+3 −0
Original line number Diff line number Diff line
@@ -68,6 +68,9 @@ typedef struct {

typedef struct SDState SDState;

#define TYPE_SD_CARD "sd-card"
#define SD_CARD(obj) OBJECT_CHECK(SDState, (obj), TYPE_SD_CARD)

SDState *sd_init(BlockBackend *bs, bool is_spi);
int sd_do_command(SDState *sd, SDRequest *req,
                  uint8_t *response);