From patchwork Fri Sep 10 00:38:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Hutchings X-Patchwork-Id: 167941 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o8A0cVTH020072 for ; Fri, 10 Sep 2010 00:38:31 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753765Ab0IJAia (ORCPT ); Thu, 9 Sep 2010 20:38:30 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:33177 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752285Ab0IJAi3 convert rfc822-to-8bit (ORCPT ); Thu, 9 Sep 2010 20:38:29 -0400 Received: from [192.168.4.185] (helo=localhost) by shadbolt.decadent.org.uk with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1OtrdF-0007se-0D; Fri, 10 Sep 2010 01:38:21 +0100 Received: from ben by localhost with local (Exim 4.72) (envelope-from ) id 1OtrdD-00048r-EH; Fri, 10 Sep 2010 01:38:19 +0100 From: Ben Hutchings To: Greg Kroah-Hartman Cc: Brett Rudley , Henry Ptasinski , Nohee Ko , linux-wireless@vger.kernel.org Date: Fri, 10 Sep 2010 01:38:18 +0100 Message-ID: <1284079098.5323.595.camel@localhost> Mime-Version: 1.0 X-Mailer: Evolution 2.30.3 X-SA-Exim-Connect-IP: 192.168.4.185 X-SA-Exim-Mail-From: ben@decadent.org.uk X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on shadbolt.decadent.org.uk X-Spam-Level: X-Spam-Status: No, score=-1.4 required=5.0 tests=ALL_TRUSTED autolearn=disabled version=3.2.5 Subject: [PATCH] brcm80211: Fix some initialisation failure paths X-SA-Exim-Version: 4.2.1 (built Wed, 25 Jun 2008 17:14:11 +0000) X-SA-Exim-Scanned: Yes (on shadbolt.decadent.org.uk) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Fri, 10 Sep 2010 00:38:32 +0000 (UTC) diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO index aa38d49..5870bca 100644 --- a/drivers/staging/brcm80211/TODO +++ b/drivers/staging/brcm80211/TODO @@ -25,7 +25,6 @@ Bugs - Various occasional asserts/hangs - Scanning during data transfer sometimes causes major slowdowns. Sometimes revcovers when scan is done, other times not. -- Driver does not handle missing firmware gracefully. - Mac80211 API not completely implemented (ie ops_bss_info_changed, ops_get_stats, etc) diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index d73ec44..3e0c450 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -837,6 +837,9 @@ static wl_info_t *wl_attach(uint16 vendor, uint16 device, ulong regs, wl->osh = osh; atomic_set(&wl->callbacks, 0); + /* setup the bottom half handler */ + tasklet_init(&wl->tasklet, wl_dpc, (ulong) wl); + #ifdef WLC_HIGH_ONLY wl->rpc_th = bcm_rpc_tp_attach(osh, NULL); if (wl->rpc_th == NULL) { @@ -905,17 +908,16 @@ static wl_info_t *wl_attach(uint16 vendor, uint16 device, ulong regs, #endif /* common load-time initialization */ - if (! - (wl->wlc = - wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh, - wl->regsva, wl->bcm_bustype, btparam, &err))) { + wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh, + wl->regsva, wl->bcm_bustype, btparam, &err); +#ifndef WLC_HIGH_ONLY + wl_release_fw(wl); +#endif + if (!wl->wlc) { printf("%s: %s driver failed with code %d\n", KBUILD_MODNAME, EPI_VERSION_STR, err); goto fail; } -#ifndef WLC_HIGH_ONLY - wl_release_fw(wl); -#endif wl->pub = wlc_pub(wl->wlc); wl->pub->ieee_hw = hw; @@ -942,9 +944,6 @@ static wl_info_t *wl_attach(uint16 vendor, uint16 device, ulong regs, wlc_iovar_setint(wl->wlc, "sd_drivestrength", sd_drivestrength); #endif - /* setup the bottom half handler */ - tasklet_init(&wl->tasklet, wl_dpc, (ulong) wl); - #ifdef WLC_LOW /* register our interrupt handler */ if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { @@ -1710,11 +1709,9 @@ void wl_free(wl_info_t * wl) ASSERT(wl); #ifndef WLC_HIGH_ONLY - ASSERT(wl->irq); /* bmac does not use direct interrupt */ /* free ucode data */ if (wl->fw.fw_cnt) wl_ucode_data_free(); - ASSERT(wl->wlc); if (wl->irq) free_irq(wl->irq, wl); #endif @@ -2509,6 +2506,7 @@ static int wl_request_fw(wl_info_t * wl, struct pci_dev *pdev) status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); if (status) { printf("fail to request firmware %s\n", fw_name); + wl_release_fw(wl); return status; } WL_NONE(("request fw %s\n", fw_name)); @@ -2517,6 +2515,7 @@ static int wl_request_fw(wl_info_t * wl, struct pci_dev *pdev) status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); if (status) { printf("fail to request firmware %s\n", fw_name); + wl_release_fw(wl); return status; } wl->fw.hdr_num_entries[i] = @@ -2539,7 +2538,7 @@ void wl_ucode_free_buf(void *p) static void wl_release_fw(wl_info_t * wl) { int i; - for (i = 0; i < wl->fw.fw_cnt; i++) { + for (i = 0; i < WL_MAX_FW; i++) { release_firmware(wl->fw.fw_bin[i]); release_firmware(wl->fw.fw_hdr[i]); }