Re: [PATCH] net: sunhme: Fix sbus regression
Sean Anderson <[email protected]>
| Newsgroups | org.kernel.vger.sparclinux,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
On 2/6/26 04:05, René Rebe wrote: > On Thu, 5 Feb 2026 20:41:11 -0500, Sean Anderson <[email protected]> wrote: > >> On 2/5/26 11:09, René Rebe wrote: >>> Commit cc216e4b44ce ("net: sunhme: Switch SBUS to devres") changed >>> explicit sized of_ioremap with BMAC_REG_SIZEs to >>> devm_platform_ioremap_resource mapping all the resource. However, >>> this does not work on my Sun Ultra 2 with SBUS HMEs: >>> hme f0072f38: error -EBUSY: can't request region for resource [mem >>> 0x1ffe8c07000-0x1ffe8c0701f] >>> hme f0072f38: Cannot map TCVR registers. >>> hme f0072f38: probe with driver hme failed with error -16 >>> hme f007ab44: error -EBUSY: can't request region for resource [mem >>> 0x1ff28c07000-0x1ff28c0701f] >>> hme f007ab44: Cannot map TCVR registers. >>> hme f007ab44: probe with driver hme failed with error -16 >>> Turns out the open-firmware resources overlap, at least on this >>> machines and PROM version: >>> hexdump /proc/device-tree/sbus@1f,0/SUNW,hme@2,8c00000/reg: >>> 00 00 00 02 08 c0 00 00 00 00 01 08 >>> 00 00 00 02 08 c0 20 00 00 00 20 00 >>> 00 00 00 02 08 c0 40 00 00 00 20 00 >>> 00 00 00 02 08 c0 60 00 00 00 20 00 >>> 00 00 00 02 08 c0 70 00 00 00 00 20 >>> And the driver previously explicitly mapped way smaller mmio regions: >>> /proc/iomem: >>> 1ff28c00000-1ff28c00107 : HME Global Regs >>> 1ff28c02000-1ff28c02033 : HME TX Regs >>> 1ff28c04000-1ff28c0401f : HME RX Regs >>> 1ff28c06000-1ff28c0635f : HME BIGMAC Regs >>> 1ff28c07000-1ff28c0701f : HME Tranceiver Regs >>> Quirk this specific issue by truncating the previous resource to not >>> overlap into the TCVR registers. >>> Fixes: cc216e4b44ce ("net: sunhme: Switch SBUS to devres") >>> Signed-off-by: René Rebe <[email protected]> >>> --- >>> Tested on Sun Ultra 2 running T2/Linux. >>> Alternatively we could explicitly size all regions, or check overlap >>> in startup code (I also already have a patch for that, too). >> >> What does this look like? > > This only checks for "sorted" overlaps w/ the previous res, but given > they probably usually are and it catches this case, ... > > The downside is, it may break other devices, I only test booted this > on an Ultra 2 and Ultra 30. On the U2 it fixes the hme ethernet, > too. On the U30 it causes an eprom region to be truncated. I probably > should investiage that and test boot on all my SPARC systems before we > consider this. That's why I sent the trivial hme driver hotfix first. > Alternatively we could also overwrite all sbus res in the hme driver > with the previously used known good sizes. I can send a patch for > that, too if you like: I'm not really familiar enough with SPARC to say whether this is reasonable or not. I've added the SPARC maintainers to CC so maybe they can comment. > diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c > index f53092b07b9e..8bd405cbc04f 100644 > --- a/arch/sparc/kernel/of_device_64.c > +++ b/arch/sparc/kernel/of_device_64.c > @@ -412,6 +412,15 @@ static void __init build_device_resources(struct platform_device *op, > r->start = result; > r->end = result + size - 1; > r->flags = flags; > + > + /* check for and correct simple bogusly overlapping resources */ > + if (index > 0 && > + op->resource[index-1].start <= r->end && > + op->resource[index-1].end > r->start) { > + printk(KERN_WARNING "%pOF: prev regs overlap (%x), limiting %x.\n", > + op->dev.of_node, op->resource[index-1].end, r->start - 1); > + op->resource[index-1].end = r->start - 1; > + } > } > r->name = op->dev.of_node->full_name; > } > > >>> --- >>> --- linux-6.18/drivers/net/ethernet/sun/sunhme.c.vanilla 2026-02-05 >>> --- 11:50:33.288906134 +0100 >>> +++ linux-6.18/drivers/net/ethernet/sun/sunhme.c 2026-02-05 >>> 11:55:22.541384377 +0100 >>> @@ -2551,6 +2551,9 @@ >>> goto err_out_clear_quattro; >>> } >>> + /* BIGMAC may have bogus sizes */ >>> + if ((op->resource[3].end - op->resource[3].start) >= BMAC_REG_SIZE) >>> + op->resource[3].end = op->resource[3].start + BMAC_REG_SIZE - 1; >>> hp->bigmacregs = devm_platform_ioremap_resource(op, 3); >>> if (IS_ERR(hp->bigmacregs)) { >>> dev_err(&op->dev, "Cannot map BIGMAC registers.\n"); >>> >> >> Reviewed-by: Sean Anderson <[email protected]> >