mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
cxl fixes for v613-rc4
- prevent probe failure when non-critical ras unmasking fails - fix CXL 1.1 link status sysfs attribute - fix 4 way (and greater) switch interleave region creation -----BEGIN PGP SIGNATURE----- iIoEABYKADIWIQSgX9xt+GwmrJEQ+euebuN7TNx1MQUCZ2LhJBQcaXJhLndlaW55 QGludGVsLmNvbQAKCRCebuN7TNx1MdG1AQC1DbZsr4+GAM19rrhOVX5PfO0Pf4uX 2BlkOnADFabTwAD9Eq3/Y/+5OqSRClcsNXVq8e4DFqDbS0uKA/srnQaiew4= =c8xR -----END PGP SIGNATURE----- Merge tag 'cxl-fixes-6.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl Pull cxl fixes from Ira Weiny: - prevent probe failure when non-critical RAS unmasking fails - fix CXL 1.1 link status sysfs attribute - fix 4 way (and greater) switch interleave region creation * tag 'cxl-fixes-6.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl: cxl/region: Fix region creation for greater than x2 switches cxl/pci: Check dport->regs.rcd_pcie_cap availability before accessing cxl/pci: Fix potential bogus return value upon successful probing
This commit is contained in:
commit
b69810f38c
@ -1295,6 +1295,7 @@ static int cxl_port_setup_targets(struct cxl_port *port,
|
||||
struct cxl_region_params *p = &cxlr->params;
|
||||
struct cxl_decoder *cxld = cxl_rr->decoder;
|
||||
struct cxl_switch_decoder *cxlsd;
|
||||
struct cxl_port *iter = port;
|
||||
u16 eig, peig;
|
||||
u8 eiw, peiw;
|
||||
|
||||
@ -1311,16 +1312,26 @@ static int cxl_port_setup_targets(struct cxl_port *port,
|
||||
|
||||
cxlsd = to_cxl_switch_decoder(&cxld->dev);
|
||||
if (cxl_rr->nr_targets_set) {
|
||||
int i, distance;
|
||||
int i, distance = 1;
|
||||
struct cxl_region_ref *cxl_rr_iter;
|
||||
|
||||
/*
|
||||
* Passthrough decoders impose no distance requirements between
|
||||
* peers
|
||||
* The "distance" between peer downstream ports represents which
|
||||
* endpoint positions in the region interleave a given port can
|
||||
* host.
|
||||
*
|
||||
* For example, at the root of a hierarchy the distance is
|
||||
* always 1 as every index targets a different host-bridge. At
|
||||
* each subsequent switch level those ports map every Nth region
|
||||
* position where N is the width of the switch == distance.
|
||||
*/
|
||||
if (cxl_rr->nr_targets == 1)
|
||||
distance = 0;
|
||||
else
|
||||
distance = p->nr_targets / cxl_rr->nr_targets;
|
||||
do {
|
||||
cxl_rr_iter = cxl_rr_load(iter, cxlr);
|
||||
distance *= cxl_rr_iter->nr_targets;
|
||||
iter = to_cxl_port(iter->dev.parent);
|
||||
} while (!is_cxl_root(iter));
|
||||
distance *= cxlrd->cxlsd.cxld.interleave_ways;
|
||||
|
||||
for (i = 0; i < cxl_rr->nr_targets_set; i++)
|
||||
if (ep->dport == cxlsd->target[i]) {
|
||||
rc = check_last_peer(cxled, ep, cxl_rr,
|
||||
|
@ -836,6 +836,9 @@ static ssize_t rcd_pcie_cap_emit(struct device *dev, u16 offset, char *buf, size
|
||||
if (!root_dev)
|
||||
return -ENXIO;
|
||||
|
||||
if (!dport->regs.rcd_pcie_cap)
|
||||
return -ENXIO;
|
||||
|
||||
guard(device)(root_dev);
|
||||
if (!root_dev->driver)
|
||||
return -ENXIO;
|
||||
@ -1032,8 +1035,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = cxl_pci_ras_unmask(pdev);
|
||||
if (rc)
|
||||
if (cxl_pci_ras_unmask(pdev))
|
||||
dev_dbg(&pdev->dev, "No RAS reporting unmasked\n");
|
||||
|
||||
pci_save_state(pdev);
|
||||
|
Loading…
Reference in New Issue
Block a user