aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc/iguanair.c
diff options
context:
space:
mode:
authorSean Young <sean@mess.org>2012-08-25 06:01:45 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-09-15 12:08:04 -0400
commit3920631c4b8af70893fe70df53e94adb0cd66f71 (patch)
tree25949242273cc307eb241c57e2deb61fca9081af /drivers/media/rc/iguanair.c
parentaa740e0a6fd5fe6ab59a95d67d8756c77df3fa66 (diff)
[media] iguanair: do not modify transmit buffer
Since commit "[media] rc-core: move timeout and checks to lirc", the incoming buffer is used after the driver transmits. Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/rc/iguanair.c')
-rw-r--r--drivers/media/rc/iguanair.c51
1 files changed, 21 insertions, 30 deletions
diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index 66ba23738601..1e4c68a5cecf 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -334,21 +334,34 @@ static int iguanair_set_tx_mask(struct rc_dev *dev, uint32_t mask)
334static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count) 334static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
335{ 335{
336 struct iguanair *ir = dev->priv; 336 struct iguanair *ir = dev->priv;
337 uint8_t space, *payload; 337 uint8_t space;
338 unsigned i, size, rc, bytes; 338 unsigned i, size, periods, bytes;
339 int rc;
339 struct send_packet *packet; 340 struct send_packet *packet;
340 341
341 mutex_lock(&ir->lock); 342 mutex_lock(&ir->lock);
342 343
344 packet = kmalloc(sizeof(*packet) + ir->bufsize, GFP_KERNEL);
345 if (!packet) {
346 rc = -ENOMEM;
347 goto out;
348 }
349
343 /* convert from us to carrier periods */ 350 /* convert from us to carrier periods */
344 for (i = size = 0; i < count; i++) { 351 for (i = space = size = 0; i < count; i++) {
345 txbuf[i] = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 1000000); 352 periods = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 1000000);
346 bytes = (txbuf[i] + 126) / 127; 353 bytes = DIV_ROUND_UP(periods, 127);
347 if (size + bytes > ir->bufsize) { 354 if (size + bytes > ir->bufsize) {
348 count = i; 355 count = i;
349 break; 356 break;
350 } 357 }
351 size += bytes; 358 while (periods > 127) {
359 packet->payload[size++] = 127 | space;
360 periods -= 127;
361 }
362
363 packet->payload[size++] = periods | space;
364 space ^= 0x80;
352 } 365 }
353 366
354 if (count == 0) { 367 if (count == 0) {
@@ -356,12 +369,6 @@ static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
356 goto out; 369 goto out;
357 } 370 }
358 371
359 packet = kmalloc(sizeof(*packet) + size, GFP_KERNEL);
360 if (!packet) {
361 rc = -ENOMEM;
362 goto out;
363 }
364
365 packet->header.start = 0; 372 packet->header.start = 0;
366 packet->header.direction = DIR_OUT; 373 packet->header.direction = DIR_OUT;
367 packet->header.cmd = CMD_SEND; 374 packet->header.cmd = CMD_SEND;
@@ -370,26 +377,11 @@ static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
370 packet->busy7 = ir->busy7; 377 packet->busy7 = ir->busy7;
371 packet->busy4 = ir->busy4; 378 packet->busy4 = ir->busy4;
372 379
373 space = 0;
374 payload = packet->payload;
375
376 for (i = 0; i < count; i++) {
377 unsigned periods = txbuf[i];
378
379 while (periods > 127) {
380 *payload++ = 127 | space;
381 periods -= 127;
382 }
383
384 *payload++ = periods | space;
385 space ^= 0x80;
386 }
387
388 if (ir->receiver_on) { 380 if (ir->receiver_on) {
389 rc = iguanair_receiver(ir, false); 381 rc = iguanair_receiver(ir, false);
390 if (rc) { 382 if (rc) {
391 dev_warn(ir->dev, "disable receiver before transmit failed\n"); 383 dev_warn(ir->dev, "disable receiver before transmit failed\n");
392 goto out_kfree; 384 goto out;
393 } 385 }
394 } 386 }
395 387
@@ -405,9 +397,8 @@ static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
405 dev_warn(ir->dev, "re-enable receiver after transmit failed\n"); 397 dev_warn(ir->dev, "re-enable receiver after transmit failed\n");
406 } 398 }
407 399
408out_kfree:
409 kfree(packet);
410out: 400out:
401 kfree(packet);
411 mutex_unlock(&ir->lock); 402 mutex_unlock(&ir->lock);
412 403
413 return rc ? rc : count; 404 return rc ? rc : count;