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;