int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg)
{
	struct dvb_usb_device *d = usb_get_intfdata(intf);
	int ret = 0, i, active_fe;
	struct dvb_frontend *fe;
	dev_dbg(&d->udev->dev, "%s:\n", __func__);

	/* stop remote controller poll */
	if (d->rc_polling_active)
		cancel_delayed_work_sync(&d->rc_query_work);

	for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; 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];
			d->adapter[i].suspend_resume_active = true;

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

			/* stop usb streaming */
			usb_urb_killv2(&d->adapter[i].stream);

			ret = dvb_frontend_suspend(fe);
		}
	}

	return ret;
}
Exemplo n.º 2
0
int usb_urb_submitv2(struct usb_data_stream *stream,
		struct usb_data_stream_properties *props)
{
	int i, ret;

	if (props) {
		ret = usb_urb_reconfig(stream, props);
		if (ret < 0)
			return ret;
	}

	for (i = 0; i < stream->urbs_initialized; i++) {
		dev_dbg(&stream->udev->dev, "%s: submit urb=%d\n", __func__, i);
		ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC);
		if (ret) {
			dev_err(&stream->udev->dev,
					"%s: could not submit urb no. %d - get them all back\n",
					KBUILD_MODNAME, i);
			usb_urb_killv2(stream);
			return ret;
		}
		stream->urbs_submitted++;
	}
	return 0;
}
static int dvb_usb_stop_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;
	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);

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

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

	/* we cannot stop streaming until last PID is removed */
	if (--adap->feed_count > 0)
		goto skip_feed_stop;

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

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

	/* kill USB streaming packets */
	usb_urb_killv2(&adap->stream);

	/* clear 'streaming' status bit */
	clear_bit(ADAP_STREAMING, &adap->state_bits);
	smp_mb__after_atomic();
	wake_up_bit(&adap->state_bits, ADAP_STREAMING);
skip_feed_stop:

	if (ret)
		dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}
Exemplo n.º 4
0
static int usb_urb_free_urbs(struct usb_data_stream *stream)
{
	int i;

	usb_urb_killv2(stream);

	for (i = stream->urbs_initialized - 1; i >= 0; i--) {
		if (stream->urb_list[i]) {
			dev_dbg(&stream->udev->dev, "%s: free urb=%d\n",
					__func__, i);
			/* free the URBs */
			usb_free_urb(stream->urb_list[i]);
		}
	}
	stream->urbs_initialized = 0;

	return 0;
}
Exemplo n.º 5
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;
}