Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dvb-usb-urb.c
Go to the documentation of this file.
1 /* dvb-usb-urb.c is part of the DVB USB library.
2  *
3  * Copyright (C) 2004-6 Patrick Boettcher ([email protected])
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 
11 int 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 
59  return ret;
60 }
62 
64 {
65  return dvb_usb_generic_rw(d,buf,len,NULL,0,0);
66 }
68 
69 static 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 
76 static 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 
83 static 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 
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 
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 }