matsuda-san,
        thanks for the very good and complete bug report.  This
information is quite helpful to me.  Many have complained about this
problem, but your message is the first to provide enough detail for me
to guess at the cause.

In message <[EMAIL PROTECTED]> Munehiro Matsuda writes:
: ad0: 14403MB <HITACHI_DK23BA-15> [29264/16/63] at ata0-master UDMA33
: pccard: card inserted, slot 0
: pcic0: debounced state is 0x30000419
: pccard: card inserted, slot 0
: pcic0: Event mask 0x9

Thank you for the dmesg.  I have a theory about what is going on, but
need your help to test a patch since I cannot reproduce the problem
here.

My theory is that we schedule an insertion event in the pcic_attach
routine.  Later, when interrupts are enabled, we effectively schedule
it again.  This leads to your panic.  Likely we should put some sanity
checking in the card insertion engine.  At least more than the
attached patch has.  The attached patch attempts to compensate for
these issues.  It also attemts to weed out more classes of cards that
don't make sense in our system (YV cards, XV cards and Cardbus cards,
to name a few).  Please test it and let me know if it works for you.

For this exact problem, only the chanage to pcic.c should be
necessary.

Warner

Index: pcic.c
===================================================================
RCS file: /home/imp/FreeBSD/CVS/src/sys/pccard/pcic.c,v
retrieving revision 1.143
diff -u -r1.143 pcic.c
--- pcic.c      2001/06/16 06:33:01     1.143
+++ pcic.c      2001/06/19 05:19:15
@@ -308,6 +308,7 @@
        struct slot     *slt;
        struct pcic_slot *sp;
        int             stat;
+       u_int32_t       event;
        
        sc = (struct pcic_softc *) device_get_softc(dev);
        callout_handle_init(&sc->timeout_ch);
@@ -340,6 +341,15 @@
 
                pcic_do_mgt_irq(sp, sc->irq);
                sp->slt->irq = sc->irq;
+
+               /* Ack any pending pci interrupts */
+               if (sp->sc->csc_route == pci_parallel) {
+                       event = bus_space_read_4(sp->bst, sp->bsh,
+                           CB_SOCKET_EVENT);
+                       if (event)
+                               bus_space_write_4(sp->bst, sp->bsh,
+                                   CB_SOCKET_EVENT, event);
+               }
 
                /* Check for changes */
                pcic_setb(sp, PCIC_POWER, PCIC_PCPWRE | PCIC_DISRST);
Index: pcic_pci.c
===================================================================
RCS file: /home/imp/FreeBSD/CVS/src/sys/pccard/pcic_pci.c,v
retrieving revision 1.50
diff -u -r1.50 pcic_pci.c
--- pcic_pci.c  2001/06/16 23:26:18     1.50
+++ pcic_pci.c  2001/06/19 05:21:22
@@ -312,15 +312,29 @@
        
        stat = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_STATE);
        device_printf(sc->dev, "debounced state is 0x%x\n", stat);
-       if ((stat & CB_SS_16BIT) == 0) {
+       if (stat & CB_SS_XVCARD) {
+               if (bootverbose)
+                       device_printf(sp->sc->dev,
+                           "X volt cards indicate unpopulated socket!");
+               sc->cd_pending = 0;
+               return;
+       }
+       if (stat & CB_SS_YVCARD) {
+               if (bootverbose)
+                       device_printf(sp->sc->dev,
+                           "Y volt cards indicate unpopulated socket!");
+               sc->cd_pending = 0;
+               return;
+       }
+       if ((stat & CB_SS_16BIT) == 0 && (stat & CB_SS_CD) == 0) {
                device_printf(sp->sc->dev, "Unsupported card type inserted\n");
-       } else {
-               if (stat & CB_SS_CD)
-                       pccard_event(sp->slt, card_removed);
-               else
-                       pccard_event(sp->slt, card_inserted);
+               sc->cd_pending = 0;
+               return;
        }
-       sc->cd_pending = 0;
+       if ((stat & CB_SS_CD) != 0)             /* CDn# signals active low */
+               pccard_event(sp->slt, card_removed);
+       else
+               pccard_event(sp->slt, card_inserted);
 }
 
 static void
@@ -335,13 +349,14 @@
                return;
        device_printf(sc->dev, "Event mask 0x%x\n", event);
        if (event & CB_SE_CD) {
+               /* Debounce insertion/removal events */
                if (!sc->cd_pending) {
                        sc->cd_pending = 1;
                        timeout(pcic_cd_event, arg, hz/2);
                }
        }
-       /* Ack the interrupt, all of them to be safe */
-       bus_space_write_4(sp->bst, sp->bsh, 0, 0xffffffff);
+       /* Ack the interrupt */
+       bus_space_write_4(sp->bst, sp->bsh, CB_SOCKET_EVENT, event);
 }
 
 /*

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to