Example #1
0
static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev,
				  struct dmxdev_filter *dmxdevfilter)
{
	if (mutex_lock_interruptible(&dmxdev->mutex))
		return -ERESTARTSYS;

	if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
		mutex_unlock(&dmxdev->mutex);
		return -ERESTARTSYS;
	}

	dvb_dmxdev_filter_stop(dmxdevfilter);
	dvb_dmxdev_filter_reset(dmxdevfilter);

	if (dmxdevfilter->buffer.data) {
		void *mem = dmxdevfilter->buffer.data;

		spin_lock_irq(&dmxdev->lock);
		dmxdevfilter->buffer.data = NULL;
		spin_unlock_irq(&dmxdev->lock);
		vfree(mem);
	}

	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE);
	wake_up(&dmxdevfilter->buffer.queue);
	mutex_unlock(&dmxdevfilter->mutex);
	mutex_unlock(&dmxdev->mutex);
	return 0;
}
Example #2
0
File: dmxdev.c Project: 274914765/C
static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
                 struct dmxdev_filter *dmxdevfilter,
                 struct dmx_sct_filter_params *params)
{
    dprintk("function : %s\n", __func__);

    dvb_dmxdev_filter_stop(dmxdevfilter);

    dmxdevfilter->type = DMXDEV_TYPE_SEC;
    memcpy(&dmxdevfilter->params.sec,
           params, sizeof(struct dmx_sct_filter_params));
    invert_mode(&dmxdevfilter->params.sec.filter);
    dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);

    if (params->flags & DMX_IMMEDIATE_START)
        return dvb_dmxdev_filter_start(dmxdevfilter);

    return 0;
}
Example #3
0
File: dmxdev.c Project: 274914765/C
static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
                     struct dmxdev_filter *dmxdevfilter,
                     struct dmx_pes_filter_params *params)
{
    dvb_dmxdev_filter_stop(dmxdevfilter);

    if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0)
        return -EINVAL;

    dmxdevfilter->type = DMXDEV_TYPE_PES;
    memcpy(&dmxdevfilter->params, params,
           sizeof(struct dmx_pes_filter_params));

    dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);

    if (params->flags & DMX_IMMEDIATE_START)
        return dvb_dmxdev_filter_start(dmxdevfilter);

    return 0;
}
Example #4
0
File: dmxdev.c Project: 274914765/C
static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
                  unsigned int cmd, void *parg)
{
    struct dmxdev_filter *dmxdevfilter = file->private_data;
    struct dmxdev *dmxdev = dmxdevfilter->dev;
    unsigned long arg = (unsigned long)parg;
    int ret = 0;

    if (mutex_lock_interruptible(&dmxdev->mutex))
        return -ERESTARTSYS;

    switch (cmd) {
    case DMX_START:
        if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
            mutex_unlock(&dmxdev->mutex);
            return -ERESTARTSYS;
        }
        if (dmxdevfilter->state < DMXDEV_STATE_SET)
            ret = -EINVAL;
        else
            ret = dvb_dmxdev_filter_start(dmxdevfilter);
        mutex_unlock(&dmxdevfilter->mutex);
        break;

    case DMX_STOP:
        if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
            mutex_unlock(&dmxdev->mutex);
            return -ERESTARTSYS;
        }
        ret = dvb_dmxdev_filter_stop(dmxdevfilter);
        mutex_unlock(&dmxdevfilter->mutex);
        break;

    case DMX_SET_FILTER:
        if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
            mutex_unlock(&dmxdev->mutex);
            return -ERESTARTSYS;
        }
        ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, parg);
        mutex_unlock(&dmxdevfilter->mutex);
        break;

    case DMX_SET_PES_FILTER:
        if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
            mutex_unlock(&dmxdev->mutex);
            return -ERESTARTSYS;
        }
        ret = dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, parg);
        mutex_unlock(&dmxdevfilter->mutex);
        break;

    case DMX_SET_BUFFER_SIZE:
        if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
            mutex_unlock(&dmxdev->mutex);
            return -ERESTARTSYS;
        }
        ret = dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);
        mutex_unlock(&dmxdevfilter->mutex);
        break;

    case DMX_GET_PES_PIDS:
        if (!dmxdev->demux->get_pes_pids) {
            ret = -EINVAL;
            break;
        }
        dmxdev->demux->get_pes_pids(dmxdev->demux, parg);
        break;

    case DMX_GET_CAPS:
        if (!dmxdev->demux->get_caps) {
            ret = -EINVAL;
            break;
        }
        ret = dmxdev->demux->get_caps(dmxdev->demux, parg);
        break;

    case DMX_SET_SOURCE:
        if (!dmxdev->demux->set_source) {
            ret = -EINVAL;
            break;
        }
        ret = dmxdev->demux->set_source(dmxdev->demux, parg);
        break;

    case DMX_GET_STC:
        if (!dmxdev->demux->get_stc) {
            ret = -EINVAL;
            break;
        }
        ret = dmxdev->demux->get_stc(dmxdev->demux,
                         ((struct dmx_stc *)parg)->num,
                         &((struct dmx_stc *)parg)->stc,
                         &((struct dmx_stc *)parg)->base);
        break;

    default:
        ret = -EINVAL;
        break;
    }
    mutex_unlock(&dmxdev->mutex);
    return ret;
}
Example #5
0
File: dmxdev.c Project: 274914765/C
static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
{
    struct dmxdev *dmxdev = filter->dev;
    void *mem;
    int ret, i;

    if (filter->state < DMXDEV_STATE_SET)
        return -EINVAL;

    if (filter->state >= DMXDEV_STATE_GO)
        dvb_dmxdev_filter_stop(filter);

    if (!filter->buffer.data) {
        mem = vmalloc(filter->buffer.size);
        if (!mem)
            return -ENOMEM;
        spin_lock_irq(&filter->dev->lock);
        filter->buffer.data = mem;
        spin_unlock_irq(&filter->dev->lock);
    }

    dvb_ringbuffer_flush(&filter->buffer);

    switch (filter->type) {
    case DMXDEV_TYPE_SEC:
    {
        struct dmx_sct_filter_params *para = &filter->params.sec;
        struct dmx_section_filter **secfilter = &filter->filter.sec;
        struct dmx_section_feed **secfeed = &filter->feed.sec;

        *secfilter = NULL;
        *secfeed = NULL;


        /* find active filter/feed with same PID */
        for (i = 0; i < dmxdev->filternum; i++) {
            if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&
                dmxdev->filter[i].type == DMXDEV_TYPE_SEC &&
                dmxdev->filter[i].params.sec.pid == para->pid) {
                *secfeed = dmxdev->filter[i].feed.sec;
                break;
            }
        }

        /* if no feed found, try to allocate new one */
        if (!*secfeed) {
            ret = dmxdev->demux->allocate_section_feed(dmxdev->demux,
                                   secfeed,
                                   dvb_dmxdev_section_callback);
            if (ret < 0) {
                printk("DVB (%s): could not alloc feed\n",
                       __func__);
                return ret;
            }

            ret = (*secfeed)->set(*secfeed, para->pid, 32768,
                          (para->flags & DMX_CHECK_CRC) ? 1 : 0);
            if (ret < 0) {
                printk("DVB (%s): could not set feed\n",
                       __func__);
                dvb_dmxdev_feed_restart(filter);
                return ret;
            }
        } else {
            dvb_dmxdev_feed_stop(filter);
        }

        ret = (*secfeed)->allocate_filter(*secfeed, secfilter);
        if (ret < 0) {
            dvb_dmxdev_feed_restart(filter);
            filter->feed.sec->start_filtering(*secfeed);
            dprintk("could not get filter\n");
            return ret;
        }

        (*secfilter)->priv = filter;

        memcpy(&((*secfilter)->filter_value[3]),
               &(para->filter.filter[1]), DMX_FILTER_SIZE - 1);
        memcpy(&(*secfilter)->filter_mask[3],
               &para->filter.mask[1], DMX_FILTER_SIZE - 1);
        memcpy(&(*secfilter)->filter_mode[3],
               &para->filter.mode[1], DMX_FILTER_SIZE - 1);

        (*secfilter)->filter_value[0] = para->filter.filter[0];
        (*secfilter)->filter_mask[0] = para->filter.mask[0];
        (*secfilter)->filter_mode[0] = para->filter.mode[0];
        (*secfilter)->filter_mask[1] = 0;
        (*secfilter)->filter_mask[2] = 0;

        filter->todo = 0;

        ret = filter->feed.sec->start_filtering(filter->feed.sec);
        if (ret < 0)
            return ret;

        dvb_dmxdev_filter_timer(filter);
        break;
    }
    case DMXDEV_TYPE_PES:
    {
        struct timespec timeout = { 0 };
        struct dmx_pes_filter_params *para = &filter->params.pes;
        dmx_output_t otype;
        int ret;
        int ts_type;
        enum dmx_ts_pes ts_pes;
        struct dmx_ts_feed **tsfeed = &filter->feed.ts;

        filter->feed.ts = NULL;
        otype = para->output;

        ts_pes = (enum dmx_ts_pes)para->pes_type;

        if (ts_pes < DMX_PES_OTHER)
            ts_type = TS_DECODER;
        else
            ts_type = 0;

        if (otype == DMX_OUT_TS_TAP)
            ts_type |= TS_PACKET;
        else if (otype == DMX_OUT_TSDEMUX_TAP)
            ts_type |= TS_PACKET | TS_DEMUX;
        else if (otype == DMX_OUT_TAP)
            ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;

        ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux,
                              tsfeed,
                              dvb_dmxdev_ts_callback);
        if (ret < 0)
            return ret;

        (*tsfeed)->priv = filter;

        ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
                     32768, timeout);
        if (ret < 0) {
            dmxdev->demux->release_ts_feed(dmxdev->demux,
                               *tsfeed);
            return ret;
        }

        ret = filter->feed.ts->start_filtering(filter->feed.ts);
        if (ret < 0) {
            dmxdev->demux->release_ts_feed(dmxdev->demux,
                               *tsfeed);
            return ret;
        }

        break;
    }
    default:
        return -EINVAL;
    }

    dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
    return 0;
}
Example #6
0
static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
			      unsigned int cmd, void *parg)
{
	struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
	struct dmxdev *dmxdev=dmxdevfilter->dev;
	unsigned long arg=(unsigned long) parg;
	int ret=0;
  
	if (down_interruptible (&dmxdev->mutex))
		return -ERESTARTSYS;

	switch (cmd) {
	case DMX_START:
		if (down_interruptible(&dmxdevfilter->mutex)) {
			up(&dmxdev->mutex);
			return -ERESTARTSYS;
		}
		if (dmxdevfilter->state<DMXDEV_STATE_SET)
			ret = -EINVAL;
		else
			ret = dvb_dmxdev_filter_start(dmxdevfilter);
		up(&dmxdevfilter->mutex);
		break;

	case DMX_STOP:
		if (down_interruptible(&dmxdevfilter->mutex)) {
			up(&dmxdev->mutex);
			return -ERESTARTSYS;
		}
		ret=dvb_dmxdev_filter_stop(dmxdevfilter);
		up(&dmxdevfilter->mutex);
		break;

	case DMX_SET_FILTER: 
		if (down_interruptible(&dmxdevfilter->mutex)) {
			up(&dmxdev->mutex);
			return -ERESTARTSYS;
		}
		ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, 
				    (struct dmx_sct_filter_params *)parg);
		up(&dmxdevfilter->mutex);
		break;

	case DMX_SET_PES_FILTER: 
		if (down_interruptible(&dmxdevfilter->mutex)) {
			up(&dmxdev->mutex);
			return -ERESTARTSYS;
		}
		ret=dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, 
					       (struct dmx_pes_filter_params *)parg);
		up(&dmxdevfilter->mutex);
		break;

	case DMX_SET_BUFFER_SIZE: 
		if (down_interruptible(&dmxdevfilter->mutex)) {
			up(&dmxdev->mutex);
			return -ERESTARTSYS;
		}
		ret=dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);
		up(&dmxdevfilter->mutex);
		break;
	
	case DMX_GET_EVENT: 
		break;
		
	case DMX_GET_PES_PIDS: 
		if (!dmxdev->demux->get_pes_pids) {
			ret=-EINVAL;
			break;
		}
		dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg);
		break;

	case DMX_GET_STC:
		if (!dmxdev->demux->get_stc) {
		        ret=-EINVAL;
			break;
		}
		ret = dmxdev->demux->get_stc(dmxdev->demux,
				((struct dmx_stc *)parg)->num,
				&((struct dmx_stc *)parg)->stc,
				&((struct dmx_stc *)parg)->base);
		break;

	default:
		ret=-EINVAL;
	}
	up(&dmxdev->mutex);
	return ret;
}