12 #include <linux/module.h>
13 #include <linux/types.h>
16 #include <linux/sysctl.h>
19 #include <linux/slab.h>
21 #include <linux/list.h>
22 #include <linux/ctype.h>
24 #include <asm/uaccess.h>
42 const char *edac_pci_name)
44 struct edac_pci_ctl_info *
pci;
52 size = ((
unsigned long)pvt) + sz_pvt;
60 pvt = sz_pvt ? ((
char *)pci) + ((
unsigned long)pvt) :
NULL;
65 snprintf(pci->name,
strlen(edac_pci_name) + 1,
"%s", edac_pci_name);
95 static struct edac_pci_ctl_info *find_edac_pci_by_dev(
struct device *
dev)
97 struct edac_pci_ctl_info *
pci;
120 static int add_edac_pci_to_global_list(
struct edac_pci_ctl_info *pci)
123 struct edac_pci_ctl_info *rover;
127 insert_before = &edac_pci_list;
130 rover = find_edac_pci_by_dev(pci->dev);
138 if (rover->pci_idx >= pci->pci_idx) {
139 if (
unlikely(rover->pci_idx == pci->pci_idx))
142 insert_before =
item;
147 list_add_tail_rcu(&pci->link, insert_before);
152 "%s (%s) %s %s already assigned %d\n",
154 rover->mod_name, rover->ctl_name, rover->pci_idx);
159 "but in low-level driver: attempt to assign\n"
160 "\tduplicate pci_idx %d in %s()\n", rover->pci_idx,
170 static void del_edac_pci_from_global_list(
struct edac_pci_ctl_info *pci)
172 list_del_rcu(&pci->link);
178 INIT_LIST_HEAD(&pci->link);
193 struct edac_pci_ctl_info *edac_pci_find(
int idx)
196 struct edac_pci_ctl_info *pci;
202 if (pci->pci_idx >= idx) {
203 if (pci->pci_idx == idx)
222 static void edac_pci_workq_function(
struct work_struct *work_req)
224 struct delayed_work *d_work = to_delayed_work(work_req);
225 struct edac_pci_ctl_info *pci = to_edac_pci_ctl_work(d_work);
237 pci->edac_check(pci);
261 static void edac_pci_workq_setup(
struct edac_pci_ctl_info *pci,
275 static void edac_pci_workq_teardown(
struct edac_pci_ctl_info *pci)
298 edac_pci_workq_teardown(pci);
303 edac_pci_workq_setup(pci, value);
338 pci->pci_idx = edac_idx;
343 if (add_edac_pci_to_global_list(pci))
348 "failed to create sysfs pci\n");
352 if (pci->edac_check !=
NULL) {
355 edac_pci_workq_setup(pci, 1000);
361 "Giving out device to module '%s' controller '%s':"
372 del_edac_pci_from_global_list(pci);
394 struct edac_pci_ctl_info *pci;
403 pci = find_edac_pci_by_dev(dev);
411 del_edac_pci_from_global_list(pci);
416 edac_pci_workq_teardown(pci);
419 "Removed device %d for %s %s: DEV %s\n",
420 pci->pci_idx, pci->mod_name, pci->ctl_name,
edac_dev_name(pci));
431 static void edac_pci_generic_check(
struct edac_pci_ctl_info *pci)
438 static int edac_pci_idx;
439 #define EDAC_PCI_GENCTL_NAME "EDAC PCI controller"
457 const char *mod_name)
459 struct edac_pci_ctl_info *pci;
466 pdata = pci->pvt_info;
471 pci->mod_name = mod_name;
473 pci->edac_check = edac_pci_generic_check;
478 edac_dbg(3,
"failed edac_pci_add_device()\n");
494 edac_dbg(0,
"pci mod=%s\n", pci->mod_name);