2 * ide bus support for qdev.
4 * Copyright (c) 2009 Gerd Hoffmann <kraxel@redhat.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu-error.h"
22 #include <hw/ide/internal.h>
26 /* --------------------------------- */
28 static char *idebus_get_fw_dev_path(DeviceState
*dev
);
30 static Property ide_props
[] = {
31 DEFINE_PROP_UINT32("unit", IDEDevice
, unit
, -1),
32 DEFINE_PROP_END_OF_LIST(),
35 static void ide_bus_class_init(ObjectClass
*klass
, void *data
)
37 BusClass
*k
= BUS_CLASS(klass
);
39 k
->get_fw_dev_path
= idebus_get_fw_dev_path
;
42 static const TypeInfo ide_bus_info
= {
45 .instance_size
= sizeof(IDEBus
),
46 .class_init
= ide_bus_class_init
,
49 void ide_bus_new(IDEBus
*idebus
, DeviceState
*dev
, int bus_id
)
51 qbus_create_inplace(&idebus
->qbus
, TYPE_IDE_BUS
, dev
, NULL
);
52 idebus
->bus_id
= bus_id
;
55 static char *idebus_get_fw_dev_path(DeviceState
*dev
)
59 snprintf(path
, sizeof(path
), "%s@%d", qdev_fw_name(dev
),
60 ((IDEBus
*)dev
->parent_bus
)->bus_id
);
65 static int ide_qdev_init(DeviceState
*qdev
)
67 IDEDevice
*dev
= IDE_DEVICE(qdev
);
68 IDEDeviceClass
*dc
= IDE_DEVICE_GET_CLASS(dev
);
69 IDEBus
*bus
= DO_UPCAST(IDEBus
, qbus
, qdev
->parent_bus
);
72 error_report("No drive specified");
75 if (dev
->unit
== -1) {
76 dev
->unit
= bus
->master
? 1 : 0;
81 error_report("IDE unit %d is in use", dev
->unit
);
88 error_report("IDE unit %d is in use", dev
->unit
);
94 error_report("Invalid IDE unit %d", dev
->unit
);
103 IDEDevice
*ide_create_drive(IDEBus
*bus
, int unit
, DriveInfo
*drive
)
107 dev
= qdev_create(&bus
->qbus
, drive
->media_cd
? "ide-cd" : "ide-hd");
108 qdev_prop_set_uint32(dev
, "unit", unit
);
109 qdev_prop_set_drive_nofail(dev
, "drive", drive
->bdrv
);
110 qdev_init_nofail(dev
);
111 return DO_UPCAST(IDEDevice
, qdev
, dev
);
114 void ide_get_bs(BlockDriverState
*bs
[], BusState
*qbus
)
116 IDEBus
*bus
= DO_UPCAST(IDEBus
, qbus
, qbus
);
117 bs
[0] = bus
->master
? bus
->master
->conf
.bs
: NULL
;
118 bs
[1] = bus
->slave
? bus
->slave
->conf
.bs
: NULL
;
121 /* --------------------------------- */
123 typedef struct IDEDrive
{
127 static int ide_dev_initfn(IDEDevice
*dev
, IDEDriveKind kind
)
129 IDEBus
*bus
= DO_UPCAST(IDEBus
, qbus
, dev
->qdev
.parent_bus
);
130 IDEState
*s
= bus
->ifs
+ dev
->unit
;
134 if (dev
->conf
.discard_granularity
&& dev
->conf
.discard_granularity
!= 512) {
135 error_report("discard_granularity must be 512 for ide");
139 serial
= dev
->serial
;
141 /* try to fall back to value set with legacy -drive serial=... */
142 dinfo
= drive_get_by_blockdev(dev
->conf
.bs
);
143 if (*dinfo
->serial
) {
144 serial
= dinfo
->serial
;
148 if (ide_init_drive(s
, dev
->conf
.bs
, kind
,
149 dev
->version
, serial
, dev
->model
, dev
->wwn
) < 0) {
154 dev
->version
= g_strdup(s
->version
);
157 dev
->serial
= g_strdup(s
->drive_serial_str
);
160 add_boot_device_path(dev
->conf
.bootindex
, &dev
->qdev
,
161 dev
->unit
? "/disk@1" : "/disk@0");
166 static int ide_hd_initfn(IDEDevice
*dev
)
168 return ide_dev_initfn(dev
, IDE_HD
);
171 static int ide_cd_initfn(IDEDevice
*dev
)
173 return ide_dev_initfn(dev
, IDE_CD
);
176 static int ide_drive_initfn(IDEDevice
*dev
)
178 DriveInfo
*dinfo
= drive_get_by_blockdev(dev
->conf
.bs
);
180 return ide_dev_initfn(dev
, dinfo
->media_cd
? IDE_CD
: IDE_HD
);
183 #define DEFINE_IDE_DEV_PROPERTIES() \
184 DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), \
185 DEFINE_PROP_STRING("ver", IDEDrive, dev.version), \
186 DEFINE_PROP_HEX64("wwn", IDEDrive, dev.wwn, 0), \
187 DEFINE_PROP_STRING("serial", IDEDrive, dev.serial),\
188 DEFINE_PROP_STRING("model", IDEDrive, dev.model)
190 static Property ide_hd_properties
[] = {
191 DEFINE_IDE_DEV_PROPERTIES(),
192 DEFINE_PROP_END_OF_LIST(),
195 static void ide_hd_class_init(ObjectClass
*klass
, void *data
)
197 DeviceClass
*dc
= DEVICE_CLASS(klass
);
198 IDEDeviceClass
*k
= IDE_DEVICE_CLASS(klass
);
199 k
->init
= ide_hd_initfn
;
200 dc
->fw_name
= "drive";
201 dc
->desc
= "virtual IDE disk";
202 dc
->props
= ide_hd_properties
;
205 static TypeInfo ide_hd_info
= {
207 .parent
= TYPE_IDE_DEVICE
,
208 .instance_size
= sizeof(IDEDrive
),
209 .class_init
= ide_hd_class_init
,
212 static Property ide_cd_properties
[] = {
213 DEFINE_IDE_DEV_PROPERTIES(),
214 DEFINE_PROP_END_OF_LIST(),
217 static void ide_cd_class_init(ObjectClass
*klass
, void *data
)
219 DeviceClass
*dc
= DEVICE_CLASS(klass
);
220 IDEDeviceClass
*k
= IDE_DEVICE_CLASS(klass
);
221 k
->init
= ide_cd_initfn
;
222 dc
->fw_name
= "drive";
223 dc
->desc
= "virtual IDE CD-ROM";
224 dc
->props
= ide_cd_properties
;
227 static TypeInfo ide_cd_info
= {
229 .parent
= TYPE_IDE_DEVICE
,
230 .instance_size
= sizeof(IDEDrive
),
231 .class_init
= ide_cd_class_init
,
234 static Property ide_drive_properties
[] = {
235 DEFINE_IDE_DEV_PROPERTIES(),
236 DEFINE_PROP_END_OF_LIST(),
239 static void ide_drive_class_init(ObjectClass
*klass
, void *data
)
241 DeviceClass
*dc
= DEVICE_CLASS(klass
);
242 IDEDeviceClass
*k
= IDE_DEVICE_CLASS(klass
);
243 k
->init
= ide_drive_initfn
;
244 dc
->fw_name
= "drive";
245 dc
->desc
= "virtual IDE disk or CD-ROM (legacy)";
246 dc
->props
= ide_drive_properties
;
249 static TypeInfo ide_drive_info
= {
251 .parent
= TYPE_IDE_DEVICE
,
252 .instance_size
= sizeof(IDEDrive
),
253 .class_init
= ide_drive_class_init
,
256 static void ide_device_class_init(ObjectClass
*klass
, void *data
)
258 DeviceClass
*k
= DEVICE_CLASS(klass
);
259 k
->init
= ide_qdev_init
;
260 k
->bus_type
= TYPE_IDE_BUS
;
261 k
->props
= ide_props
;
264 static TypeInfo ide_device_type_info
= {
265 .name
= TYPE_IDE_DEVICE
,
266 .parent
= TYPE_DEVICE
,
267 .instance_size
= sizeof(IDEDevice
),
269 .class_size
= sizeof(IDEDeviceClass
),
270 .class_init
= ide_device_class_init
,
273 static void ide_register_types(void)
275 type_register_static(&ide_bus_info
);
276 type_register_static(&ide_hd_info
);
277 type_register_static(&ide_cd_info
);
278 type_register_static(&ide_drive_info
);
279 type_register_static(&ide_device_type_info
);
282 type_init(ide_register_types
)