diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-06-22 14:20:29 +0000 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-06-22 14:20:29 +0000 |
commit | 7792831e0b09a265fd2c72ea88655f544f9df225 (patch) | |
tree | 1dfcf80f48bbf708713a24a93ab0e096f736c254 /linux/drivers/media/dvb/dvb-core | |
parent | 0b1270c68ced9a1dc8b9877607bd741810a62840 (diff) | |
download | mediapointer-dvb-s2-7792831e0b09a265fd2c72ea88655f544f9df225.tar.gz mediapointer-dvb-s2-7792831e0b09a265fd2c72ea88655f544f9df225.tar.bz2 |
split dvb_ringbuffer dual-use functions
From: Al Viro <viro@ftp.linux.org.uk>
split the suckers into kernel-memory and user-memory versions,
annotate both properly.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/dvb/dvb-core')
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dmxdev.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c | 8 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c | 78 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h | 12 |
4 files changed, 66 insertions, 34 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index df5bef6a2..1cf9fcb6f 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -96,7 +96,7 @@ static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src, if (avail > todo) avail = todo; - ret = dvb_ringbuffer_read(src, (u8 *)buf, avail, 1); + ret = dvb_ringbuffer_read_user(src, buf, avail); if (ret < 0) break; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 02d902fdf..c2954bf57 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -1358,7 +1358,7 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen); while (idx != -1) { - dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0); + dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2); if (connection_id == -1) connection_id = hdr[0]; if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) { @@ -1439,7 +1439,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, goto exit; } - dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0); + dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2); if (connection_id == -1) connection_id = hdr[0]; if (hdr[0] == connection_id) { @@ -1450,8 +1450,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, fraglen -= 2; } - if ((status = dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 2, - (u8 *)buf + pktlen, fraglen, 1)) < 0) { + if ((status = dvb_ringbuffer_pkt_read_user(&ca->slot_info[slot].rx_buffer, idx, 2, + buf + pktlen, fraglen)) < 0) { goto exit; } pktlen += fraglen; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c index 872985b79..584bbd194 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c @@ -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); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h index 890826262..41f04dae6 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h @@ -61,7 +61,7 @@ struct dvb_ringbuffer { ** *** read min. 1000, max. <bufsize> bytes *** ** avail = dvb_ringbuffer_avail(rbuf); ** if (avail >= 1000) -** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize), 0); +** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize)); ** else ** ... ** @@ -114,8 +114,10 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); ** <usermem> specifies whether <buf> resides in user space ** returns number of bytes transferred or -EFAULT */ -extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, - size_t len, int usermem); +extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, + u8 __user *buf, size_t len); +extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, + u8 *buf, size_t len); /* write routines & macros */ @@ -157,8 +159,10 @@ extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, * <usermem> Set to 1 if <buf> is in userspace. * returns Number of bytes read, or -EFAULT. */ +extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx, + int offset, u8 __user *buf, size_t len); extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, - int offset, u8* buf, size_t len, int usermem); + int offset, u8 *buf, size_t len); /** * Dispose of a packet in the ring buffer. |