summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2002-10-07 23:03:17 +0000
committerimp <imp@FreeBSD.org>2002-10-07 23:03:17 +0000
commit61ae73678b3be31aa98fc3ba21750812e1189c04 (patch)
treeb267a97edb45347dc1f4bebf31fc92100efaec81
parentf7540bad93cb1b4a6ab24acf728cd59ee110f63e (diff)
downloadFreeBSD-src-61ae73678b3be31aa98fc3ba21750812e1189c04.zip
FreeBSD-src-61ae73678b3be31aa98fc3ba21750812e1189c04.tar.gz
Merge changes from NetBSD through version 1.17 of this file. These
give us slightly better error checking than before and interpret what default bits mean better. See the NetBSD CVS tree for the authors of these changes (revs 1.10 .. 1.17).
-rw-r--r--sys/dev/pccard/pccard_cis.c68
1 files changed, 54 insertions, 14 deletions
diff --git a/sys/dev/pccard/pccard_cis.c b/sys/dev/pccard/pccard_cis.c
index 3ee3813..c11e29f 100644
--- a/sys/dev/pccard/pccard_cis.c
+++ b/sys/dev/pccard/pccard_cis.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pcmcia_cis.c,v 1.10 1998/12/29 09:03:15 marc Exp $ */
+/* $NetBSD: pcmcia_cis.c,v 1.17 2000/02/10 09:01:52 chopps Exp $ */
/* $FreeBSD$ */
/*
@@ -78,8 +78,7 @@ pccard_read_cis(struct pccard_softc *sc)
{
struct cis_state state;
- state.count = 0;
- state.gotmfc = 0;
+ bzero(&state, sizeof state);
state.card = &sc->card;
@@ -224,9 +223,8 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *),
* distant regions
*/
if ((addr >= PCCARD_CIS_SIZE) ||
- ((addr + length) < 0) ||
((addr + length) >=
- PCCARD_CIS_SIZE)) {
+ PCCARD_CIS_SIZE)) {
DPRINTF((" skipped, "
"too distant\n"));
break;
@@ -260,17 +258,50 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *),
"short %d\n", tuple.length));
break;
}
+ if (((tuple.length - 1) % 5) != 0) {
+ DPRINTF(("CISTPL_LONGLINK_MFC bogus "
+ "length %d\n", tuple.length));
+ break;
+ }
/*
* this is kind of ad hoc, as I don't have
* any real documentation
*/
{
- int i;
+ int i, tmp_count;
- mfc_count =
+ /*
+ * put count into tmp var so that
+ * if we have to bail (because it's
+ * a bogus count) it won't be
+ * remembered for later use.
+ */
+ tmp_count =
pccard_tuple_read_1(&tuple, 0);
+
DPRINTF(("CISTPL_LONGLINK_MFC %d",
- mfc_count));
+ tmp_count));
+
+ /*
+ * make _sure_ it's the right size;
+ * if too short, it may be a weird
+ * (unknown/undefined) format
+ */
+ if (tuple.length != (tmp_count*5 + 1)) {
+ DPRINTF((" bogus length %d\n",
+ tuple.length));
+ break;
+ }
+ /*
+ * sanity check for a programming
+ * error which is difficult to find
+ * when debugging.
+ */
+ if (tmp_count >
+ howmany(sizeof mfc, sizeof mfc[0]))
+ panic("CISTPL_LONGLINK_MFC mfc "
+ "count would blow stack");
+ mfc_count = tmp_count;
for (i = 0; i < mfc_count; i++) {
mfc[i].common =
(pccard_tuple_read_1(&tuple,
@@ -904,6 +935,10 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg)
if (intface) {
reg = pccard_tuple_read_1(tuple, idx);
idx++;
+ cfe->flags &= ~(PCCARD_CFE_MWAIT_REQUIRED
+ | PCCARD_CFE_RDYBSY_ACTIVE
+ | PCCARD_CFE_WP_ACTIVE
+ | PCCARD_CFE_BVD_ACTIVE);
if (reg & PCCARD_TPCE_IF_MWAIT)
cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
if (reg & PCCARD_TPCE_IF_RDYBSY)
@@ -971,7 +1006,8 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg)
reg = pccard_tuple_read_1(tuple, idx);
idx++;
-
+ cfe->flags &=
+ ~(PCCARD_CFE_IO8 | PCCARD_CFE_IO16);
if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
cfe->flags |= PCCARD_CFE_IO8;
if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
@@ -1048,7 +1084,9 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg)
reg = pccard_tuple_read_1(tuple, idx);
idx++;
-
+ cfe->flags &= ~(PCCARD_CFE_IRQSHARE
+ | PCCARD_CFE_IRQPULSE
+ | PCCARD_CFE_IRQLEVEL);
if (reg & PCCARD_TPCE_IR_SHARE)
cfe->flags |= PCCARD_CFE_IRQSHARE;
if (reg & PCCARD_TPCE_IR_PULSE)
@@ -1170,13 +1208,15 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg)
reg = pccard_tuple_read_1(tuple, idx);
idx++;
-
+ cfe->flags &= ~(PCCARD_CFE_POWERDOWN
+ | PCCARD_CFE_READONLY
+ | PCCARD_CFE_AUDIO);
if (reg & PCCARD_TPCE_MI_PWRDOWN)
- cfe->flags = PCCARD_CFE_POWERDOWN;
+ cfe->flags |= PCCARD_CFE_POWERDOWN;
if (reg & PCCARD_TPCE_MI_READONLY)
- cfe->flags = PCCARD_CFE_READONLY;
+ cfe->flags |= PCCARD_CFE_READONLY;
if (reg & PCCARD_TPCE_MI_AUDIO)
- cfe->flags = PCCARD_CFE_AUDIO;
+ cfe->flags |= PCCARD_CFE_AUDIO;
cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
while (reg & PCCARD_TPCE_MI_EXT) {
OpenPOWER on IntegriCloud