Commit 06eae25f authored by Sean Young's avatar Sean Young Committed by Mauro Carvalho Chehab

[media] redrat3: fix transmit return value and overrun

If more than 127 different lengths are transmitted then the driver causes
an overrun on sample_lens. Try to send as much as possible and return the
amount sent.
Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent db8ee106
...@@ -195,9 +195,6 @@ struct redrat3_dev { ...@@ -195,9 +195,6 @@ struct redrat3_dev {
dma_addr_t dma_in; dma_addr_t dma_in;
dma_addr_t dma_out; dma_addr_t dma_out;
/* locks this structure */
struct mutex lock;
/* rx signal timeout timer */ /* rx signal timeout timer */
struct timer_list rx_timeout; struct timer_list rx_timeout;
u32 hw_timeout; u32 hw_timeout;
...@@ -922,8 +919,7 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, ...@@ -922,8 +919,7 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
return -EAGAIN; return -EAGAIN;
} }
if (count > (RR3_DRIVER_MAXLENS * 2)) count = min_t(unsigned, count, RR3_MAX_SIG_SIZE - RR3_TX_TRAILER_LEN);
return -EINVAL;
/* rr3 will disable rc detector on transmit */ /* rr3 will disable rc detector on transmit */
rr3->det_enabled = false; rr3->det_enabled = false;
...@@ -936,24 +932,22 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, ...@@ -936,24 +932,22 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
} }
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
for (lencheck = 0; lencheck < curlencheck; lencheck++) {
cur_sample_len = redrat3_us_to_len(txbuf[i]); cur_sample_len = redrat3_us_to_len(txbuf[i]);
for (lencheck = 0; lencheck < curlencheck; lencheck++) {
if (sample_lens[lencheck] == cur_sample_len) if (sample_lens[lencheck] == cur_sample_len)
break; break;
} }
if (lencheck == curlencheck) { if (lencheck == curlencheck) {
cur_sample_len = redrat3_us_to_len(txbuf[i]);
rr3_dbg(dev, "txbuf[%d]=%u, pos %d, enc %u\n", rr3_dbg(dev, "txbuf[%d]=%u, pos %d, enc %u\n",
i, txbuf[i], curlencheck, cur_sample_len); i, txbuf[i], curlencheck, cur_sample_len);
if (curlencheck < 255) { if (curlencheck < RR3_DRIVER_MAXLENS) {
/* now convert the value to a proper /* now convert the value to a proper
* rr3 value.. */ * rr3 value.. */
sample_lens[curlencheck] = cur_sample_len; sample_lens[curlencheck] = cur_sample_len;
curlencheck++; curlencheck++;
} else { } else {
dev_err(dev, "signal too long\n"); count = i - 1;
ret = -EINVAL; break;
goto out;
} }
} }
} }
...@@ -1087,6 +1081,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) ...@@ -1087,6 +1081,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
rc->tx_ir = redrat3_transmit_ir; rc->tx_ir = redrat3_transmit_ir;
rc->s_tx_carrier = redrat3_set_tx_carrier; rc->s_tx_carrier = redrat3_set_tx_carrier;
rc->driver_name = DRIVER_NAME; rc->driver_name = DRIVER_NAME;
rc->rx_resolution = US_TO_NS(2);
rc->map_name = RC_MAP_HAUPPAUGE; rc->map_name = RC_MAP_HAUPPAUGE;
ret = rc_register_device(rc); ret = rc_register_device(rc);
...@@ -1202,7 +1197,6 @@ static int redrat3_dev_probe(struct usb_interface *intf, ...@@ -1202,7 +1197,6 @@ static int redrat3_dev_probe(struct usb_interface *intf,
rr3->bulk_out_buf, ep_out->wMaxPacketSize, rr3->bulk_out_buf, ep_out->wMaxPacketSize,
(usb_complete_t)redrat3_write_bulk_callback, rr3); (usb_complete_t)redrat3_write_bulk_callback, rr3);
mutex_init(&rr3->lock);
rr3->udev = udev; rr3->udev = udev;
redrat3_reset(rr3); redrat3_reset(rr3);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment