Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pcmcia Fix multi-function card memory problems:
details: https://anonhg.NetBSD.org/src/rev/01a8396f6e42
branches: trunk
changeset: 535338:01a8396f6e42
user: christos <christos%NetBSD.org@localhost>
date: Thu Aug 15 10:37:02 2002 +0000
description:
Fix multi-function card memory problems:
- centralize pcmcia function allocation and free'ing.
- free the cfe too, not just the pf in the multifunction card case.
- don't free pointers while walking the list, because free() will
fill the memory with deadbeef, thus killing list walking.
diffstat:
sys/dev/pcmcia/pcmcia_cis.c | 83 +++++++++++++++++++++++--------------
sys/dev/pcmcia/pcmcia_cis_quirks.c | 16 +-----
sys/dev/pcmcia/pcmciavar.h | 8 ++-
3 files changed, 60 insertions(+), 47 deletions(-)
diffs (208 lines):
diff -r 656a8b46b05b -r 01a8396f6e42 sys/dev/pcmcia/pcmcia_cis.c
--- a/sys/dev/pcmcia/pcmcia_cis.c Thu Aug 15 09:32:50 2002 +0000
+++ b/sys/dev/pcmcia/pcmcia_cis.c Thu Aug 15 10:37:02 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pcmcia_cis.c,v 1.30 2002/06/01 23:51:02 lukem Exp $ */
+/* $NetBSD: pcmcia_cis.c,v 1.31 2002/08/15 10:37:02 christos Exp $ */
/*
* Copyright (c) 1997 Marc Horowitz. All rights reserved.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pcmcia_cis.c,v 1.30 2002/06/01 23:51:02 lukem Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pcmcia_cis.c,v 1.31 2002/08/15 10:37:02 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -61,8 +61,45 @@
int pcmcia_parse_cis_tuple __P((struct pcmcia_tuple *, void *));
static int decode_funce __P((struct pcmcia_tuple *, struct pcmcia_function *));
+static void create_pf __P((struct cis_state *));
+static void
+create_pf(struct cis_state *state)
+{
+ state->pf = malloc(sizeof(*state->pf), M_DEVBUF, M_NOWAIT|M_ZERO);
+ state->pf->number = state->count++;
+ state->pf->last_config_index = -1;
+ SIMPLEQ_INIT(&state->pf->cfe_head);
+ SIMPLEQ_INSERT_TAIL(&state->card->pf_head, state->pf, pf_list);
+}
+
+void
+pcmcia_free_pf(struct pcmcia_function_head *pfhead)
+{
+ struct pcmcia_function *pf, *opf = NULL;
+ struct pcmcia_config_entry *cfe, *ocfe = NULL;
+
+ SIMPLEQ_FOREACH(pf, pfhead, pf_list) {
+ SIMPLEQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
+ if (ocfe)
+ free(ocfe, M_DEVBUF);
+ ocfe = cfe;
+ }
+ if (ocfe) {
+ free(ocfe, M_DEVBUF);
+ ocfe = NULL;
+ }
+ if (opf)
+ free(opf, M_DEVBUF);
+ opf = pf;
+ }
+ if (opf)
+ free(opf, M_DEVBUF);
+
+ SIMPLEQ_INIT(pfhead);
+}
+
void
pcmcia_read_cis(sc)
struct pcmcia_softc *sc;
@@ -690,17 +727,11 @@
* rather not change it.
*/
if (state->gotmfc == 1) {
- struct pcmcia_function *pf;
-
- SIMPLEQ_FOREACH(pf, &state->card->pf_head, pf_list) {
- free(pf, M_DEVBUF);
- }
+ state->gotmfc = 2;
+ state->count = 0;
+ state->pf = NULL;
- SIMPLEQ_INIT(&state->card->pf_head);
-
- state->count = 0;
- state->gotmfc = 2;
- state->pf = NULL;
+ pcmcia_free_pf(&state->card->pf_head);
}
break;
case PCMCIA_CISTPL_LONGLINK_MFC:
@@ -710,7 +741,11 @@
* functions declared before the MFC link can be cleaned
* up.
*/
- state->gotmfc = 1;
+ if (state->gotmfc == 0) {
+ state->gotmfc = 1;
+ } else {
+ DPRINTF(("got LONGLINK_MFC again!"));
+ }
break;
#ifdef PCMCIACISDEBUG
case PCMCIA_CISTPL_DEVICE:
@@ -849,16 +884,8 @@
state->pf = NULL;
}
}
- if (state->pf == NULL) {
- state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
- M_NOWAIT|M_ZERO);
- state->pf->number = state->count++;
- state->pf->last_config_index = -1;
- SIMPLEQ_INIT(&state->pf->cfe_head);
-
- SIMPLEQ_INSERT_TAIL(&state->card->pf_head, state->pf,
- pf_list);
- }
+ if (state->pf == NULL)
+ create_pf(state);
state->pf->function = pcmcia_tuple_read_1(tuple, 0);
DPRINTF(("CISTPL_FUNCID\n"));
@@ -897,15 +924,7 @@
break;
}
if (state->pf == NULL) {
- state->pf = malloc(sizeof(*state->pf),
- M_DEVBUF, M_NOWAIT|M_ZERO);
- state->pf->number = state->count++;
- state->pf->last_config_index = -1;
- SIMPLEQ_INIT(&state->pf->cfe_head);
-
- SIMPLEQ_INSERT_TAIL(&state->card->pf_head,
- state->pf, pf_list);
-
+ create_pf(state);
state->pf->function = PCMCIA_FUNCTION_UNSPEC;
}
state->pf->last_config_index =
diff -r 656a8b46b05b -r 01a8396f6e42 sys/dev/pcmcia/pcmcia_cis_quirks.c
--- a/sys/dev/pcmcia/pcmcia_cis_quirks.c Thu Aug 15 09:32:50 2002 +0000
+++ b/sys/dev/pcmcia/pcmcia_cis_quirks.c Thu Aug 15 10:37:02 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pcmcia_cis_quirks.c,v 1.19 2002/06/01 23:51:02 lukem Exp $ */
+/* $NetBSD: pcmcia_cis_quirks.c,v 1.20 2002/08/15 10:37:02 christos Exp $ */
/*
* Copyright (c) 1998 Marc Horowitz. All rights reserved.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pcmcia_cis_quirks.c,v 1.19 2002/06/01 23:51:02 lukem Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pcmcia_cis_quirks.c,v 1.20 2002/08/15 10:37:02 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -284,17 +284,7 @@
}
printf("\n");
}
-
- SIMPLEQ_FOREACH(pf, &sc->card.pf_head,
- pf_list) {
- SIMPLEQ_FOREACH(cfe, &pf->cfe_head,
- cfe_list) {
- free(cfe, M_DEVBUF);
- }
- free(pf, M_DEVBUF);
- }
-
- SIMPLEQ_INIT(&sc->card.pf_head);
+ pcmcia_free_pf(&sc->card.pf_head);
wiped = 1;
}
diff -r 656a8b46b05b -r 01a8396f6e42 sys/dev/pcmcia/pcmciavar.h
--- a/sys/dev/pcmcia/pcmciavar.h Thu Aug 15 09:32:50 2002 +0000
+++ b/sys/dev/pcmcia/pcmciavar.h Thu Aug 15 10:37:02 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pcmciavar.h,v 1.16 2002/06/01 23:51:02 lukem Exp $ */
+/* $NetBSD: pcmciavar.h,v 1.17 2002/08/15 10:37:02 christos Exp $ */
/*
* Copyright (c) 1997 Marc Horowitz. All rights reserved.
@@ -155,6 +155,8 @@
/* pf_flags */
#define PFF_ENABLED 0x0001 /* function is enabled */
+SIMPLEQ_HEAD(pcmcia_function_head, pcmcia_function);
+
struct pcmcia_card {
int cis1_major;
int cis1_minor;
@@ -172,7 +174,7 @@
#define PCMCIA_PRODUCT_INVALID -1
u_int16_t error;
#define PCMCIA_CIS_INVALID { NULL, NULL, NULL, NULL }
- SIMPLEQ_HEAD(, pcmcia_function) pf_head;
+ struct pcmcia_function_head pf_head;
};
struct pcmcia_softc {
@@ -297,6 +299,8 @@
bus_size_t, struct pcmcia_io_handle *, int *));
void pcmcia_io_unmap __P((struct pcmcia_function *, int));
+void pcmcia_free_pf __P((struct pcmcia_function_head *));
+
#define pcmcia_mem_alloc(pf, size, pcmhp) \
(pcmcia_chip_mem_alloc((pf)->sc->pct, (pf)->sc->pch, (size), (pcmhp)))
Home |
Main Index |
Thread Index |
Old Index