summary refs log tree commit diff stats
path: root/hw/scsi-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/scsi-bus.c')
-rw-r--r--hw/scsi-bus.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 2cf2f0d8cf..2cb5a18da2 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -132,6 +132,10 @@ static int scsi_qdev_init(DeviceState *qdev)
         error_report("bad scsi device id: %d", dev->id);
         goto err;
     }
+    if (dev->lun != -1 && dev->lun > bus->info->max_lun) {
+        error_report("bad scsi device lun: %d", dev->lun);
+        goto err;
+    }
 
     if (dev->id == -1) {
         int id = -1;
@@ -140,8 +144,8 @@ static int scsi_qdev_init(DeviceState *qdev)
         }
         do {
             d = scsi_device_find(bus, dev->channel, ++id, dev->lun);
-        } while (d && d->lun == dev->lun && id <= bus->info->max_target);
-        if (id > bus->info->max_target) {
+        } while (d && d->lun == dev->lun && id < bus->info->max_target);
+        if (d && d->lun == dev->lun) {
             error_report("no free target");
             goto err;
         }
@@ -151,14 +155,15 @@ static int scsi_qdev_init(DeviceState *qdev)
         do {
             d = scsi_device_find(bus, dev->channel, dev->id, ++lun);
         } while (d && d->lun == lun && lun < bus->info->max_lun);
-        if (lun > bus->info->max_lun) {
+        if (d && d->lun == lun) {
             error_report("no free lun");
             goto err;
         }
         dev->lun = lun;
     } else {
         d = scsi_device_find(bus, dev->channel, dev->id, dev->lun);
-        if (dev->lun == d->lun && dev != d) {
+        assert(d);
+        if (d->lun == dev->lun && dev != d) {
             qdev_free(&d->qdev);
         }
     }
@@ -217,7 +222,7 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
     int res = 0, unit;
 
     loc_push_none(&loc);
-    for (unit = 0; unit < bus->info->max_target; unit++) {
+    for (unit = 0; unit <= bus->info->max_target; unit++) {
         dinfo = drive_get(IF_SCSI, bus->busnr, unit);
         if (dinfo == NULL) {
             continue;