diff options
author | Antti Palosaari <crope@iki.fi> | 2012-09-01 08:54:43 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-09-18 11:22:01 -0400 |
commit | 8b03663644002a6c742dd38dbdc8300da85293da (patch) | |
tree | d32fbfb44723ae28349367b033fa61d2fe326624 /drivers | |
parent | c392e9e13e398c3ebf37e60942c2ddadbe823880 (diff) |
[media] rtl28xxu: correct usb_clear_halt() usage
It is not allowed to call usb_clear_halt() after urbs are submitted.
That causes oops sometimes. Move whole streaming_ctrl() logic to
power_ctrl() in order to avoid wrong usb_clear_halt() use. Also,
configuring streaming endpoint in streaming_ctrl() sounds like a
little bit wrong as it is aimed for control stream gate.
Reported-by: Hin-Tak Leung <htl10@users.sourceforge.net>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index e29fca2ba125..7d11c5dede75 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c | |||
@@ -825,37 +825,10 @@ err: | |||
825 | return ret; | 825 | return ret; |
826 | } | 826 | } |
827 | 827 | ||
828 | static int rtl28xxu_streaming_ctrl(struct dvb_frontend *fe , int onoff) | ||
829 | { | ||
830 | int ret; | ||
831 | u8 buf[2]; | ||
832 | struct dvb_usb_device *d = fe_to_d(fe); | ||
833 | |||
834 | dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff); | ||
835 | |||
836 | if (onoff) { | ||
837 | buf[0] = 0x00; | ||
838 | buf[1] = 0x00; | ||
839 | usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x81)); | ||
840 | } else { | ||
841 | buf[0] = 0x10; /* stall EPA */ | ||
842 | buf[1] = 0x02; /* reset EPA */ | ||
843 | } | ||
844 | |||
845 | ret = rtl28xx_wr_regs(d, USB_EPA_CTL, buf, 2); | ||
846 | if (ret) | ||
847 | goto err; | ||
848 | |||
849 | return ret; | ||
850 | err: | ||
851 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | ||
852 | return ret; | ||
853 | } | ||
854 | |||
855 | static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff) | 828 | static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff) |
856 | { | 829 | { |
857 | int ret; | 830 | int ret; |
858 | u8 gpio, sys0; | 831 | u8 gpio, sys0, epa_ctl[2]; |
859 | 832 | ||
860 | dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff); | 833 | dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff); |
861 | 834 | ||
@@ -878,11 +851,15 @@ static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff) | |||
878 | gpio |= 0x04; /* GPIO2 = 1, LED on */ | 851 | gpio |= 0x04; /* GPIO2 = 1, LED on */ |
879 | sys0 = sys0 & 0x0f; | 852 | sys0 = sys0 & 0x0f; |
880 | sys0 |= 0xe0; | 853 | sys0 |= 0xe0; |
854 | epa_ctl[0] = 0x00; /* clear stall */ | ||
855 | epa_ctl[1] = 0x00; /* clear reset */ | ||
881 | } else { | 856 | } else { |
882 | gpio &= (~0x01); /* GPIO0 = 0 */ | 857 | gpio &= (~0x01); /* GPIO0 = 0 */ |
883 | gpio |= 0x10; /* GPIO4 = 1 */ | 858 | gpio |= 0x10; /* GPIO4 = 1 */ |
884 | gpio &= (~0x04); /* GPIO2 = 1, LED off */ | 859 | gpio &= (~0x04); /* GPIO2 = 1, LED off */ |
885 | sys0 = sys0 & (~0xc0); | 860 | sys0 = sys0 & (~0xc0); |
861 | epa_ctl[0] = 0x10; /* set stall */ | ||
862 | epa_ctl[1] = 0x02; /* set reset */ | ||
886 | } | 863 | } |
887 | 864 | ||
888 | dev_dbg(&d->udev->dev, "%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, | 865 | dev_dbg(&d->udev->dev, "%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, |
@@ -898,6 +875,14 @@ static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff) | |||
898 | if (ret) | 875 | if (ret) |
899 | goto err; | 876 | goto err; |
900 | 877 | ||
878 | /* streaming EP: stall & reset */ | ||
879 | ret = rtl28xx_wr_regs(d, USB_EPA_CTL, epa_ctl, 2); | ||
880 | if (ret) | ||
881 | goto err; | ||
882 | |||
883 | if (onoff) | ||
884 | usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x81)); | ||
885 | |||
901 | return ret; | 886 | return ret; |
902 | err: | 887 | err: |
903 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | 888 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); |
@@ -972,6 +957,14 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff) | |||
972 | goto err; | 957 | goto err; |
973 | 958 | ||
974 | 959 | ||
960 | /* streaming EP: clear stall & reset */ | ||
961 | ret = rtl28xx_wr_regs(d, USB_EPA_CTL, "\x00\x00", 2); | ||
962 | if (ret) | ||
963 | goto err; | ||
964 | |||
965 | ret = usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x81)); | ||
966 | if (ret) | ||
967 | goto err; | ||
975 | } else { | 968 | } else { |
976 | /* demod_ctl_1 */ | 969 | /* demod_ctl_1 */ |
977 | ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val); | 970 | ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val); |
@@ -1006,6 +999,10 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff) | |||
1006 | if (ret) | 999 | if (ret) |
1007 | goto err; | 1000 | goto err; |
1008 | 1001 | ||
1002 | /* streaming EP: set stall & reset */ | ||
1003 | ret = rtl28xx_wr_regs(d, USB_EPA_CTL, "\x10\x02", 2); | ||
1004 | if (ret) | ||
1005 | goto err; | ||
1009 | } | 1006 | } |
1010 | 1007 | ||
1011 | return ret; | 1008 | return ret; |
@@ -1182,7 +1179,6 @@ static const struct dvb_usb_device_properties rtl2831u_props = { | |||
1182 | .tuner_attach = rtl2831u_tuner_attach, | 1179 | .tuner_attach = rtl2831u_tuner_attach, |
1183 | .init = rtl28xxu_init, | 1180 | .init = rtl28xxu_init, |
1184 | .get_rc_config = rtl2831u_get_rc_config, | 1181 | .get_rc_config = rtl2831u_get_rc_config, |
1185 | .streaming_ctrl = rtl28xxu_streaming_ctrl, | ||
1186 | 1182 | ||
1187 | .num_adapters = 1, | 1183 | .num_adapters = 1, |
1188 | .adapter = { | 1184 | .adapter = { |
@@ -1204,7 +1200,6 @@ static const struct dvb_usb_device_properties rtl2832u_props = { | |||
1204 | .tuner_attach = rtl2832u_tuner_attach, | 1200 | .tuner_attach = rtl2832u_tuner_attach, |
1205 | .init = rtl28xxu_init, | 1201 | .init = rtl28xxu_init, |
1206 | .get_rc_config = rtl2832u_get_rc_config, | 1202 | .get_rc_config = rtl2832u_get_rc_config, |
1207 | .streaming_ctrl = rtl28xxu_streaming_ctrl, | ||
1208 | 1203 | ||
1209 | .num_adapters = 1, | 1204 | .num_adapters = 1, |
1210 | .adapter = { | 1205 | .adapter = { |