Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Apr 2011 16:59:57 +0000 (UTC)
From:      Bernhard Schmidt <bschmidt@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r220661 - head/sys/dev/iwn
Message-ID:  <201104151659.p3FGxvOY076029@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bschmidt
Date: Fri Apr 15 16:59:56 2011
New Revision: 220661
URL: http://svn.freebsd.org/changeset/base/220661

Log:
  Fixes for firmware handling:
  - there is a local variable for sc->fw_dma, use that instead
  - OpenBSD uses 5*hz to wait for firmware to be loaded
  - in case the firmware module contains invalid data, actually release it

Modified:
  head/sys/dev/iwn/if_iwn.c

Modified: head/sys/dev/iwn/if_iwn.c
==============================================================================
--- head/sys/dev/iwn/if_iwn.c	Fri Apr 15 16:55:45 2011	(r220660)
+++ head/sys/dev/iwn/if_iwn.c	Fri Apr 15 16:59:56 2011	(r220661)
@@ -5629,10 +5629,10 @@ iwn4965_load_firmware(struct iwn_softc *
 
 	/* Copy initialization sections into pre-allocated DMA-safe memory. */
 	memcpy(dma->vaddr, fw->init.data, fw->init.datasz);
-	bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
 	memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ,
 	    fw->init.text, fw->init.textsz);
-	bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
 
 	/* Tell adapter where to find initialization sections. */
 	error = iwn_nic_lock(sc);
@@ -5670,10 +5670,10 @@ iwn4965_load_firmware(struct iwn_softc *
 
 	/* Copy runtime sections into pre-allocated DMA-safe memory. */
 	memcpy(dma->vaddr, fw->main.data, fw->main.datasz);
-	bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
 	memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ,
 	    fw->main.text, fw->main.textsz);
-	bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
 
 	/* Tell adapter where to find runtime sections. */
 	error = iwn_nic_lock(sc);
@@ -5700,7 +5700,7 @@ iwn5000_load_firmware_section(struct iwn
 
 	/* Copy firmware section into pre-allocated DMA-safe memory. */
 	memcpy(dma->vaddr, section, size);
-	bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
 
 	error = iwn_nic_lock(sc);
 	if (error != 0)
@@ -5726,7 +5726,7 @@ iwn5000_load_firmware_section(struct iwn
 	iwn_nic_unlock(sc);
 
 	/* Wait at most five seconds for FH DMA transfer to complete. */
-	return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
+	return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", 5 * hz);
 }
 
 static int
@@ -5771,7 +5771,7 @@ iwn_read_firmware_leg(struct iwn_softc *
 	size_t hdrlen = 24;
 	uint32_t rev;
 
-	ptr = (const uint32_t *)sc->fw_fp->data;
+	ptr = (const uint32_t *)fw->data;
 	rev = le32toh(*ptr++);
 
 	/* Check firmware API version. */
@@ -5819,7 +5819,7 @@ iwn_read_firmware_leg(struct iwn_softc *
 /*
  * Extract text and data sections from a TLV firmware image.
  */
-int
+static int
 iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw,
     uint16_t alt)
 {
@@ -5931,6 +5931,8 @@ iwn_read_firmware(struct iwn_softc *sc)
 		device_printf(sc->sc_dev,
 		    "%s: firmware file too short: %zu bytes\n",
 		    __func__, fw->size);
+		firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
+		sc->fw_fp = NULL;
 		return EINVAL;
 	}
 
@@ -5942,6 +5944,8 @@ iwn_read_firmware(struct iwn_softc *sc)
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: could not read firmware sections\n", __func__);
+		firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
+		sc->fw_fp = NULL;
 		return error;
 	}
 
@@ -5954,6 +5958,8 @@ iwn_read_firmware(struct iwn_softc *sc)
 	    (fw->boot.textsz & 3) != 0) {
 		device_printf(sc->sc_dev,
 		    "%s: firmware sections too large\n", __func__);
+		firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
+		sc->fw_fp = NULL;
 		return EINVAL;
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104151659.p3FGxvOY076029>