Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
cee72d5b
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
cee72d5b
编写于
11月 29, 2011
作者:
B
Benjamin Herrenschmidt
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
powerpc/powernv: Display diag data on p7ioc EEH errors
Signed-off-by:
N
Benjamin Herrenschmidt
<
benh@kernel.crashing.org
>
上级
f11fe552
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
140 addition
and
19 deletion
+140
-19
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/powernv/pci-ioda.c
+15
-10
arch/powerpc/platforms/powernv/pci-p5ioc2.c
arch/powerpc/platforms/powernv/pci-p5ioc2.c
+1
-0
arch/powerpc/platforms/powernv/pci.c
arch/powerpc/platforms/powernv/pci.c
+108
-9
arch/powerpc/platforms/powernv/pci.h
arch/powerpc/platforms/powernv/pci.h
+16
-0
未找到文件。
arch/powerpc/platforms/powernv/pci-ioda.c
浏览文件 @
cee72d5b
...
...
@@ -9,7 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
#
define
DEBUG
#
undef
DEBUG
#include <linux/kernel.h>
#include <linux/pci.h>
...
...
@@ -467,14 +467,13 @@ static void __devinit pnv_ioda_update_resources(struct pci_bus *bus)
struct
pci_bus
*
cbus
;
struct
pci_dev
*
cdev
;
unsigned
int
i
;
u16
cmd
;
/*
Clear all device enables */
list_for_each_entry
(
cdev
,
&
bus
->
devices
,
bus_list
)
{
pci_read_config_word
(
cdev
,
PCI_COMMAND
,
&
cmd
);
cmd
&=
~
(
PCI_COMMAND_IO
|
PCI_COMMAND_MEMORY
|
PCI_COMMAND_MASTER
);
pci_write_config_word
(
cdev
,
PCI_COMMAND
,
cmd
);
}
/*
We used to clear all device enables here. However it looks like
* clearing MEM enable causes Obsidian (IPR SCS) to go bonkers,
* and shoot fatal errors to the PHB which in turns fences itself
* and we can't recover from that ... yet. So for now, let's leave
* the enables as-is and hope for the best.
*/
/* Check if bus resources fit in our IO or M32 range */
for
(
i
=
0
;
bus
->
self
&&
(
i
<
2
);
i
++
)
{
...
...
@@ -618,7 +617,7 @@ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb,
struct
pci_dn
*
pdn
=
pnv_ioda_get_pdn
(
parent
);
if
(
pdn
&&
pdn
->
pe_number
!=
IODA_INVALID_PE
)
{
rc
=
opal_pci_set_peltv
(
phb
->
opal_id
,
pdn
->
pe_number
,
pe
->
pe_number
,
1
);
pe
->
pe_number
,
OPAL_ADD_PE_TO_DOMAIN
);
/* XXX What to do in case of error ? */
}
parent
=
parent
->
bus
->
self
;
...
...
@@ -638,7 +637,7 @@ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb,
pe
->
mve_number
=
-
1
;
}
else
{
rc
=
opal_pci_set_mve_enable
(
phb
->
opal_id
,
pe
->
mve_number
,
1
);
pe
->
mve_number
,
OPAL_ENABLE_MVE
);
if
(
rc
)
{
pe_err
(
pe
,
"OPAL error %ld enabling MVE %d
\n
"
,
rc
,
pe
->
mve_number
);
...
...
@@ -1187,6 +1186,12 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
phb
->
opal_id
=
phb_id
;
phb
->
type
=
PNV_PHB_IODA1
;
/* Detect specific models for error handling */
if
(
of_device_is_compatible
(
np
,
"ibm,p7ioc-pciex"
))
phb
->
model
=
PNV_PHB_MODEL_P7IOC
;
else
phb
->
model
=
PNV_PHB_MODEL_UNKNOWN
;
/* We parse "ranges" now since we need to deduce the register base
* from the IO base
*/
...
...
arch/powerpc/platforms/powernv/pci-p5ioc2.c
浏览文件 @
cee72d5b
...
...
@@ -137,6 +137,7 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np,
phb
->
hose
->
private_data
=
phb
;
phb
->
opal_id
=
phb_id
;
phb
->
type
=
PNV_PHB_P5IOC2
;
phb
->
model
=
PNV_PHB_MODEL_P5IOC2
;
phb
->
regs
=
of_iomap
(
np
,
0
);
...
...
arch/powerpc/platforms/powernv/pci.c
浏览文件 @
cee72d5b
...
...
@@ -144,6 +144,112 @@ static void pnv_teardown_msi_irqs(struct pci_dev *pdev)
}
#endif
/* CONFIG_PCI_MSI */
static
void
pnv_pci_dump_p7ioc_diag_data
(
struct
pnv_phb
*
phb
)
{
struct
OpalIoP7IOCPhbErrorData
*
data
=
&
phb
->
diag
.
p7ioc
;
int
i
;
pr_info
(
"PHB %d diagnostic data:
\n
"
,
phb
->
hose
->
global_number
);
pr_info
(
" brdgCtl = 0x%08x
\n
"
,
data
->
brdgCtl
);
pr_info
(
" portStatusReg = 0x%08x
\n
"
,
data
->
portStatusReg
);
pr_info
(
" rootCmplxStatus = 0x%08x
\n
"
,
data
->
rootCmplxStatus
);
pr_info
(
" busAgentStatus = 0x%08x
\n
"
,
data
->
busAgentStatus
);
pr_info
(
" deviceStatus = 0x%08x
\n
"
,
data
->
deviceStatus
);
pr_info
(
" slotStatus = 0x%08x
\n
"
,
data
->
slotStatus
);
pr_info
(
" linkStatus = 0x%08x
\n
"
,
data
->
linkStatus
);
pr_info
(
" devCmdStatus = 0x%08x
\n
"
,
data
->
devCmdStatus
);
pr_info
(
" devSecStatus = 0x%08x
\n
"
,
data
->
devSecStatus
);
pr_info
(
" rootErrorStatus = 0x%08x
\n
"
,
data
->
rootErrorStatus
);
pr_info
(
" uncorrErrorStatus = 0x%08x
\n
"
,
data
->
uncorrErrorStatus
);
pr_info
(
" corrErrorStatus = 0x%08x
\n
"
,
data
->
corrErrorStatus
);
pr_info
(
" tlpHdr1 = 0x%08x
\n
"
,
data
->
tlpHdr1
);
pr_info
(
" tlpHdr2 = 0x%08x
\n
"
,
data
->
tlpHdr2
);
pr_info
(
" tlpHdr3 = 0x%08x
\n
"
,
data
->
tlpHdr3
);
pr_info
(
" tlpHdr4 = 0x%08x
\n
"
,
data
->
tlpHdr4
);
pr_info
(
" sourceId = 0x%08x
\n
"
,
data
->
sourceId
);
pr_info
(
" errorClass = 0x%016llx
\n
"
,
data
->
errorClass
);
pr_info
(
" correlator = 0x%016llx
\n
"
,
data
->
correlator
);
pr_info
(
" p7iocPlssr = 0x%016llx
\n
"
,
data
->
p7iocPlssr
);
pr_info
(
" p7iocCsr = 0x%016llx
\n
"
,
data
->
p7iocCsr
);
pr_info
(
" lemFir = 0x%016llx
\n
"
,
data
->
lemFir
);
pr_info
(
" lemErrorMask = 0x%016llx
\n
"
,
data
->
lemErrorMask
);
pr_info
(
" lemWOF = 0x%016llx
\n
"
,
data
->
lemWOF
);
pr_info
(
" phbErrorStatus = 0x%016llx
\n
"
,
data
->
phbErrorStatus
);
pr_info
(
" phbFirstErrorStatus = 0x%016llx
\n
"
,
data
->
phbFirstErrorStatus
);
pr_info
(
" phbErrorLog0 = 0x%016llx
\n
"
,
data
->
phbErrorLog0
);
pr_info
(
" phbErrorLog1 = 0x%016llx
\n
"
,
data
->
phbErrorLog1
);
pr_info
(
" mmioErrorStatus = 0x%016llx
\n
"
,
data
->
mmioErrorStatus
);
pr_info
(
" mmioFirstErrorStatus = 0x%016llx
\n
"
,
data
->
mmioFirstErrorStatus
);
pr_info
(
" mmioErrorLog0 = 0x%016llx
\n
"
,
data
->
mmioErrorLog0
);
pr_info
(
" mmioErrorLog1 = 0x%016llx
\n
"
,
data
->
mmioErrorLog1
);
pr_info
(
" dma0ErrorStatus = 0x%016llx
\n
"
,
data
->
dma0ErrorStatus
);
pr_info
(
" dma0FirstErrorStatus = 0x%016llx
\n
"
,
data
->
dma0FirstErrorStatus
);
pr_info
(
" dma0ErrorLog0 = 0x%016llx
\n
"
,
data
->
dma0ErrorLog0
);
pr_info
(
" dma0ErrorLog1 = 0x%016llx
\n
"
,
data
->
dma0ErrorLog1
);
pr_info
(
" dma1ErrorStatus = 0x%016llx
\n
"
,
data
->
dma1ErrorStatus
);
pr_info
(
" dma1FirstErrorStatus = 0x%016llx
\n
"
,
data
->
dma1FirstErrorStatus
);
pr_info
(
" dma1ErrorLog0 = 0x%016llx
\n
"
,
data
->
dma1ErrorLog0
);
pr_info
(
" dma1ErrorLog1 = 0x%016llx
\n
"
,
data
->
dma1ErrorLog1
);
for
(
i
=
0
;
i
<
OPAL_P7IOC_NUM_PEST_REGS
;
i
++
)
{
if
((
data
->
pestA
[
i
]
>>
63
)
==
0
&&
(
data
->
pestB
[
i
]
>>
63
)
==
0
)
continue
;
pr_info
(
" PE[%3d] PESTA = 0x%016llx
\n
"
,
i
,
data
->
pestA
[
i
]);
pr_info
(
" PESTB = 0x%016llx
\n
"
,
data
->
pestB
[
i
]);
}
}
static
void
pnv_pci_dump_phb_diag_data
(
struct
pnv_phb
*
phb
)
{
switch
(
phb
->
model
)
{
case
PNV_PHB_MODEL_P7IOC
:
pnv_pci_dump_p7ioc_diag_data
(
phb
);
break
;
default:
pr_warning
(
"PCI %d: Can't decode this PHB diag data
\n
"
,
phb
->
hose
->
global_number
);
}
}
static
void
pnv_pci_handle_eeh_config
(
struct
pnv_phb
*
phb
,
u32
pe_no
)
{
unsigned
long
flags
,
rc
;
int
has_diag
;
spin_lock_irqsave
(
&
phb
->
lock
,
flags
);
rc
=
opal_pci_get_phb_diag_data
(
phb
->
opal_id
,
phb
->
diag
.
blob
,
PNV_PCI_DIAG_BUF_SIZE
);
has_diag
=
(
rc
==
OPAL_SUCCESS
);
rc
=
opal_pci_eeh_freeze_clear
(
phb
->
opal_id
,
pe_no
,
OPAL_EEH_ACTION_CLEAR_FREEZE_ALL
);
if
(
rc
)
{
pr_warning
(
"PCI %d: Failed to clear EEH freeze state"
" for PE#%d, err %ld
\n
"
,
phb
->
hose
->
global_number
,
pe_no
,
rc
);
/* For now, let's only display the diag buffer when we fail to clear
* the EEH status. We'll do more sensible things later when we have
* proper EEH support. We need to make sure we don't pollute ourselves
* with the normal errors generated when probing empty slots
*/
if
(
has_diag
)
pnv_pci_dump_phb_diag_data
(
phb
);
else
pr_warning
(
"PCI %d: No diag data available
\n
"
,
phb
->
hose
->
global_number
);
}
spin_unlock_irqrestore
(
&
phb
->
lock
,
flags
);
}
static
void
pnv_pci_config_check_eeh
(
struct
pnv_phb
*
phb
,
struct
pci_bus
*
bus
,
u32
bdfn
)
{
...
...
@@ -165,15 +271,8 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus,
}
cfg_dbg
(
" -> EEH check, bdfn=%04x PE%d fstate=%x
\n
"
,
bdfn
,
pe_no
,
fstate
);
if
(
fstate
!=
0
)
{
rc
=
opal_pci_eeh_freeze_clear
(
phb
->
opal_id
,
pe_no
,
OPAL_EEH_ACTION_CLEAR_FREEZE_ALL
);
if
(
rc
)
{
pr_warning
(
"PCI %d: Failed to clear EEH freeze state"
" for PE#%d, err %lld
\n
"
,
phb
->
hose
->
global_number
,
pe_no
,
rc
);
}
}
if
(
fstate
!=
0
)
pnv_pci_handle_eeh_config
(
phb
,
pe_no
);
}
static
int
pnv_pci_read_config
(
struct
pci_bus
*
bus
,
...
...
arch/powerpc/platforms/powernv/pci.h
浏览文件 @
cee72d5b
...
...
@@ -9,6 +9,15 @@ enum pnv_phb_type {
PNV_PHB_IODA2
,
};
/* Precise PHB model for error management */
enum
pnv_phb_model
{
PNV_PHB_MODEL_UNKNOWN
,
PNV_PHB_MODEL_P5IOC2
,
PNV_PHB_MODEL_P7IOC
,
};
#define PNV_PCI_DIAG_BUF_SIZE 4096
/* Data associated with a PE, including IOMMU tracking etc.. */
struct
pnv_ioda_pe
{
/* A PE can be associated with a single device or an
...
...
@@ -56,6 +65,7 @@ struct pnv_ioda_pe {
struct
pnv_phb
{
struct
pci_controller
*
hose
;
enum
pnv_phb_type
type
;
enum
pnv_phb_model
model
;
u64
opal_id
;
void
__iomem
*
regs
;
spinlock_t
lock
;
...
...
@@ -118,6 +128,12 @@ struct pnv_phb {
struct
list_head
pe_list
;
}
ioda
;
};
/* PHB status structure */
union
{
unsigned
char
blob
[
PNV_PCI_DIAG_BUF_SIZE
];
struct
OpalIoP7IOCPhbErrorData
p7ioc
;
}
diag
;
};
extern
struct
pci_ops
pnv_pci_ops
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录