[media] iguanair: do not modify transmit buffer
authorSean Young <sean@mess.org>
Sat, 25 Aug 2012 10:01:45 +0000 (07:01 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 15 Sep 2012 16:08:04 +0000 (13:08 -0300)
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>
drivers/media/rc/iguanair.c

index 66ba23738601fc92659a7166eb8cfb8a2ee988c2..1e4c68a5cecfedfa24c2053dd1b67db88f83e5a3 100644 (file)
@@ -334,21 +334,34 @@ static int iguanair_set_tx_mask(struct rc_dev *dev, uint32_t mask)
 static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
 {
        struct iguanair *ir = dev->priv;
-       uint8_t space, *payload;
-       unsigned i, size, rc, bytes;
+       uint8_t space;
+       unsigned i, size, periods, bytes;
+       int rc;
        struct send_packet *packet;
 
        mutex_lock(&ir->lock);
 
+       packet = kmalloc(sizeof(*packet) + ir->bufsize, GFP_KERNEL);
+       if (!packet) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
        /* convert from us to carrier periods */
-       for (i = size = 0; i < count; i++) {
-               txbuf[i] = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 1000000);
-               bytes = (txbuf[i] + 126) / 127;
+       for (i = space = size = 0; i < count; i++) {
+               periods = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 1000000);
+               bytes = DIV_ROUND_UP(periods, 127);
                if (size + bytes > ir->bufsize) {
                        count = i;
                        break;
                }
-               size += bytes;
+               while (periods > 127) {
+                       packet->payload[size++] = 127 | space;
+                       periods -= 127;
+               }
+
+               packet->payload[size++] = periods | space;
+               space ^= 0x80;
        }
 
        if (count == 0) {
@@ -356,12 +369,6 @@ static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
                goto out;
        }
 
-       packet = kmalloc(sizeof(*packet) + size, GFP_KERNEL);
-       if (!packet) {
-               rc = -ENOMEM;
-               goto out;
-       }
-
        packet->header.start = 0;
        packet->header.direction = DIR_OUT;
        packet->header.cmd = CMD_SEND;
@@ -370,26 +377,11 @@ static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
        packet->busy7 = ir->busy7;
        packet->busy4 = ir->busy4;
 
-       space = 0;
-       payload = packet->payload;
-
-       for (i = 0; i < count; i++) {
-               unsigned periods = txbuf[i];
-
-               while (periods > 127) {
-                       *payload++ = 127 | space;
-                       periods -= 127;
-               }
-
-               *payload++ = periods | space;
-               space ^= 0x80;
-       }
-
        if (ir->receiver_on) {
                rc = iguanair_receiver(ir, false);
                if (rc) {
                        dev_warn(ir->dev, "disable receiver before transmit failed\n");
-                       goto out_kfree;
+                       goto out;
                }
        }
 
@@ -405,9 +397,8 @@ static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
                        dev_warn(ir->dev, "re-enable receiver after transmit failed\n");
        }
 
-out_kfree:
-       kfree(packet);
 out:
+       kfree(packet);
        mutex_unlock(&ir->lock);
 
        return rc ? rc : count;