Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
67e2ccce
Commit
67e2ccce
authored
Feb 22, 2007
by
Ralf Baechle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[MIPS] RTLX: Handle signals when sleeping.
Signed-off-by:
Ralf Baechle
<
ralf@linux-mips.org
>
parent
cc39cb15
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
42 additions
and
80 deletions
+42
-80
arch/mips/kernel/rtlx.c
arch/mips/kernel/rtlx.c
+42
-80
No files found.
arch/mips/kernel/rtlx.c
View file @
67e2ccce
...
...
@@ -146,9 +146,9 @@ static void stopping(int vpe)
int
rtlx_open
(
int
index
,
int
can_sleep
)
{
int
ret
;
struct
rtlx_channel
*
chan
;
volatile
struct
rtlx_info
**
p
;
struct
rtlx_channel
*
chan
;
int
ret
=
0
;
if
(
index
>=
RTLX_CHANNELS
)
{
printk
(
KERN_DEBUG
"rtlx_open index out of range
\n
"
);
...
...
@@ -165,65 +165,37 @@ int rtlx_open(int index, int can_sleep)
if
(
rtlx
==
NULL
)
{
if
(
(
p
=
vpe_get_shared
(
RTLX_TARG_VPE
))
==
NULL
)
{
if
(
can_sleep
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
/* go to sleep */
add_wait_queue
(
&
channel_wqs
[
index
].
lx_queue
,
&
wait
);
set_current_state
(
TASK_INTERRUPTIBLE
);
while
((
p
=
vpe_get_shared
(
RTLX_TARG_VPE
))
==
NULL
)
{
schedule
();
set_current_state
(
TASK_INTERRUPTIBLE
);
}
int
ret
=
0
;
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
channel_wqs
[
index
].
lx_queue
,
&
wait
);
/* back running */
__wait_event_interruptible
(
channel_wqs
[
index
].
lx_queue
,
(
p
=
vpe_get_shared
(
RTLX_TARG_VPE
)),
ret
);
if
(
ret
)
goto
out_fail
;
}
else
{
printk
(
KERN_DEBUG
"No SP program loaded, and device "
"opened with O_NONBLOCK
\n
"
);
channel_wqs
[
index
].
in_open
=
0
;
return
-
ENOSYS
;
ret
=
-
ENOSYS
;
goto
out_fail
;
}
}
if
(
*
p
==
NULL
)
{
if
(
can_sleep
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
/* go to sleep */
add_wait_queue
(
&
channel_wqs
[
index
].
lx_queue
,
&
wait
);
set_current_state
(
TASK_INTERRUPTIBLE
);
while
(
*
p
==
NULL
)
{
schedule
();
int
ret
=
0
;
/* reset task state to interruptable otherwise
we'll whizz round here like a very fast loopy
thing. schedule() appears to return with state
set to TASK_RUNNING.
If the loaded SP program, for whatever reason,
doesn't set up the shared structure *p will never
become true. So whoever connected to either /dev/rt?
or if it was kspd, will then take up rather a lot of
processor cycles.
*/
set_current_state
(
TASK_INTERRUPTIBLE
);
}
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
channel_wqs
[
index
].
lx_queue
,
&
wait
);
/* back running */
}
else
{
__wait_event_interruptible
(
channel_wqs
[
index
].
lx_queue
,
*
p
!=
NULL
,
ret
);
if
(
ret
)
goto
out_fail
;
}
else
{
printk
(
" *vpe_get_shared is NULL. "
"Has an SP program been loaded?
\n
"
);
channel_wqs
[
index
].
in_open
=
0
;
return
-
ENOSYS
;
ret
=
-
ENOSYS
;
goto
out_fail
;
}
}
...
...
@@ -231,7 +203,8 @@ int rtlx_open(int index, int can_sleep)
printk
(
KERN_WARNING
"vpe_get_shared returned an invalid pointer "
"maybe an error code %d
\n
"
,
(
int
)
*
p
);
channel_wqs
[
index
].
in_open
=
0
;
return
-
ENOSYS
;
ret
=
-
ENOSYS
;
goto
out_fail
;
}
if
((
ret
=
rtlx_init
(
*
p
))
<
0
)
{
...
...
@@ -250,6 +223,11 @@ int rtlx_open(int index, int can_sleep)
chan
->
lx_state
=
RTLX_STATE_OPENED
;
channel_wqs
[
index
].
in_open
=
0
;
return
0
;
out_fail:
channel_wqs
[
index
].
in_open
--
;
return
ret
;
}
int
rtlx_release
(
int
index
)
...
...
@@ -270,30 +248,17 @@ unsigned int rtlx_read_poll(int index, int can_sleep)
/* data available to read? */
if
(
chan
->
lx_read
==
chan
->
lx_write
)
{
if
(
can_sleep
)
{
DECLARE_WAITQUEUE
(
wait
,
current
)
;
int
ret
=
0
;
/* go to sleep */
add_wait_queue
(
&
channel_wqs
[
index
].
lx_queue
,
&
wait
);
set_current_state
(
TASK_INTERRUPTIBLE
);
while
(
chan
->
lx_read
==
chan
->
lx_write
)
{
schedule
();
set_current_state
(
TASK_INTERRUPTIBLE
);
__wait_event_interruptible
(
channel_wqs
[
index
].
lx_queue
,
chan
->
lx_read
!=
chan
->
lx_write
||
sp_stopping
,
ret
);
if
(
ret
)
return
ret
;
if
(
sp_stopping
)
{
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
channel_wqs
[
index
].
lx_queue
,
&
wait
);
if
(
sp_stopping
)
return
0
;
}
}
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
channel_wqs
[
index
].
lx_queue
,
&
wait
);
/* back running */
}
else
}
else
return
0
;
}
...
...
@@ -454,25 +419,22 @@ static ssize_t file_write(struct file *file, const char __user * buffer,
{
int
minor
;
struct
rtlx_channel
*
rt
;
DECLARE_WAITQUEUE
(
wait
,
current
);
minor
=
iminor
(
file
->
f_path
.
dentry
->
d_inode
);
rt
=
&
rtlx
->
channel
[
minor
];
/* any space left... */
if
(
!
rtlx_write_poll
(
minor
))
{
int
ret
=
0
;
if
(
file
->
f_flags
&
O_NONBLOCK
)
return
-
EAGAIN
;
add_wait_queue
(
&
channel_wqs
[
minor
].
rt_queue
,
&
wait
);
set_current_state
(
TASK_INTERRUPTIBLE
);
while
(
!
rtlx_write_poll
(
minor
))
schedule
();
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
channel_wqs
[
minor
].
rt_queue
,
&
wait
);
__wait_event_interruptible
(
channel_wqs
[
minor
].
rt_queue
,
rtlx_write_poll
(
minor
),
ret
);
if
(
ret
)
return
ret
;
}
return
rtlx_write
(
minor
,
(
void
*
)
buffer
,
count
,
1
);
...
...
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