4 * Author: Dave Jiang <djiang@mvista.com>
6 * 2007 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
13 #include <linux/uaccess.h>
14 #include <linux/ctype.h>
15 #include <linux/highmem.h>
16 #include <linux/init.h>
17 #include <linux/module.h>
18 #include <linux/slab.h>
19 #include <linux/smp.h>
20 #include <linux/spinlock.h>
21 #include <linux/sysctl.h>
22 #include <linux/timer.h>
25 #include "edac_module.h"
27 static DEFINE_MUTEX(edac_pci_ctls_mutex
);
28 static LIST_HEAD(edac_pci_list
);
29 static atomic_t pci_indexes
= ATOMIC_INIT(0);
31 struct edac_pci_ctl_info
*edac_pci_alloc_ctl_info(unsigned int sz_pvt
,
32 const char *edac_pci_name
)
34 struct edac_pci_ctl_info
*pci
;
40 pci
= edac_align_ptr(&p
, sizeof(*pci
), 1);
41 pvt
= edac_align_ptr(&p
, 1, sz_pvt
);
42 size
= ((unsigned long)pvt
) + sz_pvt
;
44 /* Alloc the needed control struct memory */
45 pci
= kzalloc(size
, GFP_KERNEL
);
49 /* Now much private space */
50 pvt
= sz_pvt
? ((char *)pci
) + ((unsigned long)pvt
) : NULL
;
53 pci
->op_state
= OP_ALLOC
;
55 snprintf(pci
->name
, strlen(edac_pci_name
) + 1, "%s", edac_pci_name
);
59 EXPORT_SYMBOL_GPL(edac_pci_alloc_ctl_info
);
61 void edac_pci_free_ctl_info(struct edac_pci_ctl_info
*pci
)
65 edac_pci_remove_sysfs(pci
);
67 EXPORT_SYMBOL_GPL(edac_pci_free_ctl_info
);
70 * find_edac_pci_by_dev()
71 * scans the edac_pci list for a specific 'struct device *'
73 * return NULL if not found, or return control struct pointer
75 static struct edac_pci_ctl_info
*find_edac_pci_by_dev(struct device
*dev
)
77 struct edac_pci_ctl_info
*pci
;
78 struct list_head
*item
;
82 list_for_each(item
, &edac_pci_list
) {
83 pci
= list_entry(item
, struct edac_pci_ctl_info
, link
);
93 * add_edac_pci_to_global_list
94 * Before calling this function, caller must assign a unique value to
100 static int add_edac_pci_to_global_list(struct edac_pci_ctl_info
*pci
)
102 struct list_head
*item
, *insert_before
;
103 struct edac_pci_ctl_info
*rover
;
107 insert_before
= &edac_pci_list
;
109 /* Determine if already on the list */
110 rover
= find_edac_pci_by_dev(pci
->dev
);
111 if (unlikely(rover
!= NULL
))
114 /* Insert in ascending order by 'pci_idx', so find position */
115 list_for_each(item
, &edac_pci_list
) {
116 rover
= list_entry(item
, struct edac_pci_ctl_info
, link
);
118 if (rover
->pci_idx
>= pci
->pci_idx
) {
119 if (unlikely(rover
->pci_idx
== pci
->pci_idx
))
122 insert_before
= item
;
127 list_add_tail_rcu(&pci
->link
, insert_before
);
131 edac_printk(KERN_WARNING
, EDAC_PCI
,
132 "%s (%s) %s %s already assigned %d\n",
133 dev_name(rover
->dev
), edac_dev_name(rover
),
134 rover
->mod_name
, rover
->ctl_name
, rover
->pci_idx
);
138 edac_printk(KERN_WARNING
, EDAC_PCI
,
139 "but in low-level driver: attempt to assign\n"
140 "\tduplicate pci_idx %d in %s()\n", rover
->pci_idx
,
146 * del_edac_pci_from_global_list
148 * remove the PCI control struct from the global list
150 static void del_edac_pci_from_global_list(struct edac_pci_ctl_info
*pci
)
152 list_del_rcu(&pci
->link
);
154 /* these are for safe removal of devices from global list while
155 * NMI handlers may be traversing list
158 INIT_LIST_HEAD(&pci
->link
);
162 * edac_pci_workq_function()
164 * periodic function that performs the operation
165 * scheduled by a workq request, for a given PCI control struct
167 static void edac_pci_workq_function(struct work_struct
*work_req
)
169 struct delayed_work
*d_work
= to_delayed_work(work_req
);
170 struct edac_pci_ctl_info
*pci
= to_edac_pci_ctl_work(d_work
);
174 edac_dbg(3, "checking\n");
176 mutex_lock(&edac_pci_ctls_mutex
);
178 if (pci
->op_state
!= OP_RUNNING_POLL
) {
179 mutex_unlock(&edac_pci_ctls_mutex
);
183 if (edac_pci_get_check_errors())
184 pci
->edac_check(pci
);
186 /* if we are on a one second period, then use round */
187 msec
= edac_pci_get_poll_msec();
189 delay
= round_jiffies_relative(msecs_to_jiffies(msec
));
191 delay
= msecs_to_jiffies(msec
);
193 edac_queue_work(&pci
->work
, delay
);
195 mutex_unlock(&edac_pci_ctls_mutex
);
198 int edac_pci_alloc_index(void)
200 return atomic_inc_return(&pci_indexes
) - 1;
202 EXPORT_SYMBOL_GPL(edac_pci_alloc_index
);
204 int edac_pci_add_device(struct edac_pci_ctl_info
*pci
, int edac_idx
)
208 pci
->pci_idx
= edac_idx
;
209 pci
->start_time
= jiffies
;
211 mutex_lock(&edac_pci_ctls_mutex
);
213 if (add_edac_pci_to_global_list(pci
))
216 if (edac_pci_create_sysfs(pci
)) {
217 edac_pci_printk(pci
, KERN_WARNING
,
218 "failed to create sysfs pci\n");
222 if (pci
->edac_check
) {
223 pci
->op_state
= OP_RUNNING_POLL
;
225 INIT_DELAYED_WORK(&pci
->work
, edac_pci_workq_function
);
226 edac_queue_work(&pci
->work
, msecs_to_jiffies(edac_pci_get_poll_msec()));
229 pci
->op_state
= OP_RUNNING_INTERRUPT
;
232 edac_pci_printk(pci
, KERN_INFO
,
233 "Giving out device to module %s controller %s: DEV %s (%s)\n",
234 pci
->mod_name
, pci
->ctl_name
, pci
->dev_name
,
235 edac_op_state_to_string(pci
->op_state
));
237 mutex_unlock(&edac_pci_ctls_mutex
);
240 /* error unwind stack */
242 del_edac_pci_from_global_list(pci
);
244 mutex_unlock(&edac_pci_ctls_mutex
);
247 EXPORT_SYMBOL_GPL(edac_pci_add_device
);
249 struct edac_pci_ctl_info
*edac_pci_del_device(struct device
*dev
)
251 struct edac_pci_ctl_info
*pci
;
255 mutex_lock(&edac_pci_ctls_mutex
);
257 /* ensure the control struct is on the global list
260 pci
= find_edac_pci_by_dev(dev
);
262 mutex_unlock(&edac_pci_ctls_mutex
);
266 pci
->op_state
= OP_OFFLINE
;
268 del_edac_pci_from_global_list(pci
);
270 mutex_unlock(&edac_pci_ctls_mutex
);
273 edac_stop_work(&pci
->work
);
275 edac_printk(KERN_INFO
, EDAC_PCI
,
276 "Removed device %d for %s %s: DEV %s\n",
277 pci
->pci_idx
, pci
->mod_name
, pci
->ctl_name
, edac_dev_name(pci
));
281 EXPORT_SYMBOL_GPL(edac_pci_del_device
);
284 * edac_pci_generic_check
286 * a Generic parity check API
288 static void edac_pci_generic_check(struct edac_pci_ctl_info
*pci
)
291 edac_pci_do_parity_check();
294 /* free running instance index counter */
295 static int edac_pci_idx
;
296 #define EDAC_PCI_GENCTL_NAME "EDAC PCI controller"
298 struct edac_pci_gen_data
{
302 struct edac_pci_ctl_info
*edac_pci_create_generic_ctl(struct device
*dev
,
303 const char *mod_name
)
305 struct edac_pci_ctl_info
*pci
;
306 struct edac_pci_gen_data
*pdata
;
308 pci
= edac_pci_alloc_ctl_info(sizeof(*pdata
), EDAC_PCI_GENCTL_NAME
);
312 pdata
= pci
->pvt_info
;
314 dev_set_drvdata(pci
->dev
, pci
);
315 pci
->dev_name
= pci_name(to_pci_dev(dev
));
317 pci
->mod_name
= mod_name
;
318 pci
->ctl_name
= EDAC_PCI_GENCTL_NAME
;
319 if (edac_op_state
== EDAC_OPSTATE_POLL
)
320 pci
->edac_check
= edac_pci_generic_check
;
322 pdata
->edac_idx
= edac_pci_idx
++;
324 if (edac_pci_add_device(pci
, pdata
->edac_idx
) > 0) {
325 edac_dbg(3, "failed edac_pci_add_device()\n");
326 edac_pci_free_ctl_info(pci
);
332 EXPORT_SYMBOL_GPL(edac_pci_create_generic_ctl
);
334 void edac_pci_release_generic_ctl(struct edac_pci_ctl_info
*pci
)
336 edac_dbg(0, "pci mod=%s\n", pci
->mod_name
);
338 edac_pci_del_device(pci
->dev
);
339 edac_pci_free_ctl_info(pci
);
341 EXPORT_SYMBOL_GPL(edac_pci_release_generic_ctl
);