diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-12-13 06:06:07 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-12-18 08:28:04 -0500 |
commit | 567e2e9660c71372e8bd50efa9d37a0281e4abe1 (patch) | |
tree | 37310df56a90db585aab901fe3cd052b50fa7d00 /drivers/media/radio | |
parent | 0149a2e1498dba7937dd14bf924dedd6f0c15587 (diff) |
[media] si470x: don't use buffer on the stack for USB transfers
You shouldn't use buffers allocated on the stack for USB transfers,
always kmalloc them.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/radio')
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x-usb.c | 57 | ||||
-rw-r--r-- | drivers/media/radio/si470x/radio-si470x.h | 1 |
2 files changed, 32 insertions, 26 deletions
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index d6d4d60261d5..cd74025517e5 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c | |||
@@ -137,6 +137,8 @@ MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); | |||
137 | /* interrupt out endpoint 2 every 1 millisecond */ | 137 | /* interrupt out endpoint 2 every 1 millisecond */ |
138 | #define UNUSED_REPORT 23 | 138 | #define UNUSED_REPORT 23 |
139 | 139 | ||
140 | #define MAX_REPORT_SIZE 64 | ||
141 | |||
140 | 142 | ||
141 | 143 | ||
142 | /************************************************************************** | 144 | /************************************************************************** |
@@ -208,7 +210,7 @@ MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); | |||
208 | */ | 210 | */ |
209 | static int si470x_get_report(struct si470x_device *radio, void *buf, int size) | 211 | static int si470x_get_report(struct si470x_device *radio, void *buf, int size) |
210 | { | 212 | { |
211 | unsigned char *report = (unsigned char *) buf; | 213 | unsigned char *report = buf; |
212 | int retval; | 214 | int retval; |
213 | 215 | ||
214 | retval = usb_control_msg(radio->usbdev, | 216 | retval = usb_control_msg(radio->usbdev, |
@@ -231,7 +233,7 @@ static int si470x_get_report(struct si470x_device *radio, void *buf, int size) | |||
231 | */ | 233 | */ |
232 | static int si470x_set_report(struct si470x_device *radio, void *buf, int size) | 234 | static int si470x_set_report(struct si470x_device *radio, void *buf, int size) |
233 | { | 235 | { |
234 | unsigned char *report = (unsigned char *) buf; | 236 | unsigned char *report = buf; |
235 | int retval; | 237 | int retval; |
236 | 238 | ||
237 | retval = usb_control_msg(radio->usbdev, | 239 | retval = usb_control_msg(radio->usbdev, |
@@ -254,15 +256,14 @@ static int si470x_set_report(struct si470x_device *radio, void *buf, int size) | |||
254 | */ | 256 | */ |
255 | int si470x_get_register(struct si470x_device *radio, int regnr) | 257 | int si470x_get_register(struct si470x_device *radio, int regnr) |
256 | { | 258 | { |
257 | unsigned char buf[REGISTER_REPORT_SIZE]; | ||
258 | int retval; | 259 | int retval; |
259 | 260 | ||
260 | buf[0] = REGISTER_REPORT(regnr); | 261 | radio->usb_buf[0] = REGISTER_REPORT(regnr); |
261 | 262 | ||
262 | retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); | 263 | retval = si470x_get_report(radio, radio->usb_buf, REGISTER_REPORT_SIZE); |
263 | 264 | ||
264 | if (retval >= 0) | 265 | if (retval >= 0) |
265 | radio->registers[regnr] = get_unaligned_be16(&buf[1]); | 266 | radio->registers[regnr] = get_unaligned_be16(&radio->usb_buf[1]); |
266 | 267 | ||
267 | return (retval < 0) ? -EINVAL : 0; | 268 | return (retval < 0) ? -EINVAL : 0; |
268 | } | 269 | } |
@@ -273,13 +274,12 @@ int si470x_get_register(struct si470x_device *radio, int regnr) | |||
273 | */ | 274 | */ |
274 | int si470x_set_register(struct si470x_device *radio, int regnr) | 275 | int si470x_set_register(struct si470x_device *radio, int regnr) |
275 | { | 276 | { |
276 | unsigned char buf[REGISTER_REPORT_SIZE]; | ||
277 | int retval; | 277 | int retval; |
278 | 278 | ||
279 | buf[0] = REGISTER_REPORT(regnr); | 279 | radio->usb_buf[0] = REGISTER_REPORT(regnr); |
280 | put_unaligned_be16(radio->registers[regnr], &buf[1]); | 280 | put_unaligned_be16(radio->registers[regnr], &radio->usb_buf[1]); |
281 | 281 | ||
282 | retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); | 282 | retval = si470x_set_report(radio, radio->usb_buf, REGISTER_REPORT_SIZE); |
283 | 283 | ||
284 | return (retval < 0) ? -EINVAL : 0; | 284 | return (retval < 0) ? -EINVAL : 0; |
285 | } | 285 | } |
@@ -295,18 +295,17 @@ int si470x_set_register(struct si470x_device *radio, int regnr) | |||
295 | */ | 295 | */ |
296 | static int si470x_get_all_registers(struct si470x_device *radio) | 296 | static int si470x_get_all_registers(struct si470x_device *radio) |
297 | { | 297 | { |
298 | unsigned char buf[ENTIRE_REPORT_SIZE]; | ||
299 | int retval; | 298 | int retval; |
300 | unsigned char regnr; | 299 | unsigned char regnr; |
301 | 300 | ||
302 | buf[0] = ENTIRE_REPORT; | 301 | radio->usb_buf[0] = ENTIRE_REPORT; |
303 | 302 | ||
304 | retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); | 303 | retval = si470x_get_report(radio, radio->usb_buf, ENTIRE_REPORT_SIZE); |
305 | 304 | ||
306 | if (retval >= 0) | 305 | if (retval >= 0) |
307 | for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) | 306 | for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) |
308 | radio->registers[regnr] = get_unaligned_be16( | 307 | radio->registers[regnr] = get_unaligned_be16( |
309 | &buf[regnr * RADIO_REGISTER_SIZE + 1]); | 308 | &radio->usb_buf[regnr * RADIO_REGISTER_SIZE + 1]); |
310 | 309 | ||
311 | return (retval < 0) ? -EINVAL : 0; | 310 | return (retval < 0) ? -EINVAL : 0; |
312 | } | 311 | } |
@@ -323,14 +322,13 @@ static int si470x_get_all_registers(struct si470x_device *radio) | |||
323 | static int si470x_set_led_state(struct si470x_device *radio, | 322 | static int si470x_set_led_state(struct si470x_device *radio, |
324 | unsigned char led_state) | 323 | unsigned char led_state) |
325 | { | 324 | { |
326 | unsigned char buf[LED_REPORT_SIZE]; | ||
327 | int retval; | 325 | int retval; |
328 | 326 | ||
329 | buf[0] = LED_REPORT; | 327 | radio->usb_buf[0] = LED_REPORT; |
330 | buf[1] = LED_COMMAND; | 328 | radio->usb_buf[1] = LED_COMMAND; |
331 | buf[2] = led_state; | 329 | radio->usb_buf[2] = led_state; |
332 | 330 | ||
333 | retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); | 331 | retval = si470x_set_report(radio, radio->usb_buf, LED_REPORT_SIZE); |
334 | 332 | ||
335 | return (retval < 0) ? -EINVAL : 0; | 333 | return (retval < 0) ? -EINVAL : 0; |
336 | } | 334 | } |
@@ -346,19 +344,18 @@ static int si470x_set_led_state(struct si470x_device *radio, | |||
346 | */ | 344 | */ |
347 | static int si470x_get_scratch_page_versions(struct si470x_device *radio) | 345 | static int si470x_get_scratch_page_versions(struct si470x_device *radio) |
348 | { | 346 | { |
349 | unsigned char buf[SCRATCH_REPORT_SIZE]; | ||
350 | int retval; | 347 | int retval; |
351 | 348 | ||
352 | buf[0] = SCRATCH_REPORT; | 349 | radio->usb_buf[0] = SCRATCH_REPORT; |
353 | 350 | ||
354 | retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); | 351 | retval = si470x_get_report(radio, radio->usb_buf, SCRATCH_REPORT_SIZE); |
355 | 352 | ||
356 | if (retval < 0) | 353 | if (retval < 0) |
357 | dev_warn(&radio->intf->dev, "si470x_get_scratch: " | 354 | dev_warn(&radio->intf->dev, "si470x_get_scratch: " |
358 | "si470x_get_report returned %d\n", retval); | 355 | "si470x_get_report returned %d\n", retval); |
359 | else { | 356 | else { |
360 | radio->software_version = buf[1]; | 357 | radio->software_version = radio->usb_buf[1]; |
361 | radio->hardware_version = buf[2]; | 358 | radio->hardware_version = radio->usb_buf[2]; |
362 | } | 359 | } |
363 | 360 | ||
364 | return (retval < 0) ? -EINVAL : 0; | 361 | return (retval < 0) ? -EINVAL : 0; |
@@ -509,6 +506,7 @@ static void si470x_usb_release(struct v4l2_device *v4l2_dev) | |||
509 | v4l2_device_unregister(&radio->v4l2_dev); | 506 | v4l2_device_unregister(&radio->v4l2_dev); |
510 | kfree(radio->int_in_buffer); | 507 | kfree(radio->int_in_buffer); |
511 | kfree(radio->buffer); | 508 | kfree(radio->buffer); |
509 | kfree(radio->usb_buf); | ||
512 | kfree(radio); | 510 | kfree(radio); |
513 | } | 511 | } |
514 | 512 | ||
@@ -593,6 +591,11 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, | |||
593 | retval = -ENOMEM; | 591 | retval = -ENOMEM; |
594 | goto err_initial; | 592 | goto err_initial; |
595 | } | 593 | } |
594 | radio->usb_buf = kmalloc(MAX_REPORT_SIZE, GFP_KERNEL); | ||
595 | if (radio->usb_buf == NULL) { | ||
596 | retval = -ENOMEM; | ||
597 | goto err_radio; | ||
598 | } | ||
596 | radio->usbdev = interface_to_usbdev(intf); | 599 | radio->usbdev = interface_to_usbdev(intf); |
597 | radio->intf = intf; | 600 | radio->intf = intf; |
598 | radio->band = 1; /* Default to 76 - 108 MHz */ | 601 | radio->band = 1; /* Default to 76 - 108 MHz */ |
@@ -612,7 +615,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, | |||
612 | if (!radio->int_in_endpoint) { | 615 | if (!radio->int_in_endpoint) { |
613 | dev_info(&intf->dev, "could not find interrupt in endpoint\n"); | 616 | dev_info(&intf->dev, "could not find interrupt in endpoint\n"); |
614 | retval = -EIO; | 617 | retval = -EIO; |
615 | goto err_radio; | 618 | goto err_usbbuf; |
616 | } | 619 | } |
617 | 620 | ||
618 | int_end_size = le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize); | 621 | int_end_size = le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize); |
@@ -621,7 +624,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, | |||
621 | if (!radio->int_in_buffer) { | 624 | if (!radio->int_in_buffer) { |
622 | dev_info(&intf->dev, "could not allocate int_in_buffer"); | 625 | dev_info(&intf->dev, "could not allocate int_in_buffer"); |
623 | retval = -ENOMEM; | 626 | retval = -ENOMEM; |
624 | goto err_radio; | 627 | goto err_usbbuf; |
625 | } | 628 | } |
626 | 629 | ||
627 | radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 630 | radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
@@ -743,6 +746,8 @@ err_urb: | |||
743 | usb_free_urb(radio->int_in_urb); | 746 | usb_free_urb(radio->int_in_urb); |
744 | err_intbuffer: | 747 | err_intbuffer: |
745 | kfree(radio->int_in_buffer); | 748 | kfree(radio->int_in_buffer); |
749 | err_usbbuf: | ||
750 | kfree(radio->usb_buf); | ||
746 | err_radio: | 751 | err_radio: |
747 | kfree(radio); | 752 | kfree(radio); |
748 | err_initial: | 753 | err_initial: |
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index 467e95575488..4b7660470e2f 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h | |||
@@ -167,6 +167,7 @@ struct si470x_device { | |||
167 | /* reference to USB and video device */ | 167 | /* reference to USB and video device */ |
168 | struct usb_device *usbdev; | 168 | struct usb_device *usbdev; |
169 | struct usb_interface *intf; | 169 | struct usb_interface *intf; |
170 | char *usb_buf; | ||
170 | 171 | ||
171 | /* Interrupt endpoint handling */ | 172 | /* Interrupt endpoint handling */ |
172 | char *int_in_buffer; | 173 | char *int_in_buffer; |