aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/cistpl.c155
1 files changed, 81 insertions, 74 deletions
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 41ec7729eddc..04bf1ba607f7 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -1577,88 +1577,95 @@ next_entry:
1577EXPORT_SYMBOL(pccard_loop_tuple); 1577EXPORT_SYMBOL(pccard_loop_tuple);
1578 1578
1579 1579
1580/*====================================================================== 1580/**
1581 1581 * pccard_validate_cis() - check whether card has a sensible CIS
1582 This tries to determine if a card has a sensible CIS. It returns 1582 * @s: the struct pcmcia_socket we are to check
1583 the number of tuples in the CIS, or 0 if the CIS looks bad. The 1583 * @info: returns the number of tuples in the (valid) CIS, or 0
1584 checks include making sure several critical tuples are present and 1584 *
1585 valid; seeing if the total number of tuples is reasonable; and 1585 * This tries to determine if a card has a sensible CIS. In @info, it
1586 looking for tuples that use reserved codes. 1586 * returns the number of tuples in the CIS, or 0 if the CIS looks bad. The
1587 1587 * checks include making sure several critical tuples are present and
1588======================================================================*/ 1588 * valid; seeing if the total number of tuples is reasonable; and
1589 1589 * looking for tuples that use reserved codes.
1590 *
1591 * The function returns 0 on success.
1592 */
1590int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info) 1593int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
1591{ 1594{
1592 tuple_t *tuple; 1595 tuple_t *tuple;
1593 cisparse_t *p; 1596 cisparse_t *p;
1594 unsigned int count = 0; 1597 unsigned int count = 0;
1595 int ret, reserved, dev_ok = 0, ident_ok = 0; 1598 int ret, reserved, dev_ok = 0, ident_ok = 0;
1596 1599
1597 if (!s) 1600 if (!s)
1598 return -EINVAL; 1601 return -EINVAL;
1599 1602
1600 /* We do not want to validate the CIS cache... */ 1603 /* We do not want to validate the CIS cache... */
1601 destroy_cis_cache(s); 1604 destroy_cis_cache(s);
1602 1605
1603 tuple = kmalloc(sizeof(*tuple), GFP_KERNEL); 1606 tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
1604 if (tuple == NULL) { 1607 if (tuple == NULL) {
1605 dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n"); 1608 dev_warn(&s->dev, "no memory to validate CIS\n");
1606 return -ENOMEM; 1609 return -ENOMEM;
1607 } 1610 }
1608 p = kmalloc(sizeof(*p), GFP_KERNEL); 1611 p = kmalloc(sizeof(*p), GFP_KERNEL);
1609 if (p == NULL) { 1612 if (p == NULL) {
1610 kfree(tuple); 1613 kfree(tuple);
1611 dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n"); 1614 dev_warn(&s->dev, "no memory to validate CIS\n");
1612 return -ENOMEM; 1615 return -ENOMEM;
1613 } 1616 }
1614 1617
1615 count = reserved = 0; 1618 count = reserved = 0;
1616 tuple->DesiredTuple = RETURN_FIRST_TUPLE; 1619 tuple->DesiredTuple = RETURN_FIRST_TUPLE;
1617 tuple->Attributes = TUPLE_RETURN_COMMON; 1620 tuple->Attributes = TUPLE_RETURN_COMMON;
1618 ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple); 1621 ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
1619 if (ret != 0)
1620 goto done;
1621
1622 /* First tuple should be DEVICE; we should really have either that
1623 or a CFTABLE_ENTRY of some sort */
1624 if ((tuple->TupleCode == CISTPL_DEVICE) ||
1625 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p) == 0) ||
1626 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
1627 dev_ok++;
1628
1629 /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
1630 tuple, for card identification. Certain old D-Link and Linksys
1631 cards have only a broken VERS_2 tuple; hence the bogus test. */
1632 if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
1633 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
1634 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
1635 ident_ok++;
1636
1637 if (!dev_ok && !ident_ok)
1638 goto done;
1639
1640 for (count = 1; count < MAX_TUPLES; count++) {
1641 ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
1642 if (ret != 0) 1622 if (ret != 0)
1643 break; 1623 goto done;
1644 if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) || 1624
1645 ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) || 1625 /* First tuple should be DEVICE; we should really have either that
1646 ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff))) 1626 or a CFTABLE_ENTRY of some sort */
1647 reserved++; 1627 if ((tuple->TupleCode == CISTPL_DEVICE) ||
1648 } 1628 (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p)) ||
1649 if ((count == MAX_TUPLES) || (reserved > 5) || 1629 (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p)))
1650 ((!dev_ok || !ident_ok) && (count > 10))) 1630 dev_ok++;
1651 count = 0; 1631
1632 /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
1633 tuple, for card identification. Certain old D-Link and Linksys
1634 cards have only a broken VERS_2 tuple; hence the bogus test. */
1635 if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
1636 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
1637 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
1638 ident_ok++;
1639
1640 if (!dev_ok && !ident_ok)
1641 goto done;
1642
1643 for (count = 1; count < MAX_TUPLES; count++) {
1644 ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
1645 if (ret != 0)
1646 break;
1647 if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
1648 ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
1649 ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
1650 reserved++;
1651 }
1652 if ((count == MAX_TUPLES) || (reserved > 5) ||
1653 ((!dev_ok || !ident_ok) && (count > 10)))
1654 count = 0;
1655
1656 ret = 0;
1652 1657
1653done: 1658done:
1654 /* invalidate CIS cache on failure */ 1659 /* invalidate CIS cache on failure */
1655 if (!dev_ok || !ident_ok || !count) 1660 if (!dev_ok || !ident_ok || !count) {
1656 destroy_cis_cache(s); 1661 destroy_cis_cache(s);
1657 1662 ret = -EIO;
1658 if (info) 1663 }
1659 *info = count; 1664
1660 kfree(tuple); 1665 if (info)
1661 kfree(p); 1666 *info = count;
1662 return 0; 1667 kfree(tuple);
1668 kfree(p);
1669 return ret;
1663} 1670}
1664EXPORT_SYMBOL(pccard_validate_cis); 1671EXPORT_SYMBOL(pccard_validate_cis);