summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2016-07-18 09:44:10 +0300
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2016-07-19 19:27:46 +0300
commit009a620848218d521f008141c62f56bf19294dd9 (patch)
treeeceecb22b1fc73fd1c05cc22aeb622ff5b525cad
parentb7cbc892532316f2abd880186301e57239a17f28 (diff)
downloadlinux-009a620848218d521f008141c62f56bf19294dd9.tar.xz
[media] cec: always check all_device_types and features
Even when the adapter is configured for CEC 1.4, we still check and use the CEC 2.0 parts of struct cec_log_addrs. Although these aren't used in CEC messages, the information contained in them is still of use in the CEC framework itself, so keep this information. Also zero the unused trailing features[] data and unused logical address data so the contents isn't random data. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
-rw-r--r--drivers/staging/media/cec/cec-adap.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c
index 6fa3db512138..9fffddb7ac7e 100644
--- a/drivers/staging/media/cec/cec-adap.c
+++ b/drivers/staging/media/cec/cec-adap.c
@@ -1210,13 +1210,8 @@ int __cec_s_log_addrs(struct cec_adapter *adap,
return -EINVAL;
}
- if (log_addrs->cec_version < CEC_OP_CEC_VERSION_2_0) {
- memset(log_addrs->all_device_types, 0,
- sizeof(log_addrs->all_device_types));
- memset(log_addrs->features, 0, sizeof(log_addrs->features));
- }
-
for (i = 0; i < log_addrs->num_log_addrs; i++) {
+ const u8 feature_sz = ARRAY_SIZE(log_addrs->features[0]);
u8 *features = log_addrs->features[i];
bool op_is_dev_features = false;
@@ -1245,21 +1240,19 @@ int __cec_s_log_addrs(struct cec_adapter *adap,
dprintk(1, "unknown logical address type\n");
return -EINVAL;
}
- if (log_addrs->cec_version < CEC_OP_CEC_VERSION_2_0)
- continue;
-
- for (i = 0; i < ARRAY_SIZE(log_addrs->features[0]); i++) {
+ for (i = 0; i < feature_sz; i++) {
if ((features[i] & 0x80) == 0) {
if (op_is_dev_features)
break;
op_is_dev_features = true;
}
}
- if (!op_is_dev_features ||
- i == ARRAY_SIZE(log_addrs->features[0])) {
+ if (!op_is_dev_features || i == feature_sz) {
dprintk(1, "malformed features\n");
return -EINVAL;
}
+ /* Zero unused part of the feature array */
+ memset(features + i, 0, feature_sz - i);
}
if (log_addrs->cec_version >= CEC_OP_CEC_VERSION_2_0) {
@@ -1281,6 +1274,15 @@ int __cec_s_log_addrs(struct cec_adapter *adap,
}
}
+ /* Zero unused LAs */
+ for (i = log_addrs->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) {
+ log_addrs->primary_device_type[i] = 0;
+ log_addrs->log_addr_type[i] = 0;
+ log_addrs->all_device_types[i] = 0;
+ memset(log_addrs->features[i], 0,
+ sizeof(log_addrs->features[i]));
+ }
+
log_addrs->log_addr_mask = adap->log_addrs.log_addr_mask;
adap->log_addrs = *log_addrs;
if (adap->phys_addr != CEC_PHYS_ADDR_INVALID)