提交 b1535293 编写于 作者: C Chris Pascoe 提交者: Mauro Carvalho Chehab

V4L/DVB (6643): xc2028: use best match instead of first partial match during firmware selection

Rather than picking the first video standard firmware that supports any of
the standards that the user has requested, try to select one that supports
as many of them as possible.  This improves the likelihood that the firmware
we select will support the user's desired TV standard.
Signed-off-by: NChris Pascoe <c.pascoe@itee.uq.edu.au>
Signed-off-by: NMauro Carvalho Chehab <mchehab@infradead.org>
上级 0a196b6f
...@@ -377,9 +377,13 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, ...@@ -377,9 +377,13 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
v4l2_std_id *id) v4l2_std_id *id)
{ {
struct xc2028_data *priv = fe->tuner_priv; struct xc2028_data *priv = fe->tuner_priv;
int i; int i, best_i = -1, best_nr_matches = 0;
tuner_dbg("%s called\n", __FUNCTION__); tuner_dbg("%s called, want type=", __FUNCTION__);
if (debug) {
dump_firm_type(type);
printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
}
if (!priv->firm) { if (!priv->firm) {
tuner_err("Error! firmware not loaded\n"); tuner_err("Error! firmware not loaded\n");
...@@ -397,20 +401,45 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, ...@@ -397,20 +401,45 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
/* Seek for generic video standard match */ /* Seek for generic video standard match */
for (i = 0; i < priv->firm_size; i++) { for (i = 0; i < priv->firm_size; i++) {
if ((type == priv->firm[i].type) && (*id & priv->firm[i].id)) v4l2_std_id match_mask;
goto found; int nr_matches;
if (type != priv->firm[i].type)
continue;
match_mask = *id & priv->firm[i].id;
if (!match_mask)
continue;
if ((*id & match_mask) == *id)
goto found; /* Supports all the requested standards */
nr_matches = hweight64(match_mask);
if (nr_matches > best_nr_matches) {
best_nr_matches = nr_matches;
best_i = i;
}
}
if (best_nr_matches > 0) {
tuner_dbg("Selecting best matching firmware (%d bits) for "
"type=", best_nr_matches);
dump_firm_type(type);
printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
i = best_i;
goto found;
} }
/*FIXME: Would make sense to seek for type "hint" match ? */ /*FIXME: Would make sense to seek for type "hint" match ? */
i = -EINVAL; i = -ENOENT;
goto ret; goto ret;
found: found:
*id = priv->firm[i].id; *id = priv->firm[i].id;
ret: ret:
tuner_dbg("%s firmware for type=", (i < 0)? "Can't find": "Found"); tuner_dbg("%s firmware for type=", (i < 0) ? "Can't find" : "Found");
if (debug) { if (debug) {
dump_firm_type(type); dump_firm_type(type);
printk("(%x), id %016llx.\n", type, (unsigned long long)*id); printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
...@@ -432,8 +461,9 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, ...@@ -432,8 +461,9 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type,
return pos; return pos;
tuner_info("Loading firmware for type="); tuner_info("Loading firmware for type=");
dump_firm_type(type); dump_firm_type(priv->firm[pos].type);
printk("(%x), id %016llx.\n", type, (unsigned long long)*id); printk("(%x), id %016llx.\n", priv->firm[pos].type,
(unsigned long long)*id);
p = priv->firm[pos].ptr; p = priv->firm[pos].ptr;
endp = p + priv->firm[pos].size; endp = p + priv->firm[pos].size;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
新手
引导
客服 返回
顶部