Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * DVB USB framework
0004  *
0005  * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@posteo.de>
0006  * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
0007  */
0008 
0009 #include "dvb_usb_common.h"
0010 
0011 static int dvb_usb_v2_generic_io(struct dvb_usb_device *d,
0012         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
0013 {
0014     int ret, actual_length;
0015 
0016     if (!wbuf || !wlen || !d->props->generic_bulk_ctrl_endpoint ||
0017             !d->props->generic_bulk_ctrl_endpoint_response) {
0018         dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, -EINVAL);
0019         return -EINVAL;
0020     }
0021 
0022     dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf);
0023 
0024     ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
0025             d->props->generic_bulk_ctrl_endpoint), wbuf, wlen,
0026             &actual_length, 2000);
0027     if (ret) {
0028         dev_err(&d->udev->dev, "%s: usb_bulk_msg() failed=%d\n",
0029                 KBUILD_MODNAME, ret);
0030         return ret;
0031     }
0032     if (actual_length != wlen) {
0033         dev_err(&d->udev->dev, "%s: usb_bulk_msg() write length=%d, actual=%d\n",
0034             KBUILD_MODNAME, wlen, actual_length);
0035         return -EIO;
0036     }
0037 
0038     /* an answer is expected */
0039     if (rbuf && rlen) {
0040         if (d->props->generic_bulk_ctrl_delay)
0041             usleep_range(d->props->generic_bulk_ctrl_delay,
0042                     d->props->generic_bulk_ctrl_delay
0043                     + 20000);
0044 
0045         ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
0046                 d->props->generic_bulk_ctrl_endpoint_response),
0047                 rbuf, rlen, &actual_length, 2000);
0048         if (ret)
0049             dev_err(&d->udev->dev,
0050                     "%s: 2nd usb_bulk_msg() failed=%d\n",
0051                     KBUILD_MODNAME, ret);
0052 
0053         dev_dbg(&d->udev->dev, "%s: <<< %*ph\n", __func__,
0054                 actual_length, rbuf);
0055     }
0056 
0057     return ret;
0058 }
0059 
0060 int dvb_usbv2_generic_rw(struct dvb_usb_device *d,
0061         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
0062 {
0063     int ret;
0064 
0065     mutex_lock(&d->usb_mutex);
0066     ret = dvb_usb_v2_generic_io(d, wbuf, wlen, rbuf, rlen);
0067     mutex_unlock(&d->usb_mutex);
0068 
0069     return ret;
0070 }
0071 EXPORT_SYMBOL(dvb_usbv2_generic_rw);
0072 
0073 int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
0074 {
0075     int ret;
0076 
0077     mutex_lock(&d->usb_mutex);
0078     ret = dvb_usb_v2_generic_io(d, buf, len, NULL, 0);
0079     mutex_unlock(&d->usb_mutex);
0080 
0081     return ret;
0082 }
0083 EXPORT_SYMBOL(dvb_usbv2_generic_write);
0084 
0085 int dvb_usbv2_generic_rw_locked(struct dvb_usb_device *d,
0086         u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
0087 {
0088     return dvb_usb_v2_generic_io(d, wbuf, wlen, rbuf, rlen);
0089 }
0090 EXPORT_SYMBOL(dvb_usbv2_generic_rw_locked);
0091 
0092 int dvb_usbv2_generic_write_locked(struct dvb_usb_device *d, u8 *buf, u16 len)
0093 {
0094     return dvb_usb_v2_generic_io(d, buf, len, NULL, 0);
0095 }
0096 EXPORT_SYMBOL(dvb_usbv2_generic_write_locked);