@@ -66,10 +66,15 @@ static const VMStateDescription vmstate_ide_isa = {
static int isa_ide_initfn(ISADevice *dev)
{
ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev);
+ int irq = s->isairq;
ide_bus_new(&s->bus, &s->dev.qdev, 0);
ide_init_ioport(&s->bus, s->iobase, s->iobase2);
- isa_init_irq(dev, &s->irq, s->isairq);
+ if (irq >= 0) {
+ isa_init_irq(dev, &s->irq, irq);
+ } else {
+ isa_init_irq_nocheck(dev, &s->irq, -irq);
+ }
isa_init_ioport_range(dev, s->iobase, 8);
isa_init_ioport(dev, s->iobase2);
ide_init2(&s->bus, s->irq);
@@ -79,18 +79,23 @@ qemu_irq isa_reserve_irq(int isairq)
return isabus->irqs[isairq];
}
-void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq)
+void isa_init_irq_nocheck(ISADevice *dev, qemu_irq *p, int isairq)
{
assert(dev->nirqs < ARRAY_SIZE(dev->isairq));
- if (isabus->assigned & (1 << isairq)) {
- hw_error("isa irq %d already assigned", isairq);
- }
isabus->assigned |= (1 << isairq);
dev->isairq[dev->nirqs] = isairq;
*p = isabus->irqs[isairq];
dev->nirqs++;
}
+void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq)
+{
+ if (isabus->assigned & (1 << isairq)) {
+ hw_error("isa irq %d already assigned", isairq);
+ }
+ isa_init_irq_nocheck(dev, p, isairq);
+}
+
static void isa_init_ioport_one(ISADevice *dev, uint16_t ioport)
{
assert(dev->nioports < ARRAY_SIZE(dev->ioports));
@@ -28,6 +28,9 @@ ISABus *isa_bus_new(DeviceState *dev);
void isa_bus_irqs(qemu_irq *irqs);
qemu_irq isa_reserve_irq(int isairq);
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
+/* version of init_irq without check for line sharing - only there for PREP
+ target */
+void isa_init_irq_nocheck(ISADevice *dev, qemu_irq *p, int isairq);
void isa_init_ioport(ISADevice *dev, uint16_t ioport);
void isa_init_ioport_range(ISADevice *dev, uint16_t start, uint16_t length);
void isa_qdev_register(ISADeviceInfo *info);
@@ -75,7 +75,8 @@ qemu_log_mask(CPU_LOG_IOPORT, fmt, ## __VA_ARGS__)
/* Constants for devices init */
static const int ide_iobase[2] = { 0x1f0, 0x170 };
static const int ide_iobase2[2] = { 0x3f6, 0x376 };
-static const int ide_irq[2] = { 13, 13 };
+/* negative numbers mean forced share enable */
+static const int ide_irq[2] = { -13, -13 };
#define NE2000_NB_MAX 6
@@ -690,7 +691,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
}
- for(i = 0; i < 1/*MAX_IDE_BUS*/; i++) {
+ for(i = 0; i < MAX_IDE_BUS; i++) {
isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
hd[2 * i],
hd[2 * i + 1]);
The new ISA infrastructure checks for potential irq sharing bugs on interrupt lines, because usually irq lines on isa can't be shared. The PREP spec however mandates that the irq lines for both IDE ports are shared and according to Aurelien this also used to work just fine. So let's add a way to enable this sharing again, so we don't introduce unnecessary regressions over older versions of Qemu. Signed-off-by: Alexander Graf <agraf@suse.de> CC: Andreas Färber <andreas.faerber@web.de> CC: Aurelien Jarno <aurelien@aurel32.net> CC: Kevin Wolf <kwolf@redhat.com> CC: Gerd Hoffmann <kraxel@redhat.com> --- hw/ide/isa.c | 7 ++++++- hw/isa-bus.c | 13 +++++++++---- hw/isa.h | 3 +++ hw/ppc_prep.c | 5 +++-- 4 files changed, 21 insertions(+), 7 deletions(-)