static int dvb_usbv2_resume_common(struct dvb_usb_device *d)
{
	int ret = 0, i, active_fe;
	struct dvb_frontend *fe;
	dev_dbg(&d->udev->dev, "%s:\n", __func__);

	for (i = 0; i < MAX_NO_OF_ADAPTER_PER_DEVICE; i++) {
		active_fe = d->adapter[i].active_fe;
		if (d->adapter[i].dvb_adap.priv && active_fe != -1) {
			fe = d->adapter[i].fe[active_fe];

			ret = dvb_frontend_resume(fe);

			/* resume usb streaming */
			usb_urb_submitv2(&d->adapter[i].stream, NULL);

			if (d->props->streaming_ctrl)
				d->props->streaming_ctrl(fe, 1);

			d->adapter[i].suspend_resume_active = false;
		}
	}

	/* start remote controller poll */
	if (d->rc_polling_active)
		schedule_delayed_work(&d->rc_query_work,
				msecs_to_jiffies(d->rc.interval));

	return ret;
}
static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
	struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
	struct dvb_usb_device *d = adap_to_d(adap);
	int ret = 0;
	struct usb_data_stream_properties stream_props;
	dev_dbg(&d->udev->dev,
			"%s: adap=%d active_fe=%d feed_type=%d setting pid [%s]: %04x (%04d) at index %d\n",
			__func__, adap->id, adap->active_fe, dvbdmxfeed->type,
			adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
			dvbdmxfeed->pid, dvbdmxfeed->index);

	/* wait init is done */
	wait_on_bit(&adap->state_bits, ADAP_INIT, TASK_UNINTERRUPTIBLE);

	if (adap->active_fe == -1)
		return -EINVAL;

	/* skip feed setup if we are already feeding */
	if (adap->feed_count++ > 0)
		goto skip_feed_start;

	/* set 'streaming' status bit */
	set_bit(ADAP_STREAMING, &adap->state_bits);

	/* resolve input and output streaming parameters */
	if (d->props->get_stream_config) {
		memcpy(&stream_props, &adap->props->stream,
				sizeof(struct usb_data_stream_properties));
		ret = d->props->get_stream_config(adap->fe[adap->active_fe],
				&adap->ts_type, &stream_props);
		if (ret)
			dev_err(&d->udev->dev,
					"%s: get_stream_config() failed=%d\n",
					KBUILD_MODNAME, ret);
	} else {
		stream_props = adap->props->stream;
	}

	switch (adap->ts_type) {
	case DVB_USB_FE_TS_TYPE_204:
		adap->stream.complete = dvb_usb_data_complete_204;
		break;
	case DVB_USB_FE_TS_TYPE_RAW:
		adap->stream.complete = dvb_usb_data_complete_raw;
		break;
	case DVB_USB_FE_TS_TYPE_188:
	default:
		adap->stream.complete = dvb_usb_data_complete;
		break;
	}

	/* submit USB streaming packets */
	usb_urb_submitv2(&adap->stream, &stream_props);

	/* enable HW PID filter */
	if (adap->pid_filtering && adap->props->pid_filter_ctrl) {
		ret = adap->props->pid_filter_ctrl(adap, 1);
		if (ret)
			dev_err(&d->udev->dev,
					"%s: pid_filter_ctrl() failed=%d\n",
					KBUILD_MODNAME, ret);
	}

	/* ask device to start streaming */
	if (d->props->streaming_ctrl) {
		ret = d->props->streaming_ctrl(adap->fe[adap->active_fe], 1);
		if (ret)
			dev_err(&d->udev->dev,
					"%s: streaming_ctrl() failed=%d\n",
					KBUILD_MODNAME, ret);
	}
skip_feed_start:

	/* add PID to device HW PID filter */
	if (adap->pid_filtering && adap->props->pid_filter) {
		ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
				dvbdmxfeed->pid, 1);
		if (ret)
			dev_err(&d->udev->dev, "%s: pid_filter() failed=%d\n",
					KBUILD_MODNAME, ret);
	}

	if (ret)
		dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}
Example #3
0
static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
		int count)
{
	struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
	struct dvb_usb_device *d = adap_to_d(adap);
	int ret;
	dev_dbg(&d->udev->dev, "%s: adap=%d active_fe=%d feed_type=%d " \
			"setting pid [%s]: %04x (%04d) at index %d '%s'\n",
			__func__, adap->id, adap->active_fe, dvbdmxfeed->type,
			adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
			dvbdmxfeed->pid, dvbdmxfeed->index,
			(count == 1) ? "on" : "off");

	if (adap->active_fe == -1)
		return -EINVAL;

	adap->feed_count += count;

	/* stop feeding if it is last pid */
	if (adap->feed_count == 0) {
		dev_dbg(&d->udev->dev, "%s: stop feeding\n", __func__);

		if (d->props->streaming_ctrl) {
			ret = d->props->streaming_ctrl(
					adap->fe[adap->active_fe], 0);
			if (ret < 0) {
				dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
						"failed=%d\n", KBUILD_MODNAME,
						ret);
				usb_urb_killv2(&adap->stream);
				goto err_mutex_unlock;
			}
		}
		usb_urb_killv2(&adap->stream);
		mutex_unlock(&adap->sync_mutex);
	}

	/* activate the pid on the device pid filter */
	if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
			adap->pid_filtering && adap->props->pid_filter) {
		ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
				dvbdmxfeed->pid, (count == 1) ? 1 : 0);
		if (ret < 0)
			dev_err(&d->udev->dev, "%s: pid_filter() failed=%d\n",
					KBUILD_MODNAME, ret);
	}

	/* start feeding if it is first pid */
	if (adap->feed_count == 1 && count == 1) {
		struct usb_data_stream_properties stream_props;
		mutex_lock(&adap->sync_mutex);
		dev_dbg(&d->udev->dev, "%s: start feeding\n", __func__);

		/* resolve input and output streaming paramters */
		if (d->props->get_stream_config) {
			memcpy(&stream_props, &adap->props->stream,
				sizeof(struct usb_data_stream_properties));
			ret = d->props->get_stream_config(
					adap->fe[adap->active_fe],
					&adap->ts_type, &stream_props);
			if (ret < 0)
				goto err_mutex_unlock;
		} else {
			stream_props = adap->props->stream;
		}

		switch (adap->ts_type) {
		case DVB_USB_FE_TS_TYPE_204:
			adap->stream.complete = dvb_usb_data_complete_204;
			break;
		case DVB_USB_FE_TS_TYPE_RAW:
			adap->stream.complete = dvb_usb_data_complete_raw;
			break;
		case DVB_USB_FE_TS_TYPE_188:
		default:
			adap->stream.complete = dvb_usb_data_complete;
			break;
		}

		usb_urb_submitv2(&adap->stream, &stream_props);

		if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
				adap->props->caps &
				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
				adap->props->pid_filter_ctrl) {
			ret = adap->props->pid_filter_ctrl(adap,
					adap->pid_filtering);
			if (ret < 0) {
				dev_err(&d->udev->dev, "%s: " \
						"pid_filter_ctrl() failed=%d\n",
						KBUILD_MODNAME, ret);
				goto err_mutex_unlock;
			}
		}

		if (d->props->streaming_ctrl) {
			ret = d->props->streaming_ctrl(
					adap->fe[adap->active_fe], 1);
			if (ret < 0) {
				dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
						"failed=%d\n", KBUILD_MODNAME,
						ret);
				goto err_mutex_unlock;
			}
		}
	}

	return 0;
err_mutex_unlock:
	mutex_unlock(&adap->sync_mutex);
	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}