Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev implement probing for available irqs on non-cirrus p...



details:   https://anonhg.NetBSD.org/src/rev/d94437932e73
branches:  trunk
changeset: 481548:d94437932e73
user:      chopps <chopps%NetBSD.org@localhost>
date:      Tue Feb 01 22:39:51 2000 +0000

description:
implement probing for available irqs on non-cirrus pcmcia controllers
        including cardbus controllers running in pcic mode

diffstat:

 sys/dev/ic/i82365.c            |  388 ++++++++++++++++++----------------------
 sys/dev/ic/i82365reg.h         |   13 +-
 sys/dev/ic/i82365var.h         |   38 ++-
 sys/dev/isa/i82365_isa.c       |   38 +---
 sys/dev/isa/i82365_isasubr.c   |  243 ++++++++++++++++++++++++-
 sys/dev/isa/i82365_isavar.h    |    7 +-
 sys/dev/isapnp/i82365_isapnp.c |   31 +--
 sys/dev/pci/i82365_pci.c       |   24 ++-
 8 files changed, 480 insertions(+), 302 deletions(-)

diffs (truncated from 1144 to 300 lines):

diff -r 1e6b4c4712a6 -r d94437932e73 sys/dev/ic/i82365.c
--- a/sys/dev/ic/i82365.c       Tue Feb 01 22:29:27 2000 +0000
+++ b/sys/dev/ic/i82365.c       Tue Feb 01 22:39:51 2000 +0000
@@ -1,8 +1,9 @@
-/*     $NetBSD: i82365.c,v 1.32 2000/01/27 01:05:17 enami Exp $        */
+/*     $NetBSD: i82365.c,v 1.33 2000/02/01 22:39:51 chopps Exp $       */
 
 #define        PCICDEBUG
 
 /*
+ * Copyright (c) 2000 Christian E. Hopps.  All rights reserved.
  * Copyright (c) 1997 Marc Horowitz.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -60,12 +61,6 @@
 #define        DPRINTF(arg)
 #endif
 
-#define        PCIC_VENDOR_UNKNOWN             0
-#define        PCIC_VENDOR_I82365SLR0          1
-#define        PCIC_VENDOR_I82365SLR1          2
-#define        PCIC_VENDOR_CIRRUS_PD6710       3
-#define        PCIC_VENDOR_CIRRUS_PD672X       4
-
 /*
  * Individual drivers will allocate their own memory and io regions. Memory
  * regions must be a multiple of 4k, aligned on a 4k boundary.
@@ -74,11 +69,12 @@
 #define        PCIC_MEM_ALIGN  PCIC_MEM_PAGESIZE
 
 void   pcic_attach_socket __P((struct pcic_handle *));
-void   pcic_init_socket __P((struct pcic_handle *));
+void   pcic_attach_socket_finish __P((struct pcic_handle *));
 
 int    pcic_submatch __P((struct device *, struct cfdata *, void *));
 int    pcic_print  __P((void *arg, const char *pnp));
 int    pcic_intr_socket __P((struct pcic_handle *));
+void   pcic_poll_intr __P((void *));
 
 void   pcic_attach_card __P((struct pcic_handle *));
 void   pcic_detach_card __P((struct pcic_handle *, int));
@@ -184,162 +180,79 @@
 pcic_attach(sc)
        struct pcic_softc *sc;
 {
-       int vendor, count, i, reg;
-
-       /* now check for each controller/socket */
-
-       /*
-        * this could be done with a loop, but it would violate the
-        * abstraction
-        */
-
-       count = 0;
+       int count, i, reg, chip, socket, intr;
 
        DPRINTF(("pcic ident regs:"));
 
-       sc->handle[0].ph_parent = (struct device *)sc;
-       sc->handle[0].sock = C0SA;
-       /* initialise pcic_read and pcic_write functions */
-       sc->handle[0].ph_read = st_pcic_read;
-       sc->handle[0].ph_write = st_pcic_write;
-       sc->handle[0].ph_bus_t = sc->iot;
-       sc->handle[0].ph_bus_h = sc->ioh;
-       if (pcic_ident_ok(reg = pcic_read(&sc->handle[0], PCIC_IDENT))) {
-               sc->handle[0].flags = PCIC_FLAG_SOCKETP;
-               count++;
-       } else {
-               sc->handle[0].flags = 0;
-       }
-       sc->handle[0].laststate = PCIC_LASTSTATE_EMPTY;
-
-       DPRINTF((" 0x%02x", reg));
-
-       sc->handle[1].ph_parent = (struct device *)sc;
-       sc->handle[1].sock = C0SB;
-       /* initialise pcic_read and pcic_write functions */
-       sc->handle[1].ph_read = st_pcic_read;
-       sc->handle[1].ph_write = st_pcic_write;
-       sc->handle[1].ph_bus_t = sc->iot;
-       sc->handle[1].ph_bus_h = sc->ioh;
-       if (pcic_ident_ok(reg = pcic_read(&sc->handle[1], PCIC_IDENT))) {
-               sc->handle[1].flags = PCIC_FLAG_SOCKETP;
-               count++;
-       } else {
-               sc->handle[1].flags = 0;
+       /* find and configure for the available sockets */
+       count = 0;
+       for (i = 0; i < PCIC_NSLOTS; i++) {
+               chip = i / 2;
+               socket = i % 2;
+               sc->handle[i].ph_parent = (struct device *)sc;
+               sc->handle[i].chip = chip;
+               sc->handle[i].sock = chip * PCIC_CHIP_OFFSET +
+                   socket * PCIC_SOCKET_OFFSET;
+               /* initialise pcic_read and pcic_write functions */
+               sc->handle[i].ph_read = st_pcic_read;
+               sc->handle[i].ph_write = st_pcic_write;
+               sc->handle[i].ph_bus_t = sc->iot;
+               sc->handle[i].ph_bus_h = sc->ioh;
+               /* need to read vendor -- for cirrus to report no xtra chip */
+               if (socket == 0)
+                       sc->handle[i].vendor = sc->handle[i + 1].vendor =
+                           pcic_vendor(&sc->handle[i]);
+               reg = pcic_read(&sc->handle[i], PCIC_IDENT);
+               if (!pcic_ident_ok(reg)) {
+                       sc->handle[i].flags = 0;
+               } else {
+                       sc->handle[i].flags = PCIC_FLAG_SOCKETP;
+                       count++;
+               }
+               sc->handle[i].laststate = PCIC_LASTSTATE_EMPTY;
+               DPRINTF(("ident reg 0x%02x\n", reg));
        }
-       sc->handle[1].laststate = PCIC_LASTSTATE_EMPTY;
-
-       DPRINTF((" 0x%02x", reg));
-
-       /*
-        * The CL-PD6729 has only one controller and always returns 0
-        * if you try to read from the second one. Maybe pcic_ident_ok
-        * shouldn't accept 0?
-        */
-       sc->handle[2].ph_parent = (struct device *)sc;
-       sc->handle[2].sock = C1SA;
-       /* initialise pcic_read and pcic_write functions */
-       sc->handle[2].ph_read = st_pcic_read;
-       sc->handle[2].ph_write = st_pcic_write;
-       sc->handle[2].ph_bus_t = sc->iot;
-       sc->handle[2].ph_bus_h = sc->ioh;
-       if (pcic_vendor(&sc->handle[0]) != PCIC_VENDOR_CIRRUS_PD672X ||
-           pcic_read(&sc->handle[2], PCIC_IDENT) != 0) {
-               if (pcic_ident_ok(reg = pcic_read(&sc->handle[2],
-                                                 PCIC_IDENT))) {
-                       sc->handle[2].flags = PCIC_FLAG_SOCKETP;
-                       count++;
-               } else {
-                       sc->handle[2].flags = 0;
-               }
-               sc->handle[2].laststate = PCIC_LASTSTATE_EMPTY;
-
-               DPRINTF((" 0x%02x", reg));
-
-               sc->handle[3].ph_parent = (struct device *)sc;
-               sc->handle[3].sock = C1SB;
-               /* initialise pcic_read and pcic_write functions */
-               sc->handle[3].ph_read = st_pcic_read;
-               sc->handle[3].ph_write = st_pcic_write;
-               sc->handle[3].ph_bus_t = sc->iot;
-               sc->handle[3].ph_bus_h = sc->ioh;
-               if (pcic_ident_ok(reg = pcic_read(&sc->handle[3],
-                                                 PCIC_IDENT))) {
-                       sc->handle[3].flags = PCIC_FLAG_SOCKETP;
-                       count++;
-               } else {
-                       sc->handle[3].flags = 0;
-               }
-               sc->handle[3].laststate = PCIC_LASTSTATE_EMPTY;
-
-               DPRINTF((" 0x%02x\n", reg));
-       } else {
-               sc->handle[2].flags = 0;
-               sc->handle[3].flags = 0;
-       }
-
        if (count == 0)
                panic("pcic_attach: attach found no sockets");
 
-       /* establish the interrupt */
-
-       /* XXX block interrupts? */
+       for (i = 0; i < PCIC_NSLOTS; i++) {
+               if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) {
+                       SIMPLEQ_INIT(&sc->handle[i].events);
 
-       for (i = 0; i < PCIC_NSLOTS; i++) {
-               /*
-                * this should work, but w/o it, setting tty flags hangs at
-                * boot time.
-                */
-               if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
-               {
-                       SIMPLEQ_INIT(&sc->handle[i].events);
+                       /* disable interrupts -- for now */
                        pcic_write(&sc->handle[i], PCIC_CSC_INTR, 0);
+                       intr = pcic_read(&sc->handle[i], PCIC_INTR);
+                       DPRINTF(("intr was 0x%02x\n", intr));
+                       intr &= ~(PCIC_INTR_RI_ENABLE | PCIC_INTR_ENABLE |
+                           PCIC_INTR_IRQ_MASK);
+                       pcic_write(&sc->handle[i], PCIC_INTR, intr);
                        pcic_read(&sc->handle[i], PCIC_CSC);
                }
        }
 
-       if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) ||
-           (sc->handle[1].flags & PCIC_FLAG_SOCKETP)) {
-               vendor = pcic_vendor(&sc->handle[0]);
+       /* print detected info */
+       for (i = 0; i < PCIC_NSLOTS; i += 2) {
+               chip = i / 2;
+               if ((sc->handle[i].flags & PCIC_FLAG_SOCKETP) == 0 &&
+                   (sc->handle[i + 1].flags & PCIC_FLAG_SOCKETP) == 0)
+                       continue;
 
-               printf("%s: controller 0 (%s) has ", sc->dev.dv_xname,
-                      pcic_vendor_to_string(vendor));
+               printf("%s: controller %d (%s) has ", sc->dev.dv_xname, chip,
+                   pcic_vendor_to_string(sc->handle[i].vendor));
 
-               if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) &&
-                   (sc->handle[1].flags & PCIC_FLAG_SOCKETP))
+               if ((sc->handle[i].flags & PCIC_FLAG_SOCKETP) &&
+                   (sc->handle[i + 1].flags & PCIC_FLAG_SOCKETP))
                        printf("sockets A and B\n");
-               else if (sc->handle[0].flags & PCIC_FLAG_SOCKETP)
+               else if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
                        printf("socket A only\n");
                else
                        printf("socket B only\n");
-
-               if (sc->handle[0].flags & PCIC_FLAG_SOCKETP)
-                       sc->handle[0].vendor = vendor;
-               if (sc->handle[1].flags & PCIC_FLAG_SOCKETP)
-                       sc->handle[1].vendor = vendor;
-       }
-       if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) ||
-           (sc->handle[3].flags & PCIC_FLAG_SOCKETP)) {
-               vendor = pcic_vendor(&sc->handle[2]);
-
-               printf("%s: controller 1 (%s) has ", sc->dev.dv_xname,
-                      pcic_vendor_to_string(vendor));
-
-               if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) &&
-                   (sc->handle[3].flags & PCIC_FLAG_SOCKETP))
-                       printf("sockets A and B\n");
-               else if (sc->handle[2].flags & PCIC_FLAG_SOCKETP)
-                       printf("socket A only\n");
-               else
-                       printf("socket B only\n");
-
-               if (sc->handle[2].flags & PCIC_FLAG_SOCKETP)
-                       sc->handle[2].vendor = vendor;
-               if (sc->handle[3].flags & PCIC_FLAG_SOCKETP)
-                       sc->handle[3].vendor = vendor;
        }
 }
 
+/*
+ * attach the sockets before we know what interrupts we have
+ */
 void
 pcic_attach_sockets(sc)
        struct pcic_softc *sc;
@@ -358,6 +271,9 @@
 {
        struct pcic_handle *h = (struct pcic_handle *)arg;
        struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
+       int reg;
+
+       DPRINTF(("%s: power: why %d\n", h->ph_parent->dv_xname, why));
 
        if (h->flags & PCIC_FLAG_SOCKETP) {
                if ((why == PWR_RESUME) &&
@@ -365,9 +281,10 @@
 #ifdef PCICDEBUG
                        char bitbuf[64];
 #endif
-                       pcic_write(h, PCIC_CSC_INTR,
-                           (sc->irq << PCIC_CSC_INTR_IRQ_SHIFT) |
-                           PCIC_CSC_INTR_CD_ENABLE);
+                       reg = PCIC_CSC_INTR_CD_ENABLE;
+                       if (sc->irq != -1)
+                           reg |= sc->irq << PCIC_CSC_INTR_IRQ_SHIFT;
+                       pcic_write(h, PCIC_CSC_INTR, reg);
                        DPRINTF(("%s: CSC_INTR was zero; reset to %s\n",
                            sc->dev.dv_xname,
                            bitmask_snprintf(pcic_read(h, PCIC_CSC_INTR),
@@ -378,6 +295,9 @@
 }
 
 
+/*
+ * attach a socket -- we don't know about irqs yet
+ */
 void
 pcic_attach_socket(h)
        struct pcic_handle *h;
@@ -400,13 +320,98 @@
        paa.iobase = sc->iobase;
        paa.iosize = sc->iosize;
 
-       h->pcmcia = config_found_sm(&sc->dev, &paa, pcic_print,
-           pcic_submatch);
+       h->pcmcia = config_found_sm(&sc->dev, &paa, pcic_print, pcic_submatch);
+       if (h->pcmcia == 0)
+               return;
+
+       /*



Home | Main Index | Thread Index | Old Index