0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/kernel.h>
0013 #include <linux/pci.h>
0014 #include <linux/pci_regs.h>
0015
0016 #include "../pci.h"
0017
0018 struct walk_rcec_data {
0019 struct pci_dev *rcec;
0020 int (*user_callback)(struct pci_dev *dev, void *data);
0021 void *user_data;
0022 };
0023
0024 static bool rcec_assoc_rciep(struct pci_dev *rcec, struct pci_dev *rciep)
0025 {
0026 unsigned long bitmap = rcec->rcec_ea->bitmap;
0027 unsigned int devn;
0028
0029
0030 if (rcec->bus->number != rciep->bus->number)
0031 return true;
0032
0033
0034 for_each_set_bit(devn, &bitmap, 32)
0035 if (devn == PCI_SLOT(rciep->devfn))
0036 return true;
0037
0038 return false;
0039 }
0040
0041 static int link_rcec_helper(struct pci_dev *dev, void *data)
0042 {
0043 struct walk_rcec_data *rcec_data = data;
0044 struct pci_dev *rcec = rcec_data->rcec;
0045
0046 if ((pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) &&
0047 rcec_assoc_rciep(rcec, dev)) {
0048 dev->rcec = rcec;
0049 pci_dbg(dev, "PME & error events signaled via %s\n",
0050 pci_name(rcec));
0051 }
0052
0053 return 0;
0054 }
0055
0056 static int walk_rcec_helper(struct pci_dev *dev, void *data)
0057 {
0058 struct walk_rcec_data *rcec_data = data;
0059 struct pci_dev *rcec = rcec_data->rcec;
0060
0061 if ((pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) &&
0062 rcec_assoc_rciep(rcec, dev))
0063 rcec_data->user_callback(dev, rcec_data->user_data);
0064
0065 return 0;
0066 }
0067
0068 static void walk_rcec(int (*cb)(struct pci_dev *dev, void *data),
0069 void *userdata)
0070 {
0071 struct walk_rcec_data *rcec_data = userdata;
0072 struct pci_dev *rcec = rcec_data->rcec;
0073 u8 nextbusn, lastbusn;
0074 struct pci_bus *bus;
0075 unsigned int bnr;
0076
0077 if (!rcec->rcec_ea)
0078 return;
0079
0080
0081 pci_walk_bus(rcec->bus, cb, rcec_data);
0082
0083 nextbusn = rcec->rcec_ea->nextbusn;
0084 lastbusn = rcec->rcec_ea->lastbusn;
0085
0086
0087 if (nextbusn == 0xff && lastbusn == 0x00)
0088 return;
0089
0090 for (bnr = nextbusn; bnr <= lastbusn; bnr++) {
0091
0092 if (bnr == rcec->bus->number)
0093 continue;
0094
0095 bus = pci_find_bus(pci_domain_nr(rcec->bus), bnr);
0096 if (!bus)
0097 continue;
0098
0099
0100 pci_walk_bus(bus, cb, rcec_data);
0101 }
0102 }
0103
0104
0105
0106
0107
0108
0109
0110 void pcie_link_rcec(struct pci_dev *rcec)
0111 {
0112 struct walk_rcec_data rcec_data;
0113
0114 if (!rcec->rcec_ea)
0115 return;
0116
0117 rcec_data.rcec = rcec;
0118 rcec_data.user_callback = NULL;
0119 rcec_data.user_data = NULL;
0120
0121 walk_rcec(link_rcec_helper, &rcec_data);
0122 }
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 void pcie_walk_rcec(struct pci_dev *rcec, int (*cb)(struct pci_dev *, void *),
0135 void *userdata)
0136 {
0137 struct walk_rcec_data rcec_data;
0138
0139 if (!rcec->rcec_ea)
0140 return;
0141
0142 rcec_data.rcec = rcec;
0143 rcec_data.user_callback = cb;
0144 rcec_data.user_data = userdata;
0145
0146 walk_rcec(walk_rcec_helper, &rcec_data);
0147 }
0148
0149 void pci_rcec_init(struct pci_dev *dev)
0150 {
0151 struct rcec_ea *rcec_ea;
0152 u32 rcec, hdr, busn;
0153 u8 ver;
0154
0155
0156 if (pci_pcie_type(dev) != PCI_EXP_TYPE_RC_EC)
0157 return;
0158
0159 rcec = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_RCEC);
0160 if (!rcec)
0161 return;
0162
0163 rcec_ea = kzalloc(sizeof(*rcec_ea), GFP_KERNEL);
0164 if (!rcec_ea)
0165 return;
0166
0167 pci_read_config_dword(dev, rcec + PCI_RCEC_RCIEP_BITMAP,
0168 &rcec_ea->bitmap);
0169
0170
0171 pci_read_config_dword(dev, rcec, &hdr);
0172 ver = PCI_EXT_CAP_VER(hdr);
0173 if (ver >= PCI_RCEC_BUSN_REG_VER) {
0174 pci_read_config_dword(dev, rcec + PCI_RCEC_BUSN, &busn);
0175 rcec_ea->nextbusn = PCI_RCEC_BUSN_NEXT(busn);
0176 rcec_ea->lastbusn = PCI_RCEC_BUSN_LAST(busn);
0177 } else {
0178
0179 rcec_ea->nextbusn = 0xff;
0180 rcec_ea->lastbusn = 0x00;
0181 }
0182
0183 dev->rcec_ea = rcec_ea;
0184 }
0185
0186 void pci_rcec_exit(struct pci_dev *dev)
0187 {
0188 kfree(dev->rcec_ea);
0189 dev->rcec_ea = NULL;
0190 }