7 static struct BusInfo scsi_bus_info
= {
9 .size
= sizeof(SCSIBus
),
10 .props
= (Property
[]) {
11 DEFINE_PROP_UINT32("scsi-id", SCSIDevice
, id
, -1),
12 DEFINE_PROP_END_OF_LIST(),
15 static int next_scsi_bus
;
17 /* Create a scsi bus, and attach devices to it. */
18 void scsi_bus_new(SCSIBus
*bus
, DeviceState
*host
, int tcq
, int ndev
,
19 scsi_completionfn complete
)
21 qbus_create_inplace(&bus
->qbus
, &scsi_bus_info
, host
, NULL
);
22 bus
->busnr
= next_scsi_bus
++;
25 bus
->complete
= complete
;
26 bus
->qbus
.allow_hotplug
= 1;
29 static int scsi_qdev_init(DeviceState
*qdev
, DeviceInfo
*base
)
31 SCSIDevice
*dev
= DO_UPCAST(SCSIDevice
, qdev
, qdev
);
32 SCSIDeviceInfo
*info
= DO_UPCAST(SCSIDeviceInfo
, qdev
, base
);
33 SCSIBus
*bus
= DO_UPCAST(SCSIBus
, qbus
, dev
->qdev
.parent_bus
);
37 for (dev
->id
= 0; dev
->id
< bus
->ndev
; dev
->id
++) {
38 if (bus
->devs
[dev
->id
] == NULL
)
42 if (dev
->id
>= bus
->ndev
) {
43 qemu_error("bad scsi device id: %d\n", dev
->id
);
47 if (bus
->devs
[dev
->id
]) {
48 qdev_free(&bus
->devs
[dev
->id
]->qdev
);
50 bus
->devs
[dev
->id
] = dev
;
53 rc
= dev
->info
->init(dev
);
55 bus
->devs
[dev
->id
] = NULL
;
62 static int scsi_qdev_exit(DeviceState
*qdev
)
64 SCSIDevice
*dev
= DO_UPCAST(SCSIDevice
, qdev
, qdev
);
65 SCSIBus
*bus
= DO_UPCAST(SCSIBus
, qbus
, dev
->qdev
.parent_bus
);
67 assert(bus
->devs
[dev
->id
] != NULL
);
68 if (bus
->devs
[dev
->id
]->info
->destroy
) {
69 bus
->devs
[dev
->id
]->info
->destroy(bus
->devs
[dev
->id
]);
71 bus
->devs
[dev
->id
] = NULL
;
75 void scsi_qdev_register(SCSIDeviceInfo
*info
)
77 info
->qdev
.bus_info
= &scsi_bus_info
;
78 info
->qdev
.init
= scsi_qdev_init
;
79 info
->qdev
.unplug
= qdev_simple_unplug_cb
;
80 info
->qdev
.exit
= scsi_qdev_exit
;
81 qdev_register(&info
->qdev
);
84 /* handle legacy '-drive if=scsi,...' cmd line args */
85 /* FIXME callers should check for failure, but don't */
86 SCSIDevice
*scsi_bus_legacy_add_drive(SCSIBus
*bus
, DriveInfo
*dinfo
, int unit
)
91 driver
= bdrv_is_sg(dinfo
->bdrv
) ? "scsi-generic" : "scsi-disk";
92 dev
= qdev_create(&bus
->qbus
, driver
);
93 qdev_prop_set_uint32(dev
, "scsi-id", unit
);
94 qdev_prop_set_drive(dev
, "drive", dinfo
);
95 if (qdev_init(dev
) < 0)
97 return DO_UPCAST(SCSIDevice
, qdev
, dev
);
100 void scsi_bus_legacy_handle_cmdline(SCSIBus
*bus
)
105 for (unit
= 0; unit
< MAX_SCSI_DEVS
; unit
++) {
106 dinfo
= drive_get(IF_SCSI
, bus
->busnr
, unit
);
110 scsi_bus_legacy_add_drive(bus
, dinfo
, unit
);