]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/dvb/dvb-core/dvb_ringbuffer.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / drivers / media / dvb / dvb-core / dvb_ringbuffer.c
index 872985b7912d3db12036abd78380a012012033e1..584bbd194dc8a18ee65b327949bcc7a67dee8c48 100644 (file)
@@ -107,35 +107,43 @@ void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
        wake_up(&rbuf->queue);
 }
 
-
-
-ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, int usermem)
+ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len)
 {
        size_t todo = len;
        size_t split;
 
        split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
        if (split > 0) {
-               if (!usermem)
-                       memcpy(buf, rbuf->data+rbuf->pread, split);
-               else
-                       if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
-                               return -EFAULT;
+               if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
+                       return -EFAULT;
                buf += split;
                todo -= split;
                rbuf->pread = 0;
        }
-       if (!usermem)
-               memcpy(buf, rbuf->data+rbuf->pread, todo);
-       else
-               if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
-                       return -EFAULT;
+       if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
+               return -EFAULT;
 
        rbuf->pread = (rbuf->pread + todo) % rbuf->size;
 
        return len;
 }
 
+void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
+{
+       size_t todo = len;
+       size_t split;
+
+       split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
+       if (split > 0) {
+               memcpy(buf, rbuf->data+rbuf->pread, split);
+               buf += split;
+               todo -= split;
+               rbuf->pread = 0;
+       }
+       memcpy(buf, rbuf->data+rbuf->pread, todo);
+
+       rbuf->pread = (rbuf->pread + todo) % rbuf->size;
+}
 
 
 ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len)
@@ -171,8 +179,8 @@ ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t le
        return status;
 }
 
-ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
-                               int offset, u8* buf, size_t len, int usermem)
+ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
+                               int offset, u8 __user *buf, size_t len)
 {
        size_t todo;
        size_t split;
@@ -187,21 +195,40 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
        todo = len;
        split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
        if (split > 0) {
-               if (!usermem)
-                       memcpy(buf, rbuf->data+idx, split);
-               else
-                       if (copy_to_user(buf, rbuf->data+idx, split))
-                               return -EFAULT;
+               if (copy_to_user(buf, rbuf->data+idx, split))
+                       return -EFAULT;
                buf += split;
                todo -= split;
                idx = 0;
        }
-       if (!usermem)
-               memcpy(buf, rbuf->data+idx, todo);
-       else
-               if (copy_to_user(buf, rbuf->data+idx, todo))
-                       return -EFAULT;
+       if (copy_to_user(buf, rbuf->data+idx, todo))
+               return -EFAULT;
+
+       return len;
+}
 
+ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
+                               int offset, u8* buf, size_t len)
+{
+       size_t todo;
+       size_t split;
+       size_t pktlen;
+
+       pktlen = rbuf->data[idx] << 8;
+       pktlen |= rbuf->data[(idx + 1) % rbuf->size];
+       if (offset > pktlen) return -EINVAL;
+       if ((offset + len) > pktlen) len = pktlen - offset;
+
+       idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
+       todo = len;
+       split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
+       if (split > 0) {
+               memcpy(buf, rbuf->data+idx, split);
+               buf += split;
+               todo -= split;
+               idx = 0;
+       }
+       memcpy(buf, rbuf->data+idx, todo);
        return len;
 }
 
@@ -266,5 +293,6 @@ EXPORT_SYMBOL(dvb_ringbuffer_empty);
 EXPORT_SYMBOL(dvb_ringbuffer_free);
 EXPORT_SYMBOL(dvb_ringbuffer_avail);
 EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
+EXPORT_SYMBOL(dvb_ringbuffer_read_user);
 EXPORT_SYMBOL(dvb_ringbuffer_read);
 EXPORT_SYMBOL(dvb_ringbuffer_write);