5d360b
From f865f4fe293db1dfdfbb2e03963d0c6a25a398cc Mon Sep 17 00:00:00 2001
5d360b
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
5d360b
Date: Wed, 13 Dec 2017 13:38:42 +0100
5d360b
Subject: [PATCH 11/41] fw_cfg: add write callback
5d360b
MIME-Version: 1.0
5d360b
Content-Type: text/plain; charset=UTF-8
5d360b
Content-Transfer-Encoding: 8bit
5d360b
5d360b
RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
5d360b
Message-id: <20171213133912.26176-12-marcandre.lureau@redhat.com>
5d360b
Patchwork-id: 78361
5d360b
O-Subject: [RHEL-7.5 qemu-kvm PATCH v3 11/41] fw_cfg: add write callback
5d360b
Bugzilla: 1411490
5d360b
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
5d360b
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
5d360b
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
5d360b
5d360b
Reintroduce the write callback that was removed when write support was
5d360b
removed in commit 023e3148567ac898c7258138f8e86c3c2bb40d07.
5d360b
5d360b
Contrary to the previous callback implementation, the write_cb
5d360b
callback is called whenever a write happened, so handlers must be
5d360b
ready to handle partial write as necessary.
5d360b
5d360b
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
5d360b
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
5d360b
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
5d360b
5d360b
(cherry picked from commit 5f9252f7cc12c5cec1b3c6695aca02eb52ea7acc)
5d360b
5d360b
RHEL: major conflict due to API changes, but minor functional changes.
5d360b
5d360b
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
5d360b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
5d360b
---
5d360b
 hw/core/loader.c          |  2 +-
5d360b
 hw/nvram/fw_cfg.c         | 32 ++++++++++++++++++++------------
5d360b
 include/hw/nvram/fw_cfg.h |  8 ++++++--
5d360b
 3 files changed, 27 insertions(+), 15 deletions(-)
5d360b
5d360b
diff --git a/hw/core/loader.c b/hw/core/loader.c
5d360b
index c824bc2..5a15449 100644
5d360b
--- a/hw/core/loader.c
5d360b
+++ b/hw/core/loader.c
5d360b
@@ -700,7 +700,7 @@ void *rom_add_blob(const char *name, const void *blob, size_t len,
5d360b
         }
5d360b
 
5d360b
         fw_cfg_add_file_callback(fw_cfg, fw_file_name,
5d360b
-                                 fw_callback, callback_opaque,
5d360b
+                                 fw_callback, NULL, callback_opaque,
5d360b
                                  data, rom->romsize, read_only);
5d360b
     }
5d360b
     return data;
5d360b
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
5d360b
index a7bc98e..616c782 100644
5d360b
--- a/hw/nvram/fw_cfg.c
5d360b
+++ b/hw/nvram/fw_cfg.c
5d360b
@@ -54,6 +54,7 @@ typedef struct FWCfgEntry {
5d360b
     uint8_t *data;
5d360b
     void *callback_opaque;
5d360b
     FWCfgReadCallback read_callback;
5d360b
+    FWCfgWriteCallback write_cb;
5d360b
 } FWCfgEntry;
5d360b
 
5d360b
 struct FWCfgState {
5d360b
@@ -365,6 +366,8 @@ static void fw_cfg_dma_transfer(FWCfgState *s)
5d360b
                     dma_memory_read(s->dma, dma.address,
5d360b
                                     &e->data[s->cur_offset], len)) {
5d360b
                     dma.control |= FW_CFG_DMA_CTL_ERROR;
5d360b
+                } else if (e->write_cb) {
5d360b
+                    e->write_cb(e->callback_opaque, s->cur_offset, len);
5d360b
                 }
5d360b
             }
5d360b
 
5d360b
@@ -556,11 +559,12 @@ static const VMStateDescription vmstate_fw_cfg = {
5d360b
     }
5d360b
 };
5d360b
 
5d360b
-static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key,
5d360b
-                                           FWCfgReadCallback callback,
5d360b
-                                           void *callback_opaque,
5d360b
-                                           void *data, size_t len,
5d360b
-                                           bool read_only)
5d360b
+static void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
5d360b
+                                      FWCfgReadCallback callback,
5d360b
+                                      FWCfgWriteCallback write_cb,
5d360b
+                                      void *callback_opaque,
5d360b
+                                      void *data, size_t len,
5d360b
+                                      bool read_only)
5d360b
 {
5d360b
     int arch = !!(key & FW_CFG_ARCH_LOCAL);
5d360b
 
5d360b
@@ -572,13 +576,14 @@ static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key,
5d360b
     s->entries[arch][key].data = data;
5d360b
     s->entries[arch][key].len = (uint32_t)len;
5d360b
     s->entries[arch][key].read_callback = callback;
5d360b
+    s->entries[arch][key].write_cb = write_cb;
5d360b
     s->entries[arch][key].callback_opaque = callback_opaque;
5d360b
     s->entries[arch][key].allow_write = !read_only;
5d360b
 }
5d360b
 
5d360b
 void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
5d360b
 {
5d360b
-    fw_cfg_add_bytes_read_callback(s, key, NULL, NULL, data, len, true);
5d360b
+    fw_cfg_add_bytes_callback(s, key, NULL, NULL, NULL, data, len, true);
5d360b
 }
5d360b
 
5d360b
 void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value)
5d360b
@@ -616,8 +621,11 @@ void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
5d360b
 }
5d360b
 
5d360b
 void fw_cfg_add_file_callback(FWCfgState *s,  const char *filename,
5d360b
-                              FWCfgReadCallback callback, void *callback_opaque,
5d360b
-                              void *data, size_t len, bool read_only)
5d360b
+                              FWCfgReadCallback callback,
5d360b
+                              FWCfgWriteCallback write_cb,
5d360b
+                              void *callback_opaque,
5d360b
+                              void *data, size_t len,
5d360b
+                              bool read_only)
5d360b
 {
5d360b
     int i, index;
5d360b
     size_t dsize;
5d360b
@@ -641,9 +649,9 @@ void fw_cfg_add_file_callback(FWCfgState *s,  const char *filename,
5d360b
         }
5d360b
     }
5d360b
 
5d360b
-    fw_cfg_add_bytes_read_callback(s, FW_CFG_FILE_FIRST + index,
5d360b
-                                   callback, callback_opaque, data, len,
5d360b
-                                   read_only);
5d360b
+    fw_cfg_add_bytes_callback(s, FW_CFG_FILE_FIRST + index,
5d360b
+                              callback, write_cb, callback_opaque, data, len,
5d360b
+                              read_only);
5d360b
 
5d360b
     s->files->f[index].size   = cpu_to_be32(len);
5d360b
     s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
5d360b
@@ -655,7 +663,7 @@ void fw_cfg_add_file_callback(FWCfgState *s,  const char *filename,
5d360b
 void fw_cfg_add_file(FWCfgState *s,  const char *filename,
5d360b
                      void *data, size_t len)
5d360b
 {
5d360b
-    fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len, true);
5d360b
+    fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, data, len, true);
5d360b
 }
5d360b
 
5d360b
 static void fw_cfg_machine_ready(struct Notifier *n, void *data)
5d360b
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
5d360b
index 76fc787..a77ab84 100644
5d360b
--- a/include/hw/nvram/fw_cfg.h
5d360b
+++ b/include/hw/nvram/fw_cfg.h
5d360b
@@ -73,6 +73,7 @@ typedef struct FWCfgDmaAccess {
5d360b
 
5d360b
 typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
5d360b
 typedef void (*FWCfgReadCallback)(void *opaque, uint32_t offset);
5d360b
+typedef void (*FWCfgWriteCallback)(void *opaque, off_t start, size_t len);
5d360b
 
5d360b
 void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);
5d360b
 void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value);
5d360b
@@ -82,8 +83,11 @@ void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
5d360b
 void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
5d360b
                      size_t len);
5d360b
 void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
5d360b
-                              FWCfgReadCallback callback, void *callback_opaque,
5d360b
-                              void *data, size_t len, bool read_only);
5d360b
+                              FWCfgReadCallback callback,
5d360b
+                              FWCfgWriteCallback write_cb,
5d360b
+                              void *callback_opaque,
5d360b
+                              void *data, size_t len,
5d360b
+                              bool read_only);
5d360b
 FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
5d360b
                         hwaddr crl_addr, hwaddr data_addr);
5d360b
 FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
5d360b
-- 
5d360b
1.8.3.1
5d360b