All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ruien Zhang <zhangruien@bytedance.com>
To: peter.maydell@linaro.org, richard.henderson@linaro.org,
	kraxel@redhat.com, eblake@redhat.com, pbonzini@redhat.com,
	berrange@redhat.com
Cc: qemu-devel@nongnu.org, zhangruien <zhangruien@bytedance.com>
Subject: [PATCH 1/2] printer: Introduce printer subsystem
Date: Thu, 13 Jan 2022 19:56:58 +0800	[thread overview]
Message-ID: <20220113115659.72788-2-zhangruien@bytedance.com> (raw)
In-Reply-To: <20220113115659.72788-1-zhangruien@bytedance.com>

From: zhangruien <zhangruien@bytedance.com>

This patch describes the skeleton of QEMU printer subsystem with a
dummy builtin driver.

Signed-off-by: zhangruien <zhangruien@bytedance.com>
---
 MAINTAINERS               |   7 ++
 include/printer/printer.h |  42 ++++++++++
 meson.build               |  12 ++-
 meson_options.txt         |   3 +
 printer/builtin.c         |  61 +++++++++++++++
 printer/meson.build       |  14 ++++
 printer/printer.c         | 191 ++++++++++++++++++++++++++++++++++++++++++++++
 printer/trace-events      |   5 ++
 printer/trace.h           |   1 +
 qapi/meson.build          |   1 +
 qapi/printer.json         |  47 ++++++++++++
 qapi/qapi-schema.json     |   1 +
 qemu-options.hx           |   8 ++
 softmmu/vl.c              |   4 +
 14 files changed, 396 insertions(+), 1 deletion(-)
 create mode 100644 include/printer/printer.h
 create mode 100644 printer/builtin.c
 create mode 100644 printer/meson.build
 create mode 100644 printer/printer.c
 create mode 100644 printer/trace-events
 create mode 100644 printer/trace.h
 create mode 100644 qapi/printer.json

diff --git a/MAINTAINERS b/MAINTAINERS
index c98a61caee..689f20d740 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3086,6 +3086,13 @@ F: hw/core/clock-vmstate.c
 F: hw/core/qdev-clock.c
 F: docs/devel/clocks.rst
 
+Printer Subsystem
+M: Ruien Zhang <zhangruien@bytedance.com>
+S: Maintained
+F: include/printer
+F: printer
+F: qapi/printer.json
+
 Usermode Emulation
 ------------------
 Overall usermode emulation
diff --git a/include/printer/printer.h b/include/printer/printer.h
new file mode 100644
index 0000000000..c8afbc64c8
--- /dev/null
+++ b/include/printer/printer.h
@@ -0,0 +1,42 @@
+/*
+ * QEMU Printer subsystem header
+ *
+ * Copyright (c) 2022 ByteDance, Inc.
+ *
+ * Author:
+ *   Ruien Zhang <zhangruien@bytedance.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QEMU_PRINTER_H
+#define QEMU_PRINTER_H
+
+#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
+#include "qapi/qapi-types-printer.h"
+
+#define TYPE_PRINTERDEV "printerdev"
+
+struct QEMUPrinter {
+    Object  *parent_obj;
+
+    char *model;
+    Printerdev *dev;
+
+    QLIST_ENTRY(QEMUPrinter) list;
+};
+
+OBJECT_DECLARE_TYPE(QEMUPrinter, QEMUPrinterClass, PRINTERDEV)
+
+struct QEMUPrinterClass {
+    ObjectClass parent_class;
+};
+
+void qemu_printer_new_from_opts(const char *opt);
+void qemu_printer_del(QEMUPrinter *printer);
+const char *qemu_printer_id(QEMUPrinter *printer);
+QEMUPrinter *qemu_printer_by_id(const char *id);
+
+#endif /* QEMU_PRINTER_H */
diff --git a/meson.build b/meson.build
index c1b1db1e28..b3db26190d 100644
--- a/meson.build
+++ b/meson.build
@@ -2397,6 +2397,7 @@ genh += hxdep
 authz_ss = ss.source_set()
 blockdev_ss = ss.source_set()
 block_ss = ss.source_set()
+printer_ss = ss.source_set()
 chardev_ss = ss.source_set()
 common_ss = ss.source_set()
 common_user_ss = ss.source_set()
@@ -2455,6 +2456,7 @@ if have_system
     'audio',
     'backends',
     'backends/tpm',
+    'printer',
     'chardev',
     'ebpf',
     'hw/9pfs',
@@ -2574,6 +2576,7 @@ endif
 
 subdir('audio')
 subdir('io')
+subdir('printer')
 subdir('chardev')
 subdir('fsdev')
 subdir('dump')
@@ -2843,6 +2846,13 @@ libqmp = static_library('qmp', qmp_ss.sources() + genh,
 
 qmp = declare_dependency(link_whole: [libqmp])
 
+printer_ss = printer_ss.apply(config_host, strict: false)
+libprinter = static_library('printer', printer_ss.sources() + genh,
+                            name_suffix: 'fa',
+                            build_by_default: false)
+
+printer = declare_dependency(link_whole: libprinter)
+
 libchardev = static_library('chardev', chardev_ss.sources() + genh,
                             name_suffix: 'fa',
                             dependencies: [gnutls],
@@ -2869,7 +2879,7 @@ foreach m : block_mods + softmmu_mods
                 install_dir: qemu_moddir)
 endforeach
 
-softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
+softmmu_ss.add(authz, blockdev, printer, chardev, crypto, io, qmp)
 common_ss.add(qom, qemuutil)
 
 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
diff --git a/meson_options.txt b/meson_options.txt
index 921967eddb..5b3b502798 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -208,3 +208,6 @@ option('fdt', type: 'combo', value: 'auto',
 
 option('selinux', type: 'feature', value: 'auto',
        description: 'SELinux support in qemu-nbd')
+
+option('printer', type: 'feature', value: 'auto',
+       description: 'Printer subsystem support')
diff --git a/printer/builtin.c b/printer/builtin.c
new file mode 100644
index 0000000000..bc33a1d363
--- /dev/null
+++ b/printer/builtin.c
@@ -0,0 +1,61 @@
+/*
+ * QEMU Builtin printer backend
+ *
+ * Copyright (c) 2022 ByteDance, Inc.
+ *
+ * Author:
+ *   Ruien Zhang <zhangruien@bytedance.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "qemu/log.h"
+#include "qemu/main-loop.h"
+#include "qom/object.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qapi/qapi-visit-printer.h"
+#include "printer/printer.h"
+#include "trace.h"
+
+#define TYPE_PRINTER_BUILTIN TYPE_PRINTERDEV"-builtin"
+
+typedef struct PrinterBuiltin {
+    QEMUPrinter parent;
+
+    void *opaque; /* used by driver itself */
+} PrinterBuiltin;
+
+DECLARE_INSTANCE_CHECKER(PrinterBuiltin, PRINTER_BUILTIN_DEV,
+                         TYPE_PRINTER_BUILTIN)
+
+static void printer_builtin_init(Object *obj)
+{
+}
+
+static void printer_builtin_finalize(Object *obj)
+{
+}
+
+static void printer_builtin_class_init(ObjectClass *oc, void *data)
+{
+}
+
+static const TypeInfo printer_builtin_type_info = {
+    .name = TYPE_PRINTER_BUILTIN,
+    .parent = TYPE_PRINTERDEV,
+    .instance_size = sizeof(PrinterBuiltin),
+    .instance_init = printer_builtin_init,
+    .instance_finalize = printer_builtin_finalize,
+    .class_init = printer_builtin_class_init,
+};
+
+static void register_types(void)
+{
+    type_register_static(&printer_builtin_type_info);
+}
+
+type_init(register_types);
diff --git a/printer/meson.build b/printer/meson.build
new file mode 100644
index 0000000000..9814de2a57
--- /dev/null
+++ b/printer/meson.build
@@ -0,0 +1,14 @@
+printer_ss.add([files(
+  'printer.c',
+)])
+
+printer_modules = {}
+foreach m : [
+  ['builtin', files('builtin.c')],
+]
+  module_ss = ss.source_set()
+  module_ss.add(m[1])
+  printer_modules += {m[0] : module_ss}
+endforeach
+
+modules += {'printer': printer_modules}
diff --git a/printer/printer.c b/printer/printer.c
new file mode 100644
index 0000000000..2d3f57a6e1
--- /dev/null
+++ b/printer/printer.c
@@ -0,0 +1,191 @@
+/*
+ * QEMU Printer subsystem
+ *
+ * Copyright (c) 2022 ByteDance, Inc.
+ *
+ * Author:
+ *   Ruien Zhang <zhangruien@bytedance.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/help_option.h"
+#include "qemu/iov.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/qemu-print.h"
+#include "qom/object.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qapi/qapi-visit-printer.h"
+#include "printer/printer.h"
+#include "trace.h"
+
+static QLIST_HEAD(, QEMUPrinter) qemu_printers;
+
+const char *qemu_printer_id(QEMUPrinter *printer)
+{
+    if (printer->dev && printer->dev->id) {
+        return printer->dev->id;
+    }
+
+    return "";
+}
+
+QEMUPrinter *qemu_printer_by_id(const char *id)
+{
+    QEMUPrinter *printer;
+
+    if (!id) {
+        return NULL;
+    }
+
+    QLIST_FOREACH(printer, &qemu_printers, list) {
+        if (!strcmp(qemu_printer_id(printer), id)) {
+            return printer;
+        }
+    }
+
+    return NULL;
+}
+
+static const QEMUPrinterClass *printer_get_class(const char *typename,
+                                               Error **errp)
+{
+    ObjectClass *oc;
+
+    oc = module_object_class_by_name(typename);
+
+    if (!object_class_dynamic_cast(oc, TYPE_PRINTERDEV)) {
+        error_setg(errp, "%s: missing %s implementation",
+                   TYPE_PRINTERDEV, typename);
+        return NULL;
+    }
+
+    if (object_class_is_abstract(oc)) {
+        error_setg(errp, "%s: %s is abstract type", TYPE_PRINTERDEV, typename);
+        return NULL;
+    }
+
+    return PRINTERDEV_CLASS(oc);
+}
+
+static QEMUPrinter *qemu_printer_new(Printerdev *dev, Error **errp)
+{
+    Object *obj;
+    QEMUPrinter *printer = NULL;
+    g_autofree char *typename = NULL;
+    const char *driver = PrinterdevDriver_str(dev->driver);
+
+    typename = g_strdup_printf("%s-%s", TYPE_PRINTERDEV, driver);
+    if (!printer_get_class(typename, errp)) {
+        return NULL;
+    }
+
+    obj = object_new(typename);
+    if (!obj) {
+        return NULL;
+    }
+
+    printer = PRINTERDEV(obj);
+    printer->dev = dev;
+
+    QLIST_INSERT_HEAD(&qemu_printers, printer, list);
+    trace_qemu_printer_new(qemu_printer_id(printer), typename);
+
+    return printer;
+}
+
+typedef struct PrinterdevClassFE {
+    void (*fn)(const char *name, void *opaque);
+    void *opaque;
+} PrinterdevClassFE;
+
+static void printerdev_class_foreach(ObjectClass *klass, void *opaque)
+{
+    PrinterdevClassFE *fe = opaque;
+
+    assert(g_str_has_prefix(object_class_get_name(klass), TYPE_PRINTERDEV"-"));
+    fe->fn(object_class_get_name(klass) + 11, fe->opaque);
+}
+
+static void printerdev_name_foreach(void (*fn)(const char *name, void *opaque),
+                                   void *opaque)
+{
+    PrinterdevClassFE fe = { .fn = fn, .opaque = opaque };
+
+    object_class_foreach(printerdev_class_foreach, TYPE_PRINTERDEV, false, &fe);
+}
+
+static void help_string_append(const char *name, void *opaque)
+{
+    GString *str = opaque;
+
+    g_string_append_printf(str, "\n  %s", name);
+}
+
+void qemu_printer_new_from_opts(const char *opt)
+{
+    Printerdev *dev;
+
+    if (opt && is_help_option(opt)) {
+        GString *str = g_string_new("");
+
+        printerdev_name_foreach(help_string_append, str);
+
+        qemu_printf("Available printerdev backend types: %s\n", str->str);
+        g_string_free(str, true);
+        return;
+    }
+
+    Visitor *v = qobject_input_visitor_new_str(opt, "driver", &error_fatal);
+    visit_type_Printerdev(v, NULL, &dev, &error_fatal);
+    visit_free(v);
+
+    if (qemu_printer_by_id(dev->id)) {
+        error_setg(&error_fatal, "%s: id %s already existed",
+                   TYPE_PRINTERDEV, dev->id);
+    }
+
+    if (!qemu_printer_new(dev, &error_fatal)) {
+        qapi_free_Printerdev(dev);
+    }
+}
+
+void qemu_printer_del(QEMUPrinter *printer)
+{
+    trace_qemu_printer_del(qemu_printer_id(printer));
+
+    QLIST_REMOVE(printer, list);
+    qapi_free_Printerdev(printer->dev);
+    object_unref(printer);
+}
+
+
+static void printer_init(Object *obj)
+{
+}
+
+static void printer_finalize(Object *obj)
+{
+}
+
+static const TypeInfo printer_type_info = {
+    .name = TYPE_PRINTERDEV,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(QEMUPrinter),
+    .instance_init = printer_init,
+    .instance_finalize = printer_finalize,
+    .abstract = true,
+    .class_size = sizeof(QEMUPrinterClass),
+};
+
+static void register_types(void)
+{
+    type_register_static(&printer_type_info);
+}
+
+type_init(register_types);
diff --git a/printer/trace-events b/printer/trace-events
new file mode 100644
index 0000000000..e453bbe691
--- /dev/null
+++ b/printer/trace-events
@@ -0,0 +1,5 @@
+# See docs/devel/tracing.rst for syntax documentation.
+
+# printer.c
+qemu_printer_new(const char *dev, char *typename) "%s: new printer with type %s"
+qemu_printer_del(const char *dev) "%s: delete printer"
diff --git a/printer/trace.h b/printer/trace.h
new file mode 100644
index 0000000000..9717d37ac7
--- /dev/null
+++ b/printer/trace.h
@@ -0,0 +1 @@
+#include "trace/trace-printer.h"
diff --git a/qapi/meson.build b/qapi/meson.build
index c0c49c15e4..f85af6b7d6 100644
--- a/qapi/meson.build
+++ b/qapi/meson.build
@@ -59,6 +59,7 @@ if have_system
     'rdma',
     'rocker',
     'tpm',
+    'printer',
   ]
 endif
 if have_system or have_tools
diff --git a/qapi/printer.json b/qapi/printer.json
new file mode 100644
index 0000000000..9c2ecfe874
--- /dev/null
+++ b/qapi/printer.json
@@ -0,0 +1,47 @@
+# -*- mode: python -*-
+#
+# Copyright (C) 2022 Ruien Zhang <zhangruien@bytedance.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# = Printer
+##
+
+##
+# @PrinterBuiltinOptions:
+#
+# Options of the builtin printer.
+#
+# Since: 6.3
+##
+{ 'struct': 'PrinterBuiltinOptions',
+  'data': {} }
+
+##
+# @PrinterdevDriver:
+#
+# An enumeration of possible printer backend drivers.
+#
+# Since: 6.3
+##
+{ 'enum': 'PrinterdevDriver',
+  'data': [ 'builtin' ] }
+
+##
+# @Printerdev:
+#
+# Captures the configuration of a printer device.
+#
+# @id: identifier for monitor commands.
+#
+# Since: 6.3
+##
+{ 'union': 'Printerdev',
+  'base': {
+    'id': 'str',
+    'driver': 'PrinterdevDriver'},
+  'discriminator': 'driver',
+  'data': {
+    'builtin': 'PrinterBuiltinOptions' } }
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
index 4912b9744e..114b6a80cb 100644
--- a/qapi/qapi-schema.json
+++ b/qapi/qapi-schema.json
@@ -93,3 +93,4 @@
 { 'include': 'audio.json' }
 { 'include': 'acpi.json' }
 { 'include': 'pci.json' }
+{ 'include': 'printer.json' }
diff --git a/qemu-options.hx b/qemu-options.hx
index ec90505d84..448a456f86 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3564,6 +3564,14 @@ The available backends are:
     traffic identified by a name (preferably a fqdn).
 ERST
 
+DEFHEADING(Printer device options:)
+
+DEF("printerdev", HAS_ARG, QEMU_OPTION_printerdev,
+    "-printerdev help\n"
+    "-printerdev builtin,id=id\n"
+    , QEMU_ARCH_ALL
+)
+
 DEFHEADING()
 
 #ifdef CONFIG_TPM
diff --git a/softmmu/vl.c b/softmmu/vl.c
index a8cad43691..67b3c48fa1 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -94,6 +94,7 @@
 #ifdef CONFIG_VIRTFS
 #include "fsdev/qemu-fsdev.h"
 #endif
+#include "printer/printer.h"
 #include "sysemu/qtest.h"
 
 #include "disas/disas.h"
@@ -3247,6 +3248,9 @@ void qemu_init(int argc, char **argv, char **envp)
                              qemu_opt_get(opts, "mount_tag"), &error_abort);
                 break;
             }
+            case QEMU_OPTION_printerdev:
+                qemu_printer_new_from_opts(optarg);
+                break;
             case QEMU_OPTION_serial:
                 add_device_config(DEV_SERIAL, optarg);
                 default_serial = 0;
-- 
2.11.0



  reply	other threads:[~2022-01-13 14:56 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-13 11:56 [PATCH 0/2] Introduce printer subsystem and USB printer device Ruien Zhang
2022-01-13 11:56 ` Ruien Zhang [this message]
2022-01-13 11:56 ` [PATCH 2/2] usb-printer: Introduce USB printer class Ruien Zhang
2022-01-14  9:32 ` [PATCH 0/2] Introduce printer subsystem and USB printer device Gerd Hoffmann
2022-01-14 13:38   ` Ruien Zhang
2022-01-15 15:31   ` Ruien Zhang
2022-01-17  7:17     ` Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220113115659.72788-2-zhangruien@bytedance.com \
    --to=zhangruien@bytedance.com \
    --cc=berrange@redhat.com \
    --cc=eblake@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.