aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index fdfa0f54291..ebb9981eb89 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -61,10 +61,13 @@ static struct af9013_config af9015_af9013_config[] = {
61 61
62static int af9015_rw_udev(struct usb_device *udev, struct req_t *req) 62static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
63{ 63{
64#define BUF_LEN 63
65#define REQ_HDR_LEN 8 /* send header size */
66#define ACK_HDR_LEN 2 /* rece header size */
64 int act_len, ret; 67 int act_len, ret;
65 u8 buf[64]; 68 u8 buf[BUF_LEN];
66 u8 write = 1; 69 u8 write = 1;
67 u8 msg_len = 8; 70 u8 msg_len = REQ_HDR_LEN;
68 static u8 seq; /* packet sequence number */ 71 static u8 seq; /* packet sequence number */
69 72
70 if (mutex_lock_interruptible(&af9015_usb_mutex) < 0) 73 if (mutex_lock_interruptible(&af9015_usb_mutex) < 0)
@@ -107,17 +110,26 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
107 goto error_unlock; 110 goto error_unlock;
108 } 111 }
109 112
113 /* buffer overflow check */
114 if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
115 (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
116 err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
117 ret = -EINVAL;
118 goto error_unlock;
119 }
120
110 /* write requested */ 121 /* write requested */
111 if (write) { 122 if (write) {
112 memcpy(&buf[8], req->data, req->data_len); 123 memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
113 msg_len += req->data_len; 124 msg_len += req->data_len;
114 } 125 }
126
115 deb_xfer(">>> "); 127 deb_xfer(">>> ");
116 debug_dump(buf, msg_len, deb_xfer); 128 debug_dump(buf, msg_len, deb_xfer);
117 129
118 /* send req */ 130 /* send req */
119 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len, 131 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
120 &act_len, AF9015_USB_TIMEOUT); 132 &act_len, AF9015_USB_TIMEOUT);
121 if (ret) 133 if (ret)
122 err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len); 134 err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len);
123 else 135 else
@@ -130,10 +142,14 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
130 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB) 142 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
131 goto exit_unlock; 143 goto exit_unlock;
132 144
133 /* receive ack and data if read req */ 145 /* write receives seq + status = 2 bytes
134 msg_len = 1 + 1 + req->data_len; /* seq + status + data len */ 146 read receives seq + status + data = 2 + N bytes */
147 msg_len = ACK_HDR_LEN;
148 if (!write)
149 msg_len += req->data_len;
150
135 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len, 151 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
136 &act_len, AF9015_USB_TIMEOUT); 152 &act_len, AF9015_USB_TIMEOUT);
137 if (ret) { 153 if (ret) {
138 err("recv bulk message failed:%d", ret); 154 err("recv bulk message failed:%d", ret);
139 ret = -1; 155 ret = -1;
@@ -159,7 +175,7 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
159 175
160 /* read request, copy returned data to return buf */ 176 /* read request, copy returned data to return buf */
161 if (!write) 177 if (!write)
162 memcpy(req->data, &buf[2], req->data_len); 178 memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
163 179
164error_unlock: 180error_unlock:
165exit_unlock: 181exit_unlock: