Skip to content

Commit

Permalink
V4L/DVB (8130): split dvb_ringbuffer dual-use functions
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Al Viro authored and Mauro Carvalho Chehab committed Jul 20, 2008
1 parent 67778b3 commit b0ba0e3
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 37 deletions.
2 changes: 1 addition & 1 deletion drivers/media/dvb/dvb-core/dmxdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
8 changes: 4 additions & 4 deletions drivers/media/dvb/dvb-core/dvb_ca_en50221.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
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)) {
Expand Down Expand Up @@ -1438,7 +1438,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) {
Expand All @@ -1449,8 +1449,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;
Expand Down
78 changes: 53 additions & 25 deletions drivers/media/dvb/dvb-core/dvb_ringbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
12 changes: 8 additions & 4 deletions drivers/media/dvb/dvb-core/dvb_ringbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
** ...
**
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion drivers/media/dvb/ttpci/av7110.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ static void gpioirq(unsigned long data)
}
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, IRQ_STATE_EXT, len, 2);
Expand Down
2 changes: 1 addition & 1 deletion drivers/media/dvb/ttpci/av7110_av.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
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",
(unsigned long) buf->pread, (unsigned long) buf->pwrite);
Expand Down
2 changes: 1 addition & 1 deletion drivers/media/dvb/ttpci/av7110_ca.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file,
return -EINVAL;
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)
Expand Down

0 comments on commit b0ba0e3

Please sign in to comment.