From ceb2ca9cb0bfd885127fa9a2c27127b3fe1c8f28 Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Mon, 13 Mar 2006 21:20:50 -0800 Subject: [PATCH] EDAC: disable sysfs interface - Disable the EDAC sysfs code. The sysfs interface that EDAC presents to user space needs more thought, and is likely to change substantially. Therefore disable it for now so users don't start depending on it in its current form. - Disable the default behavior of calling panic() when an uncorrectible error is detected (since for now, there is no sysfs interface that allows the user to configure this behavior). Signed-off-by: David S. Peterson Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/edac_mc.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 262e44544dc..9c205274c1c 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -38,6 +38,12 @@ #define EDAC_MC_VERSION "edac_mc Ver: 2.0.0 " __DATE__ +/* For now, disable the EDAC sysfs code. The sysfs interface that EDAC + * presents to user space needs more thought, and is likely to change + * substantially. + */ +#define DISABLE_EDAC_SYSFS + #ifdef CONFIG_EDAC_DEBUG /* Values of 0 to 4 will generate output */ int edac_debug_level = 1; @@ -47,7 +53,7 @@ EXPORT_SYMBOL(edac_debug_level); /* EDAC Controls, setable by module parameter, and sysfs */ static int log_ue = 1; static int log_ce = 1; -static int panic_on_ue = 1; +static int panic_on_ue; static int poll_msec = 1000; static int check_pci_parity = 0; /* default YES check PCI parity */ @@ -77,6 +83,8 @@ static int pci_whitelist_count ; /* START sysfs data and methods */ +#ifndef DISABLE_EDAC_SYSFS + static const char *mem_types[] = { [MEM_EMPTY] = "Empty", [MEM_RESERVED] = "Reserved", @@ -241,6 +249,7 @@ static struct kobj_type ktype_memctrl = { .default_attrs = (struct attribute **) memctrl_attr, }; +#endif /* DISABLE_EDAC_SYSFS */ /* Initialize the main sysfs entries for edac: * /sys/devices/system/edac @@ -251,6 +260,11 @@ static struct kobj_type ktype_memctrl = { * !0 FAILURE */ static int edac_sysfs_memctrl_setup(void) +#ifdef DISABLE_EDAC_SYSFS +{ + return 0; +} +#else { int err=0; @@ -283,6 +297,7 @@ static int edac_sysfs_memctrl_setup(void) return err; } +#endif /* DISABLE_EDAC_SYSFS */ /* * MC teardown: @@ -290,6 +305,7 @@ static int edac_sysfs_memctrl_setup(void) */ static void edac_sysfs_memctrl_teardown(void) { +#ifndef DISABLE_EDAC_SYSFS debugf0("MC: " __FILE__ ": %s()\n", __func__); /* Unregister the MC's kobject */ @@ -300,8 +316,11 @@ static void edac_sysfs_memctrl_teardown(void) /* Unregister the 'edac' object */ sysdev_class_unregister(&edac_class); +#endif /* DISABLE_EDAC_SYSFS */ } +#ifndef DISABLE_EDAC_SYSFS + /* * /sys/devices/system/edac/pci; * data structures and methods @@ -554,11 +573,18 @@ static struct kobj_type ktype_edac_pci = { .default_attrs = (struct attribute **) edac_pci_attr, }; +#endif /* DISABLE_EDAC_SYSFS */ + /** * edac_sysfs_pci_setup() * */ static int edac_sysfs_pci_setup(void) +#ifdef DISABLE_EDAC_SYSFS +{ + return 0; +} +#else { int err; @@ -582,16 +608,20 @@ static int edac_sysfs_pci_setup(void) } return err; } - +#endif /* DISABLE_EDAC_SYSFS */ static void edac_sysfs_pci_teardown(void) { +#ifndef DISABLE_EDAC_SYSFS debugf0("MC: " __FILE__ ": %s()\n", __func__); kobject_unregister(&edac_pci_kobj); kobject_put(&edac_pci_kobj); +#endif } +#ifndef DISABLE_EDAC_SYSFS + /* EDAC sysfs CSROW data structures and methods */ /* Set of more detailed csrow attribute show/store functions */ @@ -1045,6 +1075,8 @@ static struct kobj_type ktype_mci = { .default_attrs = (struct attribute **) mci_attr, }; +#endif /* DISABLE_EDAC_SYSFS */ + #define EDAC_DEVICE_SYMLINK "device" /* @@ -1056,6 +1088,11 @@ static struct kobj_type ktype_mci = { * !0 Failure */ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) +#ifdef DISABLE_EDAC_SYSFS +{ + return 0; +} +#else { int i; int err; @@ -1124,12 +1161,14 @@ fail: return err; } +#endif /* DISABLE_EDAC_SYSFS */ /* * remove a Memory Controller instance */ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) { +#ifndef DISABLE_EDAC_SYSFS int i; debugf0("MC: " __FILE__ ": %s()\n", __func__); @@ -1146,6 +1185,7 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) kobject_unregister(&mci->edac_mci_kobj); kobject_put(&mci->edac_mci_kobj); +#endif /* DISABLE_EDAC_SYSFS */ } /* END OF sysfs data and methods */ -- cgit v1.2.3-70-g09d2 From f2fe42abbf0d99a8c4b96f1cc55db10ac35d2fb9 Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Sun, 26 Mar 2006 01:38:38 -0800 Subject: [PATCH] EDAC: switch to kthread_ API This patch was originally posted by Christoph Hellwig (see http://lkml.org/lkml/2006/2/14/331): "Christoph Hellwig" wrote: > Use the kthread_ API instead of opencoding lots of hairy code for kernel > thread creation and teardown, including tasklist_lock abuse. > Signed-off-by: Christoph Hellwig Signed-off-by: David S. Peterson Cc: Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/edac_mc.c | 88 ++++++-------------------------------------------- 1 file changed, 10 insertions(+), 78 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 9c205274c1c..8a7a3ab745a 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -64,6 +65,8 @@ static atomic_t pci_parity_count = ATOMIC_INIT(0); static DECLARE_MUTEX(mem_ctls_mutex); static struct list_head mc_devices = LIST_HEAD_INIT(mc_devices); +static struct task_struct *edac_thread; + /* Structure of the whitelist and blacklist arrays */ struct edac_pci_device_list { unsigned int vendor; /* Vendor ID */ @@ -2073,7 +2076,6 @@ static inline void check_mc_devices (void) */ static void do_edac_check(void) { - debugf3("MC: " __FILE__ ": %s()\n", __func__); check_mc_devices(); @@ -2081,62 +2083,16 @@ static void do_edac_check(void) do_pci_parity_check(); } - -/* - * EDAC thread state information - */ -struct bs_thread_info -{ - struct task_struct *task; - struct completion *event; - char *name; - void (*run)(void); -}; - -static struct bs_thread_info bs_thread; - -/* - * edac_kernel_thread - * This the kernel thread that processes edac operations - * in a normal thread environment - */ static int edac_kernel_thread(void *arg) { - struct bs_thread_info *thread = (struct bs_thread_info *) arg; - - /* detach thread */ - daemonize(thread->name); - - current->exit_signal = SIGCHLD; - allow_signal(SIGKILL); - thread->task = current; - - /* indicate to starting task we have started */ - complete(thread->event); - - /* loop forever, until we are told to stop */ - while(thread->run != NULL) { - void (*run)(void); - - /* call the function to check the memory controllers */ - run = thread->run; - if (run) - run(); - - if (signal_pending(current)) - flush_signals(current); - - /* ensure we are interruptable */ - set_current_state(TASK_INTERRUPTIBLE); + while (!kthread_should_stop()) { + do_edac_check(); /* goto sleep for the interval */ - schedule_timeout((HZ * poll_msec) / 1000); + schedule_timeout_interruptible((HZ * poll_msec) / 1000); try_to_freeze(); } - /* notify waiter that we are exiting */ - complete(thread->event); - return 0; } @@ -2146,9 +2102,6 @@ static int edac_kernel_thread(void *arg) */ static int __init edac_mc_init(void) { - int ret; - struct completion event; - printk(KERN_INFO "MC: " __FILE__ " version " EDAC_MC_VERSION "\n"); /* @@ -2176,24 +2129,15 @@ static int __init edac_mc_init(void) return -ENODEV; } - /* Create our kernel thread */ - init_completion(&event); - bs_thread.event = &event; - bs_thread.name = "kedac"; - bs_thread.run = do_edac_check; - /* create our kernel thread */ - ret = kernel_thread(edac_kernel_thread, &bs_thread, CLONE_KERNEL); - if (ret < 0) { + edac_thread = kthread_run(edac_kernel_thread, NULL, "kedac"); + if (IS_ERR(edac_thread)) { /* remove the sysfs entries */ edac_sysfs_memctrl_teardown(); edac_sysfs_pci_teardown(); - return -ENOMEM; + return PTR_ERR(edac_thread); } - /* wait for our kernel theard ack that it is up and running */ - wait_for_completion(&event); - return 0; } @@ -2204,21 +2148,9 @@ static int __init edac_mc_init(void) */ static void __exit edac_mc_exit(void) { - struct completion event; - debugf0("MC: " __FILE__ ": %s()\n", __func__); - init_completion(&event); - bs_thread.event = &event; - - /* As soon as ->run is set to NULL, the task could disappear, - * so we need to hold tasklist_lock until we have sent the signal - */ - read_lock(&tasklist_lock); - bs_thread.run = NULL; - send_sig(SIGKILL, bs_thread.task, 1); - read_unlock(&tasklist_lock); - wait_for_completion(&event); + kthread_stop(edac_thread); /* tear down the sysfs device */ edac_sysfs_memctrl_teardown(); -- cgit v1.2.3-70-g09d2 From 537fba28928c01b7db1580627450691a4bb0b9b3 Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Sun, 26 Mar 2006 01:38:40 -0800 Subject: [PATCH] EDAC: printk cleanup This implements the following idea: On Monday 30 January 2006 19:22, Eric W. Biederman wrote: > One piece missing from this conversation is the issue that we need errors > in a uniform format. That is why edac_mc has helper functions. > > However there will always be errors that don't fit any particular model. > Could we add a edac_printk(dev, ); That is similar to dev_printk but > prints out an EDAC header and the device on which the error was found? > Letting the rest of the string be user specified. > > For actual control that interface may be to blunt, but at least for people > looking in the logs it allows all of the errors to be detected and > harvested. Signed-off-by: David S. Peterson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/amd76x_edac.c | 23 ++++-- drivers/edac/e752x_edac.c | 90 +++++++++++---------- drivers/edac/e7xxx_edac.c | 62 ++++++++------- drivers/edac/edac_mc.c | 186 ++++++++++++++++++++------------------------ drivers/edac/edac_mc.h | 23 +++++- drivers/edac/i82860_edac.c | 32 ++++---- drivers/edac/i82875p_edac.c | 51 ++++++------ drivers/edac/r82600_edac.c | 48 ++++++------ 8 files changed, 275 insertions(+), 240 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c index 2fcc8120b53..60535bb9275 100644 --- a/drivers/edac/amd76x_edac.c +++ b/drivers/edac/amd76x_edac.c @@ -25,6 +25,14 @@ #include "edac_mc.h" +#define amd76x_printk(level, fmt, arg...) \ + edac_printk(level, "amd76x", fmt, ##arg) + + +#define amd76x_mc_printk(mci, level, fmt, arg...) \ + edac_mc_chipset_printk(mci, level, "amd76x", fmt, ##arg) + + #define AMD76X_NR_CSROWS 8 #define AMD76X_NR_CHANS 1 #define AMD76X_NR_DIMMS 4 @@ -174,7 +182,7 @@ static int amd76x_process_error_info (struct mem_ctl_info *mci, static void amd76x_check(struct mem_ctl_info *mci) { struct amd76x_error_info info; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); amd76x_get_error_info(mci, &info); amd76x_process_error_info(mci, &info, 1); } @@ -204,7 +212,7 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) u32 ems; u32 ems_mode; - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, &ems); ems_mode = (ems >> 10) & 0x3; @@ -216,7 +224,7 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) goto fail; } - debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); + debugf0("%s(): mci = %p\n", __func__, mci); mci->pdev = pci_dev_get(pdev); mci->mtype_cap = MEM_FLAG_RDDR; @@ -267,13 +275,12 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) (u32) (0x3 << 8)); if (edac_mc_add_mc(mci)) { - debugf3("MC: " __FILE__ - ": %s(): failed edac_mc_add_mc()\n", __func__); + debugf3("%s(): failed edac_mc_add_mc()\n", __func__); goto fail; } /* get this far and it's successful */ - debugf3("MC: " __FILE__ ": %s(): success\n", __func__); + debugf3("%s(): success\n", __func__); return 0; fail: @@ -289,7 +296,7 @@ fail: static int __devinit amd76x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); /* don't need to call pci_device_enable() */ return amd76x_probe1(pdev, ent->driver_data); @@ -309,7 +316,7 @@ static void __devexit amd76x_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; - debugf0(__FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); if ((mci = edac_mc_find_mci_by_pdev(pdev)) == NULL) return; diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index c454ded2b06..25edba55b18 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c @@ -30,6 +30,14 @@ #include "edac_mc.h" +#define e752x_printk(level, fmt, arg...) \ + edac_printk(level, "e752x", fmt, ##arg) + + +#define e752x_mc_printk(mci, level, fmt, arg...) \ + edac_mc_chipset_printk(mci, level, "e752x", fmt, ##arg) + + #ifndef PCI_DEVICE_ID_INTEL_7520_0 #define PCI_DEVICE_ID_INTEL_7520_0 0x3590 #endif /* PCI_DEVICE_ID_INTEL_7520_0 */ @@ -215,7 +223,7 @@ static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci, u32 remap; struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); if (page < pvt->tolm) return page; @@ -224,7 +232,7 @@ static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci, remap = (page - pvt->tolm) + pvt->remapbase; if (remap < pvt->remaplimit) return remap; - printk(KERN_ERR "Invalid page %lx - out of range\n", page); + e752x_printk(KERN_ERR, "Invalid page %lx - out of range\n", page); return pvt->tolm - 1; } @@ -237,7 +245,7 @@ static void do_process_ce(struct mem_ctl_info *mci, u16 error_one, int i; struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); /* convert the addr to 4k page */ page = sec1_add >> (PAGE_SHIFT - 4); @@ -246,24 +254,23 @@ static void do_process_ce(struct mem_ctl_info *mci, u16 error_one, if (pvt->mc_symmetric) { /* chip select are bits 14 & 13 */ row = ((page >> 1) & 3); - printk(KERN_WARNING - "Test row %d Table %d %d %d %d %d %d %d %d\n", - row, pvt->map[0], pvt->map[1], pvt->map[2], - pvt->map[3], pvt->map[4], pvt->map[5], - pvt->map[6], pvt->map[7]); + e752x_printk(KERN_WARNING, + "Test row %d Table %d %d %d %d %d %d %d %d\n", + row, pvt->map[0], pvt->map[1], pvt->map[2], + pvt->map[3], pvt->map[4], pvt->map[5], + pvt->map[6], pvt->map[7]); /* test for channel remapping */ for (i = 0; i < 8; i++) { if (pvt->map[i] == row) break; } - printk(KERN_WARNING "Test computed row %d\n", i); + e752x_printk(KERN_WARNING, "Test computed row %d\n", i); if (i < 8) row = i; else - printk(KERN_WARNING - "MC%d: row %d not found in remap table\n", - mci->mc_idx, row); + e752x_mc_printk(mci, KERN_WARNING, + "row %d not found in remap table\n", row); } else row = edac_mc_find_csrow_by_page(mci, page); /* 0 = channel A, 1 = channel B */ @@ -293,7 +300,7 @@ static void do_process_ue(struct mem_ctl_info *mci, u16 error_one, u32 ded_add, int row; struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); if (error_one & 0x0202) { error_2b = ded_add; @@ -336,7 +343,7 @@ static inline void process_ue_no_info_wr(struct mem_ctl_info *mci, if (!handle_error) return; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); edac_mc_handle_ue_no_info(mci, "e752x UE log memory write"); } @@ -352,9 +359,9 @@ static void do_process_ded_retry(struct mem_ctl_info *mci, u16 error, row = pvt->mc_symmetric ? ((page >> 1) & 3) : /* chip select are bits 14 & 13 */ edac_mc_find_csrow_by_page(mci, page); - printk(KERN_WARNING - "MC%d: CE page 0x%lx, row %d : Memory read retry\n", - mci->mc_idx, (long unsigned int) page, row); + e752x_mc_printk(mci, KERN_WARNING, + "CE page 0x%lx, row %d : Memory read retry\n", + (long unsigned int) page, row); } static inline void process_ded_retry(struct mem_ctl_info *mci, u16 error, @@ -372,8 +379,7 @@ static inline void process_threshold_ce(struct mem_ctl_info *mci, u16 error, *error_found = 1; if (handle_error) - printk(KERN_WARNING "MC%d: Memory threshold CE\n", - mci->mc_idx); + e752x_mc_printk(mci, KERN_WARNING, "Memory threshold CE\n"); } static char *global_message[11] = { @@ -391,7 +397,7 @@ static void do_global_error(int fatal, u32 errors) for (i = 0; i < 11; i++) { if (errors & (1 << i)) - printk(KERN_WARNING "%sError %s\n", + e752x_printk(KERN_WARNING, "%sError %s\n", fatal_message[fatal], global_message[i]); } } @@ -418,7 +424,7 @@ static void do_hub_error(int fatal, u8 errors) for (i = 0; i < 7; i++) { if (errors & (1 << i)) - printk(KERN_WARNING "%sError %s\n", + e752x_printk(KERN_WARNING, "%sError %s\n", fatal_message[fatal], hub_message[i]); } } @@ -445,7 +451,7 @@ static void do_membuf_error(u8 errors) for (i = 0; i < 4; i++) { if (errors & (1 << i)) - printk(KERN_WARNING "Non-Fatal Error %s\n", + e752x_printk(KERN_WARNING, "Non-Fatal Error %s\n", membuf_message[i]); } } @@ -478,7 +484,7 @@ static void do_sysbus_error(int fatal, u32 errors) for (i = 0; i < 10; i++) { if (errors & (1 << i)) - printk(KERN_WARNING "%sError System Bus %s\n", + e752x_printk(KERN_WARNING, "%sError System Bus %s\n", fatal_message[fatal], global_message[i]); } } @@ -727,7 +733,7 @@ static int e752x_process_error_info (struct mem_ctl_info *mci, static void e752x_check(struct mem_ctl_info *mci) { struct e752x_error_info info; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); e752x_get_error_info(mci, &info); e752x_process_error_info(mci, &info, 1); } @@ -752,7 +758,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) struct pci_dev *pres_dev; struct pci_dev *dev = NULL; - debugf0("MC: " __FILE__ ": %s(): mci\n", __func__); + debugf0("%s(): mci\n", __func__); debugf0("Starting Probe1\n"); /* enable device 0 function 1 */ @@ -776,7 +782,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) goto fail; } - debugf3("MC: " __FILE__ ": %s(): init mci\n", __func__); + debugf3("%s(): init mci\n", __func__); mci->mtype_cap = MEM_FLAG_RDDR; mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED | @@ -786,7 +792,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) mci->mod_ver = "$Revision: 1.5.2.11 $"; mci->pdev = pdev; - debugf3("MC: " __FILE__ ": %s(): init pvt\n", __func__); + debugf3("%s(): init pvt\n", __func__); pvt = (struct e752x_pvt *) mci->pvt_info; pvt->dev_info = &e752x_devs[dev_idx]; pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL, @@ -796,14 +802,14 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) pvt->bridge_ck = pci_scan_single_device(pdev->bus, PCI_DEVFN(0, 1)); if (pvt->bridge_ck == NULL) { - printk(KERN_ERR "MC: error reporting device not found:" + e752x_printk(KERN_ERR, "error reporting device not found:" "vendor %x device 0x%x (broken BIOS?)\n", PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].err_dev); goto fail; } pvt->mc_symmetric = ((ddrcsr & 0x10) != 0); - debugf3("MC: " __FILE__ ": %s(): more mci init\n", __func__); + debugf3("%s(): more mci init\n", __func__); mci->ctl_name = pvt->dev_info->ctl_name; mci->edac_check = e752x_check; mci->ctl_page_to_phys = ctl_page_to_phys; @@ -828,8 +834,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) pci_read_config_byte(mci->pdev, E752X_DRB + index, &value); /* convert a 128 or 64 MiB DRB to a page size. */ cumul_size = value << (25 + drc_drbg - PAGE_SHIFT); - debugf3("MC: " __FILE__ ": %s(): (%d) cumul_size 0x%x\n", - __func__, index, cumul_size); + debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, + cumul_size); if (cumul_size == last_cumul_size) continue; /* not populated */ @@ -897,8 +903,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) mci->edac_cap |= EDAC_FLAG_NONE; - debugf3("MC: " __FILE__ ": %s(): tolm, remapbase, remaplimit\n", - __func__); + debugf3("%s(): tolm, remapbase, remaplimit\n", __func__); /* load the top of low memory, remap base, and remap limit vars */ pci_read_config_word(mci->pdev, E752X_TOLM, &pci_data); pvt->tolm = ((u32) pci_data) << 4; @@ -906,13 +911,12 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) pvt->remapbase = ((u32) pci_data) << 14; pci_read_config_word(mci->pdev, E752X_REMAPLIMIT, &pci_data); pvt->remaplimit = ((u32) pci_data) << 14; - printk("tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm, - pvt->remapbase, pvt->remaplimit); + e752x_printk(KERN_INFO, + "tolm = %x, remapbase = %x, remaplimit = %x\n", + pvt->tolm, pvt->remapbase, pvt->remaplimit); if (edac_mc_add_mc(mci)) { - debugf3("MC: " __FILE__ - ": %s(): failed edac_mc_add_mc()\n", - __func__); + debugf3("%s(): failed edac_mc_add_mc()\n", __func__); goto fail; } @@ -975,7 +979,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) pci_write_config_word(dev, E752X_DRAM_NERR, stat16); /* get this far and it's successful */ - debugf3("MC: " __FILE__ ": %s(): success\n", __func__); + debugf3("%s(): success\n", __func__); return 0; fail: @@ -995,7 +999,7 @@ fail: static int __devinit e752x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); /* wake up and enable device */ if(pci_enable_device(pdev) < 0) @@ -1009,7 +1013,7 @@ static void __devexit e752x_remove_one(struct pci_dev *pdev) struct mem_ctl_info *mci; struct e752x_pvt *pvt; - debugf0(__FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); if ((mci = edac_mc_find_mci_by_pdev(pdev)) == NULL) return; @@ -1050,7 +1054,7 @@ static int __init e752x_init(void) { int pci_rc; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); pci_rc = pci_register_driver(&e752x_driver); return (pci_rc < 0) ? pci_rc : 0; } @@ -1058,7 +1062,7 @@ static int __init e752x_init(void) static void __exit e752x_exit(void) { - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); pci_unregister_driver(&e752x_driver); } diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c index d5e320dfc66..e7537413cad 100644 --- a/drivers/edac/e7xxx_edac.c +++ b/drivers/edac/e7xxx_edac.c @@ -32,6 +32,14 @@ #include "edac_mc.h" +#define e7xxx_printk(level, fmt, arg...) \ + edac_printk(level, "e7xxx", fmt, ##arg) + + +#define e7xxx_mc_printk(mci, level, fmt, arg...) \ + edac_mc_chipset_printk(mci, level, "e7xxx", fmt, ##arg) + + #ifndef PCI_DEVICE_ID_INTEL_7205_0 #define PCI_DEVICE_ID_INTEL_7205_0 0x255d #endif /* PCI_DEVICE_ID_INTEL_7205_0 */ @@ -161,7 +169,7 @@ static const struct e7xxx_dev_info e7xxx_devs[] = { /* FIXME - is this valid for both SECDED and S4ECD4ED? */ static inline int e7xxx_find_channel(u16 syndrome) { - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); if ((syndrome & 0xff00) == 0) return 0; @@ -179,7 +187,7 @@ ctl_page_to_phys(struct mem_ctl_info *mci, unsigned long page) u32 remap; struct e7xxx_pvt *pvt = (struct e7xxx_pvt *) mci->pvt_info; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); if ((page < pvt->tolm) || ((page >= 0x100000) && (page < pvt->remapbase))) @@ -187,7 +195,7 @@ ctl_page_to_phys(struct mem_ctl_info *mci, unsigned long page) remap = (page - pvt->tolm) + pvt->remapbase; if (remap < pvt->remaplimit) return remap; - printk(KERN_ERR "Invalid page %lx - out of range\n", page); + e7xxx_printk(KERN_ERR, "Invalid page %lx - out of range\n", page); return pvt->tolm - 1; } @@ -199,7 +207,7 @@ static void process_ce(struct mem_ctl_info *mci, struct e7xxx_error_info *info) int row; int channel; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); /* read the error address */ error_1b = info->dram_celog_add; @@ -218,7 +226,7 @@ static void process_ce(struct mem_ctl_info *mci, struct e7xxx_error_info *info) static void process_ce_no_info(struct mem_ctl_info *mci) { - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); edac_mc_handle_ce_no_info(mci, "e7xxx CE log register overflow"); } @@ -228,7 +236,7 @@ static void process_ue(struct mem_ctl_info *mci, struct e7xxx_error_info *info) u32 error_2b, block_page; int row; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); /* read the error address */ error_2b = info->dram_uelog_add; @@ -241,7 +249,7 @@ static void process_ue(struct mem_ctl_info *mci, struct e7xxx_error_info *info) static void process_ue_no_info(struct mem_ctl_info *mci) { - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); edac_mc_handle_ue_no_info(mci, "e7xxx UE log register overflow"); } @@ -330,7 +338,7 @@ static void e7xxx_check(struct mem_ctl_info *mci) { struct e7xxx_error_info info; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); e7xxx_get_error_info(mci, &info); e7xxx_process_error_info(mci, &info, 1); } @@ -351,7 +359,7 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) unsigned long last_cumul_size; - debugf0("MC: " __FILE__ ": %s(): mci\n", __func__); + debugf0("%s(): mci\n", __func__); /* need to find out the number of channels */ pci_read_config_dword(pdev, E7XXX_DRC, &drc); @@ -369,7 +377,7 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) goto fail; } - debugf3("MC: " __FILE__ ": %s(): init mci\n", __func__); + debugf3("%s(): init mci\n", __func__); mci->mtype_cap = MEM_FLAG_RDDR; mci->edac_ctl_cap = @@ -379,21 +387,21 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) mci->mod_ver = "$Revision: 1.5.2.9 $"; mci->pdev = pdev; - debugf3("MC: " __FILE__ ": %s(): init pvt\n", __func__); + debugf3("%s(): init pvt\n", __func__); pvt = (struct e7xxx_pvt *) mci->pvt_info; pvt->dev_info = &e7xxx_devs[dev_idx]; pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL, pvt->dev_info->err_dev, pvt->bridge_ck); if (!pvt->bridge_ck) { - printk(KERN_ERR - "MC: error reporting device not found:" - "vendor %x device 0x%x (broken BIOS?)\n", - PCI_VENDOR_ID_INTEL, e7xxx_devs[dev_idx].err_dev); + e7xxx_printk(KERN_ERR, "error reporting device not found:" + "vendor %x device 0x%x (broken BIOS?)\n", + PCI_VENDOR_ID_INTEL, + e7xxx_devs[dev_idx].err_dev); goto fail; } - debugf3("MC: " __FILE__ ": %s(): more mci init\n", __func__); + debugf3("%s(): more mci init\n", __func__); mci->ctl_name = pvt->dev_info->ctl_name; mci->edac_check = e7xxx_check; @@ -418,8 +426,8 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) pci_read_config_byte(mci->pdev, E7XXX_DRB + index, &value); /* convert a 64 or 32 MiB DRB to a page size. */ cumul_size = value << (25 + drc_drbg - PAGE_SHIFT); - debugf3("MC: " __FILE__ ": %s(): (%d) cumul_size 0x%x\n", - __func__, index, cumul_size); + debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, + cumul_size); if (cumul_size == last_cumul_size) continue; /* not populated */ @@ -449,8 +457,7 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) mci->edac_cap |= EDAC_FLAG_NONE; - debugf3("MC: " __FILE__ ": %s(): tolm, remapbase, remaplimit\n", - __func__); + debugf3("%s(): tolm, remapbase, remaplimit\n", __func__); /* load the top of low memory, remap base, and remap limit vars */ pci_read_config_word(mci->pdev, E7XXX_TOLM, &pci_data); pvt->tolm = ((u32) pci_data) << 4; @@ -458,22 +465,21 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) pvt->remapbase = ((u32) pci_data) << 14; pci_read_config_word(mci->pdev, E7XXX_REMAPLIMIT, &pci_data); pvt->remaplimit = ((u32) pci_data) << 14; - printk("tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm, - pvt->remapbase, pvt->remaplimit); + e7xxx_printk(KERN_INFO, + "tolm = %x, remapbase = %x, remaplimit = %x\n", + pvt->tolm, pvt->remapbase, pvt->remaplimit); /* clear any pending errors, or initial state bits */ pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_FERR, 0x03, 0x03); pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_NERR, 0x03, 0x03); if (edac_mc_add_mc(mci) != 0) { - debugf3("MC: " __FILE__ - ": %s(): failed edac_mc_add_mc()\n", - __func__); + debugf3("%s(): failed edac_mc_add_mc()\n", __func__); goto fail; } /* get this far and it's successful */ - debugf3("MC: " __FILE__ ": %s(): success\n", __func__); + debugf3("%s(): success\n", __func__); return 0; fail: @@ -490,7 +496,7 @@ fail: static int __devinit e7xxx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); /* wake up and enable device */ return pci_enable_device(pdev) ? @@ -503,7 +509,7 @@ static void __devexit e7xxx_remove_one(struct pci_dev *pdev) struct mem_ctl_info *mci; struct e7xxx_pvt *pvt; - debugf0(__FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); if (((mci = edac_mc_find_mci_by_pdev(pdev)) != 0) && edac_mc_del_mc(mci)) { diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 8a7a3ab745a..499ac90ad67 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -37,7 +37,7 @@ #include "edac_mc.h" -#define EDAC_MC_VERSION "edac_mc Ver: 2.0.0 " __DATE__ +#define EDAC_MC_VERSION "Ver: 2.0.0 " __DATE__ /* For now, disable the EDAC sysfs code. The sysfs interface that EDAC * presents to user space needs more thought, and is likely to change @@ -243,7 +243,7 @@ static struct memctrl_dev_attribute *memctrl_attr[] = { /* Main MC kobject release() function */ static void edac_memctrl_master_release(struct kobject *kobj) { - debugf1("EDAC MC: " __FILE__ ": %s()\n", __func__); + debugf1("%s()\n", __func__); } static struct kobj_type ktype_memctrl = { @@ -271,7 +271,7 @@ static int edac_sysfs_memctrl_setup(void) { int err=0; - debugf1("MC: " __FILE__ ": %s()\n", __func__); + debugf1("%s()\n", __func__); /* create the /sys/devices/system/edac directory */ err = sysdev_class_register(&edac_class); @@ -295,7 +295,7 @@ static int edac_sysfs_memctrl_setup(void) } } } else { - debugf1(KERN_WARNING "__FILE__ %s() error=%d\n", __func__,err); + debugf1("%s() error=%d\n", __func__, err); } return err; @@ -567,7 +567,7 @@ static struct edac_pci_dev_attribute *edac_pci_attr[] = { /* No memory to release */ static void edac_pci_release(struct kobject *kobj) { - debugf1("EDAC PCI: " __FILE__ ": %s()\n", __func__); + debugf1("%s()\n", __func__); } static struct kobj_type ktype_edac_pci = { @@ -591,7 +591,7 @@ static int edac_sysfs_pci_setup(void) { int err; - debugf1("MC: " __FILE__ ": %s()\n", __func__); + debugf1("%s()\n", __func__); memset(&edac_pci_kobj, 0, sizeof(edac_pci_kobj)); @@ -616,7 +616,7 @@ static int edac_sysfs_pci_setup(void) static void edac_sysfs_pci_teardown(void) { #ifndef DISABLE_EDAC_SYSFS - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); kobject_unregister(&edac_pci_kobj); kobject_put(&edac_pci_kobj); @@ -808,7 +808,7 @@ static struct csrowdev_attribute *csrow_attr[] = { /* No memory to release */ static void edac_csrow_instance_release(struct kobject *kobj) { - debugf1("EDAC MC: " __FILE__ ": %s()\n", __func__); + debugf1("%s()\n", __func__); } static struct kobj_type ktype_csrow = { @@ -823,7 +823,7 @@ static int edac_create_csrow_object(struct kobject *edac_mci_kobj, { int err = 0; - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); memset(&csrow->kobj, 0, sizeof(csrow->kobj)); @@ -1066,8 +1066,7 @@ static void edac_mci_instance_release(struct kobject *kobj) struct mem_ctl_info *mci; mci = container_of(kobj,struct mem_ctl_info,edac_mci_kobj); - debugf0("MC: " __FILE__ ": %s() idx=%d calling kfree\n", - __func__, mci->mc_idx); + debugf0("%s() idx=%d calling kfree\n", __func__, mci->mc_idx); kfree(mci); } @@ -1102,7 +1101,7 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) struct csrow_info *csrow; struct kobject *edac_mci_kobj=&mci->edac_mci_kobj; - debugf0("MC: " __FILE__ ": %s() idx=%d\n", __func__, mci->mc_idx); + debugf0("%s() idx=%d\n", __func__, mci->mc_idx); memset(edac_mci_kobj, 0, sizeof(*edac_mci_kobj)); kobject_init(edac_mci_kobj); @@ -1174,7 +1173,7 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) #ifndef DISABLE_EDAC_SYSFS int i; - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); /* remove all csrow kobjects */ for (i = 0; i < mci->nr_csrows; i++) { @@ -1396,7 +1395,7 @@ struct mem_ctl_info *edac_mc_find_mci_by_pdev(struct pci_dev *pdev) struct mem_ctl_info *mci; struct list_head *item; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); list_for_each(item, &mc_devices) { mci = list_entry(item, struct mem_ctl_info, link); @@ -1419,10 +1418,11 @@ static int add_mc_to_global_list (struct mem_ctl_info *mci) insert_before = &mc_devices; } else { if (edac_mc_find_mci_by_pdev(mci->pdev)) { - printk(KERN_WARNING - "EDAC MC: %s (%s) %s %s already assigned %d\n", - mci->pdev->dev.bus_id, pci_name(mci->pdev), - mci->mod_name, mci->ctl_name, mci->mc_idx); + edac_printk(KERN_WARNING, EDAC_MC, + "%s (%s) %s %s already assigned %d\n", + mci->pdev->dev.bus_id, + pci_name(mci->pdev), mci->mod_name, + mci->ctl_name, mci->mc_idx); return 1; } @@ -1468,7 +1468,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) { int rc = 1; - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); #ifdef CONFIG_EDAC_DEBUG if (edac_debug_level >= 3) edac_mc_dump_mci(mci); @@ -1493,19 +1493,15 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) mci->start_time = jiffies; if (edac_create_sysfs_mci_device(mci)) { - printk(KERN_WARNING - "EDAC MC%d: failed to create sysfs device\n", - mci->mc_idx); + edac_mc_printk(mci, KERN_WARNING, + "failed to create sysfs device\n"); /* FIXME - should there be an error code and unwind? */ goto finish; } /* Report action taken */ - printk(KERN_INFO - "EDAC MC%d: Giving out device to %s %s: PCI %s\n", - mci->mc_idx, mci->mod_name, mci->ctl_name, - pci_name(mci->pdev)); - + edac_mc_printk(mci, KERN_INFO, "Giving out device to %s %s: PCI %s\n", + mci->mod_name, mci->ctl_name, pci_name(mci->pdev)); rc = 0; @@ -1547,13 +1543,12 @@ int edac_mc_del_mc(struct mem_ctl_info *mci) { int rc = 1; - debugf0("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__); + debugf0("MC%d: %s()\n", mci->mc_idx, __func__); down(&mem_ctls_mutex); del_mc_from_global_list(mci); - printk(KERN_INFO - "EDAC MC%d: Removed device %d for %s %s: PCI %s\n", - mci->mc_idx, mci->mc_idx, mci->mod_name, mci->ctl_name, - pci_name(mci->pdev)); + edac_printk(KERN_INFO, EDAC_MC, + "Removed device %d for %s %s: PCI %s\n", mci->mc_idx, + mci->mod_name, mci->ctl_name, pci_name(mci->pdev)); rc = 0; up(&mem_ctls_mutex); @@ -1570,7 +1565,7 @@ void edac_mc_scrub_block(unsigned long page, unsigned long offset, void *virt_addr; unsigned long flags = 0; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); /* ECC error page was not in our memory. Ignore it. */ if(!pfn_valid(page)) @@ -1604,8 +1599,7 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, struct csrow_info *csrows = mci->csrows; int row, i; - debugf1("MC%d: " __FILE__ ": %s(): 0x%lx\n", mci->mc_idx, __func__, - page); + debugf1("MC%d: %s(): 0x%lx\n", mci->mc_idx, __func__, page); row = -1; for (i = 0; i < mci->nr_csrows; i++) { @@ -1614,11 +1608,10 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, if (csrow->nr_pages == 0) continue; - debugf3("MC%d: " __FILE__ - ": %s(): first(0x%lx) page(0x%lx)" - " last(0x%lx) mask(0x%lx)\n", mci->mc_idx, - __func__, csrow->first_page, page, - csrow->last_page, csrow->page_mask); + debugf3("MC%d: %s(): first(0x%lx) page(0x%lx) last(0x%lx) " + "mask(0x%lx)\n", mci->mc_idx, __func__, + csrow->first_page, page, csrow->last_page, + csrow->page_mask); if ((page >= csrow->first_page) && (page <= csrow->last_page) && @@ -1630,9 +1623,9 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, } if (row == -1) - printk(KERN_ERR - "EDAC MC%d: could not look up page error address %lx\n", - mci->mc_idx, (unsigned long) page); + edac_mc_printk(mci, KERN_ERR, + "could not look up page error address %lx\n", + (unsigned long) page); return row; } @@ -1650,36 +1643,35 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci, { unsigned long remapped_page; - debugf3("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__); + debugf3("MC%d: %s()\n", mci->mc_idx, __func__); /* FIXME - maybe make panic on INTERNAL ERROR an option */ if (row >= mci->nr_csrows || row < 0) { /* something is wrong */ - printk(KERN_ERR - "EDAC MC%d: INTERNAL ERROR: row out of range (%d >= %d)\n", - mci->mc_idx, row, mci->nr_csrows); + edac_mc_printk(mci, KERN_ERR, + "INTERNAL ERROR: row out of range " + "(%d >= %d)\n", row, mci->nr_csrows); edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR"); return; } if (channel >= mci->csrows[row].nr_channels || channel < 0) { /* something is wrong */ - printk(KERN_ERR - "EDAC MC%d: INTERNAL ERROR: channel out of range " - "(%d >= %d)\n", - mci->mc_idx, channel, mci->csrows[row].nr_channels); + edac_mc_printk(mci, KERN_ERR, + "INTERNAL ERROR: channel out of range " + "(%d >= %d)\n", channel, + mci->csrows[row].nr_channels); edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR"); return; } if (log_ce) /* FIXME - put in DIMM location */ - printk(KERN_WARNING - "EDAC MC%d: CE page 0x%lx, offset 0x%lx," - " grain %d, syndrome 0x%lx, row %d, channel %d," - " label \"%s\": %s\n", mci->mc_idx, - page_frame_number, offset_in_page, - mci->csrows[row].grain, syndrome, row, channel, - mci->csrows[row].channels[channel].label, msg); + edac_mc_printk(mci, KERN_WARNING, + "CE page 0x%lx, offset 0x%lx, grain %d, syndrome " + "0x%lx, row %d, channel %d, label \"%s\": %s\n", + page_frame_number, offset_in_page, + mci->csrows[row].grain, syndrome, row, channel, + mci->csrows[row].channels[channel].label, msg); mci->ce_count++; mci->csrows[row].ce_count++; @@ -1711,9 +1703,8 @@ void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg) { if (log_ce) - printk(KERN_WARNING - "EDAC MC%d: CE - no information available: %s\n", - mci->mc_idx, msg); + edac_mc_printk(mci, KERN_WARNING, + "CE - no information available: %s\n", msg); mci->ce_noinfo_count++; mci->ce_count++; } @@ -1732,14 +1723,14 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci, int chan; int chars; - debugf3("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__); + debugf3("MC%d: %s()\n", mci->mc_idx, __func__); /* FIXME - maybe make panic on INTERNAL ERROR an option */ if (row >= mci->nr_csrows || row < 0) { /* something is wrong */ - printk(KERN_ERR - "EDAC MC%d: INTERNAL ERROR: row out of range (%d >= %d)\n", - mci->mc_idx, row, mci->nr_csrows); + edac_mc_printk(mci, KERN_ERR, + "INTERNAL ERROR: row out of range " + "(%d >= %d)\n", row, mci->nr_csrows); edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR"); return; } @@ -1757,11 +1748,11 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci, } if (log_ue) - printk(KERN_EMERG - "EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, row %d," - " labels \"%s\": %s\n", mci->mc_idx, - page_frame_number, offset_in_page, - mci->csrows[row].grain, row, labels, msg); + edac_mc_printk(mci, KERN_EMERG, + "UE page 0x%lx, offset 0x%lx, grain %d, row %d, " + "labels \"%s\": %s\n", page_frame_number, + offset_in_page, mci->csrows[row].grain, row, labels, + msg); if (panic_on_ue) panic @@ -1784,9 +1775,8 @@ void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, panic("EDAC MC%d: Uncorrected Error", mci->mc_idx); if (log_ue) - printk(KERN_WARNING - "EDAC MC%d: UE - no information available: %s\n", - mci->mc_idx, msg); + edac_mc_printk(mci, KERN_WARNING, + "UE - no information available: %s\n", msg); mci->ue_noinfo_count++; mci->ue_count++; } @@ -1856,25 +1846,22 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev) /* check the status reg for errors */ if (status) { if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) - printk(KERN_CRIT - "EDAC PCI- " + edac_printk(KERN_CRIT, EDAC_PCI, "Signaled System Error on %s\n", - pci_name (dev)); + pci_name(dev)); if (status & (PCI_STATUS_PARITY)) { - printk(KERN_CRIT - "EDAC PCI- " + edac_printk(KERN_CRIT, EDAC_PCI, "Master Data Parity Error on %s\n", - pci_name (dev)); + pci_name(dev)); atomic_inc(&pci_parity_count); } if (status & (PCI_STATUS_DETECTED_PARITY)) { - printk(KERN_CRIT - "EDAC PCI- " + edac_printk(KERN_CRIT, EDAC_PCI, "Detected Parity Error on %s\n", - pci_name (dev)); + pci_name(dev)); atomic_inc(&pci_parity_count); } @@ -1895,25 +1882,22 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev) /* check the secondary status reg for errors */ if (status) { if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) - printk(KERN_CRIT - "EDAC PCI-Bridge- " + edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " "Signaled System Error on %s\n", - pci_name (dev)); + pci_name(dev)); if (status & (PCI_STATUS_PARITY)) { - printk(KERN_CRIT - "EDAC PCI-Bridge- " - "Master Data Parity Error on %s\n", - pci_name (dev)); + edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " + "Master Data Parity Error on " + "%s\n", pci_name(dev)); atomic_inc(&pci_parity_count); } if (status & (PCI_STATUS_DETECTED_PARITY)) { - printk(KERN_CRIT - "EDAC PCI-Bridge- " + edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " "Detected Parity Error on %s\n", - pci_name (dev)); + pci_name(dev)); atomic_inc(&pci_parity_count); } @@ -1992,7 +1976,7 @@ static void do_pci_parity_check(void) unsigned long flags; int before_count; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); if (!check_pci_parity) return; @@ -2050,7 +2034,7 @@ static inline void check_mc_devices (void) struct list_head *item; struct mem_ctl_info *mci; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); /* during poll, have interrupts off */ local_irq_save(flags); @@ -2076,10 +2060,8 @@ static inline void check_mc_devices (void) */ static void do_edac_check(void) { - debugf3("MC: " __FILE__ ": %s()\n", __func__); - + debugf3("%s()\n", __func__); check_mc_devices(); - do_pci_parity_check(); } @@ -2102,7 +2084,7 @@ static int edac_kernel_thread(void *arg) */ static int __init edac_mc_init(void) { - printk(KERN_INFO "MC: " __FILE__ " version " EDAC_MC_VERSION "\n"); + edac_printk(KERN_INFO, EDAC_MC, EDAC_MC_VERSION "\n"); /* * Harvest and clear any boot/initialization PCI parity errors @@ -2118,14 +2100,16 @@ static int __init edac_mc_init(void) /* Create the MC sysfs entires */ if (edac_sysfs_memctrl_setup()) { - printk(KERN_ERR "EDAC MC: Error initializing sysfs code\n"); + edac_printk(KERN_ERR, EDAC_MC, + "Error initializing sysfs code\n"); return -ENODEV; } /* Create the PCI parity sysfs entries */ if (edac_sysfs_pci_setup()) { edac_sysfs_memctrl_teardown(); - printk(KERN_ERR "EDAC PCI: Error initializing sysfs code\n"); + edac_printk(KERN_ERR, EDAC_MC, + "EDAC PCI: Error initializing sysfs code\n"); return -ENODEV; } @@ -2148,7 +2132,7 @@ static int __init edac_mc_init(void) */ static void __exit edac_mc_exit(void) { - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); kthread_stop(edac_thread); diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h index 75ecf484a43..4bd8375a8d7 100644 --- a/drivers/edac/edac_mc.h +++ b/drivers/edac/edac_mc.h @@ -43,10 +43,29 @@ #define PAGES_TO_MiB( pages ) ( ( pages ) << ( PAGE_SHIFT - 20 ) ) #endif +#define edac_printk(level, prefix, fmt, arg...) \ + printk(level "EDAC " prefix ": " fmt, ##arg) + +#define edac_mc_printk(mci, level, fmt, arg...) \ + printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg) + +#define edac_mc_chipset_printk(mci, level, prefix, fmt, arg...) \ + printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg) + +/* prefixes for edac_printk() and edac_mc_printk() */ +#define EDAC_MC "MC" +#define EDAC_PCI "PCI" +#define EDAC_DEBUG "DEBUG" + #ifdef CONFIG_EDAC_DEBUG extern int edac_debug_level; -#define edac_debug_printk(level, fmt, args...) \ -do { if (level <= edac_debug_level) printk(KERN_DEBUG fmt, ##args); } while(0) + +#define edac_debug_printk(level, fmt, arg...) \ + do { \ + if (level <= edac_debug_level) \ + edac_printk(KERN_DEBUG, EDAC_DEBUG, fmt, ##arg); \ + } while(0) + #define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ ) #define debugf1( ... ) edac_debug_printk(1, __VA_ARGS__ ) #define debugf2( ... ) edac_debug_printk(2, __VA_ARGS__ ) diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c index 52596e75f9c..fa9ab84fa5c 100644 --- a/drivers/edac/i82860_edac.c +++ b/drivers/edac/i82860_edac.c @@ -19,6 +19,14 @@ #include "edac_mc.h" +#define i82860_printk(level, fmt, arg...) \ + edac_printk(level, "i82860", fmt, ##arg) + + +#define i82860_mc_printk(mci, level, fmt, arg...) \ + edac_mc_chipset_printk(mci, level, "i82860", fmt, ##arg) + + #ifndef PCI_DEVICE_ID_INTEL_82860_0 #define PCI_DEVICE_ID_INTEL_82860_0 0x2531 #endif /* PCI_DEVICE_ID_INTEL_82860_0 */ @@ -117,7 +125,7 @@ static void i82860_check(struct mem_ctl_info *mci) { struct i82860_error_info info; - debugf1("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__); + debugf1("MC%d: %s()\n", mci->mc_idx, __func__); i82860_get_error_info(mci, &info); i82860_process_error_info(mci, &info, 1); } @@ -143,7 +151,7 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) if (!mci) return -ENOMEM; - debugf3("MC: " __FILE__ ": %s(): init mci\n", __func__); + debugf3("%s(): init mci\n", __func__); mci->pdev = pdev; mci->mtype_cap = MEM_FLAG_DDR; @@ -179,8 +187,8 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) cumul_size = (value & I82860_GBA_MASK) << (I82860_GBA_SHIFT - PAGE_SHIFT); - debugf3("MC: " __FILE__ ": %s(): (%d) cumul_size 0x%x\n", - __func__, index, cumul_size); + debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, + cumul_size); if (cumul_size == last_cumul_size) continue; /* not populated */ @@ -198,13 +206,11 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) pci_write_bits16(mci->pdev, I82860_ERRSTS, 0x0003, 0x0003); if (edac_mc_add_mc(mci)) { - debugf3("MC: " __FILE__ - ": %s(): failed edac_mc_add_mc()\n", - __func__); + debugf3("%s(): failed edac_mc_add_mc()\n", __func__); edac_mc_free(mci); } else { /* get this far and it's successful */ - debugf3("MC: " __FILE__ ": %s(): success\n", __func__); + debugf3("%s(): success\n", __func__); rc = 0; } return rc; @@ -216,9 +222,9 @@ static int __devinit i82860_init_one(struct pci_dev *pdev, { int rc; - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); - printk(KERN_INFO "i82860 init one\n"); + i82860_printk(KERN_INFO, "i82860 init one\n"); if(pci_enable_device(pdev) < 0) return -EIO; rc = i82860_probe1(pdev, ent->driver_data); @@ -231,7 +237,7 @@ static void __devexit i82860_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; - debugf0(__FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); mci = edac_mc_find_mci_by_pdev(pdev); if ((mci != NULL) && (edac_mc_del_mc(mci) == 0)) @@ -257,7 +263,7 @@ static int __init i82860_init(void) { int pci_rc; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); if ((pci_rc = pci_register_driver(&i82860_driver)) < 0) return pci_rc; @@ -281,7 +287,7 @@ static int __init i82860_init(void) static void __exit i82860_exit(void) { - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); pci_unregister_driver(&i82860_driver); if (!i82860_registered) { diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index 1991f94af75..0e22c66ee36 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c @@ -26,6 +26,14 @@ #include "edac_mc.h" +#define i82875p_printk(level, fmt, arg...) \ + edac_printk(level, "i82875p", fmt, ##arg) + + +#define i82875p_mc_printk(mci, level, fmt, arg...) \ + edac_mc_chipset_printk(mci, level, "i82875p", fmt, ##arg) + + #ifndef PCI_DEVICE_ID_INTEL_82875_0 #define PCI_DEVICE_ID_INTEL_82875_0 0x2578 #endif /* PCI_DEVICE_ID_INTEL_82875_0 */ @@ -254,7 +262,7 @@ static void i82875p_check(struct mem_ctl_info *mci) { struct i82875p_error_info info; - debugf1("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__); + debugf1("MC%d: %s()\n", mci->mc_idx, __func__); i82875p_get_error_info(mci, &info); i82875p_process_error_info(mci, &info, 1); } @@ -279,7 +287,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) u32 nr_chans; u32 drc_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */ - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); ovrfl_pdev = pci_find_device(PCI_VEND_DEV(INTEL, 82875_6), NULL); @@ -298,16 +306,16 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) } #ifdef CONFIG_PROC_FS if (!ovrfl_pdev->procent && pci_proc_attach_device(ovrfl_pdev)) { - printk(KERN_ERR "MC: " __FILE__ - ": %s(): Failed to attach overflow device\n", - __func__); + i82875p_printk(KERN_ERR, + "%s(): Failed to attach overflow device\n", + __func__); goto fail; } #endif /* CONFIG_PROC_FS */ if (pci_enable_device(ovrfl_pdev)) { - printk(KERN_ERR "MC: " __FILE__ - ": %s(): Failed to enable overflow device\n", - __func__); + i82875p_printk(KERN_ERR, + "%s(): Failed to enable overflow device\n", + __func__); goto fail; } @@ -321,8 +329,8 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) pci_resource_len(ovrfl_pdev, 0)); if (!ovrfl_window) { - printk(KERN_ERR "MC: " __FILE__ - ": %s(): Failed to ioremap bar6\n", __func__); + i82875p_printk(KERN_ERR, "%s(): Failed to ioremap bar6\n", + __func__); goto fail; } @@ -340,7 +348,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) goto fail; } - debugf3("MC: " __FILE__ ": %s(): init mci\n", __func__); + debugf3("%s(): init mci\n", __func__); mci->pdev = pdev; mci->mtype_cap = MEM_FLAG_DDR; @@ -355,7 +363,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) mci->edac_check = i82875p_check; mci->ctl_page_to_phys = NULL; - debugf3("MC: " __FILE__ ": %s(): init pvt\n", __func__); + debugf3("%s(): init pvt\n", __func__); pvt = (struct i82875p_pvt *) mci->pvt_info; pvt->ovrfl_pdev = ovrfl_pdev; @@ -374,8 +382,8 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) value = readb(ovrfl_window + I82875P_DRB + index); cumul_size = value << (I82875P_DRB_SHIFT - PAGE_SHIFT); - debugf3("MC: " __FILE__ ": %s(): (%d) cumul_size 0x%x\n", - __func__, index, cumul_size); + debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, + cumul_size); if (cumul_size == last_cumul_size) continue; /* not populated */ @@ -393,13 +401,12 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) pci_write_bits16(mci->pdev, I82875P_ERRSTS, 0x0081, 0x0081); if (edac_mc_add_mc(mci)) { - debugf3("MC: " __FILE__ - ": %s(): failed edac_mc_add_mc()\n", __func__); + debugf3("%s(): failed edac_mc_add_mc()\n", __func__); goto fail; } /* get this far and it's successful */ - debugf3("MC: " __FILE__ ": %s(): success\n", __func__); + debugf3("%s(): success\n", __func__); return 0; fail: @@ -425,9 +432,9 @@ static int __devinit i82875p_init_one(struct pci_dev *pdev, { int rc; - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); - printk(KERN_INFO "i82875p init one\n"); + i82875p_printk(KERN_INFO, "i82875p init one\n"); if(pci_enable_device(pdev) < 0) return -EIO; rc = i82875p_probe1(pdev, ent->driver_data); @@ -442,7 +449,7 @@ static void __devexit i82875p_remove_one(struct pci_dev *pdev) struct mem_ctl_info *mci; struct i82875p_pvt *pvt = NULL; - debugf0(__FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); if ((mci = edac_mc_find_mci_by_pdev(pdev)) == NULL) return; @@ -487,7 +494,7 @@ static int __init i82875p_init(void) { int pci_rc; - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); pci_rc = pci_register_driver(&i82875p_driver); if (pci_rc < 0) return pci_rc; @@ -513,7 +520,7 @@ static int __init i82875p_init(void) static void __exit i82875p_exit(void) { - debugf3("MC: " __FILE__ ": %s()\n", __func__); + debugf3("%s()\n", __func__); pci_unregister_driver(&i82875p_driver); if (!i82875p_registered) { diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c index e90892831b9..27d16dc2f11 100644 --- a/drivers/edac/r82600_edac.c +++ b/drivers/edac/r82600_edac.c @@ -26,6 +26,12 @@ #include "edac_mc.h" +#define r82600_printk(level, fmt, arg...) \ + edac_printk(level, "r82600", fmt, ##arg) + +#define r82600_mc_printk(mci, level, fmt, arg...) \ + edac_mc_chipset_printk(mci, level, "r82600", fmt, ##arg) + /* Radisys say "The 82600 integrates a main memory SDRAM controller that * supports up to four banks of memory. The four banks can support a mix of * sizes of 64 bit wide (72 bits with ECC) Synchronous DRAM (SDRAM) DIMMs, @@ -196,7 +202,7 @@ static void r82600_check(struct mem_ctl_info *mci) { struct r82600_error_info info; - debugf1("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__); + debugf1("MC%d: %s()\n", mci->mc_idx, __func__); r82600_get_error_info(mci, &info); r82600_process_error_info(mci, &info, 1); } @@ -215,7 +221,7 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) u32 row_high_limit_last = 0; u32 eap_init_bits; - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); pci_read_config_byte(pdev, R82600_DRAMC, &dramcr); @@ -226,11 +232,10 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) scrub_disabled = eapr & BIT(31); sdram_refresh_rate = dramcr & (BIT(0) | BIT(1)); - debugf2("MC: " __FILE__ ": %s(): sdram refresh rate = %#0x\n", - __func__, sdram_refresh_rate); + debugf2("%s(): sdram refresh rate = %#0x\n", __func__, + sdram_refresh_rate); - debugf2("MC: " __FILE__ ": %s(): DRAMC register = %#0x\n", __func__, - dramcr); + debugf2("%s(): DRAMC register = %#0x\n", __func__, dramcr); mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS); @@ -239,7 +244,7 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) goto fail; } - debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); + debugf0("%s(): mci = %p\n", __func__, mci); mci->pdev = pdev; mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR; @@ -255,9 +260,8 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; if (ecc_on) { if (scrub_disabled) - debugf3("MC: " __FILE__ ": %s(): mci = %p - " - "Scrubbing disabled! EAP: %#0x\n", __func__, - mci, eapr); + debugf3("%s(): mci = %p - Scrubbing disabled! EAP: " + "%#0x\n", __func__, mci, eapr); } else mci->edac_cap = EDAC_FLAG_NONE; @@ -276,16 +280,15 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) /* find the DRAM Chip Select Base address and mask */ pci_read_config_byte(mci->pdev, R82600_DRBA + index, &drbar); - debugf1("MC%d: " __FILE__ ": %s() Row=%d DRBA = %#0x\n", - mci->mc_idx, __func__, index, drbar); + debugf1("MC%d: %s() Row=%d DRBA = %#0x\n", mci->mc_idx, + __func__, index, drbar); row_high_limit = ((u32) drbar << 24); /* row_high_limit = ((u32)drbar << 24) | 0xffffffUL; */ - debugf1("MC%d: " __FILE__ ": %s() Row=%d, " - "Boundry Address=%#0x, Last = %#0x \n", - mci->mc_idx, __func__, index, row_high_limit, - row_high_limit_last); + debugf1("MC%d: %s() Row=%d, Boundry Address=%#0x, Last = " + "%#0x \n", mci->mc_idx, __func__, index, + row_high_limit, row_high_limit_last); /* Empty row [p.57] */ if (row_high_limit == row_high_limit_last) @@ -312,8 +315,7 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) /* FIXME should we? */ if (edac_mc_add_mc(mci)) { - debugf3("MC: " __FILE__ - ": %s(): failed edac_mc_add_mc()\n", __func__); + debugf3("%s(): failed edac_mc_add_mc()\n", __func__); goto fail; } @@ -325,14 +327,14 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) eap_init_bits = BIT(0) & BIT(1); if (disable_hardware_scrub) { eap_init_bits |= BIT(31); - debugf3("MC: " __FILE__ ": %s(): Disabling Hardware Scrub " - "(scrub on error)\n", __func__); + debugf3("%s(): Disabling Hardware Scrub (scrub on error)\n", + __func__); } pci_write_bits32(mci->pdev, R82600_EAP, eap_init_bits, eap_init_bits); - debugf3("MC: " __FILE__ ": %s(): success\n", __func__); + debugf3("%s(): success\n", __func__); return 0; fail: @@ -346,7 +348,7 @@ fail: static int __devinit r82600_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); /* don't need to call pci_device_enable() */ return r82600_probe1(pdev, ent->driver_data); @@ -357,7 +359,7 @@ static void __devexit r82600_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; - debugf0(__FILE__ ": %s()\n", __func__); + debugf0("%s()\n", __func__); if (((mci = edac_mc_find_mci_by_pdev(pdev)) != NULL) && !edac_mc_del_mc(mci)) -- cgit v1.2.3-70-g09d2 From 749ede57443b2a7ede2db105145f21047efcea6a Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Sun, 26 Mar 2006 01:38:45 -0800 Subject: [PATCH] EDAC: cleanup code for clearing initial errors Fix xxx_probe1() functions so they call xxx_get_error_info() functions to clear initial errors. This is simpler and cleaner than duplicating the low-level code for accessing PCI config space. Signed-off-by: David S. Peterson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/amd76x_edac.c | 5 ++--- drivers/edac/e752x_edac.c | 22 ++-------------------- drivers/edac/e7xxx_edac.c | 5 ++--- drivers/edac/edac_mc.c | 3 --- drivers/edac/i82860_edac.c | 4 ++-- drivers/edac/i82875p_edac.c | 4 ++-- drivers/edac/r82600_edac.c | 14 +++----------- 7 files changed, 13 insertions(+), 44 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c index 6b7a441f048..821c252d414 100644 --- a/drivers/edac/amd76x_edac.c +++ b/drivers/edac/amd76x_edac.c @@ -211,6 +211,7 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) }; u32 ems; u32 ems_mode; + struct amd76x_error_info discard; debugf0("%s()\n", __func__); @@ -270,9 +271,7 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) csrow->edac_mode = ems_modes[ems_mode]; } - /* clear counters */ - pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS, (u32) (0x3 << 8), - (u32) (0x3 << 8)); + amd76x_get_error_info(mci, &discard); /* clear counters */ if (edac_mc_add_mc(mci)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index f31725a55e5..24446542d8d 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c @@ -747,8 +747,6 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) int rc = -ENODEV; int index; u16 pci_data; - u32 stat32; - u16 stat16; u8 stat8; struct mem_ctl_info *mci = NULL; struct e752x_pvt *pvt = NULL; @@ -760,6 +758,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) u32 dra; unsigned long last_cumul_size; struct pci_dev *dev = NULL; + struct e752x_error_info discard; debugf0("%s(): mci\n", __func__); debugf0("Starting Probe1\n"); @@ -938,24 +937,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) pci_write_config_byte(dev, E752X_DRAM_ERRMASK, 0x00); pci_write_config_byte(dev, E752X_DRAM_SMICMD, 0x00); /* clear other MCH errors */ - pci_read_config_dword(dev, E752X_FERR_GLOBAL, &stat32); - pci_write_config_dword(dev, E752X_FERR_GLOBAL, stat32); - pci_read_config_dword(dev, E752X_NERR_GLOBAL, &stat32); - pci_write_config_dword(dev, E752X_NERR_GLOBAL, stat32); - pci_read_config_byte(dev, E752X_HI_FERR, &stat8); - pci_write_config_byte(dev, E752X_HI_FERR, stat8); - pci_read_config_byte(dev, E752X_HI_NERR, &stat8); - pci_write_config_byte(dev, E752X_HI_NERR, stat8); - pci_read_config_dword(dev, E752X_SYSBUS_FERR, &stat32); - pci_write_config_dword(dev, E752X_SYSBUS_FERR, stat32); - pci_read_config_byte(dev, E752X_BUF_FERR, &stat8); - pci_write_config_byte(dev, E752X_BUF_FERR, stat8); - pci_read_config_byte(dev, E752X_BUF_NERR, &stat8); - pci_write_config_byte(dev, E752X_BUF_NERR, stat8); - pci_read_config_word(dev, E752X_DRAM_FERR, &stat16); - pci_write_config_word(dev, E752X_DRAM_FERR, stat16); - pci_read_config_word(dev, E752X_DRAM_NERR, &stat16); - pci_write_config_word(dev, E752X_DRAM_NERR, stat16); + e752x_get_error_info(mci, &discard); /* get this far and it's successful */ debugf3("%s(): success\n", __func__); diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c index ec6eb77edae..8b0da35ae47 100644 --- a/drivers/edac/e7xxx_edac.c +++ b/drivers/edac/e7xxx_edac.c @@ -357,7 +357,7 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) int drc_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */ u32 dra; unsigned long last_cumul_size; - + struct e7xxx_error_info discard; debugf0("%s(): mci\n", __func__); @@ -470,8 +470,7 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) pvt->tolm, pvt->remapbase, pvt->remaplimit); /* clear any pending errors, or initial state bits */ - pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_FERR, 0x03, 0x03); - pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_NERR, 0x03, 0x03); + e7xxx_get_error_info(mci, &discard); if (edac_mc_add_mc(mci) != 0) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 499ac90ad67..eac09cc86aa 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -2095,9 +2095,6 @@ static int __init edac_mc_init(void) */ clear_pci_parity_errors(); - /* perform check for first time to harvest boot leftovers */ - do_edac_check(); - /* Create the MC sysfs entires */ if (edac_sysfs_memctrl_setup()) { edac_printk(KERN_ERR, EDAC_MC, diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c index e832778fc60..942129df021 100644 --- a/drivers/edac/i82860_edac.c +++ b/drivers/edac/i82860_edac.c @@ -134,6 +134,7 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) int index; struct mem_ctl_info *mci = NULL; unsigned long last_cumul_size; + struct i82860_error_info discard; u16 mchcfg_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */ @@ -200,8 +201,7 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE; } - /* clear counters */ - pci_write_bits16(mci->pdev, I82860_ERRSTS, 0x0003, 0x0003); + i82860_get_error_info(mci, &discard); /* clear counters */ if (edac_mc_add_mc(mci)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index c521178183d..40ba2be6169 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c @@ -286,6 +286,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) u32 drc_chan; /* Number of channels 0=1chan,1=2chan */ u32 nr_chans; u32 drc_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */ + struct i82875p_error_info discard; debugf0("%s()\n", __func__); @@ -397,8 +398,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) csrow->edac_mode = drc_ddim ? EDAC_SECDED : EDAC_NONE; } - /* clear counters */ - pci_write_bits16(mci->pdev, I82875P_ERRSTS, 0x0081, 0x0081); + i82875p_get_error_info(mci, &discard); /* clear counters */ if (edac_mc_add_mc(mci)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c index ac1359828e7..787a7652c7e 100644 --- a/drivers/edac/r82600_edac.c +++ b/drivers/edac/r82600_edac.c @@ -219,7 +219,7 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) u32 scrub_disabled; u32 sdram_refresh_rate; u32 row_high_limit_last = 0; - u32 eap_init_bits; + struct r82600_error_info discard; debugf0("%s()\n", __func__); @@ -311,8 +311,7 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) row_high_limit_last = row_high_limit; } - /* clear counters */ - /* FIXME should we? */ + r82600_get_error_info(mci, &discard); /* clear counters */ if (edac_mc_add_mc(mci)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); @@ -321,19 +320,12 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) /* get this far and it's successful */ - /* Clear error flags to allow next error to be reported [p.62] */ - /* Test systems seem to always have the UE flag raised on boot */ - - eap_init_bits = BIT(0) & BIT(1); if (disable_hardware_scrub) { - eap_init_bits |= BIT(31); debugf3("%s(): Disabling Hardware Scrub (scrub on error)\n", __func__); + pci_write_bits32(mci->pdev, R82600_EAP, BIT(31), BIT(31)); } - pci_write_bits32(mci->pdev, R82600_EAP, eap_init_bits, - eap_init_bits); - debugf3("%s(): success\n", __func__); return 0; -- cgit v1.2.3-70-g09d2 From a1d03fcc1399b1e23922bcc3af1772b128aa6e93 Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Sun, 26 Mar 2006 01:38:46 -0800 Subject: [PATCH] EDAC: edac_mc_add_mc fix [1/2] This is part 1 of a 2-part patch set. The code changes are split into two parts to make the patches more readable. Move complete_mc_list_del() and del_mc_from_global_list() so we can call del_mc_from_global_list() from edac_mc_add_mc() without forward declarations. Perhaps using forward declarations would be better? I'm doing things this way because the rest of the code is missing them. Signed-off-by: David S. Peterson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/edac_mc.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index eac09cc86aa..226d4fdb15f 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -1451,6 +1451,24 @@ static int add_mc_to_global_list (struct mem_ctl_info *mci) } +static void complete_mc_list_del (struct rcu_head *head) +{ + struct mem_ctl_info *mci; + + mci = container_of(head, struct mem_ctl_info, rcu); + INIT_LIST_HEAD(&mci->link); + complete(&mci->complete); +} + + +static void del_mc_from_global_list (struct mem_ctl_info *mci) +{ + list_del_rcu(&mci->link); + init_completion(&mci->complete); + call_rcu(&mci->rcu, complete_mc_list_del); + wait_for_completion(&mci->complete); +} + EXPORT_SYMBOL(edac_mc_add_mc); @@ -1511,24 +1529,6 @@ finish: } - -static void complete_mc_list_del (struct rcu_head *head) -{ - struct mem_ctl_info *mci; - - mci = container_of(head, struct mem_ctl_info, rcu); - INIT_LIST_HEAD(&mci->link); - complete(&mci->complete); -} - -static void del_mc_from_global_list (struct mem_ctl_info *mci) -{ - list_del_rcu(&mci->link); - init_completion(&mci->complete); - call_rcu(&mci->rcu, complete_mc_list_del); - wait_for_completion(&mci->complete); -} - EXPORT_SYMBOL(edac_mc_del_mc); /** -- cgit v1.2.3-70-g09d2 From 028a7b6d3d9fa2cc41d76d45575345cca8d00a4c Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Sun, 26 Mar 2006 01:38:47 -0800 Subject: [PATCH] EDAC: edac_mc_add_mc fix [2/2] This is part 2 of a 2-part patch set. Fix edac_mc_add_mc() so it cleans up properly if call to edac_create_sysfs_mci_device() fails. Signed-off-by: David S. Peterson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/edac_mc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 226d4fdb15f..d37a4c4a312 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -1484,8 +1484,6 @@ EXPORT_SYMBOL(edac_mc_add_mc); /* FIXME - should a warning be printed if no error detection? correction? */ int edac_mc_add_mc(struct mem_ctl_info *mci) { - int rc = 1; - debugf0("%s()\n", __func__); #ifdef CONFIG_EDAC_DEBUG if (edac_debug_level >= 3) @@ -1505,7 +1503,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) down(&mem_ctls_mutex); if (add_mc_to_global_list(mci)) - goto finish; + goto fail0; /* set load time so that error rate can be tracked */ mci->start_time = jiffies; @@ -1513,19 +1511,22 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) if (edac_create_sysfs_mci_device(mci)) { edac_mc_printk(mci, KERN_WARNING, "failed to create sysfs device\n"); - /* FIXME - should there be an error code and unwind? */ - goto finish; + goto fail1; } /* Report action taken */ edac_mc_printk(mci, KERN_INFO, "Giving out device to %s %s: PCI %s\n", mci->mod_name, mci->ctl_name, pci_name(mci->pdev)); - rc = 0; + up(&mem_ctls_mutex); + return 0; -finish: +fail1: + del_mc_from_global_list(mci); + +fail0: up(&mem_ctls_mutex); - return rc; + return 1; } -- cgit v1.2.3-70-g09d2 From 6e5a8748507dea83386d1d76c58aeaed1ff5a1ec Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Sun, 26 Mar 2006 01:38:48 -0800 Subject: [PATCH] EDAC: kobject_init/kobject_put fixes - Remove calls to kobject_init(). These are unnecessary because kobject_register() calls kobject_init(). - Remove extra calls to kobject_put(). When we call kobject_unregister(), this releases our reference to the kobject. The extra calls to kobject_put() may cause the reference count to drop to 0 while a kobject is still in use. Signed-off-by: David S. Peterson Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/edac_mc.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index d37a4c4a312..e6ecc7da38a 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -278,8 +278,6 @@ static int edac_sysfs_memctrl_setup(void) if (!err) { /* Init the MC's kobject */ memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); - kobject_init(&edac_memctrl_kobj); - edac_memctrl_kobj.parent = &edac_class.kset.kobj; edac_memctrl_kobj.ktype = &ktype_memctrl; @@ -314,9 +312,6 @@ static void edac_sysfs_memctrl_teardown(void) /* Unregister the MC's kobject */ kobject_unregister(&edac_memctrl_kobj); - /* release the master edac mc kobject */ - kobject_put(&edac_memctrl_kobj); - /* Unregister the 'edac' object */ sysdev_class_unregister(&edac_class); #endif /* DISABLE_EDAC_SYSFS */ @@ -594,8 +589,6 @@ static int edac_sysfs_pci_setup(void) debugf1("%s()\n", __func__); memset(&edac_pci_kobj, 0, sizeof(edac_pci_kobj)); - - kobject_init(&edac_pci_kobj); edac_pci_kobj.parent = &edac_class.kset.kobj; edac_pci_kobj.ktype = &ktype_edac_pci; @@ -619,7 +612,6 @@ static void edac_sysfs_pci_teardown(void) debugf0("%s()\n", __func__); kobject_unregister(&edac_pci_kobj); - kobject_put(&edac_pci_kobj); #endif } @@ -829,7 +821,6 @@ static int edac_create_csrow_object(struct kobject *edac_mci_kobj, /* generate ..../edac/mc/mc/csrow */ - kobject_init(&csrow->kobj); csrow->kobj.parent = edac_mci_kobj; csrow->kobj.ktype = &ktype_csrow; @@ -1104,7 +1095,6 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) debugf0("%s() idx=%d\n", __func__, mci->mc_idx); memset(edac_mci_kobj, 0, sizeof(*edac_mci_kobj)); - kobject_init(edac_mci_kobj); /* set the name of the mc object */ err = kobject_set_name(edac_mci_kobj,"mc%d",mci->mc_idx); @@ -1123,10 +1113,8 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) /* create a symlink for the device */ err = sysfs_create_link(edac_mci_kobj, &mci->pdev->dev.kobj, EDAC_DEVICE_SYMLINK); - if (err) { - kobject_unregister(edac_mci_kobj); - return err; - } + if (err) + goto fail0; /* Make directories for each CSROW object * under the mc kobject @@ -1139,7 +1127,7 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) if (csrow->nr_pages > 0) { err = edac_create_csrow_object(edac_mci_kobj,csrow,i); if (err) - goto fail; + goto fail1; } } @@ -1150,16 +1138,14 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) /* CSROW error: backout what has already been registered, */ -fail: +fail1: for ( i--; i >= 0; i--) { - if (csrow->nr_pages > 0) { + if (csrow->nr_pages > 0) kobject_unregister(&mci->csrows[i].kobj); - kobject_put(&mci->csrows[i].kobj); - } } +fail0: kobject_unregister(edac_mci_kobj); - kobject_put(edac_mci_kobj); return err; } @@ -1177,16 +1163,13 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) /* remove all csrow kobjects */ for (i = 0; i < mci->nr_csrows; i++) { - if (mci->csrows[i].nr_pages > 0) { + if (mci->csrows[i].nr_pages > 0) kobject_unregister(&mci->csrows[i].kobj); - kobject_put(&mci->csrows[i].kobj); - } } sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK); kobject_unregister(&mci->edac_mci_kobj); - kobject_put(&mci->edac_mci_kobj); #endif /* DISABLE_EDAC_SYSFS */ } -- cgit v1.2.3-70-g09d2 From 472678ebd30d87cbe8d97562dcc0e46d1076040f Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Sun, 26 Mar 2006 01:38:49 -0800 Subject: [PATCH] EDAC: kobject/sysfs fixes - After we unregister a kobject, wait for our kobject release method to call complete(). This causes us to wait until the kobject reference count reaches 0. Otherwise, a task accessing the EDAC sysfs interface can hold the reference count above 0 until after the EDAC module has been unloaded. When the reference count finally drops to 0, this will result in an attempt to call our release method inside the EDAC module after the module has already been unloaded. This isn't the best fix, since a process can get stuck sleeping forever uninterruptibly if the user does the following: rmmod my_module < /sys/my_sysfs/file I'll go back and implement a better fix later. However this should be ok for now. - Call edac_remove_sysfs_mci_device() from edac_mc_del_mc() rather than from edac_mc_free(). Since edac_mc_add_mc() calls edac_create_sysfs_mci_device(), edac_mc_del_mc() should call edac_remove_sysfs_mci_device(). Signed-off-by: David S. Peterson Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/edac_mc.c | 76 ++++++++++++++++++++++++++------------------------ drivers/edac/edac_mc.h | 9 ++---- 2 files changed, 42 insertions(+), 43 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index e6ecc7da38a..7ee9419234a 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -139,6 +139,12 @@ static struct sysdev_class edac_class = { static struct kobject edac_memctrl_kobj; static struct kobject edac_pci_kobj; +/* We use these to wait for the reference counts on edac_memctrl_kobj and + * edac_pci_kobj to reach 0. + */ +static struct completion edac_memctrl_kobj_complete; +static struct completion edac_pci_kobj_complete; + /* * /sys/devices/system/edac/mc; * data structures and methods @@ -244,6 +250,7 @@ static struct memctrl_dev_attribute *memctrl_attr[] = { static void edac_memctrl_master_release(struct kobject *kobj) { debugf1("%s()\n", __func__); + complete(&edac_memctrl_kobj_complete); } static struct kobj_type ktype_memctrl = { @@ -309,8 +316,12 @@ static void edac_sysfs_memctrl_teardown(void) #ifndef DISABLE_EDAC_SYSFS debugf0("MC: " __FILE__ ": %s()\n", __func__); - /* Unregister the MC's kobject */ + /* Unregister the MC's kobject and wait for reference count to reach + * 0. + */ + init_completion(&edac_memctrl_kobj_complete); kobject_unregister(&edac_memctrl_kobj); + wait_for_completion(&edac_memctrl_kobj_complete); /* Unregister the 'edac' object */ sysdev_class_unregister(&edac_class); @@ -563,6 +574,7 @@ static struct edac_pci_dev_attribute *edac_pci_attr[] = { static void edac_pci_release(struct kobject *kobj) { debugf1("%s()\n", __func__); + complete(&edac_pci_kobj_complete); } static struct kobj_type ktype_edac_pci = { @@ -610,8 +622,9 @@ static void edac_sysfs_pci_teardown(void) { #ifndef DISABLE_EDAC_SYSFS debugf0("%s()\n", __func__); - + init_completion(&edac_pci_kobj_complete); kobject_unregister(&edac_pci_kobj); + wait_for_completion(&edac_pci_kobj_complete); #endif } @@ -800,7 +813,11 @@ static struct csrowdev_attribute *csrow_attr[] = { /* No memory to release */ static void edac_csrow_instance_release(struct kobject *kobj) { + struct csrow_info *cs; + debugf1("%s()\n", __func__); + cs = container_of(kobj, struct csrow_info, kobj); + complete(&cs->kobj_complete); } static struct kobj_type ktype_csrow = { @@ -1055,11 +1072,10 @@ static struct mcidev_attribute *mci_attr[] = { static void edac_mci_instance_release(struct kobject *kobj) { struct mem_ctl_info *mci; - mci = container_of(kobj,struct mem_ctl_info,edac_mci_kobj); - debugf0("%s() idx=%d calling kfree\n", __func__, mci->mc_idx); - - kfree(mci); + mci = to_mci(kobj); + debugf0("%s() idx=%d\n", __func__, mci->mc_idx); + complete(&mci->kobj_complete); } static struct kobj_type ktype_mci = { @@ -1131,21 +1147,23 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) } } - /* Mark this MCI instance as having sysfs entries */ - mci->sysfs_active = MCI_SYSFS_ACTIVE; - return 0; /* CSROW error: backout what has already been registered, */ fail1: for ( i--; i >= 0; i--) { - if (csrow->nr_pages > 0) + if (csrow->nr_pages > 0) { + init_completion(&csrow->kobj_complete); kobject_unregister(&mci->csrows[i].kobj); + wait_for_completion(&csrow->kobj_complete); + } } fail0: + init_completion(&mci->kobj_complete); kobject_unregister(edac_mci_kobj); + wait_for_completion(&mci->kobj_complete); return err; } @@ -1163,13 +1181,17 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) /* remove all csrow kobjects */ for (i = 0; i < mci->nr_csrows; i++) { - if (mci->csrows[i].nr_pages > 0) + if (mci->csrows[i].nr_pages > 0) { + init_completion(&mci->csrows[i].kobj_complete); kobject_unregister(&mci->csrows[i].kobj); + wait_for_completion(&mci->csrows[i].kobj_complete); + } } sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK); - + init_completion(&mci->kobj_complete); kobject_unregister(&mci->edac_mci_kobj); + wait_for_completion(&mci->kobj_complete); #endif /* DISABLE_EDAC_SYSFS */ } @@ -1342,31 +1364,10 @@ EXPORT_SYMBOL(edac_mc_free); /** * edac_mc_free: Free a previously allocated 'mci' structure * @mci: pointer to a struct mem_ctl_info structure - * - * Free up a previously allocated mci structure - * A MCI structure can be in 2 states after being allocated - * by edac_mc_alloc(). - * 1) Allocated in a MC driver's probe, but not yet committed - * 2) Allocated and committed, by a call to edac_mc_add_mc() - * edac_mc_add_mc() is the function that adds the sysfs entries - * thus, this free function must determine which state the 'mci' - * structure is in, then either free it directly or - * perform kobject cleanup by calling edac_remove_sysfs_mci_device(). - * - * VOID Return */ void edac_mc_free(struct mem_ctl_info *mci) { - /* only if sysfs entries for this mci instance exist - * do we remove them and defer the actual kfree via - * the kobject 'release()' callback. - * - * Otherwise, do a straight kfree now. - */ - if (mci->sysfs_active == MCI_SYSFS_ACTIVE) - edac_remove_sysfs_mci_device(mci); - else - kfree(mci); + kfree(mci); } @@ -1456,7 +1457,8 @@ static void del_mc_from_global_list (struct mem_ctl_info *mci) EXPORT_SYMBOL(edac_mc_add_mc); /** - * edac_mc_add_mc: Insert the 'mci' structure into the mci global list + * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and + * create sysfs entries associated with mci structure * @mci: pointer to the mci structure to be added to the list * * Return: @@ -1516,7 +1518,8 @@ fail0: EXPORT_SYMBOL(edac_mc_del_mc); /** - * edac_mc_del_mc: Remove the specified mci structure from global list + * edac_mc_del_mc: Remove sysfs entries for specified mci structure and + * remove mci structure from global list * @mci: Pointer to struct mem_ctl_info structure * * Returns: @@ -1528,6 +1531,7 @@ int edac_mc_del_mc(struct mem_ctl_info *mci) int rc = 1; debugf0("MC%d: %s()\n", mci->mc_idx, __func__); + edac_remove_sysfs_mci_device(mci); down(&mem_ctls_mutex); del_mc_from_global_list(mci); edac_printk(KERN_INFO, EDAC_MC, diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h index 0bcc3797c75..c9c1590db72 100644 --- a/drivers/edac/edac_mc.h +++ b/drivers/edac/edac_mc.h @@ -185,11 +185,6 @@ enum scrub_type { #define SCRUB_FLAG_HW_PROG_SRC BIT(SCRUB_HW_PROG_SRC_CORR) #define SCRUB_FLAG_HW_TUN BIT(SCRUB_HW_TUNABLE) -enum mci_sysfs_status { - MCI_SYSFS_INACTIVE = 0, /* sysfs entries NOT registered */ - MCI_SYSFS_ACTIVE /* sysfs entries ARE registered */ -}; - /* FIXME - should have notify capabilities: NMI, LOG, PROC, etc */ /* @@ -299,6 +294,7 @@ struct csrow_info { struct mem_ctl_info *mci; /* the parent */ struct kobject kobj; /* sysfs kobject for this csrow */ + struct completion kobj_complete; /* FIXME the number of CHANNELs might need to become dynamic */ u32 nr_channels; @@ -320,8 +316,6 @@ struct mem_ctl_info { unsigned long scrub_cap; /* chipset scrub capabilities */ enum scrub_type scrub_mode; /* current scrub mode */ - enum mci_sysfs_status sysfs_active; /* status of sysfs */ - /* pointer to edac checking routine */ void (*edac_check) (struct mem_ctl_info * mci); /* @@ -359,6 +353,7 @@ struct mem_ctl_info { /* edac sysfs device control */ struct kobject edac_mci_kobj; + struct completion kobj_complete; }; -- cgit v1.2.3-70-g09d2 From 18dbc337af5d6efd30cb9291e74722c8ad134fd3 Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Sun, 26 Mar 2006 01:38:50 -0800 Subject: [PATCH] EDAC: protect memory controller list - Fix code so we always hold mem_ctls_mutex while we are stepping through the list of mem_ctl_info structures. Otherwise bad things may happen if one task is stepping through the list while another task is modifying it. We may eventually want to use reference counting to manage the mem_ctl_info structures. In the meantime we may as well fix this bug. - Don't disable interrupts while we are walking the list of mem_ctl_info structures in check_mc_devices(). This is unnecessary. Signed-off-by: David S. Peterson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/amd76x_edac.c | 5 ++--- drivers/edac/e752x_edac.c | 5 +---- drivers/edac/e7xxx_edac.c | 12 ++++++------ drivers/edac/edac_mc.c | 40 ++++++++++++++++++---------------------- drivers/edac/edac_mc.h | 5 +---- drivers/edac/i82860_edac.c | 7 ++++--- drivers/edac/i82875p_edac.c | 5 +---- drivers/edac/r82600_edac.c | 7 ++++--- 8 files changed, 37 insertions(+), 49 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c index 821c252d414..87bd8b4d561 100644 --- a/drivers/edac/amd76x_edac.c +++ b/drivers/edac/amd76x_edac.c @@ -314,10 +314,9 @@ static void __devexit amd76x_remove_one(struct pci_dev *pdev) debugf0("%s()\n", __func__); - if ((mci = edac_mc_find_mci_by_pdev(pdev)) == NULL) - return; - if (edac_mc_del_mc(mci)) + if ((mci = edac_mc_del_mc(pdev)) == NULL) return; + edac_mc_free(mci); } diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index 24446542d8d..c86db23d3af 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c @@ -976,10 +976,7 @@ static void __devexit e752x_remove_one(struct pci_dev *pdev) debugf0("%s()\n", __func__); - if ((mci = edac_mc_find_mci_by_pdev(pdev)) == NULL) - return; - - if (edac_mc_del_mc(mci)) + if ((mci = edac_mc_del_mc(pdev)) == NULL) return; pvt = (struct e752x_pvt *) mci->pvt_info; diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c index 8b0da35ae47..9b59c661f45 100644 --- a/drivers/edac/e7xxx_edac.c +++ b/drivers/edac/e7xxx_edac.c @@ -510,12 +510,12 @@ static void __devexit e7xxx_remove_one(struct pci_dev *pdev) debugf0("%s()\n", __func__); - if (((mci = edac_mc_find_mci_by_pdev(pdev)) != 0) && - !edac_mc_del_mc(mci)) { - pvt = (struct e7xxx_pvt *) mci->pvt_info; - pci_dev_put(pvt->bridge_ck); - edac_mc_free(mci); - } + if ((mci = edac_mc_del_mc(pdev)) == NULL) + return; + + pvt = (struct e7xxx_pvt *) mci->pvt_info; + pci_dev_put(pvt->bridge_ck); + edac_mc_free(mci); } diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 7ee9419234a..ad812a4f8c9 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -1370,11 +1370,7 @@ void edac_mc_free(struct mem_ctl_info *mci) kfree(mci); } - - -EXPORT_SYMBOL(edac_mc_find_mci_by_pdev); - -struct mem_ctl_info *edac_mc_find_mci_by_pdev(struct pci_dev *pdev) +static struct mem_ctl_info *find_mci_by_pdev(struct pci_dev *pdev) { struct mem_ctl_info *mci; struct list_head *item; @@ -1401,7 +1397,7 @@ static int add_mc_to_global_list (struct mem_ctl_info *mci) mci->mc_idx = 0; insert_before = &mc_devices; } else { - if (edac_mc_find_mci_by_pdev(mci->pdev)) { + if (find_mci_by_pdev(mci->pdev)) { edac_printk(KERN_WARNING, EDAC_MC, "%s (%s) %s %s already assigned %d\n", mci->pdev->dev.bus_id, @@ -1520,27 +1516,29 @@ EXPORT_SYMBOL(edac_mc_del_mc); /** * edac_mc_del_mc: Remove sysfs entries for specified mci structure and * remove mci structure from global list - * @mci: Pointer to struct mem_ctl_info structure + * @pdev: Pointer to 'struct pci_dev' representing mci structure to remove. * - * Returns: - * 0 Success - * 1 Failure + * Return pointer to removed mci structure, or NULL if device not found. */ -int edac_mc_del_mc(struct mem_ctl_info *mci) +struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev) { - int rc = 1; + struct mem_ctl_info *mci; - debugf0("MC%d: %s()\n", mci->mc_idx, __func__); - edac_remove_sysfs_mci_device(mci); + debugf0("MC: %s()\n", __func__); down(&mem_ctls_mutex); + + if ((mci = find_mci_by_pdev(pdev)) == NULL) { + up(&mem_ctls_mutex); + return NULL; + } + + edac_remove_sysfs_mci_device(mci); del_mc_from_global_list(mci); + up(&mem_ctls_mutex); edac_printk(KERN_INFO, EDAC_MC, "Removed device %d for %s %s: PCI %s\n", mci->mc_idx, mci->mod_name, mci->ctl_name, pci_name(mci->pdev)); - rc = 0; - up(&mem_ctls_mutex); - - return rc; + return mci; } @@ -2018,14 +2016,12 @@ static inline void clear_pci_parity_errors(void) */ static inline void check_mc_devices (void) { - unsigned long flags; struct list_head *item; struct mem_ctl_info *mci; debugf3("%s()\n", __func__); - /* during poll, have interrupts off */ - local_irq_save(flags); + down(&mem_ctls_mutex); list_for_each(item, &mc_devices) { mci = list_entry(item, struct mem_ctl_info, link); @@ -2034,7 +2030,7 @@ static inline void check_mc_devices (void) mci->edac_check(mci); } - local_irq_restore(flags); + up(&mem_ctls_mutex); } diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h index c9c1590db72..2cec157aaeb 100644 --- a/drivers/edac/edac_mc.h +++ b/drivers/edac/edac_mc.h @@ -410,14 +410,11 @@ void edac_mc_dump_csrow(struct csrow_info *csrow); #endif /* CONFIG_EDAC_DEBUG */ extern int edac_mc_add_mc(struct mem_ctl_info *mci); -extern int edac_mc_del_mc(struct mem_ctl_info *mci); +extern struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev); extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page); -extern struct mem_ctl_info *edac_mc_find_mci_by_pdev(struct pci_dev - *pdev); - extern void edac_mc_scrub_block(unsigned long page, unsigned long offset, u32 size); diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c index 942129df021..688854260a0 100644 --- a/drivers/edac/i82860_edac.c +++ b/drivers/edac/i82860_edac.c @@ -237,9 +237,10 @@ static void __devexit i82860_remove_one(struct pci_dev *pdev) debugf0("%s()\n", __func__); - mci = edac_mc_find_mci_by_pdev(pdev); - if ((mci != NULL) && (edac_mc_del_mc(mci) == 0)) - edac_mc_free(mci); + if ((mci = edac_mc_del_mc(pdev)) == NULL) + return; + + edac_mc_free(mci); } static const struct pci_device_id i82860_pci_tbl[] __devinitdata = { diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index 40ba2be6169..aad1900a468 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c @@ -452,7 +452,7 @@ static void __devexit i82875p_remove_one(struct pci_dev *pdev) debugf0("%s()\n", __func__); - if ((mci = edac_mc_find_mci_by_pdev(pdev)) == NULL) + if ((mci = edac_mc_del_mc(pdev)) == NULL) return; pvt = (struct i82875p_pvt *) mci->pvt_info; @@ -467,9 +467,6 @@ static void __devexit i82875p_remove_one(struct pci_dev *pdev) pci_dev_put(pvt->ovrfl_pdev); } - if (edac_mc_del_mc(mci)) - return; - edac_mc_free(mci); } diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c index 787a7652c7e..5966916d02b 100644 --- a/drivers/edac/r82600_edac.c +++ b/drivers/edac/r82600_edac.c @@ -353,9 +353,10 @@ static void __devexit r82600_remove_one(struct pci_dev *pdev) debugf0("%s()\n", __func__); - if (((mci = edac_mc_find_mci_by_pdev(pdev)) != NULL) && - !edac_mc_del_mc(mci)) - edac_mc_free(mci); + if ((mci = edac_mc_del_mc(pdev)) == NULL) + return; + + edac_mc_free(mci); } -- cgit v1.2.3-70-g09d2 From 54933dddc3e8ccd9db48966d8ada11951cb8a558 Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Sun, 26 Mar 2006 01:38:51 -0800 Subject: [PATCH] EDAC: reorder EXPORT_SYMBOL macros Fix EDAC code so EXPORT_SYMBOL comes after the function that is being exported. This is to maintain consistency with the rest of the kernel. Signed-off-by: David S. Peterson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/edac_mc.c | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index ad812a4f8c9..f67a4d6f897 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -1199,7 +1199,6 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) #ifdef CONFIG_EDAC_DEBUG -EXPORT_SYMBOL(edac_mc_dump_channel); void edac_mc_dump_channel(struct channel_info *chan) { @@ -1209,10 +1208,9 @@ void edac_mc_dump_channel(struct channel_info *chan) debugf4("\tchannel->label = '%s'\n", chan->label); debugf4("\tchannel->csrow = %p\n\n", chan->csrow); } +EXPORT_SYMBOL(edac_mc_dump_channel); -EXPORT_SYMBOL(edac_mc_dump_csrow); - void edac_mc_dump_csrow(struct csrow_info *csrow) { debugf4("\tcsrow = %p\n", csrow); @@ -1227,10 +1225,9 @@ void edac_mc_dump_csrow(struct csrow_info *csrow) debugf4("\tcsrow->channels = %p\n", csrow->channels); debugf4("\tcsrow->mci = %p\n\n", csrow->mci); } +EXPORT_SYMBOL(edac_mc_dump_csrow); -EXPORT_SYMBOL(edac_mc_dump_mci); - void edac_mc_dump_mci(struct mem_ctl_info *mci) { debugf3("\tmci = %p\n", mci); @@ -1245,6 +1242,7 @@ void edac_mc_dump_mci(struct mem_ctl_info *mci) mci->mod_name, mci->ctl_name); debugf3("\tpvt_info = %p\n\n", mci->pvt_info); } +EXPORT_SYMBOL(edac_mc_dump_mci); #endif /* CONFIG_EDAC_DEBUG */ @@ -1284,8 +1282,6 @@ static inline char * align_ptr (void *ptr, unsigned size) } -EXPORT_SYMBOL(edac_mc_alloc); - /** * edac_mc_alloc: Allocate a struct mem_ctl_info structure * @size_pvt: size of private storage needed @@ -1357,10 +1353,9 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, return mci; } +EXPORT_SYMBOL(edac_mc_alloc); -EXPORT_SYMBOL(edac_mc_free); - /** * edac_mc_free: Free a previously allocated 'mci' structure * @mci: pointer to a struct mem_ctl_info structure @@ -1369,6 +1364,7 @@ void edac_mc_free(struct mem_ctl_info *mci) { kfree(mci); } +EXPORT_SYMBOL(edac_mc_free); static struct mem_ctl_info *find_mci_by_pdev(struct pci_dev *pdev) { @@ -1450,8 +1446,6 @@ static void del_mc_from_global_list (struct mem_ctl_info *mci) } -EXPORT_SYMBOL(edac_mc_add_mc); - /** * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and * create sysfs entries associated with mci structure @@ -1509,10 +1503,9 @@ fail0: up(&mem_ctls_mutex); return 1; } +EXPORT_SYMBOL(edac_mc_add_mc); -EXPORT_SYMBOL(edac_mc_del_mc); - /** * edac_mc_del_mc: Remove sysfs entries for specified mci structure and * remove mci structure from global list @@ -1540,10 +1533,9 @@ struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev) mci->mod_name, mci->ctl_name, pci_name(mci->pdev)); return mci; } +EXPORT_SYMBOL(edac_mc_del_mc); -EXPORT_SYMBOL(edac_mc_scrub_block); - void edac_mc_scrub_block(unsigned long page, unsigned long offset, u32 size) { @@ -1574,11 +1566,10 @@ void edac_mc_scrub_block(unsigned long page, unsigned long offset, if (PageHighMem(pg)) local_irq_restore(flags); } +EXPORT_SYMBOL(edac_mc_scrub_block); /* FIXME - should return -1 */ -EXPORT_SYMBOL(edac_mc_find_csrow_by_page); - int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page) { @@ -1615,10 +1606,9 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, return row; } +EXPORT_SYMBOL(edac_mc_find_csrow_by_page); -EXPORT_SYMBOL(edac_mc_handle_ce); - /* FIXME - setable log (warning/emerg) levels */ /* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */ void edac_mc_handle_ce(struct mem_ctl_info *mci, @@ -1681,10 +1671,9 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci, mci->csrows[row].grain); } } +EXPORT_SYMBOL(edac_mc_handle_ce); -EXPORT_SYMBOL(edac_mc_handle_ce_no_info); - void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg) { @@ -1694,10 +1683,9 @@ void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, mci->ce_noinfo_count++; mci->ce_count++; } +EXPORT_SYMBOL(edac_mc_handle_ce_no_info); -EXPORT_SYMBOL(edac_mc_handle_ue); - void edac_mc_handle_ue(struct mem_ctl_info *mci, unsigned long page_frame_number, unsigned long offset_in_page, int row, @@ -1750,10 +1738,9 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci, mci->ue_count++; mci->csrows[row].ue_count++; } +EXPORT_SYMBOL(edac_mc_handle_ue); -EXPORT_SYMBOL(edac_mc_handle_ue_no_info); - void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg) { @@ -1766,6 +1753,7 @@ void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, mci->ue_noinfo_count++; mci->ue_count++; } +EXPORT_SYMBOL(edac_mc_handle_ue_no_info); #ifdef CONFIG_PCI -- cgit v1.2.3-70-g09d2 From e7ecd8910293564d357dbaf18eb179e06fa35fd0 Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Sun, 26 Mar 2006 01:38:52 -0800 Subject: [PATCH] EDAC: formatting cleanup Cosmetic indentation/formatting cleanup for EDAC code. Make sure we are using tabs rather than spaces to indent, etc. Signed-off-by: David S. Peterson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/amd76x_edac.c | 91 +++++-------- drivers/edac/e752x_edac.c | 234 +++++++++++++++++-------------- drivers/edac/e7xxx_edac.c | 165 +++++++++++----------- drivers/edac/edac_mc.c | 325 ++++++++++++++++++++------------------------ drivers/edac/edac_mc.h | 96 ++++++------- drivers/edac/i82860_edac.c | 66 +++++---- drivers/edac/i82875p_edac.c | 112 +++++++-------- drivers/edac/r82600_edac.c | 71 ++++------ 8 files changed, 558 insertions(+), 602 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c index 87bd8b4d561..53423ad6d4a 100644 --- a/drivers/edac/amd76x_edac.c +++ b/drivers/edac/amd76x_edac.c @@ -12,33 +12,26 @@ * */ - #include #include #include - #include #include - #include - #include "edac_mc.h" - #define amd76x_printk(level, fmt, arg...) \ - edac_printk(level, "amd76x", fmt, ##arg) - + edac_printk(level, "amd76x", fmt, ##arg) #define amd76x_mc_printk(mci, level, fmt, arg...) \ - edac_mc_chipset_printk(mci, level, "amd76x", fmt, ##arg) - + edac_mc_chipset_printk(mci, level, "amd76x", fmt, ##arg) #define AMD76X_NR_CSROWS 8 #define AMD76X_NR_CHANS 1 #define AMD76X_NR_DIMMS 4 - /* AMD 76x register addresses - device 0 function 0 - PCI bridge */ + #define AMD76X_ECC_MODE_STATUS 0x48 /* Mode and status of ECC (32b) * * 31:16 reserved @@ -50,6 +43,7 @@ * 7:4 UE cs row * 3:0 CE cs row */ + #define AMD76X_DRAM_MODE_STATUS 0x58 /* DRAM Mode and status (32b) * * 31:26 clock disable 5 - 0 @@ -64,6 +58,7 @@ * 15:8 reserved * 7:0 x4 mode enable 7 - 0 */ + #define AMD76X_MEM_BASE_ADDR 0xC0 /* Memory base address (8 x 32b) * * 31:23 chip-select base @@ -74,29 +69,28 @@ * 0 chip-select enable */ - struct amd76x_error_info { u32 ecc_mode_status; }; - enum amd76x_chips { AMD761 = 0, AMD762 }; - struct amd76x_dev_info { const char *ctl_name; }; - static const struct amd76x_dev_info amd76x_devs[] = { - [AMD761] = {.ctl_name = "AMD761"}, - [AMD762] = {.ctl_name = "AMD762"}, + [AMD761] = { + .ctl_name = "AMD761" + }, + [AMD762] = { + .ctl_name = "AMD762" + }, }; - /** * amd76x_get_error_info - fetch error information * @mci: Memory controller @@ -105,23 +99,21 @@ static const struct amd76x_dev_info amd76x_devs[] = { * Fetch and store the AMD76x ECC status. Clear pending status * on the chip so that further errors will be reported */ - -static void amd76x_get_error_info (struct mem_ctl_info *mci, - struct amd76x_error_info *info) +static void amd76x_get_error_info(struct mem_ctl_info *mci, + struct amd76x_error_info *info) { pci_read_config_dword(mci->pdev, AMD76X_ECC_MODE_STATUS, &info->ecc_mode_status); if (info->ecc_mode_status & BIT(8)) pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS, - (u32) BIT(8), (u32) BIT(8)); + (u32) BIT(8), (u32) BIT(8)); if (info->ecc_mode_status & BIT(9)) pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS, - (u32) BIT(9), (u32) BIT(9)); + (u32) BIT(9), (u32) BIT(9)); } - /** * amd76x_process_error_info - Error check * @mci: Memory controller @@ -132,8 +124,7 @@ static void amd76x_get_error_info (struct mem_ctl_info *mci, * A return of 1 indicates an error. Also if handle_errors is true * then attempt to handle and clean up after the error */ - -static int amd76x_process_error_info (struct mem_ctl_info *mci, +static int amd76x_process_error_info(struct mem_ctl_info *mci, struct amd76x_error_info *info, int handle_errors) { int error_found; @@ -149,9 +140,8 @@ static int amd76x_process_error_info (struct mem_ctl_info *mci, if (handle_errors) { row = (info->ecc_mode_status >> 4) & 0xf; - edac_mc_handle_ue(mci, - mci->csrows[row].first_page, 0, row, - mci->ctl_name); + edac_mc_handle_ue(mci, mci->csrows[row].first_page, 0, + row, mci->ctl_name); } } @@ -163,11 +153,11 @@ static int amd76x_process_error_info (struct mem_ctl_info *mci, if (handle_errors) { row = info->ecc_mode_status & 0xf; - edac_mc_handle_ce(mci, - mci->csrows[row].first_page, 0, 0, row, 0, - mci->ctl_name); + edac_mc_handle_ce(mci, mci->csrows[row].first_page, 0, + 0, row, 0, mci->ctl_name); } } + return error_found; } @@ -178,7 +168,6 @@ static int amd76x_process_error_info (struct mem_ctl_info *mci, * Called by the poll handlers this function reads the status * from the controller and checks for errors. */ - static void amd76x_check(struct mem_ctl_info *mci) { struct amd76x_error_info info; @@ -187,7 +176,6 @@ static void amd76x_check(struct mem_ctl_info *mci) amd76x_process_error_info(mci, &info, 1); } - /** * amd76x_probe1 - Perform set up for detected device * @pdev; PCI device detected @@ -197,7 +185,6 @@ static void amd76x_check(struct mem_ctl_info *mci) * controller status reporting. We configure and set up the * memory controller reporting and claim the device. */ - static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) { int rc = -ENODEV; @@ -214,10 +201,8 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) struct amd76x_error_info discard; debugf0("%s()\n", __func__); - pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, &ems); ems_mode = (ems >> 10) & 0x3; - mci = edac_mc_alloc(0, AMD76X_NR_CSROWS, AMD76X_NR_CHANS); if (mci == NULL) { @@ -226,14 +211,11 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) } debugf0("%s(): mci = %p\n", __func__, mci); - mci->pdev = pdev; mci->mtype_cap = MEM_FLAG_RDDR; - mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; mci->edac_cap = ems_mode ? - (EDAC_FLAG_EC | EDAC_FLAG_SECDED) : EDAC_FLAG_NONE; - + (EDAC_FLAG_EC | EDAC_FLAG_SECDED) : EDAC_FLAG_NONE; mci->mod_name = EDAC_MOD_STR; mci->mod_ver = "$Revision: 1.4.2.5 $"; mci->ctl_name = amd76x_devs[dev_idx].ctl_name; @@ -249,18 +231,15 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) /* find the DRAM Chip Select Base address and mask */ pci_read_config_dword(mci->pdev, - AMD76X_MEM_BASE_ADDR + (index * 4), - &mba); + AMD76X_MEM_BASE_ADDR + (index * 4), &mba); if (!(mba & BIT(0))) continue; mba_base = mba & 0xff800000UL; mba_mask = ((mba & 0xff80) << 16) | 0x7fffffUL; - pci_read_config_dword(mci->pdev, AMD76X_DRAM_MODE_STATUS, - &dms); - + &dms); csrow->first_page = mba_base >> PAGE_SHIFT; csrow->nr_pages = (mba_mask + 1) >> PAGE_SHIFT; csrow->last_page = csrow->first_page + csrow->nr_pages - 1; @@ -290,7 +269,7 @@ fail: /* returns count (>= 0), or negative on error */ static int __devinit amd76x_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { debugf0("%s()\n", __func__); @@ -298,7 +277,6 @@ static int __devinit amd76x_init_one(struct pci_dev *pdev, return amd76x_probe1(pdev, ent->driver_data); } - /** * amd76x_remove_one - driver shutdown * @pdev: PCI device being handed back @@ -307,7 +285,6 @@ static int __devinit amd76x_init_one(struct pci_dev *pdev, * structure for the device then delete the mci and free the * resources. */ - static void __devexit amd76x_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; @@ -320,18 +297,22 @@ static void __devexit amd76x_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } - static const struct pci_device_id amd76x_pci_tbl[] __devinitdata = { - {PCI_VEND_DEV(AMD, FE_GATE_700C), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - AMD762}, - {PCI_VEND_DEV(AMD, FE_GATE_700E), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - AMD761}, - {0,} /* 0 terminated list. */ + { + PCI_VEND_DEV(AMD, FE_GATE_700C), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + AMD762 + }, + { + PCI_VEND_DEV(AMD, FE_GATE_700E), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + AMD761 + }, + { + 0, + } /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, amd76x_pci_tbl); - static struct pci_driver amd76x_driver = { .name = EDAC_MOD_STR, .probe = amd76x_init_one, diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index c86db23d3af..265cce72497 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c @@ -17,26 +17,19 @@ * */ - #include #include #include - #include #include - #include - #include "edac_mc.h" - #define e752x_printk(level, fmt, arg...) \ - edac_printk(level, "e752x", fmt, ##arg) - + edac_printk(level, "e752x", fmt, ##arg) #define e752x_mc_printk(mci, level, fmt, arg...) \ - edac_mc_chipset_printk(mci, level, "e752x", fmt, ##arg) - + edac_mc_chipset_printk(mci, level, "e752x", fmt, ##arg) #ifndef PCI_DEVICE_ID_INTEL_7520_0 #define PCI_DEVICE_ID_INTEL_7520_0 0x3590 @@ -64,7 +57,6 @@ #define E752X_NR_CSROWS 8 /* number of csrows */ - /* E752X register addresses - device 0 function 0 */ #define E752X_DRB 0x60 /* DRAM row boundary register (8b) */ #define E752X_DRA 0x70 /* DRAM row attribute register (8b) */ @@ -164,7 +156,6 @@ enum e752x_chips { E7320 = 2 }; - struct e752x_pvt { struct pci_dev *bridge_ck; struct pci_dev *dev_d0f0; @@ -178,7 +169,6 @@ struct e752x_pvt { const struct e752x_dev_info *dev_info; }; - struct e752x_dev_info { u16 err_dev; u16 ctl_dev; @@ -207,22 +197,24 @@ struct e752x_error_info { static const struct e752x_dev_info e752x_devs[] = { [E7520] = { - .err_dev = PCI_DEVICE_ID_INTEL_7520_1_ERR, - .ctl_dev = PCI_DEVICE_ID_INTEL_7520_0, - .ctl_name = "E7520"}, + .err_dev = PCI_DEVICE_ID_INTEL_7520_1_ERR, + .ctl_dev = PCI_DEVICE_ID_INTEL_7520_0, + .ctl_name = "E7520" + }, [E7525] = { - .err_dev = PCI_DEVICE_ID_INTEL_7525_1_ERR, - .ctl_dev = PCI_DEVICE_ID_INTEL_7525_0, - .ctl_name = "E7525"}, + .err_dev = PCI_DEVICE_ID_INTEL_7525_1_ERR, + .ctl_dev = PCI_DEVICE_ID_INTEL_7525_0, + .ctl_name = "E7525" + }, [E7320] = { - .err_dev = PCI_DEVICE_ID_INTEL_7320_1_ERR, - .ctl_dev = PCI_DEVICE_ID_INTEL_7320_0, - .ctl_name = "E7320"}, + .err_dev = PCI_DEVICE_ID_INTEL_7320_1_ERR, + .ctl_dev = PCI_DEVICE_ID_INTEL_7320_0, + .ctl_name = "E7320" + }, }; - static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci, - unsigned long page) + unsigned long page) { u32 remap; struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info; @@ -231,17 +223,21 @@ static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci, if (page < pvt->tolm) return page; + if ((page >= 0x100000) && (page < pvt->remapbase)) return page; + remap = (page - pvt->tolm) + pvt->remapbase; + if (remap < pvt->remaplimit) return remap; + e752x_printk(KERN_ERR, "Invalid page %lx - out of range\n", page); return pvt->tolm - 1; } static void do_process_ce(struct mem_ctl_info *mci, u16 error_one, - u32 sec1_add, u16 sec1_syndrome) + u32 sec1_add, u16 sec1_syndrome) { u32 page; int row; @@ -259,34 +255,36 @@ static void do_process_ce(struct mem_ctl_info *mci, u16 error_one, /* chip select are bits 14 & 13 */ row = ((page >> 1) & 3); e752x_printk(KERN_WARNING, - "Test row %d Table %d %d %d %d %d %d %d %d\n", - row, pvt->map[0], pvt->map[1], pvt->map[2], - pvt->map[3], pvt->map[4], pvt->map[5], - pvt->map[6], pvt->map[7]); + "Test row %d Table %d %d %d %d %d %d %d %d\n", row, + pvt->map[0], pvt->map[1], pvt->map[2], pvt->map[3], + pvt->map[4], pvt->map[5], pvt->map[6], pvt->map[7]); /* test for channel remapping */ for (i = 0; i < 8; i++) { if (pvt->map[i] == row) break; } + e752x_printk(KERN_WARNING, "Test computed row %d\n", i); + if (i < 8) row = i; else e752x_mc_printk(mci, KERN_WARNING, - "row %d not found in remap table\n", row); + "row %d not found in remap table\n", row); } else row = edac_mc_find_csrow_by_page(mci, page); + /* 0 = channel A, 1 = channel B */ channel = !(error_one & 1); if (!pvt->map_type) row = 7 - row; + edac_mc_handle_ce(mci, page, 0, sec1_syndrome, row, channel, - "e752x CE"); + "e752x CE"); } - static inline void process_ce(struct mem_ctl_info *mci, u16 error_one, u32 sec1_add, u16 sec1_syndrome, int *error_found, int handle_error) @@ -297,8 +295,8 @@ static inline void process_ce(struct mem_ctl_info *mci, u16 error_one, do_process_ce(mci, error_one, sec1_add, sec1_syndrome); } -static void do_process_ue(struct mem_ctl_info *mci, u16 error_one, u32 ded_add, - u32 scrb_add) +static void do_process_ue(struct mem_ctl_info *mci, u16 error_one, + u32 ded_add, u32 scrb_add) { u32 error_2b, block_page; int row; @@ -308,25 +306,31 @@ static void do_process_ue(struct mem_ctl_info *mci, u16 error_one, u32 ded_add, if (error_one & 0x0202) { error_2b = ded_add; + /* convert to 4k address */ block_page = error_2b >> (PAGE_SHIFT - 4); + row = pvt->mc_symmetric ? - /* chip select are bits 14 & 13 */ - ((block_page >> 1) & 3) : - edac_mc_find_csrow_by_page(mci, block_page); + /* chip select are bits 14 & 13 */ + ((block_page >> 1) & 3) : + edac_mc_find_csrow_by_page(mci, block_page); + edac_mc_handle_ue(mci, block_page, 0, row, - "e752x UE from Read"); + "e752x UE from Read"); } if (error_one & 0x0404) { error_2b = scrb_add; + /* convert to 4k address */ block_page = error_2b >> (PAGE_SHIFT - 4); + row = pvt->mc_symmetric ? - /* chip select are bits 14 & 13 */ - ((block_page >> 1) & 3) : - edac_mc_find_csrow_by_page(mci, block_page); + /* chip select are bits 14 & 13 */ + ((block_page >> 1) & 3) : + edac_mc_find_csrow_by_page(mci, block_page); + edac_mc_handle_ue(mci, block_page, 0, row, - "e752x UE from Scruber"); + "e752x UE from Scruber"); } } @@ -359,13 +363,13 @@ static void do_process_ded_retry(struct mem_ctl_info *mci, u16 error, struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info; error_1b = retry_add; - page = error_1b >> (PAGE_SHIFT - 4); /* convert the addr to 4k page */ + page = error_1b >> (PAGE_SHIFT - 4); /* convert the addr to 4k page */ row = pvt->mc_symmetric ? - ((page >> 1) & 3) : /* chip select are bits 14 & 13 */ - edac_mc_find_csrow_by_page(mci, page); + ((page >> 1) & 3) : /* chip select are bits 14 & 13 */ + edac_mc_find_csrow_by_page(mci, page); e752x_mc_printk(mci, KERN_WARNING, - "CE page 0x%lx, row %d : Memory read retry\n", - (long unsigned int) page, row); + "CE page 0x%lx, row %d : Memory read retry\n", + (long unsigned int) page, row); } static inline void process_ded_retry(struct mem_ctl_info *mci, u16 error, @@ -402,7 +406,7 @@ static void do_global_error(int fatal, u32 errors) for (i = 0; i < 11; i++) { if (errors & (1 << i)) e752x_printk(KERN_WARNING, "%sError %s\n", - fatal_message[fatal], global_message[i]); + fatal_message[fatal], global_message[i]); } } @@ -429,7 +433,7 @@ static void do_hub_error(int fatal, u8 errors) for (i = 0; i < 7; i++) { if (errors & (1 << i)) e752x_printk(KERN_WARNING, "%sError %s\n", - fatal_message[fatal], hub_message[i]); + fatal_message[fatal], hub_message[i]); } } @@ -456,7 +460,7 @@ static void do_membuf_error(u8 errors) for (i = 0; i < 4; i++) { if (errors & (1 << i)) e752x_printk(KERN_WARNING, "Non-Fatal Error %s\n", - membuf_message[i]); + membuf_message[i]); } } @@ -489,7 +493,7 @@ static void do_sysbus_error(int fatal, u32 errors) for (i = 0; i < 10; i++) { if (errors & (1 << i)) e752x_printk(KERN_WARNING, "%sError System Bus %s\n", - fatal_message[fatal], global_message[i]); + fatal_message[fatal], global_message[i]); } } @@ -502,33 +506,42 @@ static inline void sysbus_error(int fatal, u32 errors, int *error_found, do_sysbus_error(fatal, errors); } -static void e752x_check_hub_interface (struct e752x_error_info *info, +static void e752x_check_hub_interface(struct e752x_error_info *info, int *error_found, int handle_error) { u8 stat8; //pci_read_config_byte(dev,E752X_HI_FERR,&stat8); + stat8 = info->hi_ferr; + if(stat8 & 0x7f) { /* Error, so process */ stat8 &= 0x7f; + if(stat8 & 0x2b) hub_error(1, stat8 & 0x2b, error_found, handle_error); + if(stat8 & 0x54) hub_error(0, stat8 & 0x54, error_found, handle_error); } + //pci_read_config_byte(dev,E752X_HI_NERR,&stat8); + stat8 = info->hi_nerr; + if(stat8 & 0x7f) { /* Error, so process */ stat8 &= 0x7f; + if (stat8 & 0x2b) hub_error(1, stat8 & 0x2b, error_found, handle_error); + if(stat8 & 0x54) hub_error(0, stat8 & 0x54, error_found, handle_error); } } -static void e752x_check_sysbus (struct e752x_error_info *info, int *error_found, - int handle_error) +static void e752x_check_sysbus(struct e752x_error_info *info, + int *error_found, int handle_error) { u32 stat32, error32; @@ -540,27 +553,34 @@ static void e752x_check_sysbus (struct e752x_error_info *info, int *error_found, error32 = (stat32 >> 16) & 0x3ff; stat32 = stat32 & 0x3ff; + if(stat32 & 0x083) sysbus_error(1, stat32 & 0x083, error_found, handle_error); + if(stat32 & 0x37c) sysbus_error(0, stat32 & 0x37c, error_found, handle_error); + if(error32 & 0x083) sysbus_error(1, error32 & 0x083, error_found, handle_error); + if(error32 & 0x37c) sysbus_error(0, error32 & 0x37c, error_found, handle_error); } -static void e752x_check_membuf (struct e752x_error_info *info, int *error_found, - int handle_error) +static void e752x_check_membuf (struct e752x_error_info *info, + int *error_found, int handle_error) { u8 stat8; stat8 = info->buf_ferr; + if (stat8 & 0x0f) { /* Error, so process */ stat8 &= 0x0f; membuf_error(stat8, error_found, handle_error); } + stat8 = info->buf_nerr; + if (stat8 & 0x0f) { /* Error, so process */ stat8 &= 0x0f; membuf_error(stat8, error_found, handle_error); @@ -568,7 +588,8 @@ static void e752x_check_membuf (struct e752x_error_info *info, int *error_found, } static void e752x_check_dram (struct mem_ctl_info *mci, - struct e752x_error_info *info, int *error_found, int handle_error) + struct e752x_error_info *info, int *error_found, + int handle_error) { u16 error_one, error_next; @@ -618,7 +639,7 @@ static void e752x_check_dram (struct mem_ctl_info *mci, } static void e752x_get_error_info (struct mem_ctl_info *mci, - struct e752x_error_info *info) + struct e752x_error_info *info) { struct pci_dev *dev; struct e752x_pvt *pvt; @@ -626,7 +647,6 @@ static void e752x_get_error_info (struct mem_ctl_info *mci, memset(info, 0, sizeof(*info)); pvt = (struct e752x_pvt *) mci->pvt_info; dev = pvt->dev_d0f1; - pci_read_config_dword(dev, E752X_FERR_GLOBAL, &info->ferr_global); if (info->ferr_global) { @@ -737,6 +757,7 @@ static int e752x_process_error_info (struct mem_ctl_info *mci, static void e752x_check(struct mem_ctl_info *mci) { struct e752x_error_info info; + debugf3("%s()\n", __func__); e752x_get_error_info(mci, &info); e752x_process_error_info(mci, &info, 1); @@ -752,9 +773,9 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) struct e752x_pvt *pvt = NULL; u16 ddrcsr; u32 drc; - int drc_chan; /* Number of channels 0=1chan,1=2chan */ - int drc_drbg; /* DRB granularity 0=64mb,1=128mb */ - int drc_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */ + int drc_chan; /* Number of channels 0=1chan,1=2chan */ + int drc_drbg; /* DRB granularity 0=64mb, 1=128mb */ + int drc_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */ u32 dra; unsigned long last_cumul_size; struct pci_dev *dev = NULL; @@ -785,7 +806,6 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) } debugf3("%s(): init mci\n", __func__); - mci->mtype_cap = MEM_FLAG_RDDR; mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED | EDAC_FLAG_S4ECD4ED; @@ -798,19 +818,21 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) pvt = (struct e752x_pvt *) mci->pvt_info; pvt->dev_info = &e752x_devs[dev_idx]; pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL, - pvt->dev_info->err_dev, - pvt->bridge_ck); + pvt->dev_info->err_dev, + pvt->bridge_ck); + if (pvt->bridge_ck == NULL) pvt->bridge_ck = pci_scan_single_device(pdev->bus, - PCI_DEVFN(0, 1)); + PCI_DEVFN(0, 1)); + if (pvt->bridge_ck == NULL) { e752x_printk(KERN_ERR, "error reporting device not found:" - "vendor %x device 0x%x (broken BIOS?)\n", - PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].err_dev); + "vendor %x device 0x%x (broken BIOS?)\n", + PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].err_dev); goto fail; } - pvt->mc_symmetric = ((ddrcsr & 0x10) != 0); + pvt->mc_symmetric = ((ddrcsr & 0x10) != 0); debugf3("%s(): more mci init\n", __func__); mci->ctl_name = pvt->dev_info->ctl_name; mci->edac_check = e752x_check; @@ -828,6 +850,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) { u8 value; u32 cumul_size; + /* mem_dev 0=x8, 1=x4 */ int mem_dev = (dra >> (index * 4 + 2)) & 0x3; struct csrow_info *csrow = &mci->csrows[index]; @@ -838,15 +861,16 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) cumul_size = value << (25 + drc_drbg - PAGE_SHIFT); debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, cumul_size); + if (cumul_size == last_cumul_size) - continue; /* not populated */ + continue; /* not populated */ csrow->first_page = last_cumul_size; csrow->last_page = cumul_size - 1; csrow->nr_pages = cumul_size - last_cumul_size; last_cumul_size = cumul_size; - csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */ - csrow->mtype = MEM_RDDR; /* only one type supported */ + csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */ + csrow->mtype = MEM_RDDR; /* only one type supported */ csrow->dtype = mem_dev ? DEV_X4 : DEV_X8; /* @@ -870,29 +894,32 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) u8 value; u8 last = 0; u8 row = 0; - for (index = 0; index < 8; index += 2) { + for (index = 0; index < 8; index += 2) { pci_read_config_byte(mci->pdev, E752X_DRB + index, - &value); + &value); + /* test if there is a dimm in this slot */ if (value == last) { /* no dimm in the slot, so flag it as empty */ pvt->map[index] = 0xff; pvt->map[index + 1] = 0xff; - } else { /* there is a dimm in the slot */ + } else { /* there is a dimm in the slot */ pvt->map[index] = row; row++; last = value; /* test the next value to see if the dimm is double sided */ pci_read_config_byte(mci->pdev, - E752X_DRB + index + 1, - &value); + E752X_DRB + index + 1, + &value); pvt->map[index + 1] = (value == last) ? - 0xff : /* the dimm is single sided, - so flag as empty */ - row; /* this is a double sided dimm - to save the next row # */ + 0xff : /* the dimm is single sided, + * so flag as empty + */ + row; /* this is a double sided dimm + * to save the next row # + */ row++; last = value; } @@ -904,8 +931,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f)); mci->edac_cap |= EDAC_FLAG_NONE; - debugf3("%s(): tolm, remapbase, remaplimit\n", __func__); + /* load the top of low memory, remap base, and remap limit vars */ pci_read_config_word(mci->pdev, E752X_TOLM, &pci_data); pvt->tolm = ((u32) pci_data) << 4; @@ -914,8 +941,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) pci_read_config_word(mci->pdev, E752X_REMAPLIMIT, &pci_data); pvt->remaplimit = ((u32) pci_data) << 14; e752x_printk(KERN_INFO, - "tolm = %x, remapbase = %x, remaplimit = %x\n", - pvt->tolm, pvt->remapbase, pvt->remaplimit); + "tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm, + pvt->remapbase, pvt->remaplimit); if (edac_mc_add_mc(mci)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); @@ -923,7 +950,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) } dev = pci_get_device(PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].ctl_dev, - NULL); + NULL); pvt->dev_d0f0 = dev; /* find the error reporting device and clear errors */ dev = pvt->dev_d0f1 = pci_dev_get(pvt->bridge_ck); @@ -936,8 +963,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) pci_write_config_byte(dev, E752X_BUF_SMICMD, 0x00); pci_write_config_byte(dev, E752X_DRAM_ERRMASK, 0x00); pci_write_config_byte(dev, E752X_DRAM_SMICMD, 0x00); - /* clear other MCH errors */ - e752x_get_error_info(mci, &discard); + + e752x_get_error_info(mci, &discard); /* clear other MCH errors */ /* get this far and it's successful */ debugf3("%s(): success\n", __func__); @@ -947,28 +974,32 @@ fail: if (mci) { if (pvt->dev_d0f0) pci_dev_put(pvt->dev_d0f0); + if (pvt->dev_d0f1) pci_dev_put(pvt->dev_d0f1); + if (pvt->bridge_ck) pci_dev_put(pvt->bridge_ck); + edac_mc_free(mci); } + return rc; } /* returns count (>= 0), or negative on error */ static int __devinit e752x_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { debugf0("%s()\n", __func__); /* wake up and enable device */ if(pci_enable_device(pdev) < 0) return -EIO; + return e752x_probe1(pdev, ent->driver_data); } - static void __devexit e752x_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; @@ -986,20 +1017,26 @@ static void __devexit e752x_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } - static const struct pci_device_id e752x_pci_tbl[] __devinitdata = { - {PCI_VEND_DEV(INTEL, 7520_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - E7520}, - {PCI_VEND_DEV(INTEL, 7525_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - E7525}, - {PCI_VEND_DEV(INTEL, 7320_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - E7320}, - {0,} /* 0 terminated list. */ + { + PCI_VEND_DEV(INTEL, 7520_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + E7520 + }, + { + PCI_VEND_DEV(INTEL, 7525_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + E7525 + }, + { + PCI_VEND_DEV(INTEL, 7320_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + E7320 + }, + { + 0, + } /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, e752x_pci_tbl); - static struct pci_driver e752x_driver = { .name = EDAC_MOD_STR, .probe = e752x_init_one, @@ -1007,7 +1044,6 @@ static struct pci_driver e752x_driver = { .id_table = e752x_pci_tbl, }; - static int __init e752x_init(void) { int pci_rc; @@ -1017,14 +1053,12 @@ static int __init e752x_init(void) return (pci_rc < 0) ? pci_rc : 0; } - static void __exit e752x_exit(void) { debugf3("%s()\n", __func__); pci_unregister_driver(&e752x_driver); } - module_init(e752x_init); module_exit(e752x_exit); diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c index 9b59c661f45..a9518d3e4be 100644 --- a/drivers/edac/e7xxx_edac.c +++ b/drivers/edac/e7xxx_edac.c @@ -11,9 +11,9 @@ * http://www.anime.net/~goemon/linux-ecc/ * * Contributors: - * Eric Biederman (Linux Networx) - * Tom Zimmerman (Linux Networx) - * Jim Garlick (Lawrence Livermore National Labs) + * Eric Biederman (Linux Networx) + * Tom Zimmerman (Linux Networx) + * Jim Garlick (Lawrence Livermore National Labs) * Dave Peterson (Lawrence Livermore National Labs) * That One Guy (Some other place) * Wang Zhenyu (intel.com) @@ -22,7 +22,6 @@ * */ - #include #include #include @@ -31,14 +30,11 @@ #include #include "edac_mc.h" - #define e7xxx_printk(level, fmt, arg...) \ - edac_printk(level, "e7xxx", fmt, ##arg) - + edac_printk(level, "e7xxx", fmt, ##arg) #define e7xxx_mc_printk(mci, level, fmt, arg...) \ - edac_mc_chipset_printk(mci, level, "e7xxx", fmt, ##arg) - + edac_mc_chipset_printk(mci, level, "e7xxx", fmt, ##arg) #ifndef PCI_DEVICE_ID_INTEL_7205_0 #define PCI_DEVICE_ID_INTEL_7205_0 0x255d @@ -72,11 +68,9 @@ #define PCI_DEVICE_ID_INTEL_7505_1_ERR 0x2551 #endif /* PCI_DEVICE_ID_INTEL_7505_1_ERR */ - #define E7XXX_NR_CSROWS 8 /* number of csrows */ #define E7XXX_NR_DIMMS 8 /* FIXME - is this correct? */ - /* E7XXX register addresses - device 0 function 0 */ #define E7XXX_DRB 0x60 /* DRAM row boundary register (8b) */ #define E7XXX_DRA 0x70 /* DRAM row attribute register (8b) */ @@ -126,7 +120,6 @@ enum e7xxx_chips { E7205, }; - struct e7xxx_pvt { struct pci_dev *bridge_ck; u32 tolm; @@ -135,13 +128,11 @@ struct e7xxx_pvt { const struct e7xxx_dev_info *dev_info; }; - struct e7xxx_dev_info { u16 err_dev; const char *ctl_name; }; - struct e7xxx_error_info { u8 dram_ferr; u8 dram_nerr; @@ -152,20 +143,23 @@ struct e7xxx_error_info { static const struct e7xxx_dev_info e7xxx_devs[] = { [E7500] = { - .err_dev = PCI_DEVICE_ID_INTEL_7500_1_ERR, - .ctl_name = "E7500"}, + .err_dev = PCI_DEVICE_ID_INTEL_7500_1_ERR, + .ctl_name = "E7500" + }, [E7501] = { - .err_dev = PCI_DEVICE_ID_INTEL_7501_1_ERR, - .ctl_name = "E7501"}, + .err_dev = PCI_DEVICE_ID_INTEL_7501_1_ERR, + .ctl_name = "E7501" + }, [E7505] = { - .err_dev = PCI_DEVICE_ID_INTEL_7505_1_ERR, - .ctl_name = "E7505"}, + .err_dev = PCI_DEVICE_ID_INTEL_7505_1_ERR, + .ctl_name = "E7505" + }, [E7205] = { - .err_dev = PCI_DEVICE_ID_INTEL_7205_1_ERR, - .ctl_name = "E7205"}, + .err_dev = PCI_DEVICE_ID_INTEL_7205_1_ERR, + .ctl_name = "E7205" + }, }; - /* FIXME - is this valid for both SECDED and S4ECD4ED? */ static inline int e7xxx_find_channel(u16 syndrome) { @@ -173,16 +167,18 @@ static inline int e7xxx_find_channel(u16 syndrome) if ((syndrome & 0xff00) == 0) return 0; + if ((syndrome & 0x00ff) == 0) return 1; + if ((syndrome & 0xf000) == 0 || (syndrome & 0x0f00) == 0) return 0; + return 1; } - -static unsigned long -ctl_page_to_phys(struct mem_ctl_info *mci, unsigned long page) +static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci, + unsigned long page) { u32 remap; struct e7xxx_pvt *pvt = (struct e7xxx_pvt *) mci->pvt_info; @@ -190,17 +186,20 @@ ctl_page_to_phys(struct mem_ctl_info *mci, unsigned long page) debugf3("%s()\n", __func__); if ((page < pvt->tolm) || - ((page >= 0x100000) && (page < pvt->remapbase))) + ((page >= 0x100000) && (page < pvt->remapbase))) return page; + remap = (page - pvt->tolm) + pvt->remapbase; + if (remap < pvt->remaplimit) return remap; + e7xxx_printk(KERN_ERR, "Invalid page %lx - out of range\n", page); return pvt->tolm - 1; } - -static void process_ce(struct mem_ctl_info *mci, struct e7xxx_error_info *info) +static void process_ce(struct mem_ctl_info *mci, + struct e7xxx_error_info *info) { u32 error_1b, page; u16 syndrome; @@ -208,52 +207,46 @@ static void process_ce(struct mem_ctl_info *mci, struct e7xxx_error_info *info) int channel; debugf3("%s()\n", __func__); - /* read the error address */ error_1b = info->dram_celog_add; /* FIXME - should use PAGE_SHIFT */ - page = error_1b >> 6; /* convert the address to 4k page */ + page = error_1b >> 6; /* convert the address to 4k page */ /* read the syndrome */ syndrome = info->dram_celog_syndrome; /* FIXME - check for -1 */ row = edac_mc_find_csrow_by_page(mci, page); /* convert syndrome to channel */ channel = e7xxx_find_channel(syndrome); - edac_mc_handle_ce(mci, page, 0, syndrome, row, channel, - "e7xxx CE"); + edac_mc_handle_ce(mci, page, 0, syndrome, row, channel, "e7xxx CE"); } - static void process_ce_no_info(struct mem_ctl_info *mci) { debugf3("%s()\n", __func__); edac_mc_handle_ce_no_info(mci, "e7xxx CE log register overflow"); } - -static void process_ue(struct mem_ctl_info *mci, struct e7xxx_error_info *info) +static void process_ue(struct mem_ctl_info *mci, + struct e7xxx_error_info *info) { u32 error_2b, block_page; int row; debugf3("%s()\n", __func__); - /* read the error address */ error_2b = info->dram_uelog_add; /* FIXME - should use PAGE_SHIFT */ - block_page = error_2b >> 6; /* convert to 4k address */ + block_page = error_2b >> 6; /* convert to 4k address */ row = edac_mc_find_csrow_by_page(mci, block_page); edac_mc_handle_ue(mci, block_page, 0, row, "e7xxx UE"); } - static void process_ue_no_info(struct mem_ctl_info *mci) { debugf3("%s()\n", __func__); edac_mc_handle_ue_no_info(mci, "e7xxx UE log register overflow"); } - static void e7xxx_get_error_info (struct mem_ctl_info *mci, struct e7xxx_error_info *info) { @@ -261,31 +254,29 @@ static void e7xxx_get_error_info (struct mem_ctl_info *mci, pvt = (struct e7xxx_pvt *) mci->pvt_info; pci_read_config_byte(pvt->bridge_ck, E7XXX_DRAM_FERR, - &info->dram_ferr); + &info->dram_ferr); pci_read_config_byte(pvt->bridge_ck, E7XXX_DRAM_NERR, - &info->dram_nerr); + &info->dram_nerr); if ((info->dram_ferr & 1) || (info->dram_nerr & 1)) { pci_read_config_dword(pvt->bridge_ck, E7XXX_DRAM_CELOG_ADD, - &info->dram_celog_add); + &info->dram_celog_add); pci_read_config_word(pvt->bridge_ck, - E7XXX_DRAM_CELOG_SYNDROME, &info->dram_celog_syndrome); + E7XXX_DRAM_CELOG_SYNDROME, + &info->dram_celog_syndrome); } if ((info->dram_ferr & 2) || (info->dram_nerr & 2)) pci_read_config_dword(pvt->bridge_ck, E7XXX_DRAM_UELOG_ADD, - &info->dram_uelog_add); + &info->dram_uelog_add); if (info->dram_ferr & 3) - pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_FERR, 0x03, - 0x03); + pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_FERR, 0x03, 0x03); if (info->dram_nerr & 3) - pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_NERR, 0x03, - 0x03); + pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_NERR, 0x03, 0x03); } - static int e7xxx_process_error_info (struct mem_ctl_info *mci, struct e7xxx_error_info *info, int handle_errors) { @@ -333,7 +324,6 @@ static int e7xxx_process_error_info (struct mem_ctl_info *mci, return error_found; } - static void e7xxx_check(struct mem_ctl_info *mci) { struct e7xxx_error_info info; @@ -343,7 +333,6 @@ static void e7xxx_check(struct mem_ctl_info *mci) e7xxx_process_error_info(mci, &info, 1); } - static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) { int rc = -ENODEV; @@ -363,13 +352,14 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) /* need to find out the number of channels */ pci_read_config_dword(pdev, E7XXX_DRC, &drc); + /* only e7501 can be single channel */ if (dev_idx == E7501) { drc_chan = ((drc >> 22) & 0x1); drc_drbg = (drc >> 18) & 0x3; } - drc_ddim = (drc >> 20) & 0x3; + drc_ddim = (drc >> 20) & 0x3; mci = edac_mc_alloc(sizeof(*pvt), E7XXX_NR_CSROWS, drc_chan + 1); if (mci == NULL) { @@ -378,10 +368,9 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) } debugf3("%s(): init mci\n", __func__); - mci->mtype_cap = MEM_FLAG_RDDR; - mci->edac_ctl_cap = - EDAC_FLAG_NONE | EDAC_FLAG_SECDED | EDAC_FLAG_S4ECD4ED; + mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED | + EDAC_FLAG_S4ECD4ED; /* FIXME - what if different memory types are in different csrows? */ mci->mod_name = EDAC_MOD_STR; mci->mod_ver = "$Revision: 1.5.2.9 $"; @@ -391,19 +380,18 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) pvt = (struct e7xxx_pvt *) mci->pvt_info; pvt->dev_info = &e7xxx_devs[dev_idx]; pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL, - pvt->dev_info->err_dev, - pvt->bridge_ck); + pvt->dev_info->err_dev, + pvt->bridge_ck); + if (!pvt->bridge_ck) { e7xxx_printk(KERN_ERR, "error reporting device not found:" - "vendor %x device 0x%x (broken BIOS?)\n", - PCI_VENDOR_ID_INTEL, - e7xxx_devs[dev_idx].err_dev); + "vendor %x device 0x%x (broken BIOS?)\n", + PCI_VENDOR_ID_INTEL, e7xxx_devs[dev_idx].err_dev); goto fail; } debugf3("%s(): more mci init\n", __func__); mci->ctl_name = pvt->dev_info->ctl_name; - mci->edac_check = e7xxx_check; mci->ctl_page_to_phys = ctl_page_to_phys; @@ -428,15 +416,16 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) cumul_size = value << (25 + drc_drbg - PAGE_SHIFT); debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, cumul_size); + if (cumul_size == last_cumul_size) - continue; /* not populated */ + continue; /* not populated */ csrow->first_page = last_cumul_size; csrow->last_page = cumul_size - 1; csrow->nr_pages = cumul_size - last_cumul_size; last_cumul_size = cumul_size; - csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */ - csrow->mtype = MEM_RDDR; /* only one type supported */ + csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */ + csrow->mtype = MEM_RDDR; /* only one type supported */ csrow->dtype = mem_dev ? DEV_X4 : DEV_X8; /* @@ -466,8 +455,8 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) pci_read_config_word(mci->pdev, E7XXX_REMAPLIMIT, &pci_data); pvt->remaplimit = ((u32) pci_data) << 14; e7xxx_printk(KERN_INFO, - "tolm = %x, remapbase = %x, remaplimit = %x\n", - pvt->tolm, pvt->remapbase, pvt->remaplimit); + "tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm, + pvt->remapbase, pvt->remaplimit); /* clear any pending errors, or initial state bits */ e7xxx_get_error_info(mci, &discard); @@ -492,17 +481,16 @@ fail: } /* returns count (>= 0), or negative on error */ -static int __devinit -e7xxx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +static int __devinit e7xxx_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) { debugf0("%s()\n", __func__); /* wake up and enable device */ return pci_enable_device(pdev) ? - -EIO : e7xxx_probe1(pdev, ent->driver_data); + -EIO : e7xxx_probe1(pdev, ent->driver_data); } - static void __devexit e7xxx_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; @@ -518,22 +506,30 @@ static void __devexit e7xxx_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } - static const struct pci_device_id e7xxx_pci_tbl[] __devinitdata = { - {PCI_VEND_DEV(INTEL, 7205_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - E7205}, - {PCI_VEND_DEV(INTEL, 7500_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - E7500}, - {PCI_VEND_DEV(INTEL, 7501_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - E7501}, - {PCI_VEND_DEV(INTEL, 7505_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - E7505}, - {0,} /* 0 terminated list. */ + { + PCI_VEND_DEV(INTEL, 7205_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + E7205 + }, + { + PCI_VEND_DEV(INTEL, 7500_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + E7500 + }, + { + PCI_VEND_DEV(INTEL, 7501_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + E7501 + }, + { + PCI_VEND_DEV(INTEL, 7505_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + E7505 + }, + { + 0, + } /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, e7xxx_pci_tbl); - static struct pci_driver e7xxx_driver = { .name = EDAC_MOD_STR, .probe = e7xxx_init_one, @@ -541,13 +537,11 @@ static struct pci_driver e7xxx_driver = { .id_table = e7xxx_pci_tbl, }; - static int __init e7xxx_init(void) { return pci_register_driver(&e7xxx_driver); } - static void __exit e7xxx_exit(void) { pci_unregister_driver(&e7xxx_driver); @@ -556,8 +550,7 @@ static void __exit e7xxx_exit(void) module_init(e7xxx_init); module_exit(e7xxx_exit); - MODULE_LICENSE("GPL"); MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh et al\n" - "Based on.work by Dan Hollis et al"); + "Based on.work by Dan Hollis et al"); MODULE_DESCRIPTION("MC support for Intel e7xxx memory controllers"); diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index f67a4d6f897..bb3460457fa 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -12,7 +12,6 @@ * */ - #include #include #include @@ -30,14 +29,12 @@ #include #include #include - #include #include #include - #include "edac_mc.h" -#define EDAC_MC_VERSION "Ver: 2.0.0 " __DATE__ +#define EDAC_MC_VERSION "Ver: 2.0.0 " __DATE__ /* For now, disable the EDAC sysfs code. The sysfs interface that EDAC * presents to user space needs more thought, and is likely to change @@ -73,7 +70,6 @@ struct edac_pci_device_list { unsigned int device; /* Deviice ID */ }; - #define MAX_LISTED_PCI_DEVICES 32 /* List of PCI devices (vendor-id:device-id) that should be skipped */ @@ -126,7 +122,6 @@ static const char *edac_caps[] = { [EDAC_S16ECD16ED] = "S16ECD16ED" }; - /* sysfs object: /sys/devices/system/edac */ static struct sysdev_class edac_class = { set_kset_name("edac"), @@ -147,7 +142,7 @@ static struct completion edac_pci_kobj_complete; /* * /sys/devices/system/edac/mc; - * data structures and methods + * data structures and methods */ #if 0 static ssize_t memctrl_string_show(void *ptr, char *buffer) @@ -174,33 +169,34 @@ static ssize_t memctrl_int_store(void *ptr, const char *buffer, size_t count) } struct memctrl_dev_attribute { - struct attribute attr; - void *value; + struct attribute attr; + void *value; ssize_t (*show)(void *,char *); ssize_t (*store)(void *, const char *, size_t); }; /* Set of show/store abstract level functions for memory control object */ -static ssize_t -memctrl_dev_show(struct kobject *kobj, struct attribute *attr, char *buffer) +static ssize_t memctrl_dev_show(struct kobject *kobj, + struct attribute *attr, char *buffer) { struct memctrl_dev_attribute *memctrl_dev; memctrl_dev = (struct memctrl_dev_attribute*)attr; if (memctrl_dev->show) return memctrl_dev->show(memctrl_dev->value, buffer); + return -EIO; } -static ssize_t -memctrl_dev_store(struct kobject *kobj, struct attribute *attr, - const char *buffer, size_t count) +static ssize_t memctrl_dev_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) { struct memctrl_dev_attribute *memctrl_dev; memctrl_dev = (struct memctrl_dev_attribute*)attr; if (memctrl_dev->store) return memctrl_dev->store(memctrl_dev->value, buffer, count); + return -EIO; } @@ -236,7 +232,6 @@ MEMCTRL_ATTR(log_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store); MEMCTRL_ATTR(log_ce,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store); MEMCTRL_ATTR(poll_msec,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store); - /* Base Attributes of the memory ECC object */ static struct memctrl_dev_attribute *memctrl_attr[] = { &attr_panic_on_ue, @@ -254,9 +249,9 @@ static void edac_memctrl_master_release(struct kobject *kobj) } static struct kobj_type ktype_memctrl = { - .release = edac_memctrl_master_release, - .sysfs_ops = &memctrlfs_ops, - .default_attrs = (struct attribute **) memctrl_attr, + .release = edac_memctrl_master_release, + .sysfs_ops = &memctrlfs_ops, + .default_attrs = (struct attribute **) memctrl_attr, }; #endif /* DISABLE_EDAC_SYSFS */ @@ -282,6 +277,7 @@ static int edac_sysfs_memctrl_setup(void) /* create the /sys/devices/system/edac directory */ err = sysdev_class_register(&edac_class); + if (!err) { /* Init the MC's kobject */ memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); @@ -290,18 +286,18 @@ static int edac_sysfs_memctrl_setup(void) /* generate sysfs "..../edac/mc" */ err = kobject_set_name(&edac_memctrl_kobj,"mc"); + if (!err) { /* FIXME: maybe new sysdev_create_subdir() */ err = kobject_register(&edac_memctrl_kobj); - if (err) { + + if (err) debugf1("Failed to register '.../edac/mc'\n"); - } else { + else debugf1("Registered '.../edac/mc' kobject\n"); - } } - } else { + } else debugf1("%s() error=%d\n", __func__, err); - } return err; } @@ -340,7 +336,6 @@ struct list_control { int *count; }; - #if 0 /* Output the list as: vendor_id:device:id<,vendor_id:device_id> */ static ssize_t edac_pci_list_string_show(void *ptr, char *buffer) @@ -365,7 +360,6 @@ static ssize_t edac_pci_list_string_show(void *ptr, char *buffer) } len += snprintf(p + len,(PAGE_SIZE-len), "\n"); - return (ssize_t) len; } @@ -387,7 +381,7 @@ static int parse_one_device(const char **s,const char **e, /* if null byte, we are done */ if (!**s) { - (*s)++; /* keep *s moving */ + (*s)++; /* keep *s moving */ return 0; } @@ -404,6 +398,7 @@ static int parse_one_device(const char **s,const char **e, /* parse vendor_id */ runner = *s; + while (runner < *e) { /* scan for vendor:device delimiter */ if (*runner == ':') { @@ -411,6 +406,7 @@ static int parse_one_device(const char **s,const char **e, runner = p + 1; break; } + runner++; } @@ -426,12 +422,11 @@ static int parse_one_device(const char **s,const char **e, } *s = runner; - return 1; } static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer, - size_t count) + size_t count) { struct list_control *listctl; struct edac_pci_device_list *list; @@ -441,14 +436,12 @@ static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer, s = (char*)buffer; e = s + count; - listctl = ptr; list = listctl->list; index = listctl->count; - *index = 0; - while (*index < MAX_LISTED_PCI_DEVICES) { + while (*index < MAX_LISTED_PCI_DEVICES) { if (parse_one_device(&s,&e,&vendor_id,&device_id)) { list[ *index ].vendor = vendor_id; list[ *index ].device = device_id; @@ -481,15 +474,15 @@ static ssize_t edac_pci_int_store(void *ptr, const char *buffer, size_t count) } struct edac_pci_dev_attribute { - struct attribute attr; - void *value; + struct attribute attr; + void *value; ssize_t (*show)(void *,char *); ssize_t (*store)(void *, const char *,size_t); }; /* Set of show/store abstract level functions for PCI Parity object */ static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr, - char *buffer) + char *buffer) { struct edac_pci_dev_attribute *edac_pci_dev; edac_pci_dev= (struct edac_pci_dev_attribute*)attr; @@ -499,8 +492,8 @@ static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr, return -EIO; } -static ssize_t edac_pci_dev_store(struct kobject *kobj, struct attribute *attr, - const char *buffer, size_t count) +static ssize_t edac_pci_dev_store(struct kobject *kobj, + struct attribute *attr, const char *buffer, size_t count) { struct edac_pci_dev_attribute *edac_pci_dev; edac_pci_dev= (struct edac_pci_dev_attribute*)attr; @@ -515,7 +508,6 @@ static struct sysfs_ops edac_pci_sysfs_ops = { .store = edac_pci_dev_store }; - #define EDAC_PCI_ATTR(_name,_mode,_show,_store) \ struct edac_pci_dev_attribute edac_pci_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ @@ -558,9 +550,11 @@ EDAC_PCI_STRING_ATTR(pci_parity_blacklist, #endif /* PCI Parity control files */ -EDAC_PCI_ATTR(check_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store); -EDAC_PCI_ATTR(panic_on_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store); -EDAC_PCI_ATTR(pci_parity_count,S_IRUGO,edac_pci_int_show,NULL); +EDAC_PCI_ATTR(check_pci_parity, S_IRUGO|S_IWUSR, edac_pci_int_show, + edac_pci_int_store); +EDAC_PCI_ATTR(panic_on_pci_parity, S_IRUGO|S_IWUSR, edac_pci_int_show, + edac_pci_int_store); +EDAC_PCI_ATTR(pci_parity_count, S_IRUGO, edac_pci_int_show, NULL); /* Base Attributes of the memory ECC object */ static struct edac_pci_dev_attribute *edac_pci_attr[] = { @@ -578,9 +572,9 @@ static void edac_pci_release(struct kobject *kobj) } static struct kobj_type ktype_edac_pci = { - .release = edac_pci_release, - .sysfs_ops = &edac_pci_sysfs_ops, - .default_attrs = (struct attribute **) edac_pci_attr, + .release = edac_pci_release, + .sysfs_ops = &edac_pci_sysfs_ops, + .default_attrs = (struct attribute **) edac_pci_attr, }; #endif /* DISABLE_EDAC_SYSFS */ @@ -603,17 +597,19 @@ static int edac_sysfs_pci_setup(void) memset(&edac_pci_kobj, 0, sizeof(edac_pci_kobj)); edac_pci_kobj.parent = &edac_class.kset.kobj; edac_pci_kobj.ktype = &ktype_edac_pci; - err = kobject_set_name(&edac_pci_kobj, "pci"); + if (!err) { /* Instanstiate the csrow object */ /* FIXME: maybe new sysdev_create_subdir() */ err = kobject_register(&edac_pci_kobj); + if (err) debugf1("Failed to register '.../edac/pci'\n"); else debugf1("Registered '.../edac/pci' kobject\n"); } + return err; } #endif /* DISABLE_EDAC_SYSFS */ @@ -641,6 +637,7 @@ static ssize_t csrow_ch0_dimm_label_show(struct csrow_info *csrow, char *data) size = snprintf(data, EDAC_MC_LABEL_LEN,"%s\n", csrow->channels[0].label); } + return size; } @@ -652,11 +649,12 @@ static ssize_t csrow_ch1_dimm_label_show(struct csrow_info *csrow, char *data) size = snprintf(data, EDAC_MC_LABEL_LEN, "%s\n", csrow->channels[1].label); } + return size; } static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow, - const char *data, size_t size) + const char *data, size_t size) { ssize_t max_size = 0; @@ -665,11 +663,12 @@ static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow, strncpy(csrow->channels[0].label, data, max_size); csrow->channels[0].label[max_size] = '\0'; } + return size; } static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow, - const char *data, size_t size) + const char *data, size_t size) { ssize_t max_size = 0; @@ -678,6 +677,7 @@ static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow, strncpy(csrow->channels[1].label, data, max_size); csrow->channels[1].label[max_size] = '\0'; } + return max_size; } @@ -698,6 +698,7 @@ static ssize_t csrow_ch0_ce_count_show(struct csrow_info *csrow, char *data) if (csrow->nr_channels > 0) { size = sprintf(data,"%u\n", csrow->channels[0].ce_count); } + return size; } @@ -708,6 +709,7 @@ static ssize_t csrow_ch1_ce_count_show(struct csrow_info *csrow, char *data) if (csrow->nr_channels > 1) { size = sprintf(data,"%u\n", csrow->channels[1].ce_count); } + return size; } @@ -732,7 +734,7 @@ static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data) } struct csrowdev_attribute { - struct attribute attr; + struct attribute attr; ssize_t (*show)(struct csrow_info *,char *); ssize_t (*store)(struct csrow_info *, const char *,size_t); }; @@ -742,24 +744,26 @@ struct csrowdev_attribute { /* Set of show/store higher level functions for csrow objects */ static ssize_t csrowdev_show(struct kobject *kobj, struct attribute *attr, - char *buffer) + char *buffer) { struct csrow_info *csrow = to_csrow(kobj); struct csrowdev_attribute *csrowdev_attr = to_csrowdev_attr(attr); if (csrowdev_attr->show) return csrowdev_attr->show(csrow, buffer); + return -EIO; } static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr, - const char *buffer, size_t count) + const char *buffer, size_t count) { struct csrow_info *csrow = to_csrow(kobj); struct csrowdev_attribute * csrowdev_attr = to_csrowdev_attr(attr); if (csrowdev_attr->store) return csrowdev_attr->store(csrow, buffer, count); + return -EIO; } @@ -793,7 +797,6 @@ CSROWDEV_ATTR(ch1_dimm_label,S_IRUGO|S_IWUSR, csrow_ch1_dimm_label_show, csrow_ch1_dimm_label_store); - /* Attributes of the CSROW object */ static struct csrowdev_attribute *csrow_attr[] = { &attr_dev_type, @@ -809,7 +812,6 @@ static struct csrowdev_attribute *csrow_attr[] = { NULL, }; - /* No memory to release */ static void edac_csrow_instance_release(struct kobject *kobj) { @@ -821,19 +823,18 @@ static void edac_csrow_instance_release(struct kobject *kobj) } static struct kobj_type ktype_csrow = { - .release = edac_csrow_instance_release, - .sysfs_ops = &csrowfs_ops, - .default_attrs = (struct attribute **) csrow_attr, + .release = edac_csrow_instance_release, + .sysfs_ops = &csrowfs_ops, + .default_attrs = (struct attribute **) csrow_attr, }; /* Create a CSROW object under specifed edac_mc_device */ static int edac_create_csrow_object(struct kobject *edac_mci_kobj, - struct csrow_info *csrow, int index ) + struct csrow_info *csrow, int index) { int err = 0; debugf0("%s()\n", __func__); - memset(&csrow->kobj, 0, sizeof(csrow->kobj)); /* generate ..../edac/mc/mc/csrow */ @@ -843,9 +844,11 @@ static int edac_create_csrow_object(struct kobject *edac_mci_kobj, /* name this instance of csrow */ err = kobject_set_name(&csrow->kobj,"csrow%d",index); + if (!err) { /* Instanstiate the csrow object */ err = kobject_register(&csrow->kobj); + if (err) debugf0("Failed to register CSROW%d\n",index); else @@ -857,8 +860,8 @@ static int edac_create_csrow_object(struct kobject *edac_mci_kobj, /* sysfs data structures and methods for the MCI kobjects */ -static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci, - const char *data, size_t count ) +static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci, + const char *data, size_t count) { int row, chan; @@ -866,16 +869,18 @@ static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci, mci->ce_noinfo_count = 0; mci->ue_count = 0; mci->ce_count = 0; + for (row = 0; row < mci->nr_csrows; row++) { struct csrow_info *ri = &mci->csrows[row]; ri->ue_count = 0; ri->ce_count = 0; + for (chan = 0; chan < ri->nr_channels; chan++) ri->channels[chan].ce_count = 0; } - mci->start_time = jiffies; + mci->start_time = jiffies; return count; } @@ -933,18 +938,16 @@ static ssize_t mci_edac_capability_show(struct mem_ctl_info *mci, char *data) p += mci_output_edac_cap(p,mci->edac_ctl_cap); p += sprintf(p, "\n"); - return p - data; } static ssize_t mci_edac_current_capability_show(struct mem_ctl_info *mci, - char *data) + char *data) { char *p = data; p += mci_output_edac_cap(p,mci->edac_cap); p += sprintf(p, "\n"); - return p - data; } @@ -961,13 +964,13 @@ static int mci_output_mtype_cap(char *buf, unsigned long mtype_cap) return p - buf; } -static ssize_t mci_supported_mem_type_show(struct mem_ctl_info *mci, char *data) +static ssize_t mci_supported_mem_type_show(struct mem_ctl_info *mci, + char *data) { char *p = data; p += mci_output_mtype_cap(p,mci->mtype_cap); p += sprintf(p, "\n"); - return p - data; } @@ -981,6 +984,7 @@ static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data) if (!csrow->nr_pages) continue; + total_pages += csrow->nr_pages; } @@ -988,7 +992,7 @@ static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data) } struct mcidev_attribute { - struct attribute attr; + struct attribute attr; ssize_t (*show)(struct mem_ctl_info *,char *); ssize_t (*store)(struct mem_ctl_info *, const char *,size_t); }; @@ -997,30 +1001,32 @@ struct mcidev_attribute { #define to_mcidev_attr(a) container_of(a, struct mcidev_attribute, attr) static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr, - char *buffer) + char *buffer) { struct mem_ctl_info *mem_ctl_info = to_mci(kobj); struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr); if (mcidev_attr->show) return mcidev_attr->show(mem_ctl_info, buffer); + return -EIO; } static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr, - const char *buffer, size_t count) + const char *buffer, size_t count) { struct mem_ctl_info *mem_ctl_info = to_mci(kobj); struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr); if (mcidev_attr->store) return mcidev_attr->store(mem_ctl_info, buffer, count); + return -EIO; } static struct sysfs_ops mci_ops = { - .show = mcidev_show, - .store = mcidev_store + .show = mcidev_show, + .store = mcidev_store }; #define MCIDEV_ATTR(_name,_mode,_show,_store) \ @@ -1048,7 +1054,6 @@ MCIDEV_ATTR(edac_current_capability,S_IRUGO, MCIDEV_ATTR(supported_mem_type,S_IRUGO, mci_supported_mem_type_show,NULL); - static struct mcidev_attribute *mci_attr[] = { &mci_attr_reset_counters, &mci_attr_module_name, @@ -1065,7 +1070,6 @@ static struct mcidev_attribute *mci_attr[] = { NULL }; - /* * Release of a MC controlling instance */ @@ -1079,9 +1083,9 @@ static void edac_mci_instance_release(struct kobject *kobj) } static struct kobj_type ktype_mci = { - .release = edac_mci_instance_release, - .sysfs_ops = &mci_ops, - .default_attrs = (struct attribute **) mci_attr, + .release = edac_mci_instance_release, + .sysfs_ops = &mci_ops, + .default_attrs = (struct attribute **) mci_attr, }; #endif /* DISABLE_EDAC_SYSFS */ @@ -1109,11 +1113,11 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) struct kobject *edac_mci_kobj=&mci->edac_mci_kobj; debugf0("%s() idx=%d\n", __func__, mci->mc_idx); - memset(edac_mci_kobj, 0, sizeof(*edac_mci_kobj)); /* set the name of the mc object */ err = kobject_set_name(edac_mci_kobj,"mc%d",mci->mc_idx); + if (err) return err; @@ -1123,12 +1127,14 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) /* register the mc kobject */ err = kobject_register(edac_mci_kobj); + if (err) return err; /* create a symlink for the device */ err = sysfs_create_link(edac_mci_kobj, &mci->pdev->dev.kobj, EDAC_DEVICE_SYMLINK); + if (err) goto fail0; @@ -1136,12 +1142,12 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) * under the mc kobject */ for (i = 0; i < mci->nr_csrows; i++) { - csrow = &mci->csrows[i]; /* Only expose populated CSROWs */ if (csrow->nr_pages > 0) { err = edac_create_csrow_object(edac_mci_kobj,csrow,i); + if (err) goto fail1; } @@ -1149,7 +1155,6 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) return 0; - /* CSROW error: backout what has already been registered, */ fail1: for ( i--; i >= 0; i--) { @@ -1164,7 +1169,6 @@ fail0: init_completion(&mci->kobj_complete); kobject_unregister(edac_mci_kobj); wait_for_completion(&mci->kobj_complete); - return err; } #endif /* DISABLE_EDAC_SYSFS */ @@ -1199,7 +1203,6 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) #ifdef CONFIG_EDAC_DEBUG - void edac_mc_dump_channel(struct channel_info *chan) { debugf4("\tchannel = %p\n", chan); @@ -1210,7 +1213,6 @@ void edac_mc_dump_channel(struct channel_info *chan) } EXPORT_SYMBOL(edac_mc_dump_channel); - void edac_mc_dump_csrow(struct csrow_info *csrow) { debugf4("\tcsrow = %p\n", csrow); @@ -1227,7 +1229,6 @@ void edac_mc_dump_csrow(struct csrow_info *csrow) } EXPORT_SYMBOL(edac_mc_dump_csrow); - void edac_mc_dump_mci(struct mem_ctl_info *mci) { debugf3("\tmci = %p\n", mci); @@ -1244,8 +1245,7 @@ void edac_mc_dump_mci(struct mem_ctl_info *mci) } EXPORT_SYMBOL(edac_mc_dump_mci); - -#endif /* CONFIG_EDAC_DEBUG */ +#endif /* CONFIG_EDAC_DEBUG */ /* 'ptr' points to a possibly unaligned item X such that sizeof(X) is 'size'. * Adjust 'ptr' so that its alignment is at least as stringent as what the @@ -1254,7 +1254,7 @@ EXPORT_SYMBOL(edac_mc_dump_mci); * If 'size' is a constant, the compiler will optimize this whole function * down to either a no-op or the addition of a constant to the value of 'ptr'. */ -static inline char * align_ptr (void *ptr, unsigned size) +static inline char * align_ptr(void *ptr, unsigned size) { unsigned align, r; @@ -1281,7 +1281,6 @@ static inline char * align_ptr (void *ptr, unsigned size) return (char *) (((unsigned long) ptr) + align - r); } - /** * edac_mc_alloc: Allocate a struct mem_ctl_info structure * @size_pvt: size of private storage needed @@ -1299,7 +1298,7 @@ static inline char * align_ptr (void *ptr, unsigned size) * struct mem_ctl_info pointer */ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, - unsigned nr_chans) + unsigned nr_chans) { struct mem_ctl_info *mci; struct csrow_info *csi, *csrow; @@ -1330,8 +1329,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, chi = (struct channel_info *) (((char *) mci) + ((unsigned long) chi)); pvt = sz_pvt ? (((char *) mci) + ((unsigned long) pvt)) : NULL; - memset(mci, 0, size); /* clear all fields */ - + memset(mci, 0, size); /* clear all fields */ mci->csrows = csi; mci->pvt_info = pvt; mci->nr_csrows = nr_csrows; @@ -1355,7 +1353,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, } EXPORT_SYMBOL(edac_mc_alloc); - /** * edac_mc_free: Free a previously allocated 'mci' structure * @mci: pointer to a struct mem_ctl_info structure @@ -1383,7 +1380,7 @@ static struct mem_ctl_info *find_mci_by_pdev(struct pci_dev *pdev) return NULL; } -static int add_mc_to_global_list (struct mem_ctl_info *mci) +static int add_mc_to_global_list(struct mem_ctl_info *mci) { struct list_head *item, *insert_before; struct mem_ctl_info *p; @@ -1426,8 +1423,7 @@ static int add_mc_to_global_list (struct mem_ctl_info *mci) return 0; } - -static void complete_mc_list_del (struct rcu_head *head) +static void complete_mc_list_del(struct rcu_head *head) { struct mem_ctl_info *mci; @@ -1436,8 +1432,7 @@ static void complete_mc_list_del (struct rcu_head *head) complete(&mci->complete); } - -static void del_mc_from_global_list (struct mem_ctl_info *mci) +static void del_mc_from_global_list(struct mem_ctl_info *mci) { list_del_rcu(&mci->link); init_completion(&mci->complete); @@ -1445,7 +1440,6 @@ static void del_mc_from_global_list (struct mem_ctl_info *mci) wait_for_completion(&mci->complete); } - /** * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and * create sysfs entries associated with mci structure @@ -1463,15 +1457,17 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) #ifdef CONFIG_EDAC_DEBUG if (edac_debug_level >= 3) edac_mc_dump_mci(mci); + if (edac_debug_level >= 4) { int i; for (i = 0; i < mci->nr_csrows; i++) { int j; + edac_mc_dump_csrow(&mci->csrows[i]); for (j = 0; j < mci->csrows[i].nr_channels; j++) - edac_mc_dump_channel(&mci->csrows[i]. - channels[j]); + edac_mc_dump_channel( + &mci->csrows[i].channels[j]); } } #endif @@ -1505,7 +1501,6 @@ fail0: } EXPORT_SYMBOL(edac_mc_add_mc); - /** * edac_mc_del_mc: Remove sysfs entries for specified mci structure and * remove mci structure from global list @@ -1535,9 +1530,7 @@ struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev) } EXPORT_SYMBOL(edac_mc_del_mc); - -void edac_mc_scrub_block(unsigned long page, unsigned long offset, - u32 size) +void edac_mc_scrub_block(unsigned long page, unsigned long offset, u32 size) { struct page *pg; void *virt_addr; @@ -1568,10 +1561,8 @@ void edac_mc_scrub_block(unsigned long page, unsigned long offset, } EXPORT_SYMBOL(edac_mc_scrub_block); - /* FIXME - should return -1 */ -int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, - unsigned long page) +int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page) { struct csrow_info *csrows = mci->csrows; int row, i; @@ -1608,14 +1599,11 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, } EXPORT_SYMBOL(edac_mc_find_csrow_by_page); - /* FIXME - setable log (warning/emerg) levels */ /* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */ void edac_mc_handle_ce(struct mem_ctl_info *mci, - unsigned long page_frame_number, - unsigned long offset_in_page, - unsigned long syndrome, int row, int channel, - const char *msg) + unsigned long page_frame_number, unsigned long offset_in_page, + unsigned long syndrome, int row, int channel, const char *msg) { unsigned long remapped_page; @@ -1630,6 +1618,7 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci, edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR"); return; } + if (channel >= mci->csrows[row].nr_channels || channel < 0) { /* something is wrong */ edac_mc_printk(mci, KERN_ERR, @@ -1668,28 +1657,25 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci, page_frame_number; edac_mc_scrub_block(remapped_page, offset_in_page, - mci->csrows[row].grain); + mci->csrows[row].grain); } } EXPORT_SYMBOL(edac_mc_handle_ce); - -void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, - const char *msg) +void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg) { if (log_ce) edac_mc_printk(mci, KERN_WARNING, "CE - no information available: %s\n", msg); + mci->ce_noinfo_count++; mci->ce_count++; } EXPORT_SYMBOL(edac_mc_handle_ce_no_info); - void edac_mc_handle_ue(struct mem_ctl_info *mci, - unsigned long page_frame_number, - unsigned long offset_in_page, int row, - const char *msg) + unsigned long page_frame_number, unsigned long offset_in_page, + int row, const char *msg) { int len = EDAC_MC_LABEL_LEN * 4; char labels[len + 1]; @@ -1710,13 +1696,14 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci, } chars = snprintf(pos, len + 1, "%s", - mci->csrows[row].channels[0].label); + mci->csrows[row].channels[0].label); len -= chars; pos += chars; + for (chan = 1; (chan < mci->csrows[row].nr_channels) && (len > 0); chan++) { chars = snprintf(pos, len + 1, ":%s", - mci->csrows[row].channels[chan].label); + mci->csrows[row].channels[chan].label); len -= chars; pos += chars; } @@ -1729,20 +1716,17 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci, msg); if (panic_on_ue) - panic - ("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, row %d," - " labels \"%s\": %s\n", mci->mc_idx, - page_frame_number, offset_in_page, - mci->csrows[row].grain, row, labels, msg); + panic("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, " + "row %d, labels \"%s\": %s\n", mci->mc_idx, + page_frame_number, offset_in_page, + mci->csrows[row].grain, row, labels, msg); mci->ue_count++; mci->csrows[row].ue_count++; } EXPORT_SYMBOL(edac_mc_handle_ue); - -void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, - const char *msg) +void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg) { if (panic_on_ue) panic("EDAC MC%d: Uncorrected Error", mci->mc_idx); @@ -1755,7 +1739,6 @@ void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, } EXPORT_SYMBOL(edac_mc_handle_ue_no_info); - #ifdef CONFIG_PCI static u16 get_pci_parity_status(struct pci_dev *dev, int secondary) @@ -1766,18 +1749,22 @@ static u16 get_pci_parity_status(struct pci_dev *dev, int secondary) where = secondary ? PCI_SEC_STATUS : PCI_STATUS; pci_read_config_word(dev, where, &status); - /* If we get back 0xFFFF then we must suspect that the card has been pulled but - the Linux PCI layer has not yet finished cleaning up. We don't want to report - on such devices */ + /* If we get back 0xFFFF then we must suspect that the card has been + * pulled but the Linux PCI layer has not yet finished cleaning up. + * We don't want to report on such devices + */ if (status == 0xFFFF) { u32 sanity; + pci_read_config_dword(dev, 0, &sanity); + if (sanity == 0xFFFFFFFF) return 0; } + status &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR | - PCI_STATUS_PARITY; + PCI_STATUS_PARITY; if (status) /* reset only the bits we are interested in */ @@ -1789,7 +1776,7 @@ static u16 get_pci_parity_status(struct pci_dev *dev, int secondary) typedef void (*pci_parity_check_fn_t) (struct pci_dev *dev); /* Clear any PCI parity errors logged by this device. */ -static void edac_pci_dev_parity_clear( struct pci_dev *dev ) +static void edac_pci_dev_parity_clear(struct pci_dev *dev) { u8 header_type; @@ -1890,58 +1877,55 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev) * Returns: 0 not found * 1 found on list */ -static int check_dev_on_list(struct edac_pci_device_list *list, int free_index, - struct pci_dev *dev) -{ - int i; - int rc = 0; /* Assume not found */ - unsigned short vendor=dev->vendor; - unsigned short device=dev->device; - - /* Scan the list, looking for a vendor/device match - */ - for (i = 0; i < free_index; i++, list++ ) { - if ( (list->vendor == vendor ) && - (list->device == device )) { - rc = 1; - break; - } - } +static int check_dev_on_list(struct edac_pci_device_list *list, + int free_index, struct pci_dev *dev) +{ + int i; + int rc = 0; /* Assume not found */ + unsigned short vendor=dev->vendor; + unsigned short device=dev->device; + + /* Scan the list, looking for a vendor/device match */ + for (i = 0; i < free_index; i++, list++ ) { + if ((list->vendor == vendor ) && (list->device == device )) { + rc = 1; + break; + } + } - return rc; + return rc; } /* * pci_dev parity list iterator - * Scan the PCI device list for one iteration, looking for SERRORs + * Scan the PCI device list for one iteration, looking for SERRORs * Master Parity ERRORS or Parity ERRORs on primary or secondary devices */ static inline void edac_pci_dev_parity_iterator(pci_parity_check_fn_t fn) { - struct pci_dev *dev=NULL; + struct pci_dev *dev = NULL; /* request for kernel access to the next PCI device, if any, * and while we are looking at it have its reference count * bumped until we are done with it */ while((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - - /* if whitelist exists then it has priority, so only scan those - * devices on the whitelist - */ - if (pci_whitelist_count > 0 ) { - if (check_dev_on_list(pci_whitelist, + /* if whitelist exists then it has priority, so only scan + * those devices on the whitelist + */ + if (pci_whitelist_count > 0 ) { + if (check_dev_on_list(pci_whitelist, pci_whitelist_count, dev)) fn(dev); - } else { + } else { /* * if no whitelist, then check if this devices is * blacklisted */ - if (!check_dev_on_list(pci_blacklist, + if (!check_dev_on_list(pci_blacklist, pci_blacklist_count, dev)) fn(dev); - } + } } } @@ -1972,7 +1956,6 @@ static void do_pci_parity_check(void) } } - static inline void clear_pci_parity_errors(void) { /* Clear any PCI bus parity errors that devices initially have logged @@ -1981,34 +1964,29 @@ static inline void clear_pci_parity_errors(void) edac_pci_dev_parity_iterator(edac_pci_dev_parity_clear); } - #else /* CONFIG_PCI */ - static inline void do_pci_parity_check(void) { /* no-op */ } - static inline void clear_pci_parity_errors(void) { /* no-op */ } - #endif /* CONFIG_PCI */ /* * Iterate over all MC instances and check for ECC, et al, errors */ -static inline void check_mc_devices (void) +static inline void check_mc_devices(void) { struct list_head *item; struct mem_ctl_info *mci; debugf3("%s()\n", __func__); - down(&mem_ctls_mutex); list_for_each(item, &mc_devices) { @@ -2021,7 +1999,6 @@ static inline void check_mc_devices (void) up(&mem_ctls_mutex); } - /* * Check MC status every poll_msec. * Check PCI status every poll_msec as well. @@ -2084,6 +2061,7 @@ static int __init edac_mc_init(void) /* create our kernel thread */ edac_thread = kthread_run(edac_kernel_thread, NULL, "kedac"); + if (IS_ERR(edac_thread)) { /* remove the sysfs entries */ edac_sysfs_memctrl_teardown(); @@ -2094,7 +2072,6 @@ static int __init edac_mc_init(void) return 0; } - /* * edac_mc_exit() * module exit/termination functioni @@ -2102,7 +2079,6 @@ static int __init edac_mc_init(void) static void __exit edac_mc_exit(void) { debugf0("%s()\n", __func__); - kthread_stop(edac_thread); /* tear down the sysfs device */ @@ -2110,15 +2086,12 @@ static void __exit edac_mc_exit(void) edac_sysfs_pci_teardown(); } - - - module_init(edac_mc_init); module_exit(edac_mc_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh et al\n" - "Based on.work by Dan Hollis et al"); + "Based on work by Dan Hollis et al"); MODULE_DESCRIPTION("Core library routines for MC reporting"); module_param(panic_on_ue, int, 0644); diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h index 2cec157aaeb..8d9e83909b9 100644 --- a/drivers/edac/edac_mc.h +++ b/drivers/edac/edac_mc.h @@ -15,11 +15,9 @@ * */ - #ifndef _EDAC_MC_H_ #define _EDAC_MC_H_ - #include #include #include @@ -33,7 +31,6 @@ #include #include - #define EDAC_MC_LABEL_LEN 31 #define MC_PROC_NAME_MAX_LEN 7 @@ -44,13 +41,13 @@ #endif #define edac_printk(level, prefix, fmt, arg...) \ - printk(level "EDAC " prefix ": " fmt, ##arg) + printk(level "EDAC " prefix ": " fmt, ##arg) #define edac_mc_printk(mci, level, fmt, arg...) \ - printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg) + printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg) #define edac_mc_chipset_printk(mci, level, prefix, fmt, arg...) \ - printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg) + printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg) /* prefixes for edac_printk() and edac_mc_printk() */ #define EDAC_MC "MC" @@ -71,14 +68,16 @@ extern int edac_debug_level; #define debugf2( ... ) edac_debug_printk(2, __VA_ARGS__ ) #define debugf3( ... ) edac_debug_printk(3, __VA_ARGS__ ) #define debugf4( ... ) edac_debug_printk(4, __VA_ARGS__ ) -#else /* !CONFIG_EDAC_DEBUG */ + +#else /* !CONFIG_EDAC_DEBUG */ + #define debugf0( ... ) #define debugf1( ... ) #define debugf2( ... ) #define debugf3( ... ) #define debugf4( ... ) -#endif /* !CONFIG_EDAC_DEBUG */ +#endif /* !CONFIG_EDAC_DEBUG */ #define edac_xstr(s) edac_str(s) #define edac_str(s) #s @@ -86,7 +85,8 @@ extern int edac_debug_level; #define BIT(x) (1 << (x)) -#define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, PCI_DEVICE_ID_ ## vend ## _ ## dev +#define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \ + PCI_DEVICE_ID_ ## vend ## _ ## dev /* memory devices */ enum dev_type { @@ -136,7 +136,6 @@ enum mem_type { #define MEM_FLAG_RDDR BIT(MEM_RDDR) #define MEM_FLAG_RMBS BIT(MEM_RMBS) - /* chipset Error Detection and Correction capabilities and mode */ enum edac_type { EDAC_UNKNOWN = 0, /* Unknown if ECC is available */ @@ -161,7 +160,6 @@ enum edac_type { #define EDAC_FLAG_S8ECD8ED BIT(EDAC_S8ECD8ED) #define EDAC_FLAG_S16ECD16ED BIT(EDAC_S16ECD16ED) - /* scrubbing capabilities */ enum scrub_type { SCRUB_UNKNOWN = 0, /* Unknown if scrubber is available */ @@ -269,20 +267,19 @@ enum scrub_type { * PS - I enjoyed writing all that about as much as you enjoyed reading it. */ - struct channel_info { int chan_idx; /* channel index */ u32 ce_count; /* Correctable Errors for this CHANNEL */ - char label[EDAC_MC_LABEL_LEN + 1]; /* DIMM label on motherboard */ + char label[EDAC_MC_LABEL_LEN + 1]; /* DIMM label on motherboard */ struct csrow_info *csrow; /* the parent */ }; - struct csrow_info { unsigned long first_page; /* first page number in dimm */ unsigned long last_page; /* last page number in dimm */ unsigned long page_mask; /* used for interleaving - - 0UL for non intlv */ + * 0UL for non intlv + */ u32 nr_pages; /* number of pages in csrow */ u32 grain; /* granularity of reported error in bytes */ int csrow_idx; /* the chip-select row */ @@ -301,18 +298,18 @@ struct csrow_info { struct channel_info *channels; }; - struct mem_ctl_info { struct list_head link; /* for global list of mem_ctl_info structs */ unsigned long mtype_cap; /* memory types supported by mc */ unsigned long edac_ctl_cap; /* Mem controller EDAC capabilities */ unsigned long edac_cap; /* configuration capabilities - this is - closely related to edac_ctl_cap. The - difference is that the controller - may be capable of s4ecd4ed which would - be listed in edac_ctl_cap, but if - channels aren't capable of s4ecd4ed then the - edac_cap would not have that capability. */ + * closely related to edac_ctl_cap. The + * difference is that the controller may be + * capable of s4ecd4ed which would be listed + * in edac_ctl_cap, but if channels aren't + * capable of s4ecd4ed then the edac_cap would + * not have that capability. + */ unsigned long scrub_cap; /* chipset scrub capabilities */ enum scrub_type scrub_mode; /* current scrub mode */ @@ -324,7 +321,7 @@ struct mem_ctl_info { */ /* FIXME - why not send the phys page to begin with? */ unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci, - unsigned long page); + unsigned long page); int mc_idx; int nr_csrows; struct csrow_info *csrows; @@ -356,67 +353,66 @@ struct mem_ctl_info { struct completion kobj_complete; }; - - /* write all or some bits in a byte-register*/ -static inline void pci_write_bits8(struct pci_dev *pdev, int offset, - u8 value, u8 mask) +static inline void pci_write_bits8(struct pci_dev *pdev, int offset, u8 value, + u8 mask) { if (mask != 0xff) { u8 buf; + pci_read_config_byte(pdev, offset, &buf); value &= mask; buf &= ~mask; value |= buf; } + pci_write_config_byte(pdev, offset, value); } - /* write all or some bits in a word-register*/ static inline void pci_write_bits16(struct pci_dev *pdev, int offset, - u16 value, u16 mask) + u16 value, u16 mask) { if (mask != 0xffff) { u16 buf; + pci_read_config_word(pdev, offset, &buf); value &= mask; buf &= ~mask; value |= buf; } + pci_write_config_word(pdev, offset, value); } - /* write all or some bits in a dword-register*/ static inline void pci_write_bits32(struct pci_dev *pdev, int offset, - u32 value, u32 mask) + u32 value, u32 mask) { if (mask != 0xffff) { u32 buf; + pci_read_config_dword(pdev, offset, &buf); value &= mask; buf &= ~mask; value |= buf; } + pci_write_config_dword(pdev, offset, value); } - #ifdef CONFIG_EDAC_DEBUG void edac_mc_dump_channel(struct channel_info *chan); void edac_mc_dump_mci(struct mem_ctl_info *mci); void edac_mc_dump_csrow(struct csrow_info *csrow); -#endif /* CONFIG_EDAC_DEBUG */ +#endif /* CONFIG_EDAC_DEBUG */ extern int edac_mc_add_mc(struct mem_ctl_info *mci); extern struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev); - extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, - unsigned long page); - -extern void edac_mc_scrub_block(unsigned long page, - unsigned long offset, u32 size); + unsigned long page); +extern void edac_mc_scrub_block(unsigned long page, unsigned long offset, + u32 size); /* * The no info errors are used when error overflows are reported. @@ -429,31 +425,25 @@ extern void edac_mc_scrub_block(unsigned long page, * statement clutter and extra function arguments. */ extern void edac_mc_handle_ce(struct mem_ctl_info *mci, - unsigned long page_frame_number, - unsigned long offset_in_page, - unsigned long syndrome, - int row, int channel, const char *msg); - + unsigned long page_frame_number, unsigned long offset_in_page, + unsigned long syndrome, int row, int channel, + const char *msg); extern void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, - const char *msg); - + const char *msg); extern void edac_mc_handle_ue(struct mem_ctl_info *mci, - unsigned long page_frame_number, - unsigned long offset_in_page, - int row, const char *msg); - + unsigned long page_frame_number, unsigned long offset_in_page, + int row, const char *msg); extern void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, - const char *msg); + const char *msg); /* * This kmalloc's and initializes all the structures. * Can't be used if all structures don't have the same lifetime. */ -extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, - unsigned nr_csrows, unsigned nr_chans); +extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, + unsigned nr_chans); /* Free an mc previously allocated by edac_mc_alloc() */ extern void edac_mc_free(struct mem_ctl_info *mci); - #endif /* _EDAC_MC_H_ */ diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c index 688854260a0..fd342163cf9 100644 --- a/drivers/edac/i82860_edac.c +++ b/drivers/edac/i82860_edac.c @@ -9,7 +9,6 @@ * by Thayne Harbaugh of Linux Networx. (http://lnxi.com) */ - #include #include #include @@ -18,14 +17,11 @@ #include #include "edac_mc.h" - #define i82860_printk(level, fmt, arg...) \ - edac_printk(level, "i82860", fmt, ##arg) - + edac_printk(level, "i82860", fmt, ##arg) #define i82860_mc_printk(mci, level, fmt, arg...) \ - edac_mc_chipset_printk(mci, level, "i82860", fmt, ##arg) - + edac_mc_chipset_printk(mci, level, "i82860", fmt, ##arg) #ifndef PCI_DEVICE_ID_INTEL_82860_0 #define PCI_DEVICE_ID_INTEL_82860_0 0x2531 @@ -56,13 +52,15 @@ struct i82860_error_info { static const struct i82860_dev_info i82860_devs[] = { [I82860] = { - .ctl_name = "i82860"}, + .ctl_name = "i82860" + }, }; static struct pci_dev *mci_pdev = NULL; /* init dev: in case that AGP code - has already registered driver */ + * has already registered driver + */ -static void i82860_get_error_info (struct mem_ctl_info *mci, +static void i82860_get_error_info(struct mem_ctl_info *mci, struct i82860_error_info *info) { /* @@ -84,14 +82,15 @@ static void i82860_get_error_info (struct mem_ctl_info *mci, */ if (!(info->errsts2 & 0x0003)) return; + if ((info->errsts ^ info->errsts2) & 0x0003) { pci_read_config_dword(mci->pdev, I82860_EAP, &info->eap); pci_read_config_word(mci->pdev, I82860_DERRCTL_STS, - &info->derrsyn); + &info->derrsyn); } } -static int i82860_process_error_info (struct mem_ctl_info *mci, +static int i82860_process_error_info(struct mem_ctl_info *mci, struct i82860_error_info *info, int handle_errors) { int row; @@ -113,8 +112,8 @@ static int i82860_process_error_info (struct mem_ctl_info *mci, if (info->errsts & 0x0002) edac_mc_handle_ue(mci, info->eap, 0, row, "i82860 UE"); else - edac_mc_handle_ce(mci, info->eap, 0, info->derrsyn, row, - 0, "i82860 UE"); + edac_mc_handle_ce(mci, info->eap, 0, info->derrsyn, row, 0, + "i82860 UE"); return 1; } @@ -147,15 +146,14 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) going to make 1 channel for group. */ mci = edac_mc_alloc(0, 16, 1); + if (!mci) return -ENOMEM; debugf3("%s(): init mci\n", __func__); - mci->pdev = pdev; mci->mtype_cap = MEM_FLAG_DDR; - mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; /* I"m not sure about this but I think that all RDRAM is SECDED */ mci->edac_cap = EDAC_FLAG_SECDED; @@ -182,12 +180,13 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) struct csrow_info *csrow = &mci->csrows[index]; pci_read_config_word(mci->pdev, I82860_GBA + index * 2, - &value); + &value); cumul_size = (value & I82860_GBA_MASK) << (I82860_GBA_SHIFT - PAGE_SHIFT); debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, cumul_size); + if (cumul_size == last_cumul_size) continue; /* not populated */ @@ -195,7 +194,7 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) csrow->last_page = cumul_size - 1; csrow->nr_pages = cumul_size - last_cumul_size; last_cumul_size = cumul_size; - csrow->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */ + csrow->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */ csrow->mtype = MEM_RMBS; csrow->dtype = DEV_UNKNOWN; csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE; @@ -211,23 +210,27 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) debugf3("%s(): success\n", __func__); rc = 0; } + return rc; } /* returns count (>= 0), or negative on error */ static int __devinit i82860_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { int rc; debugf0("%s()\n", __func__); - i82860_printk(KERN_INFO, "i82860 init one\n"); - if(pci_enable_device(pdev) < 0) + + if (pci_enable_device(pdev) < 0) return -EIO; + rc = i82860_probe1(pdev, ent->driver_data); - if(rc == 0) + + if (rc == 0) mci_pdev = pci_dev_get(pdev); + return rc; } @@ -244,9 +247,13 @@ static void __devexit i82860_remove_one(struct pci_dev *pdev) } static const struct pci_device_id i82860_pci_tbl[] __devinitdata = { - {PCI_VEND_DEV(INTEL, 82860_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - I82860}, - {0,} /* 0 terminated list. */ + { + PCI_VEND_DEV(INTEL, 82860_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + I82860 + }, + { + 0, + } /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, i82860_pci_tbl); @@ -263,24 +270,29 @@ static int __init i82860_init(void) int pci_rc; debugf3("%s()\n", __func__); + if ((pci_rc = pci_register_driver(&i82860_driver)) < 0) goto fail0; if (!mci_pdev) { mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82860_0, NULL); + PCI_DEVICE_ID_INTEL_82860_0, NULL); + if (mci_pdev == NULL) { debugf0("860 pci_get_device fail\n"); pci_rc = -ENODEV; goto fail1; } + pci_rc = i82860_init_one(mci_pdev, i82860_pci_tbl); + if (pci_rc < 0) { debugf0("860 init fail\n"); pci_rc = -ENODEV; goto fail1; } } + return 0; fail1: @@ -307,6 +319,6 @@ module_init(i82860_init); module_exit(i82860_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR - ("Red Hat Inc. (http://www.redhat.com) Ben Woodard "); +MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com) " + "Ben Woodard "); MODULE_DESCRIPTION("ECC support for Intel 82860 memory hub controllers"); diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index aad1900a468..0aec92698f1 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c @@ -13,26 +13,19 @@ * Note: E7210 appears same as D82875P - zhenyu.z.wang at intel.com */ - #include #include #include - #include #include - #include - #include "edac_mc.h" - #define i82875p_printk(level, fmt, arg...) \ - edac_printk(level, "i82875p", fmt, ##arg) - + edac_printk(level, "i82875p", fmt, ##arg) #define i82875p_mc_printk(mci, level, fmt, arg...) \ - edac_mc_chipset_printk(mci, level, "i82875p", fmt, ##arg) - + edac_mc_chipset_printk(mci, level, "i82875p", fmt, ##arg) #ifndef PCI_DEVICE_ID_INTEL_82875_0 #define PCI_DEVICE_ID_INTEL_82875_0 0x2578 @@ -42,11 +35,9 @@ #define PCI_DEVICE_ID_INTEL_82875_6 0x257e #endif /* PCI_DEVICE_ID_INTEL_82875_6 */ - /* four csrows in dual channel, eight in single channel */ #define I82875P_NR_CSROWS(nr_chans) (8/(nr_chans)) - /* Intel 82875p register addresses - device 0 function 0 - DRAM Controller */ #define I82875P_EAP 0x58 /* Error Address Pointer (32b) * @@ -95,7 +86,6 @@ * 0 reserved */ - /* Intel 82875p register addresses - device 6 function 0 - DRAM Controller */ #define I82875P_PCICMD6 0x04 /* PCI Command Register (16b) * @@ -159,23 +149,19 @@ * 1:0 DRAM type 01=DDR */ - enum i82875p_chips { I82875P = 0, }; - struct i82875p_pvt { struct pci_dev *ovrfl_pdev; void __iomem *ovrfl_window; }; - struct i82875p_dev_info { const char *ctl_name; }; - struct i82875p_error_info { u16 errsts; u32 eap; @@ -184,17 +170,19 @@ struct i82875p_error_info { u16 errsts2; }; - static const struct i82875p_dev_info i82875p_devs[] = { [I82875P] = { - .ctl_name = "i82875p"}, + .ctl_name = "i82875p" + }, }; -static struct pci_dev *mci_pdev = NULL; /* init dev: in case that AGP code - has already registered driver */ +static struct pci_dev *mci_pdev = NULL; /* init dev: in case that AGP code has + * already registered driver + */ + static int i82875p_registered = 1; -static void i82875p_get_error_info (struct mem_ctl_info *mci, +static void i82875p_get_error_info(struct mem_ctl_info *mci, struct i82875p_error_info *info) { /* @@ -218,15 +206,16 @@ static void i82875p_get_error_info (struct mem_ctl_info *mci, */ if (!(info->errsts2 & 0x0081)) return; + if ((info->errsts ^ info->errsts2) & 0x0081) { pci_read_config_dword(mci->pdev, I82875P_EAP, &info->eap); pci_read_config_byte(mci->pdev, I82875P_DES, &info->des); pci_read_config_byte(mci->pdev, I82875P_DERRSYN, - &info->derrsyn); + &info->derrsyn); } } -static int i82875p_process_error_info (struct mem_ctl_info *mci, +static int i82875p_process_error_info(struct mem_ctl_info *mci, struct i82875p_error_info *info, int handle_errors) { int row, multi_chan; @@ -251,13 +240,12 @@ static int i82875p_process_error_info (struct mem_ctl_info *mci, edac_mc_handle_ue(mci, info->eap, 0, row, "i82875p UE"); else edac_mc_handle_ce(mci, info->eap, 0, info->derrsyn, row, - multi_chan ? (info->des & 0x1) : 0, - "i82875p CE"); + multi_chan ? (info->des & 0x1) : 0, + "i82875p CE"); return 1; } - static void i82875p_check(struct mem_ctl_info *mci) { struct i82875p_error_info info; @@ -267,7 +255,6 @@ static void i82875p_check(struct mem_ctl_info *mci) i82875p_process_error_info(mci, &info, 1); } - #ifdef CONFIG_PROC_FS extern int pci_proc_attach_device(struct pci_dev *); #endif @@ -281,7 +268,6 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) unsigned long last_cumul_size; struct pci_dev *ovrfl_pdev; void __iomem *ovrfl_window = NULL; - u32 drc; u32 drc_chan; /* Number of channels 0=1chan,1=2chan */ u32 nr_chans; @@ -289,7 +275,6 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) struct i82875p_error_info discard; debugf0("%s()\n", __func__); - ovrfl_pdev = pci_get_device(PCI_VEND_DEV(INTEL, 82875_6), NULL); if (!ovrfl_pdev) { @@ -301,22 +286,23 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) */ pci_write_bits8(pdev, 0xf4, 0x2, 0x2); ovrfl_pdev = - pci_scan_single_device(pdev->bus, PCI_DEVFN(6, 0)); + pci_scan_single_device(pdev->bus, PCI_DEVFN(6, 0)); + if (!ovrfl_pdev) return -ENODEV; } + #ifdef CONFIG_PROC_FS if (!ovrfl_pdev->procent && pci_proc_attach_device(ovrfl_pdev)) { i82875p_printk(KERN_ERR, - "%s(): Failed to attach overflow device\n", - __func__); + "%s(): Failed to attach overflow device\n", __func__); return -ENODEV; } -#endif /* CONFIG_PROC_FS */ +#endif + /* CONFIG_PROC_FS */ if (pci_enable_device(ovrfl_pdev)) { i82875p_printk(KERN_ERR, - "%s(): Failed to enable overflow device\n", - __func__); + "%s(): Failed to enable overflow device\n", __func__); return -ENODEV; } @@ -325,13 +311,14 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) goto fail0; #endif } + /* cache is irrelevant for PCI bus reads/writes */ ovrfl_window = ioremap_nocache(pci_resource_start(ovrfl_pdev, 0), - pci_resource_len(ovrfl_pdev, 0)); + pci_resource_len(ovrfl_pdev, 0)); if (!ovrfl_window) { i82875p_printk(KERN_ERR, "%s(): Failed to ioremap bar6\n", - __func__); + __func__); goto fail1; } @@ -339,10 +326,10 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) drc = readl(ovrfl_window + I82875P_DRC); drc_chan = ((drc >> 21) & 0x1); nr_chans = drc_chan + 1; - drc_ddim = (drc >> 18) & 0x1; + drc_ddim = (drc >> 18) & 0x1; mci = edac_mc_alloc(sizeof(*pvt), I82875P_NR_CSROWS(nr_chans), - nr_chans); + nr_chans); if (!mci) { rc = -ENOMEM; @@ -350,10 +337,8 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) } debugf3("%s(): init mci\n", __func__); - mci->pdev = pdev; mci->mtype_cap = MEM_FLAG_DDR; - mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; mci->edac_cap = EDAC_FLAG_UNKNOWN; /* adjust FLAGS */ @@ -363,9 +348,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) mci->ctl_name = i82875p_devs[dev_idx].ctl_name; mci->edac_check = i82875p_check; mci->ctl_page_to_phys = NULL; - debugf3("%s(): init pvt\n", __func__); - pvt = (struct i82875p_pvt *) mci->pvt_info; pvt->ovrfl_pdev = ovrfl_pdev; pvt->ovrfl_window = ovrfl_window; @@ -385,6 +368,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) cumul_size = value << (I82875P_DRB_SHIFT - PAGE_SHIFT); debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, cumul_size); + if (cumul_size == last_cumul_size) continue; /* not populated */ @@ -392,7 +376,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) csrow->last_page = cumul_size - 1; csrow->nr_pages = cumul_size - last_cumul_size; last_cumul_size = cumul_size; - csrow->grain = 1 << 12; /* I82875P_EAP has 4KiB reolution */ + csrow->grain = 1 << 12; /* I82875P_EAP has 4KiB reolution */ csrow->mtype = MEM_DDR; csrow->dtype = DEV_UNKNOWN; csrow->edac_mode = drc_ddim ? EDAC_SECDED : EDAC_NONE; @@ -426,25 +410,26 @@ fail0: return rc; } - /* returns count (>= 0), or negative on error */ static int __devinit i82875p_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { int rc; debugf0("%s()\n", __func__); - i82875p_printk(KERN_INFO, "i82875p init one\n"); - if(pci_enable_device(pdev) < 0) + + if (pci_enable_device(pdev) < 0) return -EIO; + rc = i82875p_probe1(pdev, ent->driver_data); + if (mci_pdev == NULL) mci_pdev = pci_dev_get(pdev); + return rc; } - static void __devexit i82875p_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; @@ -456,6 +441,7 @@ static void __devexit i82875p_remove_one(struct pci_dev *pdev) return; pvt = (struct i82875p_pvt *) mci->pvt_info; + if (pvt->ovrfl_window) iounmap(pvt->ovrfl_window); @@ -470,16 +456,18 @@ static void __devexit i82875p_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } - static const struct pci_device_id i82875p_pci_tbl[] __devinitdata = { - {PCI_VEND_DEV(INTEL, 82875_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - I82875P}, - {0,} /* 0 terminated list. */ + { + PCI_VEND_DEV(INTEL, 82875_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + I82875P + }, + { + 0, + } /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, i82875p_pci_tbl); - static struct pci_driver i82875p_driver = { .name = EDAC_MOD_STR, .probe = i82875p_init_one, @@ -487,31 +475,35 @@ static struct pci_driver i82875p_driver = { .id_table = i82875p_pci_tbl, }; - static int __init i82875p_init(void) { int pci_rc; debugf3("%s()\n", __func__); pci_rc = pci_register_driver(&i82875p_driver); + if (pci_rc < 0) goto fail0; + if (mci_pdev == NULL) { - mci_pdev = - pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82875_0, NULL); + mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82875_0, NULL); + if (!mci_pdev) { debugf0("875p pci_get_device fail\n"); pci_rc = -ENODEV; goto fail1; } + pci_rc = i82875p_init_one(mci_pdev, i82875p_pci_tbl); + if (pci_rc < 0) { debugf0("875p init fail\n"); pci_rc = -ENODEV; goto fail1; } } + return 0; fail1: @@ -524,23 +516,21 @@ fail0: return pci_rc; } - static void __exit i82875p_exit(void) { debugf3("%s()\n", __func__); pci_unregister_driver(&i82875p_driver); + if (!i82875p_registered) { i82875p_remove_one(mci_pdev); pci_dev_put(mci_pdev); } } - module_init(i82875p_init); module_exit(i82875p_exit); - MODULE_LICENSE("GPL"); MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh"); MODULE_DESCRIPTION("MC support for Intel 82875 memory hub controllers"); diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c index 5966916d02b..2c29fafe67c 100644 --- a/drivers/edac/r82600_edac.c +++ b/drivers/edac/r82600_edac.c @@ -18,19 +18,16 @@ #include #include #include - #include #include - #include - #include "edac_mc.h" #define r82600_printk(level, fmt, arg...) \ - edac_printk(level, "r82600", fmt, ##arg) + edac_printk(level, "r82600", fmt, ##arg) #define r82600_mc_printk(mci, level, fmt, arg...) \ - edac_mc_chipset_printk(mci, level, "r82600", fmt, ##arg) + edac_mc_chipset_printk(mci, level, "r82600", fmt, ##arg) /* Radisys say "The 82600 integrates a main memory SDRAM controller that * supports up to four banks of memory. The four banks can support a mix of @@ -132,10 +129,8 @@ struct r82600_error_info { u32 eapr; }; - static unsigned int disable_hardware_scrub = 0; - static void r82600_get_error_info (struct mem_ctl_info *mci, struct r82600_error_info *info) { @@ -144,17 +139,16 @@ static void r82600_get_error_info (struct mem_ctl_info *mci, if (info->eapr & BIT(0)) /* Clear error to allow next error to be reported [p.62] */ pci_write_bits32(mci->pdev, R82600_EAP, - ((u32) BIT(0) & (u32) BIT(1)), - ((u32) BIT(0) & (u32) BIT(1))); + ((u32) BIT(0) & (u32) BIT(1)), + ((u32) BIT(0) & (u32) BIT(1))); if (info->eapr & BIT(1)) /* Clear error to allow next error to be reported [p.62] */ pci_write_bits32(mci->pdev, R82600_EAP, - ((u32) BIT(0) & (u32) BIT(1)), - ((u32) BIT(0) & (u32) BIT(1))); + ((u32) BIT(0) & (u32) BIT(1)), + ((u32) BIT(0) & (u32) BIT(1))); } - static int r82600_process_error_info (struct mem_ctl_info *mci, struct r82600_error_info *info, int handle_errors) { @@ -173,26 +167,25 @@ static int r82600_process_error_info (struct mem_ctl_info *mci, * granularity (upper 19 bits only) */ page = eapaddr >> PAGE_SHIFT; - if (info->eapr & BIT(0)) { /* CE? */ + if (info->eapr & BIT(0)) { /* CE? */ error_found = 1; if (handle_errors) - edac_mc_handle_ce( - mci, page, 0, /* not avail */ - syndrome, - edac_mc_find_csrow_by_page(mci, page), - 0, /* channel */ - mci->ctl_name); + edac_mc_handle_ce(mci, page, 0, /* not avail */ + syndrome, + edac_mc_find_csrow_by_page(mci, page), + 0, /* channel */ + mci->ctl_name); } - if (info->eapr & BIT(1)) { /* UE? */ + if (info->eapr & BIT(1)) { /* UE? */ error_found = 1; if (handle_errors) /* 82600 doesn't give enough info */ edac_mc_handle_ue(mci, page, 0, - edac_mc_find_csrow_by_page(mci, page), - mci->ctl_name); + edac_mc_find_csrow_by_page(mci, page), + mci->ctl_name); } return error_found; @@ -222,21 +215,15 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) struct r82600_error_info discard; debugf0("%s()\n", __func__); - - pci_read_config_byte(pdev, R82600_DRAMC, &dramcr); pci_read_config_dword(pdev, R82600_EAP, &eapr); - ecc_on = dramcr & BIT(5); reg_sdram = dramcr & BIT(4); scrub_disabled = eapr & BIT(31); sdram_refresh_rate = dramcr & (BIT(0) | BIT(1)); - debugf2("%s(): sdram refresh rate = %#0x\n", __func__, sdram_refresh_rate); - debugf2("%s(): DRAMC register = %#0x\n", __func__, dramcr); - mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS); if (mci == NULL) { @@ -245,19 +232,19 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) } debugf0("%s(): mci = %p\n", __func__, mci); - mci->pdev = pdev; mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR; - mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; - /* FIXME try to work out if the chip leads have been * - * used for COM2 instead on this board? [MA6?] MAYBE: */ + /* FIXME try to work out if the chip leads have been used for COM2 + * instead on this board? [MA6?] MAYBE: + */ /* On the R82600, the pins for memory bits 72:65 - i.e. the * * EC bits are shared with the pins for COM2 (!), so if COM2 * * is enabled, we assume COM2 is wired up, and thus no EDAC * * is possible. */ mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; + if (ecc_on) { if (scrub_disabled) debugf3("%s(): mci = %p - Scrubbing disabled! EAP: " @@ -295,7 +282,6 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) continue; row_base = row_high_limit_last; - csrow->first_page = row_base >> PAGE_SHIFT; csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1; csrow->nr_pages = csrow->last_page - csrow->first_page + 1; @@ -338,7 +324,7 @@ fail: /* returns count (>= 0), or negative on error */ static int __devinit r82600_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { debugf0("%s()\n", __func__); @@ -346,7 +332,6 @@ static int __devinit r82600_init_one(struct pci_dev *pdev, return r82600_probe1(pdev, ent->driver_data); } - static void __devexit r82600_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; @@ -359,15 +344,17 @@ static void __devexit r82600_remove_one(struct pci_dev *pdev) edac_mc_free(mci); } - static const struct pci_device_id r82600_pci_tbl[] __devinitdata = { - {PCI_DEVICE(PCI_VENDOR_ID_RADISYS, R82600_BRIDGE_ID)}, - {0,} /* 0 terminated list. */ + { + PCI_DEVICE(PCI_VENDOR_ID_RADISYS, R82600_BRIDGE_ID) + }, + { + 0, + } /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, r82600_pci_tbl); - static struct pci_driver r82600_driver = { .name = EDAC_MOD_STR, .probe = r82600_init_one, @@ -375,26 +362,22 @@ static struct pci_driver r82600_driver = { .id_table = r82600_pci_tbl, }; - static int __init r82600_init(void) { return pci_register_driver(&r82600_driver); } - static void __exit r82600_exit(void) { pci_unregister_driver(&r82600_driver); } - module_init(r82600_init); module_exit(r82600_exit); - MODULE_LICENSE("GPL"); MODULE_AUTHOR("Tim Small - WPAD Ltd. " - "on behalf of EADS Astrium"); + "on behalf of EADS Astrium"); MODULE_DESCRIPTION("MC support for Radisys 82600 memory controllers"); module_param(disable_hardware_scrub, bool, 0644); -- cgit v1.2.3-70-g09d2 From 9110540f7f2bbcc3577d2580a696fbb7af68c892 Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Sun, 26 Mar 2006 01:38:55 -0800 Subject: [PATCH] EDAC: use EXPORT_SYMBOL_GPL Change all instances of EXPORT_SYMBOL() in the core EDAC module to EXPORT_SYMBOL_GPL(). Signed-off-by: David S. Peterson Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/edac_mc.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index bb3460457fa..905f58ba8e1 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -45,7 +45,7 @@ #ifdef CONFIG_EDAC_DEBUG /* Values of 0 to 4 will generate output */ int edac_debug_level = 1; -EXPORT_SYMBOL(edac_debug_level); +EXPORT_SYMBOL_GPL(edac_debug_level); #endif /* EDAC Controls, setable by module parameter, and sysfs */ @@ -1211,7 +1211,7 @@ void edac_mc_dump_channel(struct channel_info *chan) debugf4("\tchannel->label = '%s'\n", chan->label); debugf4("\tchannel->csrow = %p\n\n", chan->csrow); } -EXPORT_SYMBOL(edac_mc_dump_channel); +EXPORT_SYMBOL_GPL(edac_mc_dump_channel); void edac_mc_dump_csrow(struct csrow_info *csrow) { @@ -1227,7 +1227,7 @@ void edac_mc_dump_csrow(struct csrow_info *csrow) debugf4("\tcsrow->channels = %p\n", csrow->channels); debugf4("\tcsrow->mci = %p\n\n", csrow->mci); } -EXPORT_SYMBOL(edac_mc_dump_csrow); +EXPORT_SYMBOL_GPL(edac_mc_dump_csrow); void edac_mc_dump_mci(struct mem_ctl_info *mci) { @@ -1243,7 +1243,7 @@ void edac_mc_dump_mci(struct mem_ctl_info *mci) mci->mod_name, mci->ctl_name); debugf3("\tpvt_info = %p\n\n", mci->pvt_info); } -EXPORT_SYMBOL(edac_mc_dump_mci); +EXPORT_SYMBOL_GPL(edac_mc_dump_mci); #endif /* CONFIG_EDAC_DEBUG */ @@ -1351,7 +1351,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, return mci; } -EXPORT_SYMBOL(edac_mc_alloc); +EXPORT_SYMBOL_GPL(edac_mc_alloc); /** * edac_mc_free: Free a previously allocated 'mci' structure @@ -1361,7 +1361,7 @@ void edac_mc_free(struct mem_ctl_info *mci) { kfree(mci); } -EXPORT_SYMBOL(edac_mc_free); +EXPORT_SYMBOL_GPL(edac_mc_free); static struct mem_ctl_info *find_mci_by_pdev(struct pci_dev *pdev) { @@ -1499,7 +1499,7 @@ fail0: up(&mem_ctls_mutex); return 1; } -EXPORT_SYMBOL(edac_mc_add_mc); +EXPORT_SYMBOL_GPL(edac_mc_add_mc); /** * edac_mc_del_mc: Remove sysfs entries for specified mci structure and @@ -1528,7 +1528,7 @@ struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev) mci->mod_name, mci->ctl_name, pci_name(mci->pdev)); return mci; } -EXPORT_SYMBOL(edac_mc_del_mc); +EXPORT_SYMBOL_GPL(edac_mc_del_mc); void edac_mc_scrub_block(unsigned long page, unsigned long offset, u32 size) { @@ -1559,7 +1559,7 @@ void edac_mc_scrub_block(unsigned long page, unsigned long offset, u32 size) if (PageHighMem(pg)) local_irq_restore(flags); } -EXPORT_SYMBOL(edac_mc_scrub_block); +EXPORT_SYMBOL_GPL(edac_mc_scrub_block); /* FIXME - should return -1 */ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page) @@ -1597,7 +1597,7 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page) return row; } -EXPORT_SYMBOL(edac_mc_find_csrow_by_page); +EXPORT_SYMBOL_GPL(edac_mc_find_csrow_by_page); /* FIXME - setable log (warning/emerg) levels */ /* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */ @@ -1660,7 +1660,7 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci, mci->csrows[row].grain); } } -EXPORT_SYMBOL(edac_mc_handle_ce); +EXPORT_SYMBOL_GPL(edac_mc_handle_ce); void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg) { @@ -1671,7 +1671,7 @@ void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg) mci->ce_noinfo_count++; mci->ce_count++; } -EXPORT_SYMBOL(edac_mc_handle_ce_no_info); +EXPORT_SYMBOL_GPL(edac_mc_handle_ce_no_info); void edac_mc_handle_ue(struct mem_ctl_info *mci, unsigned long page_frame_number, unsigned long offset_in_page, @@ -1724,7 +1724,7 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci, mci->ue_count++; mci->csrows[row].ue_count++; } -EXPORT_SYMBOL(edac_mc_handle_ue); +EXPORT_SYMBOL_GPL(edac_mc_handle_ue); void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg) { @@ -1737,7 +1737,7 @@ void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg) mci->ue_noinfo_count++; mci->ue_count++; } -EXPORT_SYMBOL(edac_mc_handle_ue_no_info); +EXPORT_SYMBOL_GPL(edac_mc_handle_ue_no_info); #ifdef CONFIG_PCI -- cgit v1.2.3-70-g09d2 From 7f927fcc2fd1575d01efb4b76665975007945690 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Tue, 28 Mar 2006 01:56:53 -0800 Subject: [PATCH] Typo fixes Fix a lot of typos. Eyeballed by jmc@ in OpenBSD. Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/m68k/README.buddha | 2 +- Documentation/networking/ifenslave.c | 2 +- arch/arm/lib/copy_template.S | 2 +- drivers/char/mxser.h | 2 +- drivers/char/synclink.c | 2 +- drivers/edac/edac_mc.c | 2 +- drivers/net/irda/nsc-ircc.c | 2 +- drivers/net/sis900.c | 2 +- drivers/net/tulip/de4x5.c | 2 +- drivers/net/tulip/pnic2.c | 2 +- drivers/net/typhoon.c | 4 ++-- drivers/net/wireless/orinoco.c | 2 +- drivers/net/wireless/prism54/isl_ioctl.c | 2 +- drivers/scsi/3w-9xxx.c | 2 +- drivers/serial/8250.c | 2 +- drivers/serial/serial_txx9.c | 2 +- drivers/serial/sunsu.c | 2 +- drivers/usb/host/ohci-s3c2410.c | 2 +- drivers/usb/net/zaurus.c | 2 +- fs/mbcache.c | 2 +- include/asm-parisc/pdc.h | 2 +- include/asm-sh/addrspace.h | 2 +- include/asm-sparc64/floppy.h | 2 +- include/linux/fb.h | 2 +- mm/mempolicy.c | 2 +- net/irda/af_irda.c | 6 +++--- sound/pci/rme32.c | 8 ++++---- sound/pci/rme96.c | 8 ++++---- sound/pci/rme9652/hdspm.c | 2 +- sound/usb/usx2y/usx2yhwdeppcm.c | 2 +- 30 files changed, 39 insertions(+), 39 deletions(-) (limited to 'drivers/edac/edac_mc.c') diff --git a/Documentation/m68k/README.buddha b/Documentation/m68k/README.buddha index bf802ffc98a..ef484a719bb 100644 --- a/Documentation/m68k/README.buddha +++ b/Documentation/m68k/README.buddha @@ -29,7 +29,7 @@ address is written to $4a, then the whole Byte is written to $48, while it doesn't matter how often you're writing to $4a as long as $48 is not touched. After $48 has been written, the whole card disappears from $e8 and is mapped to the new -address just written. Make shure $4a is written before $48, +address just written. Make sure $4a is written before $48, otherwise your chance is only 1:16 to find the board :-). The local memory-map is even active when mapped to $e8: diff --git a/Documentation/networking/ifenslave.c b/Documentation/networking/ifenslave.c index 545447ac503..a1205988675 100644 --- a/Documentation/networking/ifenslave.c +++ b/Documentation/networking/ifenslave.c @@ -87,7 +87,7 @@ * would fail and generate an error message in the system log. * - For opt_c: slave should not be set to the master's setting * while it is running. It was already set during enslave. To - * simplify things, it is now handeled separately. + * simplify things, it is now handled separately. * * - 2003/12/01 - Shmulik Hen * - Code cleanup and style changes diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S index 838e435e492..cab355c0c1f 100644 --- a/arch/arm/lib/copy_template.S +++ b/arch/arm/lib/copy_template.S @@ -236,7 +236,7 @@ /* - * Abort preanble and completion macros. + * Abort preamble and completion macros. * If a fixup handler is required then those macros must surround it. * It is assumed that the fixup code will handle the private part of * the exit macro. diff --git a/drivers/char/mxser.h b/drivers/char/mxser.h index e7fd0b08e0b..7e188a4d602 100644 --- a/drivers/char/mxser.h +++ b/drivers/char/mxser.h @@ -118,7 +118,7 @@ // enable CTS interrupt #define MOXA_MUST_IER_ECTSI 0x80 -// eanble RTS interrupt +// enable RTS interrupt #define MOXA_MUST_IER_ERTSI 0x40 // enable Xon/Xoff interrupt #define MOXA_MUST_IER_XINT 0x20 diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index abb03e52fe1..fee2aca3f6a 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c @@ -5996,7 +5996,7 @@ static void usc_set_async_mode( struct mgsl_struct *info ) * <15..8> ? RxFIFO IRQ Request Level * * Note: For async mode the receive FIFO level must be set - * to 0 to aviod the situation where the FIFO contains fewer bytes + * to 0 to avoid the situation where the FIFO contains fewer bytes * than the trigger level and no more data is expected. * * <7> 0 Exited Hunt IA (Interrupt Arm) diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 905f58ba8e1..ea06e3a4dc3 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -2044,7 +2044,7 @@ static int __init edac_mc_init(void) */ clear_pci_parity_errors(); - /* Create the MC sysfs entires */ + /* Create the MC sysfs entries */ if (edac_sysfs_memctrl_setup()) { edac_printk(KERN_ERR, EDAC_MC, "Error initializing sysfs code\n"); diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 9aa074b44dd..cc7ff8f00e4 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -812,7 +812,7 @@ static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info) int cfg_base = info->cfg_base; int enabled; - /* User is shure about his config... accept it. */ + /* User is sure about his config... accept it. */ IRDA_DEBUG(2, "%s(): nsc_ircc_init_39x (user settings): " "io=0x%04x, irq=%d, dma=%d\n", __FUNCTION__, info->fir_base, info->irq, info->dma); diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 8429ceb0138..b82191d2bee 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -2283,7 +2283,7 @@ static void set_rx_mode(struct net_device *net_dev) int i, table_entries; u32 rx_mode; - /* 635 Hash Table entires = 256(2^16) */ + /* 635 Hash Table entries = 256(2^16) */ if((sis_priv->chipset_rev >= SIS635A_900_REV) || (sis_priv->chipset_rev == SIS900B_900_REV)) table_entries = 16; diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index ee48bfd6734..d1a86a080a6 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -513,7 +513,7 @@ struct mii_phy { u_char *rst; /* Start of reset sequence in SROM */ u_int mc; /* Media Capabilities */ u_int ana; /* NWay Advertisement */ - u_int fdx; /* Full DupleX capabilites for each media */ + u_int fdx; /* Full DupleX capabilities for each media */ u_int ttm; /* Transmit Threshold Mode for each media */ u_int mci; /* 21142 MII Connector Interrupt info */ }; diff --git a/drivers/net/tulip/pnic2.c b/drivers/net/tulip/pnic2.c index 55f4a9a631b..ab985023fcc 100644 --- a/drivers/net/tulip/pnic2.c +++ b/drivers/net/tulip/pnic2.c @@ -199,7 +199,7 @@ void pnic2_lnk_change(struct net_device *dev, int csr5) /* negotiation ended successfully */ /* get the link partners reply and mask out all but - * bits 24-21 which show the partners capabilites + * bits 24-21 which show the partners capabilities * and match those to what we advertised * * then begin to interpret the results of the negotiation. diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index cde35dd8790..c1ce87a5f8d 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -208,7 +208,7 @@ static const struct typhoon_card_info typhoon_card_info[] __devinitdata = { }; /* Notes on the new subsystem numbering scheme: - * bits 0-1 indicate crypto capabilites: (0) variable, (1) DES, or (2) 3DES + * bits 0-1 indicate crypto capabilities: (0) variable, (1) DES, or (2) 3DES * bit 4 indicates if this card has secured firmware (we don't support it) * bit 8 indicates if this is a (0) copper or (1) fiber card * bits 12-16 indicate card type: (0) client and (1) server @@ -788,7 +788,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) /* we have two rings to choose from, but we only use txLo for now * If we start using the Hi ring as well, we'll need to update * typhoon_stop_runtime(), typhoon_interrupt(), typhoon_num_free_tx(), - * and TXHI_ENTIRES to match, as well as update the TSO code below + * and TXHI_ENTRIES to match, as well as update the TSO code below * to get the right DMA address */ txRing = &tp->txLoRing; diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 6fd0bf73683..8dfdfbd5966 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -3858,7 +3858,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev, unsigned long flags; /* Note : you may have realised that, as this is a SET operation, - * this is priviledged and therefore a normal user can't + * this is privileged and therefore a normal user can't * perform scanning. * This is not an error, while the device perform scanning, * traffic doesn't flow, so it's a perfect DoS... diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index e5bb9f5ae42..989599ad33e 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -747,7 +747,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info, if (essid->length) { dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */ - /* if it is to big, trunk it */ + /* if it is too big, trunk it */ dwrq->length = min((u8)IW_ESSID_MAX_SIZE, essid->length); } else { dwrq->flags = 0; diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 0ab26d01877..0d2b447c50e 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -1026,7 +1026,7 @@ static void twa_free_request_id(TW_Device_Extension *tw_dev, int request_id) tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH; } /* End twa_free_request_id() */ -/* This function will get parameter table entires from the firmware */ +/* This function will get parameter table entries from the firmware */ static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes) { TW_Command_Full *full_command_packet; diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 5996d3cd0ed..674b15c78f6 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -1528,7 +1528,7 @@ static int serial8250_startup(struct uart_port *port) /* * Clear the FIFO buffers and disable them. - * (they will be reeanbled in set_termios()) + * (they will be reenabled in set_termios()) */ serial8250_clear_fifos(up); diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index b848b7d9441..3bdee64d1a9 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -483,7 +483,7 @@ static int serial_txx9_startup(struct uart_port *port) /* * Clear the FIFO buffers and disable them. - * (they will be reeanbled in set_termios()) + * (they will be reenabled in set_termios()) */ sio_set(up, TXX9_SIFCR, TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE); diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 9fe2283d91e..1c4396c2962 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -641,7 +641,7 @@ static int sunsu_startup(struct uart_port *port) /* * Clear the FIFO buffers and disable them. - * (they will be reeanbled in set_termios()) + * (they will be reenabled in set_termios()) */ if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) { serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 372527a8359..682bf221566 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -158,7 +158,7 @@ static int ohci_s3c2410_hub_control ( "s3c2410_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n", hcd, typeReq, wValue, wIndex, buf, wLength); - /* if we are only an humble host without any special capabilites + /* if we are only an humble host without any special capabilities * process the request straight away and exit */ if (info == NULL) { diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c index 9c5ab251370..f7ac9d6b985 100644 --- a/drivers/usb/net/zaurus.c +++ b/drivers/usb/net/zaurus.c @@ -217,7 +217,7 @@ static int blan_mdlm_bind(struct usbnet *dev, struct usb_interface *intf) * with devices that use it and those that don't. */ if ((detail->bDetailData[1] & ~0x02) != 0x01) { - /* bmDataCapabilites == 0 would be fine too, + /* bmDataCapabilities == 0 would be fine too, * but framing is minidriver-coupled for now. */ bad_detail: diff --git a/fs/mbcache.c b/fs/mbcache.c index 73e754fea2d..e4fde1ab22c 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -311,7 +311,7 @@ fail: /* * mb_cache_shrink() * - * Removes all cache entires of a device from the cache. All cache entries + * Removes all cache entries of a device from the cache. All cache entries * currently in use cannot be freed, and thus remain in the cache. All others * are freed. * diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index 8e23e4c674f..0a3face6c48 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h @@ -333,7 +333,7 @@ struct pdc_model { /* for PDC_MODEL */ unsigned long curr_key; }; -/* Values for PDC_MODEL_CAPABILITES non-equivalent virtual aliasing support */ +/* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */ #define PDC_MODEL_IOPDIR_FDC (1 << 2) /* see sba_iommu.c */ #define PDC_MODEL_NVA_MASK (3 << 4) diff --git a/include/asm-sh/addrspace.h b/include/asm-sh/addrspace.h index dbb05d1a26d..720afc11c2c 100644 --- a/include/asm-sh/addrspace.h +++ b/include/asm-sh/addrspace.h @@ -13,7 +13,7 @@ #include -/* Memory segments (32bit Priviledged mode addresses) */ +/* Memory segments (32bit Privileged mode addresses) */ #define P0SEG 0x00000000 #define P1SEG 0x80000000 #define P2SEG 0xa0000000 diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h index 49d49a28594..6a95d5d0c57 100644 --- a/include/asm-sparc64/floppy.h +++ b/include/asm-sparc64/floppy.h @@ -738,7 +738,7 @@ static unsigned long __init sun_floppy_init(void) if (!sun_floppy_types[0] && sun_floppy_types[1]) { /* * Set the drive exchange bit in FCR on NS87303, - * make shure other bits are sane before doing so. + * make sure other bits are sane before doing so. */ ns87303_modify(config, FER, FER_EDM, 0); ns87303_modify(config, ASC, ASC_DRV2_SEL, 0); diff --git a/include/linux/fb.h b/include/linux/fb.h index 2cb19e6503a..d03fadfcafe 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -734,7 +734,7 @@ struct fb_tile_ops { /* A driver may set this flag to indicate that it does want a set_par to be * called every time when fbcon_switch is executed. The advantage is that with - * this flag set you can really be shure that set_par is always called before + * this flag set you can really be sure that set_par is always called before * any of the functions dependant on the correct hardware state or altering * that state, even if you are using some broken X releases. The disadvantage * is that it introduces unwanted delays to every console switch if set_par diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 4f71cfd29c6..dec8249e972 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -912,7 +912,7 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode, /* * Check if this process has the right to modify the specified * process. The right exists if the process has administrative - * capabilities, superuser priviledges or the same + * capabilities, superuser privileges or the same * userid as the target process. */ if ((current->euid != task->suid) && (current->euid != task->uid) && diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 75944564866..627b1134223 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -1302,7 +1302,7 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, if (sk->sk_state != TCP_ESTABLISHED) return -ENOTCONN; - /* Check that we don't send out to big frames */ + /* Check that we don't send out too big frames */ if (len > self->max_data_size) { IRDA_DEBUG(2, "%s(), Chopping frame from %zd to %d bytes!\n", __FUNCTION__, len, self->max_data_size); @@ -1546,7 +1546,7 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, IRDA_ASSERT(self != NULL, return -1;); /* - * Check that we don't send out to big frames. This is an unreliable + * Check that we don't send out too big frames. This is an unreliable * service, so we have no fragmentation and no coalescence */ if (len > self->max_data_size) { @@ -1642,7 +1642,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, } /* - * Check that we don't send out to big frames. This is an unreliable + * Check that we don't send out too big frames. This is an unreliable * service, so we have no fragmentation and no coalescence */ if (len > self->max_data_size) { diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 0cbef5fe6c6..ab78544bf04 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -313,7 +313,7 @@ static int snd_rme32_capture_copy(struct snd_pcm_substream *substream, int chann } /* - * SPDIF I/O capabilites (half-duplex mode) + * SPDIF I/O capabilities (half-duplex mode) */ static struct snd_pcm_hardware snd_rme32_spdif_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | @@ -339,7 +339,7 @@ static struct snd_pcm_hardware snd_rme32_spdif_info = { }; /* - * ADAT I/O capabilites (half-duplex mode) + * ADAT I/O capabilities (half-duplex mode) */ static struct snd_pcm_hardware snd_rme32_adat_info = { @@ -364,7 +364,7 @@ static struct snd_pcm_hardware snd_rme32_adat_info = }; /* - * SPDIF I/O capabilites (full-duplex mode) + * SPDIF I/O capabilities (full-duplex mode) */ static struct snd_pcm_hardware snd_rme32_spdif_fd_info = { .info = (SNDRV_PCM_INFO_MMAP | @@ -390,7 +390,7 @@ static struct snd_pcm_hardware snd_rme32_spdif_fd_info = { }; /* - * ADAT I/O capabilites (full-duplex mode) + * ADAT I/O capabilities (full-duplex mode) */ static struct snd_pcm_hardware snd_rme32_adat_fd_info = { diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 0e694b011dc..6c2a9f4a765 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -359,7 +359,7 @@ snd_rme96_capture_copy(struct snd_pcm_substream *substream, } /* - * Digital output capabilites (S/PDIF) + * Digital output capabilities (S/PDIF) */ static struct snd_pcm_hardware snd_rme96_playback_spdif_info = { @@ -388,7 +388,7 @@ static struct snd_pcm_hardware snd_rme96_playback_spdif_info = }; /* - * Digital input capabilites (S/PDIF) + * Digital input capabilities (S/PDIF) */ static struct snd_pcm_hardware snd_rme96_capture_spdif_info = { @@ -417,7 +417,7 @@ static struct snd_pcm_hardware snd_rme96_capture_spdif_info = }; /* - * Digital output capabilites (ADAT) + * Digital output capabilities (ADAT) */ static struct snd_pcm_hardware snd_rme96_playback_adat_info = { @@ -442,7 +442,7 @@ static struct snd_pcm_hardware snd_rme96_playback_adat_info = }; /* - * Digital input capabilites (ADAT) + * Digital input capabilities (ADAT) */ static struct snd_pcm_hardware snd_rme96_capture_adat_info = { diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 980b9cd689d..b5538efd146 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -2256,7 +2256,7 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm } /* Channel playback mixer as default control - Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats to big for any alsamixer + Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats too big for any alsamixer they are accesible via special IOCTL on hwdep and the mixer 2dimensional mixer control */ diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index 315855082fe..fe67a92e2a1 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c @@ -404,7 +404,7 @@ static void usX2Y_usbpcm_subs_startup(struct snd_usX2Y_substream *subs) struct usX2Ydev * usX2Y = subs->usX2Y; usX2Y->prepare_subs = subs; subs->urb[0]->start_frame = -1; - smp_wmb(); // Make shure above modifications are seen by i_usX2Y_subs_startup() + smp_wmb(); // Make sure above modifications are seen by i_usX2Y_subs_startup() usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_subs_startup); } -- cgit v1.2.3-70-g09d2