mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
The seemingly arbitrary use of 'pci' and 'pcidev' in the code in libxl_pci.c
is confusing and also compromises use of some macros used for other device
types. Indeed it seems that DEFINE_DEVICE_TYPE_STRUCT_X exists solely because
of this duality.
This patch purges use of 'pcidev' from the libxl internal code, but
unfortunately the 'pcidevs' and 'num_pcidevs' fields in 'libxl_domain_config'
are part of the API and need to be retained to avoid breaking callers,
particularly libvirt.
DEFINE_DEVICE_TYPE_STRUCT_X is still removed to avoid the special case in
libxl_pci.c but DEFINE_DEVICE_TYPE_STRUCT is given an extra 'array' argument
which is used to identify the fields in 'libxl_domain_config' relating to
the device type.
NOTE: Some of the more gross formatting errors (such as lack of spaces after
keywords) that came into context have been fixed in libxl_pci.c.
Signed-off-by: Paul Durrant <pdurrant@amazon.com>
Acked-by: Wei Liu <wl@xen.org>
223 lines
7.7 KiB
C
223 lines
7.7 KiB
C
/*
|
|
* Copyright (C) 2016 EPAM Systems Inc.
|
|
*
|
|
* This program 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; version 2.1 only. with the special
|
|
* exception on linking described in file LICENSE.
|
|
*
|
|
* This program 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.
|
|
*/
|
|
|
|
#include "libxl_internal.h"
|
|
|
|
#include <xen/io/displif.h>
|
|
|
|
static int libxl__device_vdispl_setdefault(libxl__gc *gc, uint32_t domid,
|
|
libxl_device_vdispl *vdispl,
|
|
bool hotplug)
|
|
{
|
|
return libxl__resolve_domid(gc, vdispl->backend_domname,
|
|
&vdispl->backend_domid);
|
|
}
|
|
|
|
static int libxl__vdispl_from_xenstore(libxl__gc *gc, const char *libxl_path,
|
|
libxl_devid devid,
|
|
libxl_device_vdispl *vdispl)
|
|
{
|
|
const char *be_path;
|
|
int rc;
|
|
|
|
vdispl->devid = devid;
|
|
rc = libxl__xs_read_mandatory(gc, XBT_NULL,
|
|
GCSPRINTF("%s/backend", libxl_path),
|
|
&be_path);
|
|
if (rc) return rc;
|
|
|
|
return libxl__backendpath_parse_domid(gc, be_path, &vdispl->backend_domid);
|
|
}
|
|
|
|
static void libxl__update_config_vdispl(libxl__gc *gc,
|
|
libxl_device_vdispl *dst,
|
|
libxl_device_vdispl *src)
|
|
{
|
|
dst->devid = src->devid;
|
|
dst->be_alloc = src->be_alloc;
|
|
}
|
|
|
|
static int libxl_device_vdispl_compare(const libxl_device_vdispl *d1,
|
|
const libxl_device_vdispl *d2)
|
|
{
|
|
return COMPARE_DEVID(d1, d2);
|
|
}
|
|
|
|
static void libxl__device_vdispl_add(libxl__egc *egc, uint32_t domid,
|
|
libxl_device_vdispl *vdispl,
|
|
libxl__ao_device *aodev)
|
|
{
|
|
libxl__device_add_async(egc, domid, &libxl__vdispl_devtype, vdispl, aodev);
|
|
}
|
|
|
|
static int libxl__set_xenstore_vdispl(libxl__gc *gc, uint32_t domid,
|
|
libxl_device_vdispl *vdispl,
|
|
flexarray_t *back, flexarray_t *front,
|
|
flexarray_t *ro_front)
|
|
{
|
|
int i;
|
|
|
|
flexarray_append_pair(ro_front, XENDISPL_FIELD_BE_ALLOC,
|
|
GCSPRINTF("%d", vdispl->be_alloc));
|
|
|
|
for (i = 0; i < vdispl->num_connectors; i++) {
|
|
flexarray_append_pair(ro_front, GCSPRINTF("%d/"XENDISPL_FIELD_RESOLUTION, i),
|
|
GCSPRINTF("%d"XENDISPL_RESOLUTION_SEPARATOR"%d", vdispl->connectors[i].width,
|
|
vdispl->connectors[i].height));
|
|
flexarray_append_pair(ro_front, GCSPRINTF("%d/"XENDISPL_FIELD_UNIQUE_ID, i),
|
|
vdispl->connectors[i].unique_id);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int libxl__device_vdispl_getconnectors(libxl_ctx *ctx,
|
|
const char *path,
|
|
libxl_vdisplinfo *info)
|
|
{
|
|
GC_INIT(ctx);
|
|
char *connector = NULL;
|
|
char *connector_path;
|
|
int i, rc;
|
|
|
|
info->num_connectors = 0;
|
|
|
|
connector_path = GCSPRINTF("%s/%d", path, info->num_connectors);
|
|
|
|
while ((connector = xs_read(ctx->xsh, XBT_NULL, connector_path, NULL)) !=
|
|
NULL) {
|
|
free(connector);
|
|
connector_path = GCSPRINTF("%s/%d", path, ++info->num_connectors);
|
|
}
|
|
|
|
info->connectors = libxl__calloc(NOGC, info->num_connectors,
|
|
sizeof(*info->connectors));
|
|
|
|
for (i = 0; i < info->num_connectors; i++) {
|
|
char *value;
|
|
char *value_path;
|
|
|
|
value_path = GCSPRINTF("%s/%d/"XENDISPL_FIELD_UNIQUE_ID, path, i);
|
|
info->connectors[i].unique_id = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
|
if (info->connectors[i].unique_id == NULL) { rc = ERROR_FAIL; goto out; }
|
|
|
|
value_path = GCSPRINTF("%s/%d/"XENDISPL_FIELD_RESOLUTION, path, i);
|
|
value = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
|
if (value == NULL) { rc = ERROR_FAIL; goto out; }
|
|
|
|
rc = sscanf(value, "%u"XENDISPL_RESOLUTION_SEPARATOR"%u", &info->connectors[i].width,
|
|
&info->connectors[i].height);
|
|
free(value);
|
|
|
|
if (rc != 2) {
|
|
rc = ERROR_FAIL; goto out;
|
|
}
|
|
|
|
value_path = GCSPRINTF("%s/%d/"XENDISPL_FIELD_REQ_RING_REF, path, i);
|
|
value = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
|
info->connectors[i].req_rref = value ? strtoul(value, NULL, 10) : -1;
|
|
free(value);
|
|
|
|
value_path = GCSPRINTF("%s/%d/"XENDISPL_FIELD_REQ_CHANNEL, path, i);
|
|
value = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
|
info->connectors[i].req_evtch = value ? strtoul(value, NULL, 10) : -1;
|
|
free(value);
|
|
|
|
value_path = GCSPRINTF("%s/%d/"XENDISPL_FIELD_EVT_RING_REF, path, i);
|
|
value = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
|
info->connectors[i].evt_rref = value ? strtoul(value, NULL, 10) : -1;
|
|
free(value);
|
|
|
|
value_path = GCSPRINTF("%s/%d/"XENDISPL_FIELD_EVT_CHANNEL, path, i);
|
|
value = xs_read(ctx->xsh, XBT_NULL, value_path, NULL);
|
|
info->connectors[i].evt_evtch = value ? strtoul(value, NULL, 10) : -1;
|
|
free(value);
|
|
}
|
|
|
|
rc = 0;
|
|
|
|
out:
|
|
return rc;
|
|
}
|
|
|
|
int libxl_device_vdispl_getinfo(libxl_ctx *ctx, uint32_t domid,
|
|
const libxl_device_vdispl *vdispl,
|
|
libxl_vdisplinfo *info)
|
|
{
|
|
GC_INIT(ctx);
|
|
char *libxl_path, *devpath;
|
|
char *val;
|
|
int rc;
|
|
|
|
libxl_vdisplinfo_init(info);
|
|
info->devid = vdispl->devid;
|
|
|
|
devpath = libxl__domain_device_frontend_path(gc, domid, info->devid,
|
|
LIBXL__DEVICE_KIND_VDISPL);
|
|
libxl_path = libxl__domain_device_libxl_path(gc, domid, info->devid,
|
|
LIBXL__DEVICE_KIND_VDISPL);
|
|
|
|
info->backend = xs_read(ctx->xsh, XBT_NULL,
|
|
GCSPRINTF("%s/backend", libxl_path),
|
|
NULL);
|
|
if (!info->backend) { rc = ERROR_FAIL; goto out; }
|
|
|
|
rc = libxl__backendpath_parse_domid(gc, info->backend, &info->backend_id);
|
|
if (rc) goto out;
|
|
|
|
val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/state", devpath));
|
|
info->state = val ? strtoul(val, NULL, 10) : -1;
|
|
|
|
info->frontend = xs_read(ctx->xsh, XBT_NULL,
|
|
GCSPRINTF("%s/frontend", libxl_path),
|
|
NULL);
|
|
info->frontend_id = domid;
|
|
|
|
val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/"XENDISPL_FIELD_BE_ALLOC, devpath));
|
|
info->be_alloc = val ? strtoul(val, NULL, 10) : 0;
|
|
|
|
rc = libxl__device_vdispl_getconnectors(ctx, devpath, info);
|
|
if (rc) goto out;
|
|
|
|
rc = 0;
|
|
|
|
out:
|
|
GC_FREE;
|
|
return rc;
|
|
}
|
|
|
|
static LIBXL_DEFINE_DEVICE_FROM_TYPE(vdispl)
|
|
static LIBXL_DEFINE_UPDATE_DEVID(vdispl)
|
|
static LIBXL_DEFINE_DEVICES_ADD(vdispl)
|
|
|
|
LIBXL_DEFINE_DEVID_TO_DEVICE(vdispl)
|
|
LIBXL_DEFINE_DEVICE_ADD(vdispl)
|
|
LIBXL_DEFINE_DEVICE_REMOVE(vdispl)
|
|
LIBXL_DEFINE_DEVICE_LIST(vdispl)
|
|
|
|
DEFINE_DEVICE_TYPE_STRUCT(vdispl, VDISPL, vdispls,
|
|
.update_config = (device_update_config_fn_t)libxl__update_config_vdispl,
|
|
.from_xenstore = (device_from_xenstore_fn_t)libxl__vdispl_from_xenstore,
|
|
.set_xenstore_config = (device_set_xenstore_config_fn_t)
|
|
libxl__set_xenstore_vdispl
|
|
);
|
|
|
|
/*
|
|
* Local variables:
|
|
* mode: C
|
|
* c-basic-offset: 4
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*/
|