diff options
author | Hans de Goede <hdegoede@redhat.com> | 2012-01-10 15:02:04 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-01-16 08:27:58 -0500 |
commit | 24be689bfbbcd6c047d7918784ff810e97648006 (patch) | |
tree | b682e75ed5ccd2124d5d44cf528707562c5a6f00 /drivers/media | |
parent | 1c852201a28601b1379857f615e99071211294c6 (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.c | 154 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-dec1.c | 2 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-dec1.h | 2 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-dec23.c | 2 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-dec23.h | 2 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-if.c | 10 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-v4l.c | 22 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc.h | 5 |
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 | ||
107 | static 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 | |||
130 | static int recv_control_msg(struct pwc_device *pdev, | 107 | static 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 | ||
154 | static inline int send_video_command(struct pwc_device *pdev, | 123 | static 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 | ||
164 | int send_control_msg(struct pwc_device *pdev, | 143 | int 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 | ||
171 | static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt, | 153 | static 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, | |||
249 | static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt, | 226 | static 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 | |||
445 | int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) | 410 | int 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) | |||
469 | int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) | 434 | int 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 | ||
482 | int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data) | 446 | int 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 | ||
495 | int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data) | 458 | int 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 */ |
521 | void pwc_camera_power(struct pwc_device *pdev, int power) | 483 | void 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 | ||
545 | int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) | 504 | int 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 |
575 | int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) | 533 | int 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 | ||
27 | void pwc_dec1_init(struct pwc_device *pdev, void *buffer) | 27 | void 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 | ||
37 | void pwc_dec1_init(struct pwc_device *pdev, void *buffer); | 37 | void 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 */ |
297 | void pwc_dec23_init(struct pwc_device *pdev, unsigned char *cmd) | 297 | void 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 | ||
57 | void pwc_dec23_init(struct pwc_device *pdev, unsigned char *cmd); | 57 | void pwc_dec23_init(struct pwc_device *pdev, const unsigned char *cmd); |
58 | void pwc_dec23_decompress(struct pwc_device *pdev, | 58 | void 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: | |||
1199 | err_free_mem: | 1208 | err_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) | |||
772 | static int pwc_set_motor(struct pwc_device *pdev) | 772 | static 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; |