aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc/redrat3.c
diff options
context:
space:
mode:
authorSean Young <sean@mess.org>2013-01-29 06:19:31 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-02-08 11:18:16 -0500
commit06eae25f162e2a0d9e60f0ad3ec3d14c738fbe68 (patch)
treeef064afc62db275ad060a5eebe34542f36699a56 /drivers/media/rc/redrat3.c
parentdb8ee1064c97879bff614d653158dff1894d2e37 (diff)
[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: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/rc/redrat3.c')
-rw-r--r--drivers/media/rc/redrat3.c18
1 files changed, 6 insertions, 12 deletions
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 1800326f93e6..1b37fe2779f8 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -195,9 +195,6 @@ struct redrat3_dev {
195 dma_addr_t dma_in; 195 dma_addr_t dma_in;
196 dma_addr_t dma_out; 196 dma_addr_t dma_out;
197 197
198 /* locks this structure */
199 struct mutex lock;
200
201 /* rx signal timeout timer */ 198 /* rx signal timeout timer */
202 struct timer_list rx_timeout; 199 struct timer_list rx_timeout;
203 u32 hw_timeout; 200 u32 hw_timeout;
@@ -922,8 +919,7 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
922 return -EAGAIN; 919 return -EAGAIN;
923 } 920 }
924 921
925 if (count > (RR3_DRIVER_MAXLENS * 2)) 922 count = min_t(unsigned, count, RR3_MAX_SIG_SIZE - RR3_TX_TRAILER_LEN);
926 return -EINVAL;
927 923
928 /* rr3 will disable rc detector on transmit */ 924 /* rr3 will disable rc detector on transmit */
929 rr3->det_enabled = false; 925 rr3->det_enabled = false;
@@ -936,24 +932,22 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
936 } 932 }
937 933
938 for (i = 0; i < count; i++) { 934 for (i = 0; i < count; i++) {
935 cur_sample_len = redrat3_us_to_len(txbuf[i]);
939 for (lencheck = 0; lencheck < curlencheck; lencheck++) { 936 for (lencheck = 0; lencheck < curlencheck; lencheck++) {
940 cur_sample_len = redrat3_us_to_len(txbuf[i]);
941 if (sample_lens[lencheck] == cur_sample_len) 937 if (sample_lens[lencheck] == cur_sample_len)
942 break; 938 break;
943 } 939 }
944 if (lencheck == curlencheck) { 940 if (lencheck == curlencheck) {
945 cur_sample_len = redrat3_us_to_len(txbuf[i]);
946 rr3_dbg(dev, "txbuf[%d]=%u, pos %d, enc %u\n", 941 rr3_dbg(dev, "txbuf[%d]=%u, pos %d, enc %u\n",
947 i, txbuf[i], curlencheck, cur_sample_len); 942 i, txbuf[i], curlencheck, cur_sample_len);
948 if (curlencheck < 255) { 943 if (curlencheck < RR3_DRIVER_MAXLENS) {
949 /* now convert the value to a proper 944 /* now convert the value to a proper
950 * rr3 value.. */ 945 * rr3 value.. */
951 sample_lens[curlencheck] = cur_sample_len; 946 sample_lens[curlencheck] = cur_sample_len;
952 curlencheck++; 947 curlencheck++;
953 } else { 948 } else {
954 dev_err(dev, "signal too long\n"); 949 count = i - 1;
955 ret = -EINVAL; 950 break;
956 goto out;
957 } 951 }
958 } 952 }
959 } 953 }
@@ -1087,6 +1081,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
1087 rc->tx_ir = redrat3_transmit_ir; 1081 rc->tx_ir = redrat3_transmit_ir;
1088 rc->s_tx_carrier = redrat3_set_tx_carrier; 1082 rc->s_tx_carrier = redrat3_set_tx_carrier;
1089 rc->driver_name = DRIVER_NAME; 1083 rc->driver_name = DRIVER_NAME;
1084 rc->rx_resolution = US_TO_NS(2);
1090 rc->map_name = RC_MAP_HAUPPAUGE; 1085 rc->map_name = RC_MAP_HAUPPAUGE;
1091 1086
1092 ret = rc_register_device(rc); 1087 ret = rc_register_device(rc);
@@ -1202,7 +1197,6 @@ static int redrat3_dev_probe(struct usb_interface *intf,
1202 rr3->bulk_out_buf, ep_out->wMaxPacketSize, 1197 rr3->bulk_out_buf, ep_out->wMaxPacketSize,
1203 (usb_complete_t)redrat3_write_bulk_callback, rr3); 1198 (usb_complete_t)redrat3_write_bulk_callback, rr3);
1204 1199
1205 mutex_init(&rr3->lock);
1206 rr3->udev = udev; 1200 rr3->udev = udev;
1207 1201
1208 redrat3_reset(rr3); 1202 redrat3_reset(rr3);