blob: 11e284b371bec9dd3ba03c5ef0cfcc1edfaad78c [file] [log] [blame]
Antti Palosaaric79b3392012-05-23 10:06:09 -03001/* 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
Antti Palosaari9f6f82e2012-06-19 22:31:04 -030011#undef DVB_USB_XFER_DEBUG
Antti Palosaaric79b3392012-05-23 10:06:09 -030012int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
Antti Palosaari1162c7b2012-06-20 20:27:42 -030013 u16 rlen)
Antti Palosaaric79b3392012-05-23 10:06:09 -030014{
Antti Palosaari1162c7b2012-06-20 20:27:42 -030015 int ret, actual_length;
Antti Palosaaric79b3392012-05-23 10:06:09 -030016
Antti Palosaari1162c7b2012-06-20 20:27:42 -030017 if (!d || !wbuf || !wlen || !d->props->generic_bulk_ctrl_endpoint ||
18 !d->props->generic_bulk_ctrl_endpoint_response) {
19 pr_debug("%s: failed=%d\n", __func__, -EINVAL);
Antti Palosaaric79b3392012-05-23 10:06:09 -030020 return -EINVAL;
21 }
22
Antti Palosaari4e60d952012-05-24 14:44:21 -030023 ret = mutex_lock_interruptible(&d->usb_mutex);
Antti Palosaari1162c7b2012-06-20 20:27:42 -030024 if (ret < 0)
Antti Palosaaric79b3392012-05-23 10:06:09 -030025 return ret;
26
Antti Palosaari9f6f82e2012-06-19 22:31:04 -030027#ifdef DVB_USB_XFER_DEBUG
Antti Palosaari23d8e632012-06-06 22:46:38 -030028 print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": >>> ", DUMP_PREFIX_NONE,
29 32, 1, wbuf, wlen, 0);
Antti Palosaari9f6f82e2012-06-19 22:31:04 -030030#endif
Antti Palosaari4e60d952012-05-24 14:44:21 -030031 ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
Antti Palosaarif093c382012-06-12 16:25:01 -030032 d->props->generic_bulk_ctrl_endpoint), wbuf, wlen,
Antti Palosaari1162c7b2012-06-20 20:27:42 -030033 &actual_length, 2000);
34 if (ret < 0)
35 pr_err("%s: usb_bulk_msg() failed=%d\n", KBUILD_MODNAME, ret);
Antti Palosaaric79b3392012-05-23 10:06:09 -030036 else
Antti Palosaari1162c7b2012-06-20 20:27:42 -030037 ret = actual_length != wlen ? -EIO : 0;
Antti Palosaaric79b3392012-05-23 10:06:09 -030038
39 /* an answer is expected, and no error before */
40 if (!ret && rbuf && rlen) {
Antti Palosaari1162c7b2012-06-20 20:27:42 -030041 if (d->props->generic_bulk_ctrl_delay)
42 usleep_range(d->props->generic_bulk_ctrl_delay,
43 d->props->generic_bulk_ctrl_delay
44 + 20000);
Antti Palosaaric79b3392012-05-23 10:06:09 -030045
Antti Palosaari4e60d952012-05-24 14:44:21 -030046 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
Antti Palosaari1162c7b2012-06-20 20:27:42 -030047 d->props->generic_bulk_ctrl_endpoint_response),
48 rbuf, rlen, &actual_length, 2000);
Antti Palosaaric79b3392012-05-23 10:06:09 -030049 if (ret)
Antti Palosaari1162c7b2012-06-20 20:27:42 -030050 pr_err("%s: 2nd usb_bulk_msg() failed=%d\n",
Antti Palosaari23d8e632012-06-06 22:46:38 -030051 KBUILD_MODNAME, ret);
Antti Palosaari1162c7b2012-06-20 20:27:42 -030052
Antti Palosaari9f6f82e2012-06-19 22:31:04 -030053#ifdef DVB_USB_XFER_DEBUG
54 print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": <<< ",
Antti Palosaari1162c7b2012-06-20 20:27:42 -030055 DUMP_PREFIX_NONE, 32, 1, rbuf, actual_length,
56 0);
Antti Palosaari9f6f82e2012-06-19 22:31:04 -030057#endif
Antti Palosaaric79b3392012-05-23 10:06:09 -030058 }
59
60 mutex_unlock(&d->usb_mutex);
61 return ret;
62}
63EXPORT_SYMBOL(dvb_usbv2_generic_rw);
64
65int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
66{
Antti Palosaari1162c7b2012-06-20 20:27:42 -030067 return dvb_usbv2_generic_rw(d, buf, len, NULL, 0);
Antti Palosaaric79b3392012-05-23 10:06:09 -030068}
69EXPORT_SYMBOL(dvb_usbv2_generic_write);