From nobody  Tue Apr  7 22:22:58 1998
Received: (from nobody@localhost)
          by hub.freebsd.org (8.8.8/8.8.8) id WAA20255;
          Tue, 7 Apr 1998 22:22:58 -0700 (PDT)
          (envelope-from nobody)
Message-Id: <199804080522.WAA20255@hub.freebsd.org>
Date: Tue, 7 Apr 1998 22:22:58 -0700 (PDT)
From: mac@st.rim.or.jp
To: freebsd-gnats-submit@freebsd.org
Subject: in PCCARD, alocate driver failed, not release IRQ
X-Send-Pr-Version: www-1.0

>Number:         6249
>Category:       kern
>Synopsis:       in PCCARD, alocate driver failed, not release IRQ
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    nate
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Apr  7 22:30:00 PDT 1998
>Closed-Date:    Tue Apr 14 16:26:48 PDT 1998
>Last-Modified:  Tue Apr 14 16:28:03 PDT 1998
>Originator:     Masahide NODA
>Release:        2.2.6-RELEASE
>Organization:
Fujitsu Lab.
>Environment:
FreeBSD gnome.pssys.flab.fujitsu.co.jp 2.2.6-RELEASE FreeBSD 2.2.6-RELEASE #7: W
ed Apr  8 13:17:25 JST 1998     mac@gnome.pssys.flab.fujitsu.co.jp:/usr/home/mac
/sys/compile/gnome  i386
>Description:
(Sorry, previous send-pr attached patch has problem. Please replace this send-pr)

When PC card insert, not release IRQ if alocate_driver() fail.
In 2.2.5-RELEASE, if remove_driver() fail, call remove_driver() and
it is unregister_intr() whether devi->running is 0 or not.
But 2.2.6-RELEASE, unregister_intr() is not called devi->running is 0.

Forwhy, In 2.2.5-RELEASE, diable_slot() and remove_driver() function's 
behavior of unregister IRQ are not same, but, In 2.2.6-RELASE, these are same.

>How-To-Repeat:
Inser disable device PC card, remove it.
display console messages,
        /kernel: Slot 1, unfielded interrupt (10)
>Fix:
can use this patch
----------------------------------------------------------------
*** pccard.c.orig       Sat Nov 15 23:11:27 1997
--- pccard.c    Wed Apr  8 13:58:59 1998
***************
*** 80,86 ****

  static int            allocate_driver(struct slot *, struct dev_desc *);
  static void           inserted(void *);
! static void           unregister_device_interrupt(struct pccard_devinfo *);
  static void           disable_slot(struct slot *);
  static int            invalid_io_memory(unsigned long, int);
  static struct pccard_device *find_driver(char *);
--- 80,86 ----

  static int            allocate_driver(struct slot *, struct dev_desc *);
  static void           inserted(void *);
! static void           unregister_device_interrupt(struct pccard_devinfo *, int
 force);
  static void           disable_slot(struct slot *);
  static int            invalid_io_memory(unsigned long, int);
  static struct pccard_device *find_driver(char *);
***************
*** 296,310 ****
   *    the device driver which is handling it, so we can remove it.
   */
  static void
! unregister_device_interrupt(struct pccard_devinfo *devi)
  {
        struct slot *slt = devi->slt;
        int s;

!       if (devi->running) {
                s = splhigh();
!               devi->drv->disable(devi);
!               devi->running = 0;
                if (devi->isahd.id_irq && --slt->irqref <= 0) {
                        printf("Return IRQ=%d\n",slt->irq);
                        slt->ctrl->mapirq(slt, 0);
--- 296,312 ----
   *    the device driver which is handling it, so we can remove it.
   */
  static void
! unregister_device_interrupt(struct pccard_devinfo *devi,int force)
  {
        struct slot *slt = devi->slt;
        int s;

!       if ((devi->running) || (force == 1)) {
                s = splhigh();
!               if (devi->running) {
!                       devi->drv->disable(devi);
!                       devi->running = 0;
!               }
                if (devi->isahd.id_irq && --slt->irqref <= 0) {
                        printf("Return IRQ=%d\n",slt->irq);
                        slt->ctrl->mapirq(slt, 0);
***************
*** 342,348 ****
         * all bets are off...
         */
        for (devi = slt->devices; devi; devi = devi->next)
!               unregister_device_interrupt(devi);

        /* Power off the slot 1/2 second after removal of the card */
        timeout(power_off_slot, (caddr_t)slt, hz / 2);
--- 344,350 ----
         * all bets are off...
         */
        for (devi = slt->devices; devi; devi = devi->next)
!               unregister_device_interrupt(devi, 1);

        /* Power off the slot 1/2 second after removal of the card */
        timeout(power_off_slot, (caddr_t)slt, hz / 2);
***************
*** 606,612 ****
         *      If an interrupt is enabled on this slot,
         *      then unregister it if no-one else is using it.
         */
!       unregister_device_interrupt(devi);
        /*
         *      Remove from device list on this slot.
         */
--- 608,614 ----
         *      If an interrupt is enabled on this slot,
         *      then unregister it if no-one else is using it.
         */
!       unregister_device_interrupt(devi, 0);
        /*
         *      Remove from device list on this slot.
         */

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->analyzed 
State-Changed-By: nate 
State-Changed-When: Wed Apr 8 07:29:11 PDT 1998 
State-Changed-Why:  
This is indeed a problem, but the way we do probes needs to be redone, so let 
me see if I can fix the original problem.  If not, I'll apply the patch. 


Responsible-Changed-From-To: freebsd-bugs->nate 
Responsible-Changed-By: nate 
Responsible-Changed-When: Wed Apr 8 07:29:11 PDT 1998 
Responsible-Changed-Why:  
My code, my bug. 

From: Nate Williams <nate@mt.sri.com>
To: mac@st.rim.or.jp
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: kern/6249: in PCCARD, alocate driver failed, not release IRQ
Date: Wed, 8 Apr 1998 09:06:33 -0600

 > >Number:         6249
 > >Category:       kern
 > >Synopsis:       in PCCARD, alocate driver failed, not release IRQ
 > >Confidential:   no
 > >Severity:       critical
 > >Priority:       high
 > >Responsible:    freebsd-bugs
 > >State:          open
 > >Quarter:
 > >Keywords:
 > >Date-Required:
 > >Class:          sw-bug
 > >Submitter-Id:   current-users
 > >Arrival-Date:   Tue Apr  7 22:30:00 PDT 1998
 > >Last-Modified:
 > >Originator:     Masahide NODA
 > >Organization:
 > Fujitsu Lab.
 > >Release:        2.2.6-RELEASE
 > >Environment:
 > FreeBSD gnome.pssys.flab.fujitsu.co.jp 2.2.6-RELEASE FreeBSD 2.2.6-RELEASE #7: W
 > ed Apr  8 13:17:25 JST 1998     mac@gnome.pssys.flab.fujitsu.co.jp:/usr/home/mac
 > /sys/compile/gnome  i386
 > >Description:
 > When PC card insert, not release IRQ if alocate_driver() fail.
 
 Ok, can you try out the fix I just committed to both -current and
 -stable.  This isn't the 'correct' fix for the probes, but should fix
 the bug that you reported.  'running' is a flag that says that the
 device is completely 'running', but is also mis-used as a flag to say
 that interrupts have been allocated (if necessary), so I simply stated
 that the driver was running after interrupts were allocated, and it will
 do the right thing to disable running if the probe fails.
 
 Thanks!
 
 
 Nate
State-Changed-From-To: analyzed->closed 
State-Changed-By: jmb 
State-Changed-When: Tue Apr 14 16:26:48 PDT 1998 
State-Changed-Why:  
fixed by Nate Williams in revision 1.57 to /sys/pccard.c 
>Unformatted:
