mirror of https://gitee.com/openkylin/linux.git
Merge branch 'linux_next' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/i7core
* 'linux_next' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/i7core: (83 commits) i7core_edac: Better describe the supported devices Add support for Westmere to i7core_edac driver i7core_edac: don't free on success i7core_edac: Add support for X5670 Always call i7core_[ur]dimm_check_mc_ecc_err i7core_edac: fix memory leak of i7core_dev EDAC: add __init to i7core_xeon_pci_fixup i7core_edac: Fix wrong device id for channel 1 devices i7core: add support for Lynnfield alternate address i7core_edac: Add initial support for Lynnfield i7core_edac: do not export static functions edac: fix i7core build edac: i7core_edac produces undefined behaviour on 32bit i7core_edac: Use a more generic approach for probing PCI devices i7core_edac: PCI device is called NONCORE, instead of NOCORE i7core_edac: Fix ringbuffer maxsize i7core_edac: First store, then increment i7core_edac: Better parse "any" addrmask i7core_edac: Use a lockless ringbuffer edac: Create an unique instance for each kobj ...
This commit is contained in:
commit
9a9620db07
|
@ -6,6 +6,8 @@ Written by Doug Thompson <dougthompson@xmission.com>
|
||||||
7 Dec 2005
|
7 Dec 2005
|
||||||
17 Jul 2007 Updated
|
17 Jul 2007 Updated
|
||||||
|
|
||||||
|
(c) Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||||
|
05 Aug 2009 Nehalem interface
|
||||||
|
|
||||||
EDAC is maintained and written by:
|
EDAC is maintained and written by:
|
||||||
|
|
||||||
|
@ -717,3 +719,153 @@ unique drivers for their hardware systems.
|
||||||
The 'test_device_edac' sample driver is located at the
|
The 'test_device_edac' sample driver is located at the
|
||||||
bluesmoke.sourceforge.net project site for EDAC.
|
bluesmoke.sourceforge.net project site for EDAC.
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
NEHALEM USAGE OF EDAC APIs
|
||||||
|
|
||||||
|
This chapter documents some EXPERIMENTAL mappings for EDAC API to handle
|
||||||
|
Nehalem EDAC driver. They will likely be changed on future versions
|
||||||
|
of the driver.
|
||||||
|
|
||||||
|
Due to the way Nehalem exports Memory Controller data, some adjustments
|
||||||
|
were done at i7core_edac driver. This chapter will cover those differences
|
||||||
|
|
||||||
|
1) On Nehalem, there are one Memory Controller per Quick Patch Interconnect
|
||||||
|
(QPI). At the driver, the term "socket" means one QPI. This is
|
||||||
|
associated with a physical CPU socket.
|
||||||
|
|
||||||
|
Each MC have 3 physical read channels, 3 physical write channels and
|
||||||
|
3 logic channels. The driver currenty sees it as just 3 channels.
|
||||||
|
Each channel can have up to 3 DIMMs.
|
||||||
|
|
||||||
|
The minimum known unity is DIMMs. There are no information about csrows.
|
||||||
|
As EDAC API maps the minimum unity is csrows, the driver sequencially
|
||||||
|
maps channel/dimm into different csrows.
|
||||||
|
|
||||||
|
For example, suposing the following layout:
|
||||||
|
Ch0 phy rd0, wr0 (0x063f4031): 2 ranks, UDIMMs
|
||||||
|
dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400
|
||||||
|
dimm 1 1024 Mb offset: 4, bank: 8, rank: 1, row: 0x4000, col: 0x400
|
||||||
|
Ch1 phy rd1, wr1 (0x063f4031): 2 ranks, UDIMMs
|
||||||
|
dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400
|
||||||
|
Ch2 phy rd3, wr3 (0x063f4031): 2 ranks, UDIMMs
|
||||||
|
dimm 0 1024 Mb offset: 0, bank: 8, rank: 1, row: 0x4000, col: 0x400
|
||||||
|
The driver will map it as:
|
||||||
|
csrow0: channel 0, dimm0
|
||||||
|
csrow1: channel 0, dimm1
|
||||||
|
csrow2: channel 1, dimm0
|
||||||
|
csrow3: channel 2, dimm0
|
||||||
|
|
||||||
|
exports one
|
||||||
|
DIMM per csrow.
|
||||||
|
|
||||||
|
Each QPI is exported as a different memory controller.
|
||||||
|
|
||||||
|
2) Nehalem MC has the hability to generate errors. The driver implements this
|
||||||
|
functionality via some error injection nodes:
|
||||||
|
|
||||||
|
For injecting a memory error, there are some sysfs nodes, under
|
||||||
|
/sys/devices/system/edac/mc/mc?/:
|
||||||
|
|
||||||
|
inject_addrmatch/*:
|
||||||
|
Controls the error injection mask register. It is possible to specify
|
||||||
|
several characteristics of the address to match an error code:
|
||||||
|
dimm = the affected dimm. Numbers are relative to a channel;
|
||||||
|
rank = the memory rank;
|
||||||
|
channel = the channel that will generate an error;
|
||||||
|
bank = the affected bank;
|
||||||
|
page = the page address;
|
||||||
|
column (or col) = the address column.
|
||||||
|
each of the above values can be set to "any" to match any valid value.
|
||||||
|
|
||||||
|
At driver init, all values are set to any.
|
||||||
|
|
||||||
|
For example, to generate an error at rank 1 of dimm 2, for any channel,
|
||||||
|
any bank, any page, any column:
|
||||||
|
echo 2 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/dimm
|
||||||
|
echo 1 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/rank
|
||||||
|
|
||||||
|
To return to the default behaviour of matching any, you can do:
|
||||||
|
echo any >/sys/devices/system/edac/mc/mc0/inject_addrmatch/dimm
|
||||||
|
echo any >/sys/devices/system/edac/mc/mc0/inject_addrmatch/rank
|
||||||
|
|
||||||
|
inject_eccmask:
|
||||||
|
specifies what bits will have troubles,
|
||||||
|
|
||||||
|
inject_section:
|
||||||
|
specifies what ECC cache section will get the error:
|
||||||
|
3 for both
|
||||||
|
2 for the highest
|
||||||
|
1 for the lowest
|
||||||
|
|
||||||
|
inject_type:
|
||||||
|
specifies the type of error, being a combination of the following bits:
|
||||||
|
bit 0 - repeat
|
||||||
|
bit 1 - ecc
|
||||||
|
bit 2 - parity
|
||||||
|
|
||||||
|
inject_enable starts the error generation when something different
|
||||||
|
than 0 is written.
|
||||||
|
|
||||||
|
All inject vars can be read. root permission is needed for write.
|
||||||
|
|
||||||
|
Datasheet states that the error will only be generated after a write on an
|
||||||
|
address that matches inject_addrmatch. It seems, however, that reading will
|
||||||
|
also produce an error.
|
||||||
|
|
||||||
|
For example, the following code will generate an error for any write access
|
||||||
|
at socket 0, on any DIMM/address on channel 2:
|
||||||
|
|
||||||
|
echo 2 >/sys/devices/system/edac/mc/mc0/inject_addrmatch/channel
|
||||||
|
echo 2 >/sys/devices/system/edac/mc/mc0/inject_type
|
||||||
|
echo 64 >/sys/devices/system/edac/mc/mc0/inject_eccmask
|
||||||
|
echo 3 >/sys/devices/system/edac/mc/mc0/inject_section
|
||||||
|
echo 1 >/sys/devices/system/edac/mc/mc0/inject_enable
|
||||||
|
dd if=/dev/mem of=/dev/null seek=16k bs=4k count=1 >& /dev/null
|
||||||
|
|
||||||
|
For socket 1, it is needed to replace "mc0" by "mc1" at the above
|
||||||
|
commands.
|
||||||
|
|
||||||
|
The generated error message will look like:
|
||||||
|
|
||||||
|
EDAC MC0: UE row 0, channel-a= 0 channel-b= 0 labels "-": NON_FATAL (addr = 0x0075b980, socket=0, Dimm=0, Channel=2, syndrome=0x00000040, count=1, Err=8c0000400001009f:4000080482 (read error: read ECC error))
|
||||||
|
|
||||||
|
3) Nehalem specific Corrected Error memory counters
|
||||||
|
|
||||||
|
Nehalem have some registers to count memory errors. The driver uses those
|
||||||
|
registers to report Corrected Errors on devices with Registered Dimms.
|
||||||
|
|
||||||
|
However, those counters don't work with Unregistered Dimms. As the chipset
|
||||||
|
offers some counters that also work with UDIMMS (but with a worse level of
|
||||||
|
granularity than the default ones), the driver exposes those registers for
|
||||||
|
UDIMM memories.
|
||||||
|
|
||||||
|
They can be read by looking at the contents of all_channel_counts/
|
||||||
|
|
||||||
|
$ for i in /sys/devices/system/edac/mc/mc0/all_channel_counts/*; do echo $i; cat $i; done
|
||||||
|
/sys/devices/system/edac/mc/mc0/all_channel_counts/udimm0
|
||||||
|
0
|
||||||
|
/sys/devices/system/edac/mc/mc0/all_channel_counts/udimm1
|
||||||
|
0
|
||||||
|
/sys/devices/system/edac/mc/mc0/all_channel_counts/udimm2
|
||||||
|
0
|
||||||
|
|
||||||
|
What happens here is that errors on different csrows, but at the same
|
||||||
|
dimm number will increment the same counter.
|
||||||
|
So, in this memory mapping:
|
||||||
|
csrow0: channel 0, dimm0
|
||||||
|
csrow1: channel 0, dimm1
|
||||||
|
csrow2: channel 1, dimm0
|
||||||
|
csrow3: channel 2, dimm0
|
||||||
|
The hardware will increment udimm0 for an error at the first dimm at either
|
||||||
|
csrow0, csrow2 or csrow3;
|
||||||
|
The hardware will increment udimm1 for an error at the second dimm at either
|
||||||
|
csrow0, csrow2 or csrow3;
|
||||||
|
The hardware will increment udimm2 for an error at the third dimm at either
|
||||||
|
csrow0, csrow2 or csrow3;
|
||||||
|
|
||||||
|
4) Standard error counters
|
||||||
|
|
||||||
|
The standard error counters are generated when an mcelog error is received
|
||||||
|
by the driver. Since, with udimm, this is counted by software, it is
|
||||||
|
possible that some errors could be lost. With rdimm's, they displays the
|
||||||
|
contents of the registers
|
||||||
|
|
|
@ -53,6 +53,8 @@ extern int pcibios_last_bus;
|
||||||
extern struct pci_bus *pci_root_bus;
|
extern struct pci_bus *pci_root_bus;
|
||||||
extern struct pci_ops pci_root_ops;
|
extern struct pci_ops pci_root_ops;
|
||||||
|
|
||||||
|
void pcibios_scan_specific_bus(int busn);
|
||||||
|
|
||||||
/* pci-irq.c */
|
/* pci-irq.c */
|
||||||
|
|
||||||
struct irq_info {
|
struct irq_info {
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/edac_mce.h>
|
||||||
|
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/hw_irq.h>
|
#include <asm/hw_irq.h>
|
||||||
|
@ -168,6 +169,15 @@ void mce_log(struct mce *mce)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
entry = rcu_dereference_check_mce(mcelog.next);
|
entry = rcu_dereference_check_mce(mcelog.next);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
/*
|
||||||
|
* If edac_mce is enabled, it will check the error type
|
||||||
|
* and will process it, if it is a known error.
|
||||||
|
* Otherwise, the error will be sent through mcelog
|
||||||
|
* interface
|
||||||
|
*/
|
||||||
|
if (edac_mce_parse(mce))
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When the buffer fills up discard new entries.
|
* When the buffer fills up discard new entries.
|
||||||
* Assume that the earlier errors are the more
|
* Assume that the earlier errors are the more
|
||||||
|
|
|
@ -11,28 +11,14 @@
|
||||||
*/
|
*/
|
||||||
static void __devinit pcibios_fixup_peer_bridges(void)
|
static void __devinit pcibios_fixup_peer_bridges(void)
|
||||||
{
|
{
|
||||||
int n, devfn;
|
int n;
|
||||||
long node;
|
|
||||||
|
|
||||||
if (pcibios_last_bus <= 0 || pcibios_last_bus > 0xff)
|
if (pcibios_last_bus <= 0 || pcibios_last_bus > 0xff)
|
||||||
return;
|
return;
|
||||||
DBG("PCI: Peer bridge fixup\n");
|
DBG("PCI: Peer bridge fixup\n");
|
||||||
|
|
||||||
for (n=0; n <= pcibios_last_bus; n++) {
|
for (n=0; n <= pcibios_last_bus; n++)
|
||||||
u32 l;
|
pcibios_scan_specific_bus(n);
|
||||||
if (pci_find_bus(0, n))
|
|
||||||
continue;
|
|
||||||
node = get_mp_bus_to_node(n);
|
|
||||||
for (devfn = 0; devfn < 256; devfn += 8) {
|
|
||||||
if (!raw_pci_read(0, n, devfn, PCI_VENDOR_ID, 2, &l) &&
|
|
||||||
l != 0x0000 && l != 0xffff) {
|
|
||||||
DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l);
|
|
||||||
printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
|
|
||||||
pci_scan_bus_on_node(n, &pci_root_ops, node);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init pci_legacy_init(void)
|
int __init pci_legacy_init(void)
|
||||||
|
@ -50,6 +36,28 @@ int __init pci_legacy_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pcibios_scan_specific_bus(int busn)
|
||||||
|
{
|
||||||
|
int devfn;
|
||||||
|
long node;
|
||||||
|
u32 l;
|
||||||
|
|
||||||
|
if (pci_find_bus(0, busn))
|
||||||
|
return;
|
||||||
|
|
||||||
|
node = get_mp_bus_to_node(busn);
|
||||||
|
for (devfn = 0; devfn < 256; devfn += 8) {
|
||||||
|
if (!raw_pci_read(0, busn, devfn, PCI_VENDOR_ID, 2, &l) &&
|
||||||
|
l != 0x0000 && l != 0xffff) {
|
||||||
|
DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l);
|
||||||
|
printk(KERN_INFO "PCI: Discovered peer bus %02x\n", busn);
|
||||||
|
pci_scan_bus_on_node(busn, &pci_root_ops, node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pcibios_scan_specific_bus);
|
||||||
|
|
||||||
int __init pci_subsys_init(void)
|
int __init pci_subsys_init(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -69,6 +69,9 @@ config EDAC_MM_EDAC
|
||||||
occurred so that a particular failing memory module can be
|
occurred so that a particular failing memory module can be
|
||||||
replaced. If unsure, select 'Y'.
|
replaced. If unsure, select 'Y'.
|
||||||
|
|
||||||
|
config EDAC_MCE
|
||||||
|
bool
|
||||||
|
|
||||||
config EDAC_AMD64
|
config EDAC_AMD64
|
||||||
tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
|
tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
|
||||||
depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE
|
depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE
|
||||||
|
@ -166,6 +169,16 @@ config EDAC_I5400
|
||||||
Support for error detection and correction the Intel
|
Support for error detection and correction the Intel
|
||||||
i5400 MCH chipset (Seaburg).
|
i5400 MCH chipset (Seaburg).
|
||||||
|
|
||||||
|
config EDAC_I7CORE
|
||||||
|
tristate "Intel i7 Core (Nehalem) processors"
|
||||||
|
depends on EDAC_MM_EDAC && PCI && X86
|
||||||
|
select EDAC_MCE
|
||||||
|
help
|
||||||
|
Support for error detection and correction the Intel
|
||||||
|
i7 Core (Nehalem) Integrated Memory Controller that exists on
|
||||||
|
newer processors like i7 Core, i7 Core Extreme, Xeon 35xx
|
||||||
|
and Xeon 55xx processors.
|
||||||
|
|
||||||
config EDAC_I82860
|
config EDAC_I82860
|
||||||
tristate "Intel 82860"
|
tristate "Intel 82860"
|
||||||
depends on EDAC_MM_EDAC && PCI && X86_32
|
depends on EDAC_MM_EDAC && PCI && X86_32
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
obj-$(CONFIG_EDAC) := edac_stub.o
|
obj-$(CONFIG_EDAC) := edac_stub.o
|
||||||
obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o
|
obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o
|
||||||
|
obj-$(CONFIG_EDAC_MCE) += edac_mce.o
|
||||||
|
|
||||||
edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
|
edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
|
||||||
edac_core-objs += edac_module.o edac_device_sysfs.o
|
edac_core-objs += edac_module.o edac_device_sysfs.o
|
||||||
|
@ -23,6 +24,7 @@ obj-$(CONFIG_EDAC_CPC925) += cpc925_edac.o
|
||||||
obj-$(CONFIG_EDAC_I5000) += i5000_edac.o
|
obj-$(CONFIG_EDAC_I5000) += i5000_edac.o
|
||||||
obj-$(CONFIG_EDAC_I5100) += i5100_edac.o
|
obj-$(CONFIG_EDAC_I5100) += i5100_edac.o
|
||||||
obj-$(CONFIG_EDAC_I5400) += i5400_edac.o
|
obj-$(CONFIG_EDAC_I5400) += i5400_edac.o
|
||||||
|
obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o
|
||||||
obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o
|
obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o
|
||||||
obj-$(CONFIG_EDAC_E752X) += e752x_edac.o
|
obj-$(CONFIG_EDAC_E752X) += e752x_edac.o
|
||||||
obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o
|
obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o
|
||||||
|
|
|
@ -341,12 +341,30 @@ struct csrow_info {
|
||||||
struct channel_info *channels;
|
struct channel_info *channels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mcidev_sysfs_group {
|
||||||
|
const char *name; /* group name */
|
||||||
|
struct mcidev_sysfs_attribute *mcidev_attr; /* group attributes */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mcidev_sysfs_group_kobj {
|
||||||
|
struct list_head list; /* list for all instances within a mc */
|
||||||
|
|
||||||
|
struct kobject kobj; /* kobj for the group */
|
||||||
|
|
||||||
|
struct mcidev_sysfs_group *grp; /* group description table */
|
||||||
|
struct mem_ctl_info *mci; /* the parent */
|
||||||
|
};
|
||||||
|
|
||||||
/* mcidev_sysfs_attribute structure
|
/* mcidev_sysfs_attribute structure
|
||||||
* used for driver sysfs attributes and in mem_ctl_info
|
* used for driver sysfs attributes and in mem_ctl_info
|
||||||
* sysfs top level entries
|
* sysfs top level entries
|
||||||
*/
|
*/
|
||||||
struct mcidev_sysfs_attribute {
|
struct mcidev_sysfs_attribute {
|
||||||
struct attribute attr;
|
/* It should use either attr or grp */
|
||||||
|
struct attribute attr;
|
||||||
|
struct mcidev_sysfs_group *grp; /* Points to a group of attributes */
|
||||||
|
|
||||||
|
/* Ops for show/store values at the attribute - not used on group */
|
||||||
ssize_t (*show)(struct mem_ctl_info *,char *);
|
ssize_t (*show)(struct mem_ctl_info *,char *);
|
||||||
ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
|
ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
|
||||||
};
|
};
|
||||||
|
@ -424,6 +442,9 @@ struct mem_ctl_info {
|
||||||
/* edac sysfs device control */
|
/* edac sysfs device control */
|
||||||
struct kobject edac_mci_kobj;
|
struct kobject edac_mci_kobj;
|
||||||
|
|
||||||
|
/* list for all grp instances within a mc */
|
||||||
|
struct list_head grp_kobj_list;
|
||||||
|
|
||||||
/* Additional top controller level attributes, but specified
|
/* Additional top controller level attributes, but specified
|
||||||
* by the low level driver.
|
* by the low level driver.
|
||||||
*
|
*
|
||||||
|
|
|
@ -557,6 +557,8 @@ static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr,
|
||||||
struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
|
struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
|
||||||
struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr);
|
struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr);
|
||||||
|
|
||||||
|
debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info);
|
||||||
|
|
||||||
if (mcidev_attr->show)
|
if (mcidev_attr->show)
|
||||||
return mcidev_attr->show(mem_ctl_info, buffer);
|
return mcidev_attr->show(mem_ctl_info, buffer);
|
||||||
|
|
||||||
|
@ -569,6 +571,8 @@ static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr,
|
||||||
struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
|
struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
|
||||||
struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr);
|
struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr);
|
||||||
|
|
||||||
|
debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info);
|
||||||
|
|
||||||
if (mcidev_attr->store)
|
if (mcidev_attr->store)
|
||||||
return mcidev_attr->store(mem_ctl_info, buffer, count);
|
return mcidev_attr->store(mem_ctl_info, buffer, count);
|
||||||
|
|
||||||
|
@ -726,28 +730,118 @@ void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci)
|
||||||
|
|
||||||
#define EDAC_DEVICE_SYMLINK "device"
|
#define EDAC_DEVICE_SYMLINK "device"
|
||||||
|
|
||||||
|
#define grp_to_mci(k) (container_of(k, struct mcidev_sysfs_group_kobj, kobj)->mci)
|
||||||
|
|
||||||
|
/* MCI show/store functions for top most object */
|
||||||
|
static ssize_t inst_grp_show(struct kobject *kobj, struct attribute *attr,
|
||||||
|
char *buffer)
|
||||||
|
{
|
||||||
|
struct mem_ctl_info *mem_ctl_info = grp_to_mci(kobj);
|
||||||
|
struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr);
|
||||||
|
|
||||||
|
debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info);
|
||||||
|
|
||||||
|
if (mcidev_attr->show)
|
||||||
|
return mcidev_attr->show(mem_ctl_info, buffer);
|
||||||
|
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t inst_grp_store(struct kobject *kobj, struct attribute *attr,
|
||||||
|
const char *buffer, size_t count)
|
||||||
|
{
|
||||||
|
struct mem_ctl_info *mem_ctl_info = grp_to_mci(kobj);
|
||||||
|
struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr);
|
||||||
|
|
||||||
|
debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info);
|
||||||
|
|
||||||
|
if (mcidev_attr->store)
|
||||||
|
return mcidev_attr->store(mem_ctl_info, buffer, count);
|
||||||
|
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No memory to release for this kobj */
|
||||||
|
static void edac_inst_grp_release(struct kobject *kobj)
|
||||||
|
{
|
||||||
|
struct mcidev_sysfs_group_kobj *grp;
|
||||||
|
struct mem_ctl_info *mci;
|
||||||
|
|
||||||
|
debugf1("%s()\n", __func__);
|
||||||
|
|
||||||
|
grp = container_of(kobj, struct mcidev_sysfs_group_kobj, kobj);
|
||||||
|
mci = grp->mci;
|
||||||
|
|
||||||
|
kobject_put(&mci->edac_mci_kobj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Intermediate show/store table */
|
||||||
|
static struct sysfs_ops inst_grp_ops = {
|
||||||
|
.show = inst_grp_show,
|
||||||
|
.store = inst_grp_store
|
||||||
|
};
|
||||||
|
|
||||||
|
/* the kobj_type instance for a instance group */
|
||||||
|
static struct kobj_type ktype_inst_grp = {
|
||||||
|
.release = edac_inst_grp_release,
|
||||||
|
.sysfs_ops = &inst_grp_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* edac_create_mci_instance_attributes
|
* edac_create_mci_instance_attributes
|
||||||
* create MC driver specific attributes at the topmost level
|
* create MC driver specific attributes bellow an specified kobj
|
||||||
* directory of this mci instance.
|
* This routine calls itself recursively, in order to create an entire
|
||||||
|
* object tree.
|
||||||
*/
|
*/
|
||||||
static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci)
|
static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
|
||||||
|
struct mcidev_sysfs_attribute *sysfs_attrib,
|
||||||
|
struct kobject *kobj)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct mcidev_sysfs_attribute *sysfs_attrib;
|
|
||||||
|
|
||||||
/* point to the start of the array and iterate over it
|
debugf1("%s()\n", __func__);
|
||||||
* adding each attribute listed to this mci instance's kobject
|
|
||||||
*/
|
while (sysfs_attrib) {
|
||||||
sysfs_attrib = mci->mc_driver_sysfs_attributes;
|
if (sysfs_attrib->grp) {
|
||||||
|
struct mcidev_sysfs_group_kobj *grp_kobj;
|
||||||
|
|
||||||
|
grp_kobj = kzalloc(sizeof(*grp_kobj), GFP_KERNEL);
|
||||||
|
if (!grp_kobj)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
list_add_tail(&grp_kobj->list, &mci->grp_kobj_list);
|
||||||
|
|
||||||
|
grp_kobj->grp = sysfs_attrib->grp;
|
||||||
|
grp_kobj->mci = mci;
|
||||||
|
|
||||||
|
debugf0("%s() grp %s, mci %p\n", __func__,
|
||||||
|
sysfs_attrib->grp->name, mci);
|
||||||
|
|
||||||
|
err = kobject_init_and_add(&grp_kobj->kobj,
|
||||||
|
&ktype_inst_grp,
|
||||||
|
&mci->edac_mci_kobj,
|
||||||
|
sysfs_attrib->grp->name);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = edac_create_mci_instance_attributes(mci,
|
||||||
|
grp_kobj->grp->mcidev_attr,
|
||||||
|
&grp_kobj->kobj);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
} else if (sysfs_attrib->attr.name) {
|
||||||
|
debugf0("%s() file %s\n", __func__,
|
||||||
|
sysfs_attrib->attr.name);
|
||||||
|
|
||||||
|
err = sysfs_create_file(kobj, &sysfs_attrib->attr);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
|
||||||
while (sysfs_attrib && sysfs_attrib->attr.name) {
|
|
||||||
err = sysfs_create_file(&mci->edac_mci_kobj,
|
|
||||||
(struct attribute*) sysfs_attrib);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
sysfs_attrib++;
|
sysfs_attrib++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,21 +853,44 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci)
|
||||||
* remove MC driver specific attributes at the topmost level
|
* remove MC driver specific attributes at the topmost level
|
||||||
* directory of this mci instance.
|
* directory of this mci instance.
|
||||||
*/
|
*/
|
||||||
static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci)
|
static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci,
|
||||||
|
struct mcidev_sysfs_attribute *sysfs_attrib,
|
||||||
|
struct kobject *kobj, int count)
|
||||||
{
|
{
|
||||||
struct mcidev_sysfs_attribute *sysfs_attrib;
|
struct mcidev_sysfs_group_kobj *grp_kobj, *tmp;
|
||||||
|
|
||||||
/* point to the start of the array and iterate over it
|
debugf1("%s()\n", __func__);
|
||||||
* adding each attribute listed to this mci instance's kobject
|
|
||||||
|
/*
|
||||||
|
* loop if there are attributes and until we hit a NULL entry
|
||||||
|
* Remove first all the atributes
|
||||||
*/
|
*/
|
||||||
sysfs_attrib = mci->mc_driver_sysfs_attributes;
|
while (sysfs_attrib) {
|
||||||
|
if (sysfs_attrib->grp) {
|
||||||
/* loop if there are attributes and until we hit a NULL entry */
|
list_for_each_entry(grp_kobj, &mci->grp_kobj_list,
|
||||||
while (sysfs_attrib && sysfs_attrib->attr.name) {
|
list)
|
||||||
sysfs_remove_file(&mci->edac_mci_kobj,
|
if (grp_kobj->grp == sysfs_attrib->grp)
|
||||||
(struct attribute *) sysfs_attrib);
|
edac_remove_mci_instance_attributes(mci,
|
||||||
|
grp_kobj->grp->mcidev_attr,
|
||||||
|
&grp_kobj->kobj, count + 1);
|
||||||
|
} else if (sysfs_attrib->attr.name) {
|
||||||
|
debugf0("%s() file %s\n", __func__,
|
||||||
|
sysfs_attrib->attr.name);
|
||||||
|
sysfs_remove_file(kobj, &sysfs_attrib->attr);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
sysfs_attrib++;
|
sysfs_attrib++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now that all attributes got removed, it is save to remove all groups
|
||||||
|
*/
|
||||||
|
if (!count)
|
||||||
|
list_for_each_entry_safe(grp_kobj, tmp, &mci->grp_kobj_list,
|
||||||
|
list) {
|
||||||
|
debugf0("%s() grp %s\n", __func__, grp_kobj->grp->name);
|
||||||
|
kobject_put(&grp_kobj->kobj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -794,6 +911,8 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
|
||||||
|
|
||||||
debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
|
debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&mci->grp_kobj_list);
|
||||||
|
|
||||||
/* create a symlink for the device */
|
/* create a symlink for the device */
|
||||||
err = sysfs_create_link(kobj_mci, &mci->dev->kobj,
|
err = sysfs_create_link(kobj_mci, &mci->dev->kobj,
|
||||||
EDAC_DEVICE_SYMLINK);
|
EDAC_DEVICE_SYMLINK);
|
||||||
|
@ -806,7 +925,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
|
||||||
* then create them now for the driver.
|
* then create them now for the driver.
|
||||||
*/
|
*/
|
||||||
if (mci->mc_driver_sysfs_attributes) {
|
if (mci->mc_driver_sysfs_attributes) {
|
||||||
err = edac_create_mci_instance_attributes(mci);
|
err = edac_create_mci_instance_attributes(mci,
|
||||||
|
mci->mc_driver_sysfs_attributes,
|
||||||
|
&mci->edac_mci_kobj);
|
||||||
if (err) {
|
if (err) {
|
||||||
debugf1("%s() failure to create mci attributes\n",
|
debugf1("%s() failure to create mci attributes\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -841,7 +962,8 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove the mci instance's attributes, if any */
|
/* remove the mci instance's attributes, if any */
|
||||||
edac_remove_mci_instance_attributes(mci);
|
edac_remove_mci_instance_attributes(mci,
|
||||||
|
mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj, 0);
|
||||||
|
|
||||||
/* remove the symlink */
|
/* remove the symlink */
|
||||||
sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK);
|
sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK);
|
||||||
|
@ -875,8 +997,9 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
|
||||||
debugf0("%s() remove_mci_instance\n", __func__);
|
debugf0("%s() remove_mci_instance\n", __func__);
|
||||||
|
|
||||||
/* remove this mci instance's attribtes */
|
/* remove this mci instance's attribtes */
|
||||||
edac_remove_mci_instance_attributes(mci);
|
edac_remove_mci_instance_attributes(mci,
|
||||||
|
mci->mc_driver_sysfs_attributes,
|
||||||
|
&mci->edac_mci_kobj, 0);
|
||||||
debugf0("%s() unregister this mci kobj\n", __func__);
|
debugf0("%s() unregister this mci kobj\n", __func__);
|
||||||
|
|
||||||
/* unregister this instance's kobject */
|
/* unregister this instance's kobject */
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/* Provides edac interface to mcelog events
|
||||||
|
*
|
||||||
|
* This file may be distributed under the terms of the
|
||||||
|
* GNU General Public License version 2.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 by:
|
||||||
|
* Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||||
|
*
|
||||||
|
* Red Hat Inc. http://www.redhat.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/edac_mce.h>
|
||||||
|
#include <asm/mce.h>
|
||||||
|
|
||||||
|
int edac_mce_enabled;
|
||||||
|
EXPORT_SYMBOL_GPL(edac_mce_enabled);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extension interface
|
||||||
|
*/
|
||||||
|
|
||||||
|
static LIST_HEAD(edac_mce_list);
|
||||||
|
static DEFINE_MUTEX(edac_mce_lock);
|
||||||
|
|
||||||
|
int edac_mce_register(struct edac_mce *edac_mce)
|
||||||
|
{
|
||||||
|
mutex_lock(&edac_mce_lock);
|
||||||
|
list_add_tail(&edac_mce->list, &edac_mce_list);
|
||||||
|
mutex_unlock(&edac_mce_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(edac_mce_register);
|
||||||
|
|
||||||
|
void edac_mce_unregister(struct edac_mce *edac_mce)
|
||||||
|
{
|
||||||
|
mutex_lock(&edac_mce_lock);
|
||||||
|
list_del(&edac_mce->list);
|
||||||
|
mutex_unlock(&edac_mce_lock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(edac_mce_unregister);
|
||||||
|
|
||||||
|
int edac_mce_parse(struct mce *mce)
|
||||||
|
{
|
||||||
|
struct edac_mce *edac_mce;
|
||||||
|
|
||||||
|
list_for_each_entry(edac_mce, &edac_mce_list, list) {
|
||||||
|
if (edac_mce->check_error(edac_mce->priv, mce))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nobody queued the error */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(edac_mce_parse);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
|
||||||
|
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
|
||||||
|
MODULE_DESCRIPTION("EDAC Driver for mcelog captured errors");
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
||||||
|
/* Provides edac interface to mcelog events
|
||||||
|
*
|
||||||
|
* This file may be distributed under the terms of the
|
||||||
|
* GNU General Public License version 2.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 by:
|
||||||
|
* Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||||
|
*
|
||||||
|
* Red Hat Inc. http://www.redhat.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_EDAC_MCE) || \
|
||||||
|
(defined(CONFIG_EDAC_MCE_MODULE) && defined(MODULE))
|
||||||
|
|
||||||
|
#include <asm/mce.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
|
||||||
|
struct edac_mce {
|
||||||
|
struct list_head list;
|
||||||
|
|
||||||
|
void *priv;
|
||||||
|
int (*check_error)(void *priv, struct mce *mce);
|
||||||
|
};
|
||||||
|
|
||||||
|
int edac_mce_register(struct edac_mce *edac_mce);
|
||||||
|
void edac_mce_unregister(struct edac_mce *edac_mce);
|
||||||
|
int edac_mce_parse(struct mce *mce);
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define edac_mce_parse(mce) (0)
|
||||||
|
#endif
|
|
@ -632,6 +632,7 @@ void pci_fixup_cardbus(struct pci_bus *);
|
||||||
|
|
||||||
/* Generic PCI functions used internally */
|
/* Generic PCI functions used internally */
|
||||||
|
|
||||||
|
void pcibios_scan_specific_bus(int busn);
|
||||||
extern struct pci_bus *pci_find_bus(int domain, int busnr);
|
extern struct pci_bus *pci_find_bus(int domain, int busnr);
|
||||||
void pci_bus_add_devices(const struct pci_bus *bus);
|
void pci_bus_add_devices(const struct pci_bus *bus);
|
||||||
struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
|
struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
|
||||||
|
|
|
@ -2532,11 +2532,63 @@
|
||||||
#define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930
|
#define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930
|
||||||
#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916
|
#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916
|
||||||
#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918
|
#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MCR 0x2c18
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_TAD 0x2c19
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_RAS 0x2c1a
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_TEST 0x2c1c
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL 0x2c20
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR 0x2c21
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_RANK 0x2c22
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_TC 0x2c23
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL 0x2c28
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_ADDR 0x2c29
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_RANK 0x2c2a
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_TC 0x2c2b
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL 0x2c30
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR 0x2c31
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK 0x2c32
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC 0x2c33
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_NONCORE 0x2c41
|
||||||
|
#define PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT 0x2c40
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE 0x2c50
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT 0x2c51
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2 0x2c70
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_SAD 0x2c81
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0 0x2c90
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_PHY0 0x2c91
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR 0x2c98
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD 0x2c99
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST 0x2c9C
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL 0x2ca0
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR 0x2ca1
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK 0x2ca2
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC 0x2ca3
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL 0x2ca8
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR 0x2ca9
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK 0x2caa
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC 0x2cab
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR_REV2 0x2d98
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD_REV2 0x2d99
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_RAS_REV2 0x2d9a
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST_REV2 0x2d9c
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL_REV2 0x2da0
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR_REV2 0x2da1
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK_REV2 0x2da2
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC_REV2 0x2da3
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL_REV2 0x2da8
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR_REV2 0x2da9
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK_REV2 0x2daa
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC_REV2 0x2dab
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_CTRL_REV2 0x2db0
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2 0x2db1
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2 0x2db2
|
||||||
|
#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2 0x2db3
|
||||||
#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
|
#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
|
||||||
#define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429
|
#define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429
|
||||||
#define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a
|
#define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a
|
||||||
#define PCI_DEVICE_ID_INTEL_IOAT_TBG6 0x342b
|
#define PCI_DEVICE_ID_INTEL_IOAT_TBG6 0x342b
|
||||||
#define PCI_DEVICE_ID_INTEL_IOAT_TBG7 0x342c
|
#define PCI_DEVICE_ID_INTEL_IOAT_TBG7 0x342c
|
||||||
|
#define PCI_DEVICE_ID_INTEL_X58_HUB_MGMT 0x342e
|
||||||
#define PCI_DEVICE_ID_INTEL_IOAT_TBG0 0x3430
|
#define PCI_DEVICE_ID_INTEL_IOAT_TBG0 0x3430
|
||||||
#define PCI_DEVICE_ID_INTEL_IOAT_TBG1 0x3431
|
#define PCI_DEVICE_ID_INTEL_IOAT_TBG1 0x3431
|
||||||
#define PCI_DEVICE_ID_INTEL_IOAT_TBG2 0x3432
|
#define PCI_DEVICE_ID_INTEL_IOAT_TBG2 0x3432
|
||||||
|
|
Loading…
Reference in New Issue