V4L/DVB (8130): split dvb_ringbuffer dual-use functions
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>
This commit is contained in:
committed by
Mauro Carvalho Chehab
parent
67778b3227
commit
b0ba0e3ab6
@@ -96,7 +96,7 @@ static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,
|
|||||||
if (avail > todo)
|
if (avail > todo)
|
||||||
avail = todo;
|
avail = todo;
|
||||||
|
|
||||||
ret = dvb_ringbuffer_read(src, (u8 *)buf, avail, 1);
|
ret = dvb_ringbuffer_read_user(src, buf, avail);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -1357,7 +1357,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);
|
idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
|
||||||
while (idx != -1) {
|
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)
|
if (connection_id == -1)
|
||||||
connection_id = hdr[0];
|
connection_id = hdr[0];
|
||||||
if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) {
|
if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) {
|
||||||
@@ -1438,7 +1438,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
|
|||||||
goto exit;
|
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)
|
if (connection_id == -1)
|
||||||
connection_id = hdr[0];
|
connection_id = hdr[0];
|
||||||
if (hdr[0] == connection_id) {
|
if (hdr[0] == connection_id) {
|
||||||
@@ -1449,8 +1449,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
|
|||||||
fraglen -= 2;
|
fraglen -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((status = dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 2,
|
if ((status = dvb_ringbuffer_pkt_read_user(&ca->slot_info[slot].rx_buffer, idx, 2,
|
||||||
(u8 *)buf + pktlen, fraglen, 1)) < 0) {
|
buf + pktlen, fraglen)) < 0) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
pktlen += fraglen;
|
pktlen += fraglen;
|
||||||
|
@@ -107,35 +107,43 @@ void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
|
|||||||
wake_up(&rbuf->queue);
|
wake_up(&rbuf->queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len)
|
||||||
|
|
||||||
ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, int usermem)
|
|
||||||
{
|
{
|
||||||
size_t todo = len;
|
size_t todo = len;
|
||||||
size_t split;
|
size_t split;
|
||||||
|
|
||||||
split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
|
split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
|
||||||
if (split > 0) {
|
if (split > 0) {
|
||||||
if (!usermem)
|
if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
|
||||||
memcpy(buf, rbuf->data+rbuf->pread, split);
|
return -EFAULT;
|
||||||
else
|
|
||||||
if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
|
|
||||||
return -EFAULT;
|
|
||||||
buf += split;
|
buf += split;
|
||||||
todo -= split;
|
todo -= split;
|
||||||
rbuf->pread = 0;
|
rbuf->pread = 0;
|
||||||
}
|
}
|
||||||
if (!usermem)
|
if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
|
||||||
memcpy(buf, rbuf->data+rbuf->pread, todo);
|
return -EFAULT;
|
||||||
else
|
|
||||||
if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
rbuf->pread = (rbuf->pread + todo) % rbuf->size;
|
rbuf->pread = (rbuf->pread + todo) % rbuf->size;
|
||||||
|
|
||||||
return len;
|
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)
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
|
ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
|
||||||
int offset, u8* buf, size_t len, int usermem)
|
int offset, u8 __user *buf, size_t len)
|
||||||
{
|
{
|
||||||
size_t todo;
|
size_t todo;
|
||||||
size_t split;
|
size_t split;
|
||||||
@@ -187,24 +195,43 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
|
|||||||
todo = len;
|
todo = len;
|
||||||
split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
|
split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
|
||||||
if (split > 0) {
|
if (split > 0) {
|
||||||
if (!usermem)
|
if (copy_to_user(buf, rbuf->data+idx, split))
|
||||||
memcpy(buf, rbuf->data+idx, split);
|
return -EFAULT;
|
||||||
else
|
|
||||||
if (copy_to_user(buf, rbuf->data+idx, split))
|
|
||||||
return -EFAULT;
|
|
||||||
buf += split;
|
buf += split;
|
||||||
todo -= split;
|
todo -= split;
|
||||||
idx = 0;
|
idx = 0;
|
||||||
}
|
}
|
||||||
if (!usermem)
|
if (copy_to_user(buf, rbuf->data+idx, todo))
|
||||||
memcpy(buf, rbuf->data+idx, todo);
|
return -EFAULT;
|
||||||
else
|
|
||||||
if (copy_to_user(buf, rbuf->data+idx, todo))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
return len;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx)
|
void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx)
|
||||||
{
|
{
|
||||||
size_t pktlen;
|
size_t pktlen;
|
||||||
@@ -266,5 +293,6 @@ EXPORT_SYMBOL(dvb_ringbuffer_empty);
|
|||||||
EXPORT_SYMBOL(dvb_ringbuffer_free);
|
EXPORT_SYMBOL(dvb_ringbuffer_free);
|
||||||
EXPORT_SYMBOL(dvb_ringbuffer_avail);
|
EXPORT_SYMBOL(dvb_ringbuffer_avail);
|
||||||
EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
|
EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
|
||||||
|
EXPORT_SYMBOL(dvb_ringbuffer_read_user);
|
||||||
EXPORT_SYMBOL(dvb_ringbuffer_read);
|
EXPORT_SYMBOL(dvb_ringbuffer_read);
|
||||||
EXPORT_SYMBOL(dvb_ringbuffer_write);
|
EXPORT_SYMBOL(dvb_ringbuffer_write);
|
||||||
|
@@ -61,7 +61,7 @@ struct dvb_ringbuffer {
|
|||||||
** *** read min. 1000, max. <bufsize> bytes ***
|
** *** read min. 1000, max. <bufsize> bytes ***
|
||||||
** avail = dvb_ringbuffer_avail(rbuf);
|
** avail = dvb_ringbuffer_avail(rbuf);
|
||||||
** if (avail >= 1000)
|
** if (avail >= 1000)
|
||||||
** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize), 0);
|
** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
|
||||||
** else
|
** else
|
||||||
** ...
|
** ...
|
||||||
**
|
**
|
||||||
@@ -114,8 +114,10 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);
|
|||||||
** <usermem> specifies whether <buf> resides in user space
|
** <usermem> specifies whether <buf> resides in user space
|
||||||
** returns number of bytes transferred or -EFAULT
|
** returns number of bytes transferred or -EFAULT
|
||||||
*/
|
*/
|
||||||
extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf,
|
extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf,
|
||||||
size_t len, int usermem);
|
u8 __user *buf, size_t len);
|
||||||
|
extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
|
||||||
|
u8 *buf, size_t len);
|
||||||
|
|
||||||
|
|
||||||
/* write routines & macros */
|
/* 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.
|
* <usermem> Set to 1 if <buf> is in userspace.
|
||||||
* returns Number of bytes read, or -EFAULT.
|
* 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,
|
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.
|
* Dispose of a packet in the ring buffer.
|
||||||
|
@@ -587,7 +587,7 @@ static void gpioirq(unsigned long data)
|
|||||||
}
|
}
|
||||||
DVB_RINGBUFFER_SKIP(cibuf, 2);
|
DVB_RINGBUFFER_SKIP(cibuf, 2);
|
||||||
|
|
||||||
dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0);
|
dvb_ringbuffer_read(cibuf, av7110->debi_virt, len);
|
||||||
|
|
||||||
iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
|
iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
|
||||||
iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
|
iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
|
||||||
|
@@ -269,7 +269,7 @@ int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dvb_ringbuffer_read(buf, dest, (size_t) blen, 0);
|
dvb_ringbuffer_read(buf, dest, (size_t) blen);
|
||||||
|
|
||||||
dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n",
|
dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n",
|
||||||
(unsigned long) buf->pread, (unsigned long) buf->pwrite);
|
(unsigned long) buf->pread, (unsigned long) buf->pwrite);
|
||||||
|
@@ -208,7 +208,7 @@ static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
DVB_RINGBUFFER_SKIP(cibuf, 2);
|
DVB_RINGBUFFER_SKIP(cibuf, 2);
|
||||||
|
|
||||||
return dvb_ringbuffer_read(cibuf, (u8 *)buf, len, 1);
|
return dvb_ringbuffer_read_user(cibuf, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dvb_ca_open(struct inode *inode, struct file *file)
|
static int dvb_ca_open(struct inode *inode, struct file *file)
|
||||||
|
Reference in New Issue
Block a user