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
86a7dc29
Commit
86a7dc29
authored
Dec 14, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Fix Rules.make removal merge
parents
59db688e
34725cc4
Changes
54
Show whitespace changes
Inline
Side-by-side
Showing
54 changed files
with
516 additions
and
2332 deletions
+516
-2332
arch/s390/Makefile
arch/s390/Makefile
+16
-15
arch/s390/boot/Makefile
arch/s390/boot/Makefile
+10
-15
arch/s390/defconfig
arch/s390/defconfig
+2
-0
arch/s390/kernel/entry.S
arch/s390/kernel/entry.S
+24
-8
arch/s390/kernel/s390_ksyms.c
arch/s390/kernel/s390_ksyms.c
+1
-0
arch/s390/kernel/signal.c
arch/s390/kernel/signal.c
+9
-0
arch/s390/math-emu/Makefile
arch/s390/math-emu/Makefile
+2
-2
arch/s390x/Makefile
arch/s390x/Makefile
+14
-13
arch/s390x/boot/Makefile
arch/s390x/boot/Makefile
+10
-14
arch/s390x/defconfig
arch/s390x/defconfig
+2
-0
arch/s390x/kernel/entry.S
arch/s390x/kernel/entry.S
+21
-6
arch/s390x/kernel/s390_ksyms.c
arch/s390x/kernel/s390_ksyms.c
+1
-0
arch/s390x/kernel/signal.c
arch/s390x/kernel/signal.c
+9
-0
arch/s390x/mm/Makefile
arch/s390x/mm/Makefile
+1
-1
arch/s390x/mm/extable.c
arch/s390x/mm/extable.c
+0
-1
drivers/s390/Makefile
drivers/s390/Makefile
+1
-1
drivers/s390/char/sclp.c
drivers/s390/char/sclp.c
+3
-3
drivers/s390/char/sclp_con.c
drivers/s390/char/sclp_con.c
+4
-4
drivers/s390/char/sclp_rw.c
drivers/s390/char/sclp_rw.c
+1
-1
drivers/s390/char/sclp_tty.c
drivers/s390/char/sclp_tty.c
+2
-2
drivers/s390/char/tape.c
drivers/s390/char/tape.c
+0
-1907
drivers/s390/cio/Makefile
drivers/s390/cio/Makefile
+1
-1
drivers/s390/cio/blacklist.c
drivers/s390/cio/blacklist.c
+5
-5
drivers/s390/cio/chsc.c
drivers/s390/cio/chsc.c
+80
-165
drivers/s390/cio/chsc.h
drivers/s390/cio/chsc.h
+80
-0
drivers/s390/cio/cio.c
drivers/s390/cio/cio.c
+16
-19
drivers/s390/cio/cio.h
drivers/s390/cio/cio.h
+0
-2
drivers/s390/cio/css.c
drivers/s390/cio/css.c
+8
-2
drivers/s390/cio/device.c
drivers/s390/cio/device.c
+19
-4
drivers/s390/cio/device_fsm.c
drivers/s390/cio/device_fsm.c
+13
-7
drivers/s390/cio/ioasm.h
drivers/s390/cio/ioasm.h
+1
-1
drivers/s390/cio/qdio.c
drivers/s390/cio/qdio.c
+18
-16
drivers/s390/misc/Makefile
drivers/s390/misc/Makefile
+0
-5
drivers/s390/net/ctcmain.c
drivers/s390/net/ctcmain.c
+8
-8
drivers/s390/net/cu3088.c
drivers/s390/net/cu3088.c
+3
-3
drivers/s390/net/lcs.c
drivers/s390/net/lcs.c
+10
-10
include/asm-s390/bitops.h
include/asm-s390/bitops.h
+43
-27
include/asm-s390/cio.h
include/asm-s390/cio.h
+0
-2
include/asm-s390/current.h
include/asm-s390/current.h
+1
-1
include/asm-s390/page.h
include/asm-s390/page.h
+1
-1
include/asm-s390/posix_types.h
include/asm-s390/posix_types.h
+3
-3
include/asm-s390/rwsem.h
include/asm-s390/rwsem.h
+1
-1
include/asm-s390/setup.h
include/asm-s390/setup.h
+6
-6
include/asm-s390/thread_info.h
include/asm-s390/thread_info.h
+10
-4
include/asm-s390/uaccess.h
include/asm-s390/uaccess.h
+1
-1
include/asm-s390/unistd.h
include/asm-s390/unistd.h
+1
-0
include/asm-s390x/bitops.h
include/asm-s390x/bitops.h
+34
-30
include/asm-s390x/ccwgroup.h
include/asm-s390x/ccwgroup.h
+4
-4
include/asm-s390x/cio.h
include/asm-s390x/cio.h
+0
-2
include/asm-s390x/current.h
include/asm-s390x/current.h
+1
-1
include/asm-s390x/posix_types.h
include/asm-s390x/posix_types.h
+3
-3
include/asm-s390x/rwsem.h
include/asm-s390x/rwsem.h
+1
-1
include/asm-s390x/thread_info.h
include/asm-s390x/thread_info.h
+10
-4
include/asm-s390x/unistd.h
include/asm-s390x/unistd.h
+1
-0
No files found.
arch/s390/Makefile
View file @
86a7dc29
...
...
@@ -20,36 +20,37 @@ LDFLAGS_BLOB := --format binary --oformat elf32-s390
CFLAGS
+=
-pipe
-fno-strength-reduce
HEAD
:=
arch
/
s390/kernel/head.o
arch
/s390
/kernel/init_task.o
HEAD
:=
arch
/
$(ARCH)
/kernel/head.o
arch
/
$(ARCH)
/kernel/init_task.o
core-y
+=
arch
/s390/mm/
arch
/s390/kernel/
core-y
+=
arch
/
$(ARCH)
/mm/
arch
/
$(ARCH)
/kernel/
libs-y
+=
arch
/
$(ARCH)
/lib/
drivers-y
+=
drivers/s390/
drivers-$(CONFIG_MATHEMU)
+=
arch
/s390/math-emu/
libs-y
+=
arch
/s390/lib/
drivers-$(CONFIG_MATHEMU)
+=
arch
/
$(ARCH)
/math-emu/
makeboot
=
$(Q)$(MAKE)
-f
scripts/Makefile.build
obj
=
arch
/
$(ARCH)
/boot
$(1)
all
:
image listing
makeboot
=
$(
call
descend,arch/
$(ARCH)
/boot,
$(1)
)
BOOTIMAGE
=
arch
/
$(ARCH)
/boot/image
listing image
:
vmlinux
$(
call
makeboot,arch/
$(ARCH)
/boot/
$@
)
listing install image
:
vmlinux
+@
$(
call
makeboot,BOOTIMAGE
=
$(BOOTIMAGE)
$@
)
install
:
vmlinux
$(
call
makeboot,
$@
)
archmrproper
:
archclean
:
+@
$(
call
makeboot,clean
)
$(Q)$(MAKE)
-f
scripts/Makefile.clean
obj
=
arch
/
$(ARCH)
/boot
archmrproper
:
prepare
:
include/asm-$(ARCH)/offsets.h
arch/$(ARCH)/kernel/asm-offsets.s
:
include/asm include/linux/version.h
\
include/config/MARKER
include/asm-$(ARCH)/offsets.h.tmp
:
arch/$(ARCH)/kernel/asm-offsets.s
@
$
(
generate-asm-offsets.h
)
<
$<
>
$@
include/asm-$(ARCH)/offsets.h
:
include/asm-$(ARCH)/offsets.h.tmp
include/asm-$(ARCH)/offsets.h
:
arch/$(ARCH)/kernel/asm-offsets.s
@
echo
-n
' Generating $@'
@
$
(
generate-asm-offsets.h
)
<
$<
>
$@
.tmp
@
$
(
update-if-changed
)
CLEAN_FILES
+=
include/asm-
$(ARCH)
/offsets.h.tmp
\
...
...
arch/s390/boot/Makefile
View file @
86a7dc29
...
...
@@ -2,24 +2,19 @@
# Makefile for the linux s390-specific parts of the memory manager.
#
EXTRA_TARGETS
:=
image listing
EXTRA_AFLAGS
:=
-traditional
quiet_cmd_listing
=
OBJDUMP
$(echo_target)
cmd_listing
=
$(OBJDUMP)
--disassemble
--disassemble-all
\
quiet_cmd_listing
=
OBJDUMP
$@
cmd_listing
=
$(OBJDUMP)
--disassemble
--disassemble-all
\
--disassemble-zeroes
--reloc
vmlinux
>
$@
$(obj)/image
:
vmlinux
$(obj)/image
:
vmlinux
FORCE
$(
call
if_changed,objcopy
)
$(obj)/listing
:
vmlinux
$(obj)/listing
:
vmlinux
FORCE
$(
call
if_changed,listing
)
image
:
$(obj)/image
listing
:
$(obj)/listing
clean
:
rm
-f
$(obj)
/image
$(obj)
/listing
install
:
$(CONFIGURE) $(BOOTIMAGE)
sh
-x
$(obj)
/install.sh
$(KERNELRELEASE)
$(BOOTIMAGE)
System.map Kerntypes
"
$(INSTALL_PATH)
"
install
:
$(CONFIGURE) $(obj)/image
sh
-x
$(obj)
/install.sh
$(KERNELRELEASE)
$(obj)
/image
\
System.map Kerntypes
"
$(INSTALL_PATH)
"
arch/s390/defconfig
View file @
86a7dc29
...
...
@@ -321,6 +321,8 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_TEST is not set
#
...
...
arch/s390/kernel/entry.S
View file @
86a7dc29
...
...
@@ -47,7 +47,8 @@ SP_ORIG_R2 = STACK_FRAME_OVERHEAD + PT_ORIGGPR2
SP_TRAP
=
(
SP_ORIG_R2
+
GPR_SIZE
)
SP_SIZE
=
(
SP_TRAP
+
4
)
_TIF_WORK_MASK
=
(
_TIF_SIGPENDING
|
_TIF_NEED_RESCHED
)
_TIF_WORK_SVC
=
(
_TIF_SIGPENDING
| _TIF_NEED_RESCHED |
_TIF_RESTART_SVC
)
_TIF_WORK_INT
=
(
_TIF_SIGPENDING
|
_TIF_NEED_RESCHED
)
/*
*
Base
Address
of
this
Module
---
saved
in
__LC_ENTRY_BASE
...
...
@@ -181,6 +182,7 @@ system_call:
GET_THREAD_INFO
#
load
pointer
to
task_struct
to
R9
sll
%
r7
,
2
stosm
24
(%
r15
),
0x03
#
reenable
interrupts
sysc_do_restart
:
l
%
r8
,
sys_call_table
-
entry_base
(%
r7
,%
r13
)
#
get
system
call
addr
.
tm
__TI_flags
+
3
(%
r9
),
_TIF_SYSCALL_TRACE
bo
BASED
(
sysc_tracesys
)
...
...
@@ -191,7 +193,7 @@ system_call:
sysc_return
:
stnsm
24
(%
r15
),
0xfc
#
disable
I
/
O
and
ext
.
interrupts
tm
__TI_flags
+
3
(%
r9
),
_TIF_WORK_
MASK
tm
__TI_flags
+
3
(%
r9
),
_TIF_WORK_
SVC
bnz
BASED
(
sysc_work
)
#
there
is
work
to
do
(
signals
etc
.
)
sysc_leave
:
RESTORE_ALL
1
...
...
@@ -202,7 +204,7 @@ sysc_leave:
sysc_work_loop
:
stnsm
24
(%
r15
),
0xfc
#
disable
I
/
O
and
ext
.
interrupts
GET_THREAD_INFO
#
load
pointer
to
task_struct
to
R9
tm
__TI_flags
+
3
(%
r9
),
_TIF_WORK_
MASK
tm
__TI_flags
+
3
(%
r9
),
_TIF_WORK_
SVC
bz
BASED
(
sysc_leave
)
#
there
is
no
work
to
do
#
#
One
of
the
work
bits
is
on
.
Find
out
which
one
.
...
...
@@ -213,6 +215,8 @@ sysc_work:
bo
BASED
(
sysc_reschedule
)
tm
__TI_flags
+
3
(%
r9
),
_TIF_SIGPENDING
bo
BASED
(
sysc_sigpending
)
tm
__TI_flags
+
3
(%
r9
),
_TIF_RESTART_SVC
bo
BASED
(
sysc_restart
)
b
BASED
(
sysc_leave
)
#
...
...
@@ -236,15 +240,27 @@ sysc_sigpending:
stnsm
24
(%
r15
),
0xfc
#
disable
I
/
O
and
ext
.
interrupts
b
BASED
(
sysc_leave
)
#
out
of
here
,
do
NOT
recheck
#
#
_TIF_RESTART_SVC
is
set
,
set
up
registers
and
restart
svc
#
sysc_restart
:
ni
__TI_flags
+
3
(%
r9
),
255
-
_TIF_RESTART_SVC
#
clear
TIF_RESTART_SVC
stosm
24
(%
r15
),
0x03
#
reenable
interrupts
l
%
r7
,
SP_R2
(%
r15
)
#
load
new
svc
number
sll
%
r7
,
2
mvc
SP_R2
(
4
,%
r15
),
SP_ORIG_R2
(%
r15
)
#
restore
first
argument
lm
%
r2
,%
r6
,
SP_R2
(%
r15
)
#
load
svc
arguments
b
BASED
(
sysc_do_restart
)
#
restart
svc
#
#
call
trace
before
and
after
sys_call
#
sysc_tracesys
:
l
%
r1
,
BASED
(
.
Ltrace
)
srl
%
r7
,
2
st
%
r7
,
SP_R2
(
4
,
%
r15
)
st
%
r7
,
SP_R2
(%
r15
)
basr
%
r14
,%
r1
l
%
r7
,
SP_R2
(
4
,%
r15
)
#
strace
might
have
changed
the
l
%
r7
,
SP_R2
(
%
r15
)
#
strace
might
have
changed
the
n
%
r7
,
BASED
(
.
Lc256
)
#
system
call
sll
%
r7
,
2
l
%
r8
,
sys_call_table
-
entry_base
(%
r7
,%
r13
)
...
...
@@ -354,7 +370,7 @@ sys_call_table:
.
long
sys_write
.
long
sys_open
/*
5
*/
.
long
sys_close
.
long
sys_
ni_syscall
/*
old
waitpid
syscall
holder
*/
.
long
sys_
restart_syscall
.
long
sys_creat
.
long
sys_link
.
long
sys_unlink
/*
10
*/
...
...
@@ -752,7 +768,7 @@ io_return:
#else
bno
BASED
(
io_leave
)
#
no
->
skip
resched
&
signal
#endif
tm
__TI_flags
+
3
(%
r9
),
_TIF_WORK_
MASK
tm
__TI_flags
+
3
(%
r9
),
_TIF_WORK_
INT
bnz
BASED
(
io_work
)
#
there
is
work
to
do
(
signals
etc
.
)
io_leave
:
RESTORE_ALL
0
...
...
@@ -788,7 +804,7 @@ io_resume_loop:
io_work_loop
:
stnsm
24
(%
r15
),
0xfc
#
disable
I
/
O
and
ext
.
interrupts
GET_THREAD_INFO
#
load
pointer
to
task_struct
to
R9
tm
__TI_flags
+
3
(%
r9
),
_TIF_WORK_
MASK
tm
__TI_flags
+
3
(%
r9
),
_TIF_WORK_
INT
bz
BASED
(
io_leave
)
#
there
is
no
work
to
do
#
#
One
of
the
work
bits
is
on
.
Find
out
which
one
.
...
...
arch/s390/kernel/s390_ksyms.c
View file @
86a7dc29
...
...
@@ -59,3 +59,4 @@ EXPORT_SYMBOL(csum_fold);
EXPORT_SYMBOL
(
console_mode
);
EXPORT_SYMBOL
(
console_device
);
EXPORT_SYMBOL_NOVERS
(
do_call_softirq
);
EXPORT_SYMBOL
(
sys_wait4
);
arch/s390/kernel/signal.c
View file @
86a7dc29
...
...
@@ -397,6 +397,10 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
if
(
regs
->
trap
==
__LC_SVC_OLD_PSW
)
{
/* If so, check system call restarting.. */
switch
(
regs
->
gprs
[
2
])
{
case
-
ERESTART_RESTARTBLOCK
:
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
clear_thread_flag
(
TIF_RESTART_SVC
);
case
-
ERESTARTNOHAND
:
regs
->
gprs
[
2
]
=
-
EINTR
;
break
;
...
...
@@ -473,6 +477,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
regs
->
gprs
[
2
]
=
regs
->
orig_gpr2
;
regs
->
psw
.
addr
-=
2
;
}
/* Restart the system call with a new system call number */
if
(
regs
->
gprs
[
2
]
==
-
ERESTART_RESTARTBLOCK
)
{
regs
->
gprs
[
2
]
=
__NR_restart_syscall
;
set_thread_flag
(
TIF_RESTART_SVC
);
}
}
return
0
;
}
arch/s390/math-emu/Makefile
View file @
86a7dc29
...
...
@@ -4,5 +4,5 @@
obj-$(CONFIG_MATHEMU)
:=
math.o qrnnd.o
EXTRA_CFLAGS
=
-I
.
-I
$(TOPDIR)
/
include/math-emu
-w
EXTRA_CFLAGS
:=
-I
$(src)
-I
include
/math-emu
-w
EXTRA_AFLAGS
:=
-traditional
arch/s390x/Makefile
View file @
86a7dc29
...
...
@@ -21,35 +21,36 @@ LDFLAGS_BLOB := --format binary --oformat elf64-s390
CFLAGS
+=
-pipe
-fno-strength-reduce
HEAD
:=
arch
/
s390x/kernel/head.o
arch
/s390x
/kernel/init_task.o
HEAD
:=
arch
/
$(ARCH)
/kernel/head.o
arch
/
$(ARCH)
/kernel/init_task.o
core-y
+=
arch
/s390x/mm/
arch
/s390x/kernel/
core-y
+=
arch
/
$(ARCH)
/mm/
arch
/
$(ARCH)
/kernel/
libs-y
+=
arch
/
$(ARCH)
/lib/
drivers-y
+=
drivers/s390/
libs-y
+=
arch
/s390x/lib/
makeboot
=
$(Q)$(MAKE)
-f
scripts/Makefile.build
obj
=
arch
/
$(ARCH)
/boot
$(1)
all
:
image listing
makeboot
=
$(
call
descend,arch/
$(ARCH)
/boot,
$(1)
)
BOOTIMAGE
=
arch
/
$(ARCH)
/boot/image
listing image
:
vmlinux
$(
call
makeboot,arch/
$(ARCH)
/boot/
$@
)
listing install image
:
vmlinux
+@
$(
call
makeboot,BOOTIMAGE
=
$(BOOTIMAGE)
$@
)
install
:
vmlinux
$(
call
makeboot,
$@
)
archmrproper
:
archclean
:
+@
$(
call
makeboot,clean
)
$(Q)$(MAKE)
-f
scripts/Makefile.clean
obj
=
arch
/
$(ARCH)
/boot
archmrproper
:
prepare
:
include/asm-$(ARCH)/offsets.h
arch/$(ARCH)/kernel/asm-offsets.s
:
include/asm include/linux/version.h
\
include/config/MARKER
include/asm-$(ARCH)/offsets.h.tmp
:
arch/$(ARCH)/kernel/asm-offsets.s
@
$
(
generate-asm-offsets.h
)
<
$<
>
$@
include/asm-$(ARCH)/offsets.h
:
include/asm-$(ARCH)/offsets.h.tmp
include/asm-$(ARCH)/offsets.h
:
arch/$(ARCH)/kernel/asm-offsets.s
@
echo
-n
' Generating $@'
@
$
(
generate-asm-offsets.h
)
<
$<
>
$@
.tmp
@
$
(
update-if-changed
)
CLEAN_FILES
+=
include/asm-
$(ARCH)
/offsets.h.tmp
\
...
...
arch/s390x/boot/Makefile
View file @
86a7dc29
...
...
@@ -2,24 +2,20 @@
# Makefile for the linux s390-specific parts of the memory manager.
#
EXTRA_TARGETS
:=
image listing
EXTRA_AFLAGS
:=
-traditional
quiet_cmd_listing
=
OBJDUMP
$
(echo_target)
cmd_listing
=
$(OBJDUMP)
--disassemble
--disassemble-all
\
quiet_cmd_listing
=
OBJDUMP
$
@
cmd_listing
=
$(OBJDUMP)
--disassemble
--disassemble-all
\
--disassemble-zeroes
--reloc
vmlinux
>
$@
$(obj)/image
:
vmlinux
$(obj)/image
:
vmlinux
FORCE
$(
call
if_changed,objcopy
)
$(obj)/listing
:
vmlinux
$(obj)/listing
:
vmlinux
FORCE
$(
call
if_changed,listing
)
image
:
$(obj)/image
listing
:
$(obj)/listing
clean
:
rm
-f
$(obj)
/image
$(obj)
/listing
install
:
$(CONFIGURE) $(BOOTIMAGE)
sh
-x
$(obj)
/install.sh
$(KERNELRELEASE)
$(BOOTIMAGE)
System.map Kerntypes
"
$(INSTALL_PATH)
"
install
:
$(CONFIGURE) $(obj)/image
sh
-x
$(obj)
/install.sh
$(KERNELRELEASE)
$(obj)
/image
\
System.map Kerntypes
"
$(INSTALL_PATH)
"
arch/s390x/defconfig
View file @
86a7dc29
...
...
@@ -382,6 +382,8 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_TEST is not set
#
...
...
arch/s390x/kernel/entry.S
View file @
86a7dc29
...
...
@@ -47,7 +47,8 @@ SP_ORIG_R2 = STACK_FRAME_OVERHEAD + PT_ORIGGPR2
SP_TRAP
=
(
SP_ORIG_R2
+
GPR_SIZE
)
SP_SIZE
=
(
SP_TRAP
+
4
)
_TIF_WORK_MASK
=
(
_TIF_SIGPENDING
|
_TIF_NEED_RESCHED
)
_TIF_WORK_SVC
=
(
_TIF_SIGPENDING
| _TIF_NEED_RESCHED |
_TIF_RESTART_SVC
)
_TIF_WORK_INT
=
(
_TIF_SIGPENDING
|
_TIF_NEED_RESCHED
)
/*
*
Register
usage
in
interrupt
handlers
:
...
...
@@ -161,6 +162,7 @@ system_call:
llgh
%
r7
,
__LC_SVC_INT_CODE
#
get
svc
number
from
lowcore
GET_THREAD_INFO
#
load
pointer
to
task_struct
to
R9
stosm
48
(%
r15
),
0x03
#
reenable
interrupts
sysc_do_restart
:
larl
%
r10
,
sys_call_table
sll
%
r7
,
3
tm
SP_PSW
+
3
(%
r15
),
0x01
#
are
we
running
in
31
bit
mode
?
...
...
@@ -177,7 +179,7 @@ sysc_noemu:
sysc_return
:
stnsm
48
(%
r15
),
0xfc
#
disable
I
/
O
and
ext
.
interrupts
tm
__TI_flags
+
7
(%
r9
),
_TIF_WORK_
MASK
tm
__TI_flags
+
7
(%
r9
),
_TIF_WORK_
SVC
jnz
sysc_work
#
there
is
work
to
do
(
signals
etc
.
)
sysc_leave
:
RESTORE_ALL
1
...
...
@@ -188,7 +190,7 @@ sysc_leave:
sysc_work_loop
:
stnsm
48
(%
r15
),
0xfc
#
disable
I
/
O
and
ext
.
interrupts
GET_THREAD_INFO
#
load
pointer
to
task_struct
to
R9
tm
__TI_flags
+
7
(%
r9
),
_TIF_WORK_
MASK
tm
__TI_flags
+
7
(%
r9
),
_TIF_WORK_
SVC
jz
sysc_leave
#
there
is
no
work
to
do
#
#
One
of
the
work
bits
is
on
.
Find
out
which
one
.
...
...
@@ -199,6 +201,8 @@ sysc_work:
jo
sysc_reschedule
tm
__TI_flags
+
7
(%
r9
),
_TIF_SIGPENDING
jo
sysc_sigpending
tm
__TI_flags
+
7
(%
r9
),
_TIF_RESTART_SVC
jo
sysc_restart
j
sysc_leave
#
...
...
@@ -220,6 +224,17 @@ sysc_sigpending:
stnsm
48
(%
r15
),
0xfc
#
disable
I
/
O
and
ext
.
interrupts
j
sysc_leave
#
out
of
here
,
do
NOT
recheck
#
#
_TIF_RESTART_SVC
is
set
,
set
up
registers
and
restart
svc
#
sysc_restart
:
ni
__TI_flags
+
3
(%
r9
),
255
-
_TIF_RESTART_SVC
#
clear
TIF_RESTART_SVC
stosm
48
(%
r15
),
0x03
#
reenable
interrupts
lg
%
r7
,
SP_R2
(%
r15
)
#
load
new
svc
number
mvc
SP_R2
(
8
,%
r15
),
SP_ORIG_R2
(%
r15
)
#
restore
first
argument
lmg
%
r2
,%
r6
,
SP_R2
(%
r15
)
#
load
svc
arguments
j
sysc_do_restart
#
restart
svc
#
#
call
syscall_trace
before
and
after
system
call
#
special
linkage
:
%
r12
contains
the
return
address
for
trace_svc
...
...
@@ -383,7 +398,7 @@ sys_call_table:
.
long
SYSCALL
(
sys_write
,
sys32_write_wrapper
)
.
long
SYSCALL
(
sys_open
,
sys32_open_wrapper
)
/*
5
*/
.
long
SYSCALL
(
sys_close
,
sys32_close_wrapper
)
.
long
SYSCALL
(
sys_
ni_syscall
,
sys_ni_syscall
)
/*
old
waitpid
syscall
*/
.
long
SYSCALL
(
sys_
restart_syscall
,
sys_ni_syscall
)
.
long
SYSCALL
(
sys_creat
,
sys32_creat_wrapper
)
.
long
SYSCALL
(
sys_link
,
sys32_link_wrapper
)
.
long
SYSCALL
(
sys_unlink
,
sys32_unlink_wrapper
)
/*
10
*/
...
...
@@ -777,7 +792,7 @@ io_return:
#else
jno
io_leave
#
no
->
skip
resched
&
signal
#endif
tm
__TI_flags
+
7
(%
r9
),
_TIF_WORK_
MASK
tm
__TI_flags
+
7
(%
r9
),
_TIF_WORK_
INT
jnz
io_work
#
there
is
work
to
do
(
signals
etc
.
)
io_leave
:
RESTORE_ALL
0
...
...
@@ -813,7 +828,7 @@ io_resume_loop:
io_work_loop
:
stnsm
48
(%
r15
),
0xfc
#
disable
I
/
O
and
ext
.
interrupts
GET_THREAD_INFO
#
load
pointer
to
task_struct
to
R9
tm
__TI_flags
+
7
(%
r9
),
_TIF_WORK_
MASK
tm
__TI_flags
+
7
(%
r9
),
_TIF_WORK_
INT
jz
io_leave
#
there
is
no
work
to
do
#
#
One
of
the
work
bits
is
on
.
Find
out
which
one
.
...
...
arch/s390x/kernel/s390_ksyms.c
View file @
86a7dc29
...
...
@@ -83,3 +83,4 @@ EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL
(
console_mode
);
EXPORT_SYMBOL
(
console_device
);
EXPORT_SYMBOL_NOVERS
(
do_call_softirq
);
EXPORT_SYMBOL
(
sys_wait4
);
arch/s390x/kernel/signal.c
View file @
86a7dc29
...
...
@@ -391,6 +391,10 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
if
(
regs
->
trap
==
__LC_SVC_OLD_PSW
)
{
/* If so, check system call restarting.. */
switch
(
regs
->
gprs
[
2
])
{
case
-
ERESTART_RESTARTBLOCK
:
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
clear_thread_flag
(
TIF_RESTART_SVC
);
case
-
ERESTARTNOHAND
:
regs
->
gprs
[
2
]
=
-
EINTR
;
break
;
...
...
@@ -473,6 +477,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
regs
->
gprs
[
2
]
=
regs
->
orig_gpr2
;
regs
->
psw
.
addr
-=
2
;
}
/* Restart the system call with a new system call number */
if
(
regs
->
gprs
[
2
]
==
-
ERESTART_RESTARTBLOCK
)
{
regs
->
gprs
[
2
]
=
__NR_restart_syscall
;
set_thread_flag
(
TIF_RESTART_SVC
);
}
}
return
0
;
}
arch/s390x/mm/Makefile
View file @
86a7dc29
#
# Makefile for the linux
i386
-specific parts of the memory manager.
# Makefile for the linux
s390
-specific parts of the memory manager.
#
obj-y
:=
init.o fault.o ioremap.o extable.o
arch/s390x/mm/extable.c
View file @
86a7dc29
...
...
@@ -40,7 +40,6 @@ extern spinlock_t modlist_lock;
unsigned
long
search_exception_table
(
unsigned
long
addr
)
{
struct
list_head
*
i
;
unsigned
long
ret
=
0
;
#ifndef CONFIG_MODULES
...
...
drivers/s390/Makefile
View file @
86a7dc29
...
...
@@ -3,6 +3,6 @@
#
obj-y
+=
s390mach.o sysinfo.o
obj-y
+=
cio/ block/ char/
misc/
net/
obj-y
+=
cio/ block/ char/ net/
drivers-y
+=
drivers/s390/built-in.o
drivers/s390/char/sclp.c
View file @
86a7dc29
...
...
@@ -47,7 +47,7 @@ static sccb_mask_t sclp_send_mask;
static
struct
list_head
sclp_reg_list
;
/* sccb queue */
struct
list_head
sclp_req_queue
;
st
atic
st
ruct
list_head
sclp_req_queue
;
/* sccb for unconditional read */
static
struct
sclp_req
sclp_read_req
;
...
...
@@ -448,7 +448,7 @@ sclp_state_change(struct evbuf_header *evbuf)
spin_unlock_irqrestore
(
&
sclp_lock
,
flags
);
}
struct
sclp_register
sclp_state_change_event
=
{
st
atic
st
ruct
sclp_register
sclp_state_change_event
=
{
.
receive_mask
=
EvTyp_StateChange_Mask
,
.
receiver_fn
=
sclp_state_change
};
...
...
@@ -514,7 +514,7 @@ sclp_quiesce(struct evbuf_header *evbuf)
ctrl_alt_del
();
}
struct
sclp_register
sclp_quiesce_event
=
{
st
atic
st
ruct
sclp_register
sclp_quiesce_event
=
{
.
receive_mask
=
EvTyp_SigQuiesce_Mask
,
.
receiver_fn
=
sclp_quiesce
};
...
...
drivers/s390/char/sclp_con.c
View file @
86a7dc29
...
...
@@ -97,7 +97,7 @@ sclp_console_timeout(unsigned long data)
/*
* Writes the given message to S390 system console
*/
void
static
void
sclp_console_write
(
struct
console
*
console
,
const
char
*
message
,
unsigned
int
count
)
{
...
...
@@ -152,7 +152,7 @@ sclp_console_write(struct console *console, const char *message,
}
/* returns the device number of the SCLP console */
kdev_t
static
kdev_t
sclp_console_device
(
struct
console
*
c
)
{
return
mk_kdev
(
sclp_console_major
,
sclp_console_minor
);
...
...
@@ -163,7 +163,7 @@ sclp_console_device(struct console *c)
* is going to give up. We have to make sure that all buffers
* will be flushed to the SCLP.
*/
void
static
void
sclp_console_unblank
(
void
)
{
unsigned
long
flags
;
...
...
@@ -187,7 +187,7 @@ sclp_console_unblank(void)
* used to register the SCLP console to the kernel and to
* give printk necessary information
*/
struct
console
sclp_console
=
st
atic
st
ruct
console
sclp_console
=
{
.
name
=
sclp_console_name
,
.
write
=
sclp_console_write
,
...
...
drivers/s390/char/sclp_rw.c
View file @
86a7dc29
...
...
@@ -31,7 +31,7 @@
#define MAX_SCCB_ROOM (PAGE_SIZE - sizeof(struct sclp_buffer))
/* Event type structure for write message and write priority message */
struct
sclp_register
sclp_rw_event
=
{
st
atic
st
ruct
sclp_register
sclp_rw_event
=
{
.
send_mask
=
EvTyp_Msg_Mask
|
EvTyp_PMsgCmd_Mask
};
...
...
drivers/s390/char/sclp_tty.c
View file @
86a7dc29
...
...
@@ -466,7 +466,7 @@ sclp_tty_flush_buffer(struct tty_struct *tty)
/*
* push input to tty
*/
void
sclp_tty_input
(
unsigned
char
*
buf
,
unsigned
int
count
)
static
void
sclp_tty_input
(
unsigned
char
*
buf
,
unsigned
int
count
)
{
unsigned
int
cchar
;
...
...
@@ -694,7 +694,7 @@ sclp_tty_state_change(struct sclp_register *reg)
{
}
struct
sclp_register
sclp_input_event
=
st
atic
st
ruct
sclp_register
sclp_input_event
=
{
.
receive_mask
=
EvTyp_OpCmd_Mask
|
EvTyp_PMsgCmd_Mask
,
.
state_change_fn
=
sclp_tty_state_change
,
...
...
drivers/s390/char/tape.c
deleted
100644 → 0
View file @
59db688e
/***********************************************************************
* drivers/s390/char/tape.c
* tape device driver for S/390 and zSeries tapes.
*
* S390 and zSeries version
* Copyright (C) 2001 IBM Corporation
* Author(s): Carsten Otte <cotte@de.ibm.com>
* Michael Holzheu <holzheu@de.ibm.com>
* Tuan Ngo-Anh <ngoanh@de.ibm.com>
*
***********************************************************************
*/
#include "tapedefs.h" // kernel 2.2 compatibility defines
#include <linux/stddef.h> // defines NULL
#include <linux/proc_fs.h> // for /proc/tapedevices
#include <linux/init.h> // for kernel parameters
#include <linux/kmod.h> // for requesting modules
#include <linux/spinlock.h> // for locks
#include <asm/types.h> // for variable types
#ifdef CONFIG_S390_TAPE_DYNAMIC
#include <asm/s390dyn.h>
#endif
#include "tape.h"
#ifdef CONFIG_S390_TAPE_3590
#include "tape3590.h"
#endif
#ifdef CONFIG_S390_TAPE_3490
#include "tape3490.h"
#endif
#ifdef CONFIG_S390_TAPE_3480
#include "tape3480.h"
#endif
#ifdef CONFIG_S390_TAPE_BLOCK
#include "tapeblock.h"
#endif
#ifdef CONFIG_S390_TAPE_CHAR
#include "tapechar.h"
#endif
#ifdef CONFIG_PROC_FS
#include <linux/vmalloc.h>
#endif
#define PRINTK_HEADER "T390:"
#define TAPE_MAX_DEVREGS (256 / TAPE_MINORS_PER_DEV)
#define TAPE_NO_IO 0
#define TAPE_DO_IO 1
#define TAPE_CIO_PRIVATE_DATA
#ifdef CONFIG_KMOD
#define tape_request_module(a) request_module(a)
#else
#define tape_request_module(a)
#endif
/*******************************************************************
* Internal Prototypes
*******************************************************************/
static
void
tape_do_irq
(
int
irq
,
void
*
int_parm
,
struct
pt_regs
*
regs
);
static
inline
int
tape_halt_io
(
tape_dev_t
*
td
);
static
void
tape_wait
(
tape_ccw_req_t
*
treq
);
#ifdef CONFIG_S390_TAPE_DYNAMIC
/* functions for dyn. dev. attach/detach */
static
int
tape_oper_handler
(
int
irq
,
struct
_devreg
*
dreg
);
static
void
tape_noper_handler
(
int
irq
,
int
status
);
#endif
static
inline
void
tape_disable_device
(
tape_dev_t
*
td
);
static
inline
int
tape_enable_device
(
tape_dev_t
*
td
);
/*******************************************************************
* GLOBALS
*******************************************************************/
static
devreg_t
*
tape_devreg
[
TAPE_MAX_DEVREGS
];
static
int
tape_devregct
=
0
;
static
int
tape_autoprobe
=
1
;
static
tape_discipline_t
*
tape_first_disc
=
NULL
;
tape_dev_t
*
tape_first_dev
=
NULL
;
tape_frontend_t
*
tape_first_front
=
NULL
;
char
*
tape
[
256
]
=
{
NULL
,
};
/*
* Lock hirarchy:
* tape_discipline_lock > tape_dev_lock > td->lock
*/
rwlock_t
tape_dev_lock
=
RW_LOCK_UNLOCKED
;
static
rwlock_t
tape_discipline_lock
=
RW_LOCK_UNLOCKED
;
#ifdef TAPE_DEBUG
debug_info_t
*
tape_dbf_area
=
NULL
;
#endif
const
char
*
tape_med_st_verbose
[
MS_SIZE
]
=
{
"UNKNOWN "
,
"LOADED "
,
"UNLOADED"
};
const
char
*
tape_state_verbose
[
TS_SIZE
]
=
{
"UNUSED"
,
"IN_USE"
,
"INIT "
,
"NOT_OP"
};
const
char
*
tape_op_verbose
[
TO_SIZE
]
=
{
"BLK"
,
"BSB"
,
"BSF"
,
"DSE"
,
"EGA"
,
"FSB"
,
"FSF"
,
"LDI"
,
"LBL"
,
"MSE"
,
"NOP"
,
"RBA"
,
"RBI"
,
"RBU"
,
"RBL"
,
"RDC"
,
"RFO"
,
"RSD"
,
"REW"
,
"RUN"
,
"SEN"
,
"SID"
,
"SNP"
,
"SPG"
,
"SWI"
,
"SMR"
,
"SYN"
,
"TIO"
,
"UNA"
,
"WRI"
,
"WTM"
,
"MSN"
,
"LOA"
,
"RCF"
,
/* 3590 */
"RAT"
,
/* 3590 */
"NOT"
};
/*******************************************************************
* DEVFS Functions
*******************************************************************/
#ifdef CONFIG_DEVFS_FS
/*
* Create devfs root entry (devno in hex) for device td
*/
static
inline
devfs_handle_t
tape_mkdevfsroot
(
tape_dev_t
*
td
)
{
char
devno
[
10
];
sprintf
(
devno
,
"tape/%04x"
,
td
->
devinfo
.
devno
);
return
devfs_mk_dir
(
NULL
,
devno
,
NULL
);
}
/*
* Remove devfs root entry for device td
*/
static
inline
void
tape_rmdevfsroot
(
tape_dev_t
*
td
)
{
devfs_remove
(
"tape/%04x"
,
td
->
devinfo
.
devno
);
}
#endif
/*******************************************************************
* PROCFS Functions
*******************************************************************/
#ifdef CONFIG_PROC_FS
/* functions used in tape_proc_file_ops */
static
ssize_t
tape_proc_devices_read
(
struct
file
*
file
,
char
*
user_buf
,
size_t
user_len
,
loff_t
*
offset
);
static
int
tape_proc_devices_open
(
struct
inode
*
inode
,
struct
file
*
file
);
static
int
tape_proc_devices_release
(
struct
inode
*
inode
,
struct
file
*
file
);
/* our proc tapedevices entry */
static
struct
proc_dir_entry
*
tape_proc_devices
;
typedef
struct
{
char
*
data
;
int
len
;
}
tape_procinfo_t
;
static
struct
file_operations
tape_proc_devices_file_ops
=
{
.
owner
=
THIS_MODULE
,
.
read
=
tape_proc_devices_read
,
/* read */
.
open
=
tape_proc_devices_open
,
/* open */
.
release
=
tape_proc_devices_release
,
/* close */
};
/*
* Initialize procfs stuff on startup
*/
static
inline
void
tape_proc_init
(
void
)
{
tape_proc_devices
=
create_proc_entry
(
"tapedevices"
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
&
proc_root
);
if
(
tape_proc_devices
==
NULL
)
goto
error
;
tape_proc_devices
->
proc_fops
=
&
tape_proc_devices_file_ops
;
tape_proc_devices
->
proc_iops
=
&
tape_proc_devices_inode_ops
;
return
;
error:
PRINT_WARN
(
"tape: Cannot register procfs entry tapedevices
\n
"
);
return
;
}
/*
* Open function for /proc/tapedevices
*/
static
int
tape_proc_devices_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
tape_dev_t
*
td
;
tape_procinfo_t
*
procinfo
;
char
*
data
=
NULL
;
int
size
=
0
,
check_size
=
-
1
;
int
pos
=
0
;
int
rc
=
0
;
long
lockflags
,
lockflags2
;
tape_ccw_req_t
*
treq
;
procinfo
=
kmalloc
(
sizeof
(
tape_procinfo_t
),
GFP_KERNEL
);
if
(
!
procinfo
){
rc
=
-
ENOMEM
;
goto
out_no_lock
;
}
/* Find out mem size for output, ensure that after releasing lock */
/* (vmalloc must not be called with interrupts disabled) no devices */
/* have been added/removed */
do
{
size
=
100
;
// Headline
read_lock_irqsave
(
&
tape_dev_lock
,
lockflags
);
for
(
td
=
tape_first_dev
;
td
!=
NULL
;
td
=
td
->
next
)
size
+=
100
;
// FIXME: Guess better!
if
(
size
==
check_size
)
break
;
read_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
if
(
data
)
vfree
(
data
);
data
=
vmalloc
(
size
);
if
(
!
data
)
{
kfree
(
procinfo
);
rc
=
-
ENOMEM
;
goto
out_no_lock
;
}
check_size
=
size
;
}
while
(
1
);
// We have the tape_dev lock now
#ifdef CONFIG_S390_TAPE_CHAR
pos
+=
sprintf
(
data
+
pos
,
"TapeNo
\t
DevNo
\t
CuType
\t
CuModel
\t
DevType
\t
DevMod
\t
BlkSize
\t
State
\t
Op
\t
MedState
\n
"
);
#else
pos
+=
sprintf
(
data
+
pos
,
"TapeNo
\t
DevNo
\t
CuType
\t
CuModel
\t
DevType
\t
DevMod
\t
State
\t
Op
\t
MedState
\n
"
);
#endif
for
(
td
=
tape_first_dev
;
td
!=
NULL
;
td
=
td
->
next
)
{
s390irq_spin_lock_irqsave
(
td
->
devinfo
.
irq
,
lockflags2
);
treq
=
tape_get_active_ccw_req
(
td
);
pos
+=
sprintf
(
data
+
pos
,
"%d
\t
"
,
td
->
first_minor
/
TAPE_MINORS_PER_DEV
);
pos
+=
sprintf
(
data
+
pos
,
"%04X
\t
"
,
td
->
devinfo
.
devno
);
pos
+=
sprintf
(
data
+
pos
,
"%04X
\t
"
,
td
->
devinfo
.
sid_data
.
cu_type
);
pos
+=
sprintf
(
data
+
pos
,
"%02X
\t
"
,
td
->
devinfo
.
sid_data
.
cu_model
);
pos
+=
sprintf
(
data
+
pos
,
"%04X
\t
"
,
td
->
devinfo
.
sid_data
.
dev_type
);
pos
+=
sprintf
(
data
+
pos
,
"%02X
\t
"
,
td
->
devinfo
.
sid_data
.
dev_model
);
#ifdef CONFIG_S390_TAPE_CHAR
if
(
td
->
char_data
.
block_size
==
0
)
pos
+=
sprintf
(
data
+
pos
,
"auto
\t
"
);
else
pos
+=
sprintf
(
data
+
pos
,
"%i
\t
"
,
td
->
char_data
.
block_size
);
#endif
pos
+=
sprintf
(
data
+
pos
,
"%s
\t
"
,((
tape_state_get
(
td
)
>=
0
)
&&
(
tape_state_get
(
td
)
<
TS_SIZE
))
?
tape_state_verbose
[
tape_state_get
(
td
)]
:
"UNKNOWN"
);
pos
+=
sprintf
(
data
+
pos
,
"%s
\t
"
,(
treq
!=
NULL
)
?
tape_op_verbose
[
treq
->
op
]
:
"---"
);
pos
+=
sprintf
(
data
+
pos
,
"%s
\n
"
,
tape_med_st_verbose
[
td
->
medium_state
]);
s390irq_spin_unlock_irqrestore
(
td
->
devinfo
.
irq
,
lockflags2
);
}
procinfo
->
data
=
data
;
procinfo
->
len
=
pos
;
if
(
pos
>
size
)
BUG
();
// we've overwritten some memory
file
->
private_data
=
(
void
*
)
procinfo
;
read_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
out_no_lock:
return
rc
;
}
/*
* Read function for /proc/tapedevices
*/
static
ssize_t
tape_proc_devices_read
(
struct
file
*
file
,
char
*
user_buf
,
size_t
user_len
,
loff_t
*
offset
)
{
loff_t
len
=
0
;
tape_procinfo_t
*
p_info
=
(
tape_procinfo_t
*
)
file
->
private_data
;
if
(
*
offset
>=
p_info
->
len
)
{
goto
out
;
/* EOF */
}
else
{
len
=
user_len
<
(
p_info
->
len
-
*
offset
)
?
user_len
:
(
p_info
->
len
-
*
offset
);
if
(
copy_to_user
(
user_buf
,
&
(
p_info
->
data
[
*
offset
]),
len
))
return
-
EFAULT
;
(
*
offset
)
+=
len
;
}
out:
return
len
;
}
/*
* Close function for /proc/tapedevices
*/
static
int
tape_proc_devices_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
int
rc
=
0
;
tape_procinfo_t
*
p_info
=
(
tape_procinfo_t
*
)
file
->
private_data
;
vfree
(
p_info
->
data
);
kfree
(
p_info
);
return
rc
;
}
/*
* Cleanup all stuff registered to the procfs
*/
static
inline
void
tape_proc_cleanup
(
void
)
{
if
(
tape_proc_devices
!=
NULL
)
remove_proc_entry
(
"tapedevices"
,
&
proc_root
);
}
#endif
/* CONFIG_PROC_FS */
/*******************************************************************
* Wait/Wakeup Functions
*******************************************************************/
static
void
tape_wake_up_remove
(
tape_ccw_req_t
*
treq
){
tape_remove_ccw_req
(
treq
->
tape_dev
,
treq
);
tape_free_ccw_req
(
treq
);
}
static
void
tape_wake_up
(
tape_ccw_req_t
*
treq
){
treq
->
wakeup
=
NULL
;
wake_up
(
&
treq
->
wq
);
}
static
void
tape_wake_up_interruptible
(
tape_ccw_req_t
*
treq
){
treq
->
wakeup
=
NULL
;
wake_up_interruptible
(
&
treq
->
wq
);
}
#ifdef CONFIG_S390_TAPE_BLOCK
static
void
tape_schedule_tapeblock
(
tape_ccw_req_t
*
treq
){
treq
->
wakeup
=
NULL
;
tapeblock_schedule_exec_io
((
tape_dev_t
*
)(
treq
->
tape_dev
));;
}
#endif
static
void
tape_wait_event
(
tape_ccw_req_t
*
treq
){
wait_event
(
treq
->
wq
,(
treq
->
wakeup
==
NULL
));
}
static
void
tape_wait_event_interruptible
(
tape_ccw_req_t
*
treq
){
wait_event_interruptible
(
treq
->
wq
,(
treq
->
wakeup
==
NULL
));
if
(
signal_pending
(
current
))
{
treq
->
rc
=
tape_halt_io
(
treq
->
tape_dev
);
if
(
treq
->
rc
==
-
ERESTARTSYS
)
PRINT_INFO
(
"IO stopped on irq %d
\n
"
,
treq
->
tape_dev
->
devinfo
.
irq
);
/* FIXME: only put into dbf */
else
if
(
treq
->
rc
==
0
)
PRINT_INFO
(
"could not stop IO,irq was faster on irq %d
\n
"
,
treq
->
tape_dev
->
devinfo
.
irq
);
/* FIXME: only put into dbf */
else
PRINT_WARN
(
"IO error while stopping IO on irq %d
\n
"
,
treq
->
tape_dev
->
devinfo
.
irq
);
}
}
static
void
tape_wait_event_interruptible_nohaltio
(
tape_ccw_req_t
*
treq
){
wait_event_interruptible
(
treq
->
wq
,(
treq
->
wakeup
==
NULL
));
}
/*******************************************************************
* DYNAMIC ATTACH/DETACH Functions
*******************************************************************/
static
inline
void
tape_init_devregs
(
void
)
{
long
lockflags
;
write_lock_irqsave
(
&
tape_dev_lock
,
lockflags
);
memset
(
tape_devreg
,
0
,
sizeof
(
devreg_t
*
)
*
TAPE_MAX_DEVREGS
);
write_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
}
/*
* Alloc a devreg for a devno
*/
static
inline
devreg_t
*
tape_create_devno_devreg
(
int
devno
)
{
devreg_t
*
devreg
=
kmalloc
(
sizeof
(
devreg_t
),
GFP_KERNEL
);
if
(
devreg
!=
NULL
)
{
memset
(
devreg
,
0
,
sizeof
(
devreg_t
));
devreg
->
ci
.
devno
=
devno
;
devreg
->
flag
=
DEVREG_TYPE_DEVNO
;
devreg
->
oper_func
=
tape_oper_handler
;
}
return
devreg
;
}
/*
* Alloc a devreg for a cu-type
*/
static
inline
devreg_t
*
tape_create_cu_devreg
(
int
cu_type
)
{
devreg_t
*
devreg
=
kmalloc
(
sizeof
(
devreg_t
),
GFP_KERNEL
);
if
(
devreg
!=
NULL
)
{
memset
(
devreg
,
0
,
sizeof
(
devreg_t
));
devreg
->
ci
.
hc
.
ctype
=
cu_type
;
devreg
->
flag
=
DEVREG_MATCH_CU_TYPE
|
DEVREG_TYPE_DEVCHARS
;
devreg
->
oper_func
=
tape_oper_handler
;
}
return
devreg
;
}
/*
* Create devregs for device numbers from "from" to "to"
*/
static
inline
void
tape_create_devregs_range
(
int
from
,
int
to
)
{
int
i
;
long
lockflags
;
write_lock_irqsave
(
&
tape_dev_lock
,
lockflags
);
for
(
i
=
from
;
i
<=
to
;
i
++
)
{
// register for attch/detach of a devno
if
(
tape_devregct
>=
TAPE_MAX_DEVREGS
){
PRINT_WARN
(
"Could not create devregs for devno range %04x - %04x.
\n
"
,
i
,
to
);
PRINT_WARN
(
"These devices cannot be used. Use autoprobe
\n
"
);
PRINT_WARN
(
"or specify device ranges more precisely!
\n
"
);
break
;
}
tape_devreg
[
tape_devregct
]
=
tape_create_devno_devreg
(
i
);
if
(
tape_devreg
[
tape_devregct
]
!=
NULL
)
{
s390_device_register
(
tape_devreg
[
tape_devregct
++
]);
}
else
{
PRINT_WARN
(
"Could not create devreg for devno %04x, dyn. attach for this devno deactivated.
\n
"
,
i
);
}
}
write_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
return
;
}
/*
* Create a devreg for a discipline
*/
static
inline
void
tape_create_devreg_for_disc
(
tape_discipline_t
*
disc
)
{
int
devreg_nr
;
long
lockflags
;
write_lock_irqsave
(
&
tape_dev_lock
,
lockflags
);
for
(
devreg_nr
=
0
;
devreg_nr
<
TAPE_MAX_DEVREGS
;
devreg_nr
++
){
if
(
tape_devreg
[
devreg_nr
]
==
NULL
)
break
;
}
if
(
devreg_nr
==
TAPE_MAX_DEVREGS
){
PRINT_WARN
(
"Could not create devreg for discipline (%x), dyn. attach for this discipline deactivated.
\n
"
,
disc
->
cu_type
);
goto
out_unlock
;
}
tape_devreg
[
devreg_nr
]
=
tape_create_cu_devreg
(
disc
->
cu_type
);
if
(
tape_devreg
[
devreg_nr
]
!=
NULL
)
{
s390_device_register
(
tape_devreg
[
devreg_nr
]);
}
else
{
PRINT_WARN
(
"Could not alloc devreg: Out of memory
\n
"
);
PRINT_WARN
(
"Dynamic attach/detach will not work!
\n
"
);
}
out_unlock:
write_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
return
;
}
/*
* Free all devregs
*/
static
inline
void
tape_delete_all_devregs
(
void
)
{
int
i
;
long
lockflags
;
write_lock_irqsave
(
&
tape_dev_lock
,
lockflags
);
for
(
i
=
0
;
i
<
TAPE_MAX_DEVREGS
;
i
++
){
if
(
tape_devreg
[
i
]){
s390_device_unregister
(
tape_devreg
[
i
]);
kfree
(
tape_devreg
[
i
]);
}
}
memset
(
tape_devreg
,
0
,
sizeof
(
devreg_t
*
)
*
TAPE_MAX_DEVREGS
);
write_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
}
/*
* Free Devregs for a discipline
*/
static
inline
void
tape_delete_devreg_for_disc
(
tape_discipline_t
*
disc
)
{
int
i
;
long
lockflags
;
write_lock_irqsave
(
&
tape_dev_lock
,
lockflags
);
for
(
i
=
0
;
i
<
TAPE_MAX_DEVREGS
;
i
++
){
if
(
tape_devreg
[
i
]){
if
(
tape_devreg
[
i
]
->
ci
.
hc
.
ctype
==
disc
->
cu_type
){
s390_device_unregister
(
tape_devreg
[
i
]);
kfree
(
tape_devreg
[
i
]);
tape_devreg
[
i
]
=
NULL
;
}
}
}
write_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
}
/*******************************************************************
* Module/Kernel Parameter Handling
*******************************************************************/
#ifndef MODULE
static
char
tape_parm_string
[
1024
]
__initdata
=
{
0
,
};
/*
* Get Kernel parameters (str) seperated by ","
* and store them into the tape[] array
*/
static
void
tape_split_parm_string
(
char
*
str
)
{
char
*
tmp
=
str
;
int
count
=
0
;
while
(
tmp
!=
NULL
&&
*
tmp
!=
'\0'
)
{
char
*
end
;
int
len
;
end
=
strchr
(
tmp
,
','
);
if
(
end
==
NULL
)
{
len
=
strlen
(
tmp
)
+
1
;
}
else
{
len
=
(
long
)
end
-
(
long
)
tmp
+
1
;
*
end
=
'\0'
;
end
++
;
}
tape
[
count
]
=
kmalloc
(
len
*
sizeof
(
char
),
GFP_ATOMIC
);
if
(
tape
[
count
]
==
NULL
)
{
printk
(
KERN_WARNING
PRINTK_HEADER
"can't store tape= parameter no %d
\n
"
,
count
+
1
);
break
;
}
memcpy
(
tape
[
count
],
tmp
,
len
*
sizeof
(
char
));
count
++
;
tmp
=
end
;
};
}
/*
* This function is called for each "tape=" Kernel parameter
* at Kernel initialization. We need tape_parm_setup because of
* 2.2 compatibility (At least I assume this :-))
*/
void
__init
tape_parm_setup
(
char
*
str
,
int
*
ints
)
{
int
len
=
strlen
(
tape_parm_string
);
if
(
len
!=
0
)
{
strcat
(
tape_parm_string
,
","
);
}
strcat
(
tape_parm_string
,
str
);
}
int
__init
tape_parm_call_setup
(
char
*
str
)
{
int
dummy
;
tape_parm_setup
(
str
,
&
dummy
);
return
1
;
}
__setup
(
"tape="
,
tape_parm_call_setup
);
#endif
/* not defined MODULE */
/*
* Convert string to int
*/
static
inline
int
tape_parm_strtoul
(
char
*
str
,
char
**
stra
)
{
char
*
temp
=
str
;
int
val
;
if
(
*
temp
==
'0'
)
{
temp
++
;
/* strip leading zero */
if
(
*
temp
==
'x'
)
temp
++
;
/* strip leading x */
}
val
=
simple_strtoul
(
temp
,
&
temp
,
16
);
/* interpret anything as hex */
*
stra
=
temp
;
return
val
;
}
/*
* Parse Kernel/Module Parameters and create devregs for dynamic attach/detach
*/
static
inline
void
tape_parm_parse
(
char
**
str
)
{
char
*
temp
;
int
from
,
to
;
if
(
*
str
==
NULL
)
{
/* no params present -> leave */
return
;
}
while
(
*
str
)
{
temp
=
*
str
;
from
=
0
;
to
=
0
;
from
=
tape_parm_strtoul
(
temp
,
&
temp
);
to
=
from
;
if
(
*
temp
==
'-'
)
{
temp
++
;
to
=
tape_parm_strtoul
(
temp
,
&
temp
);
}
tape_create_devregs_range
(
from
,
to
);
str
++
;
}
}
/*******************************************************************
* Tape device (td) functions for create, free, enq, deq, enable,
* disable, get and put
*******************************************************************/
/*
* Enable Device
*/
static
inline
int
tape_enable_device
(
tape_dev_t
*
td
)
{
#ifdef CONFIG_DEVFS_FS
tape_frontend_t
*
frontend
;
#endif
int
rc
=
0
;
if
(
td
->
discipline
->
setup_device
(
td
)
!=
0
){
rc
=
-
ENOMEM
;
goto
out
;
}
/* Register IRQ */
#ifdef TAPE_CIO_PRIVATE_DATA
#ifdef CONFIG_S390_TAPE_DYNAMIC
rc
=
s390_request_irq_special
(
td
->
devinfo
.
irq
,
tape_do_irq
,
tape_noper_handler
,
0
,
TAPE_MAGIC
,
&
(
td
->
devstat
));
#else
rc
=
s390_request_irq
(
td
->
devinfo
.
irq
,
tape_do_irq
,
0
,
TAPE_MAGIC
,
&
(
td
->
devstat
));
#endif
#else
#ifdef CONFIG_S390_TAPE_DYNAMIC
rc
=
s390_request_irq_special
(
td
->
devinfo
.
irq
,
tape_do_irq
,
tape_noper_handler
,
0
,
(
char
*
)
td
,
&
(
td
->
devstat
));
#else
rc
=
s390_request_irq
(
td
->
devinfo
.
irq
,
tape_do_irq
,
0
,
(
char
*
)
td
,
&
(
td
->
devstat
));
#endif
#endif
/* TAPE_CIO_PRIVATE_DATA */
if
(
rc
){
PRINT_WARN
(
"Cannot register irq %d, rc=%d
\n
"
,
td
->
devinfo
.
irq
,
rc
);
td
->
discipline
->
cleanup_device
(
td
);
goto
out
;
}
/* Create devfs entries */
#ifdef CONFIG_DEVFS_FS
if
(
tape_mkdevfsroot
(
td
)
==
NULL
){
PRINT_WARN
(
"Cannot create a devfs directory for device %04x
\n
"
,
td
->
devinfo
.
devno
);
goto
out_undo
;
}
for
(
frontend
=
tape_first_front
;
frontend
!=
NULL
;
frontend
=
frontend
->
next
){
if
(
frontend
->
mkdevfstree
(
td
)
==
NULL
){
goto
out_undo
;
}
}
#endif
#ifdef TAPE_CIO_PRIVATE_DATA
s390_set_private_data
(
td
->
devinfo
.
irq
,
td
);
#endif
out:
return
rc
;
out_undo:
tape_disable_device
(
td
);
return
-
ENOMEM
;
}
/*
* Disable Device
*/
static
inline
void
tape_disable_device
(
tape_dev_t
*
td
)
{
#ifdef CONFIG_DEVFS_FS
tape_frontend_t
*
frontend
;
#endif
td
->
discipline
->
cleanup_device
(
td
);
#ifdef TAPE_CIO_PRIVATE_DATA
s390_set_private_data
(
td
->
devinfo
.
irq
,
NULL
);
#else
ioinfo
[
td
->
devinfo
.
irq
]
->
irq_desc
.
name
=
NULL
;
#endif
free_irq
(
td
->
devinfo
.
irq
,
&
(
td
->
devstat
));
#ifdef CONFIG_DEVFS_FS
for
(
frontend
=
tape_first_front
;
frontend
!=
NULL
;
frontend
=
frontend
->
next
)
frontend
->
rmdevfstree
(
td
);
tape_rmdevfsroot
(
td
);
#endif
tape_state_set
(
td
,
TS_NOT_OPER
);
}
/*
* Append Tape device (td) to our tape info list
* Must be called with hold tape_dev_lock
*/
static
inline
void
tape_enq_device
(
tape_dev_t
*
td
)
{
tape_dev_t
*
temptd
=
NULL
;
if
(
tape_first_dev
==
NULL
)
{
tape_first_dev
=
td
;
}
else
{
temptd
=
tape_first_dev
;
while
(
temptd
->
next
!=
NULL
)
temptd
=
temptd
->
next
;
temptd
->
next
=
td
;
}
}
/*
* Remove Tape device (td) from our tape info list
* Must be called with hold tape_dev_lock
*/
static
inline
void
tape_deq_device
(
tape_dev_t
*
td
)
{
tape_dev_t
*
lasttd
;
if
(
td
==
tape_first_dev
)
{
tape_first_dev
=
td
->
next
;
}
else
{
lasttd
=
tape_first_dev
;
while
(
lasttd
->
next
!=
td
)
lasttd
=
lasttd
->
next
;
lasttd
->
next
=
td
->
next
;
}
}
/*
* Get Free minor number
* Must be called with held tape_dev_lock
*/
static
inline
int
tape_get_new_minor
(
int
devno
)
{
int
i
,
tape_num
=
-
1
;
tape_dev_t
*
newtape
;
if
(
!
tape_autoprobe
){
/* we have static device ranges, so fingure out the */
/* tape_num of the attached tape */
for
(
i
=
0
;
i
<
tape_devregct
;
i
++
){
if
(
tape_devreg
[
i
]
->
ci
.
devno
==
devno
)
{
tape_num
=
TAPE_MINORS_PER_DEV
*
i
;
goto
out
;
}
}
}
else
{
/* we are running in autoprobe mode, find a free */
/* tape_num */
i
=
0
;
newtape
=
tape_first_dev
;
while
(
newtape
!=
NULL
)
{
if
(
newtape
->
first_minor
==
i
)
{
/* tape num in use. try next one */
i
+=
TAPE_MINORS_PER_DEV
;
newtape
=
tape_first_dev
;
}
else
{
/* tape num not used by newtape. look at next */
/* tape info */
newtape
=
newtape
->
next
;
}
}
if
(
i
>
255
)
/* No more minor available */
tape_num
=
-
1
;
else
tape_num
=
i
;
}
out:
return
tape_num
;
}
/*
* Create device: Alloc, enable and enq device
*/
static
inline
tape_dev_t
*
tape_create_device
(
int
irq
,
int
devno
,
tape_discipline_t
*
disc
)
{
int
rc
=
0
;
int
tape_num
;
tape_dev_t
*
td
;
long
lockflags
;
write_lock_irqsave
(
&
tape_dev_lock
,
lockflags
);
td
=
kmalloc
(
sizeof
(
tape_dev_t
),
GFP_ATOMIC
);
if
(
td
==
NULL
)
{
tape_sprintf_exception
(
tape_dbf_area
,
2
,
"ti:no mem
\n
"
);
PRINT_INFO
(
"tape: can't allocate memory for "
"tape info structure
\n
"
);
goto
error
;
}
memset
(
td
,
0
,
sizeof
(
tape_dev_t
));
tape_num
=
tape_get_new_minor
(
devno
);
if
(
tape_num
==
-
1
){
PRINT_WARN
(
"tape: could not get minor for tape %x
\n
"
,
devno
);
goto
error
;
}
rc
=
get_dev_info_by_irq
(
irq
,
&
(
td
->
devinfo
));
if
(
rc
==
-
ENODEV
)
{
/* end of device list */
goto
error
;
}
td
->
discipline
=
disc
;
atomic_set
(
&
(
td
->
use_count
),
1
);
td
->
first_minor
=
tape_num
;
td
->
medium_state
=
MS_UNKNOWN
;
td
->
next
=
NULL
;
td
->
discdata
=
td
->
treq
=
NULL
;
tape_state_set
(
td
,
TS_INIT
);
td
->
discdata
=
NULL
;
td
->
last_op
=
TO_NOTHING
;
if
(
td
->
discipline
->
setup_device
(
td
)
!=
0
)
goto
error
;
if
(
tape_enable_device
(
td
)
!=
0
)
goto
error
;
tape_enq_device
(
td
);
PRINT_INFO
(
"using devno %04x with discipline %04x on irq %d as tape device %d
\n
"
,
devno
,
disc
->
cu_type
,
irq
,
tape_num
/
2
);
write_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
return
td
;
error:
tape_sprintf_event
(
tape_dbf_area
,
3
,
"tsetup err: %x
\n
"
,
rc
);
if
(
td
)
kfree
(
td
);
write_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
return
NULL
;
}
/*
* Free Device storage
*/
static
void
tape_free_device
(
tape_dev_t
*
td
)
{
if
(
TAPE_BUSY
(
td
))
BUG
();
/* one should _not_ free the device when a request is pending */
tape_sprintf_event
(
tape_dbf_area
,
6
,
"free irq: %x
\n
"
,
td
->
devinfo
.
irq
);
kfree
(
td
);
}
/*
* Decrement use count of tape structure
* if use count == 0 tape structure is freed
*/
inline
void
tape_put_device
(
tape_dev_t
*
td
)
{
if
(
td
==
NULL
)
BUG
();
if
(
atomic_dec_and_test
(
&
(
td
->
use_count
)))
tape_free_device
(
td
);
}
/*
* Find the tape_dev_t structure associated with member
* and increase use count:
*
* member: TAPE_MEMB_IRQ, TAPE_MEMB_MINOR
*/
tape_dev_t
*
__tape_get_device_by_member
(
unsigned
long
value
,
int
member
)
{
tape_dev_t
*
td
=
NULL
;
long
lockflags
;
read_lock_irqsave
(
&
tape_dev_lock
,
lockflags
);
td
=
tape_first_dev
;
while
(
td
!=
NULL
)
{
switch
(
member
){
case
TAPE_MEMB_IRQ
:
if
(
td
->
devinfo
.
irq
==
value
)
goto
out
;
break
;
case
TAPE_MEMB_MINOR
:
if
((
value
>=
td
->
first_minor
)
&&
(
value
<
(
td
->
first_minor
+
TAPE_MINORS_PER_DEV
))
)
goto
out
;
break
;
case
TAPE_MEMB_QUEUE
:
if
(((
unsigned
long
)(
&
td
->
blk_data
.
request_queue
))
==
value
)
goto
out
;
break
;
default:
BUG
();
}
td
=
td
->
next
;
}
out:
if
(
td
)
// found!
atomic_inc
(
&
(
td
->
use_count
));
read_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
return
td
;
}
/*
* Scan all irqs an create tape devices for all matching cu types
*/
static
inline
void
tape_create_devs_for_disc
(
tape_discipline_t
*
disc
)
{
int
irq
,
i
;
tape_dev_t
*
td
=
NULL
;
s390_dev_info_t
dinfo
;
for
(
irq
=
get_irq_first
();
irq
!=-
ENODEV
;
irq
=
get_irq_next
(
irq
))
{
if
(
get_dev_info_by_irq
(
irq
,
&
dinfo
)
==
-
ENODEV
)
continue
;
if
(
disc
->
cu_type
!=
dinfo
.
sid_data
.
cu_type
)
/* Wrong type - try next one */
continue
;
tape_sprintf_event
(
tape_dbf_area
,
3
,
"det irq: %x
\n
"
,
irq
);
tape_sprintf_event
(
tape_dbf_area
,
3
,
"cu : %x
\n
"
,
disc
->
cu_type
);
if
(
!
tape_autoprobe
)
{
for
(
i
=
0
;
i
<
tape_devregct
;
i
++
)
{
if
(
tape_devreg
[
i
]
->
ci
.
devno
==
dinfo
.
devno
)
{
td
=
tape_create_device
(
irq
,
dinfo
.
devno
,
disc
);
if
(
!
td
)
{
PRINT_WARN
(
"Could not initialize tape 0x%x
\n
"
,
dinfo
.
devno
);
continue
;
}
if
(
disc
->
init_device
)
disc
->
init_device
(
td
);
/* XXX */
tape_state_set
(
td
,
TS_UNUSED
);
break
;
}
}
}
else
{
td
=
tape_create_device
(
irq
,
dinfo
.
devno
,
disc
);
if
(
!
td
){
PRINT_WARN
(
"Could not initialize tape 0x%x
\n
"
,
dinfo
.
devno
);
continue
;
}
if
(
disc
->
init_device
)
disc
->
init_device
(
td
);
/* XXX */
tape_state_set
(
td
,
TS_UNUSED
);
}
}
}
/*
* Go through our tape info list and disable, deq and free all devices with
* matching cu type
*/
static
inline
void
tape_delete_devs_for_disc
(
tape_discipline_t
*
disc
)
{
tape_dev_t
*
td
;
long
lockflags
;
write_lock_irqsave
(
&
tape_dev_lock
,
lockflags
);
td
=
tape_first_dev
;
while
(
td
!=
NULL
){
if
(
td
->
discipline
==
disc
){
tape_deq_device
(
td
);
write_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
tape_disable_device
(
td
);
tape_put_device
(
td
);
write_lock_irqsave
(
&
tape_dev_lock
,
lockflags
);
td
=
tape_first_dev
;
}
else
{
td
=
td
->
next
;
}
}
write_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
}
/*******************************************************************
* TAPE Request and IO Functions
*******************************************************************/
/*
* Allocate a new tape ccw request
*/
inline
tape_ccw_req_t
*
tape_alloc_ccw_req
(
int
cplength
,
int
datasize
,
int
idal_buf_size
,
tape_op_t
operation
)
{
tape_ccw_req_t
*
treq
;
int
kmalloc_flags
;
if
(
in_interrupt
())
kmalloc_flags
=
GFP_ATOMIC
;
else
kmalloc_flags
=
GFP_KERNEL
;
treq
=
(
tape_ccw_req_t
*
)
kmalloc
(
sizeof
(
tape_ccw_req_t
),
kmalloc_flags
);
if
(
!
treq
)
goto
error
;
memset
(
treq
,
0
,
sizeof
(
tape_ccw_req_t
));
treq
->
kernbuf_size
=
datasize
;
treq
->
userbuf_size
=
datasize
;
treq
->
op
=
operation
;
treq
->
cplength
=
cplength
;
init_waitqueue_head
(
&
treq
->
wq
);
// alloc small kernel buffer
if
(
datasize
>
PAGE_SIZE
)
BUG
();
if
(
datasize
>
0
){
// the kernbuf must be below 2GB --> GFP_DMA
treq
->
kernbuf
=
kmalloc
(
datasize
,
kmalloc_flags
|
GFP_DMA
);
if
(
!
treq
->
kernbuf
)
goto
error
;
memset
(
treq
->
kernbuf
,
0
,
datasize
);
}
// alloc idal kernel buffer
if
(
idal_buf_size
>
0
){
treq
->
idal_buf
=
idalbuf_alloc
(
idal_buf_size
);
if
(
!
treq
->
idal_buf
)
goto
error
;
}
if
(
cplength
<
0
)
BUG
();
// the channel program must be below 2GB --> GFP_DMA
treq
->
cpaddr
=
kmalloc
(
cplength
*
sizeof
(
ccw1_t
),
kmalloc_flags
|
GFP_DMA
);
if
(
!
treq
->
cpaddr
)
goto
error
;
memset
(
treq
->
cpaddr
,
0
,
cplength
*
sizeof
(
ccw1_t
));
return
treq
;
error:
tape_sprintf_exception
(
tape_dbf_area
,
1
,
"cqra nomem
\n
"
);
if
(
treq
)
tape_free_ccw_req
(
treq
);
return
NULL
;
}
/*
* Free tape ccw request
*/
void
tape_free_ccw_req
(
tape_ccw_req_t
*
treq
)
{
if
(
!
treq
)
BUG
();
if
(
treq
->
cpaddr
)
kfree
(
treq
->
cpaddr
);
if
(
treq
->
kernbuf
)
kfree
(
treq
->
kernbuf
);
if
(
treq
->
idal_buf
)
idalbuf_free
(
treq
->
idal_buf
);
kfree
(
treq
);
}
/*
* Add request to request queue (At the moment queue length = 1)
*/
static
inline
int
tape_add_ccw_req
(
tape_dev_t
*
td
,
tape_ccw_req_t
*
treq
)
{
if
(
td
->
treq
)
return
-
1
;
td
->
treq
=
treq
;
treq
->
tape_dev
=
td
;
return
0
;
}
/*
* Remove request from request queue (At the moment queue length = 1)
*/
int
tape_remove_ccw_req
(
tape_dev_t
*
td
,
tape_ccw_req_t
*
treq
)
{
if
(
treq
!=
td
->
treq
)
BUG
();
td
->
last_op
=
treq
->
op
;
td
->
treq
=
NULL
;
treq
->
tape_dev
=
NULL
;
return
0
;
}
/*
* Get the active ccw request
*/
tape_ccw_req_t
*
tape_get_active_ccw_req
(
tape_dev_t
*
td
)
{
return
td
->
treq
;
}
/*
* Stop the active ccw request
*/
static
inline
int
tape_halt_io
(
tape_dev_t
*
td
)
{
int
retries
=
0
;
int
irq
=
td
->
devinfo
.
irq
;
int
rc
=
0
;
long
lockflags
;
tape_ccw_req_t
*
treq
;
s390irq_spin_lock_irqsave
(
td
->
devinfo
.
irq
,
lockflags
);
treq
=
tape_get_active_ccw_req
(
td
);
/* check if interrupt has already been processed */
if
(
!
treq
)
goto
out
;
if
(
treq
->
wakeup
==
NULL
)
goto
out
;
while
(
retries
<
5
){
if
(
retries
<
2
)
rc
=
halt_IO
(
irq
,
(
long
)
treq
,
treq
->
options
);
else
rc
=
clear_IO
(
irq
,
(
long
)
treq
,
treq
->
options
);
switch
(
rc
)
{
case
0
:
/* termination successful */
rc
=
-
ERESTARTSYS
;
goto
out
;
case
-
ENODEV
:
PRINT_INFO
(
"device gone, retry
\n
"
);
/* FIXME: s390dbf only */
break
;
case
-
EIO
:
PRINT_INFO
(
"I/O error, retry
\n
"
);
/* FIXME: s390dbf only */
break
;
case
-
EBUSY
:
PRINT_INFO
(
"device busy, retry later
\n
"
);
/* FIXME: s390dbf only */
break
;
default:
PRINT_ERR
(
"line %d unknown RC=%d, please report"
" to linux390@de.ibm.com
\n
"
,
__LINE__
,
rc
);
BUG
();
}
retries
++
;
}
out:
s390irq_spin_unlock_irqrestore
(
td
->
devinfo
.
irq
,
lockflags
);
return
rc
;
}
/*
* The tape IO function:
* tape_do_io MUST be called with locked td lock!
*/
static
inline
int
__tape_do_io
(
tape_dev_t
*
td
,
tape_ccw_req_t
*
treq
,
tape_wait_t
type
,
int
io
)
{
int
rc
=
0
;
if
((
td
==
NULL
)
||
(
treq
==
NULL
))
BUG
();
if
(
tape_state_get
(
td
)
==
TS_NOT_OPER
){
rc
=
-
ENODEV
;
goto
out
;
}
if
(
TAPE_BUSY
(
td
)){
tape_sprintf_event
(
tape_dbf_area
,
1
,
"tape: IRQ - Tape busy
\n
"
);
rc
=
-
EBUSY
;
goto
out
;
}
tape_add_ccw_req
(
td
,
treq
);
switch
(
type
){
case
TAPE_REMOVE_REQ_ON_WAKEUP
:
treq
->
wakeup
=
tape_wake_up_remove
;
break
;
case
TAPE_NO_WAIT
:
// needed for retry
break
;
case
TAPE_WAIT
:
treq
->
wakeup
=
tape_wake_up
;
treq
->
wait
=
tape_wait_event
;
break
;
case
TAPE_WAIT_INTERRUPTIBLE
:
treq
->
wakeup
=
tape_wake_up_interruptible
;
treq
->
wait
=
tape_wait_event_interruptible
;
break
;
case
TAPE_WAIT_INTERRUPTIBLE_NOHALTIO
:
// neded for dummy load
treq
->
wakeup
=
tape_wake_up_interruptible
;
treq
->
wait
=
tape_wait_event_interruptible_nohaltio
;
break
;
#ifdef CONFIG_S390_TAPE_BLOCK
case
TAPE_SCHED_BLOCK
:
treq
->
wakeup
=
tape_schedule_tapeblock
;
treq
->
wait
=
NULL
;
break
;
#endif
default:
BUG
();
}
if
(
io
)
rc
=
do_IO
(
td
->
devinfo
.
irq
,
treq
->
cpaddr
,
(
unsigned
long
)
treq
,
0x00
,
treq
->
options
);
if
(
rc
)
{
tape_sprintf_event
(
tape_dbf_area
,
1
,
"tape: DOIO failed with er = %i
\n
"
,
rc
);
treq
->
wakeup
=
NULL
;
treq
->
wait
=
NULL
;
/*XXX ??*/
tape_remove_ccw_req
(
td
,
treq
);
}
out:
return
rc
;
}
/*
* Do the io request and wait for it
*/
int
tape_do_io_and_wait
(
tape_dev_t
*
td
,
tape_ccw_req_t
*
treq
,
tape_wait_t
type
)
{
int
rc
=
0
;
long
lockflags
;
if
(
td
==
NULL
)
BUG
();
s390irq_spin_lock_irqsave
(
td
->
devinfo
.
irq
,
lockflags
);
rc
=
__tape_do_io
(
td
,
treq
,
type
,
TAPE_DO_IO
);
s390irq_spin_unlock_irqrestore
(
td
->
devinfo
.
irq
,
lockflags
);
if
(
rc
==
0
)
tape_wait
(
treq
);
return
rc
;
}
/*
* Needed for MTLOAD: Just create a wait request without doing io
*/
int
tape_do_wait_req
(
tape_dev_t
*
td
,
tape_ccw_req_t
*
treq
,
tape_wait_t
type
)
{
int
rc
=
0
;
long
lockflags
;
if
(
td
==
NULL
)
BUG
();
s390irq_spin_lock_irqsave
(
td
->
devinfo
.
irq
,
lockflags
);
rc
=
__tape_do_io
(
td
,
treq
,
type
,
TAPE_NO_IO
);
s390irq_spin_unlock_irqrestore
(
td
->
devinfo
.
irq
,
lockflags
);
tape_wait
(
treq
);
return
rc
;
}
/*
* Just do the io
*/
int
tape_do_io
(
tape_dev_t
*
td
,
tape_ccw_req_t
*
treq
,
tape_wait_t
type
)
{
int
rc
=
0
;
long
lockflags
;
s390irq_spin_lock_irqsave
(
td
->
devinfo
.
irq
,
lockflags
);
rc
=
__tape_do_io
(
td
,
treq
,
type
,
TAPE_DO_IO
);
s390irq_spin_unlock_irqrestore
(
td
->
devinfo
.
irq
,
lockflags
);
return
rc
;
}
/*
* Just do the io, but we are already locked here (in irq)
*/
int
tape_do_io_irq
(
tape_dev_t
*
td
,
tape_ccw_req_t
*
treq
,
tape_wait_t
type
)
{
return
__tape_do_io
(
td
,
treq
,
type
,
TAPE_DO_IO
);
}
/*
* Wait for an io request
*/
static
void
tape_wait
(
tape_ccw_req_t
*
treq
)
{
tape_dev_t
*
td
;
if
(
treq
==
NULL
)
BUG
();
td
=
treq
->
tape_dev
;
if
(
td
==
NULL
)
BUG
();
if
(
treq
->
wait
==
NULL
)
BUG
();
treq
->
wait
(
treq
);
tape_remove_ccw_req
(
td
,
treq
);
}
/*
* Tape interrupt routine, called from Ingo's I/O layer
*/
static
void
tape_do_irq
(
int
irq
,
void
*
int_parm
,
struct
pt_regs
*
regs
)
{
tape_dev_t
*
td
;
#ifdef TAPE_CIO_PRIVATE_DATA
td
=
(
tape_dev_t
*
)
s390_get_private_data
(
irq
);
#else
td
=
(
tape_dev_t
*
)
ioinfo
[
irq
]
->
irq_desc
.
name
;
#endif
if
(
!
td
)
{
PRINT_ERR
(
"tape: could not get device structure for irq %d in interrupt
\n
"
,
irq
);
goto
out
;
}
if
(
td
->
devstat
.
dstat
!=
0x0c
){
tape_sprintf_event
(
tape_dbf_area
,
3
,
"-- Tape Interrupthandler --
\n
"
);
tape_dump_sense_dbf
(
td
);
}
if
(
tape_state_get
(
td
)
==
TS_NOT_OPER
)
{
tape_sprintf_event
(
tape_dbf_area
,
6
,
"tape:device is not operational
\n
"
);
goto
out
;
}
td
->
discipline
->
irq
(
td
);
out:
return
;
}
/*
* Oper Handler is called from Ingo's I/O layer when a new tape device is
* attached. We create a new devinfo for the new device, enable and enq it.
*/
static
int
tape_oper_handler
(
int
irq
,
struct
_devreg
*
dreg
)
{
tape_dev_t
*
td
=
tape_first_dev
;
int
rc
=
0
;
s390_dev_info_t
dinfo
;
tape_discipline_t
*
disc
;
long
lockflags
;
td
=
tape_get_device_by_irq
(
irq
);
if
(
td
!=
NULL
)
{
// irq is (still) used by tape. tell ingo to try again later
PRINT_ERR
(
"tape:Oper handler for irq %d called, but irq is still (internally) used.
\n
"
,
irq
);
rc
=
-
EAGAIN
;
goto
out
;
}
rc
=
get_dev_info_by_irq
(
irq
,
&
dinfo
);
if
(
rc
==
-
ENODEV
)
{
PRINT_ERR
(
"tape: Cannot get dev info for irq %d in the oper handler.
\n
"
,
irq
);
rc
=
-
EAGAIN
;
goto
out
;
}
read_lock_irqsave
(
&
tape_discipline_lock
,
lockflags
);
disc
=
tape_first_disc
;
while
((
disc
!=
NULL
)
&&
(
disc
->
cu_type
!=
dinfo
.
sid_data
.
cu_type
))
disc
=
(
tape_discipline_t
*
)
(
disc
->
next
);
if
(
disc
==
NULL
){
PRINT_WARN
(
"tape: No matching discipline for cu_type %x found in the oper handler, ignoring device %04x.
\n
"
,
dinfo
.
sid_data
.
cu_type
,
dinfo
.
devno
);
rc
=
-
ENODEV
;
goto
out_unlock
;
}
/* Allocate tape structure */
td
=
tape_create_device
(
irq
,
dinfo
.
devno
,
disc
);
if
(
td
==
NULL
)
{
PRINT_WARN
(
"Could not initialize tape 0x%x
\n
"
,
dinfo
.
devno
);
rc
=
-
ENOBUFS
;
goto
out_unlock
;
}
else
{
if
(
disc
->
init_device
)
disc
->
init_device
(
td
);
}
tape_state_set
(
td
,
TS_UNUSED
);
out_unlock:
read_unlock_irqrestore
(
&
tape_discipline_lock
,
lockflags
);
out:
return
rc
;
}
/*
* Not Oper Handler is called from Ingo's IO layer, when a tape device
* is detached. We deq, disable and free the tape info for this device
*/
static
void
tape_noper_handler
(
int
irq
,
int
status
)
{
tape_dev_t
*
td
;
long
lockflags
;
tape_ccw_req_t
*
treq
;
td
=
tape_get_device_by_irq
(
irq
);
if
(
td
==
NULL
)
{
PRINT_ERR
(
"tape: not operational handler called for irq %x, but tape does not hold this irq.
\n
"
,
irq
);
goto
error
;
}
write_lock_irqsave
(
&
tape_dev_lock
,
lockflags
);
tape_deq_device
(
td
);
write_unlock_irqrestore
(
&
tape_dev_lock
,
lockflags
);
tape_disable_device
(
td
);
s390irq_spin_lock_irqsave
(
td
->
devinfo
.
irq
,
lockflags
);
treq
=
tape_get_active_ccw_req
(
td
);
if
(
treq
)
{
// device is in use!
treq
->
rc
=
-
ENODEV
;
if
(
treq
->
wakeup
)
treq
->
wakeup
(
treq
);
PRINT_WARN
(
"Tape #%d is detached while it was busy.
\n
"
,
td
->
first_minor
/
TAPE_MINORS_PER_DEV
);
}
else
{
// device is unused!
PRINT_WARN
(
"Tape #%d is detached now.
\n
"
,
td
->
first_minor
/
TAPE_MINORS_PER_DEV
);
}
s390irq_spin_unlock_irqrestore
(
td
->
devinfo
.
irq
,
lockflags
);
/* decrement use count twice ! */
tape_put_device
(
td
);
tape_put_device
(
td
);
error:
return
;
}
/*
* Write sense data to dbf
*/
void
tape_dump_sense_dbf
(
tape_dev_t
*
td
)
{
devstat_t
*
stat
=
&
td
->
devstat
;
const
char
*
op
;
if
(
TAPE_BUSY
(
td
))
op
=
tape_op_verbose
[
tape_get_active_ccw_req
(
td
)
->
op
];
else
op
=
"---"
;
tape_sprintf_event
(
tape_dbf_area
,
3
,
"DSTAT : %02x CSTAT: %02x
\n
"
,
stat
->
dstat
,
stat
->
cstat
);
tape_sprintf_event
(
tape_dbf_area
,
3
,
"DEVICE: %04x OP : %s
\n
"
,
td
->
devinfo
.
devno
,
op
);
tape_sprintf_event
(
tape_dbf_area
,
3
,
"%08x %08x
\n
"
,
*
((
unsigned
int
*
)
&
stat
->
ii
.
sense
.
data
[
0
]),
*
((
unsigned
int
*
)
&
stat
->
ii
.
sense
.
data
[
4
]));
tape_sprintf_event
(
tape_dbf_area
,
3
,
"%08x %08x
\n
"
,
*
((
unsigned
int
*
)
&
stat
->
ii
.
sense
.
data
[
8
]),
*
((
unsigned
int
*
)
&
stat
->
ii
.
sense
.
data
[
12
]));
tape_sprintf_event
(
tape_dbf_area
,
3
,
"%08x %08x
\n
"
,
*
((
unsigned
int
*
)
&
stat
->
ii
.
sense
.
data
[
16
]),
*
((
unsigned
int
*
)
&
stat
->
ii
.
sense
.
data
[
20
]));
tape_sprintf_event
(
tape_dbf_area
,
3
,
"%08x %08x
\n
"
,
*
((
unsigned
int
*
)
&
stat
->
ii
.
sense
.
data
[
24
]),
*
((
unsigned
int
*
)
&
stat
->
ii
.
sense
.
data
[
28
]));
}
/*
* Write sense data to console/dbf
*/
void
tape_dump_sense
(
tape_dev_t
*
td
)
{
devstat_t
*
stat
=
&
td
->
devstat
;
#if 1
/* XXX */
PRINT_INFO
(
"-------------------------------------------------
\n
"
);
PRINT_INFO
(
"DSTAT : %02x CSTAT: %02x CPA: %04x
\n
"
,
stat
->
dstat
,
stat
->
cstat
,
stat
->
cpa
);
PRINT_INFO
(
"DEVICE: %04x
\n
"
,
td
->
devinfo
.
devno
);
if
(
TAPE_BUSY
(
td
))
PRINT_INFO
(
"OP : %s
\n
"
,
tape_op_verbose
[
tape_get_active_ccw_req
(
td
)
->
op
]);
PRINT_INFO
(
"Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
" %02X%02X%02X%02X %02X%02X%02X%02X
\n
"
,
stat
->
ii
.
sense
.
data
[
0
],
stat
->
ii
.
sense
.
data
[
1
],
stat
->
ii
.
sense
.
data
[
2
],
stat
->
ii
.
sense
.
data
[
3
],
stat
->
ii
.
sense
.
data
[
4
],
stat
->
ii
.
sense
.
data
[
5
],
stat
->
ii
.
sense
.
data
[
6
],
stat
->
ii
.
sense
.
data
[
7
],
stat
->
ii
.
sense
.
data
[
8
],
stat
->
ii
.
sense
.
data
[
9
],
stat
->
ii
.
sense
.
data
[
10
],
stat
->
ii
.
sense
.
data
[
11
],
stat
->
ii
.
sense
.
data
[
12
],
stat
->
ii
.
sense
.
data
[
13
],
stat
->
ii
.
sense
.
data
[
14
],
stat
->
ii
.
sense
.
data
[
15
]);
PRINT_INFO
(
"Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
" %02X%02X%02X%02X %02X%02X%02X%02X
\n
"
,
stat
->
ii
.
sense
.
data
[
16
],
stat
->
ii
.
sense
.
data
[
17
],
stat
->
ii
.
sense
.
data
[
18
],
stat
->
ii
.
sense
.
data
[
19
],
stat
->
ii
.
sense
.
data
[
20
],
stat
->
ii
.
sense
.
data
[
21
],
stat
->
ii
.
sense
.
data
[
22
],
stat
->
ii
.
sense
.
data
[
23
],
stat
->
ii
.
sense
.
data
[
24
],
stat
->
ii
.
sense
.
data
[
25
],
stat
->
ii
.
sense
.
data
[
26
],
stat
->
ii
.
sense
.
data
[
27
],
stat
->
ii
.
sense
.
data
[
28
],
stat
->
ii
.
sense
.
data
[
29
],
stat
->
ii
.
sense
.
data
[
30
],
stat
->
ii
.
sense
.
data
[
31
]);
PRINT_INFO
(
"--------------------------------------------------
\n
"
);
#endif
}
/*******************************************************************
* TAPE Discipline functions
*******************************************************************/
/*
* Register backend discipline
*/
int
tape_register_discipline
(
tape_discipline_t
*
disc
)
{
tape_discipline_t
*
disc_ptr
;
long
lockflags
;
disc
->
next
=
NULL
;
write_lock_irqsave
(
&
tape_discipline_lock
,
lockflags
);
if
(
tape_first_disc
==
NULL
)
{
tape_first_disc
=
disc
;
}
else
{
for
(
disc_ptr
=
tape_first_disc
;
disc_ptr
->
next
!=
NULL
;
disc_ptr
=
(
tape_discipline_t
*
)
disc_ptr
->
next
);
disc_ptr
->
next
=
disc
;
}
tape_create_devs_for_disc
(
disc
);
if
(
tape_autoprobe
)
tape_create_devreg_for_disc
(
disc
);
write_unlock_irqrestore
(
&
tape_discipline_lock
,
lockflags
);
return
0
;
}
/*
* Unregister backend discipline
*/
void
tape_unregister_discipline
(
tape_discipline_t
*
disc
)
{
tape_discipline_t
*
lastdisc
;
long
lockflags
;
write_lock_irqsave
(
&
tape_discipline_lock
,
lockflags
);
tape_delete_devs_for_disc
(
disc
);
if
(
tape_autoprobe
)
tape_delete_devreg_for_disc
(
disc
);
if
(
disc
==
tape_first_disc
)
{
tape_first_disc
=
disc
->
next
;
}
else
{
lastdisc
=
tape_first_disc
;
while
(
lastdisc
->
next
!=
disc
)
lastdisc
=
lastdisc
->
next
;
lastdisc
->
next
=
disc
->
next
;
}
disc
->
shutdown
();
write_unlock_irqrestore
(
&
tape_discipline_lock
,
lockflags
);
}
/*
* Cleanup all registered disciplines
*/
static
inline
void
tape_cleanup_disciplines
(
void
)
{
long
lockflags
;
tape_discipline_t
*
disc
;
/* Unregister all backend disciplines - this also deletes the devices */
write_lock_irqsave
(
&
tape_discipline_lock
,
lockflags
);
disc
=
tape_first_disc
;
while
(
disc
!=
NULL
)
{
write_unlock_irqrestore
(
&
tape_discipline_lock
,
lockflags
);
tape_unregister_discipline
(
disc
);
kfree
(
disc
);
write_lock_irqsave
(
&
tape_discipline_lock
,
lockflags
);
disc
=
tape_first_disc
;
}
write_unlock_irqrestore
(
&
tape_discipline_lock
,
lockflags
);
}
/*******************************************************************
* TAPE Init Functions
*******************************************************************/
/*
* tape_print_banner will be called on initialisation and print a nice banner
*/
static
inline
void
tape_print_banner
(
void
)
{
char
*
opt_char
,
*
opt_block
;
/* print banner */
PRINT_WARN
(
"IBM zSeries Tape Device Driver (v%d.%02d).
\n
"
,
TAPE_VERSION_MAJOR
,
TAPE_VERSION_MINOR
);
PRINT_WARN
(
"(C) IBM Deutschland Entwicklung GmbH, 2000 - 2001
\n
"
);
opt_char
=
opt_block
=
"not present"
;
#ifdef CONFIG_S390_TAPE_CHAR
opt_char
=
"built in"
;
#endif
#ifdef CONFIG_S390_TAPE_BLOCK
opt_block
=
"built in"
;
#endif
/* print feature info */
PRINT_WARN
(
"character device frontend : %s
\n
"
,
opt_char
);
PRINT_WARN
(
"block device frontend : %s
\n
"
,
opt_block
);
}
/*
* tape_init will register the driver for each tape.
*/
int
tape_init
(
void
)
{
static
int
initialized
=
0
;
if
(
initialized
)
// Only init the devices once
return
0
;
initialized
=
1
;
tape_init_devregs
();
#ifdef TAPE_DEBUG
tape_dbf_area
=
debug_register
(
"tape"
,
2
,
2
,
3
*
sizeof
(
long
));
debug_register_view
(
tape_dbf_area
,
&
debug_sprintf_view
);
tape_sprintf_event
(
tape_dbf_area
,
3
,
"begin init
\n
"
);
#endif
/* TAPE_DEBUG */
tape_print_banner
();
#ifndef MODULE
tape_split_parm_string
(
tape_parm_string
);
#endif
#ifdef CONFIG_DEVFS_FS
devfs_mk_dir
(
NULL
,
"tape"
,
NULL
);
#endif
/* CONFIG_DEVFS_FS */
tape_sprintf_event
(
tape_dbf_area
,
3
,
"dev detect
\n
"
);
/* Allocate the tape structures */
if
(
*
tape
!=
NULL
)
{
/* if parameters are present */
PRINT_INFO
(
"Using ranges supplied in parameters, disabling autoprobe mode.
\n
"
);
tape_parm_parse
(
tape
);
tape_autoprobe
=
0
;
}
else
{
PRINT_INFO
(
"No parameters supplied, enabling autoprobe mode for all supported devices.
\n
"
);
tape_autoprobe
=
1
;
}
#ifdef CONFIG_PROC_FS
tape_proc_init
();
#endif
/* CONFIG_PROC_FS */
#ifdef CONFIG_S390_TAPE_3480
tape_register_discipline
(
tape3480_init
());
#else
#ifndef CONFIG_S390_TAPE
tape_request_module
(
"tape_3480_mod"
);
#endif
#endif
/* CONFIG_S390_TAPE_3480 */
#ifdef CONFIG_S390_TAPE_3490
tape_register_discipline
(
tape3490_init
());
#else
#ifndef CONFIG_S390_TAPE
tape_request_module
(
"tape_3490_mod"
);
#endif
#endif
/* CONFIG_S390_TAPE_3490 */
#ifdef CONFIG_S390_TAPE_3590
tape_register_discipline
(
tape3590_init
());
#else
#ifndef CONFIG_S390_TAPE
tape_request_module
(
"tape_3590_mod"
);
#endif
#endif
/* CONFIG_S390_TAPE_3590 */
return
0
;
}
/*******************************************************************
* TAPE Module functions
*******************************************************************/
#ifdef MODULE
MODULE_AUTHOR
(
"(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)"
);
MODULE_DESCRIPTION
(
"Linux on zSeries channel attached tape device driver"
);
MODULE_PARM
(
tape
,
"1-"
__MODULE_STRING
(
256
)
"s"
);
/*
* The famous init_module
*/
int
init_module
(
void
)
{
#ifdef CONFIG_S390_TAPE_CHAR
tapechar_init
();
#endif
#ifdef CONFIG_S390_TAPE_BLOCK
tapeblock_init
();
#endif
return
0
;
}
/*
* Cleanup the frontends
*/
static
inline
void
tape_cleanup_frontends
(
void
)
{
tape_frontend_t
*
frontend
,
*
tempfe
;
/* Now get rid of the frontends */
#ifdef CONFIG_S390_TAPE_CHAR
tapechar_uninit
();
#endif
#ifdef CONFIG_S390_TAPE_BLOCK
tapeblock_uninit
();
#endif
frontend
=
tape_first_front
;
while
(
frontend
!=
NULL
)
{
tempfe
=
frontend
;
frontend
=
frontend
->
next
;
kfree
(
tempfe
);
}
}
/*
* Cleanup module
*/
void
cleanup_module
(
void
)
{
tape_sprintf_event
(
tape_dbf_area
,
6
,
"cleaup mod"
);
tape_cleanup_disciplines
();
#ifdef CONFIG_DEVFS_FS
devfs_remove
(
"tape"
);
/* devfs checks for NULL */
#endif CONFIG_DEVFS_FS
#ifdef CONFIG_PROC_FS
tape_proc_cleanup
();
#endif
tape_cleanup_frontends
();
/* Deallocate devregs in case of not autoprobe */
if
(
!
tape_autoprobe
)
tape_delete_all_devregs
();
#ifdef TAPE_DEBUG
debug_unregister
(
tape_dbf_area
);
#endif
/* TAPE_DEBUG */
}
#endif
/* MODULE */
/*******************************************************************
* TAPE Tapestate functions
*******************************************************************/
inline
void
tape_state_set
(
tape_dev_t
*
td
,
tape_state_t
newstate
)
{
if
(
td
->
tape_state
==
TS_NOT_OPER
)
{
tape_sprintf_event
(
tape_dbf_area
,
3
,
"ts_set err: not oper
\n
"
);
}
else
{
tape_sprintf_event
(
tape_dbf_area
,
4
,
"ts. dev: %x
\n
"
,
td
->
first_minor
);
tape_sprintf_event
(
tape_dbf_area
,
4
,
"old ts: %s
\n
"
,(((
tape_state_get
(
td
)
<
TO_SIZE
)
&&
(
tape_state_get
(
td
)
>=
0
))
?
tape_state_verbose
[
tape_state_get
(
td
)]
:
"UNKNOWN TS"
));
tape_sprintf_event
(
tape_dbf_area
,
4
,
"%s
\n
"
,
(((
tape_state_get
(
td
)
<
TO_SIZE
)
&&
(
tape_state_get
(
td
)
>=
0
))
?
tape_state_verbose
[
tape_state_get
(
td
)]
:
"UNKNOWN TS"
));
tape_sprintf_event
(
tape_dbf_area
,
4
,
"new ts:
\n
"
);
tape_sprintf_event
(
tape_dbf_area
,
4
,
"%s
\n
"
,(((
newstate
<
TO_SIZE
)
&&
(
newstate
>=
0
))
?
tape_state_verbose
[
newstate
]
:
"UNKNOWN TS"
));
td
->
tape_state
=
newstate
;
}
}
inline
tape_state_t
tape_state_get
(
tape_dev_t
*
td
)
{
return
(
td
->
tape_state
);
}
inline
void
tape_med_state_set
(
tape_dev_t
*
td
,
tape_medium_state_t
newstate
)
{
if
(
td
->
medium_state
==
newstate
)
goto
out
;
switch
(
newstate
){
case
MS_UNLOADED
:
PRINT_INFO
(
"(%x): Tape is unloaded
\n
"
,
td
->
devstat
.
devno
);
break
;
case
MS_LOADED
:
PRINT_INFO
(
"(%x): Tape has been mounted
\n
"
,
td
->
devstat
.
devno
);
break
;
default:
// print nothing
break
;
}
td
->
medium_state
=
newstate
;
out:
return
;
}
/*******************************************************************
* TAPE Exported Functions
*******************************************************************/
EXPORT_SYMBOL
(
tape_register_discipline
);
EXPORT_SYMBOL
(
tape_unregister_discipline
);
EXPORT_SYMBOL
(
tape_dbf_area
);
EXPORT_SYMBOL
(
tape_alloc_ccw_req
);
EXPORT_SYMBOL
(
tape_free_ccw_req
);
EXPORT_SYMBOL
(
tape_state_set
);
EXPORT_SYMBOL
(
tape_state_get
);
EXPORT_SYMBOL
(
tape_med_state_set
);
EXPORT_SYMBOL
(
tape_state_verbose
);
EXPORT_SYMBOL
(
tape_op_verbose
);
EXPORT_SYMBOL
(
tape_dump_sense
);
EXPORT_SYMBOL
(
tape_dump_sense_dbf
);
EXPORT_SYMBOL
(
tape_do_io
);
EXPORT_SYMBOL
(
tape_do_io_irq
);
EXPORT_SYMBOL
(
tape_do_io_and_wait
);
EXPORT_SYMBOL
(
tape_remove_ccw_req
);
EXPORT_SYMBOL
(
tape_get_active_ccw_req
);
drivers/s390/cio/Makefile
View file @
86a7dc29
...
...
@@ -3,7 +3,7 @@
#
obj-y
+=
airq.o blacklist.o chsc.o cio.o css.o requestirq.o
export-objs
+=
airq.o css.o c
hsc.o c
io.o requestirq.o
export-objs
+=
airq.o css.o cio.o requestirq.o
ccw_device-objs
+=
device.o device_fsm.o device_ops.o
ccw_device-objs
+=
device_id.o device_pgid.o device_status.o
...
...
drivers/s390/cio/blacklist.c
View file @
86a7dc29
/*
* drivers/s390/cio/blacklist.c
* S/390 common I/O routines -- blacklisting of specific devices
* $Revision: 1.2
2
$
* $Revision: 1.2
3
$
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
...
...
@@ -162,10 +162,10 @@ blacklist_parse_proc_parameters (char *buf)
else
blacklist_parse_parameters
(
buf
+
5
,
free
);
}
else
if
(
strncmp
(
buf
,
"add "
,
4
)
==
0
)
{
/*
FIXME: the old code was checking if the new bl'ed
*
devices are already known to the system so
*
validate_subchannel would still give a working
*
status. is that necessary? *
/
/*
*
We don't need to check for known devices since
*
css_probe_device will handle this correctly.
*/
blacklist_parse_parameters
(
buf
+
4
,
add
);
}
else
{
printk
(
KERN_WARNING
"cio_ignore: Parse error;
\n
"
...
...
drivers/s390/cio/chsc.c
View file @
86a7dc29
/*
* drivers/s390/cio/chsc.c
* S/390 common I/O routines -- channel subsystem call
* $Revision: 1.4
3
$
* $Revision: 1.4
6
$
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
...
...
@@ -37,26 +37,6 @@ static int cio_chsc_desc_avail;
static
int
new_channel_path
(
int
chpid
,
int
status
);
int
chsc
(
void
*
data
)
{
void
*
area
;
int
cc
;
if
(
!
data
)
return
-
EINVAL
;
area
=
(
void
*
)
get_zeroed_page
(
GFP_KERNEL
);
if
(
!
area
)
return
-
ENOMEM
;
memcpy
(
area
,
data
,
PAGE_SIZE
);
cc
=
do_chsc
(
area
);
if
(
cc
==
0
)
memcpy
(
data
,
area
,
PAGE_SIZE
);
free_page
((
unsigned
long
)
area
);
return
cc
;
}
static
int
set_chp_status
(
int
chp
,
int
status
)
{
...
...
@@ -114,22 +94,19 @@ chsc_get_sch_desc_irq(int irq)
* be page-aligned. Implement proper locking or dynamic
* allocation or prove that this function does not have to be
* reentrant! */
static
struct
chsc_area
__attribute__
((
aligned
(
PAGE_SIZE
)))
chsc_area_ssd
;
static
struct
ssd_area
chsc_area_ssd
__attribute__
((
aligned
(
PAGE_SIZE
)));
typeof
(
chsc_area_ssd
.
response_block
.
response_block_data
.
ssd_res
)
*
ssd_res
=
&
chsc_area_ssd
.
response_block
.
response_block_data
.
ssd_res
;
typeof
(
chsc_area_ssd
.
response_block
)
*
ssd_res
=
&
chsc_area_ssd
.
response_block
;
chsc_area_ssd
=
(
struct
chsc
_area
)
{
chsc_area_ssd
=
(
struct
ssd
_area
)
{
.
request_block
=
{
.
command_code1
=
0x0010
,
.
command_code2
=
0x0004
,
.
request_block_data
=
{
.
ssd_req
=
{
.
f_sch
=
irq
,
.
l_sch
=
irq
,
}
}
}
};
ccode
=
chsc
(
&
chsc_area_ssd
);
...
...
@@ -306,14 +283,59 @@ s390_set_chpid_offline( __u8 chpid)
#endif
}
/* this used to be in s390_process_res_acc_*, FIXME: find a better name
* for this function */
static
int
s390_check_valid_chpid
(
u8
chpid
)
s390_process_res_acc_sch
(
u8
chpid
,
__u16
fla
,
u32
fla_mask
,
struct
subchannel
*
sch
)
{
int
found
;
int
chp
;
int
ccode
;
/* Update our ssd_info */
if
(
chsc_get_sch_desc_irq
(
sch
->
irq
))
return
0
;
found
=
0
;
for
(
chp
=
0
;
chp
<=
7
;
chp
++
)
/*
* check if chpid is in information updated by ssd
*/
if
(
sch
->
ssd_info
.
valid
&&
sch
->
ssd_info
.
chpid
[
chp
]
==
chpid
&&
(
sch
->
ssd_info
.
fla
[
chp
]
&
fla_mask
)
==
fla
)
{
found
=
1
;
break
;
}
if
(
found
==
0
)
return
0
;
/*
* Do a stsch to update our subchannel structure with the
* new path information and eventually check for logically
* offline chpids.
*/
ccode
=
stsch
(
sch
->
irq
,
&
sch
->
schib
);
if
(
ccode
>
0
)
return
0
;
return
0x80
>>
chp
;
}
static
void
s390_process_res_acc
(
u8
chpid
,
__u16
fla
,
u32
fla_mask
)
{
struct
subchannel
*
sch
;
int
irq
;
int
ret
;
char
dbf_txt
[
15
];
sprintf
(
dbf_txt
,
"accpr%x"
,
chpid
);
CIO_TRACE_EVENT
(
2
,
dbf_txt
);
if
(
fla
!=
0
)
{
sprintf
(
dbf_txt
,
"fla%x"
,
fla
);
CIO_TRACE_EVENT
(
2
,
dbf_txt
);
}
/*
* I/O resources may have become accessible.
...
...
@@ -333,31 +355,14 @@ s390_check_valid_chpid(u8 chpid)
CIO_CRW_EVENT
(
0
,
"Error: Could not retrieve "
"subchannel descriptions, will not process css"
"machine check...
\n
"
);
return
0
;
return
;
}
if
(
!
test_bit
(
chpid
,
chpids_logical
))
return
0
;
/* no need to do the rest */
return
1
;
}
static
void
s390_process_res_acc_chpid
(
u8
chpid
)
{
struct
subchannel
*
sch
;
int
irq
;
int
ccode
;
int
chp
;
int
ret
;
if
(
!
s390_check_valid_chpid
(
chpid
))
return
;
pr_debug
(
KERN_DEBUG
"Looking at chpid %x...
\n
"
,
chpid
);
return
;
/* no need to do the rest */
for
(
irq
=
0
;
irq
<=
__MAX_SUBCHANNELS
;
irq
++
)
{
int
found
;
int
chp_mask
;
sch
=
ioinfo
[
irq
];
if
(
!
sch
)
{
...
...
@@ -378,118 +383,29 @@ s390_process_res_acc_chpid (u8 chpid)
spin_lock_irq
(
&
sch
->
lock
);
/* Update our ssd_info */
if
(
chsc_get_sch_desc_irq
(
sch
->
irq
))
break
;
found
=
0
;
for
(
chp
=
0
;
chp
<=
7
;
chp
++
)
/*
* check if chpid is in information updated by ssd
*/
if
(
sch
->
ssd_info
.
valid
&&
(
sch
->
ssd_info
.
chpid
[
chp
]
==
chpid
))
{
found
=
1
;
break
;
}
chp_mask
=
s390_process_res_acc_sch
(
chpid
,
fla
,
fla_mask
,
sch
);
if
(
chp_mask
==
0
)
{
if
(
found
==
0
)
{
spin_unlock_irq
(
&
sch
->
lock
);
continue
;
}
/*
* Do a stsch to update our subchannel structure with the
* new path information and eventually check for logically
* offline chpids.
*/
ccode
=
stsch
(
sch
->
irq
,
&
sch
->
schib
);
if
(
ccode
>
0
)
{
// FIXME: ccw_device_recognition(cdev);
spin_unlock_irq
(
&
sch
->
lock
);
if
(
fla_mask
!=
0
)
break
;
else
continue
;
}
sch
->
lpm
=
sch
->
schib
.
pmcw
.
pim
&
sch
->
lpm
=
(
sch
->
schib
.
pmcw
.
pim
&
sch
->
schib
.
pmcw
.
pam
&
sch
->
schib
.
pmcw
.
pom
;
sch
->
schib
.
pmcw
.
pom
)
|
chp_mask
;
chsc_validate_chpids
(
sch
);
sch
->
lpm
|=
(
0x80
>>
chp
);
dev_fsm_event
(
sch
->
dev
.
driver_data
,
DEV_EVENT_VERIFY
);
spin_unlock_irq
(
&
sch
->
lock
);
}
}
static
void
s390_process_res_acc_linkaddr
(
__u8
chpid
,
__u16
fla
,
u32
fla_mask
)
{
char
dbf_txt
[
15
];
struct
subchannel
*
sch
;
int
irq
;
int
ccode
;
int
ret
;
int
j
;
if
(
!
s390_check_valid_chpid
(
chpid
))
return
;
sprintf
(
dbf_txt
,
"fla%x"
,
fla
);
CIO_TRACE_EVENT
(
2
,
dbf_txt
);
pr_debug
(
KERN_DEBUG
"Looking at chpid %x, link addr %x...
\n
"
,
chpid
,
fla
);
for
(
irq
=
0
;
irq
<=
__MAX_SUBCHANNELS
;
irq
++
)
{
int
found
;
sch
=
ioinfo
[
irq
];
if
(
!
sch
)
{
/* The full program again (see above), grr... */
ret
=
css_probe_device
(
irq
);
if
(
ret
==
-
ENXIO
)
/* We're through */
return
;
return
;
}
/*
* Walk through all subchannels and
* look if our chpid and our (masked) link
* address are in somewhere
* Do a stsch for the found subchannels and
* perform path grouping
*/
/* Update our ssd_info */
if
(
chsc_get_sch_desc_irq
(
sch
->
irq
))
break
;
found
=
0
;
for
(
j
=
0
;
j
<
8
;
j
++
)
if
(
sch
->
ssd_info
.
valid
&&
sch
->
ssd_info
.
chpid
[
j
]
==
chpid
&&
(
sch
->
ssd_info
.
fla
[
j
]
&
fla_mask
)
==
fla
)
{
found
=
1
;
break
;
}
if
(
found
==
0
)
continue
;
ccode
=
stsch
(
sch
->
irq
,
&
sch
->
schib
);
if
(
ccode
>
0
)
break
;
sch
->
lpm
=
sch
->
schib
.
pmcw
.
pim
&
sch
->
schib
.
pmcw
.
pam
&
sch
->
schib
.
pmcw
.
pom
;
chsc_validate_chpids
(
sch
);
sch
->
lpm
|=
(
0x80
>>
j
);
dev_fsm_event
(
sch
->
dev
.
driver_data
,
DEV_EVENT_VERIFY
);
/* We've found it, get out of here. */
if
(
fla_mask
!=
0
)
break
;
}
}
...
...
@@ -508,7 +424,7 @@ do_process_crw(void *ignore)
* be page-aligned. Implement proper locking or dynamic
* allocation or prove that this function does not have to be
* reentrant! */
static
struct
chsc
_area
chsc_area_sei
static
struct
sei
_area
chsc_area_sei
__attribute__
((
aligned
(
PAGE_SIZE
)))
=
{
.
request_block
=
{
.
command_code1
=
0x0010
,
...
...
@@ -516,8 +432,8 @@ do_process_crw(void *ignore)
}
};
typeof
(
chsc_area_sei
.
response_block
.
response_block_data
.
sei_res
)
*
sei_res
=
&
chsc_area_sei
.
response_block
.
response_block_data
.
sei_res
;
typeof
(
chsc_area_sei
.
response_block
)
*
sei_res
=
&
chsc_area_sei
.
response_block
;
CIO_TRACE_EVENT
(
2
,
"prcss"
);
...
...
@@ -582,17 +498,17 @@ do_process_crw(void *ignore)
if
((
sei_res
->
vf
&
0x80
)
==
0
)
{
pr_debug
(
KERN_DEBUG
"chpid: %x
\n
"
,
sei_res
->
rsid
);
s390_process_res_acc
_chpid
(
sei_res
->
rsid
);
s390_process_res_acc
(
sei_res
->
rsid
,
0
,
0
);
}
else
if
((
sei_res
->
vf
&
0xc0
)
==
0x80
)
{
pr_debug
(
KERN_DEBUG
"chpid: %x link addr: %x
\n
"
,
sei_res
->
rsid
,
sei_res
->
fla
);
s390_process_res_acc
_linkaddr
(
sei_res
->
rsid
,
sei_res
->
fla
,
0xff00
);
s390_process_res_acc
(
sei_res
->
rsid
,
sei_res
->
fla
,
0xff00
);
}
else
if
((
sei_res
->
vf
&
0xc0
)
==
0xc0
)
{
pr_debug
(
KERN_DEBUG
"chpid: %x full link addr: %x
\n
"
,
sei_res
->
rsid
,
sei_res
->
fla
);
s390_process_res_acc
_linkaddr
(
sei_res
->
rsid
,
sei_res
->
fla
,
0xffff
);
s390_process_res_acc
(
sei_res
->
rsid
,
sei_res
->
fla
,
0xffff
);
}
pr_debug
(
KERN_DEBUG
"
\n
"
);
...
...
@@ -810,4 +726,3 @@ register_channel_paths(void)
}
module_init
(
register_channel_paths
);
EXPORT_SYMBOL
(
chsc
);
drivers/s390/cio/chsc.h
View file @
86a7dc29
...
...
@@ -12,6 +12,86 @@
#define CHSC_SEI_ACC_LINKADDR 2
#define CHSC_SEI_ACC_FULLLINKADDR 3
struct
sei_area
{
struct
{
/* word 0 */
__u16
command_code1
;
__u16
command_code2
;
/* word 1 */
__u32
reserved1
;
/* word 2 */
__u32
reserved2
;
/* word 3 */
__u32
reserved3
;
}
__attribute__
((
packed
,
aligned
(
8
)))
request_block
;
struct
{
/* word 0 */
__u16
length
;
__u16
response_code
;
/* word 1 */
__u32
reserved1
;
/* word 2 */
__u8
flags
;
__u8
vf
;
/* validity flags */
__u8
rs
;
/* reporting source */
__u8
cc
;
/* content code */
/* word 3 */
__u16
fla
;
/* full link address */
__u16
rsid
;
/* reporting source id */
/* word 4 */
__u32
reserved2
;
/* word 5 */
__u32
reserved3
;
/* word 6 */
__u32
ccdf
;
/* content-code dependent field */
/* word 7 */
__u32
reserved4
;
/* word 8 */
__u32
reserved5
;
/* word 9 */
__u32
reserved6
;
}
__attribute__
((
packed
,
aligned
(
8
)))
response_block
;
}
__attribute__
((
packed
,
aligned
(
PAGE_SIZE
)));
struct
ssd_area
{
struct
{
/* word 0 */
__u16
command_code1
;
__u16
command_code2
;
/* word 1 */
__u16
reserved1
;
__u16
f_sch
;
/* first subchannel */
/* word 2 */
__u16
reserved2
;
__u16
l_sch
;
/* last subchannel */
/* word 3 */
__u32
reserved3
;
}
__attribute__
((
packed
,
aligned
(
8
)))
request_block
;
struct
{
/* word 0 */
__u16
length
;
__u16
response_code
;
/* word 1 */
__u32
reserved1
;
/* word 2 */
__u8
sch_valid
:
1
;
__u8
dev_valid
:
1
;
__u8
st
:
3
;
/* subchannel type */
__u8
zeroes
:
3
;
__u8
unit_addr
;
/* unit address */
__u16
devno
;
/* device number */
/* word 3 */
__u8
path_mask
;
__u8
fla_valid_mask
;
__u16
sch
;
/* subchannel */
/* words 4-5 */
__u8
chpid
[
8
];
/* chpids 0-7 */
/* words 6-9 */
__u16
fla
[
8
];
/* full link addresses 0-7 */
}
__attribute__
((
packed
,
aligned
(
8
)))
response_block
;
}
__attribute__
((
packed
,
aligned
(
PAGE_SIZE
)));
struct
channel_path
{
int
id
;
int
state
;
...
...
drivers/s390/cio/cio.c
View file @
86a7dc29
/*
* drivers/s390/cio/cio.c
* S/390 common I/O routines -- low level i/o calls
* $Revision: 1.
89
$
* $Revision: 1.
90
$
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
...
...
@@ -609,6 +609,7 @@ do_IRQ (struct pt_regs regs)
struct
subchannel
*
sch
;
struct
irb
*
irb
;
irq_enter
();
/*
* Get interrupt information from lowcore
*/
...
...
@@ -620,28 +621,23 @@ do_IRQ (struct pt_regs regs)
*/
if
(
tpi_info
->
adapter_IO
==
1
&&
tpi_info
->
int_type
==
IO_INTERRUPT_TYPE
)
{
irq_enter
();
do_adapter_IO
(
tpi_info
->
intparm
);
irq_exit
();
continue
;
}
/* Store interrupt response block to lowcore. */
if
(
tsch
(
tpi_info
->
irq
,
irb
)
!=
0
)
/* Not status pending or not operational. */
continue
;
sch
=
ioinfo
[
tpi_info
->
irq
];
if
(
!
sch
)
continue
;
irq_enter
();
if
(
sch
)
spin_lock
(
&
sch
->
lock
);
memcpy
(
&
sch
->
schib
.
scsw
,
&
irb
->
scsw
,
sizeof
(
irb
->
scsw
));
/* Store interrupt response block to lowcore. */
if
(
tsch
(
tpi_info
->
irq
,
irb
)
==
0
&&
sch
)
{
/* Keep subchannel information word up to date. */
memcpy
(
&
sch
->
schib
.
scsw
,
&
irb
->
scsw
,
sizeof
(
irb
->
scsw
));
/* Call interrupt handler if there is one. */
if
(
sch
->
driver
&&
sch
->
driver
->
irq
)
sch
->
driver
->
irq
(
&
sch
->
dev
);
}
if
(
sch
)
spin_unlock
(
&
sch
->
lock
);
irq_exit
();
/*
* Are more interrupts pending?
* If so, the tpi instruction will update the lowcore
...
...
@@ -650,6 +646,7 @@ do_IRQ (struct pt_regs regs)
* out of the sie which costs more cycles than it saves.
*/
}
while
(
!
MACHINE_IS_VM
&&
tpi
(
NULL
)
!=
0
);
irq_exit
();
}
#ifdef CONFIG_CCW_CONSOLE
...
...
drivers/s390/cio/cio.h
View file @
86a7dc29
...
...
@@ -113,7 +113,6 @@ struct subchannel {
#define to_subchannel(n) container_of(n, struct subchannel, dev)
extern
int
cio_validate_subchannel
(
struct
subchannel
*
,
unsigned
int
);
extern
int
cio_modify
(
struct
subchannel
*
);
extern
int
cio_enable_subchannel
(
struct
subchannel
*
,
unsigned
int
);
extern
int
cio_disable_subchannel
(
struct
subchannel
*
);
extern
int
cio_cancel
(
struct
subchannel
*
);
...
...
@@ -127,7 +126,6 @@ extern int cio_set_options (struct subchannel *, int);
extern
int
cio_get_options
(
struct
subchannel
*
);
/* Use with care. */
extern
int
cio_tpi
(
void
);
extern
struct
subchannel
*
cio_probe_console
(
void
);
extern
void
cio_release_console
(
void
);
...
...
drivers/s390/cio/css.c
View file @
86a7dc29
/*
* drivers/s390/cio/css.c
* driver for channel subsystem
* $Revision: 1.
39
$
* $Revision: 1.
40
$
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
...
...
@@ -20,6 +20,7 @@
#include "cio.h"
#include "cio_debug.h"
#include "device.h" // FIXME: dito
#include "ioasm.h"
struct
subchannel
*
ioinfo
[
__MAX_SUBCHANNELS
];
unsigned
int
highest_subchannel
;
...
...
@@ -154,6 +155,7 @@ css_process_crw(int irq)
{
static
DECLARE_WORK
(
work
,
do_process_crw
,
0
);
struct
subchannel
*
sch
;
int
ccode
,
devno
;
CIO_CRW_EVENT
(
2
,
"source is subchannel %04X
\n
"
,
irq
);
...
...
@@ -164,9 +166,13 @@ css_process_crw(int irq)
}
if
(
!
sch
->
dev
.
driver_data
)
return
;
devno
=
sch
->
schib
.
pmcw
.
dev
;
/* FIXME: css_process_crw must not know about ccw_device */
dev_fsm_event
(
sch
->
dev
.
driver_data
,
DEV_EVENT_NOTOPER
);
// FIXME: revalidate machine checks?
ccode
=
stsch
(
irq
,
&
sch
->
schib
);
if
(
!
ccode
)
if
(
devno
!=
sch
->
schib
.
pmcw
.
dev
)
schedule_work
(
&
work
);
}
/*
...
...
drivers/s390/cio/device.c
View file @
86a7dc29
/*
* drivers/s390/cio/device.c
* bus driver for ccw devices
* $Revision: 1.4
4
$
* $Revision: 1.4
5
$
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
...
...
@@ -362,18 +362,28 @@ io_subchannel_register(void *data)
sch
->
dev
.
driver_data
=
0
;
kfree
(
cdev
->
private
);
kfree
(
cdev
);
return
;
goto
out
;
}
ret
=
subchannel_add_files
(
cdev
->
dev
.
parent
);
if
(
ret
)
printk
(
KERN_WARNING
"%s: could not add attributes to %04x
\n
"
,
__func__
,
sch
->
irq
);
out:
put_device
(
&
sch
->
dev
);
}
static
void
io_subchannel_recog
(
struct
ccw_device
*
cdev
,
struct
subchannel
*
sch
)
{
int
rc
;
if
(
!
get_device
(
&
sch
->
dev
))
{
if
(
cdev
->
dev
.
release
)
cdev
->
dev
.
release
(
&
cdev
->
dev
);
return
;
}
sch
->
dev
.
driver_data
=
cdev
;
sch
->
driver
=
&
io_subchannel_driver
;
cdev
->
ccwlock
=
&
sch
->
lock
;
...
...
@@ -392,12 +402,17 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
/* Do first half of device_register. */
device_initialize
(
&
cdev
->
dev
);
get_device
(
&
sch
->
dev
);
/* keep parent refcount in sync. */
/* Start async. device sensing. */
spin_lock_irq
(
cdev
->
ccwlock
);
ccw_device_recognition
(
cdev
);
rc
=
ccw_device_recognition
(
cdev
);
spin_unlock_irq
(
cdev
->
ccwlock
);
if
(
rc
)
{
sch
->
dev
.
driver_data
=
0
;
put_device
(
&
sch
->
dev
);
if
(
cdev
->
dev
.
release
)
cdev
->
dev
.
release
(
&
cdev
->
dev
);
}
}
static
int
...
...
drivers/s390/cio/device_fsm.c
View file @
86a7dc29
...
...
@@ -112,7 +112,10 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
CIO_DEBUG
(
KERN_WARNING
,
2
,
"SenseID : unknown device %04X on subchannel %04X
\n
"
,
sch
->
schib
.
pmcw
.
dev
,
sch
->
irq
);
device_unregister
(
&
cdev
->
dev
);
sch
->
dev
.
driver_data
=
0
;
put_device
(
&
sch
->
dev
);
if
(
cdev
->
dev
.
release
)
cdev
->
dev
.
release
(
&
cdev
->
dev
);
break
;
case
DEV_STATE_OFFLINE
:
/* fill out sense information */
...
...
@@ -235,10 +238,8 @@ ccw_device_done(struct ccw_device *cdev, int state)
sch
=
to_subchannel
(
cdev
->
dev
.
parent
);
if
(
state
!=
DEV_STATE_ONLINE
)
{
if
(
state
!=
DEV_STATE_ONLINE
)
cio_disable_subchannel
(
sch
);
device_unregister
(
&
cdev
->
dev
);
}
/* Reset device status. */
memset
(
&
cdev
->
private
->
irb
,
0
,
sizeof
(
struct
irb
));
...
...
@@ -246,6 +247,9 @@ ccw_device_done(struct ccw_device *cdev, int state)
cdev
->
private
->
state
=
state
;
wake_up
(
&
cdev
->
private
->
wait_q
);
if
(
state
!=
DEV_STATE_ONLINE
)
put_device
(
&
cdev
->
dev
);
}
void
...
...
@@ -275,6 +279,8 @@ ccw_device_online(struct ccw_device *cdev)
if
(
cdev
->
private
->
state
!=
DEV_STATE_OFFLINE
)
return
-
EINVAL
;
sch
=
to_subchannel
(
cdev
->
dev
.
parent
);
if
(
!
get_device
(
&
cdev
->
dev
))
return
-
ENODEV
;
if
(
cio_enable_subchannel
(
sch
,
sch
->
schib
.
pmcw
.
isc
)
!=
0
)
{
/* Couldn't enable the subchannel for i/o. Sick device. */
dev_fsm_event
(
cdev
,
DEV_EVENT_NOTOPER
);
...
...
@@ -683,19 +689,19 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
[
DEV_EVENT_NOTOPER
]
ccw_device_online_notoper
,
[
DEV_EVENT_INTERRUPT
]
ccw_device_qdio_init_irq
,
[
DEV_EVENT_TIMEOUT
]
ccw_device_qdio_init_timeout
,
[
DEV_EVENT_VERIFY
]
ccw_device_nop
,
//FIXME
[
DEV_EVENT_VERIFY
]
ccw_device_nop
,
},
[
DEV_STATE_QDIO_ACTIVE
]
{
[
DEV_EVENT_NOTOPER
]
ccw_device_online_notoper
,
[
DEV_EVENT_INTERRUPT
]
ccw_device_irq
,
[
DEV_EVENT_TIMEOUT
]
ccw_device_nop
,
[
DEV_EVENT_VERIFY
]
ccw_device_nop
,
//FIXME
[
DEV_EVENT_VERIFY
]
ccw_device_nop
,
},
[
DEV_STATE_QDIO_CLEANUP
]
{
[
DEV_EVENT_NOTOPER
]
ccw_device_online_notoper
,
[
DEV_EVENT_INTERRUPT
]
ccw_device_qdio_cleanup_irq
,
[
DEV_EVENT_TIMEOUT
]
ccw_device_qdio_cleanup_timeout
,
[
DEV_EVENT_VERIFY
]
ccw_device_nop
,
//FIXME
[
DEV_EVENT_VERIFY
]
ccw_device_nop
,
},
/* states to wait for i/o completion before doing something */
[
DEV_STATE_ONLINE_VERIFY
]
{
...
...
drivers/s390/cio/ioasm.h
View file @
86a7dc29
...
...
@@ -260,7 +260,7 @@ extern __inline__ int xsch(int irq)
return
ccode
;
}
extern
__inline__
int
do_
chsc
(
void
*
chsc_area
)
extern
__inline__
int
chsc
(
void
*
chsc_area
)
{
int
cc
;
...
...
drivers/s390/cio/qdio.c
View file @
86a7dc29
...
...
@@ -53,8 +53,9 @@
#include "device.h"
#include "airq.h"
#include "qdio.h"
#include "ioasm.h"
#define VERSION_QDIO_C "$Revision: 1.1
6
$"
#define VERSION_QDIO_C "$Revision: 1.1
8
$"
/****************** MODULE PARAMETER VARIABLES ********************/
MODULE_AUTHOR
(
"Utz Bacher <utz.bacher@de.ibm.com>"
);
...
...
@@ -1573,33 +1574,33 @@ qdio_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
{
struct
qdio_irq
*
irq_ptr
;
struct
qdio_q
*
q
;
int
irq
;
int
cstat
,
dstat
;
char
dbf_text
[
15
]
=
"qintXXXX"
;
char
dbf_text
[
15
];
irq
=
cdev
->
private
->
irq
;
/* FIXME: use different dbg */
cstat
=
irb
->
scsw
.
cstat
;
dstat
=
irb
->
scsw
.
dstat
;
*
((
int
*
)(
&
dbf_text
[
4
]))
=
irq
;
QDIO_DBF_HEX4
(
0
,
trace
,
dbf_text
,
QDIO_DBF_TRACE_LEN
);
QDIO_DBF_TEXT4
(
0
,
trace
,
"qint"
);
sprintf
(
dbf_text
,
"%s"
,
cdev
->
dev
.
bus_id
);
QDIO_DBF_TEXT4
(
0
,
trace
,
dbf_text
);
if
(
!
intparm
||
!
cdev
)
{
QDIO_PRINT_STUPID
(
"got unsolicited interrupt in qdio "
\
"handler,
irq 0x%x
\n
"
,
irq
);
"handler,
device %s
\n
"
,
cdev
->
dev
.
bus_id
);
return
;
}
irq_ptr
=
cdev
->
private
->
qdio_data
;
if
(
!
irq_ptr
)
{
sprintf
(
dbf_text
,
"uint%4x"
,
irq
);
QDIO_DBF_TEXT2
(
1
,
trace
,
"uint"
);
sprintf
(
dbf_text
,
"%s"
,
cdev
->
dev
.
bus_id
);
QDIO_DBF_TEXT2
(
1
,
trace
,
dbf_text
);
QDIO_PRINT_ERR
(
"received interrupt on unused
irq 0x%04x
!
\n
"
,
irq
);
QDIO_PRINT_ERR
(
"received interrupt on unused
device %s
!
\n
"
,
cdev
->
dev
.
bus_id
);
return
;
}
qdio_irq_check_sense
(
irq
,
irb
);
qdio_irq_check_sense
(
irq
_ptr
->
irq
,
irb
);
if
(
cstat
&
SCHN_STAT_PCI
)
{
qdio_handle_pci
(
irq_ptr
);
...
...
@@ -1607,21 +1608,22 @@ qdio_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
}
if
((
cstat
&~
SCHN_STAT_PCI
)
||
dstat
)
{
sprintf
(
dbf_text
,
"ick2%4x"
,
irq
);
QDIO_DBF_TEXT2
(
1
,
trace
,
"ick2"
);
sprintf
(
dbf_text
,
"%s"
,
cdev
->
dev
.
bus_id
);
QDIO_DBF_TEXT2
(
1
,
trace
,
dbf_text
);
QDIO_DBF_HEX2
(
0
,
trace
,
&
intparm
,
sizeof
(
int
));
QDIO_DBF_HEX2
(
0
,
trace
,
&
dstat
,
sizeof
(
int
));
QDIO_DBF_HEX2
(
0
,
trace
,
&
cstat
,
sizeof
(
int
));
QDIO_PRINT_ERR
(
"received check condition on activate "
\
"queues on
irq 0x%x
(cs=x%x, ds=x%x).
\n
"
,
irq
,
cstat
,
dstat
);
"queues on
device %s
(cs=x%x, ds=x%x).
\n
"
,
cdev
->
dev
.
bus_id
,
cstat
,
dstat
);
if
(
irq_ptr
->
no_input_qs
)
{
q
=
irq_ptr
->
input_qs
[
0
];
}
else
if
(
irq_ptr
->
no_output_qs
)
{
q
=
irq_ptr
->
output_qs
[
0
];
}
else
{
QDIO_PRINT_ERR
(
"oops... no queue registered
on irq
"
\
"0x%x!?
\n
"
,
irq
);
QDIO_PRINT_ERR
(
"oops... no queue registered
for
"
\
"device %s!?
\n
"
,
cdev
->
dev
.
bus_id
);
goto
omit_handler_call
;
}
q
->
handler
(
q
->
irq
,
QDIO_STATUS_ACTIVATE_CHECK_CONDITION
|
...
...
drivers/s390/misc/Makefile
deleted
100644 → 0
View file @
59db688e
#
# S/390 miscellaneous devices
#
# placeholder for stuff to come...
drivers/s390/net/ctcmain.c
View file @
86a7dc29
/*
* $Id: ctcmain.c,v 1.
29 2002/12/06 12:31:38 cohuck
Exp $
* $Id: ctcmain.c,v 1.
30 2002/12/09 13:56:20 aberg
Exp $
*
* CTC / ESCON network driver
*
...
...
@@ -36,7 +36,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* RELEASE-TAG: CTC/ESCON network driver $Revision: 1.
29
$
* RELEASE-TAG: CTC/ESCON network driver $Revision: 1.
30
$
*
*/
...
...
@@ -279,7 +279,7 @@ static void
print_banner
(
void
)
{
static
int
printed
=
0
;
char
vbuf
[]
=
"$Revision: 1.
29
$"
;
char
vbuf
[]
=
"$Revision: 1.
30
$"
;
char
*
version
=
vbuf
;
if
(
printed
)
...
...
@@ -2821,7 +2821,7 @@ ctc_remove_files(struct device *dev)
* @returns 0 on success, !0 on failure.
*/
int
static
int
ctc_probe_device
(
struct
ccwgroup_device
*
cgdev
)
{
struct
ctc_priv
*
priv
;
...
...
@@ -2864,7 +2864,7 @@ ctc_probe_device(struct ccwgroup_device *cgdev)
*
* @returns 0 on success, !0 on failure.
*/
int
static
int
ctc_new_device
(
struct
ccwgroup_device
*
cgdev
)
{
char
read_id
[
CTC_ID_SIZE
];
...
...
@@ -2941,7 +2941,7 @@ ctc_new_device(struct ccwgroup_device *cgdev)
*
* @returns 0 on success, !0 on failure.
*/
int
static
int
ctc_shutdown_device
(
struct
ccwgroup_device
*
cgdev
)
{
struct
ctc_priv
*
priv
;
...
...
@@ -2975,7 +2975,7 @@ ctc_shutdown_device(struct ccwgroup_device *cgdev)
}
int
static
int
ctc_remove_device
(
struct
ccwgroup_device
*
cgdev
)
{
struct
ctc_priv
*
priv
;
...
...
@@ -2991,7 +2991,7 @@ ctc_remove_device(struct ccwgroup_device *cgdev)
return
0
;
}
struct
ccwgroup_driver
ctc_group_driver
=
{
st
atic
st
ruct
ccwgroup_driver
ctc_group_driver
=
{
.
name
=
"ctc"
,
.
max_slaves
=
2
,
.
driver_id
=
0xC3E3C3
,
...
...
drivers/s390/net/cu3088.c
View file @
86a7dc29
/*
* $Id: cu3088.c,v 1.2
1 2002/12/03 16:26:4
5 cohuck Exp $
* $Id: cu3088.c,v 1.2
2 2002/12/10 09:53:5
5 cohuck Exp $
*
* CTC / LCS ccw_device driver
*
...
...
@@ -172,5 +172,5 @@ MODULE_LICENSE("GPL");
module_init
(
cu3088_init
);
module_exit
(
cu3088_exit
);
EXPORT_SYMBOL
(
register_cu3088_discipline
);
EXPORT_SYMBOL
(
unregister_cu3088_discipline
);
EXPORT_SYMBOL
_GPL
(
register_cu3088_discipline
);
EXPORT_SYMBOL
_GPL
(
unregister_cu3088_discipline
);
drivers/s390/net/lcs.c
View file @
86a7dc29
...
...
@@ -11,7 +11,7 @@
* Frank Pavlic (pavlic@de.ibm.com) and
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*
* $Revision: 1.4
1 $ $Date: 2002/12/06 12:42:01
$
* $Revision: 1.4
2 $ $Date: 2002/12/09 13:55:28
$
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -59,7 +59,7 @@
/**
* initialization string for output
*/
#define VERSION_LCS_C "$Revision: 1.4
1
$"
#define VERSION_LCS_C "$Revision: 1.4
2
$"
static
const
char
*
version
=
"LCS driver ("
VERSION_LCS_C
"/"
VERSION_LCS_H
")"
;
...
...
@@ -1576,7 +1576,7 @@ lcs_get_frames_cb(struct lcs_channel *channel, struct lcs_buffer *buffer)
/**
* get network statistics for ifconfig and other user programs
*/
struct
net_device_stats
*
st
atic
st
ruct
net_device_stats
*
lcs_getstats
(
struct
net_device
*
dev
)
{
struct
lcs_card
*
card
;
...
...
@@ -1590,7 +1590,7 @@ lcs_getstats(struct net_device *dev)
* stop lcs device
* This function will be called by user doing ifconfig xxx down
*/
int
static
int
lcs_stop_device
(
struct
net_device
*
dev
)
{
struct
lcs_card
*
card
;
...
...
@@ -1612,7 +1612,7 @@ lcs_stop_device(struct net_device *dev)
* start lcs device and make it runnable
* This function will be called by user doing ifconfig xxx up
*/
int
static
int
lcs_open_device
(
struct
net_device
*
dev
)
{
struct
lcs_card
*
card
;
...
...
@@ -1678,7 +1678,7 @@ static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store);
/**
* lcs_probe_device is called on establishing a new ccwgroup_device.
*/
int
static
int
lcs_probe_device
(
struct
ccwgroup_device
*
ccwgdev
)
{
struct
lcs_card
*
card
;
...
...
@@ -1714,7 +1714,7 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev)
/**
* lcs_new_device will be called by setting the group device online.
*/
int
static
int
lcs_new_device
(
struct
ccwgroup_device
*
ccwgdev
)
{
struct
lcs_card
*
card
;
...
...
@@ -1794,7 +1794,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
/**
* lcs_shutdown_device, called when setting the group device offline.
*/
int
static
int
lcs_shutdown_device
(
struct
ccwgroup_device
*
ccwgdev
)
{
struct
lcs_card
*
card
;
...
...
@@ -1810,7 +1810,7 @@ lcs_shutdown_device(struct ccwgroup_device *ccwgdev)
/**
* lcs_remove_device, free buffers and card
*/
int
static
int
lcs_remove_device
(
struct
ccwgroup_device
*
ccwgdev
)
{
struct
lcs_card
*
card
;
...
...
@@ -1828,7 +1828,7 @@ lcs_remove_device(struct ccwgroup_device *ccwgdev)
/**
* LCS ccwgroup driver registration
*/
struct
ccwgroup_driver
lcs_group_driver
=
{
st
atic
st
ruct
ccwgroup_driver
lcs_group_driver
=
{
.
name
=
"lcs"
,
.
max_slaves
=
2
,
.
driver_id
=
0xD3C3E2
,
...
...
include/asm-s390/bitops.h
View file @
86a7dc29
...
...
@@ -53,7 +53,7 @@ extern const char _sb_findmap[];
/*
* SMP save set_bit routine based on compare and swap (CS)
*/
static
inline
void
set_bit_cs
(
int
nr
,
volatile
void
*
ptr
)
static
inline
void
set_bit_cs
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -78,7 +78,7 @@ static inline void set_bit_cs(int nr, volatile void *ptr)
/*
* SMP save clear_bit routine based on compare and swap (CS)
*/
static
inline
void
clear_bit_cs
(
int
nr
,
volatile
void
*
ptr
)
static
inline
void
clear_bit_cs
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -103,7 +103,7 @@ static inline void clear_bit_cs(int nr, volatile void *ptr)
/*
* SMP save change_bit routine based on compare and swap (CS)
*/
static
inline
void
change_bit_cs
(
int
nr
,
volatile
void
*
ptr
)
static
inline
void
change_bit_cs
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -128,7 +128,8 @@ static inline void change_bit_cs(int nr, volatile void *ptr)
/*
* SMP save test_and_set_bit routine based on compare and swap (CS)
*/
static
inline
int
test_and_set_bit_cs
(
int
nr
,
volatile
void
*
ptr
)
static
inline
int
test_and_set_bit_cs
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -154,7 +155,8 @@ static inline int test_and_set_bit_cs(int nr, volatile void *ptr)
/*
* SMP save test_and_clear_bit routine based on compare and swap (CS)
*/
static
inline
int
test_and_clear_bit_cs
(
int
nr
,
volatile
void
*
ptr
)
static
inline
int
test_and_clear_bit_cs
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -180,7 +182,8 @@ static inline int test_and_clear_bit_cs(int nr, volatile void *ptr)
/*
* SMP save test_and_change_bit routine based on compare and swap (CS)
*/
static
inline
int
test_and_change_bit_cs
(
int
nr
,
volatile
void
*
ptr
)
static
inline
int
test_and_change_bit_cs
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -207,7 +210,7 @@ static inline int test_and_change_bit_cs(int nr, volatile void *ptr)
/*
* fast, non-SMP set_bit routine
*/
static
inline
void
__set_bit
(
int
nr
,
volatile
void
*
ptr
)
static
inline
void
__set_bit
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -219,7 +222,7 @@ static inline void __set_bit(int nr, volatile void *ptr)
}
static
inline
void
__constant_set_bit
(
const
int
nr
,
volatile
void
*
ptr
)
__constant_set_bit
(
const
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -269,7 +272,7 @@ __constant_set_bit(const int nr, volatile void *ptr)
* fast, non-SMP clear_bit routine
*/
static
inline
void
__clear_bit
(
int
nr
,
volatile
void
*
ptr
)
__clear_bit
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -281,7 +284,7 @@ __clear_bit(int nr, volatile void *ptr)
}
static
inline
void
__constant_clear_bit
(
const
int
nr
,
volatile
void
*
ptr
)
__constant_clear_bit
(
const
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -330,7 +333,7 @@ __constant_clear_bit(const int nr, volatile void *ptr)
/*
* fast, non-SMP change_bit routine
*/
static
inline
void
__change_bit
(
int
nr
,
volatile
void
*
ptr
)
static
inline
void
__change_bit
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -342,7 +345,7 @@ static inline void __change_bit(int nr, volatile void *ptr)
}
static
inline
void
__constant_change_bit
(
const
int
nr
,
volatile
void
*
ptr
)
__constant_change_bit
(
const
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -391,7 +394,8 @@ __constant_change_bit(const int nr, volatile void *ptr)
/*
* fast, non-SMP test_and_set_bit routine
*/
static
inline
int
test_and_set_bit_simple
(
int
nr
,
volatile
void
*
ptr
)
static
inline
int
test_and_set_bit_simple
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
unsigned
char
ch
;
...
...
@@ -409,7 +413,8 @@ static inline int test_and_set_bit_simple(int nr, volatile void *ptr)
/*
* fast, non-SMP test_and_clear_bit routine
*/
static
inline
int
test_and_clear_bit_simple
(
int
nr
,
volatile
void
*
ptr
)
static
inline
int
test_and_clear_bit_simple
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
unsigned
char
ch
;
...
...
@@ -427,7 +432,8 @@ static inline int test_and_clear_bit_simple(int nr, volatile void *ptr)
/*
* fast, non-SMP test_and_change_bit routine
*/
static
inline
int
test_and_change_bit_simple
(
int
nr
,
volatile
void
*
ptr
)
static
inline
int
test_and_change_bit_simple
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
unsigned
char
ch
;
...
...
@@ -463,7 +469,7 @@ static inline int test_and_change_bit_simple(int nr, volatile void *ptr)
* This routine doesn't need to be atomic.
*/
static
inline
int
__test_bit
(
int
nr
,
volatile
void
*
ptr
)
static
inline
int
__test_bit
(
int
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
unsigned
char
ch
;
...
...
@@ -473,7 +479,8 @@ static inline int __test_bit(int nr, volatile void *ptr)
return
(
ch
>>
(
nr
&
7
))
&
1
;
}
static
inline
int
__constant_test_bit
(
int
nr
,
volatile
void
*
addr
)
{
static
inline
int
__constant_test_bit
(
int
nr
,
volatile
unsigned
long
*
addr
)
{
return
(((
volatile
char
*
)
addr
)[(
nr
>>
3
)
^
3
]
&
(
1
<<
(
nr
&
7
)))
!=
0
;
}
...
...
@@ -485,7 +492,8 @@ static inline int __constant_test_bit(int nr, volatile void * addr) {
/*
* Find-bit routines..
*/
static
inline
int
find_first_zero_bit
(
void
*
addr
,
unsigned
size
)
static
inline
int
find_first_zero_bit
(
unsigned
long
*
addr
,
unsigned
size
)
{
unsigned
long
cmp
,
count
;
int
res
;
...
...
@@ -523,7 +531,8 @@ static inline int find_first_zero_bit(void * addr, unsigned size)
return
(
res
<
size
)
?
res
:
size
;
}
static
inline
int
find_first_bit
(
void
*
addr
,
unsigned
size
)
static
inline
int
find_first_bit
(
unsigned
long
*
addr
,
unsigned
size
)
{
unsigned
long
cmp
,
count
;
int
res
;
...
...
@@ -561,7 +570,8 @@ static inline int find_first_bit(void * addr, unsigned size)
return
(
res
<
size
)
?
res
:
size
;
}
static
inline
int
find_next_zero_bit
(
void
*
addr
,
int
size
,
int
offset
)
static
inline
int
find_next_zero_bit
(
unsigned
long
*
addr
,
int
size
,
int
offset
)
{
unsigned
long
*
p
=
((
unsigned
long
*
)
addr
)
+
(
offset
>>
5
);
unsigned
long
bitvec
,
reg
;
...
...
@@ -599,7 +609,8 @@ static inline int find_next_zero_bit (void * addr, int size, int offset)
return
(
offset
+
res
);
}
static
inline
int
find_next_bit
(
void
*
addr
,
int
size
,
int
offset
)
static
inline
int
find_next_bit
(
unsigned
long
*
addr
,
int
size
,
int
offset
)
{
unsigned
long
*
p
=
((
unsigned
long
*
)
addr
)
+
(
offset
>>
5
);
unsigned
long
bitvec
,
reg
;
...
...
@@ -668,7 +679,7 @@ static inline unsigned long ffz(unsigned long word)
* __ffs = find first bit in word. Undefined if no bit exists,
* so code should check against 0UL first..
*/
static
inline
unsigned
long
__ffs
(
unsigned
long
word
)
static
inline
unsigned
long
__ffs
(
unsigned
long
word
)
{
unsigned
long
reg
,
result
;
...
...
@@ -707,7 +718,7 @@ static inline int sched_find_first_bit(unsigned long *b)
* differs in spirit from the above ffz (man ffs).
*/
extern
in
t
inline
ffs
(
int
x
)
extern
in
line
int
ffs
(
int
x
)
{
int
r
=
1
;
...
...
@@ -792,10 +803,15 @@ extern __inline__ int fls(int x)
* 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24
*/
#define ext2_set_bit(nr, addr) test_and_set_bit((nr)^24, addr)
#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr)^24, addr)
#define ext2_test_bit(nr, addr) test_bit((nr)^24, addr)
static
inline
int
ext2_find_first_zero_bit
(
void
*
vaddr
,
unsigned
size
)
#define ext2_set_bit(nr, addr) \
test_and_set_bit((nr)^24, (unsigned long *)addr)
#define ext2_clear_bit(nr, addr) \
test_and_clear_bit((nr)^24, (unsigned long *)addr)
#define ext2_test_bit(nr, addr) \
test_bit((nr)^24, (unsigned long *)addr)
static
inline
int
ext2_find_first_zero_bit
(
void
*
vaddr
,
unsigned
size
)
{
unsigned
long
cmp
,
count
;
int
res
;
...
...
include/asm-s390/cio.h
View file @
86a7dc29
...
...
@@ -262,8 +262,6 @@ struct diag210 {
extern
int
diag210
(
struct
diag210
*
addr
);
extern
int
chsc
(
void
*
data
);
extern
void
wait_cons_dev
(
void
);
#endif
...
...
include/asm-s390/current.h
View file @
86a7dc29
...
...
@@ -13,7 +13,7 @@
#ifdef __KERNEL__
#include <
asm
/thread_info.h>
#include <
linux
/thread_info.h>
struct
task_struct
;
...
...
include/asm-s390/page.h
View file @
86a7dc29
...
...
@@ -64,7 +64,7 @@ static inline void copy_page(void *to, void *from)
#define BUG() do { \
printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
__asm__ __volatile__(".
word 0x000
0"); \
__asm__ __volatile__(".
long
0"); \
} while (0)
#define PAGE_BUG(page) do { \
...
...
include/asm-s390/posix_types.h
View file @
86a7dc29
...
...
@@ -60,13 +60,13 @@ typedef struct {
#endif
#undef __FD_SET
#define __FD_SET(fd,fdsetp) set_bit(fd,fdsetp)
#define __FD_SET(fd,fdsetp) set_bit(fd,fdsetp
->fds_bits
)
#undef __FD_CLR
#define __FD_CLR(fd,fdsetp) clear_bit(fd,fdsetp)
#define __FD_CLR(fd,fdsetp) clear_bit(fd,fdsetp
->fds_bits
)
#undef __FD_ISSET
#define __FD_ISSET(fd,fdsetp) test_bit(fd,fdsetp)
#define __FD_ISSET(fd,fdsetp) test_bit(fd,fdsetp
->fds_bits
)
#undef __FD_ZERO
#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
...
...
include/asm-s390/rwsem.h
View file @
86a7dc29
...
...
@@ -228,7 +228,7 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
:
"=&d"
(
old
),
"=&d"
(
new
)
:
"a"
(
&
sem
->
count
),
"m"
(
tmp
)
:
"cc"
,
"memory"
);
if
(
new
>
1
)
// FIXME: is this correct ?!?
if
(
new
>
1
)
rwsem_downgrade_wake
(
sem
);
}
...
...
include/asm-s390/setup.h
View file @
86a7dc29
include/asm-s390/thread_info.h
View file @
86a7dc29
...
...
@@ -26,6 +26,7 @@ struct thread_info {
unsigned
long
flags
;
/* low level flags */
unsigned
int
cpu
;
/* current CPU */
unsigned
int
preempt_count
;
/* 0 => preemptable */
struct
restart_block
restart_block
;
};
/*
...
...
@@ -33,10 +34,13 @@ struct thread_info {
*/
#define INIT_THREAD_INFO(tsk) \
{ \
task: &tsk, \
exec_domain: &default_exec_domain, \
flags: 0, \
cpu: 0, \
.task = &tsk, \
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
}
#define init_thread_info (init_thread_union.thread_info)
...
...
@@ -69,6 +73,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NOTIFY_RESUME 1
/* resumption notification requested */
#define TIF_SIGPENDING 2
/* signal pending */
#define TIF_NEED_RESCHED 3
/* rescheduling necessary */
#define TIF_RESTART_SVC 4
/* restart svc with new svc number */
#define TIF_USEDFPU 16
/* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17
/* true if poll_idle() is polling
TIF_NEED_RESCHED */
...
...
@@ -77,6 +82,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
...
...
include/asm-s390/uaccess.h
View file @
86a7dc29
...
...
@@ -84,7 +84,7 @@ extern inline int __put_user_asm_8(void *x, void *ptr)
{
int
err
;
__asm__
__volatile__
(
" sr %0,
01
\n
"
__asm__
__volatile__
(
" sr %0,
%0
\n
"
" lr 2,%1
\n
"
" lr 4,%2
\n
"
" sacf 512
\n
"
...
...
include/asm-s390/unistd.h
View file @
86a7dc29
...
...
@@ -19,6 +19,7 @@
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_restart_syscall 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
...
...
include/asm-s390x/bitops.h
View file @
86a7dc29
#ifndef _S390_BITOPS_H
#define _S390_BITOPS_H
/*
* include/asm-s390/bitops.h
*
...
...
@@ -9,9 +12,7 @@
* Copyright (C) 1992, Linus Torvalds
*
*/
#ifndef _S390_BITOPS_H
#define _S390_BITOPS_H
#include <linux/config.h>
/*
* bit 0 is the LSB of *addr; bit 63 is the MSB of *addr;
...
...
@@ -32,7 +33,6 @@
* of the form "flags |= (1 << bitnr)" are used INTERMIXED
* with operation of the form "set_bit(bitnr, flags)".
*/
#include <linux/config.h>
/* set ALIGN_CS to 1 if the SMP safe bit operations should
* align the address to 4 byte boundary. It seems to work
...
...
@@ -57,7 +57,7 @@ extern const char _sb_findmap[];
/*
* SMP save set_bit routine based on compare and swap (CS)
*/
static
inline
void
set_bit_cs
(
unsigned
long
nr
,
volatile
void
*
ptr
)
static
inline
void
set_bit_cs
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -82,7 +82,7 @@ static inline void set_bit_cs(unsigned long nr, volatile void *ptr)
/*
* SMP save clear_bit routine based on compare and swap (CS)
*/
static
inline
void
clear_bit_cs
(
unsigned
long
nr
,
volatile
void
*
ptr
)
static
inline
void
clear_bit_cs
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -107,7 +107,7 @@ static inline void clear_bit_cs(unsigned long nr, volatile void *ptr)
/*
* SMP save change_bit routine based on compare and swap (CS)
*/
static
inline
void
change_bit_cs
(
unsigned
long
nr
,
volatile
void
*
ptr
)
static
inline
void
change_bit_cs
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -133,7 +133,7 @@ static inline void change_bit_cs(unsigned long nr, volatile void *ptr)
* SMP save test_and_set_bit routine based on compare and swap (CS)
*/
static
inline
int
test_and_set_bit_cs
(
unsigned
long
nr
,
volatile
void
*
ptr
)
test_and_set_bit_cs
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -160,7 +160,7 @@ test_and_set_bit_cs(unsigned long nr, volatile void *ptr)
* SMP save test_and_clear_bit routine based on compare and swap (CS)
*/
static
inline
int
test_and_clear_bit_cs
(
unsigned
long
nr
,
volatile
void
*
ptr
)
test_and_clear_bit_cs
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -187,7 +187,7 @@ test_and_clear_bit_cs(unsigned long nr, volatile void *ptr)
* SMP save test_and_change_bit routine based on compare and swap (CS)
*/
static
inline
int
test_and_change_bit_cs
(
unsigned
long
nr
,
volatile
void
*
ptr
)
test_and_change_bit_cs
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
,
old
,
new
,
mask
;
...
...
@@ -214,7 +214,7 @@ test_and_change_bit_cs(unsigned long nr, volatile void *ptr)
/*
* fast, non-SMP set_bit routine
*/
static
inline
void
__set_bit
(
unsigned
long
nr
,
volatile
void
*
ptr
)
static
inline
void
__set_bit
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -226,7 +226,7 @@ static inline void __set_bit(unsigned long nr, volatile void *ptr)
}
static
inline
void
__constant_set_bit
(
const
unsigned
long
nr
,
volatile
void
*
ptr
)
__constant_set_bit
(
const
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -276,7 +276,7 @@ __constant_set_bit(const unsigned long nr, volatile void *ptr)
* fast, non-SMP clear_bit routine
*/
static
inline
void
__clear_bit
(
unsigned
long
nr
,
volatile
void
*
ptr
)
__clear_bit
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -288,7 +288,7 @@ __clear_bit(unsigned long nr, volatile void *ptr)
}
static
inline
void
__constant_clear_bit
(
const
unsigned
long
nr
,
volatile
void
*
ptr
)
__constant_clear_bit
(
const
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -337,7 +337,7 @@ __constant_clear_bit(const unsigned long nr, volatile void *ptr)
/*
* fast, non-SMP change_bit routine
*/
static
inline
void
__change_bit
(
unsigned
long
nr
,
volatile
void
*
ptr
)
static
inline
void
__change_bit
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -349,7 +349,7 @@ static inline void __change_bit(unsigned long nr, volatile void *ptr)
}
static
inline
void
__constant_change_bit
(
const
unsigned
long
nr
,
volatile
void
*
ptr
)
__constant_change_bit
(
const
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
...
...
@@ -399,7 +399,7 @@ __constant_change_bit(const unsigned long nr, volatile void *ptr)
* fast, non-SMP test_and_set_bit routine
*/
static
inline
int
test_and_set_bit_simple
(
unsigned
long
nr
,
volatile
void
*
ptr
)
test_and_set_bit_simple
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
unsigned
char
ch
;
...
...
@@ -418,7 +418,7 @@ test_and_set_bit_simple(unsigned long nr, volatile void *ptr)
* fast, non-SMP test_and_clear_bit routine
*/
static
inline
int
test_and_clear_bit_simple
(
unsigned
long
nr
,
volatile
void
*
ptr
)
test_and_clear_bit_simple
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
unsigned
char
ch
;
...
...
@@ -437,7 +437,7 @@ test_and_clear_bit_simple(unsigned long nr, volatile void *ptr)
* fast, non-SMP test_and_change_bit routine
*/
static
inline
int
test_and_change_bit_simple
(
unsigned
long
nr
,
volatile
void
*
ptr
)
test_and_change_bit_simple
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
unsigned
char
ch
;
...
...
@@ -473,7 +473,7 @@ test_and_change_bit_simple(unsigned long nr, volatile void *ptr)
* This routine doesn't need to be atomic.
*/
static
inline
int
__test_bit
(
unsigned
long
nr
,
volatile
void
*
ptr
)
static
inline
int
__test_bit
(
unsigned
long
nr
,
volatile
unsigned
long
*
ptr
)
{
unsigned
long
addr
;
unsigned
char
ch
;
...
...
@@ -484,7 +484,7 @@ static inline int __test_bit(unsigned long nr, volatile void *ptr)
}
static
inline
int
__constant_test_bit
(
unsigned
long
nr
,
volatile
void
*
addr
)
{
__constant_test_bit
(
unsigned
long
nr
,
volatile
unsigned
long
*
addr
)
{
return
(((
volatile
char
*
)
addr
)[(
nr
>>
3
)
^
7
]
&
(
1
<<
(
nr
&
7
)))
!=
0
;
}
...
...
@@ -497,7 +497,7 @@ __constant_test_bit(unsigned long nr, volatile void *addr) {
* Find-bit routines..
*/
static
inline
unsigned
long
find_first_zero_bit
(
void
*
addr
,
unsigned
long
size
)
find_first_zero_bit
(
unsigned
long
*
addr
,
unsigned
long
size
)
{
unsigned
long
res
,
cmp
,
count
;
...
...
@@ -539,7 +539,7 @@ find_first_zero_bit(void * addr, unsigned long size)
}
static
inline
unsigned
long
find_first_bit
(
void
*
addr
,
unsigned
long
size
)
find_first_bit
(
unsigned
long
*
addr
,
unsigned
long
size
)
{
unsigned
long
res
,
cmp
,
count
;
...
...
@@ -581,7 +581,7 @@ find_first_bit(void * addr, unsigned long size)
}
static
inline
unsigned
long
find_next_zero_bit
(
void
*
addr
,
unsigned
long
size
,
unsigned
long
offset
)
find_next_zero_bit
(
unsigned
long
*
addr
,
unsigned
long
size
,
unsigned
long
offset
)
{
unsigned
long
*
p
=
((
unsigned
long
*
)
addr
)
+
(
offset
>>
6
);
unsigned
long
bitvec
,
reg
;
...
...
@@ -625,7 +625,7 @@ find_next_zero_bit (void * addr, unsigned long size, unsigned long offset)
}
static
inline
unsigned
long
find_next_bit
(
void
*
addr
,
unsigned
long
size
,
unsigned
long
offset
)
find_next_bit
(
unsigned
long
*
addr
,
unsigned
long
size
,
unsigned
long
offset
)
{
unsigned
long
*
p
=
((
unsigned
long
*
)
addr
)
+
(
offset
>>
6
);
unsigned
long
bitvec
,
reg
;
...
...
@@ -744,7 +744,7 @@ static inline int sched_find_first_bit(unsigned long *b)
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
extern
in
t
inline
ffs
(
int
x
)
extern
in
line
int
ffs
(
int
x
)
{
int
r
=
1
;
...
...
@@ -836,9 +836,13 @@ extern __inline__ int fls(int x)
* 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24
*/
#define ext2_set_bit(nr, addr) test_and_set_bit((nr)^56, addr)
#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr)^56, addr)
#define ext2_test_bit(nr, addr) test_bit((nr)^56, addr)
#define ext2_set_bit(nr, addr) \
test_and_set_bit((nr)^56, (unsigned long *)addr)
#define ext2_clear_bit(nr, addr) \
test_and_clear_bit((nr)^56, (unsigned long *)addr)
#define ext2_test_bit(nr, addr) \
test_bit((nr)^56, (unsigned long *)addr)
static
inline
unsigned
long
ext2_find_first_zero_bit
(
void
*
vaddr
,
unsigned
long
size
)
{
...
...
include/asm-s390x/ccwgroup.h
View file @
86a7dc29
...
...
@@ -31,7 +31,7 @@ struct ccwgroup_driver {
extern
int
ccwgroup_driver_register
(
struct
ccwgroup_driver
*
cdriver
);
extern
void
ccwgroup_driver_unregister
(
struct
ccwgroup_driver
*
cdriver
);
extern
int
ccwgroup_create
_dev
(
struct
device
*
root
,
extern
int
ccwgroup_create
(
struct
device
*
root
,
unsigned
int
creator_id
,
struct
ccw_driver
*
gdrv
,
int
argc
,
char
*
argv
[]);
...
...
include/asm-s390x/cio.h
View file @
86a7dc29
...
...
@@ -262,8 +262,6 @@ struct diag210 {
extern
int
diag210
(
struct
diag210
*
addr
);
extern
int
chsc
(
void
*
data
);
extern
void
wait_cons_dev
(
void
);
#endif
...
...
include/asm-s390x/current.h
View file @
86a7dc29
...
...
@@ -13,7 +13,7 @@
#ifdef __KERNEL__
#include <
asm
/thread_info.h>
#include <
linux
/thread_info.h>
struct
task_struct
;
...
...
include/asm-s390x/posix_types.h
View file @
86a7dc29
...
...
@@ -58,13 +58,13 @@ typedef struct {
#endif
#undef __FD_SET
#define __FD_SET(fd,fdsetp) set_bit(fd,fdsetp)
#define __FD_SET(fd,fdsetp) set_bit(fd,fdsetp
->fds_bits
)
#undef __FD_CLR
#define __FD_CLR(fd,fdsetp) clear_bit(fd,fdsetp)
#define __FD_CLR(fd,fdsetp) clear_bit(fd,fdsetp
->fds_bits
)
#undef __FD_ISSET
#define __FD_ISSET(fd,fdsetp) test_bit(fd,fdsetp)
#define __FD_ISSET(fd,fdsetp) test_bit(fd,fdsetp
->fds_bits
)
#undef __FD_ZERO
#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
...
...
include/asm-s390x/rwsem.h
View file @
86a7dc29
...
...
@@ -228,7 +228,7 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
:
"=&d"
(
old
),
"=&d"
(
new
)
:
"a"
(
&
sem
->
count
),
"m"
(
tmp
)
:
"cc"
,
"memory"
);
if
(
new
>
1
)
// FIXME: is this correct ?!?
if
(
new
>
1
)
rwsem_downgrade_wake
(
sem
);
}
...
...
include/asm-s390x/thread_info.h
View file @
86a7dc29
...
...
@@ -26,6 +26,7 @@ struct thread_info {
unsigned
long
flags
;
/* low level flags */
unsigned
int
cpu
;
/* current CPU */
unsigned
int
preempt_count
;
/* 0 => preemptable */
struct
restart_block
restart_block
;
};
/*
...
...
@@ -33,10 +34,13 @@ struct thread_info {
*/
#define INIT_THREAD_INFO(tsk) \
{ \
task: &tsk, \
exec_domain: &default_exec_domain, \
flags: 0, \
cpu: 0, \
.task = &tsk, \
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
}
#define init_thread_info (init_thread_union.thread_info)
...
...
@@ -69,6 +73,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NOTIFY_RESUME 1
/* resumption notification requested */
#define TIF_SIGPENDING 2
/* signal pending */
#define TIF_NEED_RESCHED 3
/* rescheduling necessary */
#define TIF_RESTART_SVC 4
/* restart svc with new svc number */
#define TIF_USEDFPU 16
/* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17
/* true if poll_idle() is polling
TIF_NEED_RESCHED */
...
...
@@ -77,6 +82,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
...
...
include/asm-s390x/unistd.h
View file @
86a7dc29
...
...
@@ -19,6 +19,7 @@
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_restart_syscall 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
...
...
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