pcmcia: cleanup pccard_validate_cis()
Cleanup pccard_validate_cis() and make it return an error code on all failures, not merely on some failures. Tested-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
parent
904e377744
commit
f131ddc4bd
|
@ -1577,88 +1577,95 @@ next_entry:
|
||||||
EXPORT_SYMBOL(pccard_loop_tuple);
|
EXPORT_SYMBOL(pccard_loop_tuple);
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================
|
/**
|
||||||
|
* pccard_validate_cis() - check whether card has a sensible CIS
|
||||||
This tries to determine if a card has a sensible CIS. It returns
|
* @s: the struct pcmcia_socket we are to check
|
||||||
the number of tuples in the CIS, or 0 if the CIS looks bad. The
|
* @info: returns the number of tuples in the (valid) CIS, or 0
|
||||||
checks include making sure several critical tuples are present and
|
*
|
||||||
valid; seeing if the total number of tuples is reasonable; and
|
* This tries to determine if a card has a sensible CIS. In @info, it
|
||||||
looking for tuples that use reserved codes.
|
* returns the number of tuples in the CIS, or 0 if the CIS looks bad. The
|
||||||
|
* checks include making sure several critical tuples are present and
|
||||||
======================================================================*/
|
* valid; seeing if the total number of tuples is reasonable; and
|
||||||
|
* looking for tuples that use reserved codes.
|
||||||
|
*
|
||||||
|
* The function returns 0 on success.
|
||||||
|
*/
|
||||||
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
|
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
|
||||||
{
|
{
|
||||||
tuple_t *tuple;
|
tuple_t *tuple;
|
||||||
cisparse_t *p;
|
cisparse_t *p;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
int ret, reserved, dev_ok = 0, ident_ok = 0;
|
int ret, reserved, dev_ok = 0, ident_ok = 0;
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* We do not want to validate the CIS cache... */
|
/* We do not want to validate the CIS cache... */
|
||||||
destroy_cis_cache(s);
|
destroy_cis_cache(s);
|
||||||
|
|
||||||
tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
|
tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
|
||||||
if (tuple == NULL) {
|
if (tuple == NULL) {
|
||||||
dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
|
dev_warn(&s->dev, "no memory to validate CIS\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
p = kmalloc(sizeof(*p), GFP_KERNEL);
|
p = kmalloc(sizeof(*p), GFP_KERNEL);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
kfree(tuple);
|
kfree(tuple);
|
||||||
dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
|
dev_warn(&s->dev, "no memory to validate CIS\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = reserved = 0;
|
count = reserved = 0;
|
||||||
tuple->DesiredTuple = RETURN_FIRST_TUPLE;
|
tuple->DesiredTuple = RETURN_FIRST_TUPLE;
|
||||||
tuple->Attributes = TUPLE_RETURN_COMMON;
|
tuple->Attributes = TUPLE_RETURN_COMMON;
|
||||||
ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
|
ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
|
||||||
if (ret != 0)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* First tuple should be DEVICE; we should really have either that
|
|
||||||
or a CFTABLE_ENTRY of some sort */
|
|
||||||
if ((tuple->TupleCode == CISTPL_DEVICE) ||
|
|
||||||
(pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p) == 0) ||
|
|
||||||
(pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
|
|
||||||
dev_ok++;
|
|
||||||
|
|
||||||
/* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
|
|
||||||
tuple, for card identification. Certain old D-Link and Linksys
|
|
||||||
cards have only a broken VERS_2 tuple; hence the bogus test. */
|
|
||||||
if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
|
|
||||||
(pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
|
|
||||||
(pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
|
|
||||||
ident_ok++;
|
|
||||||
|
|
||||||
if (!dev_ok && !ident_ok)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
for (count = 1; count < MAX_TUPLES; count++) {
|
|
||||||
ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
break;
|
goto done;
|
||||||
if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
|
|
||||||
((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
|
/* First tuple should be DEVICE; we should really have either that
|
||||||
((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
|
or a CFTABLE_ENTRY of some sort */
|
||||||
reserved++;
|
if ((tuple->TupleCode == CISTPL_DEVICE) ||
|
||||||
}
|
(!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p)) ||
|
||||||
if ((count == MAX_TUPLES) || (reserved > 5) ||
|
(!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p)))
|
||||||
((!dev_ok || !ident_ok) && (count > 10)))
|
dev_ok++;
|
||||||
count = 0;
|
|
||||||
|
/* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
|
||||||
|
tuple, for card identification. Certain old D-Link and Linksys
|
||||||
|
cards have only a broken VERS_2 tuple; hence the bogus test. */
|
||||||
|
if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
|
||||||
|
(pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
|
||||||
|
(pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
|
||||||
|
ident_ok++;
|
||||||
|
|
||||||
|
if (!dev_ok && !ident_ok)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
for (count = 1; count < MAX_TUPLES; count++) {
|
||||||
|
ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
|
||||||
|
if (ret != 0)
|
||||||
|
break;
|
||||||
|
if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
|
||||||
|
((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
|
||||||
|
((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
|
||||||
|
reserved++;
|
||||||
|
}
|
||||||
|
if ((count == MAX_TUPLES) || (reserved > 5) ||
|
||||||
|
((!dev_ok || !ident_ok) && (count > 10)))
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
/* invalidate CIS cache on failure */
|
/* invalidate CIS cache on failure */
|
||||||
if (!dev_ok || !ident_ok || !count)
|
if (!dev_ok || !ident_ok || !count) {
|
||||||
destroy_cis_cache(s);
|
destroy_cis_cache(s);
|
||||||
|
ret = -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
*info = count;
|
*info = count;
|
||||||
kfree(tuple);
|
kfree(tuple);
|
||||||
kfree(p);
|
kfree(p);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pccard_validate_cis);
|
EXPORT_SYMBOL(pccard_validate_cis);
|
||||||
|
|
Loading…
Reference in New Issue