[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 3/3] xen: arm: handle PCI DT node ranges and interrupt-map properties
On Mon, 2015-03-16 at 16:14 +0000, Julien Grall wrote: > Hi Ian, > > On 12/03/15 17:17, Ian Campbell wrote: > > These properties are defined in ePAPR (2.3.8 and 2.4.3.1 respectively) > > and the OpenFirmware PCI Bus Binding Specification (IEEE Std 1275-1994). > > > > This replaces the xgene specific mapping. Tested on Mustang and on a > > model with a PCI virtio controller. > > > > TODO: Use a helper iterator (e.g. dt_for_each_range) for the ranges > > property, like is already done for interrupts using > > dt_for_each_irq_map. > > > > TODO: Should we stop calling map_device for nodes beneath this one > > (since we should have mapped everything underneath)? I think this is > > complex for cases which map interrupt but not ranges or vice versa, > > perhaps meaning we need to recurse on them separately. Maybe we can > > continue to descend and the mappings may just be harmlessly > > instantiated twice. > > There is not harm to route twice the same IRQ. Although it's pointless > to continue. > > How difficult would it be to introduce a new bus? It's a couple of reasonably trivial hook functions (which one would naturally just get from Linux) and a struct tying a name to those. Not too hard. > > + if ( dt_device_type_is_equal(dev, "pci") ) > > + return map_pci_device_ranges(d, dev, ranges, len); > > + > > + printk("Cannot handle ranges for non-PCI device %s type %s\n", > > + dt_node_name(dev), dev->type); > > + > > Is the printk really necessary? It will a spurious log on platform where > ranges is not empty (midway, arndale, foundation model...). If the ranges is present and non-empty it's not impossible that we need to be doing something with it. I'd rather try and figure out how to whitelist such nodes, perhaps they lack a dev_type completely? > In general, we should not handle ranges by default as we may overlap the > mapping done during the domain creation (such as the GIC). > > > + /* Lets not worry for now... */ > > + return 0; > > +} > > + > > +static int map_interrupt_to_domain(const struct dt_device_node *dev, > > + const struct dt_raw_irq *dt_raw_irq, > > + void *data) > > +{ > > + struct domain *d = data; > > + struct dt_irq dt_irq; > > + int res; > > + > > + res = dt_irq_translate(dt_raw_irq, &dt_irq); > > + if ( res < 0 ) > > + { > > + printk(XENLOG_ERR "%s: Failed to translate IRQ: %d\n", > > + dt_node_name(dev), res); > > + return res; > > + } > > + > > + if ( dt_irq.irq < NR_LOCAL_IRQS ) > > + { > > + printk(XENLOG_ERR "%s: IRQ%"PRId32" is not a SPI\n", > > + dt_node_name(dev), dt_irq.irq); > > + return -EINVAL; > > + } > > + > > + /* Setup the IRQ type */ > > + res = irq_set_spi_type(dt_irq.irq, dt_irq.type); > > + if ( res ) > > + { > > + printk(XENLOG_ERR > > + "%s: Unable to setup IRQ%"PRId32" to dom%d\n", > > + dt_node_name(dev), dt_irq.irq, d->domain_id); > > + return res; > > + } > > + > > + res = route_irq_to_guest(d, dt_irq.irq, dt_node_name(dev)); > > + if ( res < 0 ) > > + { > > + printk(XENLOG_ERR "Unable to map IRQ%"PRId32" to dom%d\n", > > + dt_irq.irq, d->domain_id); > > + return res; > > + } > > + > > + DPRINT("PCI IRQ %u mapped to guest", dt_irq.irq); > > + > > + return 0; > > +} > > + > > +static int map_device_interrupts(struct domain *d, const struct > > dt_device_node *dev) > > +{ > > + > > + if ( !dt_property_read_bool(dev, "interrupt-map") ) > > It's strange to use dt_property_read_bool here and dt_get_property above > to check the emptiness. > > I prefer the dt_get_property version which is less confusing. > > Anyway, why do you need to check interrupt-map. Can't your new helper > deal with empty property? It can, but the code below would log for any non-pci device, which is undesirable if there is no interrupt-map present. > > > + return 0; /* No interrupt map to handle */ > > + > > + if ( dt_device_type_is_equal(dev, "pci") ) > > + return dt_for_each_irq_map(dev, &map_interrupt_to_domain, d); > > + > > + printk("Cannot handle interrupt-map for non-PCI device %s type %s\n", > > + dt_node_name(dev), dev->type); > > + > > + /* Lets not worry for now... */ > > + return 0; > > +} > > + > > + > > /* Map the device in the domain */ > > static int map_device(struct domain *d, struct dt_device_node *dev) > > { > > @@ -1025,6 +1173,14 @@ static int map_device(struct domain *d, struct > > dt_device_node *dev) > > } > > } > > > > + res = map_device_ranges(d, dev); > > + if ( res ) > > + return res; > > + > > + res = map_device_interrupts(d, dev); > > The name of the function doesn't make much sense. We already map the > interrupt above (see platform get_irq). child_interrupt perhaps? Ian. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |