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 /hw/scsi-bus.c | |
parent | d29275f10382844e000ddaafaddc6780555e8d83 (diff) |
Implement scsi device destruction
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/scsi-bus.c')
-rw-r--r-- | hw/scsi-bus.c | 24 |
1 files changed, 21 insertions, 3 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); } |