From 817d4a6bc8bc6c2ad57ffdbab1a33c9b930ddde4 Mon Sep 17 00:00:00 2001 From: Dong Jia Shi Date: Wed, 17 May 2017 02:48:05 +0200 Subject: s390x/css: realize css_create_sch The S390 virtual css support already has a mechanism to create a virtual subchannel and provide it to the guest. However, to pass-through subchannels to a guest, we need to introduce a new mechanism to create the subchannel according to the real device information. Thus we reconstruct css_create_virtual_sch to a new css_create_sch function to handle all these cases and do allocation and initialization of the subchannel according to the device type and machine configuration. Reviewed-by: Pierre Morel Signed-off-by: Dong Jia Shi Message-Id: <20170517004813.58227-6-bjsdjshi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck --- hw/s390x/css.c | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) (limited to 'hw/s390x/css.c') diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 2c8d0e7219..a8aed9cb3a 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -1948,28 +1948,59 @@ PropertyInfo css_devid_ro_propinfo = { .get = get_css_devid, }; -SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp) +SubchDev *css_create_sch(CssDevId bus_id, bool is_virtual, bool squash_mcss, + Error **errp) { uint16_t schid = 0; SubchDev *sch; if (bus_id.valid) { - /* Enforce use of virtual cssid. */ - if (bus_id.cssid != VIRTUAL_CSSID) { - error_setg(errp, "cssid %hhx not valid for virtual devices", - bus_id.cssid); + if (is_virtual != (bus_id.cssid == VIRTUAL_CSSID)) { + error_setg(errp, "cssid %hhx not valid for %s devices", + bus_id.cssid, + (is_virtual ? "virtual" : "non-virtual")); return NULL; } + } + + if (bus_id.valid) { + if (squash_mcss) { + bus_id.cssid = channel_subsys.default_cssid; + } else if (!channel_subsys.css[bus_id.cssid]) { + css_create_css_image(bus_id.cssid, false); + } + if (!css_find_free_subch_for_devno(bus_id.cssid, bus_id.ssid, bus_id.devid, &schid, errp)) { return NULL; } - } else { - bus_id.cssid = VIRTUAL_CSSID; + } else if (squash_mcss || is_virtual) { + bus_id.cssid = channel_subsys.default_cssid; + if (!css_find_free_subch_and_devno(bus_id.cssid, &bus_id.ssid, &bus_id.devid, &schid, errp)) { return NULL; } + } else { + for (bus_id.cssid = 0; bus_id.cssid < MAX_CSSID; ++bus_id.cssid) { + if (bus_id.cssid == VIRTUAL_CSSID) { + continue; + } + + if (!channel_subsys.css[bus_id.cssid]) { + css_create_css_image(bus_id.cssid, false); + } + + if (css_find_free_subch_and_devno(bus_id.cssid, &bus_id.ssid, + &bus_id.devid, &schid, + NULL)) { + break; + } + if (bus_id.cssid == MAX_CSSID) { + error_setg(errp, "Virtual channel subsystem is full!"); + return NULL; + } + } } sch = g_malloc0(sizeof(*sch)); -- cgit 1.4.1