Gleb Natapov <g...@redhat.com> writes: > On Mon, Oct 25, 2010 at 06:22:12PM +0200, Markus Armbruster wrote: >> Gleb Natapov <g...@redhat.com> writes: >> >> > On Mon, Oct 25, 2010 at 04:29:35PM +0200, Markus Armbruster wrote: >> >> Gleb Natapov <g...@redhat.com> writes: >> >> >> >> > Without this patch both buses on PIIX3_IDE device have the same unit id. >> >> >> >> Are you sure that's wrong? >> >> >> > So how do I know which bus is it on PIIX3_IDE? >> [...] >> >> Let me try to explain the IDE pointer thicket. >> >> piix3-ide provides two IDE buses. pci_piix_ide_initfn() stores them in >> PCIIDEState member IDEBus bus[2]. Technically redundant, because qdev >> stores child buses in dev.qdev.child_bus. >> >> IDEBus points back: qbus.parent. >> >> Up to two IDE devices can sit on each IDE bus. The first one uses >> IDEBus members master and ifs[0], the second one uses slave and ifs[1]. >> >> ifs[i].bus points back to the IDE bus. >> >> {master,slave}.qdev.parent_bus point back to the IDE bus. >> >> Say you got an IDEDevice and want to know which to which of the two >> buses it's connected. Let's call it d. >> >> d->qdev.parent_bus is the BusState. >> >> Upcast to IDEBus: b = DO_UPCAST(IDEBus, qbus, d->qdev.parent_bus). >> >> b->qbus.parent is the IDE controller. >> >> Upcast to PCIIDEState: c = DO_UPCAST(PCIIDEState, dev, n->qbus.parent); >> > This will not work if IDEBus sits on ISA bus. Any other ideas? > >> If c->bus[0] == b, it's on the first bus. >> >> Else it must be on the second bus, i.e. c->bus[1] == b.
Well, you asked for piix3-ide specifically :) isa-ide provides just one IDE bus. Thus we have two isa-ide devices. To find them, you need to walk the ISA devices. Our PCish machines have just one ISA bus, and it's called "isa.0". You could try bus = qbus_find("isa.0"); QLIST_FOREACH(dev, &bus->children, sibling) { // examine dev // it's safe to upcast dev to ISADevice } Perhaps best to have some means in qdev.h to iterate over a bus like that. If dev->info->name is "isa-ide", you found one of the controllers. How to tell whether it's primary or secondary? Primary uses I/O ports 0x1f0..0x1ff,0x3f0..0x3ff and IRQ 14. IRQ could be easier to check, because it should be right in ISADevice member isairq[0]. Alternatively, upcast to ISAIDEState and check members iobase or isairq. Hmm, there's a way that doesn't require special-casing the IDE controller devices: find the IDEBus as above. Then check the IRQ# b->irq->n: 14 is primary, 15 is secondary.