Antti Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 1 | /* 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 Palosaari | 9f6f82e | 2012-06-19 22:31:04 -0300 | [diff] [blame] | 11 | #undef DVB_USB_XFER_DEBUG |
Antti Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 12 | int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 13 | u16 rlen) |
Antti Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 14 | { |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 15 | int ret, actual_length; |
Antti Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 16 | |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 17 | 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 Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 20 | return -EINVAL; |
| 21 | } |
| 22 | |
Antti Palosaari | 4e60d95 | 2012-05-24 14:44:21 -0300 | [diff] [blame] | 23 | ret = mutex_lock_interruptible(&d->usb_mutex); |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 24 | if (ret < 0) |
Antti Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 25 | return ret; |
| 26 | |
Antti Palosaari | 9f6f82e | 2012-06-19 22:31:04 -0300 | [diff] [blame] | 27 | #ifdef DVB_USB_XFER_DEBUG |
Antti Palosaari | 23d8e63 | 2012-06-06 22:46:38 -0300 | [diff] [blame] | 28 | print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": >>> ", DUMP_PREFIX_NONE, |
| 29 | 32, 1, wbuf, wlen, 0); |
Antti Palosaari | 9f6f82e | 2012-06-19 22:31:04 -0300 | [diff] [blame] | 30 | #endif |
Antti Palosaari | 4e60d95 | 2012-05-24 14:44:21 -0300 | [diff] [blame] | 31 | ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev, |
Antti Palosaari | f093c38 | 2012-06-12 16:25:01 -0300 | [diff] [blame] | 32 | d->props->generic_bulk_ctrl_endpoint), wbuf, wlen, |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 33 | &actual_length, 2000); |
| 34 | if (ret < 0) |
| 35 | pr_err("%s: usb_bulk_msg() failed=%d\n", KBUILD_MODNAME, ret); |
Antti Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 36 | else |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 37 | ret = actual_length != wlen ? -EIO : 0; |
Antti Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 38 | |
| 39 | /* an answer is expected, and no error before */ |
| 40 | if (!ret && rbuf && rlen) { |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 41 | 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 Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 45 | |
Antti Palosaari | 4e60d95 | 2012-05-24 14:44:21 -0300 | [diff] [blame] | 46 | ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 47 | d->props->generic_bulk_ctrl_endpoint_response), |
| 48 | rbuf, rlen, &actual_length, 2000); |
Antti Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 49 | if (ret) |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 50 | pr_err("%s: 2nd usb_bulk_msg() failed=%d\n", |
Antti Palosaari | 23d8e63 | 2012-06-06 22:46:38 -0300 | [diff] [blame] | 51 | KBUILD_MODNAME, ret); |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 52 | |
Antti Palosaari | 9f6f82e | 2012-06-19 22:31:04 -0300 | [diff] [blame] | 53 | #ifdef DVB_USB_XFER_DEBUG |
| 54 | print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": <<< ", |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 55 | DUMP_PREFIX_NONE, 32, 1, rbuf, actual_length, |
| 56 | 0); |
Antti Palosaari | 9f6f82e | 2012-06-19 22:31:04 -0300 | [diff] [blame] | 57 | #endif |
Antti Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 58 | } |
| 59 | |
| 60 | mutex_unlock(&d->usb_mutex); |
| 61 | return ret; |
| 62 | } |
| 63 | EXPORT_SYMBOL(dvb_usbv2_generic_rw); |
| 64 | |
| 65 | int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len) |
| 66 | { |
Antti Palosaari | 1162c7b | 2012-06-20 20:27:42 -0300 | [diff] [blame^] | 67 | return dvb_usbv2_generic_rw(d, buf, len, NULL, 0); |
Antti Palosaari | c79b339 | 2012-05-23 10:06:09 -0300 | [diff] [blame] | 68 | } |
| 69 | EXPORT_SYMBOL(dvb_usbv2_generic_write); |