Skip to contentSkip to conversation

of/irq: fix bug in computing output requester-id for an msi-map

PATCH In review Stuart Yoder 2 participants 2 messages Feb 8, 2016 Device tree

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 of/irq: fix bug in computing output requester-id for an msi-map

From: Stuart Yoder <[email protected]>

The binding for msi-map specifies that the output requester id should be computed as: (r - rid-base + msi-base)

...update the code accordingly.

---
 drivers/of/irq.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/of/irq.c +3 -1
index 706e3ff..3f5e5fd 100644
@@ -589,6 +589,7 @@ static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
 	struct device_node *msi_controller_node;
 	struct device_node *msi_np = *np;
 	u32 map_mask, masked_rid, rid_base, msi_base, rid_len, phandle;
+	u32 masked_rid_base;
 	int msi_map_len;
 	bool matched;
 	u32 rid_out = rid_in;
@@ -654,7 +655,8 @@ static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
 	if (!matched)
 		return rid_out;
 
-	rid_out = masked_rid + msi_base;
+	masked_rid_base = map_mask & rid_base;
+	rid_out = msi_base + (masked_rid - masked_rid_base);
 	dev_dbg(dev,
 		"msi-map at: %s, using mask %08x, rid-base: %08x, msi-base: %08x, length: %08x, rid: %08x -> %08x\n",
 		dev_name(parent_dev), map_mask, rid_base, msi_base,
Signature · 1 line
1.7.9.5
Acked-by on v1 1/1
#1 lore raw
Quoted 6 lines · Stuart Yoder

From: Stuart Yoder <[email protected]>

The binding for msi-map specifies that the output requester id should be computed as: (r - rid-base + msi-base)

...update the code accordingly.

I agree there is a problem however ...

Quoted 19 lines
---
  drivers/of/irq.c |    4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)
drivers/of/irq.c +1 -0
index 706e3ff..3f5e5fd 100644
@@ -589,6 +589,7 @@ static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
  	struct device_node *msi_controller_node;
  	struct device_node *msi_np = *np;
  	u32 map_mask, masked_rid, rid_base, msi_base, rid_len, phandle;
+	u32 masked_rid_base;
  	int msi_map_len;
  	bool matched;
  	u32 rid_out = rid_in;

drivers/of/irq.c static u32 __of_msi_map_rid(struct device *dev, struct device_node **np, · line 658

Quoted 5 lines
drivers/of/irq.c +1 -1
@@ -654,7 +655,8 @@ static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
  	if (!matched)
  		return rid_out;
 
-	rid_out = masked_rid + msi_base;
+	masked_rid_base = map_mask & rid_base;

... The binding document nowhere, that I see, talks about applying the mask to the rid-base.

The device tree should already contain the rid-base in the correct range.

If you remove this masking step, I think it may be correct.

If you just do:

drivers/of/irq.c +1 -1
index 7ee21ae..92abe01 100644
@@ -654,7 +654,7 @@ static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
        if (!matched)
                return rid_out;
 
-       rid_out = masked_rid + msi_base;
+       rid_out = msi_base + (masked_rid - rid_base);
        dev_dbg(dev,
                "msi-map at: %s, using mask %08x, rid-base: %08x, 

msi-base: %08x, length: %08x, rid: %08x -> %08x\n",

It think it will be correct.

I have tested it that way. If you do that,

Quoted 5 lines
drivers/of/irq.c +1 -0
+	rid_out = msi_base + (masked_rid - masked_rid_base);
  	dev_dbg(dev,
  		"msi-map at: %s, using mask %08x, rid-base: %08x, msi-base: %08x, length: %08x, rid: %08x -> %08x\n",
  		dev_name(parent_dev), map_mask, rid_base, msi_base,