Return-Path: Received: from localhost (bix [127.0.0.1]) by localhost.localdomain (8.12.10/8.12.10) with ESMTP id iANNGbdk007774 for ; Tue, 23 Nov 2004 15:16:38 -0800 Received: from bix [127.0.0.1] by localhost with POP3 (fetchmail-6.2.0) for akpm@localhost (single-drop); Tue, 23 Nov 2004 15:16:38 -0800 (PST) Received: from fire-1.osdl.org (fire.osdl.org [65.172.181.4]) by mail.osdl.org (8.11.6/8.11.6) with ESMTP id iANNE4925426; Tue, 23 Nov 2004 15:14:04 -0800 Received: from Cantor.suse.de (mail-ex.suse.de [195.135.220.2]) by fire-1.osdl.org (8.12.8/8.12.8) with ESMTP id iANNE1PE022724 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=FAIL); Tue, 23 Nov 2004 15:14:03 -0800 Received: from hermes.suse.de (hermes-ext.suse.de [195.135.221.8]) (using TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (No client certificate requested) by Cantor.suse.de (Postfix) with ESMTP id 0824B115DB18; Wed, 24 Nov 2004 00:14:00 +0100 (CET) Date: Wed, 24 Nov 2004 00:13:55 +0100 From: Karsten Keil To: linux-kernel@vger.kernel.org Cc: Linus Torvalds , Andrew Morton Subject: [PATCH] fix deadlock in CAPI code, reenable SMP Message-ID: <20041123231355.GA16080@pingi3.kke.suse.de> Mail-Followup-To: linux-kernel@vger.kernel.org, Linus Torvalds , Andrew Morton Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Organization: SuSE Linux AG X-Operating-System: Linux 2.6.5-7.108-default i686 User-Agent: Mutt/1.5.6i Received-SPF: none (domain of kkeil@suse.de does not designate permitted sender hosts) X-MIMEDefang-Filter: osdl$Revision: 1.95 $ X-Scanned-By: MIMEDefang 2.36 X-Spam-Checker-Version: SpamAssassin 2.60 (1.212-2003-09-23-exp) on bix X-Spam-Status: No, hits=-4.9 required=1.0 tests=BAYES_00 autolearn=ham version=2.60 X-Spam-Level: Hi, this patch fix a deadlock in CAPI device driver registration code and reenable SMP for the activ AVM cards., also some minor cleanup and fixes. Signed-off-by: Karsten Keil diff -ur linux-2.6.10-rc2-bk7.org/drivers/isdn/capi/capidrv.c linux-2.6.10-rc2-bk7/drivers/isdn/capi/capidrv.c --- linux-2.6.10-rc2-bk7.org/drivers/isdn/capi/capidrv.c 2004-11-23 15:56:47.048749784 +0100 +++ linux-2.6.10-rc2-bk7/drivers/isdn/capi/capidrv.c 2004-11-23 16:44:31.767040277 +0100 @@ -2058,6 +2058,10 @@ return -1; } card->myid = card->interface.channels; + memset(card->bchans, 0, sizeof(capidrv_bchan) * card->nbchan); + for (i = 0; i < card->nbchan; i++) { + card->bchans[i].contr = card; + } spin_lock_irqsave(&global_lock, flags); card->next = global.contr_list; @@ -2065,11 +2069,6 @@ global.ncontr++; spin_unlock_irqrestore(&global_lock, flags); - memset(card->bchans, 0, sizeof(capidrv_bchan) * card->nbchan); - for (i = 0; i < card->nbchan; i++) { - card->bchans[i].contr = card; - } - cmd.command = ISDN_STAT_RUN; cmd.driver = card->myid; card->interface.statcallb(&cmd); @@ -2077,10 +2076,9 @@ card->cipmask = 0x1FFF03FF; /* any */ card->cipmask2 = 0; - send_listen(card); - card->listentimer.data = (unsigned long)card; card->listentimer.function = listentimerfunc; + send_listen(card); mod_timer(&card->listentimer, jiffies + 60*HZ); printk(KERN_INFO "%s: now up (%d B channels)\n", diff -ur linux-2.6.10-rc2-bk7.org/drivers/isdn/capi/kcapi.c linux-2.6.10-rc2-bk7/drivers/isdn/capi/kcapi.c --- linux-2.6.10-rc2-bk7.org/drivers/isdn/capi/kcapi.c 2004-11-23 15:56:47.051749385 +0100 +++ linux-2.6.10-rc2-bk7/drivers/isdn/capi/kcapi.c 2004-11-23 16:44:31.781038431 +0100 @@ -150,7 +150,10 @@ { card = capi_ctr_get(card); - card->register_appl(card, applid, rparam); + if (card) + card->register_appl(card, applid, rparam); + else + printk(KERN_WARNING "%s: cannot get card resources\n", __FUNCTION__); } @@ -173,10 +176,15 @@ if (showcapimsgs & 1) { printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr); } - + if (!card) { + printk(KERN_WARNING "%s: invalid contr %d\n", __FUNCTION__, contr); + return; + } for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { ap = get_capi_appl_by_nr(applid); - if (ap && ap->callback && !ap->release_in_progress) + if (!ap || ap->release_in_progress) continue; + register_appl(card, applid, &ap->rparam); + if (ap->callback && !ap->release_in_progress) ap->callback(KCI_CONTRUP, contr, &card->profile); } } @@ -319,19 +327,8 @@ void capi_ctr_ready(struct capi_ctr * card) { - u16 appl; - struct capi20_appl *ap; - card->cardstate = CARD_RUNNING; - down(&controller_sem); - for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { - ap = get_capi_appl_by_nr(appl); - if (!ap || ap->release_in_progress) continue; - register_appl(card, appl, &ap->rparam); - } - up(&controller_sem); - printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", card->cnr, card->name); diff -ur linux-2.6.10-rc2-bk7.org/drivers/isdn/hardware/avm/c4.c linux-2.6.10-rc2-bk7/drivers/isdn/hardware/avm/c4.c --- linux-2.6.10-rc2-bk7.org/drivers/isdn/hardware/avm/c4.c 2004-11-23 15:53:57.526313625 +0100 +++ linux-2.6.10-rc2-bk7/drivers/isdn/hardware/avm/c4.c 2004-11-23 16:44:31.803035529 +0100 @@ -662,15 +662,16 @@ static irqreturn_t c4_handle_interrupt(avmcard *card) { + unsigned long flags; u32 status; - spin_lock(&card->lock); + spin_lock_irqsave(&card->lock, flags); status = c4inmeml(card->mbase+DOORBELL); if (status & DBELL_RESET_HOST) { u_int i; c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c); - spin_unlock(&card->lock); + spin_unlock_irqrestore(&card->lock, flags); if (card->nlogcontr == 0) return IRQ_HANDLED; printk(KERN_ERR "%s: unexpected reset\n", card->name); @@ -686,7 +687,7 @@ status &= (DBELL_UP_HOST | DBELL_DOWN_HOST); if (!status) { - spin_unlock(&card->lock); + spin_unlock_irqrestore(&card->lock, flags); return IRQ_HANDLED; } c4outmeml(card->mbase+DOORBELL, status); @@ -709,7 +710,7 @@ c4_dispatch_tx(card); } } - spin_unlock(&card->lock); + spin_unlock_irqrestore(&card->lock, flags); return IRQ_HANDLED; } diff -ur linux-2.6.10-rc2-bk7.org/drivers/isdn/hardware/avm/Kconfig linux-2.6.10-rc2-bk7/drivers/isdn/hardware/avm/Kconfig --- linux-2.6.10-rc2-bk7.org/drivers/isdn/hardware/avm/Kconfig 2004-11-23 15:51:59.184033931 +0100 +++ linux-2.6.10-rc2-bk7/drivers/isdn/hardware/avm/Kconfig 2004-11-23 16:46:44.835475108 +0100 @@ -12,13 +12,13 @@ config ISDN_DRV_AVMB1_B1ISA tristate "AVM B1 ISA support" - depends on CAPI_AVM && ISDN_CAPI && ISA && BROKEN_ON_SMP + depends on CAPI_AVM && ISDN_CAPI && ISA help Enable support for the ISA version of the AVM B1 card. config ISDN_DRV_AVMB1_B1PCI tristate "AVM B1 PCI support" - depends on CAPI_AVM && ISDN_CAPI && PCI && BROKEN_ON_SMP + depends on CAPI_AVM && ISDN_CAPI && PCI help Enable support for the PCI version of the AVM B1 card. @@ -30,14 +30,14 @@ config ISDN_DRV_AVMB1_T1ISA tristate "AVM T1/T1-B ISA support" - depends on CAPI_AVM && ISDN_CAPI && ISA && BROKEN_ON_SMP + depends on CAPI_AVM && ISDN_CAPI && ISA help Enable support for the AVM T1 T1B card. Note: This is a PRI card and handle 30 B-channels. config ISDN_DRV_AVMB1_B1PCMCIA tristate "AVM B1/M1/M2 PCMCIA support" - depends on CAPI_AVM && ISDN_CAPI && BROKEN_ON_SMP + depends on CAPI_AVM && ISDN_CAPI help Enable support for the PCMCIA version of the AVM B1 card. @@ -50,14 +50,14 @@ config ISDN_DRV_AVMB1_T1PCI tristate "AVM T1/T1-B PCI support" - depends on CAPI_AVM && ISDN_CAPI && PCI && BROKEN_ON_SMP + depends on CAPI_AVM && ISDN_CAPI && PCI help Enable support for the AVM T1 T1B card. Note: This is a PRI card and handle 30 B-channels. config ISDN_DRV_AVMB1_C4 tristate "AVM C4/C2 support" - depends on CAPI_AVM && ISDN_CAPI && PCI && BROKEN_ON_SMP + depends on CAPI_AVM && ISDN_CAPI && PCI help Enable support for the AVM C4/C2 PCI cards. These cards handle 4/2 BRI ISDN lines (8/4 channels). -- Karsten Keil SuSE Labs ISDN development