nodedev: add optional device address of channel device to css device

Add the new introduced sysfs attribute dev_busid which provides the address
of the device in the subchannel independent from the bound device driver.
It is added if available in the sysfs as optional channel_dev_addr element into
the css device capabilty providing the ccw deivce address attributes cssid,
ssid and devno.

Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Boris Fiuczynski 2022-05-13 12:31:15 +02:00 committed by Michal Privoznik
parent e9ba2ced0b
commit 122b975e40
4 changed files with 43 additions and 0 deletions

View File

@ -645,6 +645,17 @@ virNodeDeviceCapCSSDefFormat(virBuffer *buf,
virNodeDeviceCapCCWDefFormat(buf, data); virNodeDeviceCapCCWDefFormat(buf, data);
if (ccw_dev.channel_dev_addr) {
virCCWDeviceAddress *ccw = ccw_dev.channel_dev_addr;
virBufferAddLit(buf, "<channel_dev_addr>\n");
virBufferAdjustIndent(buf, 2);
virBufferAsprintf(buf, "<cssid>0x%x</cssid>\n", ccw->cssid);
virBufferAsprintf(buf, "<ssid>0x%x</ssid>\n", ccw->ssid);
virBufferAsprintf(buf, "<devno>0x%04x</devno>\n", ccw->devno);
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</channel_dev_addr>\n");
}
if (ccw_dev.flags & VIR_NODE_DEV_CAP_FLAG_CSS_MDEV) if (ccw_dev.flags & VIR_NODE_DEV_CAP_FLAG_CSS_MDEV)
virNodeDeviceCapMdevTypesFormat(buf, virNodeDeviceCapMdevTypesFormat(buf,
ccw_dev.mdev_types, ccw_dev.mdev_types,
@ -1257,6 +1268,7 @@ virNodeDevCapCSSParseXML(xmlXPathContextPtr ctxt,
g_autofree xmlNodePtr *nodes = NULL; g_autofree xmlNodePtr *nodes = NULL;
int n = 0; int n = 0;
size_t i = 0; size_t i = 0;
xmlNodePtr channel_ddno = NULL;
ctxt->node = node; ctxt->node = node;
@ -1271,6 +1283,21 @@ virNodeDevCapCSSParseXML(xmlXPathContextPtr ctxt,
return -1; return -1;
} }
/* channel_dev_addr is optional */
if ((channel_ddno = virXPathNode("./channel_dev_addr[1]", ctxt))) {
g_autofree virCCWDeviceAddress *channel_dev = NULL;
channel_dev = g_new0(virCCWDeviceAddress, 1);
if (virNodeDevCCWDeviceAddressParseXML(ctxt,
channel_ddno,
def->name,
channel_dev) < 0)
return -1;
ccw_dev->channel_dev_addr = g_steal_pointer(&channel_dev);
}
return 0; return 0;
} }
@ -2639,6 +2666,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDef *caps)
for (i = 0; i < data->ccw_dev.nmdev_types; i++) for (i = 0; i < data->ccw_dev.nmdev_types; i++)
virMediatedDeviceTypeFree(data->ccw_dev.mdev_types[i]); virMediatedDeviceTypeFree(data->ccw_dev.mdev_types[i]);
g_free(data->ccw_dev.mdev_types); g_free(data->ccw_dev.mdev_types);
g_free(data->ccw_dev.channel_dev_addr);
break; break;
case VIR_NODE_DEV_CAP_AP_MATRIX: case VIR_NODE_DEV_CAP_AP_MATRIX:
g_free(data->ap_matrix.addr); g_free(data->ap_matrix.addr);

View File

@ -24,6 +24,7 @@
#include "internal.h" #include "internal.h"
#include "virbitmap.h" #include "virbitmap.h"
#include "virccw.h"
#include "virpcivpd.h" #include "virpcivpd.h"
#include "virscsihost.h" #include "virscsihost.h"
#include "virpci.h" #include "virpci.h"
@ -279,6 +280,7 @@ struct _virNodeDevCapCCW {
unsigned int flags; /* enum virNodeDevCCWCapFlags */ unsigned int flags; /* enum virNodeDevCCWCapFlags */
virMediatedDeviceType **mdev_types; virMediatedDeviceType **mdev_types;
size_t nmdev_types; size_t nmdev_types;
virCCWDeviceAddress *channel_dev_addr;
}; };
typedef struct _virNodeDevCapVDPA virNodeDevCapVDPA; typedef struct _virNodeDevCapVDPA virNodeDevCapVDPA;

View File

@ -682,6 +682,11 @@
<value>css</value> <value>css</value>
</attribute> </attribute>
<ref name="capccwaddress"/> <ref name="capccwaddress"/>
<optional>
<element name="channel_dev_addr">
<ref name="capccwaddress"/>
</element>
</optional>
<optional> <optional>
<ref name="mdev_types"/> <ref name="mdev_types"/>
</optional> </optional>

View File

@ -1124,6 +1124,8 @@ static int
udevProcessCSS(struct udev_device *device, udevProcessCSS(struct udev_device *device,
virNodeDeviceDef *def) virNodeDeviceDef *def)
{ {
g_autofree char *dev_busid = NULL;
/* only process IO subchannel and vfio-ccw devices to keep the list sane */ /* only process IO subchannel and vfio-ccw devices to keep the list sane */
if (!def->driver || if (!def->driver ||
(STRNEQ(def->driver, "io_subchannel") && (STRNEQ(def->driver, "io_subchannel") &&
@ -1135,6 +1137,12 @@ udevProcessCSS(struct udev_device *device,
udevGenerateDeviceName(device, def, NULL); udevGenerateDeviceName(device, def, NULL);
/* process optional channel devices information */
udevGetStringSysfsAttr(device, "dev_busid", &dev_busid);
if (dev_busid != NULL)
def->caps->data.ccw_dev.channel_dev_addr = virCCWDeviceAddressFromString(dev_busid);
if (virNodeDeviceGetCSSDynamicCaps(def->sysfs_path, &def->caps->data.ccw_dev) < 0) if (virNodeDeviceGetCSSDynamicCaps(def->sysfs_path, &def->caps->data.ccw_dev) < 0)
return -1; return -1;