aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc
diff options
context:
space:
mode:
authorAndrew Vincer <Andrew.Vincer@redrat.co.uk>2011-11-08 10:43:45 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-11-24 11:45:41 -0500
commitdbea1880368071dfa97d5e6aa4a368e7d0146a85 (patch)
treef56ab48140d571ba564f469d34d721d1a4a98c58 /drivers/media/rc
parent9369cc96af2d5e093ed7f0ac9671f4b30d30af86 (diff)
[media] rc: Fix input deadlock and transmit error in redrat3 driver
Fixed submit urb logic so hardware doesn't hang trying to transmit signal data Removed unneeded enable/disable detector commands in redrat3_transmit_ir (the hardware does this anyway) and converted arguments to unsigned as per 5588dc2 Signed-off-by: Andrew Vincer <andrew@redrat.co.uk> Cc: Jarod Wilson <jarod@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/rc')
-rw-r--r--drivers/media/rc/redrat3.c52
1 files changed, 18 insertions, 34 deletions
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 61287fcca61a..9bff23cb0a5b 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -286,12 +286,6 @@ static void redrat3_issue_async(struct redrat3_dev *rr3)
286 286
287 rr3_ftr(rr3->dev, "Entering %s\n", __func__); 287 rr3_ftr(rr3->dev, "Entering %s\n", __func__);
288 288
289 if (!rr3->det_enabled) {
290 dev_warn(rr3->dev, "not issuing async read, "
291 "detector not enabled\n");
292 return;
293 }
294
295 memset(rr3->bulk_in_buf, 0, rr3->ep_in->wMaxPacketSize); 289 memset(rr3->bulk_in_buf, 0, rr3->ep_in->wMaxPacketSize);
296 res = usb_submit_urb(rr3->read_urb, GFP_ATOMIC); 290 res = usb_submit_urb(rr3->read_urb, GFP_ATOMIC);
297 if (res) 291 if (res)
@@ -827,6 +821,7 @@ out:
827static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) 821static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs)
828{ 822{
829 struct redrat3_dev *rr3; 823 struct redrat3_dev *rr3;
824 int ret;
830 825
831 if (!urb) 826 if (!urb)
832 return; 827 return;
@@ -840,15 +835,13 @@ static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs)
840 835
841 rr3_ftr(rr3->dev, "Entering %s\n", __func__); 836 rr3_ftr(rr3->dev, "Entering %s\n", __func__);
842 837
843 if (!rr3->det_enabled) {
844 rr3_dbg(rr3->dev, "received a read callback but detector "
845 "disabled - ignoring\n");
846 return;
847 }
848
849 switch (urb->status) { 838 switch (urb->status) {
850 case 0: 839 case 0:
851 redrat3_get_ir_data(rr3, urb->actual_length); 840 ret = redrat3_get_ir_data(rr3, urb->actual_length);
841 if (!ret) {
842 /* no error, prepare to read more */
843 redrat3_issue_async(rr3);
844 }
852 break; 845 break;
853 846
854 case -ECONNRESET: 847 case -ECONNRESET:
@@ -865,11 +858,6 @@ static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs)
865 rr3->pkttype = 0; 858 rr3->pkttype = 0;
866 break; 859 break;
867 } 860 }
868
869 if (!rr3->transmitting)
870 redrat3_issue_async(rr3);
871 else
872 rr3_dbg(rr3->dev, "IR transmit in progress\n");
873} 861}
874 862
875static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs) 863static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
@@ -896,21 +884,24 @@ static u16 mod_freq_to_val(unsigned int mod_freq)
896 return (u16)(65536 - (mult / mod_freq)); 884 return (u16)(65536 - (mult / mod_freq));
897} 885}
898 886
899static int redrat3_set_tx_carrier(struct rc_dev *dev, u32 carrier) 887static int redrat3_set_tx_carrier(struct rc_dev *rcdev, u32 carrier)
900{ 888{
901 struct redrat3_dev *rr3 = dev->priv; 889 struct redrat3_dev *rr3 = rcdev->priv;
890 struct device *dev = rr3->dev;
902 891
892 rr3_dbg(dev, "Setting modulation frequency to %u", carrier);
903 rr3->carrier = carrier; 893 rr3->carrier = carrier;
904 894
905 return carrier; 895 return carrier;
906} 896}
907 897
908static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n) 898static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
899 unsigned count)
909{ 900{
910 struct redrat3_dev *rr3 = rcdev->priv; 901 struct redrat3_dev *rr3 = rcdev->priv;
911 struct device *dev = rr3->dev; 902 struct device *dev = rr3->dev;
912 struct redrat3_signal_header header; 903 struct redrat3_signal_header header;
913 int i, j, count, ret, ret_len, offset; 904 int i, j, ret, ret_len, offset;
914 int lencheck, cur_sample_len, pipe; 905 int lencheck, cur_sample_len, pipe;
915 char *buffer = NULL, *sigdata = NULL; 906 char *buffer = NULL, *sigdata = NULL;
916 int *sample_lens = NULL; 907 int *sample_lens = NULL;
@@ -928,20 +919,13 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n)
928 return -EAGAIN; 919 return -EAGAIN;
929 } 920 }
930 921
931 count = n / sizeof(int);
932 if (count > (RR3_DRIVER_MAXLENS * 2)) 922 if (count > (RR3_DRIVER_MAXLENS * 2))
933 return -EINVAL; 923 return -EINVAL;
934 924
925 /* rr3 will disable rc detector on transmit */
926 rr3->det_enabled = false;
935 rr3->transmitting = true; 927 rr3->transmitting = true;
936 928
937 redrat3_disable_detector(rr3);
938
939 if (rr3->det_enabled) {
940 dev_err(dev, "%s: cannot tx while rx is enabled\n", __func__);
941 ret = -EIO;
942 goto out;
943 }
944
945 sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL); 929 sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL);
946 if (!sample_lens) { 930 if (!sample_lens) {
947 ret = -ENOMEM; 931 ret = -ENOMEM;
@@ -1055,7 +1039,7 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n)
1055 if (ret < 0) 1039 if (ret < 0)
1056 dev_err(dev, "Error: control msg send failed, rc %d\n", ret); 1040 dev_err(dev, "Error: control msg send failed, rc %d\n", ret);
1057 else 1041 else
1058 ret = n; 1042 ret = count;
1059 1043
1060out: 1044out:
1061 kfree(sample_lens); 1045 kfree(sample_lens);
@@ -1063,8 +1047,8 @@ out:
1063 kfree(sigdata); 1047 kfree(sigdata);
1064 1048
1065 rr3->transmitting = false; 1049 rr3->transmitting = false;
1066 1050 /* rr3 re-enables rc detector because it was enabled before */
1067 redrat3_enable_detector(rr3); 1051 rr3->det_enabled = true;
1068 1052
1069 return ret; 1053 return ret;
1070} 1054}