static int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file, int slots, ca_slot_info_t *slot) { int i; int len = 0; u8 msg[8] = { 0x00, 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00 }; for (i = 0; i < 2; i++) { if (slots & (1 << i)) len += 8; } if (dvb_ringbuffer_free(cibuf) < len) return -EBUSY; for (i = 0; i < 2; i++) { if (slots & (1 << i)) { msg[2] = i; dvb_ringbuffer_write(cibuf, msg, 8); slot[i].flags = 0; } } return 0; }
int mpq_streambuffer_data_write_deposit( struct mpq_streambuffer *sbuff, size_t len) { if (NULL == sbuff) return -EINVAL; if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len)) return -ENOSPC; if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) { DVB_RINGBUFFER_PUSH(&sbuff->raw_data, len); wake_up_all(&sbuff->raw_data.queue); } else { /* Linear buffer group */ struct mpq_streambuffer_buffer_desc *desc; desc = (struct mpq_streambuffer_buffer_desc *) &sbuff->raw_data.data[sbuff->raw_data.pwrite]; if ((sbuff->pending_buffers_count == sbuff->buffers_num) || ((desc->size - desc->write_ptr) < len)) { MPQ_DVB_ERR_PRINT( "%s: No space available!\n", __func__); return -ENOSPC; } desc->write_ptr += len; } return 0; }
void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len) { if (dvb_ringbuffer_free(cibuf) < len + 2) return; DVB_RINGBUFFER_WRITE_BYTE(cibuf, len >> 8); DVB_RINGBUFFER_WRITE_BYTE(cibuf, len & 0xff); dvb_ringbuffer_write(cibuf, data, len); wake_up_interruptible(&cibuf->queue); }
ssize_t mpq_streambuffer_data_write( struct mpq_streambuffer *sbuff, const u8 *buf, size_t len) { int res; if ((NULL == sbuff) || (NULL == buf)) return -EINVAL; if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) { if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len)) return -ENOSPC; /* * Secure buffers are not permitted to be mapped into kernel * memory, and so buffer base address may be NULL */ if (NULL == sbuff->raw_data.data) return -EPERM; res = dvb_ringbuffer_write(&sbuff->raw_data, buf, len); wake_up_all(&sbuff->raw_data.queue); } else { /* Linear buffer group */ struct mpq_streambuffer_buffer_desc *desc; desc = (struct mpq_streambuffer_buffer_desc *) &sbuff->raw_data.data[sbuff->raw_data.pwrite]; /* * Secure buffers are not permitted to be mapped into kernel * memory, and so buffer base address may be NULL */ if (NULL == desc->base) return -EPERM; if ((sbuff->pending_buffers_count == sbuff->buffers_num) || ((desc->size - desc->write_ptr) < len)) { MPQ_DVB_ERR_PRINT( "%s: No space available! %d pending buffers out of %d total buffers. write_ptr=%d, size=%d\n", __func__, sbuff->pending_buffers_count, sbuff->buffers_num, desc->write_ptr, desc->size); return -ENOSPC; } memcpy(desc->base + desc->write_ptr, buf, len); desc->write_ptr += len; MPQ_DVB_DBG_PRINT( "%s: copied %d data bytes. handle=%d, write_ptr=%d\n", __func__, len, desc->handle, desc->write_ptr); res = len; } return res; }
int mpq_streambuffer_pkt_write( struct mpq_streambuffer *sbuff, struct mpq_streambuffer_packet_header *packet, u8 *user_data) { ssize_t idx; size_t len; if ((NULL == sbuff) || (NULL == packet)) return -EINVAL; MPQ_DVB_DBG_PRINT( "%s: handle=%d, offset=%d, len=%d\n", __func__, packet->raw_data_handle, packet->raw_data_offset, packet->raw_data_len); len = sizeof(struct mpq_streambuffer_packet_header) + packet->user_data_len; /* Make sure enough space available for packet header */ if (dvb_ringbuffer_free(&sbuff->packet_data) < len) return -ENOSPC; /* Starting writing packet header */ idx = dvb_ringbuffer_pkt_start(&sbuff->packet_data, len); /* Write non-user private data header */ dvb_ringbuffer_write(&sbuff->packet_data, (u8 *)packet, sizeof(struct mpq_streambuffer_packet_header)); /* Write user's own private data header */ dvb_ringbuffer_write(&sbuff->packet_data, user_data, packet->user_data_len); dvb_ringbuffer_pkt_close(&sbuff->packet_data, idx); /* Move write pointer to next linear buffer for subsequent writes */ if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) && (packet->raw_data_len > 0)) { if (sbuff->pending_buffers_count == sbuff->buffers_num) return -ENOSPC; DVB_RINGBUFFER_PUSH(&sbuff->raw_data, sizeof(struct mpq_streambuffer_buffer_desc)); sbuff->pending_buffers_count++; } wake_up_all(&sbuff->packet_data.queue); return 0; }
static void *ain_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) { struct ngene_channel *chan = priv; struct ngene *dev = chan->dev; if (dvb_ringbuffer_free(&dev->ain_rbuf) >= len) { dvb_ringbuffer_write(&dev->ain_rbuf, buf, len); wake_up_interruptible(&dev->ain_rbuf.queue); } else printk(KERN_INFO DEVICE_NAME ": Dropped ain packet.\n"); return 0; }
static ssize_t ci_ll_write(struct dvb_ringbuffer *cibuf, struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int free; int non_blocking = file->f_flags & O_NONBLOCK; u8 *page = (u8 *)__get_free_page(GFP_USER); int res; if (!page) return -ENOMEM; res = -EINVAL; if (count > 2048) goto out; res = -EFAULT; if (copy_from_user(page, buf, count)) goto out; free = dvb_ringbuffer_free(cibuf); if (count + 2 > free) { res = -EWOULDBLOCK; if (non_blocking) goto out; res = -ERESTARTSYS; if (wait_event_interruptible(cibuf->queue, (dvb_ringbuffer_free(cibuf) >= count + 2))) goto out; } DVB_RINGBUFFER_WRITE_BYTE(cibuf, count >> 8); DVB_RINGBUFFER_WRITE_BYTE(cibuf, count & 0xff); res = dvb_ringbuffer_write(cibuf, page, count); out: free_page((unsigned long)page); return res; }
static void *vcap_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) { struct ngene_channel *chan = priv; struct ngene *dev = chan->dev; if (len >= 1920 * 1080) len = 1920 * 1080; if (dvb_ringbuffer_free(&dev->vin_rbuf) >= len) { dvb_ringbuffer_write(&dev->vin_rbuf, buf, len); wake_up_interruptible(&dev->vin_rbuf.queue); } else { ;/*printk(KERN_INFO DEVICE_NAME ": Dropped vcap packet.\n"); */ } return 0; }
static ssize_t ts_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct dvb_device *dvbdev = file->private_data; struct ngene_channel *chan = dvbdev->priv; struct ngene *dev = chan->dev; if (wait_event_interruptible(dev->tsout_rbuf.queue, dvb_ringbuffer_free (&dev->tsout_rbuf) >= count) < 0) return 0; dvb_ringbuffer_write_user(&dev->tsout_rbuf, buf, count); return count; }
static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf, const u8 *src, size_t len) { ssize_t free; if (!len) return 0; if (!buf->data) return 0; free = dvb_ringbuffer_free(buf); if (len > free) { dprintk("dmxdev: buffer overflow\n"); return -EOVERFLOW; } return dvb_ringbuffer_write(buf, src, len); }
ssize_t mpq_streambuffer_data_free( struct mpq_streambuffer *sbuff) { struct mpq_streambuffer_buffer_desc *desc; if (NULL == sbuff) return -EINVAL; if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) return dvb_ringbuffer_free(&sbuff->raw_data); if (sbuff->pending_buffers_count == sbuff->buffers_num) return 0; desc = (struct mpq_streambuffer_buffer_desc *) &sbuff->raw_data.data[sbuff->raw_data.pwrite]; return desc->size - desc->write_ptr; }
void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) { struct ngene_channel *chan = priv; struct ngene *dev = chan->dev; if (flags & DF_SWAP32) swap_buffer(buf, len); if (dev->ci.en && chan->number == 2) { while (len >= 188) { if (memcmp(buf, fill_ts, sizeof fill_ts) != 0) { if (dvb_ringbuffer_free(&dev->tsin_rbuf) >= 188) { dvb_ringbuffer_write(&dev->tsin_rbuf, buf, 188); wake_up(&dev->tsin_rbuf.queue); #ifdef DEBUG_CI_XFER ok++; #endif } #ifdef DEBUG_CI_XFER else overflow++; #endif } #ifdef DEBUG_CI_XFER else stripped++; if (ok % 100 == 0 && overflow) printk(KERN_WARNING "%s: ok %u overflow %u dropped %u\n", __func__, ok, overflow, stripped); #endif buf += 188; len -= 188; } return NULL; } if (chan->users > 0) dvb_dmx_swfilter(&chan->demux, buf, len); return NULL; }
static unsigned int dvb_ca_poll (struct file *file, poll_table *wait) { struct dvb_device *dvbdev = file->private_data; struct av7110 *av7110 = dvbdev->priv; struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer; struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer; unsigned int mask = 0; dprintk(8, "av7110:%p\n",av7110); poll_wait(file, &rbuf->queue, wait); poll_wait(file, &wbuf->queue, wait); if (!dvb_ringbuffer_empty(rbuf)) mask |= (POLLIN | POLLRDNORM); if (dvb_ringbuffer_free(wbuf) > 1024) mask |= (POLLOUT | POLLWRNORM); return mask; }