Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 7 Apr 1998 22:22:58 -0700 (PDT)
From:      mac@st.rim.or.jp
To:        freebsd-gnats-submit@FreeBSD.ORG
Subject:   kern/6249: in PCCARD, alocate driver failed, not release IRQ
Message-ID:  <199804080522.WAA20255@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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:
(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.
         */

>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



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