Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
44814ec9
cloud-kernel
项目概览
openanolis
/
cloud-kernel
接近 2 年 前同步成功
通知
169
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看板
提交
44814ec9
编写于
9月 12, 2017
作者:
C
Corey Minyard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ipmi_si: Move the hotmod handling to another file.
Signed-off-by:
N
Corey Minyard
<
cminyard@mvista.com
>
上级
bb398a4c
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
264 addition
and
244 deletion
+264
-244
drivers/char/ipmi/Makefile
drivers/char/ipmi/Makefile
+2
-1
drivers/char/ipmi/ipmi_si.h
drivers/char/ipmi/ipmi_si.h
+2
-0
drivers/char/ipmi/ipmi_si_hotmod.c
drivers/char/ipmi/ipmi_si_hotmod.c
+242
-0
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/ipmi/ipmi_si_intf.c
+18
-243
未找到文件。
drivers/char/ipmi/Makefile
浏览文件 @
44814ec9
...
...
@@ -2,7 +2,8 @@
# Makefile for the ipmi drivers.
#
ipmi_si-y
:=
ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o
ipmi_si-y
:=
ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o
\
ipmi_si_hotmod.o
obj-$(CONFIG_IPMI_HANDLER)
+=
ipmi_msghandler.o
obj-$(CONFIG_IPMI_DEVICE_INTERFACE)
+=
ipmi_devintf.o
...
...
drivers/char/ipmi/ipmi_si.h
浏览文件 @
44814ec9
...
...
@@ -20,3 +20,5 @@ void ipmi_irq_start_cleanup(struct si_sm_io *io);
int
ipmi_std_irq_setup
(
struct
si_sm_io
*
io
);
void
ipmi_irq_finish_setup
(
struct
si_sm_io
*
io
);
int
ipmi_si_remove_by_dev
(
struct
device
*
dev
);
void
ipmi_si_remove_by_data
(
int
addr_space
,
enum
si_type
si_type
,
unsigned
long
addr
);
drivers/char/ipmi/ipmi_si_hotmod.c
0 → 100644
浏览文件 @
44814ec9
/*
* ipmi_si_hotmod.c
*
* Handling for dynamically adding/removing IPMI devices through
* a module parameter (and thus sysfs).
*/
#include <linux/moduleparam.h>
#include <linux/ipmi.h>
#include "ipmi_si.h"
#define PFX "ipmi_hotmod: "
static
int
hotmod_handler
(
const
char
*
val
,
struct
kernel_param
*
kp
);
module_param_call
(
hotmod
,
hotmod_handler
,
NULL
,
NULL
,
0200
);
MODULE_PARM_DESC
(
hotmod
,
"Add and remove interfaces. See"
" Documentation/IPMI.txt in the kernel sources for the"
" gory details."
);
/*
* Parms come in as <op1>[:op2[:op3...]]. ops are:
* add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]]
* Options are:
* rsp=<regspacing>
* rsi=<regsize>
* rsh=<regshift>
* irq=<irq>
* ipmb=<ipmb addr>
*/
enum
hotmod_op
{
HM_ADD
,
HM_REMOVE
};
struct
hotmod_vals
{
const
char
*
name
;
const
int
val
;
};
static
const
struct
hotmod_vals
hotmod_ops
[]
=
{
{
"add"
,
HM_ADD
},
{
"remove"
,
HM_REMOVE
},
{
NULL
}
};
static
const
struct
hotmod_vals
hotmod_si
[]
=
{
{
"kcs"
,
SI_KCS
},
{
"smic"
,
SI_SMIC
},
{
"bt"
,
SI_BT
},
{
NULL
}
};
static
const
struct
hotmod_vals
hotmod_as
[]
=
{
{
"mem"
,
IPMI_MEM_ADDR_SPACE
},
{
"i/o"
,
IPMI_IO_ADDR_SPACE
},
{
NULL
}
};
static
int
parse_str
(
const
struct
hotmod_vals
*
v
,
int
*
val
,
char
*
name
,
char
**
curr
)
{
char
*
s
;
int
i
;
s
=
strchr
(
*
curr
,
','
);
if
(
!
s
)
{
pr_warn
(
PFX
"No hotmod %s given.
\n
"
,
name
);
return
-
EINVAL
;
}
*
s
=
'\0'
;
s
++
;
for
(
i
=
0
;
v
[
i
].
name
;
i
++
)
{
if
(
strcmp
(
*
curr
,
v
[
i
].
name
)
==
0
)
{
*
val
=
v
[
i
].
val
;
*
curr
=
s
;
return
0
;
}
}
pr_warn
(
PFX
"Invalid hotmod %s '%s'
\n
"
,
name
,
*
curr
);
return
-
EINVAL
;
}
static
int
check_hotmod_int_op
(
const
char
*
curr
,
const
char
*
option
,
const
char
*
name
,
int
*
val
)
{
char
*
n
;
if
(
strcmp
(
curr
,
name
)
==
0
)
{
if
(
!
option
)
{
pr_warn
(
PFX
"No option given for '%s'
\n
"
,
curr
);
return
-
EINVAL
;
}
*
val
=
simple_strtoul
(
option
,
&
n
,
0
);
if
((
*
n
!=
'\0'
)
||
(
*
option
==
'\0'
))
{
pr_warn
(
PFX
"Bad option given for '%s'
\n
"
,
curr
);
return
-
EINVAL
;
}
return
1
;
}
return
0
;
}
static
int
hotmod_handler
(
const
char
*
val
,
struct
kernel_param
*
kp
)
{
char
*
str
=
kstrdup
(
val
,
GFP_KERNEL
);
int
rv
;
char
*
next
,
*
curr
,
*
s
,
*
n
,
*
o
;
enum
hotmod_op
op
;
enum
si_type
si_type
;
int
addr_space
;
unsigned
long
addr
;
int
regspacing
;
int
regsize
;
int
regshift
;
int
irq
;
int
ipmb
;
int
ival
;
int
len
;
if
(
!
str
)
return
-
ENOMEM
;
/* Kill any trailing spaces, as we can get a "\n" from echo. */
len
=
strlen
(
str
);
ival
=
len
-
1
;
while
((
ival
>=
0
)
&&
isspace
(
str
[
ival
]))
{
str
[
ival
]
=
'\0'
;
ival
--
;
}
for
(
curr
=
str
;
curr
;
curr
=
next
)
{
regspacing
=
1
;
regsize
=
1
;
regshift
=
0
;
irq
=
0
;
ipmb
=
0
;
/* Choose the default if not specified */
next
=
strchr
(
curr
,
':'
);
if
(
next
)
{
*
next
=
'\0'
;
next
++
;
}
rv
=
parse_str
(
hotmod_ops
,
&
ival
,
"operation"
,
&
curr
);
if
(
rv
)
break
;
op
=
ival
;
rv
=
parse_str
(
hotmod_si
,
&
ival
,
"interface type"
,
&
curr
);
if
(
rv
)
break
;
si_type
=
ival
;
rv
=
parse_str
(
hotmod_as
,
&
addr_space
,
"address space"
,
&
curr
);
if
(
rv
)
break
;
s
=
strchr
(
curr
,
','
);
if
(
s
)
{
*
s
=
'\0'
;
s
++
;
}
addr
=
simple_strtoul
(
curr
,
&
n
,
0
);
if
((
*
n
!=
'\0'
)
||
(
*
curr
==
'\0'
))
{
pr_warn
(
PFX
"Invalid hotmod address '%s'
\n
"
,
curr
);
break
;
}
while
(
s
)
{
curr
=
s
;
s
=
strchr
(
curr
,
','
);
if
(
s
)
{
*
s
=
'\0'
;
s
++
;
}
o
=
strchr
(
curr
,
'='
);
if
(
o
)
{
*
o
=
'\0'
;
o
++
;
}
rv
=
check_hotmod_int_op
(
curr
,
o
,
"rsp"
,
&
regspacing
);
if
(
rv
<
0
)
goto
out
;
else
if
(
rv
)
continue
;
rv
=
check_hotmod_int_op
(
curr
,
o
,
"rsi"
,
&
regsize
);
if
(
rv
<
0
)
goto
out
;
else
if
(
rv
)
continue
;
rv
=
check_hotmod_int_op
(
curr
,
o
,
"rsh"
,
&
regshift
);
if
(
rv
<
0
)
goto
out
;
else
if
(
rv
)
continue
;
rv
=
check_hotmod_int_op
(
curr
,
o
,
"irq"
,
&
irq
);
if
(
rv
<
0
)
goto
out
;
else
if
(
rv
)
continue
;
rv
=
check_hotmod_int_op
(
curr
,
o
,
"ipmb"
,
&
ipmb
);
if
(
rv
<
0
)
goto
out
;
else
if
(
rv
)
continue
;
rv
=
-
EINVAL
;
pr_warn
(
PFX
"Invalid hotmod option '%s'
\n
"
,
curr
);
goto
out
;
}
if
(
op
==
HM_ADD
)
{
struct
si_sm_io
io
;
memset
(
&
io
,
0
,
sizeof
(
io
));
io
.
addr_source
=
SI_HOTMOD
;
io
.
si_type
=
si_type
;
io
.
addr_data
=
addr
;
io
.
addr_type
=
addr_space
;
io
.
addr
=
NULL
;
io
.
regspacing
=
regspacing
;
if
(
!
io
.
regspacing
)
io
.
regspacing
=
DEFAULT_REGSPACING
;
io
.
regsize
=
regsize
;
if
(
!
io
.
regsize
)
io
.
regsize
=
DEFAULT_REGSIZE
;
io
.
regshift
=
regshift
;
io
.
irq
=
irq
;
if
(
io
.
irq
)
io
.
irq_setup
=
ipmi_std_irq_setup
;
io
.
slave_addr
=
ipmb
;
rv
=
ipmi_si_add_smi
(
&
io
);
if
(
rv
)
goto
out
;
}
else
{
ipmi_si_remove_by_data
(
addr_space
,
si_type
,
addr
);
}
}
rv
=
len
;
out:
kfree
(
str
);
return
rv
;
}
drivers/char/ipmi/ipmi_si_intf.c
浏览文件 @
44814ec9
...
...
@@ -1310,13 +1310,6 @@ static unsigned int num_slave_addrs;
static
const
char
*
const
addr_space_to_str
[]
=
{
"i/o"
,
"mem"
};
static
int
hotmod_handler
(
const
char
*
val
,
struct
kernel_param
*
kp
);
module_param_call
(
hotmod
,
hotmod_handler
,
NULL
,
NULL
,
0200
);
MODULE_PARM_DESC
(
hotmod
,
"Add and remove interfaces. See"
" Documentation/IPMI.txt in the kernel sources for the"
" gory details."
);
#ifdef CONFIG_ACPI
module_param_named
(
tryacpi
,
si_tryacpi
,
bool
,
0
);
MODULE_PARM_DESC
(
tryacpi
,
"Setting this to zero will disable the"
...
...
@@ -1689,86 +1682,6 @@ static int mem_setup(struct si_sm_io *io)
return
0
;
}
/*
* Parms come in as <op1>[:op2[:op3...]]. ops are:
* add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]]
* Options are:
* rsp=<regspacing>
* rsi=<regsize>
* rsh=<regshift>
* irq=<irq>
* ipmb=<ipmb addr>
*/
enum
hotmod_op
{
HM_ADD
,
HM_REMOVE
};
struct
hotmod_vals
{
const
char
*
name
;
const
int
val
;
};
static
const
struct
hotmod_vals
hotmod_ops
[]
=
{
{
"add"
,
HM_ADD
},
{
"remove"
,
HM_REMOVE
},
{
NULL
}
};
static
const
struct
hotmod_vals
hotmod_si
[]
=
{
{
"kcs"
,
SI_KCS
},
{
"smic"
,
SI_SMIC
},
{
"bt"
,
SI_BT
},
{
NULL
}
};
static
const
struct
hotmod_vals
hotmod_as
[]
=
{
{
"mem"
,
IPMI_MEM_ADDR_SPACE
},
{
"i/o"
,
IPMI_IO_ADDR_SPACE
},
{
NULL
}
};
static
int
parse_str
(
const
struct
hotmod_vals
*
v
,
int
*
val
,
char
*
name
,
char
**
curr
)
{
char
*
s
;
int
i
;
s
=
strchr
(
*
curr
,
','
);
if
(
!
s
)
{
pr_warn
(
PFX
"No hotmod %s given.
\n
"
,
name
);
return
-
EINVAL
;
}
*
s
=
'\0'
;
s
++
;
for
(
i
=
0
;
v
[
i
].
name
;
i
++
)
{
if
(
strcmp
(
*
curr
,
v
[
i
].
name
)
==
0
)
{
*
val
=
v
[
i
].
val
;
*
curr
=
s
;
return
0
;
}
}
pr_warn
(
PFX
"Invalid hotmod %s '%s'
\n
"
,
name
,
*
curr
);
return
-
EINVAL
;
}
static
int
check_hotmod_int_op
(
const
char
*
curr
,
const
char
*
option
,
const
char
*
name
,
int
*
val
)
{
char
*
n
;
if
(
strcmp
(
curr
,
name
)
==
0
)
{
if
(
!
option
)
{
pr_warn
(
PFX
"No option given for '%s'
\n
"
,
curr
);
return
-
EINVAL
;
}
*
val
=
simple_strtoul
(
option
,
&
n
,
0
);
if
((
*
n
!=
'\0'
)
||
(
*
option
==
'\0'
))
{
pr_warn
(
PFX
"Bad option given for '%s'
\n
"
,
curr
);
return
-
EINVAL
;
}
return
1
;
}
return
0
;
}
static
struct
smi_info
*
smi_info_alloc
(
void
)
{
struct
smi_info
*
info
=
kzalloc
(
sizeof
(
*
info
),
GFP_KERNEL
);
...
...
@@ -1778,162 +1691,6 @@ static struct smi_info *smi_info_alloc(void)
return
info
;
}
static
int
hotmod_handler
(
const
char
*
val
,
struct
kernel_param
*
kp
)
{
char
*
str
=
kstrdup
(
val
,
GFP_KERNEL
);
int
rv
;
char
*
next
,
*
curr
,
*
s
,
*
n
,
*
o
;
enum
hotmod_op
op
;
enum
si_type
si_type
;
int
addr_space
;
unsigned
long
addr
;
int
regspacing
;
int
regsize
;
int
regshift
;
int
irq
;
int
ipmb
;
int
ival
;
int
len
;
if
(
!
str
)
return
-
ENOMEM
;
/* Kill any trailing spaces, as we can get a "\n" from echo. */
len
=
strlen
(
str
);
ival
=
len
-
1
;
while
((
ival
>=
0
)
&&
isspace
(
str
[
ival
]))
{
str
[
ival
]
=
'\0'
;
ival
--
;
}
for
(
curr
=
str
;
curr
;
curr
=
next
)
{
regspacing
=
1
;
regsize
=
1
;
regshift
=
0
;
irq
=
0
;
ipmb
=
0
;
/* Choose the default if not specified */
next
=
strchr
(
curr
,
':'
);
if
(
next
)
{
*
next
=
'\0'
;
next
++
;
}
rv
=
parse_str
(
hotmod_ops
,
&
ival
,
"operation"
,
&
curr
);
if
(
rv
)
break
;
op
=
ival
;
rv
=
parse_str
(
hotmod_si
,
&
ival
,
"interface type"
,
&
curr
);
if
(
rv
)
break
;
si_type
=
ival
;
rv
=
parse_str
(
hotmod_as
,
&
addr_space
,
"address space"
,
&
curr
);
if
(
rv
)
break
;
s
=
strchr
(
curr
,
','
);
if
(
s
)
{
*
s
=
'\0'
;
s
++
;
}
addr
=
simple_strtoul
(
curr
,
&
n
,
0
);
if
((
*
n
!=
'\0'
)
||
(
*
curr
==
'\0'
))
{
pr_warn
(
PFX
"Invalid hotmod address '%s'
\n
"
,
curr
);
break
;
}
while
(
s
)
{
curr
=
s
;
s
=
strchr
(
curr
,
','
);
if
(
s
)
{
*
s
=
'\0'
;
s
++
;
}
o
=
strchr
(
curr
,
'='
);
if
(
o
)
{
*
o
=
'\0'
;
o
++
;
}
rv
=
check_hotmod_int_op
(
curr
,
o
,
"rsp"
,
&
regspacing
);
if
(
rv
<
0
)
goto
out
;
else
if
(
rv
)
continue
;
rv
=
check_hotmod_int_op
(
curr
,
o
,
"rsi"
,
&
regsize
);
if
(
rv
<
0
)
goto
out
;
else
if
(
rv
)
continue
;
rv
=
check_hotmod_int_op
(
curr
,
o
,
"rsh"
,
&
regshift
);
if
(
rv
<
0
)
goto
out
;
else
if
(
rv
)
continue
;
rv
=
check_hotmod_int_op
(
curr
,
o
,
"irq"
,
&
irq
);
if
(
rv
<
0
)
goto
out
;
else
if
(
rv
)
continue
;
rv
=
check_hotmod_int_op
(
curr
,
o
,
"ipmb"
,
&
ipmb
);
if
(
rv
<
0
)
goto
out
;
else
if
(
rv
)
continue
;
rv
=
-
EINVAL
;
pr_warn
(
PFX
"Invalid hotmod option '%s'
\n
"
,
curr
);
goto
out
;
}
if
(
op
==
HM_ADD
)
{
struct
si_sm_io
io
;
memset
(
&
io
,
0
,
sizeof
(
io
));
io
.
addr_source
=
SI_HOTMOD
;
io
.
si_type
=
si_type
;
io
.
addr_data
=
addr
;
io
.
addr_type
=
addr_space
;
io
.
addr
=
NULL
;
io
.
regspacing
=
regspacing
;
if
(
!
io
.
regspacing
)
io
.
regspacing
=
DEFAULT_REGSPACING
;
io
.
regsize
=
regsize
;
if
(
!
io
.
regsize
)
io
.
regsize
=
DEFAULT_REGSIZE
;
io
.
regshift
=
regshift
;
io
.
irq
=
irq
;
if
(
io
.
irq
)
io
.
irq_setup
=
ipmi_std_irq_setup
;
io
.
slave_addr
=
ipmb
;
rv
=
ipmi_si_add_smi
(
&
io
);
if
(
rv
)
goto
out
;
}
else
{
/* remove */
struct
smi_info
*
e
,
*
tmp_e
;
mutex_lock
(
&
smi_infos_lock
);
list_for_each_entry_safe
(
e
,
tmp_e
,
&
smi_infos
,
link
)
{
if
(
e
->
io
.
addr_type
!=
addr_space
)
continue
;
if
(
e
->
io
.
si_type
!=
si_type
)
continue
;
if
(
e
->
io
.
addr_data
==
addr
)
cleanup_one_si
(
e
);
}
mutex_unlock
(
&
smi_infos_lock
);
}
}
rv
=
len
;
out:
kfree
(
str
);
return
rv
;
}
static
int
hardcode_find_bmc
(
void
)
{
int
ret
=
-
ENODEV
;
...
...
@@ -3779,6 +3536,24 @@ int ipmi_si_remove_by_dev(struct device *dev)
return
rv
;
}
void
ipmi_si_remove_by_data
(
int
addr_space
,
enum
si_type
si_type
,
unsigned
long
addr
)
{
/* remove */
struct
smi_info
*
e
,
*
tmp_e
;
mutex_lock
(
&
smi_infos_lock
);
list_for_each_entry_safe
(
e
,
tmp_e
,
&
smi_infos
,
link
)
{
if
(
e
->
io
.
addr_type
!=
addr_space
)
continue
;
if
(
e
->
io
.
si_type
!=
si_type
)
continue
;
if
(
e
->
io
.
addr_data
==
addr
)
cleanup_one_si
(
e
);
}
mutex_unlock
(
&
smi_infos_lock
);
}
static
void
cleanup_ipmi_si
(
void
)
{
struct
smi_info
*
e
,
*
tmp_e
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录