mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 08:43:55 -06:00
Various patches loosely related to single binary work:
- Replace cpu_list() definition by CPUClass::list_cpus() callback - Remove few MO_TE definitions on Hexagon / X86 targets - Remove target_ulong uses in ARMMMUFaultInfo and ARM CPUWatchpoint - Remove DEVICE_HOST_ENDIAN definition - Evaluate TARGET_BIG_ENDIAN at compile time and use target_needs_bswap() more - Rename target_words_bigendian() as target_big_endian() - Convert target_name() and target_cpu_type() to TargetInfo API - Constify QOM TypeInfo class_data/interfaces fields - Get default_cpu_type calling machine_class_default_cpu_type() - Correct various uses of GLibCompareDataFunc prototype - Simplify ARM/Aarch64 gdb_get_core_xml_file() handling a bit - Move device tree files in their own pc-bios/dtb/ subdir - Correctly check strchrnul() symbol availability on macOS SDK - Move target-agnostic methods out of cpu-target.c and accel-target.c - Unmap canceled USB XHCI packet - Use deposit/extract API in designware model - Fix MIPS16e translation - Few missing header fixes -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmgLqb8ACgkQ4+MsLN6t wN6nCQ//cmv1M+NsndhO5TAK8T1eUSXKlTZh932uro6ZgxKwN4p+j1Qo7bq3O9gu qUMHNbcfQl8sHSytiXBoxCjLMCXC3u38iyz75WGXuPay06rs4wqmahqxL4tyno3l 1RviFts9xlLn+tJqqrAR6+pRdALld0TY+yXUjXgr4aK5pIRpLz9U/sIEoh7qbA5U x0MTaceDG3A91OYo0TgrNbcMe1b9GqQZ+a4tbaP+oE37wbiKdyQ68LjrEbV08Y1O qrFF4oxquV31QJcUiuII1W7hC6psGrMsUA1f1qDu7QvmybAZWNZNsR9T66X9jH5J wXMShJmmXwxugohmuPPFnDshzJy90aFL6Jy2shrfqcG2v0W66ARY1ZnbJLCcfczt 073bnE2dnOVhd/ny37RrIJNJLLmYM0yFDeKuYtNNAzpK9fpA7Q2PI8QiqNacQ3Pa TdEYrGlMk7OeNck8xJmJMY5rATthi1D4dIBv3rjQbUolQvPJe2Y9or0R2WL1jK5v hhr6DY01iSPES3CravmUs/aB1HRMPi/nX45OmFR6frAB7xqWMreh81heBVuoTTK8 PuXtRQgRMRKwDeTxlc6p+zba4mIEYG8rqJtPFRgViNCJ1KsgSIowup3BNU05YuFn NoPoRayMDVMgejVgJin3Mg2DCYvt/+MBmO4IoggWlFsXj59uUgA= =DXnZ -----END PGP SIGNATURE----- Merge tag 'single-binary-20250425' of https://github.com/philmd/qemu into staging Various patches loosely related to single binary work: - Replace cpu_list() definition by CPUClass::list_cpus() callback - Remove few MO_TE definitions on Hexagon / X86 targets - Remove target_ulong uses in ARMMMUFaultInfo and ARM CPUWatchpoint - Remove DEVICE_HOST_ENDIAN definition - Evaluate TARGET_BIG_ENDIAN at compile time and use target_needs_bswap() more - Rename target_words_bigendian() as target_big_endian() - Convert target_name() and target_cpu_type() to TargetInfo API - Constify QOM TypeInfo class_data/interfaces fields - Get default_cpu_type calling machine_class_default_cpu_type() - Correct various uses of GLibCompareDataFunc prototype - Simplify ARM/Aarch64 gdb_get_core_xml_file() handling a bit - Move device tree files in their own pc-bios/dtb/ subdir - Correctly check strchrnul() symbol availability on macOS SDK - Move target-agnostic methods out of cpu-target.c and accel-target.c - Unmap canceled USB XHCI packet - Use deposit/extract API in designware model - Fix MIPS16e translation - Few missing header fixes # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmgLqb8ACgkQ4+MsLN6t # wN6nCQ//cmv1M+NsndhO5TAK8T1eUSXKlTZh932uro6ZgxKwN4p+j1Qo7bq3O9gu # qUMHNbcfQl8sHSytiXBoxCjLMCXC3u38iyz75WGXuPay06rs4wqmahqxL4tyno3l # 1RviFts9xlLn+tJqqrAR6+pRdALld0TY+yXUjXgr4aK5pIRpLz9U/sIEoh7qbA5U # x0MTaceDG3A91OYo0TgrNbcMe1b9GqQZ+a4tbaP+oE37wbiKdyQ68LjrEbV08Y1O # qrFF4oxquV31QJcUiuII1W7hC6psGrMsUA1f1qDu7QvmybAZWNZNsR9T66X9jH5J # wXMShJmmXwxugohmuPPFnDshzJy90aFL6Jy2shrfqcG2v0W66ARY1ZnbJLCcfczt # 073bnE2dnOVhd/ny37RrIJNJLLmYM0yFDeKuYtNNAzpK9fpA7Q2PI8QiqNacQ3Pa # TdEYrGlMk7OeNck8xJmJMY5rATthi1D4dIBv3rjQbUolQvPJe2Y9or0R2WL1jK5v # hhr6DY01iSPES3CravmUs/aB1HRMPi/nX45OmFR6frAB7xqWMreh81heBVuoTTK8 # PuXtRQgRMRKwDeTxlc6p+zba4mIEYG8rqJtPFRgViNCJ1KsgSIowup3BNU05YuFn # NoPoRayMDVMgejVgJin3Mg2DCYvt/+MBmO4IoggWlFsXj59uUgA= # =DXnZ # -----END PGP SIGNATURE----- # gpg: Signature made Fri 25 Apr 2025 11:26:55 EDT # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * tag 'single-binary-20250425' of https://github.com/philmd/qemu: (58 commits) qemu: Convert target_name() to TargetInfo API accel: Move target-agnostic code from accel-target.c -> accel-common.c accel: Make AccelCPUClass structure target-agnostic accel: Include missing 'qemu/accel.h' header in accel-internal.h accel: Implement accel_init_ops_interfaces() for both system/user mode cpus: Move target-agnostic methods out of cpu-target.c cpus: Replace CPU_RESOLVING_TYPE -> target_cpu_type() qemu: Introduce target_cpu_type() qapi: Rename TargetInfo structure as QemuTargetInfo hw/microblaze: Evaluate TARGET_BIG_ENDIAN at compile time hw/mips: Evaluate TARGET_BIG_ENDIAN at compile time target/xtensa: Evaluate TARGET_BIG_ENDIAN at compile time target/mips: Check CPU endianness at runtime using env_is_bigendian() accel/kvm: Use target_needs_bswap() linux-user/elfload: Use target_needs_bswap() target/hexagon: Include missing 'accel/tcg/getpc.h' accel/tcg: Correct list of included headers in tcg-stub.c system/kvm: make functions accessible from common code meson: Use osdep_prefix for strchrnul() meson: Share common C source prefixes ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
06b40d250e
1202 changed files with 2817 additions and 2612 deletions
|
@ -232,7 +232,7 @@ static char *default_bus_get_fw_dev_path(DeviceState *dev)
|
|||
return g_strdup(object_get_typename(OBJECT(dev)));
|
||||
}
|
||||
|
||||
static void bus_class_init(ObjectClass *class, void *data)
|
||||
static void bus_class_init(ObjectClass *class, const void *data)
|
||||
{
|
||||
BusClass *bc = BUS_CLASS(class);
|
||||
ResettableClass *rc = RESETTABLE_CLASS(class);
|
||||
|
@ -260,7 +260,7 @@ static const TypeInfo bus_info = {
|
|||
.instance_init = qbus_initfn,
|
||||
.instance_finalize = qbus_finalize,
|
||||
.class_init = bus_class_init,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
.interfaces = (const InterfaceInfo[]) {
|
||||
{ TYPE_RESETTABLE_INTERFACE },
|
||||
{ }
|
||||
},
|
||||
|
|
|
@ -206,7 +206,7 @@ static void clock_finalizefn(Object *obj)
|
|||
g_free(clk->canonical_path);
|
||||
}
|
||||
|
||||
static void clock_class_init(ObjectClass *klass, void *data)
|
||||
static void clock_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
klass->unparent = clock_unparent;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include "qemu/log.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/lockcnt.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/qemu-print.h"
|
||||
#include "qemu/target-info.h"
|
||||
#include "exec/log.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "system/tcg.h"
|
||||
|
@ -152,6 +155,21 @@ ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
char *cpu_model_from_type(const char *typename)
|
||||
{
|
||||
g_autofree char *suffix = g_strdup_printf("-%s", target_cpu_type());
|
||||
|
||||
if (!object_class_by_name(typename)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (g_str_has_suffix(typename, suffix)) {
|
||||
return g_strndup(typename, strlen(typename) - strlen(suffix));
|
||||
}
|
||||
|
||||
return g_strdup(typename);
|
||||
}
|
||||
|
||||
static void cpu_common_parse_features(const char *typename, char *features,
|
||||
Error **errp)
|
||||
{
|
||||
|
@ -183,6 +201,33 @@ static void cpu_common_parse_features(const char *typename, char *features,
|
|||
}
|
||||
}
|
||||
|
||||
const char *parse_cpu_option(const char *cpu_option)
|
||||
{
|
||||
ObjectClass *oc;
|
||||
CPUClass *cc;
|
||||
gchar **model_pieces;
|
||||
const char *cpu_type;
|
||||
|
||||
model_pieces = g_strsplit(cpu_option, ",", 2);
|
||||
if (!model_pieces[0]) {
|
||||
error_report("-cpu option cannot be empty");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
oc = cpu_class_by_name(target_cpu_type(), model_pieces[0]);
|
||||
if (oc == NULL) {
|
||||
error_report("unable to find CPU model '%s'", model_pieces[0]);
|
||||
g_strfreev(model_pieces);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
cpu_type = object_class_get_name(oc);
|
||||
cc = CPU_CLASS(oc);
|
||||
cc->parse_features(cpu_type, model_pieces[1], &error_fatal);
|
||||
g_strfreev(model_pieces);
|
||||
return cpu_type;
|
||||
}
|
||||
|
||||
bool cpu_exec_realizefn(CPUState *cpu, Error **errp)
|
||||
{
|
||||
if (!accel_cpu_common_realize(cpu, errp)) {
|
||||
|
@ -320,7 +365,7 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
|
|||
return cpu->cpu_index;
|
||||
}
|
||||
|
||||
static void cpu_common_class_init(ObjectClass *klass, void *data)
|
||||
static void cpu_common_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||
|
@ -359,3 +404,32 @@ static void cpu_register_types(void)
|
|||
}
|
||||
|
||||
type_init(cpu_register_types)
|
||||
|
||||
static void cpu_list_entry(gpointer data, gpointer user_data)
|
||||
{
|
||||
CPUClass *cc = CPU_CLASS(OBJECT_CLASS(data));
|
||||
const char *typename = object_class_get_name(OBJECT_CLASS(data));
|
||||
g_autofree char *model = cpu_model_from_type(typename);
|
||||
|
||||
if (cc->deprecation_note) {
|
||||
qemu_printf(" %s (deprecated)\n", model);
|
||||
} else {
|
||||
qemu_printf(" %s\n", model);
|
||||
}
|
||||
}
|
||||
|
||||
void list_cpus(void)
|
||||
{
|
||||
CPUClass *cc = CPU_CLASS(object_class_by_name(target_cpu_type()));
|
||||
|
||||
if (cc->list_cpus) {
|
||||
cc->list_cpus();
|
||||
} else {
|
||||
GSList *list;
|
||||
|
||||
list = object_class_get_list_sorted(TYPE_CPU, false);
|
||||
qemu_printf("Available CPUs:\n");
|
||||
g_slist_foreach(list, cpu_list_entry, NULL);
|
||||
g_slist_free(list);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ bool cpu_virtio_is_big_endian(CPUState *cpu)
|
|||
if (cpu->cc->sysemu_ops->virtio_is_big_endian) {
|
||||
return cpu->cc->sysemu_ops->virtio_is_big_endian(cpu);
|
||||
}
|
||||
return target_words_bigendian();
|
||||
return target_big_endian();
|
||||
}
|
||||
|
||||
GuestPanicInformation *cpu_get_crash_info(CPUState *cpu)
|
||||
|
|
|
@ -182,7 +182,7 @@ static const Property generic_loader_props[] = {
|
|||
DEFINE_PROP_STRING("file", GenericLoaderState, file),
|
||||
};
|
||||
|
||||
static void generic_loader_class_init(ObjectClass *klass, void *data)
|
||||
static void generic_loader_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ static const Property guest_loader_props[] = {
|
|||
DEFINE_PROP_STRING("initrd", GuestLoaderState, initrd),
|
||||
};
|
||||
|
||||
static void guest_loader_class_init(ObjectClass *klass, void *data)
|
||||
static void guest_loader_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
|
|
|
@ -1410,7 +1410,7 @@ typedef struct RomSec {
|
|||
* work, but this way saves a little work later by avoiding
|
||||
* dealing with "gaps" of 0 length.
|
||||
*/
|
||||
static gint sort_secs(gconstpointer a, gconstpointer b)
|
||||
static gint sort_secs(gconstpointer a, gconstpointer b, gpointer d)
|
||||
{
|
||||
RomSec *ra = (RomSec *) a;
|
||||
RomSec *rb = (RomSec *) b;
|
||||
|
@ -1463,7 +1463,7 @@ RomGap rom_find_largest_gap_between(hwaddr base, size_t size)
|
|||
/* sentinel */
|
||||
secs = add_romsec_to_list(secs, base + size, 1);
|
||||
|
||||
secs = g_list_sort(secs, sort_secs);
|
||||
secs = g_list_sort_with_data(secs, sort_secs, NULL);
|
||||
|
||||
for (it = g_list_first(secs); it; it = g_list_next(it)) {
|
||||
cand = (RomSec *) it->data;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "qapi/qobject-input-visitor.h"
|
||||
#include "qapi/type-helpers.h"
|
||||
#include "qemu/uuid.h"
|
||||
#include "qemu/target-info.h"
|
||||
#include "qom/qom-qobject.h"
|
||||
#include "system/hostmem.h"
|
||||
#include "system/hw_accel.h"
|
||||
|
@ -73,6 +74,7 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
|
|||
|
||||
for (el = machines; el; el = el->next) {
|
||||
MachineClass *mc = el->data;
|
||||
const char *default_cpu_type = machine_class_default_cpu_type(mc);
|
||||
MachineInfo *info;
|
||||
|
||||
info = g_malloc0(sizeof(*info));
|
||||
|
@ -91,8 +93,8 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
|
|||
info->numa_mem_supported = mc->numa_mem_supported;
|
||||
info->deprecated = !!mc->deprecation_reason;
|
||||
info->acpi = !!object_class_property_find(OBJECT_CLASS(mc), "acpi");
|
||||
if (mc->default_cpu_type) {
|
||||
info->default_cpu_type = g_strdup(mc->default_cpu_type);
|
||||
if (default_cpu_type) {
|
||||
info->default_cpu_type = g_strdup(default_cpu_type);
|
||||
}
|
||||
if (mc->default_ram_id) {
|
||||
info->default_ram_id = g_strdup(mc->default_ram_id);
|
||||
|
@ -133,9 +135,9 @@ CurrentMachineParams *qmp_query_current_machine(Error **errp)
|
|||
return params;
|
||||
}
|
||||
|
||||
TargetInfo *qmp_query_target(Error **errp)
|
||||
QemuTargetInfo *qmp_query_target(Error **errp)
|
||||
{
|
||||
TargetInfo *info = g_malloc0(sizeof(*info));
|
||||
QemuTargetInfo *info = g_malloc0(sizeof(*info));
|
||||
|
||||
info->arch = qapi_enum_parse(&SysEmuTarget_lookup, target_name(), -1,
|
||||
&error_abort);
|
||||
|
|
|
@ -1100,7 +1100,7 @@ out:
|
|||
return r;
|
||||
}
|
||||
|
||||
static void machine_class_init(ObjectClass *oc, void *data)
|
||||
static void machine_class_init(ObjectClass *oc, const void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
|
@ -1243,7 +1243,7 @@ static void machine_class_init(ObjectClass *oc, void *data)
|
|||
"Memory size configuration");
|
||||
}
|
||||
|
||||
static void machine_class_base_init(ObjectClass *oc, void *data)
|
||||
static void machine_class_base_init(ObjectClass *oc, const void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
mc->max_cpus = mc->max_cpus ?: 1;
|
||||
|
|
|
@ -119,7 +119,7 @@ static const Property or_irq_properties[] = {
|
|||
DEFINE_PROP_UINT16("num-lines", OrIRQState, num_lines, 1),
|
||||
};
|
||||
|
||||
static void or_irq_class_init(ObjectClass *klass, void *data)
|
||||
static void or_irq_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ static const Property platform_bus_properties[] = {
|
|||
DEFINE_PROP_UINT32("mmio_size", PlatformBusDevice, mmio_size, 0),
|
||||
};
|
||||
|
||||
static void platform_bus_class_init(ObjectClass *klass, void *data)
|
||||
static void platform_bus_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
|
|
|
@ -693,7 +693,7 @@ static void device_finalize(Object *obj)
|
|||
g_free(dev->id);
|
||||
}
|
||||
|
||||
static void device_class_base_init(ObjectClass *class, void *data)
|
||||
static void device_class_base_init(ObjectClass *class, const void *data)
|
||||
{
|
||||
DeviceClass *klass = DEVICE_CLASS(class);
|
||||
|
||||
|
@ -731,7 +731,7 @@ device_vmstate_if_get_id(VMStateIf *obj)
|
|||
return qdev_get_dev_path(dev);
|
||||
}
|
||||
|
||||
static void device_class_init(ObjectClass *class, void *data)
|
||||
static void device_class_init(ObjectClass *class, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(class);
|
||||
VMStateIfClass *vc = VMSTATE_IF_CLASS(class);
|
||||
|
@ -870,7 +870,7 @@ static const TypeInfo device_type_info = {
|
|||
.class_init = device_class_init,
|
||||
.abstract = true,
|
||||
.class_size = sizeof(DeviceClass),
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
.interfaces = (const InterfaceInfo[]) {
|
||||
{ TYPE_VMSTATE_IF },
|
||||
{ TYPE_RESETTABLE_INTERFACE },
|
||||
{ }
|
||||
|
|
|
@ -319,7 +319,7 @@ void register_finalize_block(RegisterInfoArray *r_array)
|
|||
g_free(r_array);
|
||||
}
|
||||
|
||||
static void register_class_init(ObjectClass *oc, void *data)
|
||||
static void register_class_init(ObjectClass *oc, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ static void legacy_reset_finalize(Object *obj)
|
|||
{
|
||||
}
|
||||
|
||||
static void legacy_reset_class_init(ObjectClass *klass, void *data)
|
||||
static void legacy_reset_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||
|
||||
|
|
|
@ -68,7 +68,8 @@ static void resettable_container_finalize(Object *obj)
|
|||
{
|
||||
}
|
||||
|
||||
static void resettable_container_class_init(ObjectClass *klass, void *data)
|
||||
static void resettable_container_class_init(ObjectClass *klass,
|
||||
const void *data)
|
||||
{
|
||||
ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ static const Property split_irq_properties[] = {
|
|||
DEFINE_PROP_UINT16("num-lines", SplitIRQ, num_lines, 1),
|
||||
};
|
||||
|
||||
static void split_irq_class_init(ObjectClass *klass, void *data)
|
||||
static void split_irq_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ void foreach_dynamic_sysbus_device(FindSysbusDeviceFunc *func, void *opaque)
|
|||
}
|
||||
|
||||
|
||||
static void system_bus_class_init(ObjectClass *klass, void *data)
|
||||
static void system_bus_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
BusClass *k = BUS_CLASS(klass);
|
||||
|
||||
|
@ -280,7 +280,7 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev)
|
|||
return g_strdup(qdev_fw_name(dev));
|
||||
}
|
||||
|
||||
static void sysbus_device_class_init(ObjectClass *klass, void *data)
|
||||
static void sysbus_device_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *k = DEVICE_CLASS(klass);
|
||||
k->realize = sysbus_device_realize;
|
||||
|
@ -320,7 +320,8 @@ BusState *sysbus_get_default(void)
|
|||
return main_system_bus;
|
||||
}
|
||||
|
||||
static void dynamic_sysbus_device_class_init(ObjectClass *klass, void *data)
|
||||
static void dynamic_sysbus_device_class_init(ObjectClass *klass,
|
||||
const void *data)
|
||||
{
|
||||
DeviceClass *k = DEVICE_CLASS(klass);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue