1 // SPDX-License-Identifier: GPL-2.0
2 /* dvb-usb-urb.c is part of the DVB USB library.
4 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
5 * see dvb-usb-init.c for copyright information.
7 * This file keeps functions for initializing and handling the
10 #include "dvb-usb-common.h"
12 int dvb_usb_generic_rw(struct dvb_usb_device
*d
, u8
*wbuf
, u16 wlen
, u8
*rbuf
,
13 u16 rlen
, int delay_ms
)
15 int actlen
,ret
= -ENOMEM
;
17 if (!d
|| wbuf
== NULL
|| wlen
== 0)
20 if (d
->props
.generic_bulk_ctrl_endpoint
== 0) {
21 err("endpoint for generic control not specified.");
25 if ((ret
= mutex_lock_interruptible(&d
->usb_mutex
)))
29 debug_dump(wbuf
,wlen
,deb_xfer
);
31 ret
= usb_bulk_msg(d
->udev
,usb_sndbulkpipe(d
->udev
,
32 d
->props
.generic_bulk_ctrl_endpoint
), wbuf
,wlen
,&actlen
,
36 err("bulk message failed: %d (%d/%d)",ret
,wlen
,actlen
);
38 ret
= actlen
!= wlen
? -1 : 0;
40 /* an answer is expected, and no error before */
41 if (!ret
&& rbuf
&& rlen
) {
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
,
52 err("recv bulk message failed: %d",ret
);
55 debug_dump(rbuf
,actlen
,deb_xfer
);
59 mutex_unlock(&d
->usb_mutex
);
62 EXPORT_SYMBOL(dvb_usb_generic_rw
);
64 int dvb_usb_generic_write(struct dvb_usb_device
*d
, u8
*buf
, u16 len
)
66 return dvb_usb_generic_rw(d
,buf
,len
,NULL
,0,0);
68 EXPORT_SYMBOL(dvb_usb_generic_write
);
70 static void dvb_usb_data_complete(struct usb_data_stream
*stream
, u8
*buffer
, size_t length
)
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
);
77 static void dvb_usb_data_complete_204(struct usb_data_stream
*stream
, u8
*buffer
, size_t length
)
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
);
84 static void dvb_usb_data_complete_raw(struct usb_data_stream
*stream
,
85 u8
*buffer
, size_t length
)
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
);
92 int dvb_usb_adapter_stream_init(struct dvb_usb_adapter
*adap
)
95 for (i
= 0; i
< adap
->props
.num_frontends
; i
++) {
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
;
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
;
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
);
116 int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter
*adap
)
119 for (i
= 0; i
< adap
->props
.num_frontends
; i
++)
120 usb_urb_exit(&adap
->fe_adap
[i
].stream
);