Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
44814ec9
Commit
44814ec9
authored
Sep 12, 2017
by
Corey Minyard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ipmi_si: Move the hotmod handling to another file.
Signed-off-by:
Corey Minyard
<
cminyard@mvista.com
>
parent
bb398a4c
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
264 additions
and
244 deletions
+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
No files found.
drivers/char/ipmi/Makefile
View file @
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
View file @
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
View file @
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
View file @
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
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment