Loading Documentation/PCI/pci-error-recovery.rst +7 −0 Original line number Original line Diff line number Diff line Loading @@ -83,6 +83,7 @@ This structure has the form:: int (*mmio_enabled)(struct pci_dev *dev); int (*mmio_enabled)(struct pci_dev *dev); int (*slot_reset)(struct pci_dev *dev); int (*slot_reset)(struct pci_dev *dev); void (*resume)(struct pci_dev *dev); void (*resume)(struct pci_dev *dev); void (*cor_error_detected)(struct pci_dev *dev); }; }; The possible channel states are:: The possible channel states are:: Loading Loading @@ -422,5 +423,11 @@ That is, the recovery API only requires that: - drivers/net/cxgb3 - drivers/net/cxgb3 - drivers/net/s2io.c - drivers/net/s2io.c The cor_error_detected() callback is invoked in handle_error_source() when the error severity is "correctable". The callback is optional and allows additional logging to be done if desired. See example: - drivers/cxl/pci.c The End The End ------- ------- drivers/cxl/core/hdm.c +19 −14 Original line number Original line Diff line number Diff line Loading @@ -82,18 +82,23 @@ static void parse_hdm_decoder_caps(struct cxl_hdm *cxlhdm) cxlhdm->interleave_mask |= GENMASK(14, 12); cxlhdm->interleave_mask |= GENMASK(14, 12); } } static void __iomem *map_hdm_decoder_regs(struct cxl_port *port, static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb, void __iomem *crb) struct cxl_component_regs *regs) { { struct cxl_component_reg_map map; struct cxl_register_map map = { .resource = port->component_reg_phys, .base = crb, .max_size = CXL_COMPONENT_REG_BLOCK_SIZE, }; cxl_probe_component_regs(&port->dev, crb, &map); cxl_probe_component_regs(&port->dev, crb, &map.component_map); if (!map.hdm_decoder.valid) { if (!map.component_map.hdm_decoder.valid) { dev_err(&port->dev, "HDM decoder registers invalid\n"); dev_err(&port->dev, "HDM decoder registers invalid\n"); return IOMEM_ERR_PTR(-ENXIO); return -ENXIO; } } return crb + map.hdm_decoder.offset; return cxl_map_component_regs(&port->dev, regs, &map, BIT(CXL_CM_CAP_CAP_ID_HDM)); } } /** /** Loading @@ -103,25 +108,25 @@ static void __iomem *map_hdm_decoder_regs(struct cxl_port *port, struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port) struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port) { { struct device *dev = &port->dev; struct device *dev = &port->dev; void __iomem *crb, *hdm; struct cxl_hdm *cxlhdm; struct cxl_hdm *cxlhdm; void __iomem *crb; int rc; cxlhdm = devm_kzalloc(dev, sizeof(*cxlhdm), GFP_KERNEL); cxlhdm = devm_kzalloc(dev, sizeof(*cxlhdm), GFP_KERNEL); if (!cxlhdm) if (!cxlhdm) return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM); cxlhdm->port = port; cxlhdm->port = port; crb = devm_cxl_iomap_block(dev, port->component_reg_phys, crb = ioremap(port->component_reg_phys, CXL_COMPONENT_REG_BLOCK_SIZE); CXL_COMPONENT_REG_BLOCK_SIZE); if (!crb) { if (!crb) { dev_err(dev, "No component registers mapped\n"); dev_err(dev, "No component registers mapped\n"); return ERR_PTR(-ENXIO); return ERR_PTR(-ENXIO); } } hdm = map_hdm_decoder_regs(port, crb); rc = map_hdm_decoder_regs(port, crb, &cxlhdm->regs); if (IS_ERR(hdm)) iounmap(crb); return ERR_CAST(hdm); if (rc) cxlhdm->regs.hdm_decoder = hdm; return ERR_PTR(rc); parse_hdm_decoder_caps(cxlhdm); parse_hdm_decoder_caps(cxlhdm); if (cxlhdm->decoder_count == 0) { if (cxlhdm->decoder_count == 0) { Loading drivers/cxl/core/memdev.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -344,6 +344,7 @@ struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds) * needed as this is ordered with cdev_add() publishing the device. * needed as this is ordered with cdev_add() publishing the device. */ */ cxlmd->cxlds = cxlds; cxlmd->cxlds = cxlds; cxlds->cxlmd = cxlmd; cdev = &cxlmd->cdev; cdev = &cxlmd->cdev; rc = cdev_device_add(cdev, dev); rc = cdev_device_add(cdev, dev); Loading drivers/cxl/core/pci.c +1 −2 Original line number Original line Diff line number Diff line Loading @@ -54,8 +54,7 @@ static int match_add_dports(struct pci_dev *pdev, void *data) dev_dbg(&port->dev, "failed to find component registers\n"); dev_dbg(&port->dev, "failed to find component registers\n"); port_num = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap); port_num = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap); dport = devm_cxl_add_dport(port, &pdev->dev, port_num, dport = devm_cxl_add_dport(port, &pdev->dev, port_num, map.resource); cxl_regmap_to_base(pdev, &map)); if (IS_ERR(dport)) { if (IS_ERR(dport)) { ctx->error = PTR_ERR(dport); ctx->error = PTR_ERR(dport); return PTR_ERR(dport); return PTR_ERR(dport); Loading drivers/cxl/core/port.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -1292,7 +1292,7 @@ static resource_size_t find_component_registers(struct device *dev) pdev = to_pci_dev(dev); pdev = to_pci_dev(dev); cxl_find_regblock(pdev, CXL_REGLOC_RBI_COMPONENT, &map); cxl_find_regblock(pdev, CXL_REGLOC_RBI_COMPONENT, &map); return cxl_regmap_to_base(pdev, &map); return map.resource; } } static int add_port_attach_ep(struct cxl_memdev *cxlmd, static int add_port_attach_ep(struct cxl_memdev *cxlmd, Loading Loading
Documentation/PCI/pci-error-recovery.rst +7 −0 Original line number Original line Diff line number Diff line Loading @@ -83,6 +83,7 @@ This structure has the form:: int (*mmio_enabled)(struct pci_dev *dev); int (*mmio_enabled)(struct pci_dev *dev); int (*slot_reset)(struct pci_dev *dev); int (*slot_reset)(struct pci_dev *dev); void (*resume)(struct pci_dev *dev); void (*resume)(struct pci_dev *dev); void (*cor_error_detected)(struct pci_dev *dev); }; }; The possible channel states are:: The possible channel states are:: Loading Loading @@ -422,5 +423,11 @@ That is, the recovery API only requires that: - drivers/net/cxgb3 - drivers/net/cxgb3 - drivers/net/s2io.c - drivers/net/s2io.c The cor_error_detected() callback is invoked in handle_error_source() when the error severity is "correctable". The callback is optional and allows additional logging to be done if desired. See example: - drivers/cxl/pci.c The End The End ------- -------
drivers/cxl/core/hdm.c +19 −14 Original line number Original line Diff line number Diff line Loading @@ -82,18 +82,23 @@ static void parse_hdm_decoder_caps(struct cxl_hdm *cxlhdm) cxlhdm->interleave_mask |= GENMASK(14, 12); cxlhdm->interleave_mask |= GENMASK(14, 12); } } static void __iomem *map_hdm_decoder_regs(struct cxl_port *port, static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb, void __iomem *crb) struct cxl_component_regs *regs) { { struct cxl_component_reg_map map; struct cxl_register_map map = { .resource = port->component_reg_phys, .base = crb, .max_size = CXL_COMPONENT_REG_BLOCK_SIZE, }; cxl_probe_component_regs(&port->dev, crb, &map); cxl_probe_component_regs(&port->dev, crb, &map.component_map); if (!map.hdm_decoder.valid) { if (!map.component_map.hdm_decoder.valid) { dev_err(&port->dev, "HDM decoder registers invalid\n"); dev_err(&port->dev, "HDM decoder registers invalid\n"); return IOMEM_ERR_PTR(-ENXIO); return -ENXIO; } } return crb + map.hdm_decoder.offset; return cxl_map_component_regs(&port->dev, regs, &map, BIT(CXL_CM_CAP_CAP_ID_HDM)); } } /** /** Loading @@ -103,25 +108,25 @@ static void __iomem *map_hdm_decoder_regs(struct cxl_port *port, struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port) struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port) { { struct device *dev = &port->dev; struct device *dev = &port->dev; void __iomem *crb, *hdm; struct cxl_hdm *cxlhdm; struct cxl_hdm *cxlhdm; void __iomem *crb; int rc; cxlhdm = devm_kzalloc(dev, sizeof(*cxlhdm), GFP_KERNEL); cxlhdm = devm_kzalloc(dev, sizeof(*cxlhdm), GFP_KERNEL); if (!cxlhdm) if (!cxlhdm) return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM); cxlhdm->port = port; cxlhdm->port = port; crb = devm_cxl_iomap_block(dev, port->component_reg_phys, crb = ioremap(port->component_reg_phys, CXL_COMPONENT_REG_BLOCK_SIZE); CXL_COMPONENT_REG_BLOCK_SIZE); if (!crb) { if (!crb) { dev_err(dev, "No component registers mapped\n"); dev_err(dev, "No component registers mapped\n"); return ERR_PTR(-ENXIO); return ERR_PTR(-ENXIO); } } hdm = map_hdm_decoder_regs(port, crb); rc = map_hdm_decoder_regs(port, crb, &cxlhdm->regs); if (IS_ERR(hdm)) iounmap(crb); return ERR_CAST(hdm); if (rc) cxlhdm->regs.hdm_decoder = hdm; return ERR_PTR(rc); parse_hdm_decoder_caps(cxlhdm); parse_hdm_decoder_caps(cxlhdm); if (cxlhdm->decoder_count == 0) { if (cxlhdm->decoder_count == 0) { Loading
drivers/cxl/core/memdev.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -344,6 +344,7 @@ struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds) * needed as this is ordered with cdev_add() publishing the device. * needed as this is ordered with cdev_add() publishing the device. */ */ cxlmd->cxlds = cxlds; cxlmd->cxlds = cxlds; cxlds->cxlmd = cxlmd; cdev = &cxlmd->cdev; cdev = &cxlmd->cdev; rc = cdev_device_add(cdev, dev); rc = cdev_device_add(cdev, dev); Loading
drivers/cxl/core/pci.c +1 −2 Original line number Original line Diff line number Diff line Loading @@ -54,8 +54,7 @@ static int match_add_dports(struct pci_dev *pdev, void *data) dev_dbg(&port->dev, "failed to find component registers\n"); dev_dbg(&port->dev, "failed to find component registers\n"); port_num = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap); port_num = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap); dport = devm_cxl_add_dport(port, &pdev->dev, port_num, dport = devm_cxl_add_dport(port, &pdev->dev, port_num, map.resource); cxl_regmap_to_base(pdev, &map)); if (IS_ERR(dport)) { if (IS_ERR(dport)) { ctx->error = PTR_ERR(dport); ctx->error = PTR_ERR(dport); return PTR_ERR(dport); return PTR_ERR(dport); Loading
drivers/cxl/core/port.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -1292,7 +1292,7 @@ static resource_size_t find_component_registers(struct device *dev) pdev = to_pci_dev(dev); pdev = to_pci_dev(dev); cxl_find_regblock(pdev, CXL_REGLOC_RBI_COMPONENT, &map); cxl_find_regblock(pdev, CXL_REGLOC_RBI_COMPONENT, &map); return cxl_regmap_to_base(pdev, &map); return map.resource; } } static int add_port_attach_ep(struct cxl_memdev *cxlmd, static int add_port_attach_ep(struct cxl_memdev *cxlmd, Loading