Diff for /qemu/hw/qdev.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2018/04/24 18:28:31 version 1.1.1.4, 2018/04/24 18:37:51
Line 31 Line 31
 #include "monitor.h"  #include "monitor.h"
   
 static int qdev_hotplug = 0;  static int qdev_hotplug = 0;
   static bool qdev_hot_added = false;
   static bool qdev_hot_removed = false;
   
 /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */  /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
 static BusState *main_system_bus;  static BusState *main_system_bus;
Line 92  static DeviceState *qdev_create_from_inf Line 94  static DeviceState *qdev_create_from_inf
     if (qdev_hotplug) {      if (qdev_hotplug) {
         assert(bus->allow_hotplug);          assert(bus->allow_hotplug);
         dev->hotplugged = 1;          dev->hotplugged = 1;
           qdev_hot_added = true;
     }      }
     dev->instance_id_alias = -1;      dev->instance_id_alias = -1;
     dev->state = DEV_STATE_CREATED;      dev->state = DEV_STATE_CREATED;
Line 106  DeviceState *qdev_create(BusState *bus,  Line 109  DeviceState *qdev_create(BusState *bus, 
     DeviceInfo *info;      DeviceInfo *info;
   
     if (!bus) {      if (!bus) {
         if (!main_system_bus) {          bus = sysbus_get_default();
             main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");  
         }  
         bus = main_system_bus;  
     }      }
   
     info = qdev_find_info(bus->info, name);      info = qdev_find_info(bus->info, name);
Line 256  DeviceState *qdev_device_add(QemuOpts *o Line 256  DeviceState *qdev_device_add(QemuOpts *o
     return qdev;      return qdev;
 }  }
   
 static void qdev_reset(void *opaque)  
 {  
     DeviceState *dev = opaque;  
     if (dev->info->reset)  
         dev->info->reset(dev);  
 }  
   
 /* Initialize a device.  Device properties should be set before calling  /* Initialize a device.  Device properties should be set before calling
    this function.  IRQs and MMIO regions should be connected/mapped after     this function.  IRQs and MMIO regions should be connected/mapped after
    calling this function.     calling this function.
Line 278  int qdev_init(DeviceState *dev) Line 271  int qdev_init(DeviceState *dev)
         qdev_free(dev);          qdev_free(dev);
         return rc;          return rc;
     }      }
     qemu_register_reset(qdev_reset, dev);  
     if (dev->info->vmsd) {      if (dev->info->vmsd) {
         vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,          vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
                                        dev->instance_id_alias,                                         dev->instance_id_alias,
Line 304  int qdev_unplug(DeviceState *dev) Line 296  int qdev_unplug(DeviceState *dev)
     }      }
     assert(dev->info->unplug != NULL);      assert(dev->info->unplug != NULL);
   
       qdev_hot_removed = true;
   
     return dev->info->unplug(dev);      return dev->info->unplug(dev);
 }  }
   
   static int qdev_reset_one(DeviceState *dev, void *opaque)
   {
       if (dev->info->reset) {
           dev->info->reset(dev);
       }
   
       return 0;
   }
   
   BusState *sysbus_get_default(void)
   {
       if (!main_system_bus) {
           main_system_bus = qbus_create(&system_bus_info, NULL,
                                         "main-system-bus");
       }
       return main_system_bus;
   }
   
   static int qbus_reset_one(BusState *bus, void *opaque)
   {
       if (bus->info->reset) {
           return bus->info->reset(bus);
       }
       return 0;
   }
   
   void qdev_reset_all(DeviceState *dev)
   {
       qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
   }
   
   void qbus_reset_all_fn(void *opaque)
   {
       BusState *bus = opaque;
       qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
   }
   
 /* can be used as ->unplug() callback for the simple cases */  /* can be used as ->unplug() callback for the simple cases */
 int qdev_simple_unplug_cb(DeviceState *dev)  int qdev_simple_unplug_cb(DeviceState *dev)
 {  {
Line 350  void qdev_free(DeviceState *dev) Line 381  void qdev_free(DeviceState *dev)
         if (dev->opts)          if (dev->opts)
             qemu_opts_del(dev->opts);              qemu_opts_del(dev->opts);
     }      }
     qemu_unregister_reset(qdev_reset, dev);  
     QLIST_REMOVE(dev, sibling);      QLIST_REMOVE(dev, sibling);
     for (prop = dev->info->props; prop && prop->name; prop++) {      for (prop = dev->info->props; prop && prop->name; prop++) {
         if (prop->info->free) {          if (prop->info->free) {
Line 369  void qdev_machine_creation_done(void) Line 399  void qdev_machine_creation_done(void)
     qdev_hotplug = 1;      qdev_hotplug = 1;
 }  }
   
   bool qdev_machine_modified(void)
   {
       return qdev_hot_added || qdev_hot_removed;
   }
   
 /* Get a character (serial) device interface.  */  /* Get a character (serial) device interface.  */
 CharDriverState *qdev_init_chardev(DeviceState *dev)  CharDriverState *qdev_init_chardev(DeviceState *dev)
 {  {
Line 422  void qdev_set_nic_properties(DeviceState Line 457  void qdev_set_nic_properties(DeviceState
     }      }
 }  }
   
 static int next_block_unit[IF_COUNT];  BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
   {
       BusState *bus;
   
 /* Get a block device.  This should only be used for single-drive devices      QLIST_FOREACH(bus, &dev->child_bus, sibling) {
    (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the          if (strcmp(name, bus->name) == 0) {
    appropriate bus.  */              return bus;
 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)          }
       }
       return NULL;
   }
   
   int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
                          qbus_walkerfn *busfn, void *opaque)
 {  {
     int unit = next_block_unit[type]++;      DeviceState *dev;
     DriveInfo *dinfo;      int err;
   
     dinfo = drive_get(type, 0, unit);      if (busfn) {
     return dinfo ? dinfo->bdrv : NULL;          err = busfn(bus, opaque);
           if (err) {
               return err;
           }
       }
   
       QLIST_FOREACH(dev, &bus->children, sibling) {
           err = qdev_walk_children(dev, devfn, busfn, opaque);
           if (err < 0) {
               return err;
           }
       }
   
       return 0;
 }  }
   
 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)  int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
                          qbus_walkerfn *busfn, void *opaque)
 {  {
     BusState *bus;      BusState *bus;
       int err;
   
       if (devfn) {
           err = devfn(dev, opaque);
           if (err) {
               return err;
           }
       }
   
     QLIST_FOREACH(bus, &dev->child_bus, sibling) {      QLIST_FOREACH(bus, &dev->child_bus, sibling) {
         if (strcmp(name, bus->name) == 0) {          err = qbus_walk_children(bus, devfn, busfn, opaque);
             return bus;          if (err < 0) {
               return err;
         }          }
     }      }
     return NULL;  
       return 0;
 }  }
   
 static BusState *qbus_find_recursive(BusState *bus, const char *name,  static BusState *qbus_find_recursive(BusState *bus, const char *name,
Line 476  static BusState *qbus_find_recursive(Bus Line 543  static BusState *qbus_find_recursive(Bus
     return NULL;      return NULL;
 }  }
   
 static DeviceState *qdev_find_recursive(BusState *bus, const char *id)  DeviceState *qdev_find_recursive(BusState *bus, const char *id)
 {  {
     DeviceState *dev, *ret;      DeviceState *dev, *ret;
     BusState *child;      BusState *child;
Line 683  void qbus_create_inplace(BusState *bus,  Line 750  void qbus_create_inplace(BusState *bus, 
     if (parent) {      if (parent) {
         QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);          QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
         parent->num_child_bus++;          parent->num_child_bus++;
       } else if (bus != main_system_bus) {
           /* TODO: once all bus devices are qdevified,
              only reset handler for main_system_bus should be registered here. */
           qemu_register_reset(qbus_reset_all_fn, bus);
     }      }
   
 }  }
   
 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)  BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
Line 707  void qbus_free(BusState *bus) Line 777  void qbus_free(BusState *bus)
     if (bus->parent) {      if (bus->parent) {
         QLIST_REMOVE(bus, sibling);          QLIST_REMOVE(bus, sibling);
         bus->parent->num_child_bus--;          bus->parent->num_child_bus--;
       } else {
           assert(bus != main_system_bus); /* main_system_bus is never freed */
           qemu_unregister_reset(qbus_reset_all_fn, bus);
     }      }
     qemu_free((void*)bus->name);      qemu_free((void*)bus->name);
     if (bus->qdev_allocated) {      if (bus->qdev_allocated) {
Line 792  int do_device_add(Monitor *mon, const QD Line 865  int do_device_add(Monitor *mon, const QD
 {  {
     QemuOpts *opts;      QemuOpts *opts;
   
     opts = qemu_opts_from_qdict(&qemu_device_opts, qdict);      opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
     if (!opts) {      if (!opts) {
         return -1;          return -1;
     }      }
Line 819  int do_device_del(Monitor *mon, const QD Line 892  int do_device_del(Monitor *mon, const QD
     }      }
     return qdev_unplug(dev);      return qdev_unplug(dev);
 }  }
   
   static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
   {
       int l = 0;
   
       if (dev && dev->parent_bus) {
           char *d;
           l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
           if (dev->parent_bus->info->get_fw_dev_path) {
               d = dev->parent_bus->info->get_fw_dev_path(dev);
               l += snprintf(p + l, size - l, "%s", d);
               qemu_free(d);
           } else {
               l += snprintf(p + l, size - l, "%s", dev->info->name);
           }
       }
       l += snprintf(p + l , size - l, "/");
   
       return l;
   }
   
   char* qdev_get_fw_dev_path(DeviceState *dev)
   {
       char path[128];
       int l;
   
       l = qdev_get_fw_dev_path_helper(dev, path, 128);
   
       path[l-1] = '\0';
   
       return strdup(path);
   }

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


unix.superglobalmegacorp.com