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
4cf7d905
Commit
4cf7d905
authored
Aug 29, 2002
by
Peter Wächtler
Committed by
Linus Torvalds
Aug 29, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] oss/dmabuf.c - convert cli to spinlocks
parent
5790711c
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
80 additions
and
77 deletions
+80
-77
sound/oss/dmabuf.c
sound/oss/dmabuf.c
+80
-77
No files found.
sound/oss/dmabuf.c
View file @
4cf7d905
...
@@ -199,6 +199,7 @@ static int open_dmap(struct audio_operations *adev, int mode, struct dma_buffpar
...
@@ -199,6 +199,7 @@ static int open_dmap(struct audio_operations *adev, int mode, struct dma_buffpar
return
-
EBUSY
;
return
-
EBUSY
;
}
}
dma_init_buffers
(
dmap
);
dma_init_buffers
(
dmap
);
spin_lock_init
(
&
dmap
->
lock
);
dmap
->
open_mode
=
mode
;
dmap
->
open_mode
=
mode
;
dmap
->
subdivision
=
dmap
->
underrun_count
=
0
;
dmap
->
subdivision
=
dmap
->
underrun_count
=
0
;
dmap
->
fragment_size
=
0
;
dmap
->
fragment_size
=
0
;
...
@@ -319,7 +320,7 @@ int DMAbuf_open(int dev, int mode)
...
@@ -319,7 +320,7 @@ int DMAbuf_open(int dev, int mode)
adev
->
dmap_out
->
bytes_in_use
);
adev
->
dmap_out
->
bytes_in_use
);
return
0
;
return
0
;
}
}
/* MUST not hold the spinlock */
void
DMAbuf_reset
(
int
dev
)
void
DMAbuf_reset
(
int
dev
)
{
{
if
(
audio_devs
[
dev
]
->
open_mode
&
OPEN_WRITE
)
if
(
audio_devs
[
dev
]
->
open_mode
&
OPEN_WRITE
)
...
@@ -341,15 +342,17 @@ static void dma_reset_output(int dev)
...
@@ -341,15 +342,17 @@ static void dma_reset_output(int dev)
/*
/*
* First wait until the current fragment has been played completely
* First wait until the current fragment has been played completely
*/
*/
save_flags
(
flags
);
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
cli
();
adev
->
dmap_out
->
flags
|=
DMA_SYNCING
;
adev
->
dmap_out
->
flags
|=
DMA_SYNCING
;
adev
->
dmap_out
->
underrun_count
=
0
;
adev
->
dmap_out
->
underrun_count
=
0
;
if
(
!
signal_pending
(
current
)
&&
adev
->
dmap_out
->
qlen
&&
if
(
!
signal_pending
(
current
)
&&
adev
->
dmap_out
->
qlen
&&
adev
->
dmap_out
->
underrun_count
==
0
)
adev
->
dmap_out
->
underrun_count
==
0
){
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
interruptible_sleep_on_timeout
(
&
adev
->
out_sleeper
,
interruptible_sleep_on_timeout
(
&
adev
->
out_sleeper
,
dmabuf_timeout
(
dmap
));
dmabuf_timeout
(
dmap
));
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
}
adev
->
dmap_out
->
flags
&=
~
(
DMA_SYNCING
|
DMA_ACTIVE
);
adev
->
dmap_out
->
flags
&=
~
(
DMA_SYNCING
|
DMA_ACTIVE
);
/*
/*
...
@@ -366,10 +369,10 @@ static void dma_reset_output(int dev)
...
@@ -366,10 +369,10 @@ static void dma_reset_output(int dev)
disable_dma
(
dmap
->
dma
);
disable_dma
(
dmap
->
dma
);
release_dma_lock
(
f
);
release_dma_lock
(
f
);
restore_flags
(
flags
);
dmap
->
byte_counter
=
0
;
dmap
->
byte_counter
=
0
;
reorganize_buffers
(
dev
,
adev
->
dmap_out
,
0
);
reorganize_buffers
(
dev
,
adev
->
dmap_out
,
0
);
dmap
->
qlen
=
dmap
->
qhead
=
dmap
->
qtail
=
dmap
->
user_counter
=
0
;
dmap
->
qlen
=
dmap
->
qhead
=
dmap
->
qtail
=
dmap
->
user_counter
=
0
;
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
}
}
static
void
dma_reset_input
(
int
dev
)
static
void
dma_reset_input
(
int
dev
)
...
@@ -378,20 +381,19 @@ static void dma_reset_input(int dev)
...
@@ -378,20 +381,19 @@ static void dma_reset_input(int dev)
unsigned
long
flags
;
unsigned
long
flags
;
struct
dma_buffparms
*
dmap
=
adev
->
dmap_in
;
struct
dma_buffparms
*
dmap
=
adev
->
dmap_in
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
cli
();
if
(
!
(
adev
->
flags
&
DMA_DUPLEX
)
||
!
adev
->
d
->
halt_input
)
if
(
!
(
adev
->
flags
&
DMA_DUPLEX
)
||
!
adev
->
d
->
halt_input
)
adev
->
d
->
halt_io
(
dev
);
adev
->
d
->
halt_io
(
dev
);
else
else
adev
->
d
->
halt_input
(
dev
);
adev
->
d
->
halt_input
(
dev
);
adev
->
dmap_in
->
flags
&=
~
DMA_STARTED
;
adev
->
dmap_in
->
flags
&=
~
DMA_STARTED
;
restore_flags
(
flags
);
dmap
->
qlen
=
dmap
->
qhead
=
dmap
->
qtail
=
dmap
->
user_counter
=
0
;
dmap
->
qlen
=
dmap
->
qhead
=
dmap
->
qtail
=
dmap
->
user_counter
=
0
;
dmap
->
byte_counter
=
0
;
dmap
->
byte_counter
=
0
;
reorganize_buffers
(
dev
,
adev
->
dmap_in
,
1
);
reorganize_buffers
(
dev
,
adev
->
dmap_in
,
1
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
}
}
/* MUST be called with holding the dmap->lock */
void
DMAbuf_launch_output
(
int
dev
,
struct
dma_buffparms
*
dmap
)
void
DMAbuf_launch_output
(
int
dev
,
struct
dma_buffparms
*
dmap
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
...
@@ -432,8 +434,7 @@ int DMAbuf_sync(int dev)
...
@@ -432,8 +434,7 @@ int DMAbuf_sync(int dev)
if
(
adev
->
dmap_out
->
dma_mode
==
DMODE_OUTPUT
)
{
if
(
adev
->
dmap_out
->
dma_mode
==
DMODE_OUTPUT
)
{
dmap
=
adev
->
dmap_out
;
dmap
=
adev
->
dmap_out
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
cli
();
if
(
dmap
->
qlen
>
0
&&
!
(
dmap
->
flags
&
DMA_ACTIVE
))
if
(
dmap
->
qlen
>
0
&&
!
(
dmap
->
flags
&
DMA_ACTIVE
))
DMAbuf_launch_output
(
dev
,
dmap
);
DMAbuf_launch_output
(
dev
,
dmap
);
adev
->
dmap_out
->
flags
|=
DMA_SYNCING
;
adev
->
dmap_out
->
flags
|=
DMA_SYNCING
;
...
@@ -441,31 +442,33 @@ int DMAbuf_sync(int dev)
...
@@ -441,31 +442,33 @@ int DMAbuf_sync(int dev)
while
(
!
signal_pending
(
current
)
&&
n
++
<=
adev
->
dmap_out
->
nbufs
&&
while
(
!
signal_pending
(
current
)
&&
n
++
<=
adev
->
dmap_out
->
nbufs
&&
adev
->
dmap_out
->
qlen
&&
adev
->
dmap_out
->
underrun_count
==
0
)
{
adev
->
dmap_out
->
qlen
&&
adev
->
dmap_out
->
underrun_count
==
0
)
{
long
t
=
dmabuf_timeout
(
dmap
);
long
t
=
dmabuf_timeout
(
dmap
);
t
=
interruptible_sleep_on_timeout
(
&
adev
->
out_sleeper
,
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
t
);
t
=
interruptible_sleep_on_timeout
(
&
adev
->
out_sleeper
,
t
);
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
if
(
!
t
)
{
if
(
!
t
)
{
adev
->
dmap_out
->
flags
&=
~
DMA_SYNCING
;
adev
->
dmap_out
->
flags
&=
~
DMA_SYNCING
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
return
adev
->
dmap_out
->
qlen
;
return
adev
->
dmap_out
->
qlen
;
}
}
}
}
adev
->
dmap_out
->
flags
&=
~
(
DMA_SYNCING
|
DMA_ACTIVE
);
adev
->
dmap_out
->
flags
&=
~
(
DMA_SYNCING
|
DMA_ACTIVE
);
restore_flags
(
flags
);
/*
/*
* Some devices such as GUS have huge amount of on board RAM for the
* Some devices such as GUS have huge amount of on board RAM for the
* audio data. We have to wait until the device has finished playing.
* audio data. We have to wait until the device has finished playing.
*/
*/
save_flags
(
flags
);
/* still holding the lock */
cli
();
if
(
adev
->
d
->
local_qlen
)
{
/* Device has hidden buffers */
if
(
adev
->
d
->
local_qlen
)
{
/* Device has hidden buffers */
while
(
!
signal_pending
(
current
)
&&
while
(
!
signal_pending
(
current
)
&&
adev
->
d
->
local_qlen
(
dev
))
adev
->
d
->
local_qlen
(
dev
)){
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
interruptible_sleep_on_timeout
(
&
adev
->
out_sleeper
,
interruptible_sleep_on_timeout
(
&
adev
->
out_sleeper
,
dmabuf_timeout
(
dmap
));
dmabuf_timeout
(
dmap
));
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
}
}
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
}
}
adev
->
dmap_out
->
dma_mode
=
DMODE_NONE
;
adev
->
dmap_out
->
dma_mode
=
DMODE_NONE
;
return
adev
->
dmap_out
->
qlen
;
return
adev
->
dmap_out
->
qlen
;
...
@@ -474,23 +477,26 @@ int DMAbuf_sync(int dev)
...
@@ -474,23 +477,26 @@ int DMAbuf_sync(int dev)
int
DMAbuf_release
(
int
dev
,
int
mode
)
int
DMAbuf_release
(
int
dev
,
int
mode
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
dma_buffparms
*
dmap
;
unsigned
long
flags
;
unsigned
long
flags
;
dmap
=
adev
->
dmap_out
;
if
(
adev
->
open_mode
&
OPEN_WRITE
)
if
(
adev
->
open_mode
&
OPEN_WRITE
)
adev
->
dmap_out
->
closing
=
1
;
adev
->
dmap_out
->
closing
=
1
;
if
(
adev
->
open_mode
&
OPEN_READ
)
adev
->
dmap_in
->
closing
=
1
;
if
(
adev
->
open_mode
&
OPEN_READ
){
adev
->
dmap_in
->
closing
=
1
;
dmap
=
adev
->
dmap_in
;
}
if
(
adev
->
open_mode
&
OPEN_WRITE
)
if
(
adev
->
open_mode
&
OPEN_WRITE
)
if
(
!
(
adev
->
dmap_out
->
mapping_flags
&
DMA_MAP_MAPPED
))
if
(
!
(
adev
->
dmap_out
->
mapping_flags
&
DMA_MAP_MAPPED
))
if
(
!
signal_pending
(
current
)
&&
(
adev
->
dmap_out
->
dma_mode
==
DMODE_OUTPUT
))
if
(
!
signal_pending
(
current
)
&&
(
adev
->
dmap_out
->
dma_mode
==
DMODE_OUTPUT
))
DMAbuf_sync
(
dev
);
DMAbuf_sync
(
dev
);
if
(
adev
->
dmap_out
->
dma_mode
==
DMODE_OUTPUT
)
if
(
adev
->
dmap_out
->
dma_mode
==
DMODE_OUTPUT
)
memset
(
adev
->
dmap_out
->
raw_buf
,
adev
->
dmap_out
->
neutral_byte
,
adev
->
dmap_out
->
bytes_in_use
);
memset
(
adev
->
dmap_out
->
raw_buf
,
adev
->
dmap_out
->
neutral_byte
,
adev
->
dmap_out
->
bytes_in_use
);
save_flags
(
flags
);
cli
();
DMAbuf_reset
(
dev
);
DMAbuf_reset
(
dev
);
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
adev
->
d
->
close
(
dev
);
adev
->
d
->
close
(
dev
);
if
(
adev
->
open_mode
&
OPEN_WRITE
)
if
(
adev
->
open_mode
&
OPEN_WRITE
)
...
@@ -501,10 +507,10 @@ int DMAbuf_release(int dev, int mode)
...
@@ -501,10 +507,10 @@ int DMAbuf_release(int dev, int mode)
(
adev
->
flags
&
DMA_DUPLEX
)))
(
adev
->
flags
&
DMA_DUPLEX
)))
close_dmap
(
adev
,
adev
->
dmap_in
);
close_dmap
(
adev
,
adev
->
dmap_in
);
adev
->
open_mode
=
0
;
adev
->
open_mode
=
0
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
return
0
;
return
0
;
}
}
/* called with dmap->lock dold */
int
DMAbuf_activate_recording
(
int
dev
,
struct
dma_buffparms
*
dmap
)
int
DMAbuf_activate_recording
(
int
dev
,
struct
dma_buffparms
*
dmap
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
...
@@ -515,8 +521,12 @@ int DMAbuf_activate_recording(int dev, struct dma_buffparms *dmap)
...
@@ -515,8 +521,12 @@ int DMAbuf_activate_recording(int dev, struct dma_buffparms *dmap)
if
(
!
(
adev
->
enable_bits
&
PCM_ENABLE_INPUT
))
if
(
!
(
adev
->
enable_bits
&
PCM_ENABLE_INPUT
))
return
0
;
return
0
;
if
(
dmap
->
dma_mode
==
DMODE_OUTPUT
)
{
/* Direction change */
if
(
dmap
->
dma_mode
==
DMODE_OUTPUT
)
{
/* Direction change */
unsigned
long
flags
;
/* release lock - it's not recursive */
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
DMAbuf_sync
(
dev
);
DMAbuf_sync
(
dev
);
DMAbuf_reset
(
dev
);
DMAbuf_reset
(
dev
);
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
dmap
->
dma_mode
=
DMODE_NONE
;
dmap
->
dma_mode
=
DMODE_NONE
;
}
}
if
(
!
dmap
->
dma_mode
)
{
if
(
!
dmap
->
dma_mode
)
{
...
@@ -538,7 +548,7 @@ int DMAbuf_activate_recording(int dev, struct dma_buffparms *dmap)
...
@@ -538,7 +548,7 @@ int DMAbuf_activate_recording(int dev, struct dma_buffparms *dmap)
}
}
return
0
;
return
0
;
}
}
/* aquires lock */
int
DMAbuf_getrdbuffer
(
int
dev
,
char
**
buf
,
int
*
len
,
int
dontblock
)
int
DMAbuf_getrdbuffer
(
int
dev
,
char
**
buf
,
int
*
len
,
int
dontblock
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
...
@@ -549,34 +559,36 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
...
@@ -549,34 +559,36 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
if
(
!
(
adev
->
open_mode
&
OPEN_READ
))
if
(
!
(
adev
->
open_mode
&
OPEN_READ
))
return
-
EIO
;
return
-
EIO
;
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
if
(
dmap
->
needs_reorg
)
if
(
dmap
->
needs_reorg
)
reorganize_buffers
(
dev
,
dmap
,
0
);
reorganize_buffers
(
dev
,
dmap
,
0
);
save_flags
(
flags
);
cli
();
if
(
adev
->
dmap_in
->
mapping_flags
&
DMA_MAP_MAPPED
)
{
if
(
adev
->
dmap_in
->
mapping_flags
&
DMA_MAP_MAPPED
)
{
/* printk(KERN_WARNING "Sound: Can't read from mmapped device (1)\n");*/
/* printk(KERN_WARNING "Sound: Can't read from mmapped device (1)\n");*/
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
return
-
EINVAL
;
return
-
EINVAL
;
}
else
while
(
dmap
->
qlen
<=
0
&&
n
++
<
10
)
{
}
else
while
(
dmap
->
qlen
<=
0
&&
n
++
<
10
)
{
long
timeout
=
MAX_SCHEDULE_TIMEOUT
;
long
timeout
=
MAX_SCHEDULE_TIMEOUT
;
if
(
!
(
adev
->
enable_bits
&
PCM_ENABLE_INPUT
)
||
!
adev
->
go
)
{
if
(
!
(
adev
->
enable_bits
&
PCM_ENABLE_INPUT
)
||
!
adev
->
go
)
{
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
return
-
EAGAIN
;
return
-
EAGAIN
;
}
}
if
((
err
=
DMAbuf_activate_recording
(
dev
,
dmap
))
<
0
)
{
if
((
err
=
DMAbuf_activate_recording
(
dev
,
dmap
))
<
0
)
{
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
return
err
;
return
err
;
}
}
/* Wait for the next block */
/* Wait for the next block */
if
(
dontblock
)
{
if
(
dontblock
)
{
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
return
-
EAGAIN
;
return
-
EAGAIN
;
}
}
if
((
go
=
adev
->
go
))
if
((
go
=
adev
->
go
))
timeout
=
dmabuf_timeout
(
dmap
);
timeout
=
dmabuf_timeout
(
dmap
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
timeout
=
interruptible_sleep_on_timeout
(
&
adev
->
in_sleeper
,
timeout
=
interruptible_sleep_on_timeout
(
&
adev
->
in_sleeper
,
timeout
);
timeout
);
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
if
(
!
timeout
)
{
if
(
!
timeout
)
{
/* FIXME: include device name */
/* FIXME: include device name */
err
=
-
EIO
;
err
=
-
EIO
;
...
@@ -585,7 +597,7 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
...
@@ -585,7 +597,7 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
}
else
}
else
err
=
-
EINTR
;
err
=
-
EINTR
;
}
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
if
(
dmap
->
qlen
<=
0
)
if
(
dmap
->
qlen
<=
0
)
return
err
?
err
:
-
EINTR
;
return
err
?
err
:
-
EINTR
;
...
@@ -617,7 +629,7 @@ int DMAbuf_rmchars(int dev, int buff_no, int c)
...
@@ -617,7 +629,7 @@ int DMAbuf_rmchars(int dev, int buff_no, int c)
return
0
;
return
0
;
}
}
/* MUST be called with dmap->lock hold */
int
DMAbuf_get_buffer_pointer
(
int
dev
,
struct
dma_buffparms
*
dmap
,
int
direction
)
int
DMAbuf_get_buffer_pointer
(
int
dev
,
struct
dma_buffparms
*
dmap
,
int
direction
)
{
{
/*
/*
...
@@ -626,11 +638,8 @@ int DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction
...
@@ -626,11 +638,8 @@ int DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction
*/
*/
int
pos
;
int
pos
;
unsigned
long
flags
;
unsigned
long
f
;
unsigned
long
f
;
save_flags
(
flags
);
cli
();
if
(
!
(
dmap
->
flags
&
DMA_ACTIVE
))
if
(
!
(
dmap
->
flags
&
DMA_ACTIVE
))
pos
=
0
;
pos
=
0
;
else
{
else
{
...
@@ -667,7 +676,6 @@ int DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction
...
@@ -667,7 +676,6 @@ int DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction
release_dma_lock
(
f
);
release_dma_lock
(
f
);
}
}
restore_flags
(
flags
);
/* printk( "%04x ", pos); */
/* printk( "%04x ", pos); */
return
pos
;
return
pos
;
...
@@ -698,7 +706,7 @@ void DMAbuf_start_devices(unsigned int devmask)
...
@@ -698,7 +706,7 @@ void DMAbuf_start_devices(unsigned int devmask)
adev
->
d
->
trigger
(
dev
,
adev
->
enable_bits
*
adev
->
go
);
adev
->
d
->
trigger
(
dev
,
adev
->
enable_bits
*
adev
->
go
);
}
}
}
}
/* via poll called without a lock ?*/
int
DMAbuf_space_in_queue
(
int
dev
)
int
DMAbuf_space_in_queue
(
int
dev
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
...
@@ -735,7 +743,7 @@ int DMAbuf_space_in_queue(int dev)
...
@@ -735,7 +743,7 @@ int DMAbuf_space_in_queue(int dev)
return
0
;
return
0
;
return
max
-
len
;
return
max
-
len
;
}
}
/* MUST not hold the spinlock - this function may sleep */
static
int
output_sleep
(
int
dev
,
int
dontblock
)
static
int
output_sleep
(
int
dev
,
int
dontblock
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
...
@@ -770,12 +778,11 @@ static int output_sleep(int dev, int dontblock)
...
@@ -770,12 +778,11 @@ static int output_sleep(int dev, int dontblock)
}
}
return
err
;
return
err
;
}
}
/* called with the lock held */
static
int
find_output_space
(
int
dev
,
char
**
buf
,
int
*
size
)
static
int
find_output_space
(
int
dev
,
char
**
buf
,
int
*
size
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
dma_buffparms
*
dmap
=
adev
->
dmap_out
;
struct
dma_buffparms
*
dmap
=
adev
->
dmap_out
;
unsigned
long
flags
;
unsigned
long
active_offs
;
unsigned
long
active_offs
;
long
len
,
offs
;
long
len
,
offs
;
int
maxfrags
;
int
maxfrags
;
...
@@ -784,8 +791,6 @@ static int find_output_space(int dev, char **buf, int *size)
...
@@ -784,8 +791,6 @@ static int find_output_space(int dev, char **buf, int *size)
*
buf
=
dmap
->
raw_buf
;
*
buf
=
dmap
->
raw_buf
;
if
(
!
(
maxfrags
=
DMAbuf_space_in_queue
(
dev
))
&&
!
occupied_bytes
)
if
(
!
(
maxfrags
=
DMAbuf_space_in_queue
(
dev
))
&&
!
occupied_bytes
)
return
0
;
return
0
;
save_flags
(
flags
);
cli
();
#ifdef BE_CONSERVATIVE
#ifdef BE_CONSERVATIVE
active_offs
=
dmap
->
byte_counter
+
dmap
->
qhead
*
dmap
->
fragment_size
;
active_offs
=
dmap
->
byte_counter
+
dmap
->
qhead
*
dmap
->
fragment_size
;
...
@@ -799,7 +804,6 @@ static int find_output_space(int dev, char **buf, int *size)
...
@@ -799,7 +804,6 @@ static int find_output_space(int dev, char **buf, int *size)
offs
=
(
dmap
->
user_counter
%
dmap
->
bytes_in_use
)
&
~
SAMPLE_ROUNDUP
;
offs
=
(
dmap
->
user_counter
%
dmap
->
bytes_in_use
)
&
~
SAMPLE_ROUNDUP
;
if
(
offs
<
0
||
offs
>=
dmap
->
bytes_in_use
)
{
if
(
offs
<
0
||
offs
>=
dmap
->
bytes_in_use
)
{
restore_flags
(
flags
);
printk
(
KERN_ERR
"Sound: Got unexpected offs %ld. Giving up.
\n
"
,
offs
);
printk
(
KERN_ERR
"Sound: Got unexpected offs %ld. Giving up.
\n
"
,
offs
);
printk
(
"Counter = %ld, bytes=%d
\n
"
,
dmap
->
user_counter
,
dmap
->
bytes_in_use
);
printk
(
"Counter = %ld, bytes=%d
\n
"
,
dmap
->
user_counter
,
dmap
->
bytes_in_use
);
return
0
;
return
0
;
...
@@ -811,16 +815,14 @@ static int find_output_space(int dev, char **buf, int *size)
...
@@ -811,16 +815,14 @@ static int find_output_space(int dev, char **buf, int *size)
if
((
offs
+
len
)
>
dmap
->
bytes_in_use
)
if
((
offs
+
len
)
>
dmap
->
bytes_in_use
)
len
=
dmap
->
bytes_in_use
-
offs
;
len
=
dmap
->
bytes_in_use
-
offs
;
if
(
len
<
0
)
{
if
(
len
<
0
)
{
restore_flags
(
flags
);
return
0
;
return
0
;
}
}
if
(
len
>
((
maxfrags
*
dmap
->
fragment_size
)
-
occupied_bytes
))
if
(
len
>
((
maxfrags
*
dmap
->
fragment_size
)
-
occupied_bytes
))
len
=
(
maxfrags
*
dmap
->
fragment_size
)
-
occupied_bytes
;
len
=
(
maxfrags
*
dmap
->
fragment_size
)
-
occupied_bytes
;
*
size
=
len
&
~
SAMPLE_ROUNDUP
;
*
size
=
len
&
~
SAMPLE_ROUNDUP
;
restore_flags
(
flags
);
return
(
*
size
>
0
);
return
(
*
size
>
0
);
}
}
/* aquires lock */
int
DMAbuf_getwrbuffer
(
int
dev
,
char
**
buf
,
int
*
size
,
int
dontblock
)
int
DMAbuf_getwrbuffer
(
int
dev
,
char
**
buf
,
int
*
size
,
int
dontblock
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
...
@@ -828,39 +830,45 @@ int DMAbuf_getwrbuffer(int dev, char **buf, int *size, int dontblock)
...
@@ -828,39 +830,45 @@ int DMAbuf_getwrbuffer(int dev, char **buf, int *size, int dontblock)
int
err
=
-
EIO
;
int
err
=
-
EIO
;
struct
dma_buffparms
*
dmap
=
adev
->
dmap_out
;
struct
dma_buffparms
*
dmap
=
adev
->
dmap_out
;
if
(
dmap
->
needs_reorg
)
reorganize_buffers
(
dev
,
dmap
,
0
);
if
(
dmap
->
mapping_flags
&
DMA_MAP_MAPPED
)
{
if
(
dmap
->
mapping_flags
&
DMA_MAP_MAPPED
)
{
/* printk(KERN_DEBUG "Sound: Can't write to mmapped device (3)\n");*/
/* printk(KERN_DEBUG "Sound: Can't write to mmapped device (3)\n");*/
return
-
EINVAL
;
return
-
EINVAL
;
}
}
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
if
(
dmap
->
needs_reorg
)
reorganize_buffers
(
dev
,
dmap
,
0
);
if
(
dmap
->
dma_mode
==
DMODE_INPUT
)
{
/* Direction change */
if
(
dmap
->
dma_mode
==
DMODE_INPUT
)
{
/* Direction change */
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
DMAbuf_reset
(
dev
);
DMAbuf_reset
(
dev
);
dmap
->
dma_mode
=
DMODE_NONE
;
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
)
;
}
}
dmap
->
dma_mode
=
DMODE_OUTPUT
;
dmap
->
dma_mode
=
DMODE_OUTPUT
;
save_flags
(
flags
);
cli
();
while
(
find_output_space
(
dev
,
buf
,
size
)
<=
0
)
{
while
(
find_output_space
(
dev
,
buf
,
size
)
<=
0
)
{
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
if
((
err
=
output_sleep
(
dev
,
dontblock
))
<
0
)
{
if
((
err
=
output_sleep
(
dev
,
dontblock
))
<
0
)
{
restore_flags
(
flags
);
return
err
;
return
err
;
}
}
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
}
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
return
0
;
return
0
;
}
}
/* has to aquire dmap->lock */
int
DMAbuf_move_wrpointer
(
int
dev
,
int
l
)
int
DMAbuf_move_wrpointer
(
int
dev
,
int
l
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
dma_buffparms
*
dmap
=
adev
->
dmap_out
;
struct
dma_buffparms
*
dmap
=
adev
->
dmap_out
;
unsigned
long
ptr
=
(
dmap
->
user_counter
/
dmap
->
fragment_size
)
*
dmap
->
fragment_size
;
unsigned
long
ptr
;
unsigned
long
end_ptr
,
p
;
unsigned
long
end_ptr
,
p
;
int
post
=
(
dmap
->
flags
&
DMA_POST
);
int
post
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
post
=
(
dmap
->
flags
&
DMA_POST
);
ptr
=
(
dmap
->
user_counter
/
dmap
->
fragment_size
)
*
dmap
->
fragment_size
;
dmap
->
flags
&=
~
DMA_POST
;
dmap
->
flags
&=
~
DMA_POST
;
dmap
->
cfrag
=
-
1
;
dmap
->
cfrag
=
-
1
;
...
@@ -890,7 +898,7 @@ int DMAbuf_move_wrpointer(int dev, int l)
...
@@ -890,7 +898,7 @@ int DMAbuf_move_wrpointer(int dev, int l)
dmap
->
counts
[
dmap
->
qtail
]
=
dmap
->
user_counter
-
ptr
;
dmap
->
counts
[
dmap
->
qtail
]
=
dmap
->
user_counter
-
ptr
;
/*
/*
* Let the low level driver
to
perform some postprocessing to
* Let the low level driver perform some postprocessing to
* the written data.
* the written data.
*/
*/
if
(
adev
->
d
->
postprocess_write
)
if
(
adev
->
d
->
postprocess_write
)
...
@@ -899,6 +907,8 @@ int DMAbuf_move_wrpointer(int dev, int l)
...
@@ -899,6 +907,8 @@ int DMAbuf_move_wrpointer(int dev, int l)
if
(
!
(
dmap
->
flags
&
DMA_ACTIVE
))
if
(
!
(
dmap
->
flags
&
DMA_ACTIVE
))
if
(
dmap
->
qlen
>
1
||
(
dmap
->
qlen
>
0
&&
(
post
||
dmap
->
qlen
>=
dmap
->
nbufs
-
1
)))
if
(
dmap
->
qlen
>
1
||
(
dmap
->
qlen
>
0
&&
(
post
||
dmap
->
qlen
>=
dmap
->
nbufs
-
1
)))
DMAbuf_launch_output
(
dev
,
dmap
);
DMAbuf_launch_output
(
dev
,
dmap
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
return
0
;
return
0
;
}
}
...
@@ -945,11 +955,10 @@ static void finish_output_interrupt(int dev, struct dma_buffparms *dmap)
...
@@ -945,11 +955,10 @@ static void finish_output_interrupt(int dev, struct dma_buffparms *dmap)
wake_up
(
&
adev
->
out_sleeper
);
wake_up
(
&
adev
->
out_sleeper
);
wake_up
(
&
adev
->
poll_sleeper
);
wake_up
(
&
adev
->
poll_sleeper
);
}
}
/* called with dmap->lock held in irq context*/
static
void
do_outputintr
(
int
dev
,
int
dummy
)
static
void
do_outputintr
(
int
dev
,
int
dummy
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
unsigned
long
flags
;
struct
dma_buffparms
*
dmap
=
adev
->
dmap_out
;
struct
dma_buffparms
*
dmap
=
adev
->
dmap_out
;
int
this_fragment
;
int
this_fragment
;
...
@@ -977,8 +986,6 @@ static void do_outputintr(int dev, int dummy)
...
@@ -977,8 +986,6 @@ static void do_outputintr(int dev, int dummy)
finish_output_interrupt
(
dev
,
dmap
);
finish_output_interrupt
(
dev
,
dmap
);
return
;
return
;
}
}
save_flags
(
flags
);
cli
();
dmap
->
qlen
--
;
dmap
->
qlen
--
;
this_fragment
=
dmap
->
qhead
;
this_fragment
=
dmap
->
qhead
;
...
@@ -1014,18 +1021,16 @@ static void do_outputintr(int dev, int dummy)
...
@@ -1014,18 +1021,16 @@ static void do_outputintr(int dev, int dummy)
}
}
if
(
dmap
->
qlen
>
0
)
if
(
dmap
->
qlen
>
0
)
DMAbuf_launch_output
(
dev
,
dmap
);
DMAbuf_launch_output
(
dev
,
dmap
);
restore_flags
(
flags
);
finish_output_interrupt
(
dev
,
dmap
);
finish_output_interrupt
(
dev
,
dmap
);
}
}
/* called in irq context */
void
DMAbuf_outputintr
(
int
dev
,
int
notify_only
)
void
DMAbuf_outputintr
(
int
dev
,
int
notify_only
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
unsigned
long
flags
;
unsigned
long
flags
;
struct
dma_buffparms
*
dmap
=
adev
->
dmap_out
;
struct
dma_buffparms
*
dmap
=
adev
->
dmap_out
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
cli
();
if
(
!
(
dmap
->
flags
&
DMA_NODMA
))
{
if
(
!
(
dmap
->
flags
&
DMA_NODMA
))
{
int
chan
=
dmap
->
dma
,
pos
,
n
;
int
chan
=
dmap
->
dma
,
pos
,
n
;
unsigned
long
f
;
unsigned
long
f
;
...
@@ -1049,9 +1054,9 @@ void DMAbuf_outputintr(int dev, int notify_only)
...
@@ -1049,9 +1054,9 @@ void DMAbuf_outputintr(int dev, int notify_only)
}
}
else
else
do_outputintr
(
dev
,
notify_only
);
do_outputintr
(
dev
,
notify_only
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
}
}
/* called with dmap->lock held in irq context */
static
void
do_inputintr
(
int
dev
)
static
void
do_inputintr
(
int
dev
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
...
@@ -1117,15 +1122,14 @@ static void do_inputintr(int dev)
...
@@ -1117,15 +1122,14 @@ static void do_inputintr(int dev)
wake_up
(
&
adev
->
poll_sleeper
);
wake_up
(
&
adev
->
poll_sleeper
);
}
}
}
}
/* called in irq context */
void
DMAbuf_inputintr
(
int
dev
)
void
DMAbuf_inputintr
(
int
dev
)
{
{
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
audio_operations
*
adev
=
audio_devs
[
dev
];
struct
dma_buffparms
*
dmap
=
adev
->
dmap_in
;
struct
dma_buffparms
*
dmap
=
adev
->
dmap_in
;
unsigned
long
flags
;
unsigned
long
flags
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
cli
();
if
(
!
(
dmap
->
flags
&
DMA_NODMA
))
{
if
(
!
(
dmap
->
flags
&
DMA_NODMA
))
{
int
chan
=
dmap
->
dma
,
pos
,
n
;
int
chan
=
dmap
->
dma
,
pos
,
n
;
...
@@ -1149,7 +1153,7 @@ void DMAbuf_inputintr(int dev)
...
@@ -1149,7 +1153,7 @@ void DMAbuf_inputintr(int dev)
do_inputintr
(
dev
);
do_inputintr
(
dev
);
}
else
}
else
do_inputintr
(
dev
);
do_inputintr
(
dev
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
}
}
int
DMAbuf_open_dma
(
int
dev
)
int
DMAbuf_open_dma
(
int
dev
)
...
@@ -1240,10 +1244,9 @@ static unsigned int poll_input(struct file * file, int dev, poll_table *wait)
...
@@ -1240,10 +1244,9 @@ static unsigned int poll_input(struct file * file, int dev, poll_table *wait)
!
dmap
->
qlen
&&
adev
->
go
)
{
!
dmap
->
qlen
&&
adev
->
go
)
{
unsigned
long
flags
;
unsigned
long
flags
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
dmap
->
lock
,
flags
);
cli
();
DMAbuf_activate_recording
(
dev
,
dmap
);
DMAbuf_activate_recording
(
dev
,
dmap
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
dmap
->
lock
,
flags
);
}
}
return
0
;
return
0
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment