diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9015.c | 32 |
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 | ||
62 | static int af9015_rw_udev(struct usb_device *udev, struct req_t *req) | 62 | static 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 | ||
164 | error_unlock: | 180 | error_unlock: |
165 | exit_unlock: | 181 | exit_unlock: |