cxled->pos = cxl_calc_interleave_pos(cxled, &cxlr->hpa_range);
/*
* Record that sorting failed, but still continue to calc
- * cxled->pos so that follow-on code paths can reliably
- * do p->targets[cxled->pos] to self-reference their entry.
+ * cxled->pos so that cxl_calc_interleave_pos() emits its
+ * dev_dbg() for every member. which is useful for auto
+ * discovery debug.
*/
if (cxled->pos < 0)
rc = -ENXIO;
return 0;
}
-static int cxl_region_by_target(struct device *dev, const void *data)
+static int cxl_region_remove_target(struct device *dev, void *data)
{
- const struct cxl_endpoint_decoder *cxled = data;
+ struct cxl_endpoint_decoder *cxled = data;
struct cxl_region_params *p;
struct cxl_region *cxlr;
+ int i;
if (!is_cxl_region(dev))
return 0;
cxlr = to_cxl_region(dev);
p = &cxlr->params;
- return p->targets[cxled->pos] == cxled;
+ for (i = 0; i < p->interleave_ways; i++) {
+ if (p->targets[i] == cxled) {
+ p->nr_targets--;
+ cxled->state = CXL_DECODER_STATE_AUTO;
+ cxled->pos = -1;
+ p->targets[i] = NULL;
+
+ return 1;
+ }
+ }
+
+ return 0;
}
/*
*/
static void cxl_cancel_auto_attach(struct cxl_endpoint_decoder *cxled)
{
- struct cxl_region_params *p;
- struct cxl_region *cxlr;
- int pos = cxled->pos;
-
if (cxled->state != CXL_DECODER_STATE_AUTO_STAGED)
return;
- struct device *dev __free(put_device) =
- bus_find_device(&cxl_bus_type, NULL, cxled, cxl_region_by_target);
- if (!dev)
- return;
-
- cxlr = to_cxl_region(dev);
- p = &cxlr->params;
-
- p->nr_targets--;
- cxled->state = CXL_DECODER_STATE_AUTO;
- cxled->pos = -1;
- p->targets[pos] = NULL;
+ bus_for_each_dev(&cxl_bus_type, NULL, cxled, cxl_region_remove_target);
}
static struct cxl_region *