linux/drivers/media/usb/dvb-usb/dvb-usb-urb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* dvb-usb-urb.c is part of the DVB USB library.
   3 *
   4 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
   5 * see dvb-usb-init.c for copyright information.
   6 *
   7 * This file keeps functions for initializing and handling the
   8 * USB and URB stuff.
   9 */
  10#include "dvb-usb-common.h"
  11
  12int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
  13        u16 rlen, int delay_ms)
  14{
  15        int actlen = 0, ret = -ENOMEM;
  16
  17        if (!d || wbuf == NULL || wlen == 0)
  18                return -EINVAL;
  19
  20        if (d->props.generic_bulk_ctrl_endpoint == 0) {
  21                err("endpoint for generic control not specified.");
  22                return -EINVAL;
  23        }
  24
  25        if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
  26                return ret;
  27
  28        deb_xfer(">>> ");
  29        debug_dump(wbuf,wlen,deb_xfer);
  30
  31        ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
  32                        d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
  33                        2000);
  34
  35        if (ret)
  36                err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
  37        else
  38                ret = actlen != wlen ? -1 : 0;
  39
  40        /* an answer is expected, and no error before */
  41        if (!ret && rbuf && rlen) {
  42                if (delay_ms)
  43                        msleep(delay_ms);
  44
  45                ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
  46                                d->props.generic_bulk_ctrl_endpoint_response ?
  47                                d->props.generic_bulk_ctrl_endpoint_response :
  48                                d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
  49                                2000);
  50
  51                if (ret)
  52                        err("recv bulk message failed: %d",ret);
  53                else {
  54                        deb_xfer("<<< ");
  55                        debug_dump(rbuf,actlen,deb_xfer);
  56                }
  57        }
  58
  59        mutex_unlock(&d->usb_mutex);
  60        return ret;
  61}
  62EXPORT_SYMBOL(dvb_usb_generic_rw);
  63
  64int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
  65{
  66        return dvb_usb_generic_rw(d,buf,len,NULL,0,0);
  67}
  68EXPORT_SYMBOL(dvb_usb_generic_write);
  69
  70static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, size_t length)
  71{
  72        struct dvb_usb_adapter *adap = stream->user_priv;
  73        if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
  74                dvb_dmx_swfilter(&adap->demux, buffer, length);
  75}
  76
  77static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buffer, size_t length)
  78{
  79        struct dvb_usb_adapter *adap = stream->user_priv;
  80        if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
  81                dvb_dmx_swfilter_204(&adap->demux, buffer, length);
  82}
  83
  84static void dvb_usb_data_complete_raw(struct usb_data_stream *stream,
  85                                      u8 *buffer, size_t length)
  86{
  87        struct dvb_usb_adapter *adap = stream->user_priv;
  88        if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
  89                dvb_dmx_swfilter_raw(&adap->demux, buffer, length);
  90}
  91
  92int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
  93{
  94        int i, ret = 0;
  95        for (i = 0; i < adap->props.num_frontends; i++) {
  96
  97                adap->fe_adap[i].stream.udev      = adap->dev->udev;
  98                if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_204_BYTE_TS)
  99                        adap->fe_adap[i].stream.complete =
 100                                dvb_usb_data_complete_204;
 101                else
 102                if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD)
 103                        adap->fe_adap[i].stream.complete =
 104                                dvb_usb_data_complete_raw;
 105                else
 106                adap->fe_adap[i].stream.complete  = dvb_usb_data_complete;
 107                adap->fe_adap[i].stream.user_priv = adap;
 108                ret = usb_urb_init(&adap->fe_adap[i].stream,
 109                                   &adap->props.fe[i].stream);
 110                if (ret < 0)
 111                        break;
 112        }
 113        return ret;
 114}
 115
 116int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap)
 117{
 118        int i;
 119        for (i = 0; i < adap->props.num_frontends; i++)
 120                usb_urb_exit(&adap->fe_adap[i].stream);
 121        return 0;
 122}
 123