/*
 * s390 CCW Assignment Support
 *
 * Copyright 2017 IBM Corp
 * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
 *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
 *            Pierre Morel <pmorel@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2
 * or (at your option) any later version. See the COPYING file in the
 * top-level directory.
 */

#include "qemu/osdep.h"
#include <libgen.h>
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "hw/s390x/css.h"
#include "hw/s390x/css-bridge.h"
#include "hw/s390x/s390-ccw.h"

IOInstEnding s390_ccw_cmd_request(SubchDev *sch)
{
    S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(sch->driver_data);

    if (!cdc->handle_request) {
        return IOINST_CC_STATUS_PRESENT;
    }
    return cdc->handle_request(sch);
}

static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
                                  char *sysfsdev,
                                  Error **errp)
{
    unsigned int cssid, ssid, devid;
    char dev_path[PATH_MAX] = {0}, *tmp;

    if (!sysfsdev) {
        error_setg(errp, "No host device provided");
        error_append_hint(errp,
                          "Use -device vfio-ccw,sysfsdev=PATH_TO_DEVICE\n");
        return;
    }

    if (!realpath(sysfsdev, dev_path)) {
        error_setg_errno(errp, errno, "Host device '%s' not found", sysfsdev);
        return;
    }

    cdev->mdevid = g_path_get_basename(dev_path);

    tmp = basename(dirname(dev_path));
    if (sscanf(tmp, "%2x.%1x.%4x", &cssid, &ssid, &devid) != 3) {
        error_setg_errno(errp, errno, "Failed to read %s", tmp);
        return;
    }

    cdev->hostid.cssid = cssid;
    cdev->hostid.ssid = ssid;
    cdev->hostid.devid = devid;
    cdev->hostid.valid = true;
}

static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
{
    CcwDevice *ccw_dev = CCW_DEVICE(cdev);
    CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
    DeviceState *parent = DEVICE(ccw_dev);
    BusState *qbus = qdev_get_parent_bus(parent);
    VirtualCssBus *cbus = VIRTUAL_CSS_BUS(qbus);
    SubchDev *sch;
    int ret;
    Error *err = NULL;

    s390_ccw_get_dev_info(cdev, sysfsdev, &err);
    if (err) {
        goto out_err_propagate;
    }

    sch = css_create_sch(ccw_dev->devno, cbus->squash_mcss, &err);
    if (!sch) {
        goto out_mdevid_free;
    }
    sch->driver_data = cdev;
    sch->do_subchannel_work = do_subchannel_work_passthrough;

    ccw_dev->sch = sch;
    ret = css_sch_build_schib(sch, &cdev->hostid);
    if (ret) {
        error_setg_errno(&err, -ret, "%s: Failed to build initial schib",
                         __func__);
        goto out_err;
    }

    ck->realize(ccw_dev, &err);
    if (err) {
        goto out_err;
    }

    css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
                          parent->hotplugged, 1);
    return;

out_err:
    css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
    ccw_dev->sch = NULL;
    g_free(sch);
out_mdevid_free:
    g_free(cdev->mdevid);
out_err_propagate:
    error_propagate(errp, err);
}

static void s390_ccw_unrealize(S390CCWDevice *cdev, Error **errp)
{
    CcwDevice *ccw_dev = CCW_DEVICE(cdev);
    SubchDev *sch = ccw_dev->sch;

    if (sch) {
        css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
        g_free(sch);
        ccw_dev->sch = NULL;
    }

    g_free(cdev->mdevid);
}

static void s390_ccw_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass);

    dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
    cdc->realize = s390_ccw_realize;
    cdc->unrealize = s390_ccw_unrealize;
}

static const TypeInfo s390_ccw_info = {
    .name          = TYPE_S390_CCW,
    .parent        = TYPE_CCW_DEVICE,
    .instance_size = sizeof(S390CCWDevice),
    .class_size    = sizeof(S390CCWDeviceClass),
    .class_init    = s390_ccw_class_init,
    .abstract      = true,
};

static void register_s390_ccw_type(void)
{
    type_register_static(&s390_ccw_info);
}

type_init(register_s390_ccw_type)
