Module Name: src Committed By: christos Date: Fri Apr 23 20:56:20 UTC 2010
Modified Files: src/sys/dev/pci: if_iwn.c if_iwnvar.h Log Message: Align usage of *free and *alloc and clean up the firmware read code. This fixes two panics that occur for kernels compiled with DIAGNOSTIC and DEBUG. From Sverre Froyen To generate a diff of this commit: cvs rdiff -u -r1.41 -r1.42 src/sys/dev/pci/if_iwn.c cvs rdiff -u -r1.9 -r1.10 src/sys/dev/pci/if_iwnvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/if_iwn.c diff -u src/sys/dev/pci/if_iwn.c:1.41 src/sys/dev/pci/if_iwn.c:1.42 --- src/sys/dev/pci/if_iwn.c:1.41 Sat Apr 17 11:57:22 2010 +++ src/sys/dev/pci/if_iwn.c Fri Apr 23 16:56:20 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: if_iwn.c,v 1.41 2010/04/17 15:57:22 christos Exp $ */ +/* $NetBSD: if_iwn.c,v 1.42 2010/04/23 20:56:20 christos Exp $ */ /* $OpenBSD: if_iwn.c,v 1.88 2010/04/10 08:37:36 damien Exp $ */ /*- @@ -22,7 +22,7 @@ * adapters. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.41 2010/04/17 15:57:22 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.42 2010/04/23 20:56:20 christos Exp $"); #define IWN_USE_RBUF /* Use local storage for RX */ #undef IWN_HWCRYPTO /* XXX does not even compile yet */ @@ -1764,7 +1764,7 @@ static struct ieee80211_node * iwn_node_alloc(struct ieee80211_node_table *ic __unused) { - return malloc(sizeof (struct iwn_node), M_DEVBUF, M_NOWAIT | M_ZERO); + return malloc(sizeof (struct iwn_node), M_80211_NODE, M_NOWAIT | M_ZERO); } static void @@ -5577,6 +5577,10 @@ size_t size; int error; + /* Initialize for error returns */ + fw->data = NULL; + fw->datasz = 0; + /* Open firmware image. */ if ((error = firmware_open("if_iwn", sc->fwname, &fwh)) != 0) { aprint_error_dev(sc->sc_dev, @@ -5587,7 +5591,6 @@ if (size < 28) { aprint_error_dev(sc->sc_dev, "truncated firmware header: %zu bytes\n", size); - free(fw->data, M_DEVBUF); firmware_close(fwh); return EINVAL; } @@ -5600,12 +5603,13 @@ firmware_close(fwh); return ENOMEM; } - if ((error = firmware_read(fwh, 0, fw->data, size)) != 0) { + error = firmware_read(fwh, 0, fw->data, size); + firmware_close(fwh); + fw->datasz = size; + if (error != 0) { aprint_error_dev(sc->sc_dev, "could not read firmware %s\n", sc->fwname); - firmware_free(fw->data, size); - firmware_close(fwh); - return error; + goto out; } /* Process firmware header. */ @@ -5615,9 +5619,8 @@ if (IWN_FW_API(rev) <= 1) { aprint_error_dev(sc->sc_dev, "bad firmware, need API version >=2\n"); - firmware_free(fw->data, size); - firmware_close(fwh); - return EINVAL; + firmware_free(fw->data, fw->datasz); + goto out; } if (IWN_FW_API(rev) >= 3) { /* Skip build number (version 2 header). */ @@ -5640,9 +5643,7 @@ (fw->boot.textsz & 3) != 0) { aprint_error_dev(sc->sc_dev, "invalid firmware header\n"); - firmware_free(fw->data, size); - firmware_close(fwh); - return EINVAL; + goto out; } /* Check that all firmware sections fit. */ @@ -5650,9 +5651,7 @@ fw->init.datasz + fw->boot.textsz > size) { aprint_error_dev(sc->sc_dev, "firmware file too short: %zu bytes\n", size); - firmware_free(fw->data, size); - firmware_close(fwh); - return EINVAL; + goto out; } /* Get pointers to firmware sections. */ @@ -5663,6 +5662,11 @@ fw->boot.text = fw->init.data + fw->init.datasz; return 0; +out: + firmware_free(fw->data, fw->datasz); + fw->data = NULL; + fw->datasz = 0; + return error ? error : EINVAL; } static int @@ -6054,8 +6058,11 @@ sc->sc_flags &= ~IWN_FLAG_USE_ICT; /* Initialize hardware and upload firmware. */ + KASSERT(sc->fw.data != NULL && sc->fw.datasz > 0); error = iwn_hw_init(sc); - free(sc->fw.data, M_DEVBUF); + firmware_free(sc->fw.data, sc->fw.datasz); + sc->fw.data = NULL; + sc->fw.datasz = 0; if (error != 0) { aprint_error_dev(sc->sc_dev, "could not initialize hardware\n"); Index: src/sys/dev/pci/if_iwnvar.h diff -u src/sys/dev/pci/if_iwnvar.h:1.9 src/sys/dev/pci/if_iwnvar.h:1.10 --- src/sys/dev/pci/if_iwnvar.h:1.9 Thu Apr 15 21:40:41 2010 +++ src/sys/dev/pci/if_iwnvar.h Fri Apr 23 16:56:20 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: if_iwnvar.h,v 1.9 2010/04/16 01:40:41 christos Exp $ */ +/* $NetBSD: if_iwnvar.h,v 1.10 2010/04/23 20:56:20 christos Exp $ */ /* $OpenBSD: if_iwnvar.h,v 1.17 2010/02/17 18:23:00 damien Exp $ */ /*- @@ -168,6 +168,7 @@ struct iwn_fw_info { u_char *data; + uint32_t datasz; struct iwn_fw_part init; struct iwn_fw_part main; struct iwn_fw_part boot;