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