2012-05-23 21:06:09 +08:00
|
|
|
/* dvb-usb-urb.c is part of the DVB USB library.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
|
|
|
|
* see dvb-usb-init.c for copyright information.
|
|
|
|
*
|
|
|
|
* This file keeps functions for initializing and handling the
|
|
|
|
* USB and URB stuff.
|
|
|
|
*/
|
|
|
|
#include "dvb_usb_common.h"
|
|
|
|
|
2012-06-20 09:31:04 +08:00
|
|
|
#undef DVB_USB_XFER_DEBUG
|
2012-05-23 21:06:09 +08:00
|
|
|
int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
|
2012-06-21 07:27:42 +08:00
|
|
|
u16 rlen)
|
2012-05-23 21:06:09 +08:00
|
|
|
{
|
2012-06-21 07:27:42 +08:00
|
|
|
int ret, actual_length;
|
2012-05-23 21:06:09 +08:00
|
|
|
|
2012-06-21 07:27:42 +08:00
|
|
|
if (!d || !wbuf || !wlen || !d->props->generic_bulk_ctrl_endpoint ||
|
|
|
|
!d->props->generic_bulk_ctrl_endpoint_response) {
|
|
|
|
pr_debug("%s: failed=%d\n", __func__, -EINVAL);
|
2012-05-23 21:06:09 +08:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2012-05-25 01:44:21 +08:00
|
|
|
ret = mutex_lock_interruptible(&d->usb_mutex);
|
2012-06-21 07:27:42 +08:00
|
|
|
if (ret < 0)
|
2012-05-23 21:06:09 +08:00
|
|
|
return ret;
|
|
|
|
|
2012-06-20 09:31:04 +08:00
|
|
|
#ifdef DVB_USB_XFER_DEBUG
|
2012-06-07 09:46:38 +08:00
|
|
|
print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": >>> ", DUMP_PREFIX_NONE,
|
|
|
|
32, 1, wbuf, wlen, 0);
|
2012-06-20 09:31:04 +08:00
|
|
|
#endif
|
2012-05-25 01:44:21 +08:00
|
|
|
ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
|
2012-06-13 03:25:01 +08:00
|
|
|
d->props->generic_bulk_ctrl_endpoint), wbuf, wlen,
|
2012-06-21 07:27:42 +08:00
|
|
|
&actual_length, 2000);
|
|
|
|
if (ret < 0)
|
|
|
|
pr_err("%s: usb_bulk_msg() failed=%d\n", KBUILD_MODNAME, ret);
|
2012-05-23 21:06:09 +08:00
|
|
|
else
|
2012-06-21 07:27:42 +08:00
|
|
|
ret = actual_length != wlen ? -EIO : 0;
|
2012-05-23 21:06:09 +08:00
|
|
|
|
|
|
|
/* an answer is expected, and no error before */
|
|
|
|
if (!ret && rbuf && rlen) {
|
2012-06-21 07:27:42 +08:00
|
|
|
if (d->props->generic_bulk_ctrl_delay)
|
|
|
|
usleep_range(d->props->generic_bulk_ctrl_delay,
|
|
|
|
d->props->generic_bulk_ctrl_delay
|
|
|
|
+ 20000);
|
2012-05-23 21:06:09 +08:00
|
|
|
|
2012-05-25 01:44:21 +08:00
|
|
|
ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
|
2012-06-21 07:27:42 +08:00
|
|
|
d->props->generic_bulk_ctrl_endpoint_response),
|
|
|
|
rbuf, rlen, &actual_length, 2000);
|
2012-05-23 21:06:09 +08:00
|
|
|
if (ret)
|
2012-06-21 07:27:42 +08:00
|
|
|
pr_err("%s: 2nd usb_bulk_msg() failed=%d\n",
|
2012-06-07 09:46:38 +08:00
|
|
|
KBUILD_MODNAME, ret);
|
2012-06-21 07:27:42 +08:00
|
|
|
|
2012-06-20 09:31:04 +08:00
|
|
|
#ifdef DVB_USB_XFER_DEBUG
|
|
|
|
print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": <<< ",
|
2012-06-21 07:27:42 +08:00
|
|
|
DUMP_PREFIX_NONE, 32, 1, rbuf, actual_length,
|
|
|
|
0);
|
2012-06-20 09:31:04 +08:00
|
|
|
#endif
|
2012-05-23 21:06:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
mutex_unlock(&d->usb_mutex);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(dvb_usbv2_generic_rw);
|
|
|
|
|
|
|
|
int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
|
|
|
|
{
|
2012-06-21 07:27:42 +08:00
|
|
|
return dvb_usbv2_generic_rw(d, buf, len, NULL, 0);
|
2012-05-23 21:06:09 +08:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(dvb_usbv2_generic_write);
|