diff options
author | Andrew Vincer <Andrew.Vincer@redrat.co.uk> | 2011-11-08 10:43:45 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-11-24 11:45:41 -0500 |
commit | dbea1880368071dfa97d5e6aa4a368e7d0146a85 (patch) | |
tree | f56ab48140d571ba564f469d34d721d1a4a98c58 | |
parent | 9369cc96af2d5e093ed7f0ac9671f4b30d30af86 (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>
-rw-r--r-- | drivers/media/rc/redrat3.c | 52 |
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: | |||
827 | static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs) | 821 | static 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 | ||
875 | static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs) | 863 | static 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 | ||
899 | static int redrat3_set_tx_carrier(struct rc_dev *dev, u32 carrier) | 887 | static 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 | ||
908 | static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n) | 898 | static 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 | ||
1060 | out: | 1044 | out: |
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 | } |