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
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