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
nexedi
linux
Commits
58e27635
Commit
58e27635
authored
Sep 12, 2017
by
Corey Minyard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ipmi_si: Move port and mem I/O handling to their own files
Signed-off-by:
Corey Minyard
<
cminyard@mvista.com
>
parent
d1a67913
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
263 additions
and
255 deletions
+263
-255
drivers/char/ipmi/Makefile
drivers/char/ipmi/Makefile
+2
-1
drivers/char/ipmi/ipmi_si.h
drivers/char/ipmi/ipmi_si.h
+3
-0
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/ipmi/ipmi_si_intf.c
+2
-254
drivers/char/ipmi/ipmi_si_mem_io.c
drivers/char/ipmi/ipmi_si_mem_io.c
+144
-0
drivers/char/ipmi/ipmi_si_port_io.c
drivers/char/ipmi/ipmi_si_port_io.c
+112
-0
No files found.
drivers/char/ipmi/Makefile
View file @
58e27635
...
...
@@ -3,7 +3,8 @@
#
ipmi_si-y
:=
ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o
\
ipmi_si_hotmod.o ipmi_si_hardcode.o ipmi_si_platform.o
ipmi_si_hotmod.o ipmi_si_hardcode.o ipmi_si_platform.o
\
ipmi_si_port_io.o ipmi_si_mem_io.o
ifdef
CONFIG_PCI
ipmi_si-y
+=
ipmi_si_pci.o
endif
...
...
drivers/char/ipmi/ipmi_si.h
View file @
58e27635
...
...
@@ -44,3 +44,6 @@ void ipmi_si_parisc_shutdown(void);
static
inline
void
ipmi_si_parisc_init
(
void
)
{
}
static
inline
void
ipmi_si_parisc_shutdown
(
void
)
{
}
#endif
int
ipmi_si_port_setup
(
struct
si_sm_io
*
io
);
int
ipmi_si_mem_setup
(
struct
si_sm_io
*
io
);
drivers/char/ipmi/ipmi_si_intf.c
View file @
58e27635
...
...
@@ -49,7 +49,6 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/ioport.h>
#include <linux/notifier.h>
#include <linux/mutex.h>
#include <linux/kthread.h>
...
...
@@ -58,7 +57,6 @@
#include <linux/rcupdate.h>
#include <linux/ipmi.h>
#include <linux/ipmi_smi.h>
#include <asm/io.h>
#include "ipmi_si.h"
#include <linux/string.h>
#include <linux/ctype.h>
...
...
@@ -1304,256 +1302,6 @@ int ipmi_std_irq_setup(struct si_sm_io *io)
return
rv
;
}
static
unsigned
char
port_inb
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
unsigned
int
addr
=
io
->
addr_data
;
return
inb
(
addr
+
(
offset
*
io
->
regspacing
));
}
static
void
port_outb
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
unsigned
int
addr
=
io
->
addr_data
;
outb
(
b
,
addr
+
(
offset
*
io
->
regspacing
));
}
static
unsigned
char
port_inw
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
unsigned
int
addr
=
io
->
addr_data
;
return
(
inw
(
addr
+
(
offset
*
io
->
regspacing
))
>>
io
->
regshift
)
&
0xff
;
}
static
void
port_outw
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
unsigned
int
addr
=
io
->
addr_data
;
outw
(
b
<<
io
->
regshift
,
addr
+
(
offset
*
io
->
regspacing
));
}
static
unsigned
char
port_inl
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
unsigned
int
addr
=
io
->
addr_data
;
return
(
inl
(
addr
+
(
offset
*
io
->
regspacing
))
>>
io
->
regshift
)
&
0xff
;
}
static
void
port_outl
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
unsigned
int
addr
=
io
->
addr_data
;
outl
(
b
<<
io
->
regshift
,
addr
+
(
offset
*
io
->
regspacing
));
}
static
void
port_cleanup
(
struct
si_sm_io
*
io
)
{
unsigned
int
addr
=
io
->
addr_data
;
int
idx
;
if
(
addr
)
{
for
(
idx
=
0
;
idx
<
io
->
io_size
;
idx
++
)
release_region
(
addr
+
idx
*
io
->
regspacing
,
io
->
regsize
);
}
}
static
int
port_setup
(
struct
si_sm_io
*
io
)
{
unsigned
int
addr
=
io
->
addr_data
;
int
idx
;
if
(
!
addr
)
return
-
ENODEV
;
io
->
io_cleanup
=
port_cleanup
;
/*
* Figure out the actual inb/inw/inl/etc routine to use based
* upon the register size.
*/
switch
(
io
->
regsize
)
{
case
1
:
io
->
inputb
=
port_inb
;
io
->
outputb
=
port_outb
;
break
;
case
2
:
io
->
inputb
=
port_inw
;
io
->
outputb
=
port_outw
;
break
;
case
4
:
io
->
inputb
=
port_inl
;
io
->
outputb
=
port_outl
;
break
;
default:
dev_warn
(
io
->
dev
,
"Invalid register size: %d
\n
"
,
io
->
regsize
);
return
-
EINVAL
;
}
/*
* Some BIOSes reserve disjoint I/O regions in their ACPI
* tables. This causes problems when trying to register the
* entire I/O region. Therefore we must register each I/O
* port separately.
*/
for
(
idx
=
0
;
idx
<
io
->
io_size
;
idx
++
)
{
if
(
request_region
(
addr
+
idx
*
io
->
regspacing
,
io
->
regsize
,
DEVICE_NAME
)
==
NULL
)
{
/* Undo allocations */
while
(
idx
--
)
release_region
(
addr
+
idx
*
io
->
regspacing
,
io
->
regsize
);
return
-
EIO
;
}
}
return
0
;
}
static
unsigned
char
intf_mem_inb
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
return
readb
((
io
->
addr
)
+
(
offset
*
io
->
regspacing
));
}
static
void
intf_mem_outb
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
writeb
(
b
,
(
io
->
addr
)
+
(
offset
*
io
->
regspacing
));
}
static
unsigned
char
intf_mem_inw
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
return
(
readw
((
io
->
addr
)
+
(
offset
*
io
->
regspacing
))
>>
io
->
regshift
)
&
0xff
;
}
static
void
intf_mem_outw
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
writeb
(
b
<<
io
->
regshift
,
(
io
->
addr
)
+
(
offset
*
io
->
regspacing
));
}
static
unsigned
char
intf_mem_inl
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
return
(
readl
((
io
->
addr
)
+
(
offset
*
io
->
regspacing
))
>>
io
->
regshift
)
&
0xff
;
}
static
void
intf_mem_outl
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
writel
(
b
<<
io
->
regshift
,
(
io
->
addr
)
+
(
offset
*
io
->
regspacing
));
}
#ifdef readq
static
unsigned
char
mem_inq
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
return
(
readq
((
io
->
addr
)
+
(
offset
*
io
->
regspacing
))
>>
io
->
regshift
)
&
0xff
;
}
static
void
mem_outq
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
writeq
(
b
<<
io
->
regshift
,
(
io
->
addr
)
+
(
offset
*
io
->
regspacing
));
}
#endif
static
void
mem_region_cleanup
(
struct
si_sm_io
*
io
,
int
num
)
{
unsigned
long
addr
=
io
->
addr_data
;
int
idx
;
for
(
idx
=
0
;
idx
<
num
;
idx
++
)
release_mem_region
(
addr
+
idx
*
io
->
regspacing
,
io
->
regsize
);
}
static
void
mem_cleanup
(
struct
si_sm_io
*
io
)
{
if
(
io
->
addr
)
{
iounmap
(
io
->
addr
);
mem_region_cleanup
(
io
,
io
->
io_size
);
}
}
static
int
mem_setup
(
struct
si_sm_io
*
io
)
{
unsigned
long
addr
=
io
->
addr_data
;
int
mapsize
,
idx
;
if
(
!
addr
)
return
-
ENODEV
;
io
->
io_cleanup
=
mem_cleanup
;
/*
* Figure out the actual readb/readw/readl/etc routine to use based
* upon the register size.
*/
switch
(
io
->
regsize
)
{
case
1
:
io
->
inputb
=
intf_mem_inb
;
io
->
outputb
=
intf_mem_outb
;
break
;
case
2
:
io
->
inputb
=
intf_mem_inw
;
io
->
outputb
=
intf_mem_outw
;
break
;
case
4
:
io
->
inputb
=
intf_mem_inl
;
io
->
outputb
=
intf_mem_outl
;
break
;
#ifdef readq
case
8
:
io
->
inputb
=
mem_inq
;
io
->
outputb
=
mem_outq
;
break
;
#endif
default:
dev_warn
(
io
->
dev
,
"Invalid register size: %d
\n
"
,
io
->
regsize
);
return
-
EINVAL
;
}
/*
* Some BIOSes reserve disjoint memory regions in their ACPI
* tables. This causes problems when trying to request the
* entire region. Therefore we must request each register
* separately.
*/
for
(
idx
=
0
;
idx
<
io
->
io_size
;
idx
++
)
{
if
(
request_mem_region
(
addr
+
idx
*
io
->
regspacing
,
io
->
regsize
,
DEVICE_NAME
)
==
NULL
)
{
/* Undo allocations */
mem_region_cleanup
(
io
,
idx
);
return
-
EIO
;
}
}
/*
* Calculate the total amount of memory to claim. This is an
* unusual looking calculation, but it avoids claiming any
* more memory than it has to. It will claim everything
* between the first address to the end of the last full
* register.
*/
mapsize
=
((
io
->
io_size
*
io
->
regspacing
)
-
(
io
->
regspacing
-
io
->
regsize
));
io
->
addr
=
ioremap
(
addr
,
mapsize
);
if
(
io
->
addr
==
NULL
)
{
mem_region_cleanup
(
io
,
io
->
io_size
);
return
-
EIO
;
}
return
0
;
}
static
struct
smi_info
*
smi_info_alloc
(
void
)
{
struct
smi_info
*
info
=
kzalloc
(
sizeof
(
*
info
),
GFP_KERNEL
);
...
...
@@ -2146,9 +1894,9 @@ int ipmi_si_add_smi(struct si_sm_io *io)
if
(
!
io
->
io_setup
)
{
if
(
io
->
addr_type
==
IPMI_IO_ADDR_SPACE
)
{
io
->
io_setup
=
port_setup
;
io
->
io_setup
=
ipmi_si_
port_setup
;
}
else
if
(
io
->
addr_type
==
IPMI_MEM_ADDR_SPACE
)
{
io
->
io_setup
=
mem_setup
;
io
->
io_setup
=
ipmi_si_
mem_setup
;
}
else
{
return
-
EINVAL
;
}
...
...
drivers/char/ipmi/ipmi_si_mem_io.c
0 → 100644
View file @
58e27635
#include <linux/io.h>
#include "ipmi_si.h"
static
unsigned
char
intf_mem_inb
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
return
readb
((
io
->
addr
)
+
(
offset
*
io
->
regspacing
));
}
static
void
intf_mem_outb
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
writeb
(
b
,
(
io
->
addr
)
+
(
offset
*
io
->
regspacing
));
}
static
unsigned
char
intf_mem_inw
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
return
(
readw
((
io
->
addr
)
+
(
offset
*
io
->
regspacing
))
>>
io
->
regshift
)
&
0xff
;
}
static
void
intf_mem_outw
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
writeb
(
b
<<
io
->
regshift
,
(
io
->
addr
)
+
(
offset
*
io
->
regspacing
));
}
static
unsigned
char
intf_mem_inl
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
return
(
readl
((
io
->
addr
)
+
(
offset
*
io
->
regspacing
))
>>
io
->
regshift
)
&
0xff
;
}
static
void
intf_mem_outl
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
writel
(
b
<<
io
->
regshift
,
(
io
->
addr
)
+
(
offset
*
io
->
regspacing
));
}
#ifdef readq
static
unsigned
char
mem_inq
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
return
(
readq
((
io
->
addr
)
+
(
offset
*
io
->
regspacing
))
>>
io
->
regshift
)
&
0xff
;
}
static
void
mem_outq
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
writeq
(
b
<<
io
->
regshift
,
(
io
->
addr
)
+
(
offset
*
io
->
regspacing
));
}
#endif
static
void
mem_region_cleanup
(
struct
si_sm_io
*
io
,
int
num
)
{
unsigned
long
addr
=
io
->
addr_data
;
int
idx
;
for
(
idx
=
0
;
idx
<
num
;
idx
++
)
release_mem_region
(
addr
+
idx
*
io
->
regspacing
,
io
->
regsize
);
}
static
void
mem_cleanup
(
struct
si_sm_io
*
io
)
{
if
(
io
->
addr
)
{
iounmap
(
io
->
addr
);
mem_region_cleanup
(
io
,
io
->
io_size
);
}
}
int
ipmi_si_mem_setup
(
struct
si_sm_io
*
io
)
{
unsigned
long
addr
=
io
->
addr_data
;
int
mapsize
,
idx
;
if
(
!
addr
)
return
-
ENODEV
;
io
->
io_cleanup
=
mem_cleanup
;
/*
* Figure out the actual readb/readw/readl/etc routine to use based
* upon the register size.
*/
switch
(
io
->
regsize
)
{
case
1
:
io
->
inputb
=
intf_mem_inb
;
io
->
outputb
=
intf_mem_outb
;
break
;
case
2
:
io
->
inputb
=
intf_mem_inw
;
io
->
outputb
=
intf_mem_outw
;
break
;
case
4
:
io
->
inputb
=
intf_mem_inl
;
io
->
outputb
=
intf_mem_outl
;
break
;
#ifdef readq
case
8
:
io
->
inputb
=
mem_inq
;
io
->
outputb
=
mem_outq
;
break
;
#endif
default:
dev_warn
(
io
->
dev
,
"Invalid register size: %d
\n
"
,
io
->
regsize
);
return
-
EINVAL
;
}
/*
* Some BIOSes reserve disjoint memory regions in their ACPI
* tables. This causes problems when trying to request the
* entire region. Therefore we must request each register
* separately.
*/
for
(
idx
=
0
;
idx
<
io
->
io_size
;
idx
++
)
{
if
(
request_mem_region
(
addr
+
idx
*
io
->
regspacing
,
io
->
regsize
,
DEVICE_NAME
)
==
NULL
)
{
/* Undo allocations */
mem_region_cleanup
(
io
,
idx
);
return
-
EIO
;
}
}
/*
* Calculate the total amount of memory to claim. This is an
* unusual looking calculation, but it avoids claiming any
* more memory than it has to. It will claim everything
* between the first address to the end of the last full
* register.
*/
mapsize
=
((
io
->
io_size
*
io
->
regspacing
)
-
(
io
->
regspacing
-
io
->
regsize
));
io
->
addr
=
ioremap
(
addr
,
mapsize
);
if
(
io
->
addr
==
NULL
)
{
mem_region_cleanup
(
io
,
io
->
io_size
);
return
-
EIO
;
}
return
0
;
}
drivers/char/ipmi/ipmi_si_port_io.c
0 → 100644
View file @
58e27635
#include <linux/io.h>
#include "ipmi_si.h"
static
unsigned
char
port_inb
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
unsigned
int
addr
=
io
->
addr_data
;
return
inb
(
addr
+
(
offset
*
io
->
regspacing
));
}
static
void
port_outb
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
unsigned
int
addr
=
io
->
addr_data
;
outb
(
b
,
addr
+
(
offset
*
io
->
regspacing
));
}
static
unsigned
char
port_inw
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
unsigned
int
addr
=
io
->
addr_data
;
return
(
inw
(
addr
+
(
offset
*
io
->
regspacing
))
>>
io
->
regshift
)
&
0xff
;
}
static
void
port_outw
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
unsigned
int
addr
=
io
->
addr_data
;
outw
(
b
<<
io
->
regshift
,
addr
+
(
offset
*
io
->
regspacing
));
}
static
unsigned
char
port_inl
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
)
{
unsigned
int
addr
=
io
->
addr_data
;
return
(
inl
(
addr
+
(
offset
*
io
->
regspacing
))
>>
io
->
regshift
)
&
0xff
;
}
static
void
port_outl
(
const
struct
si_sm_io
*
io
,
unsigned
int
offset
,
unsigned
char
b
)
{
unsigned
int
addr
=
io
->
addr_data
;
outl
(
b
<<
io
->
regshift
,
addr
+
(
offset
*
io
->
regspacing
));
}
static
void
port_cleanup
(
struct
si_sm_io
*
io
)
{
unsigned
int
addr
=
io
->
addr_data
;
int
idx
;
if
(
addr
)
{
for
(
idx
=
0
;
idx
<
io
->
io_size
;
idx
++
)
release_region
(
addr
+
idx
*
io
->
regspacing
,
io
->
regsize
);
}
}
int
ipmi_si_port_setup
(
struct
si_sm_io
*
io
)
{
unsigned
int
addr
=
io
->
addr_data
;
int
idx
;
if
(
!
addr
)
return
-
ENODEV
;
io
->
io_cleanup
=
port_cleanup
;
/*
* Figure out the actual inb/inw/inl/etc routine to use based
* upon the register size.
*/
switch
(
io
->
regsize
)
{
case
1
:
io
->
inputb
=
port_inb
;
io
->
outputb
=
port_outb
;
break
;
case
2
:
io
->
inputb
=
port_inw
;
io
->
outputb
=
port_outw
;
break
;
case
4
:
io
->
inputb
=
port_inl
;
io
->
outputb
=
port_outl
;
break
;
default:
dev_warn
(
io
->
dev
,
"Invalid register size: %d
\n
"
,
io
->
regsize
);
return
-
EINVAL
;
}
/*
* Some BIOSes reserve disjoint I/O regions in their ACPI
* tables. This causes problems when trying to register the
* entire I/O region. Therefore we must register each I/O
* port separately.
*/
for
(
idx
=
0
;
idx
<
io
->
io_size
;
idx
++
)
{
if
(
request_region
(
addr
+
idx
*
io
->
regspacing
,
io
->
regsize
,
DEVICE_NAME
)
==
NULL
)
{
/* Undo allocations */
while
(
idx
--
)
release_region
(
addr
+
idx
*
io
->
regspacing
,
io
->
regsize
);
return
-
EIO
;
}
}
return
0
;
}
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