diff options
author | Antti Palosaari <crope@iki.fi> | 2012-01-21 09:19:29 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-01-26 11:46:09 -0500 |
commit | cf427952adcee0210e64b77ae7de9c8f256cce5c (patch) | |
tree | 1a10d40bf9b5207b4a04dea36b5eb90ffa81ed4c | |
parent | 3e9caa525147e28d032a8e413d9797c21cbaf88c (diff) |
[media] anysee: repeat failed USB control messages
Control message load increased heavily after CI/CAM support due
to dvb_ca_en50221. It looks like CI/CAM drops to non-working
state easily after error is returned to its callbacks. Due to
that, add some logic to avoid errors repeating failed messages.
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/dvb/dvb-usb/anysee.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index cf0c318d6989..03c28655af1b 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c | |||
@@ -58,7 +58,7 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, | |||
58 | u8 *rbuf, u8 rlen) | 58 | u8 *rbuf, u8 rlen) |
59 | { | 59 | { |
60 | struct anysee_state *state = d->priv; | 60 | struct anysee_state *state = d->priv; |
61 | int act_len, ret; | 61 | int act_len, ret, i; |
62 | u8 buf[64]; | 62 | u8 buf[64]; |
63 | 63 | ||
64 | memcpy(&buf[0], sbuf, slen); | 64 | memcpy(&buf[0], sbuf, slen); |
@@ -73,26 +73,52 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, | |||
73 | /* We need receive one message more after dvb_usb_generic_rw due | 73 | /* We need receive one message more after dvb_usb_generic_rw due |
74 | to weird transaction flow, which is 1 x send + 2 x receive. */ | 74 | to weird transaction flow, which is 1 x send + 2 x receive. */ |
75 | ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); | 75 | ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); |
76 | if (!ret) { | 76 | if (ret) |
77 | goto error_unlock; | ||
78 | |||
79 | /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32 | ||
80 | * (EPIPE, Broken pipe). Function supports currently msleep() as a | ||
81 | * parameter but I would not like to use it, since according to | ||
82 | * Documentation/timers/timers-howto.txt it should not be used such | ||
83 | * short, under < 20ms, sleeps. Repeating failed message would be | ||
84 | * better choice as not to add unwanted delays... | ||
85 | * Fixing that correctly is one of those or both; | ||
86 | * 1) use repeat if possible | ||
87 | * 2) add suitable delay | ||
88 | */ | ||
89 | |||
90 | /* get answer, retry few times if error returned */ | ||
91 | for (i = 0; i < 3; i++) { | ||
77 | /* receive 2nd answer */ | 92 | /* receive 2nd answer */ |
78 | ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, | 93 | ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, |
79 | d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf), | 94 | d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf), |
80 | &act_len, 2000); | 95 | &act_len, 2000); |
81 | if (ret) | 96 | |
82 | err("%s: recv bulk message failed: %d", __func__, ret); | 97 | if (ret) { |
83 | else { | 98 | deb_info("%s: recv bulk message failed: %d", |
99 | __func__, ret); | ||
100 | } else { | ||
84 | deb_xfer("<<< "); | 101 | deb_xfer("<<< "); |
85 | debug_dump(buf, rlen, deb_xfer); | 102 | debug_dump(buf, rlen, deb_xfer); |
86 | 103 | ||
87 | if (buf[63] != 0x4f) | 104 | if (buf[63] != 0x4f) |
88 | deb_info("%s: cmd failed\n", __func__); | 105 | deb_info("%s: cmd failed\n", __func__); |
106 | |||
107 | break; | ||
89 | } | 108 | } |
90 | } | 109 | } |
91 | 110 | ||
111 | if (ret) { | ||
112 | /* all retries failed, it is fatal */ | ||
113 | err("%s: recv bulk message failed: %d", __func__, ret); | ||
114 | goto error_unlock; | ||
115 | } | ||
116 | |||
92 | /* read request, copy returned data to return buf */ | 117 | /* read request, copy returned data to return buf */ |
93 | if (!ret && rbuf && rlen) | 118 | if (rbuf && rlen) |
94 | memcpy(rbuf, buf, rlen); | 119 | memcpy(rbuf, buf, rlen); |
95 | 120 | ||
121 | error_unlock: | ||
96 | mutex_unlock(&anysee_usb_mutex); | 122 | mutex_unlock(&anysee_usb_mutex); |
97 | 123 | ||
98 | return ret; | 124 | return ret; |