diff options
author | Sean Young <sean@mess.org> | 2013-02-16 15:25:43 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-19 14:14:00 -0400 |
commit | 801b69f2570e2556c6d5a060df85ce9bd0d38119 (patch) | |
tree | 31c5debaeceb7a0a7c1ac027ab96a710708dc3a0 /drivers/media/rc | |
parent | 4159d01bea38ee82f6e49383b7e73e328c118755 (diff) |
[media] redrat3: limit periods to hardware limits
The redrat hardware cannot handle periods of larger than 32767us,
limit appropriately. Also fix memory leak in redrat3_get_timeout.
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/rc')
-rw-r--r-- | drivers/media/rc/redrat3.c | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 1b37fe2779f8..842bdcded27c 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c | |||
@@ -209,9 +209,6 @@ struct redrat3_dev { | |||
209 | u16 pktlen; | 209 | u16 pktlen; |
210 | u16 pkttype; | 210 | u16 pkttype; |
211 | u16 bytes_read; | 211 | u16 bytes_read; |
212 | /* indicate whether we are going to reprocess | ||
213 | * the USB callback with a bigger buffer */ | ||
214 | int buftoosmall; | ||
215 | char *datap; | 212 | char *datap; |
216 | 213 | ||
217 | u32 carrier; | 214 | u32 carrier; |
@@ -396,7 +393,6 @@ static u32 redrat3_us_to_len(u32 microsec) | |||
396 | 393 | ||
397 | /* don't allow zero lengths to go back, breaks lirc */ | 394 | /* don't allow zero lengths to go back, breaks lirc */ |
398 | return result ? result : 1; | 395 | return result ? result : 1; |
399 | |||
400 | } | 396 | } |
401 | 397 | ||
402 | /* timer callback to send reset event */ | 398 | /* timer callback to send reset event */ |
@@ -515,8 +511,6 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) | |||
515 | 511 | ||
516 | rr3_dbg(dev, "calling ir_raw_event_handle\n"); | 512 | rr3_dbg(dev, "calling ir_raw_event_handle\n"); |
517 | ir_raw_event_handle(rr3->rc); | 513 | ir_raw_event_handle(rr3->rc); |
518 | |||
519 | return; | ||
520 | } | 514 | } |
521 | 515 | ||
522 | /* Util fn to send rr3 cmds */ | 516 | /* Util fn to send rr3 cmds */ |
@@ -613,7 +607,7 @@ static inline void redrat3_delete(struct redrat3_dev *rr3, | |||
613 | 607 | ||
614 | static u32 redrat3_get_timeout(struct redrat3_dev *rr3) | 608 | static u32 redrat3_get_timeout(struct redrat3_dev *rr3) |
615 | { | 609 | { |
616 | u32 *tmp; | 610 | __be32 *tmp; |
617 | u32 timeout = MS_TO_US(150); /* a sane default, if things go haywire */ | 611 | u32 timeout = MS_TO_US(150); /* a sane default, if things go haywire */ |
618 | int len, ret, pipe; | 612 | int len, ret, pipe; |
619 | 613 | ||
@@ -628,14 +622,16 @@ static u32 redrat3_get_timeout(struct redrat3_dev *rr3) | |||
628 | ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM, | 622 | ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM, |
629 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, | 623 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
630 | RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5); | 624 | RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5); |
631 | if (ret != len) { | 625 | if (ret != len) |
632 | dev_warn(rr3->dev, "Failed to read timeout from hardware\n"); | 626 | dev_warn(rr3->dev, "Failed to read timeout from hardware\n"); |
633 | return timeout; | 627 | else { |
628 | timeout = redrat3_len_to_us(be32_to_cpup(tmp)); | ||
629 | |||
630 | rr3_dbg(rr3->dev, "Got timeout of %d ms\n", timeout / 1000); | ||
634 | } | 631 | } |
635 | 632 | ||
636 | timeout = redrat3_len_to_us(be32_to_cpu(*tmp)); | 633 | kfree(tmp); |
637 | 634 | ||
638 | rr3_dbg(rr3->dev, "Got timeout of %d ms\n", timeout / 1000); | ||
639 | return timeout; | 635 | return timeout; |
640 | } | 636 | } |
641 | 637 | ||
@@ -755,7 +751,6 @@ static void redrat3_read_packet_start(struct redrat3_dev *rr3, int len) | |||
755 | 751 | ||
756 | static void redrat3_read_packet_continue(struct redrat3_dev *rr3, int len) | 752 | static void redrat3_read_packet_continue(struct redrat3_dev *rr3, int len) |
757 | { | 753 | { |
758 | |||
759 | rr3_ftr(rr3->dev, "Entering %s\n", __func__); | 754 | rr3_ftr(rr3->dev, "Entering %s\n", __func__); |
760 | 755 | ||
761 | memcpy(rr3->datap, (unsigned char *)rr3->bulk_in_buf, len); | 756 | memcpy(rr3->datap, (unsigned char *)rr3->bulk_in_buf, len); |
@@ -815,7 +810,7 @@ out: | |||
815 | } | 810 | } |
816 | 811 | ||
817 | /* callback function from USB when async USB request has completed */ | 812 | /* callback function from USB when async USB request has completed */ |
818 | static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) | 813 | static void redrat3_handle_async(struct urb *urb) |
819 | { | 814 | { |
820 | struct redrat3_dev *rr3; | 815 | struct redrat3_dev *rr3; |
821 | int ret; | 816 | int ret; |
@@ -857,7 +852,7 @@ static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) | |||
857 | } | 852 | } |
858 | } | 853 | } |
859 | 854 | ||
860 | static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs) | 855 | static void redrat3_write_bulk_callback(struct urb *urb) |
861 | { | 856 | { |
862 | struct redrat3_dev *rr3; | 857 | struct redrat3_dev *rr3; |
863 | int len; | 858 | int len; |
@@ -901,7 +896,7 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, | |||
901 | struct redrat3_dev *rr3 = rcdev->priv; | 896 | struct redrat3_dev *rr3 = rcdev->priv; |
902 | struct device *dev = rr3->dev; | 897 | struct device *dev = rr3->dev; |
903 | struct redrat3_signal_header header; | 898 | struct redrat3_signal_header header; |
904 | int i, j, ret, ret_len, offset; | 899 | int i, ret, ret_len, offset; |
905 | int lencheck, cur_sample_len, pipe; | 900 | int lencheck, cur_sample_len, pipe; |
906 | char *buffer = NULL, *sigdata = NULL; | 901 | char *buffer = NULL, *sigdata = NULL; |
907 | int *sample_lens = NULL; | 902 | int *sample_lens = NULL; |
@@ -931,8 +926,19 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, | |||
931 | goto out; | 926 | goto out; |
932 | } | 927 | } |
933 | 928 | ||
929 | sigdata = kzalloc((count + RR3_TX_TRAILER_LEN), GFP_KERNEL); | ||
930 | if (!sigdata) { | ||
931 | ret = -ENOMEM; | ||
932 | goto out; | ||
933 | } | ||
934 | |||
934 | for (i = 0; i < count; i++) { | 935 | for (i = 0; i < count; i++) { |
935 | cur_sample_len = redrat3_us_to_len(txbuf[i]); | 936 | cur_sample_len = redrat3_us_to_len(txbuf[i]); |
937 | if (cur_sample_len > 0xffff) { | ||
938 | dev_warn(dev, "transmit period of %uus truncated to %uus\n", | ||
939 | txbuf[i], redrat3_len_to_us(0xffff)); | ||
940 | cur_sample_len = 0xffff; | ||
941 | } | ||
936 | for (lencheck = 0; lencheck < curlencheck; lencheck++) { | 942 | for (lencheck = 0; lencheck < curlencheck; lencheck++) { |
937 | if (sample_lens[lencheck] == cur_sample_len) | 943 | if (sample_lens[lencheck] == cur_sample_len) |
938 | break; | 944 | break; |
@@ -950,22 +956,11 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, | |||
950 | break; | 956 | break; |
951 | } | 957 | } |
952 | } | 958 | } |
953 | } | 959 | sigdata[i] = lencheck; |
954 | |||
955 | sigdata = kzalloc((count + RR3_TX_TRAILER_LEN), GFP_KERNEL); | ||
956 | if (!sigdata) { | ||
957 | ret = -ENOMEM; | ||
958 | goto out; | ||
959 | } | 960 | } |
960 | 961 | ||
961 | sigdata[count] = RR3_END_OF_SIGNAL; | 962 | sigdata[count] = RR3_END_OF_SIGNAL; |
962 | sigdata[count + 1] = RR3_END_OF_SIGNAL; | 963 | sigdata[count + 1] = RR3_END_OF_SIGNAL; |
963 | for (i = 0; i < count; i++) { | ||
964 | for (j = 0; j < curlencheck; j++) { | ||
965 | if (sample_lens[j] == redrat3_us_to_len(txbuf[i])) | ||
966 | sigdata[i] = j; | ||
967 | } | ||
968 | } | ||
969 | 964 | ||
970 | offset = RR3_TX_HEADER_OFFSET; | 965 | offset = RR3_TX_HEADER_OFFSET; |
971 | sendbuf_len = RR3_HEADER_LENGTH + (sizeof(u16) * RR3_DRIVER_MAXLENS) | 966 | sendbuf_len = RR3_HEADER_LENGTH + (sizeof(u16) * RR3_DRIVER_MAXLENS) |
@@ -1175,7 +1170,7 @@ static int redrat3_dev_probe(struct usb_interface *intf, | |||
1175 | pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress); | 1170 | pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress); |
1176 | usb_fill_bulk_urb(rr3->read_urb, udev, pipe, | 1171 | usb_fill_bulk_urb(rr3->read_urb, udev, pipe, |
1177 | rr3->bulk_in_buf, ep_in->wMaxPacketSize, | 1172 | rr3->bulk_in_buf, ep_in->wMaxPacketSize, |
1178 | (usb_complete_t)redrat3_handle_async, rr3); | 1173 | redrat3_handle_async, rr3); |
1179 | 1174 | ||
1180 | /* set up bulk-out endpoint*/ | 1175 | /* set up bulk-out endpoint*/ |
1181 | rr3->write_urb = usb_alloc_urb(0, GFP_KERNEL); | 1176 | rr3->write_urb = usb_alloc_urb(0, GFP_KERNEL); |
@@ -1195,7 +1190,7 @@ static int redrat3_dev_probe(struct usb_interface *intf, | |||
1195 | pipe = usb_sndbulkpipe(udev, ep_out->bEndpointAddress); | 1190 | pipe = usb_sndbulkpipe(udev, ep_out->bEndpointAddress); |
1196 | usb_fill_bulk_urb(rr3->write_urb, udev, pipe, | 1191 | usb_fill_bulk_urb(rr3->write_urb, udev, pipe, |
1197 | rr3->bulk_out_buf, ep_out->wMaxPacketSize, | 1192 | rr3->bulk_out_buf, ep_out->wMaxPacketSize, |
1198 | (usb_complete_t)redrat3_write_bulk_callback, rr3); | 1193 | redrat3_write_bulk_callback, rr3); |
1199 | 1194 | ||
1200 | rr3->udev = udev; | 1195 | rr3->udev = udev; |
1201 | 1196 | ||