0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <asm/page.h>
0010 #include <linux/uaccess.h>
0011 #include <linux/ctype.h>
0012 #include <linux/highmem.h>
0013 #include <linux/init.h>
0014 #include <linux/module.h>
0015 #include <linux/slab.h>
0016 #include <linux/smp.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/sysctl.h>
0019 #include <linux/timer.h>
0020
0021 #include "edac_pci.h"
0022 #include "edac_module.h"
0023
0024 static DEFINE_MUTEX(edac_pci_ctls_mutex);
0025 static LIST_HEAD(edac_pci_list);
0026 static atomic_t pci_indexes = ATOMIC_INIT(0);
0027
0028 struct edac_pci_ctl_info *edac_pci_alloc_ctl_info(unsigned int sz_pvt,
0029 const char *edac_pci_name)
0030 {
0031 struct edac_pci_ctl_info *pci;
0032
0033 edac_dbg(1, "\n");
0034
0035 pci = kzalloc(sizeof(struct edac_pci_ctl_info), GFP_KERNEL);
0036 if (!pci)
0037 return NULL;
0038
0039 if (sz_pvt) {
0040 pci->pvt_info = kzalloc(sz_pvt, GFP_KERNEL);
0041 if (!pci->pvt_info)
0042 goto free;
0043 }
0044
0045 pci->op_state = OP_ALLOC;
0046
0047 snprintf(pci->name, strlen(edac_pci_name) + 1, "%s", edac_pci_name);
0048
0049 return pci;
0050
0051 free:
0052 kfree(pci);
0053 return NULL;
0054 }
0055 EXPORT_SYMBOL_GPL(edac_pci_alloc_ctl_info);
0056
0057 void edac_pci_free_ctl_info(struct edac_pci_ctl_info *pci)
0058 {
0059 edac_dbg(1, "\n");
0060
0061 edac_pci_remove_sysfs(pci);
0062 }
0063 EXPORT_SYMBOL_GPL(edac_pci_free_ctl_info);
0064
0065
0066
0067
0068
0069
0070
0071 static struct edac_pci_ctl_info *find_edac_pci_by_dev(struct device *dev)
0072 {
0073 struct edac_pci_ctl_info *pci;
0074 struct list_head *item;
0075
0076 edac_dbg(1, "\n");
0077
0078 list_for_each(item, &edac_pci_list) {
0079 pci = list_entry(item, struct edac_pci_ctl_info, link);
0080
0081 if (pci->dev == dev)
0082 return pci;
0083 }
0084
0085 return NULL;
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 static int add_edac_pci_to_global_list(struct edac_pci_ctl_info *pci)
0097 {
0098 struct list_head *item, *insert_before;
0099 struct edac_pci_ctl_info *rover;
0100
0101 edac_dbg(1, "\n");
0102
0103 insert_before = &edac_pci_list;
0104
0105
0106 rover = find_edac_pci_by_dev(pci->dev);
0107 if (unlikely(rover != NULL))
0108 goto fail0;
0109
0110
0111 list_for_each(item, &edac_pci_list) {
0112 rover = list_entry(item, struct edac_pci_ctl_info, link);
0113
0114 if (rover->pci_idx >= pci->pci_idx) {
0115 if (unlikely(rover->pci_idx == pci->pci_idx))
0116 goto fail1;
0117
0118 insert_before = item;
0119 break;
0120 }
0121 }
0122
0123 list_add_tail_rcu(&pci->link, insert_before);
0124 return 0;
0125
0126 fail0:
0127 edac_printk(KERN_WARNING, EDAC_PCI,
0128 "%s (%s) %s %s already assigned %d\n",
0129 dev_name(rover->dev), edac_dev_name(rover),
0130 rover->mod_name, rover->ctl_name, rover->pci_idx);
0131 return 1;
0132
0133 fail1:
0134 edac_printk(KERN_WARNING, EDAC_PCI,
0135 "but in low-level driver: attempt to assign\n"
0136 "\tduplicate pci_idx %d in %s()\n", rover->pci_idx,
0137 __func__);
0138 return 1;
0139 }
0140
0141
0142
0143
0144
0145
0146 static void del_edac_pci_from_global_list(struct edac_pci_ctl_info *pci)
0147 {
0148 list_del_rcu(&pci->link);
0149
0150
0151
0152
0153 synchronize_rcu();
0154 INIT_LIST_HEAD(&pci->link);
0155 }
0156
0157
0158
0159
0160
0161
0162
0163 static void edac_pci_workq_function(struct work_struct *work_req)
0164 {
0165 struct delayed_work *d_work = to_delayed_work(work_req);
0166 struct edac_pci_ctl_info *pci = to_edac_pci_ctl_work(d_work);
0167 int msec;
0168 unsigned long delay;
0169
0170 edac_dbg(3, "checking\n");
0171
0172 mutex_lock(&edac_pci_ctls_mutex);
0173
0174 if (pci->op_state != OP_RUNNING_POLL) {
0175 mutex_unlock(&edac_pci_ctls_mutex);
0176 return;
0177 }
0178
0179 if (edac_pci_get_check_errors())
0180 pci->edac_check(pci);
0181
0182
0183 msec = edac_pci_get_poll_msec();
0184 if (msec == 1000)
0185 delay = round_jiffies_relative(msecs_to_jiffies(msec));
0186 else
0187 delay = msecs_to_jiffies(msec);
0188
0189 edac_queue_work(&pci->work, delay);
0190
0191 mutex_unlock(&edac_pci_ctls_mutex);
0192 }
0193
0194 int edac_pci_alloc_index(void)
0195 {
0196 return atomic_inc_return(&pci_indexes) - 1;
0197 }
0198 EXPORT_SYMBOL_GPL(edac_pci_alloc_index);
0199
0200 int edac_pci_add_device(struct edac_pci_ctl_info *pci, int edac_idx)
0201 {
0202 edac_dbg(0, "\n");
0203
0204 pci->pci_idx = edac_idx;
0205 pci->start_time = jiffies;
0206
0207 mutex_lock(&edac_pci_ctls_mutex);
0208
0209 if (add_edac_pci_to_global_list(pci))
0210 goto fail0;
0211
0212 if (edac_pci_create_sysfs(pci)) {
0213 edac_pci_printk(pci, KERN_WARNING,
0214 "failed to create sysfs pci\n");
0215 goto fail1;
0216 }
0217
0218 if (pci->edac_check) {
0219 pci->op_state = OP_RUNNING_POLL;
0220
0221 INIT_DELAYED_WORK(&pci->work, edac_pci_workq_function);
0222 edac_queue_work(&pci->work, msecs_to_jiffies(edac_pci_get_poll_msec()));
0223
0224 } else {
0225 pci->op_state = OP_RUNNING_INTERRUPT;
0226 }
0227
0228 edac_pci_printk(pci, KERN_INFO,
0229 "Giving out device to module %s controller %s: DEV %s (%s)\n",
0230 pci->mod_name, pci->ctl_name, pci->dev_name,
0231 edac_op_state_to_string(pci->op_state));
0232
0233 mutex_unlock(&edac_pci_ctls_mutex);
0234 return 0;
0235
0236
0237 fail1:
0238 del_edac_pci_from_global_list(pci);
0239 fail0:
0240 mutex_unlock(&edac_pci_ctls_mutex);
0241 return 1;
0242 }
0243 EXPORT_SYMBOL_GPL(edac_pci_add_device);
0244
0245 struct edac_pci_ctl_info *edac_pci_del_device(struct device *dev)
0246 {
0247 struct edac_pci_ctl_info *pci;
0248
0249 edac_dbg(0, "\n");
0250
0251 mutex_lock(&edac_pci_ctls_mutex);
0252
0253
0254
0255
0256 pci = find_edac_pci_by_dev(dev);
0257 if (pci == NULL) {
0258 mutex_unlock(&edac_pci_ctls_mutex);
0259 return NULL;
0260 }
0261
0262 pci->op_state = OP_OFFLINE;
0263
0264 del_edac_pci_from_global_list(pci);
0265
0266 mutex_unlock(&edac_pci_ctls_mutex);
0267
0268 if (pci->edac_check)
0269 edac_stop_work(&pci->work);
0270
0271 edac_printk(KERN_INFO, EDAC_PCI,
0272 "Removed device %d for %s %s: DEV %s\n",
0273 pci->pci_idx, pci->mod_name, pci->ctl_name, edac_dev_name(pci));
0274
0275 return pci;
0276 }
0277 EXPORT_SYMBOL_GPL(edac_pci_del_device);
0278
0279
0280
0281
0282
0283
0284 static void edac_pci_generic_check(struct edac_pci_ctl_info *pci)
0285 {
0286 edac_dbg(4, "\n");
0287 edac_pci_do_parity_check();
0288 }
0289
0290
0291 static int edac_pci_idx;
0292 #define EDAC_PCI_GENCTL_NAME "EDAC PCI controller"
0293
0294 struct edac_pci_gen_data {
0295 int edac_idx;
0296 };
0297
0298 struct edac_pci_ctl_info *edac_pci_create_generic_ctl(struct device *dev,
0299 const char *mod_name)
0300 {
0301 struct edac_pci_ctl_info *pci;
0302 struct edac_pci_gen_data *pdata;
0303
0304 pci = edac_pci_alloc_ctl_info(sizeof(*pdata), EDAC_PCI_GENCTL_NAME);
0305 if (!pci)
0306 return NULL;
0307
0308 pdata = pci->pvt_info;
0309 pci->dev = dev;
0310 dev_set_drvdata(pci->dev, pci);
0311 pci->dev_name = pci_name(to_pci_dev(dev));
0312
0313 pci->mod_name = mod_name;
0314 pci->ctl_name = EDAC_PCI_GENCTL_NAME;
0315 if (edac_op_state == EDAC_OPSTATE_POLL)
0316 pci->edac_check = edac_pci_generic_check;
0317
0318 pdata->edac_idx = edac_pci_idx++;
0319
0320 if (edac_pci_add_device(pci, pdata->edac_idx) > 0) {
0321 edac_dbg(3, "failed edac_pci_add_device()\n");
0322 edac_pci_free_ctl_info(pci);
0323 return NULL;
0324 }
0325
0326 return pci;
0327 }
0328 EXPORT_SYMBOL_GPL(edac_pci_create_generic_ctl);
0329
0330 void edac_pci_release_generic_ctl(struct edac_pci_ctl_info *pci)
0331 {
0332 edac_dbg(0, "pci mod=%s\n", pci->mod_name);
0333
0334 edac_pci_del_device(pci->dev);
0335 edac_pci_free_ctl_info(pci);
0336 }
0337 EXPORT_SYMBOL_GPL(edac_pci_release_generic_ctl);