Patchwork [v5,13/14] pcie/hotplug: introduce pushing attention button command

login
register
mail settings
Submitter Isaku Yamahata
Date Oct. 19, 2010, 9:06 a.m.
Message ID <11c84a8d5de0534826e4f514da56d64c7e8f9d0e.1287478251.git.yamahata@valinux.co.jp>
Download mbox | patch
Permalink /patch/68283/
State New
Headers show

Comments

Isaku Yamahata - Oct. 19, 2010, 9:06 a.m.
glue pcie_push_attention_button command.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
 hw/pcie_port.c  |   82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-monitor.hx |   14 +++++++++
 sysemu.h        |    4 +++
 3 files changed, 100 insertions(+), 0 deletions(-)

Patch

diff --git a/hw/pcie_port.c b/hw/pcie_port.c
index 117de61..f43a1c7 100644
--- a/hw/pcie_port.c
+++ b/hw/pcie_port.c
@@ -18,6 +18,10 @@ 
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "qemu-objects.h"
+#include "sysemu.h"
+#include "monitor.h"
+#include "pcie.h"
 #include "pcie_port.h"
 
 void pcie_port_init_reg(PCIDevice *d)
@@ -114,3 +118,81 @@  void pcie_chassis_del_slot(PCIESlot *s)
 {
     QLIST_REMOVE(s, next);
 }
+
+/**************************************************************************
+ * glue for qemu monitor
+ */
+
+/* Parse [<chassis>.]<slot>, return -1 on error */
+static int pcie_parse_slot_addr(const char* slot_addr,
+                                uint8_t *chassisp, uint16_t *slotp)
+{
+    const char *p;
+    char *e;
+    unsigned long val;
+    unsigned long chassis = 0;
+    unsigned long slot;
+
+    p = slot_addr;
+    val = strtoul(p, &e, 0);
+    if (e == p) {
+        return -1;
+    }
+    if (*e == '.') {
+        chassis = val;
+        p = e + 1;
+        val = strtoul(p, &e, 0);
+        if (e == p) {
+            return -1;
+        }
+    }
+    slot = val;
+
+    if (*e) {
+        return -1;
+    }
+
+    if (chassis > 0xff || slot > 0xffff) {
+        return -1;
+    }
+
+    *chassisp = chassis;
+    *slotp = slot;
+    return 0;
+}
+
+void pcie_attention_button_push_print(Monitor *mon, const QObject *data)
+{
+    QDict *qdict;
+
+    assert(qobject_type(data) == QTYPE_QDICT);
+    qdict = qobject_to_qdict(data);
+
+    monitor_printf(mon, "OK chassis %d, slot %d\n",
+                   (int) qdict_get_int(qdict, "chassis"),
+                   (int) qdict_get_int(qdict, "slot"));
+}
+
+int pcie_attention_button_push(Monitor *mon, const QDict *qdict,
+                               QObject **ret_data)
+{
+    const char* pcie_slot = qdict_get_str(qdict, "pcie_slot");
+    uint8_t chassis;
+    uint16_t slot;
+    PCIESlot *s;
+
+    if (pcie_parse_slot_addr(pcie_slot, &chassis, &slot) < 0) {
+        monitor_printf(mon, "invalid pcie slot address %s\n", pcie_slot);
+        return -1;
+    }
+    s = pcie_chassis_find_slot(chassis, slot);
+    if (!s) {
+        monitor_printf(mon, "slot is not found. %s\n", pcie_slot);
+        return -1;
+    }
+    pcie_cap_slot_push_attention_button(&s->port.br.dev);
+    *ret_data = qobject_from_jsonf("{ 'chassis': %d, 'slot': %d}",
+                                   chassis, slot);
+    assert(*ret_data);
+    return 0;
+}
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 2af3de6..965c754 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -1154,6 +1154,20 @@  Hot remove PCI device.
 ETEXI
 
     {
+        .name       = "pcie_push_attention_button",
+        .args_type  = "pcie_slot:s",
+        .params     = "[<chassis>.]<slot>",
+        .help       = "push pci express attention button",
+        .user_print  = pcie_attention_button_push_print,
+        .mhandler.cmd_new = pcie_attention_button_push,
+    },
+
+STEXI
+@item pcie_abp
+Push PCI express attention button
+ETEXI
+
+    {
         .name       = "host_net_add",
         .args_type  = "device:s,opts:s?",
         .params     = "tap|user|socket|vde|dump [options]",
diff --git a/sysemu.h b/sysemu.h
index 9c988bb..cca411d 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -150,6 +150,10 @@  extern unsigned int nb_prom_envs;
 void pci_device_hot_add(Monitor *mon, const QDict *qdict);
 void drive_hot_add(Monitor *mon, const QDict *qdict);
 void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
+/* pcie hotplug */
+void pcie_attention_button_push_print(Monitor *mon, const QObject *data);
+int pcie_attention_button_push(Monitor *mon, const QDict *qdict,
+                               QObject **ret_data);
 
 /* serial ports */