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