Lines Matching +full:bus +full:- +full:err

1 // SPDX-License-Identifier: GPL-2.0
8 * user space helper tool aer-inject, which can be gotten from:
9 * https://github.com/intel/aer-inject.git
35 u8 bus; member
50 unsigned int bus; member
66 struct pci_bus *bus; member
77 static void aer_error_init(struct aer_error *err, u32 domain, in aer_error_init() argument
78 unsigned int bus, unsigned int devfn, in aer_error_init() argument
81 INIT_LIST_HEAD(&err->list); in aer_error_init()
82 err->domain = domain; in aer_error_init()
83 err->bus = bus; in aer_error_init()
84 err->devfn = devfn; in aer_error_init()
85 err->pos_cap_err = pos_cap_err; in aer_error_init()
89 static struct aer_error *__find_aer_error(u32 domain, unsigned int bus, in __find_aer_error() argument
92 struct aer_error *err; in __find_aer_error() local
94 list_for_each_entry(err, &einjected, list) { in __find_aer_error()
95 if (domain == err->domain && in __find_aer_error()
96 bus == err->bus && in __find_aer_error()
97 devfn == err->devfn) in __find_aer_error()
98 return err; in __find_aer_error()
106 int domain = pci_domain_nr(dev->bus); in __find_aer_error_by_dev()
109 return __find_aer_error(domain, dev->bus->number, dev->devfn); in __find_aer_error_by_dev()
113 static struct pci_ops *__find_pci_bus_ops(struct pci_bus *bus) in __find_pci_bus_ops() argument
118 if (bus_ops->bus == bus) in __find_pci_bus_ops()
119 return bus_ops->ops; in __find_pci_bus_ops()
133 list_del(&bus_ops->list); in pci_bus_ops_pop()
138 static u32 *find_pci_config_dword(struct aer_error *err, int where, in find_pci_config_dword() argument
144 if (err->pos_cap_err == -1) in find_pci_config_dword()
147 switch (where - err->pos_cap_err) { in find_pci_config_dword()
149 target = &err->uncor_status; in find_pci_config_dword()
153 target = &err->cor_status; in find_pci_config_dword()
157 target = &err->header_log0; in find_pci_config_dword()
160 target = &err->header_log1; in find_pci_config_dword()
163 target = &err->header_log2; in find_pci_config_dword()
166 target = &err->header_log3; in find_pci_config_dword()
169 target = &err->root_status; in find_pci_config_dword()
173 target = &err->source_id; in find_pci_config_dword()
181 static int aer_inj_read(struct pci_bus *bus, unsigned int devfn, int where, in aer_inj_read() argument
187 ops = __find_pci_bus_ops(bus); in aer_inj_read()
189 return -1; in aer_inj_read()
191 my_ops = bus->ops; in aer_inj_read()
192 bus->ops = ops; in aer_inj_read()
193 rv = ops->read(bus, devfn, where, size, val); in aer_inj_read()
194 bus->ops = my_ops; in aer_inj_read()
199 static int aer_inj_write(struct pci_bus *bus, unsigned int devfn, int where, in aer_inj_write() argument
205 ops = __find_pci_bus_ops(bus); in aer_inj_write()
207 return -1; in aer_inj_write()
209 my_ops = bus->ops; in aer_inj_write()
210 bus->ops = ops; in aer_inj_write()
211 rv = ops->write(bus, devfn, where, size, val); in aer_inj_write()
212 bus->ops = my_ops; in aer_inj_write()
217 static int aer_inj_read_config(struct pci_bus *bus, unsigned int devfn, in aer_inj_read_config() argument
221 struct aer_error *err; in aer_inj_read_config() local
229 domain = pci_domain_nr(bus); in aer_inj_read_config()
232 err = __find_aer_error(domain, bus->number, devfn); in aer_inj_read_config()
233 if (!err) in aer_inj_read_config()
236 sim = find_pci_config_dword(err, where, NULL); in aer_inj_read_config()
243 rv = aer_inj_read(bus, devfn, where, size, val); in aer_inj_read_config()
248 static int aer_inj_write_config(struct pci_bus *bus, unsigned int devfn, in aer_inj_write_config() argument
252 struct aer_error *err; in aer_inj_write_config() local
261 domain = pci_domain_nr(bus); in aer_inj_write_config()
264 err = __find_aer_error(domain, bus->number, devfn); in aer_inj_write_config()
265 if (!err) in aer_inj_write_config()
268 sim = find_pci_config_dword(err, where, &rw1cs); in aer_inj_write_config()
278 rv = aer_inj_write(bus, devfn, where, size, val); in aer_inj_write_config()
289 struct pci_bus *bus, in pci_bus_ops_init() argument
292 INIT_LIST_HEAD(&bus_ops->list); in pci_bus_ops_init()
293 bus_ops->bus = bus; in pci_bus_ops_init()
294 bus_ops->ops = ops; in pci_bus_ops_init()
297 static int pci_bus_set_aer_ops(struct pci_bus *bus) in pci_bus_set_aer_ops() argument
305 return -ENOMEM; in pci_bus_set_aer_ops()
306 ops = pci_bus_set_ops(bus, &aer_inj_pci_ops); in pci_bus_set_aer_ops()
310 pci_bus_ops_init(bus_ops, bus, ops); in pci_bus_set_aer_ops()
311 list_add(&bus_ops->list, &pci_bus_ops_list); in pci_bus_set_aer_ops()
321 struct aer_error *err, *rperr; in aer_inject() local
327 unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); in aer_inject()
332 dev = pci_get_domain_bus_and_slot(einj->domain, einj->bus, devfn); in aer_inject()
334 return -ENODEV; in aer_inject()
338 rpdev = dev->rcec; in aer_inject()
341 ret = -ENODEV; in aer_inject()
345 pos_cap_err = dev->aer_cap; in aer_inject()
348 ret = -EPROTONOSUPPORT; in aer_inject()
356 rp_pos_cap_err = rpdev->aer_cap; in aer_inject()
359 ret = -EPROTONOSUPPORT; in aer_inject()
365 ret = -ENOMEM; in aer_inject()
370 ret = -ENOMEM; in aer_inject()
376 cor_mask &= !(einj->cor_status); in aer_inject()
381 uncor_mask &= !(einj->uncor_status); in aer_inject()
388 err = __find_aer_error_by_dev(dev); in aer_inject()
389 if (!err) { in aer_inject()
390 err = err_alloc; in aer_inject()
392 aer_error_init(err, einj->domain, einj->bus, devfn, in aer_inject()
394 list_add(&err->list, &einjected); in aer_inject()
396 err->uncor_status |= einj->uncor_status; in aer_inject()
397 err->cor_status |= einj->cor_status; in aer_inject()
398 err->header_log0 = einj->header_log0; in aer_inject()
399 err->header_log1 = einj->header_log1; in aer_inject()
400 err->header_log2 = einj->header_log2; in aer_inject()
401 err->header_log3 = einj->header_log3; in aer_inject()
403 if (!aer_mask_override && einj->cor_status && in aer_inject()
404 !(einj->cor_status & ~cor_mask)) { in aer_inject()
405 ret = -EINVAL; in aer_inject()
410 if (!aer_mask_override && einj->uncor_status && in aer_inject()
411 !(einj->uncor_status & ~uncor_mask)) { in aer_inject()
412 ret = -EINVAL; in aer_inject()
422 aer_error_init(rperr, pci_domain_nr(rpdev->bus), in aer_inject()
423 rpdev->bus->number, rpdev->devfn, in aer_inject()
425 list_add(&rperr->list, &einjected); in aer_inject()
427 if (einj->cor_status) { in aer_inject()
428 if (rperr->root_status & PCI_ERR_ROOT_COR_RCV) in aer_inject()
429 rperr->root_status |= PCI_ERR_ROOT_MULTI_COR_RCV; in aer_inject()
431 rperr->root_status |= PCI_ERR_ROOT_COR_RCV; in aer_inject()
432 rperr->source_id &= 0xffff0000; in aer_inject()
433 rperr->source_id |= PCI_DEVID(einj->bus, devfn); in aer_inject()
435 if (einj->uncor_status) { in aer_inject()
436 if (rperr->root_status & PCI_ERR_ROOT_UNCOR_RCV) in aer_inject()
437 rperr->root_status |= PCI_ERR_ROOT_MULTI_UNCOR_RCV; in aer_inject()
438 if (sever & einj->uncor_status) { in aer_inject()
439 rperr->root_status |= PCI_ERR_ROOT_FATAL_RCV; in aer_inject()
440 if (!(rperr->root_status & PCI_ERR_ROOT_UNCOR_RCV)) in aer_inject()
441 rperr->root_status |= PCI_ERR_ROOT_FIRST_FATAL; in aer_inject()
443 rperr->root_status |= PCI_ERR_ROOT_NONFATAL_RCV; in aer_inject()
444 rperr->root_status |= PCI_ERR_ROOT_UNCOR_RCV; in aer_inject()
445 rperr->source_id &= 0x0000ffff; in aer_inject()
446 rperr->source_id |= PCI_DEVID(einj->bus, devfn) << 16; in aer_inject()
457 ret = pci_bus_set_aer_ops(dev->bus); in aer_inject()
460 ret = pci_bus_set_aer_ops(rpdev->bus); in aer_inject()
468 pci_warn(edev->port, "AER service is not initialized\n"); in aer_inject()
469 ret = -EPROTONOSUPPORT; in aer_inject()
472 pci_info(edev->port, "Injecting errors %08x/%08x into device %s\n", in aer_inject()
473 einj->cor_status, einj->uncor_status, pci_name(dev)); in aer_inject()
474 ret = irq_inject_interrupt(edev->irq); in aer_inject()
477 ret = -ENODEV; in aer_inject()
493 return -EPERM; in aer_inject_write()
496 return -EINVAL; in aer_inject_write()
500 return -EFAULT; in aer_inject_write()
525 struct aer_error *err, *err_next; in aer_inject_exit() local
532 pci_bus_set_ops(bus_ops->bus, bus_ops->ops); in aer_inject_exit()
537 list_for_each_entry_safe(err, err_next, &einjected, list) { in aer_inject_exit()
538 list_del(&err->list); in aer_inject_exit()
539 kfree(err); in aer_inject_exit()