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; }
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; }