Statistics
| Branch: | Revision:

root / hw / ide / cmd646.c @ c9159fe9

History | View | Annotate | Download (10.2 kB)

1 4c3df0ec Juan Quintela
/*
2 4c3df0ec Juan Quintela
 * QEMU IDE Emulation: PCI cmd646 support.
3 4c3df0ec Juan Quintela
 *
4 4c3df0ec Juan Quintela
 * Copyright (c) 2003 Fabrice Bellard
5 4c3df0ec Juan Quintela
 * Copyright (c) 2006 Openedhand Ltd.
6 4c3df0ec Juan Quintela
 *
7 4c3df0ec Juan Quintela
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 4c3df0ec Juan Quintela
 * of this software and associated documentation files (the "Software"), to deal
9 4c3df0ec Juan Quintela
 * in the Software without restriction, including without limitation the rights
10 4c3df0ec Juan Quintela
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 4c3df0ec Juan Quintela
 * copies of the Software, and to permit persons to whom the Software is
12 4c3df0ec Juan Quintela
 * furnished to do so, subject to the following conditions:
13 4c3df0ec Juan Quintela
 *
14 4c3df0ec Juan Quintela
 * The above copyright notice and this permission notice shall be included in
15 4c3df0ec Juan Quintela
 * all copies or substantial portions of the Software.
16 4c3df0ec Juan Quintela
 *
17 4c3df0ec Juan Quintela
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 4c3df0ec Juan Quintela
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 4c3df0ec Juan Quintela
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 4c3df0ec Juan Quintela
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 4c3df0ec Juan Quintela
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 4c3df0ec Juan Quintela
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 4c3df0ec Juan Quintela
 * THE SOFTWARE.
24 4c3df0ec Juan Quintela
 */
25 4c3df0ec Juan Quintela
#include <hw/hw.h>
26 4c3df0ec Juan Quintela
#include <hw/pc.h>
27 4c3df0ec Juan Quintela
#include <hw/pci.h>
28 4c3df0ec Juan Quintela
#include <hw/isa.h>
29 4c3df0ec Juan Quintela
#include "block.h"
30 4c3df0ec Juan Quintela
#include "sysemu.h"
31 4c3df0ec Juan Quintela
#include "dma.h"
32 4c3df0ec Juan Quintela
33 4c3df0ec Juan Quintela
#include <hw/ide/pci.h>
34 4c3df0ec Juan Quintela
35 4c3df0ec Juan Quintela
/* CMD646 specific */
36 4c3df0ec Juan Quintela
#define MRDMODE                0x71
37 4c3df0ec Juan Quintela
#define   MRDMODE_INTR_CH0        0x04
38 4c3df0ec Juan Quintela
#define   MRDMODE_INTR_CH1        0x08
39 4c3df0ec Juan Quintela
#define   MRDMODE_BLK_CH0        0x10
40 4c3df0ec Juan Quintela
#define   MRDMODE_BLK_CH1        0x20
41 4c3df0ec Juan Quintela
#define UDIDETCR0        0x73
42 4c3df0ec Juan Quintela
#define UDIDETCR1        0x7B
43 4c3df0ec Juan Quintela
44 4c3df0ec Juan Quintela
static void cmd646_update_irq(PCIIDEState *d);
45 4c3df0ec Juan Quintela
46 a9deb8c6 Avi Kivity
static uint64_t cmd646_cmd_read(void *opaque, target_phys_addr_t addr,
47 a9deb8c6 Avi Kivity
                                unsigned size)
48 4c3df0ec Juan Quintela
{
49 a9deb8c6 Avi Kivity
    CMD646BAR *cmd646bar = opaque;
50 a9deb8c6 Avi Kivity
51 a9deb8c6 Avi Kivity
    if (addr != 2 || size != 1) {
52 a9deb8c6 Avi Kivity
        return ((uint64_t)1 << (size * 8)) - 1;
53 a9deb8c6 Avi Kivity
    }
54 a9deb8c6 Avi Kivity
    return ide_status_read(cmd646bar->bus, addr + 2);
55 a9deb8c6 Avi Kivity
}
56 a9deb8c6 Avi Kivity
57 a9deb8c6 Avi Kivity
static void cmd646_cmd_write(void *opaque, target_phys_addr_t addr,
58 a9deb8c6 Avi Kivity
                             uint64_t data, unsigned size)
59 a9deb8c6 Avi Kivity
{
60 a9deb8c6 Avi Kivity
    CMD646BAR *cmd646bar = opaque;
61 a9deb8c6 Avi Kivity
62 a9deb8c6 Avi Kivity
    if (addr != 2 || size != 1) {
63 a9deb8c6 Avi Kivity
        return;
64 a9deb8c6 Avi Kivity
    }
65 a9deb8c6 Avi Kivity
    ide_cmd_write(cmd646bar->bus, addr + 2, data);
66 a9deb8c6 Avi Kivity
}
67 a9deb8c6 Avi Kivity
68 a348f108 Stefan Weil
static const MemoryRegionOps cmd646_cmd_ops = {
69 a9deb8c6 Avi Kivity
    .read = cmd646_cmd_read,
70 a9deb8c6 Avi Kivity
    .write = cmd646_cmd_write,
71 a9deb8c6 Avi Kivity
    .endianness = DEVICE_LITTLE_ENDIAN,
72 a9deb8c6 Avi Kivity
};
73 a9deb8c6 Avi Kivity
74 a9deb8c6 Avi Kivity
static uint64_t cmd646_data_read(void *opaque, target_phys_addr_t addr,
75 a9deb8c6 Avi Kivity
                                 unsigned size)
76 a9deb8c6 Avi Kivity
{
77 a9deb8c6 Avi Kivity
    CMD646BAR *cmd646bar = opaque;
78 a9deb8c6 Avi Kivity
79 a9deb8c6 Avi Kivity
    if (size == 1) {
80 a9deb8c6 Avi Kivity
        return ide_ioport_read(cmd646bar->bus, addr);
81 a9deb8c6 Avi Kivity
    } else if (addr == 0) {
82 a9deb8c6 Avi Kivity
        if (size == 2) {
83 a9deb8c6 Avi Kivity
            return ide_data_readw(cmd646bar->bus, addr);
84 4c3df0ec Juan Quintela
        } else {
85 a9deb8c6 Avi Kivity
            return ide_data_readl(cmd646bar->bus, addr);
86 4c3df0ec Juan Quintela
        }
87 4c3df0ec Juan Quintela
    }
88 a9deb8c6 Avi Kivity
    return ((uint64_t)1 << (size * 8)) - 1;
89 4c3df0ec Juan Quintela
}
90 4c3df0ec Juan Quintela
91 a9deb8c6 Avi Kivity
static void cmd646_data_write(void *opaque, target_phys_addr_t addr,
92 a9deb8c6 Avi Kivity
                             uint64_t data, unsigned size)
93 61f58e59 Juan Quintela
{
94 a9deb8c6 Avi Kivity
    CMD646BAR *cmd646bar = opaque;
95 a9deb8c6 Avi Kivity
96 a9deb8c6 Avi Kivity
    if (size == 1) {
97 0ed8b6f6 Blue Swirl
        ide_ioport_write(cmd646bar->bus, addr, data);
98 a9deb8c6 Avi Kivity
    } else if (addr == 0) {
99 a9deb8c6 Avi Kivity
        if (size == 2) {
100 0ed8b6f6 Blue Swirl
            ide_data_writew(cmd646bar->bus, addr, data);
101 a9deb8c6 Avi Kivity
        } else {
102 0ed8b6f6 Blue Swirl
            ide_data_writel(cmd646bar->bus, addr, data);
103 a9deb8c6 Avi Kivity
        }
104 a9deb8c6 Avi Kivity
    }
105 a9deb8c6 Avi Kivity
}
106 a9deb8c6 Avi Kivity
107 a348f108 Stefan Weil
static const MemoryRegionOps cmd646_data_ops = {
108 a9deb8c6 Avi Kivity
    .read = cmd646_data_read,
109 a9deb8c6 Avi Kivity
    .write = cmd646_data_write,
110 a9deb8c6 Avi Kivity
    .endianness = DEVICE_LITTLE_ENDIAN,
111 a9deb8c6 Avi Kivity
};
112 a9deb8c6 Avi Kivity
113 a9deb8c6 Avi Kivity
static void setup_cmd646_bar(PCIIDEState *d, int bus_num)
114 a9deb8c6 Avi Kivity
{
115 a9deb8c6 Avi Kivity
    IDEBus *bus = &d->bus[bus_num];
116 a9deb8c6 Avi Kivity
    CMD646BAR *bar = &d->cmd646_bar[bus_num];
117 a9deb8c6 Avi Kivity
118 a9deb8c6 Avi Kivity
    bar->bus = bus;
119 a9deb8c6 Avi Kivity
    bar->pci_dev = d;
120 a9deb8c6 Avi Kivity
    memory_region_init_io(&bar->cmd, &cmd646_cmd_ops, bar, "cmd646-cmd", 4);
121 a9deb8c6 Avi Kivity
    memory_region_init_io(&bar->data, &cmd646_data_ops, bar, "cmd646-data", 8);
122 a9deb8c6 Avi Kivity
}
123 a9deb8c6 Avi Kivity
124 a9deb8c6 Avi Kivity
static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr,
125 a9deb8c6 Avi Kivity
                           unsigned size)
126 a9deb8c6 Avi Kivity
{
127 a9deb8c6 Avi Kivity
    BMDMAState *bm = opaque;
128 a9deb8c6 Avi Kivity
    PCIIDEState *pci_dev = bm->pci_dev;
129 4c3df0ec Juan Quintela
    uint32_t val;
130 4c3df0ec Juan Quintela
131 a9deb8c6 Avi Kivity
    if (size != 1) {
132 a9deb8c6 Avi Kivity
        return ((uint64_t)1 << (size * 8)) - 1;
133 a9deb8c6 Avi Kivity
    }
134 a9deb8c6 Avi Kivity
135 4c3df0ec Juan Quintela
    switch(addr & 3) {
136 4c3df0ec Juan Quintela
    case 0:
137 4c3df0ec Juan Quintela
        val = bm->cmd;
138 4c3df0ec Juan Quintela
        break;
139 4c3df0ec Juan Quintela
    case 1:
140 58c0e732 Juan Quintela
        val = pci_dev->dev.config[MRDMODE];
141 4c3df0ec Juan Quintela
        break;
142 4c3df0ec Juan Quintela
    case 2:
143 4c3df0ec Juan Quintela
        val = bm->status;
144 4c3df0ec Juan Quintela
        break;
145 4c3df0ec Juan Quintela
    case 3:
146 70ae65f5 Igor V. Kovalenko
        if (bm == &pci_dev->bmdma[0]) {
147 58c0e732 Juan Quintela
            val = pci_dev->dev.config[UDIDETCR0];
148 4c3df0ec Juan Quintela
        } else {
149 58c0e732 Juan Quintela
            val = pci_dev->dev.config[UDIDETCR1];
150 4c3df0ec Juan Quintela
        }
151 4c3df0ec Juan Quintela
        break;
152 4c3df0ec Juan Quintela
    default:
153 4c3df0ec Juan Quintela
        val = 0xff;
154 4c3df0ec Juan Quintela
        break;
155 4c3df0ec Juan Quintela
    }
156 4c3df0ec Juan Quintela
#ifdef DEBUG_IDE
157 08406b03 malc
    printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
158 4c3df0ec Juan Quintela
#endif
159 4c3df0ec Juan Quintela
    return val;
160 4c3df0ec Juan Quintela
}
161 4c3df0ec Juan Quintela
162 a9deb8c6 Avi Kivity
static void bmdma_write(void *opaque, target_phys_addr_t addr,
163 a9deb8c6 Avi Kivity
                        uint64_t val, unsigned size)
164 70ae65f5 Igor V. Kovalenko
{
165 a9deb8c6 Avi Kivity
    BMDMAState *bm = opaque;
166 a9deb8c6 Avi Kivity
    PCIIDEState *pci_dev = bm->pci_dev;
167 70ae65f5 Igor V. Kovalenko
168 a9deb8c6 Avi Kivity
    if (size != 1) {
169 a9deb8c6 Avi Kivity
        return;
170 a9deb8c6 Avi Kivity
    }
171 70ae65f5 Igor V. Kovalenko
172 4c3df0ec Juan Quintela
#ifdef DEBUG_IDE
173 08406b03 malc
    printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
174 4c3df0ec Juan Quintela
#endif
175 4c3df0ec Juan Quintela
    switch(addr & 3) {
176 50a48094 Igor V. Kovalenko
    case 0:
177 a9deb8c6 Avi Kivity
        bmdma_cmd_writeb(bm, val);
178 50a48094 Igor V. Kovalenko
        break;
179 4c3df0ec Juan Quintela
    case 1:
180 58c0e732 Juan Quintela
        pci_dev->dev.config[MRDMODE] =
181 58c0e732 Juan Quintela
            (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30);
182 58c0e732 Juan Quintela
        cmd646_update_irq(pci_dev);
183 4c3df0ec Juan Quintela
        break;
184 4c3df0ec Juan Quintela
    case 2:
185 4c3df0ec Juan Quintela
        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
186 4c3df0ec Juan Quintela
        break;
187 4c3df0ec Juan Quintela
    case 3:
188 70ae65f5 Igor V. Kovalenko
        if (bm == &pci_dev->bmdma[0])
189 58c0e732 Juan Quintela
            pci_dev->dev.config[UDIDETCR0] = val;
190 58c0e732 Juan Quintela
        else
191 58c0e732 Juan Quintela
            pci_dev->dev.config[UDIDETCR1] = val;
192 4c3df0ec Juan Quintela
        break;
193 4c3df0ec Juan Quintela
    }
194 4c3df0ec Juan Quintela
}
195 4c3df0ec Juan Quintela
196 a348f108 Stefan Weil
static const MemoryRegionOps cmd646_bmdma_ops = {
197 a9deb8c6 Avi Kivity
    .read = bmdma_read,
198 a9deb8c6 Avi Kivity
    .write = bmdma_write,
199 a9deb8c6 Avi Kivity
};
200 70ae65f5 Igor V. Kovalenko
201 a9deb8c6 Avi Kivity
static void bmdma_setup_bar(PCIIDEState *d)
202 4c3df0ec Juan Quintela
{
203 a9deb8c6 Avi Kivity
    BMDMAState *bm;
204 4c3df0ec Juan Quintela
    int i;
205 4c3df0ec Juan Quintela
206 a9deb8c6 Avi Kivity
    memory_region_init(&d->bmdma_bar, "cmd646-bmdma", 16);
207 4c3df0ec Juan Quintela
    for(i = 0;i < 2; i++) {
208 a9deb8c6 Avi Kivity
        bm = &d->bmdma[i];
209 a9deb8c6 Avi Kivity
        memory_region_init_io(&bm->extra_io, &cmd646_bmdma_ops, bm,
210 a9deb8c6 Avi Kivity
                              "cmd646-bmdma-bus", 4);
211 a9deb8c6 Avi Kivity
        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
212 a9deb8c6 Avi Kivity
        memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm,
213 a9deb8c6 Avi Kivity
                              "cmd646-bmdma-ioport", 4);
214 a9deb8c6 Avi Kivity
        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
215 4c3df0ec Juan Quintela
    }
216 4c3df0ec Juan Quintela
}
217 4c3df0ec Juan Quintela
218 4c3df0ec Juan Quintela
/* XXX: call it also when the MRDMODE is changed from the PCI config
219 4c3df0ec Juan Quintela
   registers */
220 4c3df0ec Juan Quintela
static void cmd646_update_irq(PCIIDEState *d)
221 4c3df0ec Juan Quintela
{
222 4c3df0ec Juan Quintela
    int pci_level;
223 4c3df0ec Juan Quintela
    pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) &&
224 4c3df0ec Juan Quintela
                 !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) ||
225 4c3df0ec Juan Quintela
        ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) &&
226 4c3df0ec Juan Quintela
         !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1));
227 4c3df0ec Juan Quintela
    qemu_set_irq(d->dev.irq[0], pci_level);
228 4c3df0ec Juan Quintela
}
229 4c3df0ec Juan Quintela
230 4c3df0ec Juan Quintela
/* the PCI irq level is the logical OR of the two channels */
231 4c3df0ec Juan Quintela
static void cmd646_set_irq(void *opaque, int channel, int level)
232 4c3df0ec Juan Quintela
{
233 4c3df0ec Juan Quintela
    PCIIDEState *d = opaque;
234 4c3df0ec Juan Quintela
    int irq_mask;
235 4c3df0ec Juan Quintela
236 4c3df0ec Juan Quintela
    irq_mask = MRDMODE_INTR_CH0 << channel;
237 4c3df0ec Juan Quintela
    if (level)
238 4c3df0ec Juan Quintela
        d->dev.config[MRDMODE] |= irq_mask;
239 4c3df0ec Juan Quintela
    else
240 4c3df0ec Juan Quintela
        d->dev.config[MRDMODE] &= ~irq_mask;
241 4c3df0ec Juan Quintela
    cmd646_update_irq(d);
242 4c3df0ec Juan Quintela
}
243 4c3df0ec Juan Quintela
244 4c3df0ec Juan Quintela
static void cmd646_reset(void *opaque)
245 4c3df0ec Juan Quintela
{
246 4c3df0ec Juan Quintela
    PCIIDEState *d = opaque;
247 4c3df0ec Juan Quintela
    unsigned int i;
248 4c3df0ec Juan Quintela
249 4a643563 Blue Swirl
    for (i = 0; i < 2; i++) {
250 4a643563 Blue Swirl
        ide_bus_reset(&d->bus[i]);
251 4a643563 Blue Swirl
    }
252 4c3df0ec Juan Quintela
}
253 4c3df0ec Juan Quintela
254 4c3df0ec Juan Quintela
/* CMD646 PCI IDE controller */
255 4c3df0ec Juan Quintela
static int pci_cmd646_ide_initfn(PCIDevice *dev)
256 4c3df0ec Juan Quintela
{
257 4c3df0ec Juan Quintela
    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
258 4c3df0ec Juan Quintela
    uint8_t *pci_conf = d->dev.config;
259 4c3df0ec Juan Quintela
    qemu_irq *irq;
260 61d9d6b0 Stefan Hajnoczi
    int i;
261 4c3df0ec Juan Quintela
262 409570a7 Michael S. Tsirkin
    pci_conf[PCI_CLASS_PROG] = 0x8f;
263 4c3df0ec Juan Quintela
264 4c3df0ec Juan Quintela
    pci_conf[0x51] = 0x04; // enable IDE0
265 4c3df0ec Juan Quintela
    if (d->secondary) {
266 4c3df0ec Juan Quintela
        /* XXX: if not enabled, really disable the seconday IDE controller */
267 4c3df0ec Juan Quintela
        pci_conf[0x51] |= 0x08; /* enable IDE1 */
268 4c3df0ec Juan Quintela
    }
269 4c3df0ec Juan Quintela
270 a9deb8c6 Avi Kivity
    setup_cmd646_bar(d, 0);
271 a9deb8c6 Avi Kivity
    setup_cmd646_bar(d, 1);
272 e824b2cc Avi Kivity
    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].data);
273 e824b2cc Avi Kivity
    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].cmd);
274 e824b2cc Avi Kivity
    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].data);
275 e824b2cc Avi Kivity
    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].cmd);
276 a9deb8c6 Avi Kivity
    bmdma_setup_bar(d);
277 e824b2cc Avi Kivity
    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
278 4c3df0ec Juan Quintela
279 409570a7 Michael S. Tsirkin
    /* TODO: RST# value should be 0 */
280 409570a7 Michael S. Tsirkin
    pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
281 4c3df0ec Juan Quintela
282 4c3df0ec Juan Quintela
    irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
283 61d9d6b0 Stefan Hajnoczi
    for (i = 0; i < 2; i++) {
284 61d9d6b0 Stefan Hajnoczi
        ide_bus_new(&d->bus[i], &d->dev.qdev, i);
285 61d9d6b0 Stefan Hajnoczi
        ide_init2(&d->bus[i], irq[i]);
286 61d9d6b0 Stefan Hajnoczi
287 a9deb8c6 Avi Kivity
        bmdma_init(&d->bus[i], &d->bmdma[i], d);
288 f56b18c0 Kevin Wolf
        d->bmdma[i].bus = &d->bus[i];
289 61d9d6b0 Stefan Hajnoczi
        qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
290 f56b18c0 Kevin Wolf
                                         &d->bmdma[i].dma);
291 61d9d6b0 Stefan Hajnoczi
    }
292 4c3df0ec Juan Quintela
293 0be71e32 Alex Williamson
    vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d);
294 4c3df0ec Juan Quintela
    qemu_register_reset(cmd646_reset, d);
295 4c3df0ec Juan Quintela
    return 0;
296 4c3df0ec Juan Quintela
}
297 4c3df0ec Juan Quintela
298 f90c2bcd Alex Williamson
static void pci_cmd646_ide_exitfn(PCIDevice *dev)
299 a9deb8c6 Avi Kivity
{
300 a9deb8c6 Avi Kivity
    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
301 a9deb8c6 Avi Kivity
    unsigned i;
302 a9deb8c6 Avi Kivity
303 a9deb8c6 Avi Kivity
    for (i = 0; i < 2; ++i) {
304 a9deb8c6 Avi Kivity
        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
305 a9deb8c6 Avi Kivity
        memory_region_destroy(&d->bmdma[i].extra_io);
306 a9deb8c6 Avi Kivity
        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
307 a9deb8c6 Avi Kivity
        memory_region_destroy(&d->bmdma[i].addr_ioport);
308 a9deb8c6 Avi Kivity
        memory_region_destroy(&d->cmd646_bar[i].cmd);
309 a9deb8c6 Avi Kivity
        memory_region_destroy(&d->cmd646_bar[i].data);
310 a9deb8c6 Avi Kivity
    }
311 a9deb8c6 Avi Kivity
    memory_region_destroy(&d->bmdma_bar);
312 a9deb8c6 Avi Kivity
}
313 a9deb8c6 Avi Kivity
314 4c3df0ec Juan Quintela
void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
315 4c3df0ec Juan Quintela
                         int secondary_ide_enabled)
316 4c3df0ec Juan Quintela
{
317 4c3df0ec Juan Quintela
    PCIDevice *dev;
318 4c3df0ec Juan Quintela
319 556cd098 Markus Armbruster
    dev = pci_create(bus, -1, "cmd646-ide");
320 4c3df0ec Juan Quintela
    qdev_prop_set_uint32(&dev->qdev, "secondary", secondary_ide_enabled);
321 4c3df0ec Juan Quintela
    qdev_init_nofail(&dev->qdev);
322 4c3df0ec Juan Quintela
323 4c3df0ec Juan Quintela
    pci_ide_create_devs(dev, hd_table);
324 4c3df0ec Juan Quintela
}
325 4c3df0ec Juan Quintela
326 40021f08 Anthony Liguori
static Property cmd646_ide_properties[] = {
327 40021f08 Anthony Liguori
    DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
328 40021f08 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
329 40021f08 Anthony Liguori
};
330 40021f08 Anthony Liguori
331 40021f08 Anthony Liguori
static void cmd646_ide_class_init(ObjectClass *klass, void *data)
332 40021f08 Anthony Liguori
{
333 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
334 40021f08 Anthony Liguori
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
335 40021f08 Anthony Liguori
336 40021f08 Anthony Liguori
    k->init = pci_cmd646_ide_initfn;
337 40021f08 Anthony Liguori
    k->exit = pci_cmd646_ide_exitfn;
338 40021f08 Anthony Liguori
    k->vendor_id = PCI_VENDOR_ID_CMD;
339 40021f08 Anthony Liguori
    k->device_id = PCI_DEVICE_ID_CMD_646;
340 40021f08 Anthony Liguori
    k->revision = 0x07;
341 40021f08 Anthony Liguori
    k->class_id = PCI_CLASS_STORAGE_IDE;
342 39bffca2 Anthony Liguori
    dc->props = cmd646_ide_properties;
343 40021f08 Anthony Liguori
}
344 40021f08 Anthony Liguori
345 39bffca2 Anthony Liguori
static TypeInfo cmd646_ide_info = {
346 39bffca2 Anthony Liguori
    .name          = "cmd646-ide",
347 39bffca2 Anthony Liguori
    .parent        = TYPE_PCI_DEVICE,
348 39bffca2 Anthony Liguori
    .instance_size = sizeof(PCIIDEState),
349 39bffca2 Anthony Liguori
    .class_init    = cmd646_ide_class_init,
350 4c3df0ec Juan Quintela
};
351 4c3df0ec Juan Quintela
352 83f7d43a Andreas Färber
static void cmd646_ide_register_types(void)
353 4c3df0ec Juan Quintela
{
354 39bffca2 Anthony Liguori
    type_register_static(&cmd646_ide_info);
355 4c3df0ec Juan Quintela
}
356 83f7d43a Andreas Färber
357 83f7d43a Andreas Färber
type_init(cmd646_ide_register_types)