diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2009-09-25 21:42:36 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-10-05 09:32:48 -0500 |
commit | 01985dcf38a94d0db35f54315ba2454e68f16175 (patch) | |
tree | 83a90b7164f8a7b6a60a3dfe45845970416795a9 | |
parent | d29275f10382844e000ddaafaddc6780555e8d83 (diff) |
Implement scsi device destruction
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r-- | hw/scsi-bus.c | 24 | ||||
-rw-r--r-- | hw/scsi-disk.c | 6 | ||||
-rw-r--r-- | hw/scsi-generic.c | 2 |
3 files changed, 21 insertions, 11 deletions
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 881e36320a..27defc4109 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -30,6 +30,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base); SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus); + int rc = -1; if (dev->id == -1) { for (dev->id = 0; dev->id < bus->ndev; dev->id++) { @@ -43,21 +44,38 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) } if (bus->devs[dev->id]) { - bus->devs[dev->id]->info->destroy(bus->devs[dev->id]); + qdev_free(&bus->devs[dev->id]->qdev); } bus->devs[dev->id] = dev; dev->info = info; - return dev->info->init(dev); + rc = dev->info->init(dev); + if (rc != 0) { + bus->devs[dev->id] = NULL; + } err: - return -1; + return rc; +} + +static int scsi_qdev_exit(DeviceState *qdev) +{ + SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); + SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus); + + assert(bus->devs[dev->id] != NULL); + if (bus->devs[dev->id]->info->destroy) { + bus->devs[dev->id]->info->destroy(bus->devs[dev->id]); + } + bus->devs[dev->id] = NULL; + return 0; } void scsi_qdev_register(SCSIDeviceInfo *info) { info->qdev.bus_info = &scsi_bus_info; info->qdev.init = scsi_qdev_init; + info->qdev.exit = scsi_qdev_exit; qdev_register(&info->qdev); } diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index de8e314b15..0f029f897d 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -936,11 +936,6 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, } } -static void scsi_destroy(SCSIDevice *d) -{ - qemu_free(d); -} - static int scsi_disk_initfn(SCSIDevice *dev) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); @@ -974,7 +969,6 @@ static SCSIDeviceInfo scsi_disk_info = { .qdev.desc = "virtual scsi disk or cdrom", .qdev.size = sizeof(SCSIDiskState), .init = scsi_disk_initfn, - .destroy = scsi_destroy, .send_command = scsi_send_command, .read_data = scsi_read_data, .write_data = scsi_write_data, diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index f8c010b639..86d1e54a5f 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -668,8 +668,6 @@ static void scsi_destroy(SCSIDevice *d) qemu_free(r); r = n; } - - qemu_free(d); } static int scsi_generic_initfn(SCSIDevice *dev) |