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