/*
 * ide bus support for qdev.
 *
 * Copyright (c) 2009 Gerd Hoffmann <kraxel@redhat.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
#include <hw/hw.h>
#include "dma.h"

#include <hw/ide/internal.h>

/* --------------------------------- */

static struct BusInfo ide_bus_info = {
    .name  = "IDE",
    .size  = sizeof(IDEBus),
};

void ide_bus_new(IDEBus *idebus, DeviceState *dev)
{
    qbus_create_inplace(&idebus->qbus, &ide_bus_info, dev, NULL);
}

static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
{
    IDEDevice *dev = DO_UPCAST(IDEDevice, qdev, qdev);
    IDEDeviceInfo *info = DO_UPCAST(IDEDeviceInfo, qdev, base);
    IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus);

    if (!dev->conf.bs) {
        fprintf(stderr, "%s: no drive specified\n", qdev->info->name);
        goto err;
    }
    if (dev->unit == -1) {
        dev->unit = bus->master ? 1 : 0;
    }
    switch (dev->unit) {
    case 0:
        if (bus->master) {
            fprintf(stderr, "ide: tried to assign master twice\n");
            goto err;
        }
        bus->master = dev;
        break;
    case 1:
        if (bus->slave) {
            fprintf(stderr, "ide: tried to assign slave twice\n");
            goto err;
        }
        bus->slave = dev;
        break;
    default:
        goto err;
    }
    return info->init(dev);

err:
    return -1;
}

static void ide_qdev_register(IDEDeviceInfo *info)
{
    info->qdev.init = ide_qdev_init;
    info->qdev.bus_info = &ide_bus_info;
    qdev_register(&info->qdev);
}

IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive)
{
    DeviceState *dev;

    dev = qdev_create(&bus->qbus, "ide-drive");
    qdev_prop_set_uint32(dev, "unit", unit);
    qdev_prop_set_drive_nofail(dev, "drive", drive->bdrv);
    qdev_init_nofail(dev);
    return DO_UPCAST(IDEDevice, qdev, dev);
}

void ide_get_bs(BlockDriverState *bs[], BusState *qbus)
{
    IDEBus *bus = DO_UPCAST(IDEBus, qbus, qbus);
    bs[0] = bus->master ? bus->master->conf.bs : NULL;
    bs[1] = bus->slave  ? bus->slave->conf.bs  : NULL;
}

/* --------------------------------- */

typedef struct IDEDrive {
    IDEDevice dev;
} IDEDrive;

static int ide_drive_initfn(IDEDevice *dev)
{
    IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
    IDEState *s = bus->ifs + dev->unit;
    const char *serial;
    DriveInfo *dinfo;

    serial = dev->serial;
    if (!serial) {
        /* try to fall back to value set with legacy -drive serial=... */
        dinfo = drive_get_by_blockdev(dev->conf.bs);
        if (*dinfo->serial) {
            serial = dinfo->serial;
        }
    }

    ide_init_drive(s, dev->conf.bs, dev->version, serial);

    if (!dev->version) {
        dev->version = qemu_strdup(s->version);
    }
    if (!dev->serial) {
        dev->serial = qemu_strdup(s->drive_serial_str);
    }
    return 0;
}

static IDEDeviceInfo ide_drive_info = {
    .qdev.name  = "ide-drive",
    .qdev.size  = sizeof(IDEDrive),
    .init       = ide_drive_initfn,
    .qdev.props = (Property[]) {
        DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1),
        DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),
        DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),
        DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial),
        DEFINE_PROP_END_OF_LIST(),
    }
};

static void ide_drive_register(void)
{
    ide_qdev_register(&ide_drive_info);
}
device_init(ide_drive_register);
