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