mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-11-29 00:24:28 +03:00
nodedev: add ccwgroup node device support
Add ccwgroup node device type supporting qeth generic driver. 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:
committed by
Michal Privoznik
parent
de4c28cd4a
commit
985cb9c32a
@@ -5533,9 +5533,9 @@ List all of the devices available on the node that are known by libvirt.
|
|||||||
separated by comma, e.g. --cap pci,scsi. Valid capability types include
|
separated by comma, e.g. --cap pci,scsi. Valid capability types include
|
||||||
'system', 'pci', 'usb_device', 'usb', 'net', 'scsi_host', 'scsi_target',
|
'system', 'pci', 'usb_device', 'usb', 'net', 'scsi_host', 'scsi_target',
|
||||||
'scsi', 'storage', 'fc_host', 'vports', 'scsi_generic', 'drm', 'mdev',
|
'scsi', 'storage', 'fc_host', 'vports', 'scsi_generic', 'drm', 'mdev',
|
||||||
'mdev_types', 'ccw', 'css', 'ap_card', 'ap_queue', 'ap_matrix'. By default,
|
'mdev_types', 'ccw', 'ccwgroup', 'css', 'ap_card', 'ap_queue', 'ap_matrix'.
|
||||||
only active devices are listed. *--inactive* is used to list only inactive
|
By default, only active devices are listed. *--inactive* is used to list only
|
||||||
devices, and *--all* is used to list both active and inactive devices.
|
inactive devices, and *--all* is used to list both active and inactive devices.
|
||||||
*--persistent* is used to list only persistent devices, and *--transient* is
|
*--persistent* is used to list only persistent devices, and *--transient* is
|
||||||
used to list only transient devices. Not providing *--persistent* or
|
used to list only transient devices. Not providing *--persistent* or
|
||||||
*--transient* will list all devices unless filtered otherwise. *--transient*
|
*--transient* will list all devices unless filtered otherwise. *--transient*
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ typedef enum {
|
|||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE = 1 << 19, /* s390 AP Queue (Since: 7.0.0) */
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE = 1 << 19, /* s390 AP Queue (Since: 7.0.0) */
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX = 1 << 20, /* s390 AP Matrix (Since: 7.0.0) */
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX = 1 << 20, /* s390 AP Matrix (Since: 7.0.0) */
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPD = 1 << 21, /* Device with VPD (Since: 7.9.0) */
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPD = 1 << 21, /* Device with VPD (Since: 7.9.0) */
|
||||||
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_DEV = 1 << 22, /* s390 CCWGROUP device (Since: 11.1.0) */
|
||||||
|
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_PERSISTENT = 1 << 28, /* Persisted devices (Since: 10.1.0) */
|
VIR_CONNECT_LIST_NODE_DEVICES_PERSISTENT = 1 << 28, /* Persisted devices (Since: 10.1.0) */
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT = 1 << 29, /* Transient devices (Since: 10.1.0) */
|
VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT = 1 << 29, /* Transient devices (Since: 10.1.0) */
|
||||||
|
|||||||
@@ -71,6 +71,12 @@ VIR_ENUM_IMPL(virNodeDevCap,
|
|||||||
"ap_queue",
|
"ap_queue",
|
||||||
"ap_matrix",
|
"ap_matrix",
|
||||||
"vpd",
|
"vpd",
|
||||||
|
"ccwgroup",
|
||||||
|
);
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virNodeDevCCWGroupCap,
|
||||||
|
VIR_NODE_DEV_CAP_CCWGROUP_LAST,
|
||||||
|
"qeth_generic",
|
||||||
);
|
);
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virNodeDevNetCap,
|
VIR_ENUM_IMPL(virNodeDevNetCap,
|
||||||
@@ -671,6 +677,53 @@ virNodeDeviceCapCCWStateTypeFormat(virBuffer *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virNodeDeviceCapCCWGroupQethFormat(virBuffer *buf,
|
||||||
|
const virCCWGroupTypeQeth *qeth)
|
||||||
|
{
|
||||||
|
virBufferAsprintf(buf, "<card_type>%s</card_type>\n", qeth->card_type);
|
||||||
|
virBufferAsprintf(buf, "<chpid>%s</chpid>\n", qeth->chpid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virNodeDeviceCapCCWGroupDefFormat(virBuffer *buf,
|
||||||
|
const virNodeDevCapData *data)
|
||||||
|
{
|
||||||
|
virNodeDevCapCCWGroup ccwgroup_dev = data->ccwgroup_dev;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
virNodeDeviceCapCCWStateTypeFormat(buf, ccwgroup_dev.state);
|
||||||
|
virCCWDeviceAddressFormat(buf, ccwgroup_dev.address);
|
||||||
|
|
||||||
|
if (ccwgroup_dev.members) {
|
||||||
|
virBufferAddLit(buf, "<members>\n");
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
for (i = 0; i < ccwgroup_dev.nmembers; i++) {
|
||||||
|
virBufferEscapeString(buf, "<ccw_device ref='%s'>",
|
||||||
|
ccwgroup_dev.members[i]->ref);
|
||||||
|
virBufferEscapeString(buf, "%s</ccw_device>\n",
|
||||||
|
ccwgroup_dev.members[i]->device);
|
||||||
|
}
|
||||||
|
virBufferAdjustIndent(buf, -2);
|
||||||
|
virBufferAddLit(buf, "</members>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAsprintf(buf, "<capability type='%s'>\n",
|
||||||
|
virNodeDevCCWGroupCapTypeToString(ccwgroup_dev.type));
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
switch (ccwgroup_dev.type) {
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_QETH_GENERIC:
|
||||||
|
virNodeDeviceCapCCWGroupQethFormat(buf, &ccwgroup_dev.qeth);
|
||||||
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_LAST:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
virBufferAdjustIndent(buf, -2);
|
||||||
|
virBufferAddLit(buf, "</capability>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
virNodeDeviceDefFormat(const virNodeDeviceDef *def, unsigned int flags)
|
virNodeDeviceDefFormat(const virNodeDeviceDef *def, unsigned int flags)
|
||||||
{
|
{
|
||||||
@@ -788,6 +841,9 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def, unsigned int flags)
|
|||||||
data->mdev_parent.mdev_types,
|
data->mdev_parent.mdev_types,
|
||||||
data->mdev_parent.nmdev_types);
|
data->mdev_parent.nmdev_types);
|
||||||
break;
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
|
virNodeDeviceCapCCWGroupDefFormat(&buf, data);
|
||||||
|
break;
|
||||||
case VIR_NODE_DEV_CAP_FC_HOST:
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
||||||
case VIR_NODE_DEV_CAP_VPORTS:
|
case VIR_NODE_DEV_CAP_VPORTS:
|
||||||
case VIR_NODE_DEV_CAP_VPD:
|
case VIR_NODE_DEV_CAP_VPD:
|
||||||
@@ -1304,6 +1360,107 @@ virNodeDevCapCSSParseXML(xmlXPathContextPtr ctxt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNodeDevCapCCWGroupQethParseXML(xmlXPathContextPtr ctxt,
|
||||||
|
xmlNodePtr node,
|
||||||
|
virCCWGroupTypeQeth *qeth)
|
||||||
|
{
|
||||||
|
VIR_XPATH_NODE_AUTORESTORE(ctxt)
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
qeth->card_type = virXPathString("string(./card_type[1])", ctxt);
|
||||||
|
qeth->chpid = virXPathString("string(./chpid[1])", ctxt);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNodeDevCapCCWGroupParseXML(xmlXPathContextPtr ctxt,
|
||||||
|
virNodeDeviceDef *def,
|
||||||
|
xmlNodePtr node,
|
||||||
|
virNodeDevCapCCWGroup *ccwgroup_dev)
|
||||||
|
{
|
||||||
|
VIR_XPATH_NODE_AUTORESTORE(ctxt)
|
||||||
|
g_autofree virCCWGroupMemberType **members = NULL;
|
||||||
|
g_autofree virCCWDeviceAddress *address = NULL;
|
||||||
|
g_autofree xmlNodePtr *ccw_device_nodes = NULL;
|
||||||
|
xmlNodePtr cap_node = NULL;
|
||||||
|
g_autofree char *state = NULL;
|
||||||
|
size_t i = 0;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
/* state is optional */
|
||||||
|
ccwgroup_dev->state = VIR_NODE_DEV_CCW_STATE_LAST;
|
||||||
|
if ((state = virXPathString("string(./state[1])", ctxt))) {
|
||||||
|
int val;
|
||||||
|
if ((val = virNodeDevCCWStateTypeFromString(state)) < 0) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("unknown state '%1$s' for '%2$s'"), state, def->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ccwgroup_dev->state = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
address = g_new0(virCCWDeviceAddress, 1);
|
||||||
|
|
||||||
|
if (virNodeDevCCWDeviceAddressParseXML(ctxt,
|
||||||
|
node,
|
||||||
|
def->name,
|
||||||
|
address) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ccwgroup_dev->address = g_steal_pointer(&address);
|
||||||
|
|
||||||
|
/* Parse ccw_devices in members */
|
||||||
|
if ((n = virXPathNodeSet("./members/ccw_device", ctxt, &ccw_device_nodes)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ccwgroup_dev->members = g_new0(virCCWGroupMemberType *, n);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
g_autoptr(virCCWGroupMemberType) ccwMember = g_new0(virCCWGroupMemberType, 1);
|
||||||
|
|
||||||
|
if (!(ccwMember->ref = virXMLPropString(ccw_device_nodes[i], "ref"))) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("Missing ref property on ccw_device in members for '%1$s'"),
|
||||||
|
def->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!(ccwMember->device = virXMLNodeContentString(ccw_device_nodes[i]))) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("Missing data in ccw_device with ref '%1$s' in members for '%2$s'"),
|
||||||
|
ccwMember->ref, def->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_APPEND_ELEMENT(ccwgroup_dev->members,
|
||||||
|
ccwgroup_dev->nmembers,
|
||||||
|
ccwMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse capability */
|
||||||
|
cap_node = virXPathNode("./capability", ctxt);
|
||||||
|
if (cap_node && virXMLPropEnum(cap_node, "type",
|
||||||
|
virNodeDevCCWGroupCapTypeFromString,
|
||||||
|
VIR_XML_PROP_REQUIRED, &ccwgroup_dev->type) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
switch (ccwgroup_dev->type) {
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_QETH_GENERIC:
|
||||||
|
if (virNodeDevCapCCWGroupQethParseXML(ctxt, cap_node, &ccwgroup_dev->qeth) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_LAST:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virNodeDevCapAPAdapterParseXML(xmlXPathContextPtr ctxt,
|
virNodeDevCapAPAdapterParseXML(xmlXPathContextPtr ctxt,
|
||||||
virNodeDeviceDef *def,
|
virNodeDeviceDef *def,
|
||||||
@@ -2344,6 +2501,10 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
|
|||||||
ret = virNodeDevCapAPMatrixParseXML(ctxt, def, node,
|
ret = virNodeDevCapAPMatrixParseXML(ctxt, def, node,
|
||||||
&caps->data.ap_matrix);
|
&caps->data.ap_matrix);
|
||||||
break;
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
|
ret = virNodeDevCapCCWGroupParseXML(ctxt, def, node,
|
||||||
|
&caps->data.ccwgroup_dev);
|
||||||
|
break;
|
||||||
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
||||||
case VIR_NODE_DEV_CAP_FC_HOST:
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
||||||
case VIR_NODE_DEV_CAP_VPORTS:
|
case VIR_NODE_DEV_CAP_VPORTS:
|
||||||
@@ -2636,6 +2797,19 @@ virNodeDevCapsDefFree(virNodeDevCapsDef *caps)
|
|||||||
case VIR_NODE_DEV_CAP_CCW_DEV:
|
case VIR_NODE_DEV_CAP_CCW_DEV:
|
||||||
g_free(data->ccw_dev.dev_addr);
|
g_free(data->ccw_dev.dev_addr);
|
||||||
break;
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
|
g_free(data->ccwgroup_dev.address);
|
||||||
|
for (i = 0; i < data->ccwgroup_dev.nmembers; i++)
|
||||||
|
virCCWGroupMemberTypeFree(data->ccwgroup_dev.members[i]);
|
||||||
|
g_free(data->ccwgroup_dev.members);
|
||||||
|
switch (data->ccwgroup_dev.type) {
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_QETH_GENERIC:
|
||||||
|
virCCWGroupTypeQethFree(&data->ccwgroup_dev.qeth);
|
||||||
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_LAST:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case VIR_NODE_DEV_CAP_DRM:
|
case VIR_NODE_DEV_CAP_DRM:
|
||||||
case VIR_NODE_DEV_CAP_FC_HOST:
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
||||||
case VIR_NODE_DEV_CAP_VPORTS:
|
case VIR_NODE_DEV_CAP_VPORTS:
|
||||||
@@ -2695,6 +2869,11 @@ virNodeDeviceUpdateCaps(virNodeDeviceDef *def)
|
|||||||
&cap->data.mdev_parent) < 0)
|
&cap->data.mdev_parent) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
|
if (virNodeDeviceGetCCWGroupDynamicCaps(def->sysfs_path,
|
||||||
|
&cap->data.ccwgroup_dev) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
/* all types that (supposedly) don't require any updates
|
/* all types that (supposedly) don't require any updates
|
||||||
* relative to what's in the cache.
|
* relative to what's in the cache.
|
||||||
@@ -3195,6 +3374,31 @@ virNodeDeviceGetMdevParentDynamicCaps(const char *sysfsPath,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* virNodeDeviceGetCCWGroupDynamicCaps() get info that is stored in sysfs
|
||||||
|
* about devices related to this device, i.e. things that can change
|
||||||
|
* without this device itself changing. These must be refreshed
|
||||||
|
* anytime full XML of the device is requested, because they can
|
||||||
|
* change with no corresponding notification from the kernel/udev.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virNodeDeviceGetCCWGroupDynamicCaps(const char *sysfsPath,
|
||||||
|
virNodeDevCapCCWGroup *ccwgroup)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < ccwgroup->nmembers; i++)
|
||||||
|
virCCWGroupMemberTypeFree(ccwgroup->members[i]);
|
||||||
|
VIR_FREE(ccwgroup->members);
|
||||||
|
ccwgroup->nmembers = 0;
|
||||||
|
|
||||||
|
if (virCCWGroupDeviceGetMembers(sysfsPath,
|
||||||
|
&ccwgroup->members,
|
||||||
|
&ccwgroup->nmembers) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -3240,4 +3444,12 @@ virNodeDeviceGetMdevParentDynamicCaps(const char *sysfsPath G_GNUC_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virNodeDeviceGetCCWGroupDynamicCaps(const char *sysfsPath G_GNUC_UNUSED,
|
||||||
|
virNodeDevCapCCWGroup *ccwgroup G_GNUC_UNUSED)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* __linux__ */
|
#endif /* __linux__ */
|
||||||
|
|||||||
@@ -71,10 +71,17 @@ typedef enum {
|
|||||||
VIR_NODE_DEV_CAP_AP_QUEUE, /* s390 AP Queue */
|
VIR_NODE_DEV_CAP_AP_QUEUE, /* s390 AP Queue */
|
||||||
VIR_NODE_DEV_CAP_AP_MATRIX, /* s390 AP Matrix device */
|
VIR_NODE_DEV_CAP_AP_MATRIX, /* s390 AP Matrix device */
|
||||||
VIR_NODE_DEV_CAP_VPD, /* Device provides VPD */
|
VIR_NODE_DEV_CAP_VPD, /* Device provides VPD */
|
||||||
|
VIR_NODE_DEV_CAP_CCWGROUP_DEV, /* s390 CCWGROUP device */
|
||||||
|
|
||||||
VIR_NODE_DEV_CAP_LAST
|
VIR_NODE_DEV_CAP_LAST
|
||||||
} virNodeDevCapType;
|
} virNodeDevCapType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
|
||||||
|
VIR_NODE_DEV_CAP_CCWGROUP_QETH_GENERIC, /* s390 CCWGROUP QETH generic device */
|
||||||
|
VIR_NODE_DEV_CAP_CCWGROUP_LAST
|
||||||
|
} virNodeDevCCWGroupCapType;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
|
/* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
|
||||||
VIR_NODE_DEV_CAP_NET_80203, /* 802.03 network device */
|
VIR_NODE_DEV_CAP_NET_80203, /* 802.03 network device */
|
||||||
@@ -83,6 +90,7 @@ typedef enum {
|
|||||||
} virNodeDevNetCapType;
|
} virNodeDevNetCapType;
|
||||||
|
|
||||||
VIR_ENUM_DECL(virNodeDevCap);
|
VIR_ENUM_DECL(virNodeDevCap);
|
||||||
|
VIR_ENUM_DECL(virNodeDevCCWGroupCap);
|
||||||
VIR_ENUM_DECL(virNodeDevNetCap);
|
VIR_ENUM_DECL(virNodeDevNetCap);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -321,6 +329,19 @@ struct _virNodeDevCapMdevParent {
|
|||||||
char *address;
|
char *address;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _virNodeDevCapCCWGroup virNodeDevCapCCWGroup;
|
||||||
|
struct _virNodeDevCapCCWGroup {
|
||||||
|
virNodeDevCCWStateType state; /* online attribute */
|
||||||
|
virCCWDeviceAddress *address;
|
||||||
|
virCCWGroupMemberType **members;
|
||||||
|
size_t nmembers;
|
||||||
|
|
||||||
|
virNodeDevCCWGroupCapType type;
|
||||||
|
union {
|
||||||
|
virCCWGroupTypeQeth qeth;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _virNodeDevCapData virNodeDevCapData;
|
typedef struct _virNodeDevCapData virNodeDevCapData;
|
||||||
struct _virNodeDevCapData {
|
struct _virNodeDevCapData {
|
||||||
virNodeDevCapType type;
|
virNodeDevCapType type;
|
||||||
@@ -343,6 +364,7 @@ struct _virNodeDevCapData {
|
|||||||
virNodeDevCapAPQueue ap_queue;
|
virNodeDevCapAPQueue ap_queue;
|
||||||
virNodeDevCapAPMatrix ap_matrix;
|
virNodeDevCapAPMatrix ap_matrix;
|
||||||
virNodeDevCapMdevParent mdev_parent;
|
virNodeDevCapMdevParent mdev_parent;
|
||||||
|
virNodeDevCapCCWGroup ccwgroup_dev;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -434,7 +456,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNodeDevCapsDef, virNodeDevCapsDefFree);
|
|||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_CARD | \
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_CARD | \
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE | \
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE | \
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX | \
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX | \
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPD)
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPD | \
|
||||||
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_DEV)
|
||||||
|
|
||||||
#define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_ACTIVE \
|
#define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_ACTIVE \
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_ACTIVE | \
|
VIR_CONNECT_LIST_NODE_DEVICES_ACTIVE | \
|
||||||
@@ -472,6 +495,10 @@ int
|
|||||||
virNodeDeviceGetMdevParentDynamicCaps(const char *sysfsPath,
|
virNodeDeviceGetMdevParentDynamicCaps(const char *sysfsPath,
|
||||||
virNodeDevCapMdevParent *mdev_parent);
|
virNodeDevCapMdevParent *mdev_parent);
|
||||||
|
|
||||||
|
int
|
||||||
|
virNodeDeviceGetCCWGroupDynamicCaps(const char *sysfsPath,
|
||||||
|
virNodeDevCapCCWGroup *ccwgroup);
|
||||||
|
|
||||||
int
|
int
|
||||||
virNodeDeviceUpdateCaps(virNodeDeviceDef *def);
|
virNodeDeviceUpdateCaps(virNodeDeviceDef *def);
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,7 @@
|
|||||||
<ref name="capdrm"/>
|
<ref name="capdrm"/>
|
||||||
<ref name="capmdev"/>
|
<ref name="capmdev"/>
|
||||||
<ref name="capccwdev"/>
|
<ref name="capccwdev"/>
|
||||||
|
<ref name="capccwgroupdev"/>
|
||||||
<ref name="capcssdev"/>
|
<ref name="capcssdev"/>
|
||||||
<ref name="capvdpa"/>
|
<ref name="capvdpa"/>
|
||||||
<ref name="capapcard"/>
|
<ref name="capapcard"/>
|
||||||
@@ -669,6 +670,48 @@
|
|||||||
</interleave>
|
</interleave>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
|
<define name="capccwgrouptypeqeth">
|
||||||
|
<attribute name="type">
|
||||||
|
<value>qeth_generic</value>
|
||||||
|
</attribute>
|
||||||
|
<interleave>
|
||||||
|
<element name="card_type"><text/></element>
|
||||||
|
<element name="chpid"><text/></element>
|
||||||
|
</interleave>
|
||||||
|
</define>
|
||||||
|
|
||||||
|
<define name="capccwgroupdev">
|
||||||
|
<attribute name="type">
|
||||||
|
<value>ccwgroup</value>
|
||||||
|
</attribute>
|
||||||
|
<optional>
|
||||||
|
<element name="state">
|
||||||
|
<choice>
|
||||||
|
<value>online</value>
|
||||||
|
<value>offline</value>
|
||||||
|
</choice>
|
||||||
|
</element>
|
||||||
|
</optional>
|
||||||
|
<ref name="capccwaddress"/>
|
||||||
|
<optional>
|
||||||
|
<element name="members">
|
||||||
|
<oneOrMore>
|
||||||
|
<element name="ccw_device">
|
||||||
|
<attribute name="ref">
|
||||||
|
<data type="string"/>
|
||||||
|
</attribute>
|
||||||
|
<text/>
|
||||||
|
</element>
|
||||||
|
</oneOrMore>
|
||||||
|
</element>
|
||||||
|
</optional>
|
||||||
|
<element name="capability">
|
||||||
|
<choice>
|
||||||
|
<ref name="capccwgrouptypeqeth"/>
|
||||||
|
</choice>
|
||||||
|
</element>
|
||||||
|
</define>
|
||||||
|
|
||||||
<define name="capccwdev">
|
<define name="capccwdev">
|
||||||
<attribute name="type">
|
<attribute name="type">
|
||||||
<value>ccw</value>
|
<value>ccw</value>
|
||||||
|
|||||||
@@ -741,6 +741,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj,
|
|||||||
case VIR_NODE_DEV_CAP_AP_CARD:
|
case VIR_NODE_DEV_CAP_AP_CARD:
|
||||||
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
||||||
case VIR_NODE_DEV_CAP_VPD:
|
case VIR_NODE_DEV_CAP_VPD:
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
case VIR_NODE_DEV_CAP_LAST:
|
case VIR_NODE_DEV_CAP_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -899,7 +900,8 @@ virNodeDeviceObjMatch(virNodeDeviceObj *obj,
|
|||||||
MATCH_CAP(AP_CARD) ||
|
MATCH_CAP(AP_CARD) ||
|
||||||
MATCH_CAP(AP_QUEUE) ||
|
MATCH_CAP(AP_QUEUE) ||
|
||||||
MATCH_CAP(AP_MATRIX) ||
|
MATCH_CAP(AP_MATRIX) ||
|
||||||
MATCH_CAP(VPD)))
|
MATCH_CAP(VPD) ||
|
||||||
|
MATCH_CAP(CCWGROUP_DEV)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -892,12 +892,15 @@ virNetDevIPRouteParseXML;
|
|||||||
virNodeDevCapsDefFree;
|
virNodeDevCapsDefFree;
|
||||||
virNodeDevCapTypeFromString;
|
virNodeDevCapTypeFromString;
|
||||||
virNodeDevCapTypeToString;
|
virNodeDevCapTypeToString;
|
||||||
|
virNodeDevCCWGroupCapTypeFromString;
|
||||||
|
virNodeDevCCWGroupCapTypeToString;
|
||||||
virNodeDeviceCapsListExport;
|
virNodeDeviceCapsListExport;
|
||||||
virNodeDeviceDefFormat;
|
virNodeDeviceDefFormat;
|
||||||
virNodeDeviceDefFree;
|
virNodeDeviceDefFree;
|
||||||
virNodeDeviceDefParse;
|
virNodeDeviceDefParse;
|
||||||
virNodeDeviceDefParseXML;
|
virNodeDeviceDefParseXML;
|
||||||
virNodeDeviceGetAPMatrixDynamicCaps;
|
virNodeDeviceGetAPMatrixDynamicCaps;
|
||||||
|
virNodeDeviceGetCCWGroupDynamicCaps;
|
||||||
virNodeDeviceGetCSSDynamicCaps;
|
virNodeDeviceGetCSSDynamicCaps;
|
||||||
virNodeDeviceGetMdevParentDynamicCaps;
|
virNodeDeviceGetMdevParentDynamicCaps;
|
||||||
virNodeDeviceGetPCIDynamicCaps;
|
virNodeDeviceGetPCIDynamicCaps;
|
||||||
@@ -2029,6 +2032,9 @@ virCCWDeviceAddressFromString;
|
|||||||
virCCWDeviceAddressIncrement;
|
virCCWDeviceAddressIncrement;
|
||||||
virCCWDeviceAddressIsValid;
|
virCCWDeviceAddressIsValid;
|
||||||
virCCWDeviceAddressParseFromString;
|
virCCWDeviceAddressParseFromString;
|
||||||
|
virCCWGroupDeviceGetMembers;
|
||||||
|
virCCWGroupMemberTypeFree;
|
||||||
|
virCCWGroupTypeQethFree;
|
||||||
|
|
||||||
|
|
||||||
# util/vircgroup.h
|
# util/vircgroup.h
|
||||||
|
|||||||
@@ -695,6 +695,10 @@ nodeDeviceObjFormatAddress(virNodeDeviceObj *obj)
|
|||||||
addr = g_strdup(caps->data.mdev_parent.address);
|
addr = g_strdup(caps->data.mdev_parent.address);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
|
addr = virCCWDeviceAddressAsString(caps->data.ccwgroup_dev.address);
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_NODE_DEV_CAP_SYSTEM:
|
case VIR_NODE_DEV_CAP_SYSTEM:
|
||||||
case VIR_NODE_DEV_CAP_USB_DEV:
|
case VIR_NODE_DEV_CAP_USB_DEV:
|
||||||
case VIR_NODE_DEV_CAP_USB_INTERFACE:
|
case VIR_NODE_DEV_CAP_USB_INTERFACE:
|
||||||
@@ -2189,6 +2193,7 @@ int nodeDeviceDefValidate(virNodeDeviceDef *def,
|
|||||||
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
||||||
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
||||||
case VIR_NODE_DEV_CAP_VPD:
|
case VIR_NODE_DEV_CAP_VPD:
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
case VIR_NODE_DEV_CAP_LAST:
|
case VIR_NODE_DEV_CAP_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1389,6 +1389,43 @@ udevProcessAPMatrix(struct udev_device *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
udevProcessCCWGroup(struct udev_device *device,
|
||||||
|
virNodeDeviceDef *def)
|
||||||
|
{
|
||||||
|
const char *devtype = udev_device_get_devtype(device);
|
||||||
|
virNodeDevCapData *data = &def->caps->data;
|
||||||
|
|
||||||
|
data->ccwgroup_dev.address = virCCWDeviceAddressFromString(udev_device_get_sysname(device));
|
||||||
|
|
||||||
|
udevCCWGetState(device, &data->ccwgroup_dev.state);
|
||||||
|
|
||||||
|
udevGenerateDeviceName(device, def, NULL);
|
||||||
|
|
||||||
|
if ((data->ccwgroup_dev.type = virNodeDevCCWGroupCapTypeFromString(devtype)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
switch (data->ccwgroup_dev.type) {
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_QETH_GENERIC:
|
||||||
|
{
|
||||||
|
virCCWGroupTypeQeth *qeth = &data->ccwgroup_dev.qeth;
|
||||||
|
/* process qeth device information */
|
||||||
|
udevGetStringSysfsAttr(device, "card_type", &qeth->card_type);
|
||||||
|
udevGetStringSysfsAttr(device, "chpid", &qeth->chpid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_LAST:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virNodeDeviceGetCCWGroupDynamicCaps(def->sysfs_path,
|
||||||
|
&data->ccwgroup_dev) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
udevGetDeviceNodes(struct udev_device *device,
|
udevGetDeviceNodes(struct udev_device *device,
|
||||||
virNodeDeviceDef *def)
|
virNodeDeviceDef *def)
|
||||||
@@ -1447,6 +1484,8 @@ udevGetDeviceType(struct udev_device *device,
|
|||||||
*type = VIR_NODE_DEV_CAP_AP_CARD;
|
*type = VIR_NODE_DEV_CAP_AP_CARD;
|
||||||
else if (STREQ(devtype, "ap_queue"))
|
else if (STREQ(devtype, "ap_queue"))
|
||||||
*type = VIR_NODE_DEV_CAP_AP_QUEUE;
|
*type = VIR_NODE_DEV_CAP_AP_QUEUE;
|
||||||
|
else if (STREQ(devtype, "qeth_generic"))
|
||||||
|
*type = VIR_NODE_DEV_CAP_CCWGROUP_DEV;
|
||||||
} else {
|
} else {
|
||||||
/* PCI devices don't set the DEVTYPE property. */
|
/* PCI devices don't set the DEVTYPE property. */
|
||||||
if (udevHasDeviceProperty(device, "PCI_CLASS"))
|
if (udevHasDeviceProperty(device, "PCI_CLASS"))
|
||||||
@@ -1534,6 +1573,8 @@ udevGetDeviceDetails(virNodeDeviceDriverState *driver_state,
|
|||||||
return udevProcessAPMatrix(device, def);
|
return udevProcessAPMatrix(device, def);
|
||||||
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
||||||
return udevProcessMdevParent(device, def);
|
return udevProcessMdevParent(device, def);
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
|
return udevProcessCCWGroup(device, def);
|
||||||
case VIR_NODE_DEV_CAP_VPD:
|
case VIR_NODE_DEV_CAP_VPD:
|
||||||
case VIR_NODE_DEV_CAP_SYSTEM:
|
case VIR_NODE_DEV_CAP_SYSTEM:
|
||||||
case VIR_NODE_DEV_CAP_FC_HOST:
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
||||||
|
|||||||
@@ -19,9 +19,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include "virccw.h"
|
#include "virccw.h"
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
|
#include "virfile.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
|
#include "viralloc.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
@@ -101,3 +107,99 @@ virCCWDeviceAddressParseFromString(const char *address,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
virCCWGroupMemberTypeFree(virCCWGroupMemberType *member)
|
||||||
|
{
|
||||||
|
if (!member)
|
||||||
|
return;
|
||||||
|
|
||||||
|
VIR_FREE(member->ref);
|
||||||
|
VIR_FREE(member->device);
|
||||||
|
VIR_FREE(member);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
virCCWGroupDeviceDevNodeName(const char *nodedev_prefix,
|
||||||
|
const char *sysfs_path)
|
||||||
|
{
|
||||||
|
g_autofree char *node_name = NULL;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
node_name = g_path_get_basename(sysfs_path);
|
||||||
|
|
||||||
|
for (i = 0; i < strlen(node_name); i++) {
|
||||||
|
if (!(g_ascii_isalnum(*(node_name + i))))
|
||||||
|
*(node_name + i) = '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_strdup_printf("%s_%s", nodedev_prefix, node_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virCCWGroupDeviceGetMembers:
|
||||||
|
* @sysfs_path: sysfs path to a group device
|
||||||
|
* @members: Where to add the found group members
|
||||||
|
* @nmembers: Number of found group members
|
||||||
|
*
|
||||||
|
* The sysfs path is searched for links with a name prefix "cdev".
|
||||||
|
* These links point the ccw device sysfs entry which is a member
|
||||||
|
* of the ccw group.
|
||||||
|
*
|
||||||
|
* Returns: -1 on error (invalid sysfs_path or group has no members)
|
||||||
|
* 0 on success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virCCWGroupDeviceGetMembers(const char *sysfs_path,
|
||||||
|
virCCWGroupMemberType ***members,
|
||||||
|
size_t *nmembers)
|
||||||
|
{
|
||||||
|
virCCWGroupMemberType *member = NULL;
|
||||||
|
g_autofree char *ccwdevpath = NULL;
|
||||||
|
g_autoptr(DIR) dir = NULL;
|
||||||
|
struct dirent *entry;
|
||||||
|
int direrr;
|
||||||
|
|
||||||
|
if (virDirOpenIfExists(&dir, sysfs_path) <= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while ((direrr = virDirRead(dir, &entry, NULL)) > 0) {
|
||||||
|
if (g_str_has_prefix(entry->d_name, "cdev")) {
|
||||||
|
/* found a cdev reference */
|
||||||
|
g_autofree char *cdevpath = NULL;
|
||||||
|
cdevpath = g_build_filename(sysfs_path, entry->d_name, NULL);
|
||||||
|
|
||||||
|
if (virFileIsLink(cdevpath) != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (virFileResolveLink(cdevpath, &ccwdevpath) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!virFileExists(ccwdevpath))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
member = g_new0(virCCWGroupMemberType, 1);
|
||||||
|
|
||||||
|
member->ref = g_strdup(entry->d_name);
|
||||||
|
member->device = virCCWGroupDeviceDevNodeName("ccw", ccwdevpath);
|
||||||
|
|
||||||
|
VIR_APPEND_ELEMENT(*members, *nmembers, member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Groups without a member must not exist */
|
||||||
|
if (*nmembers == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
virCCWGroupTypeQethFree(virCCWGroupTypeQeth *qeth)
|
||||||
|
{
|
||||||
|
if (!qeth)
|
||||||
|
return;
|
||||||
|
|
||||||
|
VIR_FREE(qeth->card_type);
|
||||||
|
VIR_FREE(qeth->chpid);
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,6 +35,18 @@ struct _virCCWDeviceAddress {
|
|||||||
bool assigned;
|
bool assigned;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _virCCWGroupMemberType virCCWGroupMemberType;
|
||||||
|
struct _virCCWGroupMemberType {
|
||||||
|
char *ref; /* cdev reference */
|
||||||
|
char *device;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _virCCWGroupTypeQeth virCCWGroupTypeQeth;
|
||||||
|
struct _virCCWGroupTypeQeth {
|
||||||
|
char *card_type;
|
||||||
|
char *chpid;
|
||||||
|
};
|
||||||
|
|
||||||
bool virCCWDeviceAddressIsValid(virCCWDeviceAddress *addr);
|
bool virCCWDeviceAddressIsValid(virCCWDeviceAddress *addr);
|
||||||
bool virCCWDeviceAddressEqual(virCCWDeviceAddress *addr1,
|
bool virCCWDeviceAddressEqual(virCCWDeviceAddress *addr1,
|
||||||
virCCWDeviceAddress *addr2);
|
virCCWDeviceAddress *addr2);
|
||||||
@@ -50,3 +62,13 @@ int virCCWDeviceAddressParseFromString(const char *address,
|
|||||||
unsigned int *cssid,
|
unsigned int *cssid,
|
||||||
unsigned int *ssid,
|
unsigned int *ssid,
|
||||||
unsigned int *devno);
|
unsigned int *devno);
|
||||||
|
|
||||||
|
void virCCWGroupMemberTypeFree(virCCWGroupMemberType *member);
|
||||||
|
|
||||||
|
int virCCWGroupDeviceGetMembers(const char *sysfs_path,
|
||||||
|
virCCWGroupMemberType ***members,
|
||||||
|
size_t *nmembers);
|
||||||
|
|
||||||
|
void virCCWGroupTypeQethFree(virCCWGroupTypeQeth *qeth);
|
||||||
|
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCCWGroupMemberType, virCCWGroupMemberTypeFree);
|
||||||
|
|||||||
20
tests/nodedevschemadata/ccwgroup_0_0_bd00.xml
Normal file
20
tests/nodedevschemadata/ccwgroup_0_0_bd00.xml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<device>
|
||||||
|
<name>ccwgroup_0_0_bd00</name>
|
||||||
|
<path>/sys/devices/qeth/0.0.bd00</path>
|
||||||
|
<parent>computer</parent>
|
||||||
|
<capability type='ccwgroup'>
|
||||||
|
<state>online</state>
|
||||||
|
<cssid>0x0</cssid>
|
||||||
|
<ssid>0x0</ssid>
|
||||||
|
<devno>0xbd00</devno>
|
||||||
|
<members>
|
||||||
|
<ccw_device ref='cdev1'>ccw_0_0_bd01</ccw_device>
|
||||||
|
<ccw_device ref='cdev2'>ccw_0_0_bd02</ccw_device>
|
||||||
|
<ccw_device ref='cdev0'>ccw_0_0_bd00</ccw_device>
|
||||||
|
</members>
|
||||||
|
<capability type='qeth_generic'>
|
||||||
|
<card_type>OSD_10GIG</card_type>
|
||||||
|
<chpid>BD</chpid>
|
||||||
|
</capability>
|
||||||
|
</capability>
|
||||||
|
</device>
|
||||||
1
tests/nodedevxml2xmlout/ccwgroup_0_0_bd00.xml
Symbolic link
1
tests/nodedevxml2xmlout/ccwgroup_0_0_bd00.xml
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../nodedevschemadata/ccwgroup_0_0_bd00.xml
|
||||||
@@ -146,6 +146,7 @@ mymain(void)
|
|||||||
DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b");
|
DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b");
|
||||||
DO_TEST_INACTIVE("mdev_3627463d_b7f0_4fea_b468_f1da537d301b");
|
DO_TEST_INACTIVE("mdev_3627463d_b7f0_4fea_b468_f1da537d301b");
|
||||||
DO_TEST("ccw_0_0_ffff");
|
DO_TEST("ccw_0_0_ffff");
|
||||||
|
DO_TEST("ccwgroup_0_0_bd00");
|
||||||
DO_TEST("css_0_0_ffff");
|
DO_TEST("css_0_0_ffff");
|
||||||
DO_TEST("css_0_0_ffff_channel_dev_addr");
|
DO_TEST("css_0_0_ffff_channel_dev_addr");
|
||||||
DO_TEST("css_0_0_fffe_mdev_types");
|
DO_TEST("css_0_0_fffe_mdev_types");
|
||||||
|
|||||||
@@ -501,6 +501,9 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)
|
|||||||
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
||||||
flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX;
|
flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX;
|
||||||
break;
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
|
flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_DEV;
|
||||||
|
break;
|
||||||
case VIR_NODE_DEV_CAP_LAST:
|
case VIR_NODE_DEV_CAP_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user