2012-05-23 13:06:09 +00: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 01:31:04 +00:00
|
|
|
#undef DVB_USB_XFER_DEBUG
|
2012-05-23 13:06:09 +00:00
|
|
|
int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
|
|
|
|
u16 rlen, int delay_ms)
|
|
|
|
{
|
2012-05-24 17:44:21 +00:00
|
|
|
int actlen, ret = -ENOMEM;
|
2012-05-23 13:06:09 +00:00
|
|
|
|
|
|
|
if (!d || wbuf == NULL || wlen == 0)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2012-06-12 19:25:01 +00:00
|
|
|
if (d->props->generic_bulk_ctrl_endpoint == 0) {
|
2012-06-07 20:52:06 +00:00
|
|
|
pr_err("%s: endpoint for generic control not specified\n",
|
2012-06-07 01:46:38 +00:00
|
|
|
KBUILD_MODNAME);
|
2012-05-23 13:06:09 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2012-05-24 17:44:21 +00:00
|
|
|
ret = mutex_lock_interruptible(&d->usb_mutex);
|
|
|
|
if (ret)
|
2012-05-23 13:06:09 +00:00
|
|
|
return ret;
|
|
|
|
|
2012-06-20 01:31:04 +00:00
|
|
|
#ifdef DVB_USB_XFER_DEBUG
|
2012-06-07 01:46:38 +00:00
|
|
|
print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": >>> ", DUMP_PREFIX_NONE,
|
|
|
|
32, 1, wbuf, wlen, 0);
|
2012-06-20 01:31:04 +00:00
|
|
|
#endif
|
2012-05-23 13:06:09 +00:00
|
|
|
|
2012-05-24 17:44:21 +00:00
|
|
|
ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
|
2012-06-12 19:25:01 +00:00
|
|
|
d->props->generic_bulk_ctrl_endpoint), wbuf, wlen,
|
2012-05-24 17:44:21 +00:00
|
|
|
&actlen, 2000);
|
2012-05-23 13:06:09 +00:00
|
|
|
|
|
|
|
if (ret)
|
2012-06-07 20:52:06 +00:00
|
|
|
pr_err("%s: bulk message failed: %d (%d/%d)\n", KBUILD_MODNAME,
|
2012-06-07 01:46:38 +00:00
|
|
|
ret, wlen, actlen);
|
2012-05-23 13:06:09 +00:00
|
|
|
else
|
|
|
|
ret = actlen != wlen ? -1 : 0;
|
|
|
|
|
|
|
|
/* an answer is expected, and no error before */
|
|
|
|
if (!ret && rbuf && rlen) {
|
|
|
|
if (delay_ms)
|
|
|
|
msleep(delay_ms);
|
|
|
|
|
2012-05-24 17:44:21 +00:00
|
|
|
ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
|
2012-06-12 19:25:01 +00:00
|
|
|
d->props->generic_bulk_ctrl_endpoint_response ?
|
|
|
|
d->props->generic_bulk_ctrl_endpoint_response :
|
|
|
|
d->props->generic_bulk_ctrl_endpoint),
|
2012-05-24 17:44:21 +00:00
|
|
|
rbuf, rlen, &actlen, 2000);
|
2012-05-23 13:06:09 +00:00
|
|
|
|
|
|
|
if (ret)
|
2012-06-07 20:52:06 +00:00
|
|
|
pr_err("%s: recv bulk message failed: %d\n",
|
2012-06-07 01:46:38 +00:00
|
|
|
KBUILD_MODNAME, ret);
|
2012-06-20 01:31:04 +00:00
|
|
|
#ifdef DVB_USB_XFER_DEBUG
|
|
|
|
print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": <<< ",
|
|
|
|
DUMP_PREFIX_NONE, 32, 1, rbuf, actlen, 0);
|
|
|
|
#endif
|
2012-05-23 13:06:09 +00: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-05-24 17:44:21 +00:00
|
|
|
return dvb_usbv2_generic_rw(d, buf, len, NULL, 0, 0);
|
2012-05-23 13:06:09 +00:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(dvb_usbv2_generic_write);
|