|
|
1.1 root 1: /*
2: * ide bus support for qdev.
3: *
4: * Copyright (c) 2009 Gerd Hoffmann <[email protected]>
5: *
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.
10: *
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.
15: *
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/>.
18: */
19: #include <hw/hw.h>
20: #include "dma.h"
1.1.1.3 ! root 21: #include "qemu-error.h"
1.1 root 22: #include <hw/ide/internal.h>
23:
24: /* --------------------------------- */
25:
26: static struct BusInfo ide_bus_info = {
27: .name = "IDE",
28: .size = sizeof(IDEBus),
29: };
30:
31: void ide_bus_new(IDEBus *idebus, DeviceState *dev)
32: {
33: qbus_create_inplace(&idebus->qbus, &ide_bus_info, dev, NULL);
34: }
35:
36: static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
37: {
38: IDEDevice *dev = DO_UPCAST(IDEDevice, qdev, qdev);
39: IDEDeviceInfo *info = DO_UPCAST(IDEDeviceInfo, qdev, base);
40: IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus);
41:
1.1.1.3 ! root 42: if (!dev->conf.bs) {
! 43: error_report("No drive specified");
1.1 root 44: goto err;
45: }
46: if (dev->unit == -1) {
47: dev->unit = bus->master ? 1 : 0;
48: }
49: switch (dev->unit) {
50: case 0:
51: if (bus->master) {
1.1.1.3 ! root 52: error_report("IDE unit %d is in use", dev->unit);
1.1 root 53: goto err;
54: }
55: bus->master = dev;
56: break;
57: case 1:
58: if (bus->slave) {
1.1.1.3 ! root 59: error_report("IDE unit %d is in use", dev->unit);
1.1 root 60: goto err;
61: }
62: bus->slave = dev;
63: break;
64: default:
1.1.1.3 ! root 65: error_report("Invalid IDE unit %d", dev->unit);
1.1 root 66: goto err;
67: }
68: return info->init(dev);
69:
70: err:
71: return -1;
72: }
73:
74: static void ide_qdev_register(IDEDeviceInfo *info)
75: {
76: info->qdev.init = ide_qdev_init;
77: info->qdev.bus_info = &ide_bus_info;
78: qdev_register(&info->qdev);
79: }
80:
81: IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive)
82: {
83: DeviceState *dev;
84:
85: dev = qdev_create(&bus->qbus, "ide-drive");
86: qdev_prop_set_uint32(dev, "unit", unit);
1.1.1.3 ! root 87: qdev_prop_set_drive_nofail(dev, "drive", drive->bdrv);
! 88: qdev_init_nofail(dev);
1.1 root 89: return DO_UPCAST(IDEDevice, qdev, dev);
90: }
91:
1.1.1.3 ! root 92: void ide_get_bs(BlockDriverState *bs[], BusState *qbus)
! 93: {
! 94: IDEBus *bus = DO_UPCAST(IDEBus, qbus, qbus);
! 95: bs[0] = bus->master ? bus->master->conf.bs : NULL;
! 96: bs[1] = bus->slave ? bus->slave->conf.bs : NULL;
! 97: }
! 98:
1.1 root 99: /* --------------------------------- */
100:
101: typedef struct IDEDrive {
102: IDEDevice dev;
103: } IDEDrive;
104:
105: static int ide_drive_initfn(IDEDevice *dev)
106: {
107: IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
1.1.1.3 ! root 108: IDEState *s = bus->ifs + dev->unit;
! 109: const char *serial;
! 110: DriveInfo *dinfo;
! 111:
! 112: serial = dev->serial;
! 113: if (!serial) {
! 114: /* try to fall back to value set with legacy -drive serial=... */
! 115: dinfo = drive_get_by_blockdev(dev->conf.bs);
! 116: if (*dinfo->serial) {
! 117: serial = dinfo->serial;
! 118: }
! 119: }
! 120:
! 121: if (ide_init_drive(s, dev->conf.bs, dev->version, serial) < 0) {
! 122: return -1;
! 123: }
! 124:
! 125: if (!dev->version) {
! 126: dev->version = qemu_strdup(s->version);
! 127: }
! 128: if (!dev->serial) {
! 129: dev->serial = qemu_strdup(s->drive_serial_str);
! 130: }
1.1 root 131: return 0;
132: }
133:
134: static IDEDeviceInfo ide_drive_info = {
135: .qdev.name = "ide-drive",
136: .qdev.size = sizeof(IDEDrive),
137: .init = ide_drive_initfn,
138: .qdev.props = (Property[]) {
139: DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1),
1.1.1.3 ! root 140: DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),
1.1.1.2 root 141: DEFINE_PROP_STRING("ver", IDEDrive, dev.version),
1.1.1.3 ! root 142: DEFINE_PROP_STRING("serial", IDEDrive, dev.serial),
1.1 root 143: DEFINE_PROP_END_OF_LIST(),
144: }
145: };
146:
147: static void ide_drive_register(void)
148: {
149: ide_qdev_register(&ide_drive_info);
150: }
151: device_init(ide_drive_register);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.