On Fri, Apr 14, 2023 at 11:54:11AM -0700, Dan Williams wrote: > Do not assume that a single-target port falls back to a passthrough > decoder configuration. Scan for decoders and only fallback after probing > that the HDM decoder capability is not present. > > One user visible affect of this bug is the inability to enumerate > present CXL regions as the decoder settings for the present decoders are > skipped. > > Fixes: d17d0540a0db ("cxl/core/hdm: Add CXL standard decoder enumeration to the core") > Reported-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> > Link: http://lore.kernel.org/r/20230227153128.8164-1-Jonathan.Cameron@xxxxxxxxxx > Cc: <stable@xxxxxxxxxxxxxxx> > Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx> Reviewed-by: Alison Schofield <alison.schofield@xxxxxxxxx> > --- > drivers/cxl/core/hdm.c | 5 +++-- > drivers/cxl/port.c | 18 +++++++++++++----- > 2 files changed, 16 insertions(+), 7 deletions(-) > > diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c > index 6fdf7981ddc7..abe3877cfa63 100644 > --- a/drivers/cxl/core/hdm.c > +++ b/drivers/cxl/core/hdm.c > @@ -92,8 +92,9 @@ static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb, > > cxl_probe_component_regs(&port->dev, crb, &map.component_map); > if (!map.component_map.hdm_decoder.valid) { > - dev_err(&port->dev, "HDM decoder registers invalid\n"); > - return -ENXIO; > + dev_dbg(&port->dev, "HDM decoder registers not implemented\n"); > + /* unique error code to indicate no HDM decoder capability */ > + return -ENODEV; > } > > return cxl_map_component_regs(&port->dev, regs, &map, > diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c > index 22a7ab2bae7c..eb57324c4ad4 100644 > --- a/drivers/cxl/port.c > +++ b/drivers/cxl/port.c > @@ -66,14 +66,22 @@ static int cxl_switch_port_probe(struct cxl_port *port) > if (rc < 0) > return rc; > > - if (rc == 1) > - return devm_cxl_add_passthrough_decoder(port); > - > cxlhdm = devm_cxl_setup_hdm(port, NULL); > - if (IS_ERR(cxlhdm)) > + if (!IS_ERR(cxlhdm)) > + return devm_cxl_enumerate_decoders(cxlhdm, NULL); > + > + if (PTR_ERR(cxlhdm) != -ENODEV) { > + dev_err(&port->dev, "Failed to map HDM decoder capability\n"); > return PTR_ERR(cxlhdm); > + } > + > + if (rc == 1) { > + dev_dbg(&port->dev, "Fallback to passthrough decoder\n"); > + return devm_cxl_add_passthrough_decoder(port); > + } > > - return devm_cxl_enumerate_decoders(cxlhdm, NULL); > + dev_err(&port->dev, "HDM decoder capability not found\n"); > + return -ENXIO; > } > > static int cxl_endpoint_port_probe(struct cxl_port *port) >