aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/dvb-usb/af9035.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/drivers/media/dvb/dvb-usb/af9035.c b/drivers/media/dvb/dvb-usb/af9035.c
index 6a83120afcd6..92d27aa80800 100644
--- a/drivers/media/dvb/dvb-usb/af9035.c
+++ b/drivers/media/dvb/dvb-usb/af9035.c
@@ -36,6 +36,22 @@ static struct af9033_config af9035_af9033_config[] = {
36 } 36 }
37}; 37};
38 38
39static u16 af9035_checksum(const u8 *buf, size_t len)
40{
41 size_t i;
42 u16 checksum = 0;
43
44 for (i = 1; i < len; i++) {
45 if (i % 2)
46 checksum += buf[i] << 8;
47 else
48 checksum += buf[i];
49 }
50 checksum = ~checksum;
51
52 return checksum;
53}
54
39static int af9035_ctrl_msg(struct usb_device *udev, struct usb_req *req) 55static int af9035_ctrl_msg(struct usb_device *udev, struct usb_req *req)
40{ 56{
41#define BUF_LEN 63 57#define BUF_LEN 63
@@ -44,11 +60,11 @@ static int af9035_ctrl_msg(struct usb_device *udev, struct usb_req *req)
44#define CHECKSUM_LEN 2 60#define CHECKSUM_LEN 2
45#define USB_TIMEOUT 2000 61#define USB_TIMEOUT 2000
46 62
47 int ret, i, act_len; 63 int ret, act_len;
48 u8 buf[BUF_LEN]; 64 u8 buf[BUF_LEN];
49 u32 msg_len; 65 u32 msg_len;
50 static u8 seq; /* packet sequence number */ 66 static u8 seq; /* packet sequence number */
51 u16 checksum = 0; 67 u16 checksum, tmpsum;
52 68
53 /* buffer overflow check */ 69 /* buffer overflow check */
54 if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) || 70 if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
@@ -69,14 +85,7 @@ static int af9035_ctrl_msg(struct usb_device *udev, struct usb_req *req)
69 memcpy(&buf[4], req->wbuf, req->wlen); 85 memcpy(&buf[4], req->wbuf, req->wlen);
70 86
71 /* calc and add checksum */ 87 /* calc and add checksum */
72 for (i = 1; i < buf[0]-1; i++) { 88 checksum = af9035_checksum(buf, buf[0] - 1);
73 if (i % 2)
74 checksum += buf[i] << 8;
75 else
76 checksum += buf[i];
77 }
78 checksum = ~checksum;
79
80 buf[buf[0]-1] = (checksum >> 8); 89 buf[buf[0]-1] = (checksum >> 8);
81 buf[buf[0]-0] = (checksum & 0xff); 90 buf[buf[0]-0] = (checksum & 0xff);
82 91
@@ -106,7 +115,23 @@ static int af9035_ctrl_msg(struct usb_device *udev, struct usb_req *req)
106 ret = -EIO; 115 ret = -EIO;
107 goto err_mutex_unlock; 116 goto err_mutex_unlock;
108 } 117 }
118 if (act_len != msg_len) {
119 err("recv bulk message truncated (%d != %u)\n",
120 act_len, (unsigned int)msg_len);
121 ret = -EIO;
122 goto err_mutex_unlock;
123 }
109 124
125 /* verify checksum */
126 checksum = af9035_checksum(buf, act_len - 2);
127 tmpsum = (buf[act_len - 2] << 8) | buf[act_len - 1];
128 if (tmpsum != checksum) {
129 err("%s: command=%02X checksum mismatch (%04X != %04X)\n",
130 __func__, req->cmd,
131 (unsigned int)tmpsum, (unsigned int)checksum);
132 ret = -EIO;
133 goto err_mutex_unlock;
134 }
110 /* check status */ 135 /* check status */
111 if (buf[2]) { 136 if (buf[2]) {
112 pr_debug("%s: command=%02x failed fw error=%d\n", __func__, 137 pr_debug("%s: command=%02x failed fw error=%d\n", __func__,