From 7f81c3cc3c44ecba08bf58d219740190de3f55e9 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Mon, 27 Dec 2010 07:49:24 -0600 Subject: [PATCH] skypopen: OSS driver, added some code from /dev/zero to read(), and performances are better --- src/mod/endpoints/mod_skypopen/oss/main.c | 26 ++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index a96e38d68a..10a210a574 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -249,6 +249,7 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { DEFINE_WAIT(wait); + size_t written; struct skypopen_dev *dev = filp->private_data; if(unload) @@ -273,8 +274,31 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); schedule(); 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,