Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
eafd7e5e
提交
eafd7e5e
authored
12月 14, 2010
作者:
Giovanni Maruzzelli
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
skypopen: tweaking the OSS audio driver
上级
1d668e25
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
110 行增加
和
126 行删除
+110
-126
Makefile
src/mod/endpoints/mod_skypopen/oss/Makefile
+3
-3
main.c
src/mod/endpoints/mod_skypopen/oss/main.c
+90
-100
skypopen.h
src/mod/endpoints/mod_skypopen/oss/skypopen.h
+17
-23
没有找到文件。
src/mod/endpoints/mod_skypopen/oss/Makefile
浏览文件 @
eafd7e5e
...
...
@@ -4,7 +4,7 @@
# Add your debugging flag (or not) to CFLAGS
ifeq
($(DEBUG),y)
DEBFLAGS
=
-O
-g
-DS
CULL
_DEBUG
# "-O" is needed to expand inlines
DEBFLAGS
=
-O
-g
-DS
KYPOPEN
_DEBUG
# "-O" is needed to expand inlines
else
DEBFLAGS
=
-O2
-Wall
endif
...
...
@@ -15,9 +15,9 @@ EXTRA_CFLAGS += -I$(LDDINC)
ifneq
($(KERNELRELEASE),)
# call from kernel build system
s
cull
-objs
:=
main.o
s
kypopen
-objs
:=
main.o
obj-m
:=
s
cull
.o
obj-m
:=
s
kypopen
.o
else
...
...
src/mod/endpoints/mod_skypopen/oss/main.c
浏览文件 @
eafd7e5e
/*
* main.c -- the bare s
cull
char module
* main.c -- the bare s
kypopen
char module
*
* Copyright (C) 2010 Giovanni Maruzzelli
* Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
...
...
@@ -41,33 +41,32 @@
#include <linux/hrtimer.h>
#include <linux/ktime.h>
#include "s
cull
.h"
/* local definitions */
#include "s
kypopen
.h"
/* local definitions */
/*
* Our parameters which can be set at load time.
*/
int
s
cull_major
=
SCULL
_MAJOR
;
int
s
cull
_minor
=
3
;
int
s
cull_nr_devs
=
SCULL_NR_DEVS
;
/* number of bare scull
devices */
int
s
kypopen_major
=
SKYPOPEN
_MAJOR
;
int
s
kypopen
_minor
=
3
;
int
s
kypopen_nr_devs
=
SKYPOPEN_NR_DEVS
;
/* number of bare skypopen
devices */
module_param
(
s
cull
_major
,
int
,
S_IRUGO
);
module_param
(
s
cull
_minor
,
int
,
S_IRUGO
);
module_param
(
s
cull
_nr_devs
,
int
,
S_IRUGO
);
module_param
(
s
kypopen
_major
,
int
,
S_IRUGO
);
module_param
(
s
kypopen
_minor
,
int
,
S_IRUGO
);
module_param
(
s
kypopen
_nr_devs
,
int
,
S_IRUGO
);
MODULE_AUTHOR
(
"Original: Alessandro Rubini, Jonathan Corbet.
Heavy modified by: Giovanni Maruzzelli
"
);
MODULE_AUTHOR
(
"Original: Alessandro Rubini, Jonathan Corbet.
Modified by: Giovanni Maruzzelli for FreeSWITCH skypopen
"
);
MODULE_LICENSE
(
"Dual BSD/GPL"
);
static
struct
s
cull_dev
*
scull_devices
;
/* allocated in scull
_init_module */
static
struct
s
kypopen_dev
*
skypopen_devices
;
/* allocated in skypopen
_init_module */
#define GIOVA_BLK 1920
#define GIOVA_SLEEP 20
void
my_timer_callback_inq
(
unsigned
long
data
)
{
struct
s
cull
_dev
*
dev
=
(
void
*
)
data
;
struct
s
kypopen
_dev
*
dev
=
(
void
*
)
data
;
//dev->readable=1;
wake_up_interruptible
(
&
dev
->
inq
);
mod_timer
(
&
dev
->
timer_inq
,
jiffies
+
msecs_to_jiffies
(
GIOVA_SLEEP
)
);
...
...
@@ -75,83 +74,83 @@ void my_timer_callback_inq( unsigned long data )
void
my_timer_callback_outq
(
unsigned
long
data
)
{
struct
s
cull
_dev
*
dev
=
(
void
*
)
data
;
struct
s
kypopen
_dev
*
dev
=
(
void
*
)
data
;
//dev->writable=1;
wake_up_interruptible
(
&
dev
->
outq
);
mod_timer
(
&
dev
->
timer_outq
,
jiffies
+
msecs_to_jiffies
(
GIOVA_SLEEP
)
);
}
/* The clone-specific data structure includes a key field */
struct
s
cull
_listitem
{
struct
s
cull
_dev
device
;
struct
s
kypopen
_listitem
{
struct
s
kypopen
_dev
device
;
dev_t
key
;
struct
list_head
list
;
};
/* The list of devices, and a lock to protect it */
static
LIST_HEAD
(
s
cull
_c_list
);
static
spinlock_t
s
cull
_c_lock
=
SPIN_LOCK_UNLOCKED
;
static
LIST_HEAD
(
s
kypopen
_c_list
);
static
spinlock_t
s
kypopen
_c_lock
=
SPIN_LOCK_UNLOCKED
;
/* Look for a device or create one if missing */
static
struct
s
cull_dev
*
scull
_c_lookfor_device
(
dev_t
key
)
static
struct
s
kypopen_dev
*
skypopen
_c_lookfor_device
(
dev_t
key
)
{
struct
s
cull
_listitem
*
lptr
;
struct
s
kypopen
_listitem
*
lptr
;
list_for_each_entry
(
lptr
,
&
s
cull
_c_list
,
list
)
{
list_for_each_entry
(
lptr
,
&
s
kypopen
_c_list
,
list
)
{
if
(
lptr
->
key
==
key
)
return
&
(
lptr
->
device
);
}
/* not found */
lptr
=
kmalloc
(
sizeof
(
struct
s
cull
_listitem
),
GFP_KERNEL
);
lptr
=
kmalloc
(
sizeof
(
struct
s
kypopen
_listitem
),
GFP_KERNEL
);
if
(
!
lptr
)
return
NULL
;
/* initialize the device */
memset
(
lptr
,
0
,
sizeof
(
struct
s
cull
_listitem
));
memset
(
lptr
,
0
,
sizeof
(
struct
s
kypopen
_listitem
));
lptr
->
key
=
key
;
init_waitqueue_head
(
&
lptr
->
device
.
inq
);
init_waitqueue_head
(
&
lptr
->
device
.
outq
);
printk
(
" Timer installing
\n
"
);
setup_timer
(
&
lptr
->
device
.
timer_inq
,
my_timer_callback_inq
,
(
long
int
)
lptr
);
setup_timer
(
&
lptr
->
device
.
timer_outq
,
my_timer_callback_outq
,
(
long
int
)
lptr
);
printk
(
"Starting timer to fire in %dms (%ld)
\n
"
,
GIOVA_SLEEP
,
jiffies
);
mod_timer
(
&
lptr
->
device
.
timer_inq
,
jiffies
+
msecs_to_jiffies
(
GIOVA_SLEEP
)
);
mod_timer
(
&
lptr
->
device
.
timer_outq
,
jiffies
+
msecs_to_jiffies
(
GIOVA_SLEEP
)
);
init_waitqueue_head
(
&
lptr
->
device
.
inq
);
init_waitqueue_head
(
&
lptr
->
device
.
outq
);
setup_timer
(
&
lptr
->
device
.
timer_inq
,
my_timer_callback_inq
,
(
long
int
)
lptr
);
setup_timer
(
&
lptr
->
device
.
timer_outq
,
my_timer_callback_outq
,
(
long
int
)
lptr
);
printk
(
"Starting skypopen OSS driver read timer (%dms) skype client:(%d)
\n
"
,
GIOVA_SLEEP
,
current
->
tgid
);
mod_timer
(
&
lptr
->
device
.
timer_inq
,
jiffies
+
msecs_to_jiffies
(
GIOVA_SLEEP
)
);
printk
(
"Starting skypopen OSS driver write timer (%dms) skype client:(%d)
\n
"
,
GIOVA_SLEEP
,
current
->
tgid
);
mod_timer
(
&
lptr
->
device
.
timer_outq
,
jiffies
+
msecs_to_jiffies
(
GIOVA_SLEEP
)
);
/* place it in the list */
list_add
(
&
lptr
->
list
,
&
s
cull
_c_list
);
list_add
(
&
lptr
->
list
,
&
s
kypopen
_c_list
);
return
&
(
lptr
->
device
);
}
static
int
scull_c_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
/*
* Open and close
*/
static
int
skypopen_c_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
struct
s
cull
_dev
*
dev
;
struct
s
kypopen
_dev
*
dev
;
dev_t
key
;
if
(
!
current
->
pid
)
{
printk
(
"Process
\"
%s
\"
has no pid
\n
"
,
current
->
comm
);
return
-
EINVAL
;
}
key
=
current
->
pid
;
/* look for a s
cull
c device in the list */
spin_lock
(
&
s
cull
_c_lock
);
dev
=
s
cull
_c_lookfor_device
(
key
);
spin_unlock
(
&
s
cull
_c_lock
);
/* look for a s
kypopen
c device in the list */
spin_lock
(
&
s
kypopen
_c_lock
);
dev
=
s
kypopen
_c_lookfor_device
(
key
);
spin_unlock
(
&
s
kypopen
_c_lock
);
if
(
!
dev
)
return
-
ENOMEM
;
/* then, everything else is copied from the bare s
cull
device */
/* then, everything else is copied from the bare s
kypopen
device */
filp
->
private_data
=
dev
;
return
0
;
/* success */
}
static
int
s
cull
_c_release
(
struct
inode
*
inode
,
struct
file
*
filp
)
static
int
s
kypopen
_c_release
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
/*
* Nothing to do, because the device is persistent.
...
...
@@ -163,39 +162,29 @@ static int scull_c_release(struct inode *inode, struct file *filp)
/*************************************************************/
/*
* Open and close
*/
ssize_t
s
cull
_read
(
struct
file
*
filp
,
char
__user
*
buf
,
size_t
count
,
ssize_t
s
kypopen
_read
(
struct
file
*
filp
,
char
__user
*
buf
,
size_t
count
,
loff_t
*
f_pos
)
{
struct
scull_dev
*
dev
=
filp
->
private_data
;
struct
skypopen_dev
*
dev
=
filp
->
private_data
;
DEFINE_WAIT
(
wait
);
prepare_to_wait
(
&
dev
->
inq
,
&
wait
,
TASK_INTERRUPTIBLE
);
schedule
();
finish_wait
(
&
dev
->
inq
,
&
wait
);
//memset(buf, 255, count);
//wait_event_interruptible(dev->inq, dev->readable);
//dev->readable=0;
return
count
;
}
ssize_t
s
cull
_write
(
struct
file
*
filp
,
const
char
__user
*
buf
,
size_t
count
,
ssize_t
s
kypopen
_write
(
struct
file
*
filp
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
f_pos
)
{
struct
s
cull
_dev
*
dev
=
filp
->
private_data
;
struct
s
kypopen
_dev
*
dev
=
filp
->
private_data
;
DEFINE_WAIT
(
wait
);
prepare_to_wait
(
&
dev
->
outq
,
&
wait
,
TASK_INTERRUPTIBLE
);
schedule
();
finish_wait
(
&
dev
->
outq
,
&
wait
);
//wait_event_interruptible(dev->outq, dev->writable);
//dev->writable=0;
return
count
;
}
...
...
@@ -203,7 +192,7 @@ ssize_t scull_write(struct file *filp, const char __user *buf, size_t count,
* The ioctl() implementation
*/
int
s
cull
_ioctl
(
struct
inode
*
inode
,
struct
file
*
filp
,
int
s
kypopen
_ioctl
(
struct
inode
*
inode
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
void
__user
*
argp
=
(
void
__user
*
)
arg
;
...
...
@@ -223,14 +212,14 @@ int scull_ioctl(struct inode *inode, struct file *filp,
}
struct
file_operations
s
cull
_fops
=
{
struct
file_operations
s
kypopen
_fops
=
{
.
owner
=
THIS_MODULE
,
.
llseek
=
no_llseek
,
.
read
=
s
cull
_read
,
.
write
=
s
cull
_write
,
.
ioctl
=
s
cull
_ioctl
,
.
open
=
s
cull
_c_open
,
.
release
=
s
cull
_c_release
,
.
read
=
s
kypopen
_read
,
.
write
=
s
kypopen
_write
,
.
ioctl
=
s
kypopen
_ioctl
,
.
open
=
s
kypopen
_c_open
,
.
release
=
s
kypopen
_c_release
,
};
/*
...
...
@@ -243,34 +232,34 @@ struct file_operations scull_fops = {
* have not been initialized
*/
void
s
cull
_cleanup_module
(
void
)
void
s
kypopen
_cleanup_module
(
void
)
{
int
i
;
int
ret
;
struct
s
cull
_listitem
*
lptr
,
*
next
;
dev_t
devno
=
MKDEV
(
s
cull_major
,
scull
_minor
);
struct
s
kypopen
_listitem
*
lptr
,
*
next
;
dev_t
devno
=
MKDEV
(
s
kypopen_major
,
skypopen
_minor
);
/* Get rid of our char dev entries */
if
(
s
cull
_devices
)
{
for
(
i
=
0
;
i
<
s
cull
_nr_devs
;
i
++
)
{
cdev_del
(
&
s
cull
_devices
[
i
].
cdev
);
if
(
s
kypopen
_devices
)
{
for
(
i
=
0
;
i
<
s
kypopen
_nr_devs
;
i
++
)
{
cdev_del
(
&
s
kypopen
_devices
[
i
].
cdev
);
}
kfree
(
s
cull
_devices
);
kfree
(
s
kypopen
_devices
);
}
/* And all the cloned devices */
list_for_each_entry_safe
(
lptr
,
next
,
&
s
cull
_c_list
,
list
)
{
list_for_each_entry_safe
(
lptr
,
next
,
&
s
kypopen
_c_list
,
list
)
{
ret
=
del_timer
(
&
lptr
->
device
.
timer_inq
);
if
(
ret
)
printk
(
"The inq timer was still in use...
\n
"
);
//printk( "Stopped skypopen OSS driver read timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid
);
ret
=
del_timer
(
&
lptr
->
device
.
timer_outq
);
if
(
ret
)
printk
(
"The outq timer was still in use...
\n
"
);
//printk( "Stopped skypopen OSS driver write timer (%dms) skype client:(%d)\n", GIOVA_SLEEP, current->tgid
);
list_del
(
&
lptr
->
list
);
kfree
(
lptr
);
}
printk
(
"Timer uninstalling
\n
"
);
/* cleanup_module is never called if registering failed */
unregister_chrdev_region
(
devno
,
scull_nr_devs
);
unregister_chrdev_region
(
devno
,
skypopen_nr_devs
);
printk
(
"skypopen OSS driver unloaded
\n
"
);
}
...
...
@@ -278,40 +267,41 @@ void scull_cleanup_module(void)
/*
* Set up the char_dev structure for this device.
*/
static
void
s
cull_setup_cdev
(
struct
scull
_dev
*
dev
,
int
index
)
static
void
s
kypopen_setup_cdev
(
struct
skypopen
_dev
*
dev
,
int
index
)
{
int
err
,
devno
=
MKDEV
(
s
cull_major
,
scull
_minor
+
index
);
int
err
,
devno
=
MKDEV
(
s
kypopen_major
,
skypopen
_minor
+
index
);
cdev_init
(
&
dev
->
cdev
,
&
s
cull
_fops
);
cdev_init
(
&
dev
->
cdev
,
&
s
kypopen
_fops
);
dev
->
cdev
.
owner
=
THIS_MODULE
;
dev
->
cdev
.
ops
=
&
s
cull
_fops
;
dev
->
cdev
.
ops
=
&
s
kypopen
_fops
;
err
=
cdev_add
(
&
dev
->
cdev
,
devno
,
1
);
/* Fail gracefully if need be */
if
(
err
)
printk
(
KERN_NOTICE
"Error %d adding s
cull
%d"
,
err
,
index
);
printk
(
KERN_NOTICE
"Error %d adding s
kypopen
%d"
,
err
,
index
);
}
int
s
cull
_init_module
(
void
)
int
s
kypopen
_init_module
(
void
)
{
int
result
,
i
;
dev_t
dev
=
0
;
printk
(
"skypopen OSS driver loading (www.freeswitch.org)
\n
"
);
/*
* Get a range of minor numbers to work with, asking for a dynamic
* major unless directed otherwise at load time.
*/
if
(
s
cull
_major
)
{
dev
=
MKDEV
(
s
cull_major
,
scull
_minor
);
result
=
register_chrdev_region
(
dev
,
s
cull
_nr_devs
,
"dsp"
);
if
(
s
kypopen
_major
)
{
dev
=
MKDEV
(
s
kypopen_major
,
skypopen
_minor
);
result
=
register_chrdev_region
(
dev
,
s
kypopen
_nr_devs
,
"dsp"
);
}
else
{
result
=
alloc_chrdev_region
(
&
dev
,
s
cull_minor
,
scull
_nr_devs
,
result
=
alloc_chrdev_region
(
&
dev
,
s
kypopen_minor
,
skypopen
_nr_devs
,
"dsp"
);
s
cull
_major
=
MAJOR
(
dev
);
s
kypopen
_major
=
MAJOR
(
dev
);
}
if
(
result
<
0
)
{
printk
(
KERN_WARNING
"s
cull: can't get major %d
\n
"
,
scull
_major
);
printk
(
KERN_WARNING
"s
kypopen OSS driver: can't get major %d
\n
"
,
skypopen
_major
);
return
result
;
}
...
...
@@ -319,26 +309,26 @@ int scull_init_module(void)
* allocate the devices -- we can't have them static, as the number
* can be specified at load time
*/
s
cull_devices
=
kmalloc
(
scull_nr_devs
*
sizeof
(
struct
scull
_dev
),
GFP_KERNEL
);
if
(
!
s
cull
_devices
)
{
s
kypopen_devices
=
kmalloc
(
skypopen_nr_devs
*
sizeof
(
struct
skypopen
_dev
),
GFP_KERNEL
);
if
(
!
s
kypopen
_devices
)
{
result
=
-
ENOMEM
;
goto
fail
;
/* Make this more graceful */
}
memset
(
s
cull_devices
,
0
,
scull_nr_devs
*
sizeof
(
struct
scull
_dev
));
memset
(
s
kypopen_devices
,
0
,
skypopen_nr_devs
*
sizeof
(
struct
skypopen
_dev
));
/* Initialize each device. */
for
(
i
=
0
;
i
<
s
cull
_nr_devs
;
i
++
)
{
s
cull_setup_cdev
(
&
scull
_devices
[
i
],
i
);
for
(
i
=
0
;
i
<
s
kypopen
_nr_devs
;
i
++
)
{
s
kypopen_setup_cdev
(
&
skypopen
_devices
[
i
],
i
);
}
/* At this point call the init function for any friend device */
dev
=
MKDEV
(
s
cull_major
,
scull_minor
+
scull
_nr_devs
);
dev
=
MKDEV
(
s
kypopen_major
,
skypopen_minor
+
skypopen
_nr_devs
);
return
0
;
/* succeed */
fail:
s
cull
_cleanup_module
();
s
kypopen
_cleanup_module
();
return
result
;
}
module_init
(
s
cull
_init_module
);
module_exit
(
s
cull
_cleanup_module
);
module_init
(
s
kypopen
_init_module
);
module_exit
(
s
kypopen
_cleanup_module
);
src/mod/endpoints/mod_skypopen/oss/s
cull
.h
→
src/mod/endpoints/mod_skypopen/oss/s
kypopen
.h
浏览文件 @
eafd7e5e
/*
* s
cull
.h -- definitions for the char module
* s
kypopen
.h -- definitions for the char module
*
* Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
* Copyright (C) 2001 O'Reilly & Associates
...
...
@@ -12,55 +12,49 @@
* by O'Reilly & Associates. No warranty is attached;
* we cannot take responsibility for errors or fitness for use.
*
* $Id: s
cull
.h,v 1.15 2004/11/04 17:51:18 rubini Exp $
* $Id: s
kypopen
.h,v 1.15 2004/11/04 17:51:18 rubini Exp $
*/
#ifndef _S
CULL
_H_
#define _S
CULL
_H_
#ifndef _S
KYPOPEN
_H_
#define _S
KYPOPEN
_H_
#include <linux/ioctl.h>
/* needed for the _IOW etc stuff used later */
#ifndef S
CULL
_MAJOR
#define S
CULL
_MAJOR 14
/* dynamic major by default */
#ifndef S
KYPOPEN
_MAJOR
#define S
KYPOPEN
_MAJOR 14
/* dynamic major by default */
#endif
#ifndef S
CULL
_NR_DEVS
#define S
CULL_NR_DEVS 1
/* scull0 through scull
3 */
#ifndef S
KYPOPEN
_NR_DEVS
#define S
KYPOPEN_NR_DEVS 1
/* skypopen0 through skypopen
3 */
#endif
struct
s
cull
_dev
{
struct
s
kypopen
_dev
{
struct
cdev
cdev
;
/* Char device structure */
wait_queue_head_t
inq
;
/* read and write queues */
wait_queue_head_t
outq
;
/* read and write queues */
struct
timer_list
timer_inq
;
struct
timer_list
timer_outq
;
int
readable
;
int
writable
;
//unsigned long read_howmany;
//unsigned long write_howmany;
//unsigned long read_sleeped_acc;
//unsigned long write_sleeped_acc;
//double read_delay; /* how much delay last time */
//double write_delay; /* how much delay last time */
int
timer_inq_started
;
int
timer_outq_started
;
};
/*
* The different configurable parameters
*/
extern
int
s
cull
_major
;
/* main.c */
extern
int
s
cull
_nr_devs
;
extern
int
s
kypopen
_major
;
/* main.c */
extern
int
s
kypopen
_nr_devs
;
/*
* Prototypes for shared functions
*/
ssize_t
s
cull
_read
(
struct
file
*
filp
,
char
__user
*
buf
,
size_t
count
,
ssize_t
s
kypopen
_read
(
struct
file
*
filp
,
char
__user
*
buf
,
size_t
count
,
loff_t
*
f_pos
);
ssize_t
s
cull
_write
(
struct
file
*
filp
,
const
char
__user
*
buf
,
size_t
count
,
ssize_t
s
kypopen
_write
(
struct
file
*
filp
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
f_pos
);
int
s
cull
_ioctl
(
struct
inode
*
inode
,
struct
file
*
filp
,
int
s
kypopen
_ioctl
(
struct
inode
*
inode
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
);
#endif
/* _S
CULL
_H_ */
#endif
/* _S
KYPOPEN
_H_ */
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论