aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-01-10 15:02:04 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-01-16 08:27:58 -0500
commit24be689bfbbcd6c047d7918784ff810e97648006 (patch)
treeb682e75ed5ccd2124d5d44cf528707562c5a6f00 /drivers/media
parent1c852201a28601b1379857f615e99071211294c6 (diff)
[media] pwc: Use one shared usb command buffer
The pwc driver used to: 1. kmalloc a buffer 2. memcpy data to send over usb there 3. do the usb_control_msg call (which does not work with data on the stack) 4. free the buffer For every usb command send. This patch changes the code to instead malloc a buffer for this purpose once and use it everywhere. [mchehab@redhat.com: Fix a compilation breakage with allyesconfig: drivers/media/video/pwc/pwc-ctrl.c: In function ‘pwc_get_cmos_sensor’: drivers/media/video/pwc/pwc-ctrl.c:546:3: warning: passing argument 4 of ‘recv_control_msg’ makes integer from pointer without a cast [en$ drivers/media/video/pwc/pwc-ctrl.c:107:12: note: expected ‘int’ but argument is of type ‘unsigned char *’ drivers/media/video/pwc/pwc-ctrl.c:546:3: error: too many arguments to function ‘recv_control_msg’ drivers/media/video/pwc/pwc-ctrl.c:107:12: note: declared here] Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c154
-rw-r--r--drivers/media/video/pwc/pwc-dec1.c2
-rw-r--r--drivers/media/video/pwc/pwc-dec1.h2
-rw-r--r--drivers/media/video/pwc/pwc-dec23.c2
-rw-r--r--drivers/media/video/pwc/pwc-dec23.h2
-rw-r--r--drivers/media/video/pwc/pwc-if.c10
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c22
-rw-r--r--drivers/media/video/pwc/pwc.h5
8 files changed, 81 insertions, 118 deletions
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 9c1fb3f07dee..1f506fde97d0 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -104,47 +104,16 @@ static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] =
104 104
105/****************************************************************************/ 105/****************************************************************************/
106 106
107static int _send_control_msg(struct pwc_device *pdev,
108 u8 request, u16 value, int index, void *buf, int buflen)
109{
110 int rc;
111 void *kbuf = NULL;
112
113 if (buflen) {
114 kbuf = kmemdup(buf, buflen, GFP_KERNEL); /* not allowed on stack */
115 if (kbuf == NULL)
116 return -ENOMEM;
117 }
118
119 rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
120 request,
121 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
122 value,
123 index,
124 kbuf, buflen, USB_CTRL_SET_TIMEOUT);
125
126 kfree(kbuf);
127 return rc;
128}
129
130static int recv_control_msg(struct pwc_device *pdev, 107static int recv_control_msg(struct pwc_device *pdev,
131 u8 request, u16 value, void *buf, int buflen) 108 u8 request, u16 value, int recv_count)
132{ 109{
133 int rc; 110 int rc;
134 void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
135
136 if (kbuf == NULL)
137 return -ENOMEM;
138 111
139 rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), 112 rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
140 request, 113 request,
141 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 114 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
142 value, 115 value, pdev->vcinterface,
143 pdev->vcinterface, 116 pdev->ctrl_buf, recv_count, USB_CTRL_GET_TIMEOUT);
144 kbuf, buflen, USB_CTRL_GET_TIMEOUT);
145 memcpy(buf, kbuf, buflen);
146 kfree(kbuf);
147
148 if (rc < 0) 117 if (rc < 0)
149 PWC_ERROR("recv_control_msg error %d req %02x val %04x\n", 118 PWC_ERROR("recv_control_msg error %d req %02x val %04x\n",
150 rc, request, value); 119 rc, request, value);
@@ -152,26 +121,38 @@ static int recv_control_msg(struct pwc_device *pdev,
152} 121}
153 122
154static inline int send_video_command(struct pwc_device *pdev, 123static inline int send_video_command(struct pwc_device *pdev,
155 int index, void *buf, int buflen) 124 int index, const unsigned char *buf, int buflen)
156{ 125{
157 return _send_control_msg(pdev, 126 int rc;
158 SET_EP_STREAM_CTL, 127
159 VIDEO_OUTPUT_CONTROL_FORMATTER, 128 memcpy(pdev->ctrl_buf, buf, buflen);
160 index, 129
161 buf, buflen); 130 rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
131 SET_EP_STREAM_CTL,
132 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
133 VIDEO_OUTPUT_CONTROL_FORMATTER, index,
134 pdev->ctrl_buf, buflen, USB_CTRL_SET_TIMEOUT);
135 if (rc >= 0)
136 memcpy(pdev->cmd_buf, buf, buflen);
137 else
138 PWC_ERROR("send_video_command error %d\n", rc);
139
140 return rc;
162} 141}
163 142
164int send_control_msg(struct pwc_device *pdev, 143int send_control_msg(struct pwc_device *pdev,
165 u8 request, u16 value, void *buf, int buflen) 144 u8 request, u16 value, void *buf, int buflen)
166{ 145{
167 return _send_control_msg(pdev, 146 return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
168 request, value, pdev->vcinterface, buf, buflen); 147 request,
148 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
149 value, pdev->vcinterface,
150 buf, buflen, USB_CTRL_SET_TIMEOUT);
169} 151}
170 152
171static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt, 153static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt,
172 int frames, int *compression, int send_to_cam) 154 int frames, int *compression, int send_to_cam)
173{ 155{
174 unsigned char buf[3];
175 int fps, ret = 0; 156 int fps, ret = 0;
176 struct Nala_table_entry *pEntry; 157 struct Nala_table_entry *pEntry;
177 int frames2frames[31] = 158 int frames2frames[31] =
@@ -206,18 +187,14 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt,
206 if (pEntry->alternate == 0) 187 if (pEntry->alternate == 0)
207 return -EINVAL; 188 return -EINVAL;
208 189
209 memcpy(buf, pEntry->mode, 3);
210 if (send_to_cam) 190 if (send_to_cam)
211 ret = send_video_command(pdev, pdev->vendpoint, buf, 3); 191 ret = send_video_command(pdev, pdev->vendpoint,
212 if (ret < 0) { 192 pEntry->mode, 3);
213 PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); 193 if (ret < 0)
214 return ret; 194 return ret;
215 }
216 if (pEntry->compressed && pixfmt == V4L2_PIX_FMT_YUV420)
217 pwc_dec1_init(pdev, buf);
218 195
219 pdev->cmd_len = 3; 196 if (pEntry->compressed && pixfmt == V4L2_PIX_FMT_YUV420)
220 memcpy(pdev->cmd_buf, buf, 3); 197 pwc_dec1_init(pdev, pEntry->mode);
221 198
222 /* Set various parameters */ 199 /* Set various parameters */
223 pdev->pixfmt = pixfmt; 200 pdev->pixfmt = pixfmt;
@@ -249,7 +226,6 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt,
249static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt, 226static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt,
250 int frames, int *compression, int send_to_cam) 227 int frames, int *compression, int send_to_cam)
251{ 228{
252 unsigned char buf[13];
253 const struct Timon_table_entry *pChoose; 229 const struct Timon_table_entry *pChoose;
254 int fps, ret = 0; 230 int fps, ret = 0;
255 231
@@ -274,17 +250,14 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt,
274 if (pChoose == NULL || pChoose->alternate == 0) 250 if (pChoose == NULL || pChoose->alternate == 0)
275 return -ENOENT; /* Not supported. */ 251 return -ENOENT; /* Not supported. */
276 252
277 memcpy(buf, pChoose->mode, 13);
278 if (send_to_cam) 253 if (send_to_cam)
279 ret = send_video_command(pdev, pdev->vendpoint, buf, 13); 254 ret = send_video_command(pdev, pdev->vendpoint,
255 pChoose->mode, 13);
280 if (ret < 0) 256 if (ret < 0)
281 return ret; 257 return ret;
282 258
283 if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420) 259 if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420)
284 pwc_dec23_init(pdev, buf); 260 pwc_dec23_init(pdev, pChoose->mode);
285
286 pdev->cmd_len = 13;
287 memcpy(pdev->cmd_buf, buf, 13);
288 261
289 /* Set various parameters */ 262 /* Set various parameters */
290 pdev->pixfmt = pixfmt; 263 pdev->pixfmt = pixfmt;
@@ -306,7 +279,6 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int pixfmt,
306{ 279{
307 const struct Kiara_table_entry *pChoose = NULL; 280 const struct Kiara_table_entry *pChoose = NULL;
308 int fps, ret = 0; 281 int fps, ret = 0;
309 unsigned char buf[12];
310 282
311 if (size >= PSZ_MAX || *compression < 0 || *compression > 3) 283 if (size >= PSZ_MAX || *compression < 0 || *compression > 3)
312 return -EINVAL; 284 return -EINVAL;
@@ -328,22 +300,15 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int pixfmt,
328 if (pChoose == NULL || pChoose->alternate == 0) 300 if (pChoose == NULL || pChoose->alternate == 0)
329 return -ENOENT; /* Not supported. */ 301 return -ENOENT; /* Not supported. */
330 302
331 PWC_TRACE("Using alternate setting %d.\n", pChoose->alternate);
332
333 /* usb_control_msg won't take staticly allocated arrays as argument?? */
334 memcpy(buf, pChoose->mode, 12);
335
336 /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */ 303 /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
337 if (send_to_cam) 304 if (send_to_cam)
338 ret = send_video_command(pdev, 4, buf, 12); 305 ret = send_video_command(pdev, 4, pChoose->mode, 12);
339 if (ret < 0) 306 if (ret < 0)
340 return ret; 307 return ret;
341 308
342 if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420) 309 if (pChoose->bandlength > 0 && pixfmt == V4L2_PIX_FMT_YUV420)
343 pwc_dec23_init(pdev, buf); 310 pwc_dec23_init(pdev, pChoose->mode);
344 311
345 pdev->cmd_len = 12;
346 memcpy(pdev->cmd_buf, buf, 12);
347 /* All set and go */ 312 /* All set and go */
348 pdev->pixfmt = pixfmt; 313 pdev->pixfmt = pixfmt;
349 pdev->vframes = (fps + 1) * 5; 314 pdev->vframes = (fps + 1) * 5;
@@ -445,13 +410,12 @@ unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned i
445int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) 410int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
446{ 411{
447 int ret; 412 int ret;
448 u8 buf;
449 413
450 ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf)); 414 ret = recv_control_msg(pdev, request, value, 1);
451 if (ret < 0) 415 if (ret < 0)
452 return ret; 416 return ret;
453 417
454 *data = buf; 418 *data = pdev->ctrl_buf[0];
455 return 0; 419 return 0;
456} 420}
457 421
@@ -459,7 +423,8 @@ int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data)
459{ 423{
460 int ret; 424 int ret;
461 425
462 ret = send_control_msg(pdev, request, value, &data, sizeof(data)); 426 pdev->ctrl_buf[0] = data;
427 ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 1);
463 if (ret < 0) 428 if (ret < 0)
464 return ret; 429 return ret;
465 430
@@ -469,37 +434,34 @@ int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data)
469int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) 434int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
470{ 435{
471 int ret; 436 int ret;
472 s8 buf;
473 437
474 ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf)); 438 ret = recv_control_msg(pdev, request, value, 1);
475 if (ret < 0) 439 if (ret < 0)
476 return ret; 440 return ret;
477 441
478 *data = buf; 442 *data = ((s8 *)pdev->ctrl_buf)[0];
479 return 0; 443 return 0;
480} 444}
481 445
482int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) 446int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
483{ 447{
484 int ret; 448 int ret;
485 u8 buf[2];
486 449
487 ret = recv_control_msg(pdev, request, value, buf, sizeof(buf)); 450 ret = recv_control_msg(pdev, request, value, 2);
488 if (ret < 0) 451 if (ret < 0)
489 return ret; 452 return ret;
490 453
491 *data = (buf[1] << 8) | buf[0]; 454 *data = (pdev->ctrl_buf[1] << 8) | pdev->ctrl_buf[0];
492 return 0; 455 return 0;
493} 456}
494 457
495int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data) 458int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data)
496{ 459{
497 int ret; 460 int ret;
498 u8 buf[2];
499 461
500 buf[0] = data & 0xff; 462 pdev->ctrl_buf[0] = data & 0xff;
501 buf[1] = data >> 8; 463 pdev->ctrl_buf[1] = data >> 8;
502 ret = send_control_msg(pdev, request, value, buf, sizeof(buf)); 464 ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 2);
503 if (ret < 0) 465 if (ret < 0)
504 return ret; 466 return ret;
505 467
@@ -520,7 +482,6 @@ int pwc_button_ctrl(struct pwc_device *pdev, u16 value)
520/* POWER */ 482/* POWER */
521void pwc_camera_power(struct pwc_device *pdev, int power) 483void pwc_camera_power(struct pwc_device *pdev, int power)
522{ 484{
523 char buf;
524 int r; 485 int r;
525 486
526 if (!pdev->power_save) 487 if (!pdev->power_save)
@@ -530,13 +491,11 @@ void pwc_camera_power(struct pwc_device *pdev, int power)
530 return; /* Not supported by Nala or Timon < release 6 */ 491 return; /* Not supported by Nala or Timon < release 6 */
531 492
532 if (power) 493 if (power)
533 buf = 0x00; /* active */ 494 pdev->ctrl_buf[0] = 0x00; /* active */
534 else 495 else
535 buf = 0xFF; /* power save */ 496 pdev->ctrl_buf[0] = 0xFF; /* power save */
536 r = send_control_msg(pdev, 497 r = send_control_msg(pdev, SET_STATUS_CTL,
537 SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 498 SET_POWER_SAVE_MODE_FORMATTER, pdev->ctrl_buf, 1);
538 &buf, sizeof(buf));
539
540 if (r < 0) 499 if (r < 0)
541 PWC_ERROR("Failed to power %s camera (%d)\n", 500 PWC_ERROR("Failed to power %s camera (%d)\n",
542 power ? "on" : "off", r); 501 power ? "on" : "off", r);
@@ -544,7 +503,6 @@ void pwc_camera_power(struct pwc_device *pdev, int power)
544 503
545int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) 504int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
546{ 505{
547 unsigned char buf[2];
548 int r; 506 int r;
549 507
550 if (pdev->type < 730) 508 if (pdev->type < 730)
@@ -560,11 +518,11 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
560 if (off_value > 0xff) 518 if (off_value > 0xff)
561 off_value = 0xff; 519 off_value = 0xff;
562 520
563 buf[0] = on_value; 521 pdev->ctrl_buf[0] = on_value;
564 buf[1] = off_value; 522 pdev->ctrl_buf[1] = off_value;
565 523
566 r = send_control_msg(pdev, 524 r = send_control_msg(pdev,
567 SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf)); 525 SET_STATUS_CTL, LED_FORMATTER, pdev->ctrl_buf, 2);
568 if (r < 0) 526 if (r < 0)
569 PWC_ERROR("Failed to set LED on/off time (%d)\n", r); 527 PWC_ERROR("Failed to set LED on/off time (%d)\n", r);
570 528
@@ -574,7 +532,6 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
574#ifdef CONFIG_USB_PWC_DEBUG 532#ifdef CONFIG_USB_PWC_DEBUG
575int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) 533int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
576{ 534{
577 unsigned char buf;
578 int ret = -1, request; 535 int ret = -1, request;
579 536
580 if (pdev->type < 675) 537 if (pdev->type < 675)
@@ -584,14 +541,13 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
584 else 541 else
585 request = SENSOR_TYPE_FORMATTER2; 542 request = SENSOR_TYPE_FORMATTER2;
586 543
587 ret = recv_control_msg(pdev, 544 ret = recv_control_msg(pdev, GET_STATUS_CTL, request, 1);
588 GET_STATUS_CTL, request, &buf, sizeof(buf));
589 if (ret < 0) 545 if (ret < 0)
590 return ret; 546 return ret;
591 if (pdev->type < 675) 547 if (pdev->type < 675)
592 *sensor = buf | 0x100; 548 *sensor = pdev->ctrl_buf[0] | 0x100;
593 else 549 else
594 *sensor = buf; 550 *sensor = pdev->ctrl_buf[0];
595 return 0; 551 return 0;
596} 552}
597#endif 553#endif
diff --git a/drivers/media/video/pwc/pwc-dec1.c b/drivers/media/video/pwc/pwc-dec1.c
index bac0d83fe119..e899036aadf4 100644
--- a/drivers/media/video/pwc/pwc-dec1.c
+++ b/drivers/media/video/pwc/pwc-dec1.c
@@ -24,7 +24,7 @@
24*/ 24*/
25#include "pwc.h" 25#include "pwc.h"
26 26
27void pwc_dec1_init(struct pwc_device *pdev, void *buffer) 27void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd)
28{ 28{
29 struct pwc_dec1_private *pdec = &pdev->dec1; 29 struct pwc_dec1_private *pdec = &pdev->dec1;
30 30
diff --git a/drivers/media/video/pwc/pwc-dec1.h b/drivers/media/video/pwc/pwc-dec1.h
index 6e8f3c561c9b..c565ef8f52fb 100644
--- a/drivers/media/video/pwc/pwc-dec1.h
+++ b/drivers/media/video/pwc/pwc-dec1.h
@@ -34,6 +34,6 @@ struct pwc_dec1_private
34 int version; 34 int version;
35}; 35};
36 36
37void pwc_dec1_init(struct pwc_device *pdev, void *buffer); 37void pwc_dec1_init(struct pwc_device *pdev, const unsigned char *cmd);
38 38
39#endif 39#endif
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c
index 98772efc5bde..3792fedff951 100644
--- a/drivers/media/video/pwc/pwc-dec23.c
+++ b/drivers/media/video/pwc/pwc-dec23.c
@@ -294,7 +294,7 @@ static unsigned char pwc_crop_table[256 + 2*MAX_OUTER_CROP_VALUE];
294 294
295 295
296/* If the type or the command change, we rebuild the lookup table */ 296/* If the type or the command change, we rebuild the lookup table */
297void pwc_dec23_init(struct pwc_device *pdev, unsigned char *cmd) 297void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd)
298{ 298{
299 int flags, version, shift, i; 299 int flags, version, shift, i;
300 struct pwc_dec23_private *pdec = &pdev->dec23; 300 struct pwc_dec23_private *pdec = &pdev->dec23;
diff --git a/drivers/media/video/pwc/pwc-dec23.h b/drivers/media/video/pwc/pwc-dec23.h
index af31d6047bb2..c655b1c1e6a9 100644
--- a/drivers/media/video/pwc/pwc-dec23.h
+++ b/drivers/media/video/pwc/pwc-dec23.h
@@ -54,7 +54,7 @@ struct pwc_dec23_private
54 54
55}; 55};
56 56
57void pwc_dec23_init(struct pwc_device *pdev, unsigned char *cmd); 57void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd);
58void pwc_dec23_decompress(struct pwc_device *pdev, 58void pwc_dec23_decompress(struct pwc_device *pdev,
59 const void *src, 59 const void *src,
60 void *dst); 60 void *dst);
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 23eaceea4862..a07df4e4aa04 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -605,6 +605,7 @@ static void pwc_video_release(struct v4l2_device *v)
605 605
606 v4l2_ctrl_handler_free(&pdev->ctrl_handler); 606 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
607 607
608 kfree(pdev->ctrl_buf);
608 kfree(pdev); 609 kfree(pdev);
609} 610}
610 611
@@ -1115,6 +1116,14 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1115 if (hint < MAX_DEV_HINTS) 1116 if (hint < MAX_DEV_HINTS)
1116 device_hint[hint].pdev = pdev; 1117 device_hint[hint].pdev = pdev;
1117 1118
1119 /* Allocate USB command buffers */
1120 pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL);
1121 if (!pdev->ctrl_buf) {
1122 PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
1123 rc = -ENOMEM;
1124 goto err_free_mem;
1125 }
1126
1118#ifdef CONFIG_USB_PWC_DEBUG 1127#ifdef CONFIG_USB_PWC_DEBUG
1119 /* Query sensor type */ 1128 /* Query sensor type */
1120 if (pwc_get_cmos_sensor(pdev, &rc) >= 0) { 1129 if (pwc_get_cmos_sensor(pdev, &rc) >= 0) {
@@ -1199,6 +1208,7 @@ err_free_controls:
1199err_free_mem: 1208err_free_mem:
1200 if (hint < MAX_DEV_HINTS) 1209 if (hint < MAX_DEV_HINTS)
1201 device_hint[hint].pdev = NULL; 1210 device_hint[hint].pdev = NULL;
1211 kfree(pdev->ctrl_buf);
1202 kfree(pdev); 1212 kfree(pdev);
1203 return rc; 1213 return rc;
1204} 1214}
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 46feece38852..f495eeb5403a 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -772,33 +772,33 @@ static int pwc_set_autogain_expo(struct pwc_device *pdev)
772static int pwc_set_motor(struct pwc_device *pdev) 772static int pwc_set_motor(struct pwc_device *pdev)
773{ 773{
774 int ret; 774 int ret;
775 u8 buf[4];
776 775
777 buf[0] = 0; 776 pdev->ctrl_buf[0] = 0;
778 if (pdev->motor_pan_reset->is_new) 777 if (pdev->motor_pan_reset->is_new)
779 buf[0] |= 0x01; 778 pdev->ctrl_buf[0] |= 0x01;
780 if (pdev->motor_tilt_reset->is_new) 779 if (pdev->motor_tilt_reset->is_new)
781 buf[0] |= 0x02; 780 pdev->ctrl_buf[0] |= 0x02;
782 if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) { 781 if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) {
783 ret = send_control_msg(pdev, SET_MPT_CTL, 782 ret = send_control_msg(pdev, SET_MPT_CTL,
784 PT_RESET_CONTROL_FORMATTER, buf, 1); 783 PT_RESET_CONTROL_FORMATTER,
784 pdev->ctrl_buf, 1);
785 if (ret < 0) 785 if (ret < 0)
786 return ret; 786 return ret;
787 } 787 }
788 788
789 memset(buf, 0, sizeof(buf)); 789 memset(pdev->ctrl_buf, 0, 4);
790 if (pdev->motor_pan->is_new) { 790 if (pdev->motor_pan->is_new) {
791 buf[0] = pdev->motor_pan->val & 0xFF; 791 pdev->ctrl_buf[0] = pdev->motor_pan->val & 0xFF;
792 buf[1] = (pdev->motor_pan->val >> 8); 792 pdev->ctrl_buf[1] = (pdev->motor_pan->val >> 8);
793 } 793 }
794 if (pdev->motor_tilt->is_new) { 794 if (pdev->motor_tilt->is_new) {
795 buf[2] = pdev->motor_tilt->val & 0xFF; 795 pdev->ctrl_buf[2] = pdev->motor_tilt->val & 0xFF;
796 buf[3] = (pdev->motor_tilt->val >> 8); 796 pdev->ctrl_buf[3] = (pdev->motor_tilt->val >> 8);
797 } 797 }
798 if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) { 798 if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) {
799 ret = send_control_msg(pdev, SET_MPT_CTL, 799 ret = send_control_msg(pdev, SET_MPT_CTL,
800 PT_RELATIVE_CONTROL_FORMATTER, 800 PT_RELATIVE_CONTROL_FORMATTER,
801 buf, sizeof(buf)); 801 pdev->ctrl_buf, 4);
802 if (ret < 0) 802 if (ret < 0)
803 return ret; 803 return ret;
804 } 804 }
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index f441999e5bd1..e4d4d711dd1f 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -134,9 +134,6 @@
134#define DEVICE_USE_CODEC3(x) ((x)>=700) 134#define DEVICE_USE_CODEC3(x) ((x)>=700)
135#define DEVICE_USE_CODEC23(x) ((x)>=675) 135#define DEVICE_USE_CODEC23(x) ((x)>=675)
136 136
137/* from pwc-dec.h */
138#define PWCX_FLAG_PLANAR 0x0001
139
140/* Request types: video */ 137/* Request types: video */
141#define SET_LUM_CTL 0x01 138#define SET_LUM_CTL 0x01
142#define GET_LUM_CTL 0x02 139#define GET_LUM_CTL 0x02
@@ -250,8 +247,8 @@ struct pwc_device
250 char vmirror; /* for ToUCaM series */ 247 char vmirror; /* for ToUCaM series */
251 char power_save; /* Do powersaving for this cam */ 248 char power_save; /* Do powersaving for this cam */
252 249
253 int cmd_len;
254 unsigned char cmd_buf[13]; 250 unsigned char cmd_buf[13];
251 unsigned char *ctrl_buf;
255 252
256 struct urb *urbs[MAX_ISO_BUFS]; 253 struct urb *urbs[MAX_ISO_BUFS];
257 char iso_init; 254 char iso_init;