skypopen: OSS driver, refinement
This commit is contained in:
parent
5cc3b2e635
commit
b0a23f8e64
|
@ -1,6 +1,6 @@
|
||||||
# Comment/uncomment the following line to disable/enable debugging
|
# Comment/uncomment the following line to disable/enable debugging
|
||||||
#DEBUG = y
|
#DEBUG = y
|
||||||
#LDDINC=/usr/src/linux-headers-2.6.32-26-server/include
|
#LDDINC=
|
||||||
|
|
||||||
# Add your debugging flag (or not) to CFLAGS
|
# Add your debugging flag (or not) to CFLAGS
|
||||||
ifeq ($(DEBUG),y)
|
ifeq ($(DEBUG),y)
|
||||||
|
|
|
@ -43,12 +43,13 @@
|
||||||
|
|
||||||
#include "skypopen.h" /* local definitions */
|
#include "skypopen.h" /* local definitions */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our parameters which can be set at load time.
|
* Our parameters which can be set at load time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int skypopen_major = SKYPOPEN_MAJOR;
|
int skypopen_major = SKYPOPEN_MAJOR;
|
||||||
int skypopen_minor = 3;
|
int skypopen_minor = SKYPOPEN_MINOR;
|
||||||
int skypopen_nr_devs = SKYPOPEN_NR_DEVS; /* number of bare skypopen devices */
|
int skypopen_nr_devs = SKYPOPEN_NR_DEVS; /* number of bare skypopen devices */
|
||||||
|
|
||||||
module_param(skypopen_major, int, S_IRUGO);
|
module_param(skypopen_major, int, S_IRUGO);
|
||||||
|
@ -61,9 +62,6 @@ MODULE_LICENSE("Dual BSD/GPL");
|
||||||
static struct skypopen_dev *skypopen_devices; /* allocated in skypopen_init_module */
|
static struct skypopen_dev *skypopen_devices; /* allocated in skypopen_init_module */
|
||||||
|
|
||||||
static int unload = 0;
|
static int unload = 0;
|
||||||
#ifdef CENTOS
|
|
||||||
#define HRTIMER_MODE_REL HRTIMER_REL
|
|
||||||
#endif// CENTOS
|
|
||||||
|
|
||||||
#ifndef WANT_HRTIMER
|
#ifndef WANT_HRTIMER
|
||||||
void my_timer_callback_inq( unsigned long data )
|
void my_timer_callback_inq( unsigned long data )
|
||||||
|
@ -84,7 +82,7 @@ void my_timer_callback_outq( unsigned long data )
|
||||||
}
|
}
|
||||||
#else// WANT_HRTIMER
|
#else// WANT_HRTIMER
|
||||||
|
|
||||||
#ifndef CENTOS
|
#ifndef CENTOS_5
|
||||||
static enum hrtimer_restart my_hrtimer_callback_inq( struct hrtimer *timer_inq )
|
static enum hrtimer_restart my_hrtimer_callback_inq( struct hrtimer *timer_inq )
|
||||||
{
|
{
|
||||||
struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq);
|
struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq);
|
||||||
|
@ -113,7 +111,7 @@ static enum hrtimer_restart my_hrtimer_callback_outq( struct hrtimer *timer_outq
|
||||||
|
|
||||||
return HRTIMER_RESTART;
|
return HRTIMER_RESTART;
|
||||||
}
|
}
|
||||||
#else// CENTOS
|
#else// CENTOS_5
|
||||||
static int my_hrtimer_callback_inq( struct hrtimer *timer_inq )
|
static int my_hrtimer_callback_inq( struct hrtimer *timer_inq )
|
||||||
{
|
{
|
||||||
struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq);
|
struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq);
|
||||||
|
@ -138,7 +136,7 @@ static int my_hrtimer_callback_outq( struct hrtimer *timer_outq )
|
||||||
|
|
||||||
return HRTIMER_RESTART;
|
return HRTIMER_RESTART;
|
||||||
}
|
}
|
||||||
#endif// CENTOS
|
#endif// CENTOS_5
|
||||||
#endif// WANT_HRTIMER
|
#endif// WANT_HRTIMER
|
||||||
|
|
||||||
/* The clone-specific data structure includes a key field */
|
/* The clone-specific data structure includes a key field */
|
||||||
|
@ -159,10 +157,6 @@ static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key)
|
||||||
{
|
{
|
||||||
struct skypopen_listitem *lptr;
|
struct skypopen_listitem *lptr;
|
||||||
#ifdef WANT_HRTIMER
|
#ifdef WANT_HRTIMER
|
||||||
#if 0
|
|
||||||
ktime_t ktime_inq;
|
|
||||||
ktime_t ktime_outq;
|
|
||||||
#endif //0
|
|
||||||
#endif// WANT_HRTIMER
|
#endif// WANT_HRTIMER
|
||||||
|
|
||||||
list_for_each_entry(lptr, &skypopen_c_list, list) {
|
list_for_each_entry(lptr, &skypopen_c_list, list) {
|
||||||
|
@ -181,6 +175,7 @@ static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key)
|
||||||
|
|
||||||
init_waitqueue_head(&lptr->device.inq);
|
init_waitqueue_head(&lptr->device.inq);
|
||||||
init_waitqueue_head(&lptr->device.outq);
|
init_waitqueue_head(&lptr->device.outq);
|
||||||
|
|
||||||
#ifndef WANT_HRTIMER
|
#ifndef WANT_HRTIMER
|
||||||
setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr );
|
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 );
|
setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr );
|
||||||
|
@ -188,19 +183,6 @@ static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key)
|
||||||
mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
|
mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
|
||||||
printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid );
|
printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid );
|
||||||
mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
|
mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) );
|
||||||
#else// WANT_HRTIMER
|
|
||||||
#if 0
|
|
||||||
ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000);
|
|
||||||
hrtimer_init( &lptr->device.timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
|
|
||||||
lptr->device.timer_inq.function = &my_hrtimer_callback_inq;
|
|
||||||
hrtimer_start( &lptr->device.timer_inq, ktime_inq, HRTIMER_MODE_REL );
|
|
||||||
|
|
||||||
ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000);
|
|
||||||
hrtimer_init( &lptr->device.timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
|
|
||||||
lptr->device.timer_outq.function = &my_hrtimer_callback_outq;
|
|
||||||
hrtimer_start( &lptr->device.timer_outq, ktime_outq, HRTIMER_MODE_REL );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif// WANT_HRTIMER
|
#endif// WANT_HRTIMER
|
||||||
|
|
||||||
/* place it in the list */
|
/* place it in the list */
|
||||||
|
@ -249,14 +231,12 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count,
|
||||||
loff_t *f_pos)
|
loff_t *f_pos)
|
||||||
{
|
{
|
||||||
DEFINE_WAIT(wait);
|
DEFINE_WAIT(wait);
|
||||||
size_t written;
|
|
||||||
struct skypopen_dev *dev = filp->private_data;
|
struct skypopen_dev *dev = filp->private_data;
|
||||||
|
|
||||||
if(unload)
|
if(unload)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
#ifdef WANT_HRTIMER
|
#ifdef WANT_HRTIMER
|
||||||
#if 1
|
|
||||||
if(dev->timer_inq_started == 0){
|
if(dev->timer_inq_started == 0){
|
||||||
ktime_t ktime_inq;
|
ktime_t ktime_inq;
|
||||||
|
|
||||||
|
@ -266,39 +246,13 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count,
|
||||||
hrtimer_start( &dev->timer_inq, ktime_inq, HRTIMER_MODE_REL );
|
hrtimer_start( &dev->timer_inq, ktime_inq, HRTIMER_MODE_REL );
|
||||||
dev->timer_inq_started = 1;
|
dev->timer_inq_started = 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif// WANT_HRTIMER
|
#endif// WANT_HRTIMER
|
||||||
|
|
||||||
|
|
||||||
//printk("READ\n");
|
//printk("READ\n");
|
||||||
prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
|
prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
|
||||||
schedule();
|
schedule();
|
||||||
finish_wait(&dev->inq, &wait);
|
finish_wait(&dev->inq, &wait);
|
||||||
|
return count;
|
||||||
if (!count)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, buf, count))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
written = 0;
|
|
||||||
while (count) {
|
|
||||||
unsigned long unwritten;
|
|
||||||
size_t chunk = count;
|
|
||||||
|
|
||||||
if (chunk > PAGE_SIZE)
|
|
||||||
chunk = PAGE_SIZE; /* Just for latency reasons */
|
|
||||||
unwritten = __clear_user(buf, chunk);
|
|
||||||
written += chunk - unwritten;
|
|
||||||
if (unwritten)
|
|
||||||
break;
|
|
||||||
if (signal_pending(current))
|
|
||||||
return written ? written : -ERESTARTSYS;
|
|
||||||
buf += chunk;
|
|
||||||
count -= chunk;
|
|
||||||
cond_resched();
|
|
||||||
}
|
|
||||||
return written ? written : -EFAULT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count,
|
static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count,
|
||||||
|
@ -311,7 +265,6 @@ static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
#ifdef WANT_HRTIMER
|
#ifdef WANT_HRTIMER
|
||||||
#if 1
|
|
||||||
if(dev->timer_outq_started == 0){
|
if(dev->timer_outq_started == 0){
|
||||||
ktime_t ktime_outq;
|
ktime_t ktime_outq;
|
||||||
|
|
||||||
|
@ -321,10 +274,8 @@ static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t
|
||||||
hrtimer_start( &dev->timer_outq, ktime_outq, HRTIMER_MODE_REL );
|
hrtimer_start( &dev->timer_outq, ktime_outq, HRTIMER_MODE_REL );
|
||||||
dev->timer_outq_started = 1;
|
dev->timer_outq_started = 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif// WANT_HRTIMER
|
#endif// WANT_HRTIMER
|
||||||
|
|
||||||
|
|
||||||
//printk("WRITE\n");
|
//printk("WRITE\n");
|
||||||
prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE);
|
prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE);
|
||||||
schedule();
|
schedule();
|
||||||
|
@ -448,6 +399,7 @@ int skypopen_init_module(void)
|
||||||
dev_t dev = 0;
|
dev_t dev = 0;
|
||||||
|
|
||||||
printk("skypopen OSS driver loading (www.freeswitch.org)\n");
|
printk("skypopen OSS driver loading (www.freeswitch.org)\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a range of minor numbers to work with, asking for a dynamic
|
* Get a range of minor numbers to work with, asking for a dynamic
|
||||||
* major unless directed otherwise at load time.
|
* major unless directed otherwise at load time.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* skypopen.h -- definitions for the char module
|
* skypopen.h -- definitions for the char module
|
||||||
*
|
*
|
||||||
|
* Copyright (C) 2010 Giovanni Maruzzelli
|
||||||
* Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
|
* Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
|
||||||
* Copyright (C) 2001 O'Reilly & Associates
|
* Copyright (C) 2001 O'Reilly & Associates
|
||||||
*
|
*
|
||||||
|
@ -20,20 +21,20 @@
|
||||||
|
|
||||||
#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */
|
#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */
|
||||||
|
|
||||||
|
#define CENTOS_5 /* define this ONLY if you're on CentOS 5.x (eg: undef on CentOS 6.x ) */
|
||||||
|
#define WANT_HRTIMER /* undef this only if you don't want to use High Resolution Timers (why?) */
|
||||||
#define SKYPOPEN_BLK 960
|
#define SKYPOPEN_BLK 960
|
||||||
#define SKYPOPEN_SLEEP 10
|
#define SKYPOPEN_SLEEP 10
|
||||||
|
|
||||||
#define CENTOS
|
|
||||||
|
|
||||||
#ifndef SKYPOPEN_MAJOR
|
|
||||||
#define SKYPOPEN_MAJOR 14 /* dynamic major by default */
|
#define SKYPOPEN_MAJOR 14 /* dynamic major by default */
|
||||||
#endif
|
#define SKYPOPEN_MINOR 3 /* dynamic major by default */
|
||||||
|
#define SKYPOPEN_NR_DEVS 1 /* not useful, I'm too lazy to remove it */
|
||||||
|
|
||||||
#ifndef SKYPOPEN_NR_DEVS
|
#ifdef CENTOS_5
|
||||||
#define SKYPOPEN_NR_DEVS 1 /* skypopen0 through skypopen3 */
|
#define HRTIMER_MODE_REL HRTIMER_REL
|
||||||
#endif
|
#endif// CENTOS_5
|
||||||
|
|
||||||
#define WANT_HRTIMER
|
|
||||||
struct skypopen_dev {
|
struct skypopen_dev {
|
||||||
struct cdev cdev; /* Char device structure */
|
struct cdev cdev; /* Char device structure */
|
||||||
wait_queue_head_t inq; /* read and write queues */
|
wait_queue_head_t inq; /* read and write queues */
|
||||||
|
@ -56,16 +57,4 @@ struct skypopen_dev {
|
||||||
extern int skypopen_major; /* main.c */
|
extern int skypopen_major; /* main.c */
|
||||||
extern int skypopen_nr_devs;
|
extern int skypopen_nr_devs;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prototypes for shared functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
//ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count,
|
|
||||||
//loff_t *f_pos);
|
|
||||||
//ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count,
|
|
||||||
//loff_t *f_pos);
|
|
||||||
//int skypopen_ioctl(struct inode *inode, struct file *filp,
|
|
||||||
//unsigned int cmd, unsigned long arg);
|
|
||||||
|
|
||||||
#endif /* _SKYPOPEN_H_ */
|
#endif /* _SKYPOPEN_H_ */
|
||||||
|
|
Loading…
Reference in New Issue