diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index aa7e870..e863002 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -54,7 +54,7 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
         return NULL;
     }
 
-    opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", NULL);
+    opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", 0);
     if (!opts) {
         monitor_printf(mon, "parsing network options '%s' failed\n",
                        opts_str ? opts_str : "");
diff --git a/hw/qdev.c b/hw/qdev.c
index a028e9c..80a027a 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -767,7 +767,7 @@ void do_device_add(Monitor *mon, const QDict *qdict)
     QemuOpts *opts;
 
     opts = qemu_opts_parse(&qemu_device_opts,
-                           qdict_get_str(qdict, "config"), "driver");
+                           qdict_get_str(qdict, "config"), 1);
     if (opts) {
         if (qdev_device_help(opts) || qdev_device_add(opts) == NULL) {
             qemu_opts_del(opts);
diff --git a/hw/usb-net.c b/hw/usb-net.c
index cfd2f62..56fdd9b 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1478,7 +1478,7 @@ static USBDevice *usb_net_init(const char *cmdline)
     QemuOpts *opts;
     int idx;
 
-    opts = qemu_opts_parse(&qemu_net_opts, cmdline, NULL);
+    opts = qemu_opts_parse(&qemu_net_opts, cmdline, 0);
     if (!opts) {
         return NULL;
     }
diff --git a/net.c b/net.c
index 2479e65..c97787f 100644
--- a/net.c
+++ b/net.c
@@ -1156,7 +1156,7 @@ void net_host_device_add(Monitor *mon, const QDict *qdict)
         return;
     }
 
-    opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", NULL);
+    opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", 0);
     if (!opts) {
         monitor_printf(mon, "parsing network options '%s' failed\n",
                        opts_str ? opts_str : "");
@@ -1361,7 +1361,7 @@ int net_client_parse(QemuOptsList *opts_list, const char *optarg)
     }
 #endif
 
-    if (!qemu_opts_parse(opts_list, optarg, "type")) {
+    if (!qemu_opts_parse(opts_list, optarg, 1)) {
         return -1;
     }
 
diff --git a/qemu-config.c b/qemu-config.c
index acd4db7..72b6279 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -86,6 +86,7 @@ QemuOptsList qemu_drive_opts = {
 
 QemuOptsList qemu_chardev_opts = {
     .name = "chardev",
+    .implied_opt_name = "backend",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
     .desc = {
         {
@@ -152,6 +153,7 @@ QemuOptsList qemu_chardev_opts = {
 
 QemuOptsList qemu_device_opts = {
     .name = "device",
+    .implied_opt_name = "driver",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
     .desc = {
         /*
@@ -165,6 +167,7 @@ QemuOptsList qemu_device_opts = {
 
 QemuOptsList qemu_netdev_opts = {
     .name = "netdev",
+    .implied_opt_name = "type",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_netdev_opts.head),
     .desc = {
         /*
@@ -177,6 +180,7 @@ QemuOptsList qemu_netdev_opts = {
 
 QemuOptsList qemu_net_opts = {
     .name = "net",
+    .implied_opt_name = "type",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_net_opts.head),
     .desc = {
         /*
@@ -227,6 +231,7 @@ QemuOptsList qemu_global_opts = {
 
 QemuOptsList qemu_mon_opts = {
     .name = "mon",
+    .implied_opt_name = "chardev",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head),
     .desc = {
         {
diff --git a/qemu-option.c b/qemu-option.c
index f86aac0..ec2a918 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -754,12 +754,17 @@ int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname
     return 0;
 }
 
-QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname)
+QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
+                          int permit_abbrev)
 {
+    const char *firstname;
     char value[1024], *id = NULL;
     const char *p;
     QemuOpts *opts;
 
+    assert(!permit_abbrev || list->implied_opt_name);
+    firstname = permit_abbrev ? list->implied_opt_name : NULL;
+
     if (strncmp(params, "id=", 3) == 0) {
         get_opt_value(value, sizeof(value), params+3);
         id = qemu_strdup(value);
diff --git a/qemu-option.h b/qemu-option.h
index d735386..58136f3 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -97,6 +97,7 @@ typedef struct QemuOptDesc {
 
 struct QemuOptsList {
     const char *name;
+    const char *implied_opt_name;
     QTAILQ_HEAD(, QemuOpts) head;
     QemuOptDesc desc[];
 };
@@ -118,7 +119,7 @@ const char *qemu_opts_id(QemuOpts *opts);
 void qemu_opts_del(QemuOpts *opts);
 int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc);
 int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname);
-QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname);
+QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, int permit_abbrev);
 QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict);
 QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
 
diff --git a/vl.c b/vl.c
index fa2898d..6f96cde 100644
--- a/vl.c
+++ b/vl.c
@@ -1800,7 +1800,7 @@ QemuOpts *drive_add(const char *file, const char *fmt, ...)
     vsnprintf(optstr, sizeof(optstr), fmt, ap);
     va_end(ap);
 
-    opts = qemu_opts_parse(&qemu_drive_opts, optstr, NULL);
+    opts = qemu_opts_parse(&qemu_drive_opts, optstr, 0);
     if (!opts) {
         fprintf(stderr, "%s: huh? duplicate? (%s)\n",
                 __FUNCTION__, optstr);
@@ -4330,7 +4330,7 @@ static int balloon_parse(const char *arg)
     if (!strncmp(arg, "virtio", 6)) {
         if (arg[6] == ',') {
             /* have params -> parse them */
-            opts = qemu_opts_parse(&qemu_device_opts, arg+7, NULL);
+            opts = qemu_opts_parse(&qemu_device_opts, arg+7, 0);
             if (!opts)
                 return  -1;
         } else {
@@ -5317,7 +5317,7 @@ int main(int argc, char **argv, char **envp)
                 default_monitor = 0;
                 break;
             case QEMU_OPTION_mon:
-                opts = qemu_opts_parse(&qemu_mon_opts, optarg, "chardev");
+                opts = qemu_opts_parse(&qemu_mon_opts, optarg, 1);
                 if (!opts) {
                     fprintf(stderr, "parse error: %s\n", optarg);
                     exit(1);
@@ -5325,7 +5325,7 @@ int main(int argc, char **argv, char **envp)
                 default_monitor = 0;
                 break;
             case QEMU_OPTION_chardev:
-                opts = qemu_opts_parse(&qemu_chardev_opts, optarg, "backend");
+                opts = qemu_opts_parse(&qemu_chardev_opts, optarg, 1);
                 if (!opts) {
                     fprintf(stderr, "parse error: %s\n", optarg);
                     exit(1);
@@ -5419,7 +5419,7 @@ int main(int argc, char **argv, char **envp)
                 add_device_config(DEV_USB, optarg);
                 break;
             case QEMU_OPTION_device:
-                if (!qemu_opts_parse(&qemu_device_opts, optarg, "driver")) {
+                if (!qemu_opts_parse(&qemu_device_opts, optarg, 1)) {
                     exit(1);
                 }
                 break;
@@ -5528,7 +5528,7 @@ int main(int argc, char **argv, char **envp)
                 configure_rtc_date_offset(optarg, 1);
                 break;
             case QEMU_OPTION_rtc:
-                opts = qemu_opts_parse(&qemu_rtc_opts, optarg, NULL);
+                opts = qemu_opts_parse(&qemu_rtc_opts, optarg, 0);
                 if (!opts) {
                     fprintf(stderr, "parse error: %s\n", optarg);
                     exit(1);
