From 5e29f016e37bb52cb85f2679d9d7d1058f9f3148 Mon Sep 17 00:00:00 2001 From: imp Date: Wed, 11 Aug 2004 17:24:42 +0000 Subject: [PATCH] Remove badly broken pcic driver for NEWCARD --- sys/dev/pcic/i82365.c | 1522 ------------------------------------- sys/dev/pcic/i82365_isa.c | 406 ---------- sys/dev/pcic/i82365reg.h | 365 --------- sys/dev/pcic/i82365var.h | 168 ---- 4 files changed, 2461 deletions(-) delete mode 100644 sys/dev/pcic/i82365.c delete mode 100644 sys/dev/pcic/i82365_isa.c delete mode 100644 sys/dev/pcic/i82365reg.h delete mode 100644 sys/dev/pcic/i82365var.h diff --git a/sys/dev/pcic/i82365.c b/sys/dev/pcic/i82365.c deleted file mode 100644 index 65827460c73a..000000000000 --- a/sys/dev/pcic/i82365.c +++ /dev/null @@ -1,1522 +0,0 @@ -/* $NetBSD: i82365.c,v 1.25 1999/10/15 06:07:27 haya Exp $ */ - - -#include -__FBSDID("$FreeBSD$"); -/* - * Copyright (c) 1997 Marc Horowitz. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Marc Horowitz. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include - -/* We shouldn't need to include the following, but sadly we do for now */ -/* XXX */ -#include -#include - -#include -#include - -#include "card_if.h" - -#define PCICDEBUG - -#ifdef PCICDEBUG -int pcic_debug = 1; -#define DPRINTF(arg) if (pcic_debug) printf arg; else ; -#define DEVPRINTF(arg) if (pcic_debug) device_printf arg; else ; -#else -#define DPRINTF(arg) -#define DEVPRINTF(arg) -#endif - -#define VERBOSE(arg) if (bootverbose) printf arg; else ; - -#define N(a) (sizeof(a)/sizeof(a[0])) - -#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 - -#define PCIC_H2SOFTC(h) ((struct pcic_softc *)h->sc) -/* - * Individual drivers will allocate their own memory and io regions. Memory - * regions must be a multiple of 4k, aligned on a 4k boundary. - */ - -#define PCIC_MEM_ALIGN PCIC_MEM_PAGESIZE - -static void pcic_init_socket(struct pcic_handle *); -static void pcic_intr_socket(struct pcic_handle *); - -static int pcic_activate(device_t dev); -static void pcic_intr(void *arg); - -static void pcic_attach_card(struct pcic_handle *); -static void pcic_detach_card(struct pcic_handle *); - -static void pcic_chip_do_mem_map(struct pcic_handle *, int); -static void pcic_chip_do_io_map(struct pcic_handle *, int); - -void pcic_create_event_thread(void *); -void pcic_event_thread(void *); - -void pcic_queue_event(struct pcic_handle *, int); - -static void pcic_wait_ready(struct pcic_handle *); - -static u_int8_t st_pcic_read(struct pcic_handle *, int); -static void st_pcic_write(struct pcic_handle *, int, u_int8_t); - -/* XXX Should really be dynamic XXX */ -static struct pcic_handle *handles[20]; -static struct pcic_handle **lasthandle = handles; - -static struct pcic_handle * -pcic_get_handle(device_t dev, device_t child) -{ - if (dev == child) - return NULL; - while (child && device_get_parent(child) != dev) - child = device_get_parent(child); - if (child == NULL) - return NULL; - return ((struct pcic_handle *) device_get_ivars(child)); -} - -int -pcic_ident_ok(int ident) -{ - /* this is very empirical and heuristic */ - - if ((ident == 0) || (ident == 0xff) || (ident & PCIC_IDENT_ZERO)) - return (0); - - if ((ident & PCIC_IDENT_IFTYPE_MASK) != PCIC_IDENT_IFTYPE_MEM_AND_IO) { -#ifdef DIAGNOSTIC - printf("pcic: does not support memory and I/O cards, " - "ignored (ident=%0x)\n", ident); -#endif - return (0); - } - return (1); -} - -int -pcic_vendor(struct pcic_handle *h) -{ - int reg; - - /* - * the chip_id of the cirrus toggles between 11 and 00 after a write. - * weird. - */ - - pcic_write(h, PCIC_CIRRUS_CHIP_INFO, 0); - reg = pcic_read(h, -1); - - if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == - PCIC_CIRRUS_CHIP_INFO_CHIP_ID) { - reg = pcic_read(h, -1); - if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 0) { - if (reg & PCIC_CIRRUS_CHIP_INFO_SLOTS) - return (PCIC_VENDOR_CIRRUS_PD672X); - else - return (PCIC_VENDOR_CIRRUS_PD6710); - } - } - - reg = pcic_read(h, PCIC_IDENT); - - if ((reg & PCIC_IDENT_REV_MASK) == PCIC_IDENT_REV_I82365SLR0) - return (PCIC_VENDOR_I82365SLR0); - else - return (PCIC_VENDOR_I82365SLR1); - - return (PCIC_VENDOR_UNKNOWN); -} - -char * -pcic_vendor_to_string(int vendor) -{ - switch (vendor) { - case PCIC_VENDOR_I82365SLR0: - return ("Intel 82365SL Revision 0"); - case PCIC_VENDOR_I82365SLR1: - return ("Intel 82365SL Revision 1"); - case PCIC_VENDOR_CIRRUS_PD6710: - return ("Cirrus PD6710"); - case PCIC_VENDOR_CIRRUS_PD672X: - return ("Cirrus PD672X"); - } - - return ("Unknown controller"); -} - -static int -pcic_activate(device_t dev) -{ - struct pcic_softc *sc = PCIC_SOFTC(dev); - int err; - - sc->port_rid = 0; - sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, - 0, ~0, PCIC_IOSIZE, RF_ACTIVE); - if (!sc->port_res) { - device_printf(dev, "Cannot allocate ioport\n"); - return ENOMEM; - } - - sc->irq_rid = 0; - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, - RF_ACTIVE); - if (sc->irq_res) { - sc->irq = rman_get_start(sc->irq_res); - if ((err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC, - pcic_intr, sc, &sc->intrhand)) != 0) { - device_printf(dev, "Cannot setup intr\n"); - pcic_deactivate(dev); - return err; - } - } else { - printf("Polling not supported\n"); - /* XXX Do polling */ - return (ENXIO); - } - - /* XXX This might not be needed in future, get it directly from - * XXX parent */ - sc->mem_rid = 0; - sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid, - 0, ~0, 1 << 13, RF_ACTIVE); - if (sc->mem_res == NULL) { - device_printf(dev, "Cannot allocate mem\n"); - pcic_deactivate(dev); - return ENOMEM; - } - - sc->iot = rman_get_bustag(sc->port_res); - sc->ioh = rman_get_bushandle(sc->port_res);; - sc->memt = rman_get_bustag(sc->mem_res); - sc->memh = rman_get_bushandle(sc->mem_res);; - - return (0); -} - -void -pcic_deactivate(device_t dev) -{ - struct pcic_softc *sc = PCIC_SOFTC(dev); - - if (sc->intrhand) - bus_teardown_intr(dev, sc->irq_res, sc->intrhand); - sc->intrhand = 0; - if (sc->port_res) - bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid, - sc->port_res); - sc->port_res = 0; - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, - sc->irq_res); - sc->irq_res = 0; - if (sc->mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, - sc->mem_res); - sc->mem_res = 0; - return; -} - -int -pcic_attach(device_t dev) -{ - struct pcic_softc *sc = PCIC_SOFTC(dev); - struct pcic_handle *h; - int vendor, count, i, reg, error; - - sc->dev = dev; - - /* Activate our resources */ - if ((error = pcic_activate(dev)) != 0) { - printf("pcic_attach (active) returns %d\n", error); - return error; - } - - /* now check for each controller/socket */ - - /* - * this could be done with a loop, but it would violate the - * abstraction... --- unknown - * I don't see the abstraction... --imp - */ - - count = 0; - - VERBOSE(("pcic ident regs:")); - - sc->handle[0].sc = 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; - - VERBOSE((" 0x%02x", reg)); - - sc->handle[1].sc = 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; - } - sc->handle[1].laststate = PCIC_LASTSTATE_EMPTY; - - VERBOSE((" 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].sc = 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; - - VERBOSE((" 0x%02x", reg)); - - sc->handle[3].sc = 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; - - VERBOSE((" 0x%02x\n", reg)); - } else { - sc->handle[2].flags = 0; - sc->handle[3].flags = 0; - } - - if (count == 0) { - printf("pcic_attach: attach found no sockets\n"); - return (ENXIO); - } - - /* establish the interrupt */ - - /* XXX block interrupts? */ - - 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) - { - STAILQ_INIT(&sc->handle[i].events); - pcic_write(&sc->handle[i], PCIC_CSC_INTR, 0); - 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]); - - device_printf(dev, "controller 0 (%s) has ", - pcic_vendor_to_string(vendor)); - - if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) && - (sc->handle[1].flags & PCIC_FLAG_SOCKETP)) - printf("sockets A and B\n"); - else if (sc->handle[0].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]); - - device_printf(dev, "controller 1 (%s) has ", - 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; - } - - for (i = 0; i < PCIC_NSLOTS; i++) { - if ((sc->handle[i].flags & PCIC_FLAG_SOCKETP) == 0) - continue; - h = &sc->handle[i]; - /* initialize the rest of the handle */ - h->shutdown = 0; - h->memalloc = 0; - h->ioalloc = 0; - h->ih_irq = 0; - h->sc = sc; - h->dev = device_add_child(dev, "pccard", -1); - device_set_ivars(h->dev, h); - pcic_init_socket(h); - } - - /* - * Probe and attach any children as were configured above. - */ - error = bus_generic_attach(dev); - if (error) - pcic_deactivate(dev); - return error; -} - -void -pcic_create_event_thread(void *arg) -{ - struct pcic_handle *h = arg; - const char *cs; - - switch (h->sock) { - case C0SA: - cs = "0,0"; - break; - case C0SB: - cs = "0,1"; - break; - case C1SA: - cs = "1,0"; - break; - case C1SB: - cs = "1,1"; - break; - default: - panic("pcic_create_event_thread: unknown pcic socket"); - } - - if (kthread_create(pcic_event_thread, h, &h->event_thread, - 0, 0, "%s,%s", device_get_name(PCIC_H2SOFTC(h)->dev), cs)) { - device_printf(PCIC_H2SOFTC(h)->dev, - "cannot create event thread for sock 0x%02x\n", h->sock); - panic("pcic_create_event_thread"); - } -} - -void -pcic_event_thread(void *arg) -{ - struct pcic_handle *h = arg; - struct pcic_event *pe; - int s; - struct pcic_softc *sc = h->sc; - - while (h->shutdown == 0) { - s = splhigh(); - if ((pe = STAILQ_FIRST(&h->events)) == NULL) { - splx(s); - (void) tsleep(&h->events, PWAIT, "pcicev", 0); - continue; - } else { - splx(s); - /* sleep .25s to be enqueued chatterling interrupts */ - (void) tsleep(pcic_event_thread, PWAIT, "pcicss", hz/4); - } - s = splhigh(); - STAILQ_REMOVE_HEAD_UNTIL(&h->events, pe, pe_q); - splx(s); - - switch (pe->pe_type) { - case PCIC_EVENT_INSERTION: - s = splhigh(); - while (1) { - struct pcic_event *pe1, *pe2; - - if ((pe1 = STAILQ_FIRST(&h->events)) == NULL) - break; - if (pe1->pe_type != PCIC_EVENT_REMOVAL) - break; - if ((pe2 = STAILQ_NEXT(pe1, pe_q)) == NULL) - break; - if (pe2->pe_type == PCIC_EVENT_INSERTION) { - STAILQ_REMOVE_HEAD_UNTIL(&h->events, pe1, pe_q); - free(pe1, M_TEMP); - STAILQ_REMOVE_HEAD_UNTIL(&h->events, pe2, pe_q); - free(pe2, M_TEMP); - } - } - splx(s); - - DEVPRINTF((h->dev, "insertion event\n")); - pcic_attach_card(h); - break; - - case PCIC_EVENT_REMOVAL: - s = splhigh(); - while (1) { - struct pcic_event *pe1, *pe2; - - if ((pe1 = STAILQ_FIRST(&h->events)) == NULL) - break; - if (pe1->pe_type != PCIC_EVENT_INSERTION) - break; - if ((pe2 = STAILQ_NEXT(pe1, pe_q)) == NULL) - break; - if (pe2->pe_type == PCIC_EVENT_REMOVAL) { - STAILQ_REMOVE_HEAD_UNTIL(&h->events, pe1, pe_q); - free(pe1, M_TEMP); - STAILQ_REMOVE_HEAD_UNTIL(&h->events, pe2, pe_q); - free(pe2, M_TEMP); - } - } - splx(s); - - DEVPRINTF((h->dev, "removal event\n")); - pcic_detach_card(h); - break; - - default: - panic("pcic_event_thread: unknown event %d", - pe->pe_type); - } - free(pe, M_TEMP); - } - - h->event_thread = NULL; - - /* In case parent is waiting for us to exit. */ - wakeup(sc); - - kthread_exit(0); -} - -void -pcic_init_socket(struct pcic_handle *h) -{ - int reg; - struct pcic_softc *sc = h->sc; - - /* - * queue creation of a kernel thread to handle insert/removal events. - */ - *lasthandle++ = h; - - /* set up the card to interrupt on card detect */ - - pcic_write(h, PCIC_CSC_INTR, (sc->irq << PCIC_CSC_INTR_IRQ_SHIFT) | - PCIC_CSC_INTR_CD_ENABLE); - pcic_write(h, PCIC_INTR, 0); - pcic_read(h, PCIC_CSC); - - /* unsleep the cirrus controller */ - - if ((h->vendor == PCIC_VENDOR_CIRRUS_PD6710) || - (h->vendor == PCIC_VENDOR_CIRRUS_PD672X)) { - reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2); - if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) { - DEVPRINTF((sc->dev, "socket %02x was suspended\n", - h->sock)); - reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND; - pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg); - } - } - h->laststate = PCIC_LASTSTATE_EMPTY; - -#if 0 -/* XXX */ -/* Should do this later */ -/* maybe as part of interrupt routing verification */ - if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) == - PCIC_IF_STATUS_CARDDETECT_PRESENT) { - pcic_attach_card(h); - h->laststate = PCIC_LASTSTATE_PRESENT; - } else { - h->laststate = PCIC_LASTSTATE_EMPTY; - } -#endif -} - -static void -pcic_intr(void *arg) -{ - struct pcic_softc *sc = arg; - int i; - - for (i = 0; i < PCIC_NSLOTS; i++) - if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) - pcic_intr_socket(&sc->handle[i]); -} - -static void -pcic_intr_socket(struct pcic_handle *h) -{ - int cscreg; - - cscreg = pcic_read(h, PCIC_CSC); - - cscreg &= (PCIC_CSC_GPI | PCIC_CSC_CD | PCIC_CSC_READY | - PCIC_CSC_BATTWARN | PCIC_CSC_BATTDEAD); - - if (cscreg & PCIC_CSC_GPI) { - DEVPRINTF((h->dev, "%02x GPI\n", h->sock)); - } - if (cscreg & PCIC_CSC_CD) { - int statreg; - - statreg = pcic_read(h, PCIC_IF_STATUS); - - DEVPRINTF((h->dev, "%02x CD %x\n", h->sock, statreg)); - - if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) == - PCIC_IF_STATUS_CARDDETECT_PRESENT) { - if (h->laststate != PCIC_LASTSTATE_PRESENT) { - DEVPRINTF((h->dev, - "enqueing INSERTION event\n")); - pcic_queue_event(h, PCIC_EVENT_INSERTION); - } - h->laststate = PCIC_LASTSTATE_PRESENT; - } else { - if (h->laststate == PCIC_LASTSTATE_PRESENT) { - /* Deactivate the card now. */ - DEVPRINTF((h->dev, "detaching card\n")); - pcic_detach_card(h); - DEVPRINTF((h->dev,"enqueing REMOVAL event\n")); - pcic_queue_event(h, PCIC_EVENT_REMOVAL); - } - h->laststate = ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) == 0) - ? PCIC_LASTSTATE_EMPTY : PCIC_LASTSTATE_HALF; - } - } - if (cscreg & PCIC_CSC_READY) { - DEVPRINTF((h->dev, "%02x READY\n", h->sock)); - /* shouldn't happen */ - } - if (cscreg & PCIC_CSC_BATTWARN) { - DEVPRINTF((h->dev, "%02x BATTWARN\n", h->sock)); - } - if (cscreg & PCIC_CSC_BATTDEAD) { - DEVPRINTF((h->dev, "%02x BATTDEAD\n", h->sock)); - } -} - -void -pcic_queue_event(struct pcic_handle *h, int event) -{ - struct pcic_event *pe; - int s; - - pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT); - if (pe == NULL) - panic("pcic_queue_event: can't allocate event"); - - pe->pe_type = event; - s = splhigh(); - STAILQ_INSERT_TAIL(&h->events, pe, pe_q); - splx(s); - wakeup(&h->events); -} - -static void -pcic_attach_card(struct pcic_handle *h) -{ - if (!(h->flags & PCIC_FLAG_CARDP)) { - /* call the MI attach function */ - CARD_ATTACH_CARD(h->dev); - h->flags |= PCIC_FLAG_CARDP; - } else { - DPRINTF(("pcic_attach_card: already attached\n")); - } -} - -static void -pcic_detach_card(struct pcic_handle *h) -{ - if (h->flags & PCIC_FLAG_CARDP) { - h->flags &= ~PCIC_FLAG_CARDP; - /* call the MI detach function */ - CARD_DETACH_CARD(h->dev); - } -} - -static int -pcic_chip_mem_alloc(struct pcic_handle *h, struct resource *r, bus_size_t size, - struct pccard_mem_handle *pcmhp) -{ - bus_space_handle_t memh; - bus_addr_t addr; - bus_size_t sizepg; - int mask; - struct pcic_softc *sc = h->sc; - - /* out of sc->memh, allocate as many pages as necessary */ - - /* convert size to PCIC pages */ - sizepg = (size + (PCIC_MEM_ALIGN - 1)) / PCIC_MEM_ALIGN; - if (sizepg > PCIC_MAX_MEM_PAGES) - return (1); - - mask = (1 << sizepg) - 1; - - addr = rman_get_start(r); - memh = addr; - pcmhp->memt = sc->memt; - pcmhp->memh = memh; - pcmhp->addr = addr; - pcmhp->size = size; - pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE; - return (0); -} - -static void -pcic_chip_mem_free(struct pcic_handle *h, struct pccard_mem_handle *pcmhp) -{ -} - -static struct mem_map_index_st { - int sysmem_start_lsb; - int sysmem_start_msb; - int sysmem_stop_lsb; - int sysmem_stop_msb; - int cardmem_lsb; - int cardmem_msb; - int memenable; -} mem_map_index[] = { - { - PCIC_SYSMEM_ADDR0_START_LSB, - PCIC_SYSMEM_ADDR0_START_MSB, - PCIC_SYSMEM_ADDR0_STOP_LSB, - PCIC_SYSMEM_ADDR0_STOP_MSB, - PCIC_CARDMEM_ADDR0_LSB, - PCIC_CARDMEM_ADDR0_MSB, - PCIC_ADDRWIN_ENABLE_MEM0, - }, - { - PCIC_SYSMEM_ADDR1_START_LSB, - PCIC_SYSMEM_ADDR1_START_MSB, - PCIC_SYSMEM_ADDR1_STOP_LSB, - PCIC_SYSMEM_ADDR1_STOP_MSB, - PCIC_CARDMEM_ADDR1_LSB, - PCIC_CARDMEM_ADDR1_MSB, - PCIC_ADDRWIN_ENABLE_MEM1, - }, - { - PCIC_SYSMEM_ADDR2_START_LSB, - PCIC_SYSMEM_ADDR2_START_MSB, - PCIC_SYSMEM_ADDR2_STOP_LSB, - PCIC_SYSMEM_ADDR2_STOP_MSB, - PCIC_CARDMEM_ADDR2_LSB, - PCIC_CARDMEM_ADDR2_MSB, - PCIC_ADDRWIN_ENABLE_MEM2, - }, - { - PCIC_SYSMEM_ADDR3_START_LSB, - PCIC_SYSMEM_ADDR3_START_MSB, - PCIC_SYSMEM_ADDR3_STOP_LSB, - PCIC_SYSMEM_ADDR3_STOP_MSB, - PCIC_CARDMEM_ADDR3_LSB, - PCIC_CARDMEM_ADDR3_MSB, - PCIC_ADDRWIN_ENABLE_MEM3, - }, - { - PCIC_SYSMEM_ADDR4_START_LSB, - PCIC_SYSMEM_ADDR4_START_MSB, - PCIC_SYSMEM_ADDR4_STOP_LSB, - PCIC_SYSMEM_ADDR4_STOP_MSB, - PCIC_CARDMEM_ADDR4_LSB, - PCIC_CARDMEM_ADDR4_MSB, - PCIC_ADDRWIN_ENABLE_MEM4, - }, -}; - -static void -pcic_chip_do_mem_map(struct pcic_handle *h, int win) -{ - int reg; - - pcic_write(h, mem_map_index[win].sysmem_start_lsb, - (h->mem[win].addr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff); - pcic_write(h, mem_map_index[win].sysmem_start_msb, - ((h->mem[win].addr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) & - PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK)); - -#if 0 - /* XXX do I want 16 bit all the time? */ - PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT; -#endif - - pcic_write(h, mem_map_index[win].sysmem_stop_lsb, - ((h->mem[win].addr + h->mem[win].size) >> - PCIC_SYSMEM_ADDRX_SHIFT) & 0xff); - pcic_write(h, mem_map_index[win].sysmem_stop_msb, - (((h->mem[win].addr + h->mem[win].size) >> - (PCIC_SYSMEM_ADDRX_SHIFT + 8)) & - PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) | - PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2); - - pcic_write(h, mem_map_index[win].cardmem_lsb, - (h->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff); - pcic_write(h, mem_map_index[win].cardmem_msb, - ((h->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) & - PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) | - ((h->mem[win].kind == PCCARD_MEM_ATTR) ? - PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0)); - - reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); - reg |= (mem_map_index[win].memenable | PCIC_ADDRWIN_ENABLE_MEMCS16); - pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); - - DELAY(100); - -#ifdef PCICDEBUG - { - int r1, r2, r3, r4, r5, r6; - - r1 = pcic_read(h, mem_map_index[win].sysmem_start_msb); - r2 = pcic_read(h, mem_map_index[win].sysmem_start_lsb); - r3 = pcic_read(h, mem_map_index[win].sysmem_stop_msb); - r4 = pcic_read(h, mem_map_index[win].sysmem_stop_lsb); - r5 = pcic_read(h, mem_map_index[win].cardmem_msb); - r6 = pcic_read(h, mem_map_index[win].cardmem_lsb); - - DPRINTF(("pcic_chip_do_mem_map window %d: %02x%02x %02x%02x " - "%02x%02x\n", win, r1, r2, r3, r4, r5, r6)); - } -#endif -} - -static int -pcic_chip_mem_map(struct pcic_handle *h, int kind, bus_addr_t card_addr, - bus_size_t size, struct pccard_mem_handle *pcmhp, bus_addr_t *offsetp, - int *windowp) -{ - bus_addr_t busaddr; - long card_offset; - int i, win; - - win = -1; - for (i = 0; i < N(mem_map_index); i++) { - if ((h->memalloc & (1 << i)) == 0) { - win = i; - h->memalloc |= (1 << i); - break; - } - } - - if (win == -1) - return (1); - - *windowp = win; - busaddr = pcmhp->addr; - - /* - * compute the address offset to the pccard address space for the - * pcic. this is intentionally signed. The masks and shifts below - * will cause TRT to happen in the pcic registers. Deal with making - * sure the address is aligned, and return the alignment offset. - */ - - *offsetp = card_addr % PCIC_MEM_ALIGN; - card_addr -= *offsetp; - - DPRINTF(("pcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr " - "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size, - (u_long) card_addr)); - - /* - * include the offset in the size, and decrement size by one, since - * the hw wants start/stop - */ - size += *offsetp - 1; - - card_offset = (((long) card_addr) - ((long) busaddr)); - - h->mem[win].addr = busaddr; - h->mem[win].size = size; - h->mem[win].offset = card_offset; - h->mem[win].kind = kind; - - pcic_chip_do_mem_map(h, win); - - return (0); -} - -static void -pcic_chip_mem_unmap(struct pcic_handle *h, int window) -{ - int reg; - - if (window >= N(mem_map_index)) - panic("pcic_chip_mem_unmap: window out of range"); - - reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); - reg &= ~mem_map_index[window].memenable; - pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); - - h->memalloc &= ~(1 << window); -} - -static int -pcic_chip_io_alloc(struct pcic_handle *h, bus_addr_t start, bus_size_t size, - bus_size_t align, struct pccard_io_handle *pcihp) -{ - bus_space_tag_t iot; - bus_space_handle_t ioh; - bus_addr_t ioaddr; - int flags = 0; - - /* - * Allocate some arbitrary I/O space. - */ - iot = h->ph_bus_t; - ioaddr = start; - if (start) { - ioh = start; - DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n", - (u_long) ioaddr, (u_long) size)); - } else { - flags |= PCCARD_IO_ALLOCATED; - ioh = start; - DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n", - (u_long) ioaddr, (u_long) size)); - } - - pcihp->iot = iot; - pcihp->ioh = ioh; - pcihp->addr = ioaddr; - pcihp->size = size; - pcihp->flags = flags; - - return (0); -} - -static void -pcic_chip_io_free(struct pcic_handle *h, struct pccard_io_handle *pcihp) -{ -} - - -static struct io_map_index_st { - int start_lsb; - int start_msb; - int stop_lsb; - int stop_msb; - int ioenable; - int ioctlmask; - int ioctlbits[3]; /* indexed by PCCARD_WIDTH_* */ -} io_map_index[] = { - { - PCIC_IOADDR0_START_LSB, - PCIC_IOADDR0_START_MSB, - PCIC_IOADDR0_STOP_LSB, - PCIC_IOADDR0_STOP_MSB, - PCIC_ADDRWIN_ENABLE_IO0, - PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT | - PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK, - { - PCIC_IOCTL_IO0_IOCS16SRC_CARD, - PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | - PCIC_IOCTL_IO0_DATASIZE_8BIT, - PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | - PCIC_IOCTL_IO0_DATASIZE_16BIT, - }, - }, - { - PCIC_IOADDR1_START_LSB, - PCIC_IOADDR1_START_MSB, - PCIC_IOADDR1_STOP_LSB, - PCIC_IOADDR1_STOP_MSB, - PCIC_ADDRWIN_ENABLE_IO1, - PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT | - PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK, - { - PCIC_IOCTL_IO1_IOCS16SRC_CARD, - PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | - PCIC_IOCTL_IO1_DATASIZE_8BIT, - PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | - PCIC_IOCTL_IO1_DATASIZE_16BIT, - }, - }, -}; - -static void -pcic_chip_do_io_map(struct pcic_handle *h, int win) -{ - int reg; - - DPRINTF(("pcic_chip_do_io_map win %d addr %lx size %lx width %d\n", - win, (long) h->io[win].addr, (long) h->io[win].size, - h->io[win].width * 8)); - - pcic_write(h, io_map_index[win].start_lsb, h->io[win].addr & 0xff); - pcic_write(h, io_map_index[win].start_msb, - (h->io[win].addr >> 8) & 0xff); - - pcic_write(h, io_map_index[win].stop_lsb, - (h->io[win].addr + h->io[win].size - 1) & 0xff); - pcic_write(h, io_map_index[win].stop_msb, - ((h->io[win].addr + h->io[win].size - 1) >> 8) & 0xff); - - reg = pcic_read(h, PCIC_IOCTL); - reg &= ~io_map_index[win].ioctlmask; - reg |= io_map_index[win].ioctlbits[h->io[win].width]; - pcic_write(h, PCIC_IOCTL, reg); - - reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); - reg |= io_map_index[win].ioenable; - pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); -} - -static int -pcic_chip_io_map(struct pcic_handle *h, int width, bus_addr_t offset, - bus_size_t size, struct pccard_io_handle *pcihp, int *windowp) -{ - bus_addr_t ioaddr = pcihp->addr + offset; - int i, win; -#ifdef PCICDEBUG - static char *width_names[] = { "auto", "io8", "io16" }; -#endif - - /* XXX Sanity check offset/size. */ - - win = -1; - for (i = 0; i < N(io_map_index); i++) { - if ((h->ioalloc & (1 << i)) == 0) { - win = i; - h->ioalloc |= (1 << i); - break; - } - } - - if (win == -1) - return (1); - - *windowp = win; - - DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n", - win, width_names[width], (u_long) ioaddr, (u_long) size)); - - h->io[win].addr = ioaddr; - h->io[win].size = size; - h->io[win].width = width; - - pcic_chip_do_io_map(h, win); - - return (0); -} - -static void -pcic_chip_io_unmap(struct pcic_handle *h, int window) -{ - int reg; - - if (window >= N(io_map_index)) - panic("pcic_chip_io_unmap: window out of range"); - - reg = pcic_read(h, PCIC_ADDRWIN_ENABLE); - reg &= ~io_map_index[window].ioenable; - pcic_write(h, PCIC_ADDRWIN_ENABLE, reg); - - h->ioalloc &= ~(1 << window); -} - -static void -pcic_wait_ready(struct pcic_handle *h) -{ - int i; - - for (i = 0; i < 10000; i++) { - if (pcic_read(h, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY) - return; - DELAY(500); -#ifdef PCICDEBUG - if (pcic_debug) { - if ((i>5000) && (i%100 == 99)) - printf("."); - } -#endif - } - -#ifdef DIAGNOSTIC - printf("pcic_wait_ready: ready never happened, status = %02x\n", - pcic_read(h, PCIC_IF_STATUS)); -#endif -} - -int -pcic_enable_socket(device_t dev, device_t child) -{ - struct pcic_handle *h = pcic_get_handle(dev, child); - int cardtype, reg, win; - - /* this bit is mostly stolen from pcic_attach_card */ - - /* power down the socket to reset it, clear the card reset pin */ - - pcic_write(h, PCIC_PWRCTL, 0); - - /* - * wait 300ms until power fails (Tpf). Then, wait 100ms since - * we are changing Vcc (Toff). - */ - DELAY((300 + 100) * 1000); - -#ifdef VADEM_POWER_HACK - bus_space_write_1(sc->iot, sc->ioh, PCIC_REG_INDEX, 0x0e); - bus_space_write_1(sc->iot, sc->ioh, PCIC_REG_INDEX, 0x37); - printf("prcr = %02x\n", pcic_read(h, 0x02)); - printf("cvsr = %02x\n", pcic_read(h, 0x2f)); - printf("DANGER WILL ROBINSON! Changing voltage select!\n"); - pcic_write(h, 0x2f, pcic_read(h, 0x2f) & ~0x03); - printf("cvsr = %02x\n", pcic_read(h, 0x2f)); -#endif - - /* power up the socket */ - - pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_DISABLE_RESETDRV - | PCIC_PWRCTL_PWR_ENABLE); - - /* - * wait 100ms until power raise (Tpr) and 20ms to become - * stable (Tsu(Vcc)). - * - * some machines require some more time to be settled - * (300ms is added here). - */ - DELAY((100 + 20 + 300) * 1000); - - pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_DISABLE_RESETDRV | PCIC_PWRCTL_OE - | PCIC_PWRCTL_PWR_ENABLE); - pcic_write(h, PCIC_INTR, 0); - - /* - * hold RESET at least 10us. - */ - DELAY(10); - - /* clear the reset flag */ - - pcic_write(h, PCIC_INTR, PCIC_INTR_RESET); - - /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */ - - DELAY(20000); - - /* wait for the chip to finish initializing */ - -#ifdef DIAGNOSTIC - reg = pcic_read(h, PCIC_IF_STATUS); - if (!(reg & PCIC_IF_STATUS_POWERACTIVE)) { - printf("pcic_chip_socket_enable: status %x", reg); - } -#endif - - pcic_wait_ready(h); - - /* zero out the address windows */ - pcic_write(h, PCIC_ADDRWIN_ENABLE, 0); - - /* set the card type */ - CARD_GET_TYPE(h->dev, &cardtype); - - reg = pcic_read(h, PCIC_INTR); - reg &= ~(PCIC_INTR_CARDTYPE_MASK | PCIC_INTR_IRQ_MASK | PCIC_INTR_ENABLE); - reg |= ((cardtype == PCCARD_IFTYPE_IO) ? - PCIC_INTR_CARDTYPE_IO : - PCIC_INTR_CARDTYPE_MEM); - reg |= h->ih_irq; - pcic_write(h, PCIC_INTR, reg); - - DEVPRINTF((h->dev, "pcic_chip_socket_enable cardtype %s %02x\n", - ((cardtype == PCCARD_IFTYPE_IO) ? "io" : "mem"), reg)); - - /* reinstall all the memory and io mappings */ - - for (win = 0; win < PCIC_MEM_WINS; win++) - if (h->memalloc & (1 << win)) - pcic_chip_do_mem_map(h, win); - - for (win = 0; win < PCIC_IO_WINS; win++) - if (h->ioalloc & (1 << win)) - pcic_chip_do_io_map(h, win); - - return 0; -} - -int -pcic_disable_socket(device_t dev, device_t child) -{ - struct pcic_handle *h = pcic_get_handle(dev, child); - - /* power down the socket */ - - pcic_write(h, PCIC_PWRCTL, 0); - - /* - * wait 300ms until power fails (Tpf). - */ - DELAY(300 * 1000); - - return 0; -} - -static u_int8_t -st_pcic_read(struct pcic_handle *h, int idx) -{ - if (idx != -1) { - bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_INDEX, - h->sock + idx); - } - return bus_space_read_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_DATA); -} - -static void -st_pcic_write(struct pcic_handle *h, int idx, u_int8_t data) -{ - if (idx != -1) { - bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_INDEX, - h->sock + idx); - } - - bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_DATA, data); -} - -int -pcic_activate_resource(device_t dev, device_t child, int type, int rid, - struct resource *r) -{ - int err; - int sz; - int win; - bus_addr_t off; - struct pcic_handle *h = pcic_get_handle(dev, child); - - sz = rman_get_size(r); - switch (type) { - case SYS_RES_IOPORT: - win = rid; - err = pcic_chip_io_map(h, 0, 0, sz, &h->io[rid], &win); - if (err) { - pcic_chip_io_free(h, &h->io[rid]); - return err; - } - break; - case SYS_RES_MEMORY: - err = pcic_chip_mem_map(h, 0, 0, sz, &h->mem[rid], &off, &win); - if (err) { - pcic_chip_mem_free(h, &h->mem[rid]); - return err; - } - break; - default: - break; - } - err = bus_generic_activate_resource(device_get_parent(dev), child, - type, rid, r); - return (err); -} - -int -pcic_deactivate_resource(device_t dev, device_t child, int type, int rid, - struct resource *r) -{ - struct pcic_handle *h = pcic_get_handle(dev, child); - int err = 0; - - switch (type) { - case SYS_RES_IOPORT: - pcic_chip_io_unmap(h, rid); - break; - case SYS_RES_MEMORY: - pcic_chip_mem_unmap(h, rid); - default: - break; - } - err = bus_generic_deactivate_resource(device_get_parent(dev), child, - type, rid, r); - return (err); -} - -int -pcic_setup_intr(device_t dev, device_t child, struct resource *irqres, - int flags, driver_intr_t intr, void *arg, void **cookiep) -{ - struct pcic_handle *h = pcic_get_handle(dev, child); - int reg; - int irq; - int err; - - err = bus_generic_setup_intr(device_get_parent(dev), child, irqres, - flags, intr, arg, cookiep); - if (!err) - return (err); - - irq = rman_get_start(irqres); - reg = pcic_read(h, PCIC_INTR); - reg &= ~(PCIC_INTR_IRQ_MASK | PCIC_INTR_ENABLE); - reg |= irq; - pcic_write(h, PCIC_INTR, reg); - - h->ih_irq = irq; - - device_printf(dev, "card irq %d\n", irq); - - return 0; -} - -int -pcic_teardown_intr(device_t dev, device_t child, struct resource *irq, - void *cookiep) -{ - int reg; - struct pcic_handle *h = pcic_get_handle(dev, child); - - h->ih_irq = 0; - - reg = pcic_read(h, PCIC_INTR); - reg &= ~(PCIC_INTR_IRQ_MASK | PCIC_INTR_ENABLE); - pcic_write(h, PCIC_INTR, reg); - - return (bus_generic_teardown_intr(device_get_parent(dev), child, irq, - cookiep)); -} - -struct resource * -pcic_alloc_resource(device_t dev, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, u_int flags) -{ - int sz; - int err; - struct resource *r; - struct pcic_handle *h = pcic_get_handle(dev, child); - - /* Nearly default */ - if (type == SYS_RES_MEMORY && start == 0 && end == ~0 && count != 1) { - start = 0xd0000; /* XXX */ - end = 0xdffff; - } - - r = bus_generic_alloc_resource(dev, child, type, rid, start, end, - count, flags); - if (r == NULL) - return r; - sz = rman_get_size(r); - switch (type) { - case SYS_RES_IOPORT: - err = pcic_chip_io_alloc(h, rman_get_start(r), sz, 0, - &h->io[*rid]); - if (err) { - bus_generic_release_resource(dev, child, type, *rid, - r); - return 0; - } - break; - case SYS_RES_MEMORY: - err = pcic_chip_mem_alloc(h, r, sz, &h->mem[*rid]); - if (err) { - bus_generic_release_resource(dev, child, type, *rid, - r); - return 0; - } - break; - default: - break; - } - return r; -} - -int -pcic_release_resource(device_t dev, device_t child, int type, int rid, - struct resource *r) -{ - struct pcic_handle *h = pcic_get_handle(dev, child); - - switch (type) { - case SYS_RES_IOPORT: - pcic_chip_io_free(h, &h->io[rid]); - break; - case SYS_RES_MEMORY: - pcic_chip_mem_free(h, &h->mem[rid]); - default: - break; - } - return bus_generic_release_resource(dev, child, type, rid, r); -} - -int -pcic_suspend(device_t dev) -{ - /* - * Do nothing for now, maybe in time do what FreeBSD's current - * pccard code does and detach my children. That's the safest thing - * to do since we don't want to wake up and have different hardware - * in the slots. - */ - - return 0; -} - -int -pcic_resume(device_t dev) -{ - /* Need to port pcic_power from newer netbsd versions of this file */ - - return 0; -} - -int -pcic_set_res_flags(device_t dev, device_t child, int type, int rid, - u_int32_t flags) -{ - struct pcic_handle *h = pcic_get_handle(dev, child); - - if (type != SYS_RES_MEMORY) - return (EINVAL); - h->mem[rid].kind = PCCARD_MEM_ATTR; - pcic_chip_do_mem_map(h, rid); - - return 0; -} - -int -pcic_set_memory_offset(device_t dev, device_t child, int rid, u_int32_t offset, - u_int32_t *deltap) -{ - /* XXX BAD XXX */ - return EIO; -} - -static void -pcic_start_threads(void *arg) -{ - struct pcic_handle **walker; - walker = handles; - while (*walker) { - pcic_create_event_thread(*walker++); - } -} - -int -pcic_detach(device_t dev) -{ - device_t *kids; - int nkids; - int i; - int ret; - - pcic_deactivate(dev); - ret = bus_generic_detach(dev); - if (ret != 0) - return (ret); - /* - * Normally, one wouldn't delete the children. However, detach - * merely detaches the children w/o deleting them. So if - * we were to reattach, we add additional children and wind up - * with duplicates. So, we remove them here following the - * implicit "if you add it in attach, you should delete it in - * detach" rule that may or may not be documented. - */ - device_get_children(dev, &kids, &nkids); - for (i = 0; i < nkids; i++) { - if ((ret = device_delete_child(dev, kids[i])) != 0) - device_printf(dev, "delete of %s failed: %d\n", - device_get_nameunit(kids[i]), ret); - } - free(kids, M_TEMP); - return 0; -} - -SYSINIT(pcic, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, pcic_start_threads, 0); -MODULE_VERSION(pcic, 1); diff --git a/sys/dev/pcic/i82365_isa.c b/sys/dev/pcic/i82365_isa.c deleted file mode 100644 index 0a464155989e..000000000000 --- a/sys/dev/pcic/i82365_isa.c +++ /dev/null @@ -1,406 +0,0 @@ -/* $NetBSD: i82365_isasubr.c,v 1.3 1999/10/15 06:07:27 haya Exp $ */ -/* $NetBSD: i82365_isa.c,v 1.11 1998/06/09 07:25:00 thorpej Exp $ */ - - -#include -__FBSDID("$FreeBSD$"); -/* - * Copyright (c) 1998 Bill Sommerfeld. All rights reserved. - * Copyright (c) 1997 Marc Horowitz. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Marc Horowitz. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include - -#include "power_if.h" -#include "card_if.h" - -/***************************************************************************** - * Configurable parameters. - *****************************************************************************/ - -/* - * Default I/O allocation range. If both are set to non-zero, these - * values will be used instead. Otherwise, the code attempts to probe - * the bus width. Systems with 10 address bits should use 0x300 and 0xff. - * Systems with 12 address bits (most) should use 0x400 and 0xbff. - */ - -#ifndef PCIC_ISA_ALLOC_IOBASE -#define PCIC_ISA_ALLOC_IOBASE 0 -#endif - -#ifndef PCIC_ISA_ALLOC_IOSIZE -#define PCIC_ISA_ALLOC_IOSIZE 0 -#endif - -int pcic_isa_alloc_iobase = PCIC_ISA_ALLOC_IOBASE; -int pcic_isa_alloc_iosize = PCIC_ISA_ALLOC_IOSIZE; - - -/* - * Default IRQ allocation bitmask. This defines the range of allowable - * IRQs for PCCARD slots. Useful if order of probing would screw up other - * devices, or if PCIC hardware/cards have trouble with certain interrupt - * lines. - * - * We disable IRQ 10 by default, since some common laptops (namely, the - * NEC Versa series) reserve IRQ 10 for the docking station SCSI interface. - */ - -#ifndef PCIC_ISA_INTR_ALLOC_MASK -#define PCIC_ISA_INTR_ALLOC_MASK 0xfbff -#endif - -int pcic_isa_intr_alloc_mask = PCIC_ISA_INTR_ALLOC_MASK; - -/***************************************************************************** - * End of configurable parameters. - *****************************************************************************/ - -#define PCICISADEBUG 1 - -#ifdef PCICISADEBUG -int pcicisa_debug = PCICISADEBUG; -#define DPRINTF(arg) if (pcicisa_debug) printf arg; -#define DEVPRINTF(arg) if (pcicisa_debug) device_printf arg; -#else -#define DPRINTF(arg) -#define DEVPRINTF(arg) -#endif - -static struct isa_pnp_id pcic_ids[] = { - {PCIC_PNP_ACTIONTEC, NULL}, /* AEI0218 */ - {PCIC_PNP_IBM3765, NULL}, /* IBM3765 */ - {PCIC_PNP_82365, NULL}, /* PNP0E00 */ - {PCIC_PNP_CL_PD6720, NULL}, /* PNP0E01 */ - {PCIC_PNP_VLSI_82C146, NULL}, /* PNP0E02 */ - {PCIC_PNP_82365_CARDBUS, NULL}, /* PNP0E03 */ - {PCIC_PNP_SCM_SWAPBOX, NULL}, /* SCM0469 */ - {0} -}; - -static void -pcic_isa_bus_width_probe (device_t dev) -{ - struct pcic_softc *sc = PCIC_SOFTC(dev); - bus_space_handle_t ioh_high; - int i, iobuswidth, tmp1, tmp2; - int rid; - u_long base; - u_int32_t length; - bus_space_tag_t iot; - bus_space_handle_t ioh; - struct resource *r; - - base = rman_get_start(sc->port_res); - length = rman_get_size(sc->port_res); - iot = sc->iot; - ioh = sc->ioh; - - /* - * figure out how wide the isa bus is. Do this by checking if the - * pcic controller is mirrored 0x400 above where we expect it to be. - */ - - iobuswidth = 12; - rid = 1; - r = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, base + 0x400, - base + 0x400 + length, length, RF_ACTIVE); - if (!r) { - printf("Can't allocated mirror area for pcic bus width probe\n"); - return; - } - ioh_high = rman_get_bushandle(r); - for (i = 0; i < PCIC_NSLOTS; i++) { - if (sc->handle[i].flags & PCIC_FLAG_SOCKETP) { - /* - * read the ident flags from the normal space and - * from the mirror, and compare them - */ - - bus_space_write_1(iot, ioh, PCIC_REG_INDEX, - sc->handle[i].sock + PCIC_IDENT); - tmp1 = bus_space_read_1(iot, ioh, PCIC_REG_DATA); - - bus_space_write_1(iot, ioh_high, PCIC_REG_INDEX, - sc->handle[i].sock + PCIC_IDENT); - tmp2 = bus_space_read_1(iot, ioh_high, PCIC_REG_DATA); - - if (tmp1 == tmp2) - iobuswidth = 10; - } - } - bus_release_resource(dev, SYS_RES_IOPORT, rid, r); - - /* - * XXX mycroft recommends I/O space range 0x400-0xfff . I should put - * this in a header somewhere - */ - - /* - * XXX some hardware doesn't seem to grok addresses in 0x400 range-- - * apparently missing a bit or more of address lines. (e.g. - * CIRRUS_PD672X with Linksys EthernetCard ne2000 clone in TI - * TravelMate 5000--not clear which is at fault) - * - * Add a kludge to detect 10 bit wide buses and deal with them, - * and also a config file option to override the probe. - */ - - if (iobuswidth == 10) { - sc->iobase = 0x300; - sc->iosize = 0x0ff; - } else { -#if 0 - /* - * This is what we'd like to use, but... - */ - sc->iobase = 0x400; - sc->iosize = 0xbff; -#else - /* - * ...the above bus width probe doesn't always work. - * So, experimentation has shown the following range - * to not lose on systems that 0x300-0x3ff loses on - * (e.g. the NEC Versa 6030X). - */ - sc->iobase = 0x330; - sc->iosize = 0x0cf; -#endif - } - - DEVPRINTF((dev, "bus_space_alloc range 0x%04lx-0x%04lx (probed)\n", - (long) sc->iobase, (long) sc->iobase + sc->iosize)); - - if (pcic_isa_alloc_iobase && pcic_isa_alloc_iosize) { - sc->iobase = pcic_isa_alloc_iobase; - sc->iosize = pcic_isa_alloc_iosize; - - DEVPRINTF((dev, "bus_space_alloc range 0x%04lx-0x%04lx " - "(config override)\n", (long) sc->iobase, - (long) sc->iobase + sc->iosize)); - } -} - -#if 0 -static int -pcic_isa_check(device_t dev, u_int16_t addr) -{ - bus_space_tag_t iot; - bus_space_handle_t ioh; - int val, found; - int rid; - struct resource *res; - - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, addr, addr, - PCIC_IOSIZE, RF_ACTIVE); - if (!res) - return(ENXIO); - iot = rman_get_bustag(res); - ioh = rman_get_bushandle(res); - found = 0; - - /* - * this could be done with a loop, but it would violate the - * abstraction - */ - bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C0SA + PCIC_IDENT); - val = bus_space_read_1(iot, ioh, PCIC_REG_DATA); - if (pcic_ident_ok(val)) - found++; - - bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C0SB + PCIC_IDENT); - val = bus_space_read_1(iot, ioh, PCIC_REG_DATA); - if (pcic_ident_ok(val)) - found++; - - bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C1SA + PCIC_IDENT); - val = bus_space_read_1(iot, ioh, PCIC_REG_DATA); - if (pcic_ident_ok(val)) - found++; - - bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C1SB + PCIC_IDENT); - val = bus_space_read_1(iot, ioh, PCIC_REG_DATA); - if (pcic_ident_ok(val)) - found++; - - bus_release_resource(dev, SYS_RES_IOPORT, rid, res); - - return (found); -} -#endif - -static int -pcic_isa_probe(device_t dev) -{ - int error; - struct resource *res; - int rid; - int i; - u_long mem; - - /* Check isapnp ids */ - error = ISA_PNP_PROBE(device_get_parent(dev), dev, pcic_ids); - if (error == ENXIO) - return (ENXIO); - - /* If we had some other problem. */ - if (!(error == 0 || error == ENOENT)) - return (error); - - /* If we have the resources we need then we're good to go. */ - if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0) - return (ENXIO); - rid = 0; - res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (res == NULL) { - /* - * No IRQ specified, find one. This can be due to the PnP - * data not specifying any IRQ - */ - for (i = 0; i < 16; i++) { - if (((1 << i) & PCIC_INTR_IRQ_VALIDMASK) == 0) - continue; - res = bus_alloc_resource(dev, SYS_RES_IRQ, - &rid, i, i, 1, RF_ACTIVE); - if (res != NULL) - break; - } - if (res == NULL) - return (ENXIO); - mem = rman_get_start(res); - bus_release_resource(dev, SYS_RES_IRQ, rid, res); - bus_set_resource(dev, SYS_RES_IRQ, 0, i, 1); - } else { - bus_release_resource(dev, SYS_RES_IRQ, rid, res); - } - /* XXX This might not be needed in future, get it directly from - * XXX parent */ - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, - 1 << 13, RF_ACTIVE); - if (res == NULL) { - /* - * We failed to get memory. Since this XXX comment above - * indicates that this is transient, we try to get a hunk - * of memory in the isa hole. Sure would be nice if there - * were some MI constants for this. - */ - res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, - 0xa0000, 0xdffff, 1 << 13, RF_ACTIVE); - if (res != NULL) { - mem = rman_get_start(res); - bus_release_resource(dev, SYS_RES_MEMORY, rid, res); - bus_set_resource(dev, SYS_RES_MEMORY, 0, mem, 1 << 13); - } - } else { - bus_release_resource(dev, SYS_RES_MEMORY, rid, res); - } - if (res == NULL) { - device_printf(dev, "Cannot allocate mem\n"); - return ENOMEM; - } - return (0); -} - -static int -pcic_isa_attach(device_t dev) -{ - int err = 0; - - if ((err = pcic_attach(dev)) == 0) - pcic_isa_bus_width_probe (dev); - return err; -} - -static int -pcic_isa_detach(device_t dev) -{ - pcic_detach(dev); - return 0; -} - -static device_method_t pcic_isa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pcic_isa_probe), - DEVMETHOD(device_attach, pcic_isa_attach), - DEVMETHOD(device_detach, pcic_isa_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, pcic_suspend), - DEVMETHOD(device_resume, pcic_resume), - - /* Bus Interface */ - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_alloc_resource, pcic_alloc_resource), - DEVMETHOD(bus_release_resource, pcic_release_resource), - DEVMETHOD(bus_activate_resource, pcic_activate_resource), - DEVMETHOD(bus_deactivate_resource, pcic_deactivate_resource), - DEVMETHOD(bus_setup_intr, pcic_setup_intr), - DEVMETHOD(bus_teardown_intr, pcic_teardown_intr), - - /* pccard/cardbus interface */ - DEVMETHOD(card_set_res_flags, pcic_set_res_flags), - DEVMETHOD(card_set_memory_offset, pcic_set_memory_offset), - - /* Power Interface */ - DEVMETHOD(power_enable_socket, pcic_enable_socket), - DEVMETHOD(power_disable_socket, pcic_disable_socket), - { 0, 0 } -}; - -static driver_t pcic_driver = { - "pcic", - pcic_isa_methods, - sizeof(struct pcic_softc) -}; - -static devclass_t pcic_devclass; - -DRIVER_MODULE(pcic, isa, pcic_driver, pcic_devclass, 0, 0); -MODULE_DEPEND(pcic, pccard, 1, 1, 1); diff --git a/sys/dev/pcic/i82365reg.h b/sys/dev/pcic/i82365reg.h deleted file mode 100644 index 7854d7eeeea9..000000000000 --- a/sys/dev/pcic/i82365reg.h +++ /dev/null @@ -1,365 +0,0 @@ -/* $NetBSD: i82365reg.h,v 1.3 1998/12/20 17:53:28 nathanw Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1997 Marc Horowitz. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Marc Horowitz. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * All information is from the intel 82365sl PC Card Interface Controller - * (PCIC) data sheet, marked "preliminary". Order number 290423-002, January - * 1993. - */ - -#define PCIC_IOSIZE 2 - -#define PCIC_REG_INDEX 0 -#define PCIC_REG_DATA 1 - -/* - * I/o ports - */ -#define PCIC_INDEX0 0x3e0 - -/* - * The PCIC allows two chips to share the same address. In order not to run - * afoul of the netbsd device model, this driver will treat those chips as - * the same device. - */ - -#define PCIC_CHIP0_BASE 0x00 -#define PCIC_CHIP1_BASE 0x80 - -/* Each PCIC chip can drive two sockets */ - -#define PCIC_SOCKETA_INDEX 0x00 -#define PCIC_SOCKETB_INDEX 0x40 - -/* general setup registers */ - -#define PCIC_IDENT 0x00 /* RO */ -#define PCIC_IDENT_IFTYPE_MASK 0xC0 -#define PCIC_IDENT_IFTYPE_IO_ONLY 0x00 -#define PCIC_IDENT_IFTYPE_MEM_ONLY 0x40 -#define PCIC_IDENT_IFTYPE_MEM_AND_IO 0x80 -#define PCIC_IDENT_IFTYPE_RESERVED 0xC0 -#define PCIC_IDENT_ZERO 0x30 -#define PCIC_IDENT_REV_MASK 0x0F -#define PCIC_IDENT_REV_I82365SLR0 0x02 -#define PCIC_IDENT_REV_I82365SLR1 0x03 - -#define PCIC_IF_STATUS 0x01 /* RO */ -#define PCIC_IF_STATUS_GPI 0x80 /* General Purpose Input */ -#define PCIC_IF_STATUS_POWERACTIVE 0x40 -#define PCIC_IF_STATUS_READY 0x20 /* really READY/!BUSY */ -#define PCIC_IF_STATUS_MEM_WP 0x10 -#define PCIC_IF_STATUS_CARDDETECT_MASK 0x0C -#define PCIC_IF_STATUS_CARDDETECT_PRESENT 0x0C -#define PCIC_IF_STATUS_BATTERY_MASK 0x03 -#define PCIC_IF_STATUS_BATTERY_DEAD1 0x00 -#define PCIC_IF_STATUS_BATTERY_DEAD2 0x01 -#define PCIC_IF_STATUS_BATTERY_WARNING 0x02 -#define PCIC_IF_STATUS_BATTERY_GOOD 0x03 - -#define PCIC_PWRCTL 0x02 /* RW */ -#define PCIC_PWRCTL_OE 0x80 /* output enable */ -#define PCIC_PWRCTL_DISABLE_RESETDRV 0x40 -#define PCIC_PWRCTL_AUTOSWITCH_ENABLE 0x20 -#define PCIC_PWRCTL_PWR_ENABLE 0x10 -#define PCIC_PWRCTL_VPP2_MASK 0x0C -/* XXX these are a little unclear from the data sheet */ -#define PCIC_PWRCTL_VPP2_RESERVED 0x0C -#define PCIC_PWRCTL_VPP2_EN1 0x08 -#define PCIC_PWRCTL_VPP2_EN0 0x04 -#define PCIC_PWRCTL_VPP2_ENX 0x00 -#define PCIC_PWRCTL_VPP1_MASK 0x03 -/* XXX these are a little unclear from the data sheet */ -#define PCIC_PWRCTL_VPP1_RESERVED 0x03 -#define PCIC_PWRCTL_VPP1_EN1 0x02 -#define PCIC_PWRCTL_VPP1_EN0 0x01 -#define PCIC_PWRCTL_VPP1_ENX 0x00 - -#define PCIC_CSC 0x04 /* RW */ -#define PCIC_CSC_ZERO 0xE0 -#define PCIC_CSC_GPI 0x10 -#define PCIC_CSC_CD 0x08 /* Card Detect Change */ -#define PCIC_CSC_READY 0x04 -#define PCIC_CSC_BATTWARN 0x02 -#define PCIC_CSC_BATTDEAD 0x01 /* for memory cards */ -#define PCIC_CSC_RI 0x01 /* for i/o cards */ - -#define PCIC_ADDRWIN_ENABLE 0x06 /* RW */ -#define PCIC_ADDRWIN_ENABLE_IO1 0x80 -#define PCIC_ADDRWIN_ENABLE_IO0 0x40 -#define PCIC_ADDRWIN_ENABLE_MEMCS16 0x20 /* rtfds if you care */ -#define PCIC_ADDRWIN_ENABLE_MEM4 0x10 -#define PCIC_ADDRWIN_ENABLE_MEM3 0x08 -#define PCIC_ADDRWIN_ENABLE_MEM2 0x04 -#define PCIC_ADDRWIN_ENABLE_MEM1 0x02 -#define PCIC_ADDRWIN_ENABLE_MEM0 0x01 - -#define PCIC_CARD_DETECT 0x16 /* RW */ -#define PCIC_CARD_DETECT_RESERVED 0xC0 -#define PCIC_CARD_DETECT_SW_INTR 0x20 -#define PCIC_CARD_DETECT_RESUME_ENABLE 0x10 -#define PCIC_CARD_DETECT_GPI_TRANSCTL 0x08 -#define PCIC_CARD_DETECT_GPI_ENABLE 0x04 -#define PCIC_CARD_DETECT_CFGRST_ENABLE 0x02 -#define PCIC_CARD_DETECT_MEMDLY_INHIBIT 0x01 - -/* interrupt registers */ - -#define PCIC_INTR 0x03 /* RW */ -#define PCIC_INTR_RI_ENABLE 0x80 -#define PCIC_INTR_RESET 0x40 /* active low (zero) */ -#define PCIC_INTR_CARDTYPE_MASK 0x20 -#define PCIC_INTR_CARDTYPE_IO 0x20 -#define PCIC_INTR_CARDTYPE_MEM 0x00 -#define PCIC_INTR_ENABLE 0x10 -#define PCIC_INTR_IRQ_MASK 0x0F -#define PCIC_INTR_IRQ_SHIFT 0 -#define PCIC_INTR_IRQ_NONE 0x00 -#define PCIC_INTR_IRQ_RESERVED1 0x01 -#define PCIC_INTR_IRQ_RESERVED2 0x02 -#define PCIC_INTR_IRQ3 0x03 -#define PCIC_INTR_IRQ4 0x04 -#define PCIC_INTR_IRQ5 0x05 -#define PCIC_INTR_IRQ_RESERVED6 0x06 -#define PCIC_INTR_IRQ7 0x07 -#define PCIC_INTR_IRQ_RESERVED8 0x08 -#define PCIC_INTR_IRQ9 0x09 -#define PCIC_INTR_IRQ10 0x0A -#define PCIC_INTR_IRQ11 0x0B -#define PCIC_INTR_IRQ12 0x0C -#define PCIC_INTR_IRQ_RESERVED13 0x0D -#define PCIC_INTR_IRQ14 0x0E -#define PCIC_INTR_IRQ15 0x0F - -#define PCIC_INTR_IRQ_VALIDMASK 0xDEB8 /* 1101 1110 1011 1000 */ - -#define PCIC_CSC_INTR 0x05 /* RW */ -#define PCIC_CSC_INTR_IRQ_MASK 0xF0 -#define PCIC_CSC_INTR_IRQ_SHIFT 4 -#define PCIC_CSC_INTR_IRQ_NONE 0x00 -#define PCIC_CSC_INTR_IRQ_RESERVED1 0x10 -#define PCIC_CSC_INTR_IRQ_RESERVED2 0x20 -#define PCIC_CSC_INTR_IRQ3 0x30 -#define PCIC_CSC_INTR_IRQ4 0x40 -#define PCIC_CSC_INTR_IRQ5 0x50 -#define PCIC_CSC_INTR_IRQ_RESERVED6 0x60 -#define PCIC_CSC_INTR_IRQ7 0x70 -#define PCIC_CSC_INTR_IRQ_RESERVED8 0x80 -#define PCIC_CSC_INTR_IRQ9 0x90 -#define PCIC_CSC_INTR_IRQ10 0xA0 -#define PCIC_CSC_INTR_IRQ11 0xB0 -#define PCIC_CSC_INTR_IRQ12 0xC0 -#define PCIC_CSC_INTR_IRQ_RESERVED13 0xD0 -#define PCIC_CSC_INTR_IRQ14 0xE0 -#define PCIC_CSC_INTR_IRQ15 0xF0 -#define PCIC_CSC_INTR_CD_ENABLE 0x08 -#define PCIC_CSC_INTR_READY_ENABLE 0x04 -#define PCIC_CSC_INTR_BATTWARN_ENABLE 0x02 -#define PCIC_CSC_INTR_BATTDEAD_ENABLE 0x01 /* for memory cards */ -#define PCIC_CSC_INTR_RI_ENABLE 0x01 /* for I/O cards */ - -#define PCIC_CSC_INTR_IRQ_VALIDMASK 0xDEB8 /* 1101 1110 1011 1000 */ - -/* I/O registers */ - -#define PCIC_IO_WINS 2 - -#define PCIC_IOCTL 0x07 /* RW */ -#define PCIC_IOCTL_IO1_WAITSTATE 0x80 -#define PCIC_IOCTL_IO1_ZEROWAIT 0x40 -#define PCIC_IOCTL_IO1_IOCS16SRC_MASK 0x20 -#define PCIC_IOCTL_IO1_IOCS16SRC_CARD 0x20 -#define PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE 0x00 -#define PCIC_IOCTL_IO1_DATASIZE_MASK 0x10 -#define PCIC_IOCTL_IO1_DATASIZE_16BIT 0x10 -#define PCIC_IOCTL_IO1_DATASIZE_8BIT 0x00 -#define PCIC_IOCTL_IO0_WAITSTATE 0x08 -#define PCIC_IOCTL_IO0_ZEROWAIT 0x04 -#define PCIC_IOCTL_IO0_IOCS16SRC_MASK 0x02 -#define PCIC_IOCTL_IO0_IOCS16SRC_CARD 0x02 -#define PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE 0x00 -#define PCIC_IOCTL_IO0_DATASIZE_MASK 0x01 -#define PCIC_IOCTL_IO0_DATASIZE_16BIT 0x01 -#define PCIC_IOCTL_IO0_DATASIZE_8BIT 0x00 - -#define PCIC_IOADDR0_START_LSB 0x08 -#define PCIC_IOADDR0_START_MSB 0x09 -#define PCIC_IOADDR0_STOP_LSB 0x0A -#define PCIC_IOADDR0_STOP_MSB 0x0B -#define PCIC_IOADDR1_START_LSB 0x0C -#define PCIC_IOADDR1_START_MSB 0x0D -#define PCIC_IOADDR1_STOP_LSB 0x0E -#define PCIC_IOADDR1_STOP_MSB 0x0F - -/* memory registers */ - -/* - * memory window addresses refer to bits A23-A12 of the ISA system memory - * address. This is a shift of 12 bits. The LSB contains A19-A12, and the - * MSB contains A23-A20, plus some other bits. - */ - -#define PCIC_MEM_WINS 5 - -#define PCIC_MEM_SHIFT 12 -#define PCIC_MEM_PAGESIZE (1< - -#include - -struct proc; - -struct pcic_event { - STAILQ_ENTRY(pcic_event) pe_q; - int pe_type; -}; - -/* pe_type */ -#define PCIC_EVENT_INSERTION 0 -#define PCIC_EVENT_REMOVAL 1 - -struct proc; - -struct pcic_handle { - void *sc; - device_t dev; - bus_space_tag_t ph_bus_t; /* I/O or MEM? I don't mind */ - bus_space_handle_t ph_bus_h; - u_int8_t (*ph_read)(struct pcic_handle*, int); - void (*ph_write)(struct pcic_handle *, int, u_int8_t); - - int vendor; - int sock; - int flags; - int laststate; - int memalloc; - struct pccard_mem_handle mem[PCIC_MEM_WINS]; /* XXX BAD XXX */ - int ioalloc; - struct pccard_io_handle io[PCIC_IO_WINS]; /* XXX BAD XXX */ - int ih_irq; - - int shutdown; - struct proc *event_thread; - STAILQ_HEAD(, pcic_event) events; -}; - -#define PCIC_FLAG_SOCKETP 0x0001 -#define PCIC_FLAG_CARDP 0x0002 - -#define PCIC_LASTSTATE_PRESENT 0x0002 -#define PCIC_LASTSTATE_HALF 0x0001 -#define PCIC_LASTSTATE_EMPTY 0x0000 - -#define C0SA PCIC_CHIP0_BASE+PCIC_SOCKETA_INDEX -#define C0SB PCIC_CHIP0_BASE+PCIC_SOCKETB_INDEX -#define C1SA PCIC_CHIP1_BASE+PCIC_SOCKETA_INDEX -#define C1SB PCIC_CHIP1_BASE+PCIC_SOCKETB_INDEX - -/* - * This is sort of arbitrary. It merely needs to be "enough". It can be - * overridden in the conf file, anyway. - */ - -#define PCIC_MEM_PAGES 4 -#define PCIC_MEMSIZE PCIC_MEM_PAGES*PCIC_MEM_PAGESIZE - -#define PCIC_NSLOTS 4 - -struct pcic_softc { - device_t dev; - - bus_space_tag_t memt; - bus_space_handle_t memh; - bus_space_tag_t iot; - bus_space_handle_t ioh; - - void *intrhand; - struct resource *irq_res; - int irq_rid; - struct resource *mem_res; - int mem_rid; - struct resource *port_res; - int port_rid; - -#define PCIC_MAX_MEM_PAGES (8 * sizeof(int)) - - /* used by memory window mapping functions */ - bus_addr_t membase; - - /* - * used by io window mapping functions. These can actually overlap - * with another pcic, since the underlying extent mapper will deal - * with individual allocations. This is here to deal with the fact - * that different busses have different real widths (different pc - * hardware seems to use 10 or 12 bits for the I/O bus). - */ - bus_addr_t iobase; - bus_addr_t iosize; - - int irq; - void *ih; - - struct pcic_handle handle[PCIC_NSLOTS]; -}; - - -int pcic_ident_ok(int); -int pcic_vendor(struct pcic_handle *); -char *pcic_vendor_to_string(int); - -int pcic_attach(device_t dev); - -#define pcic_read(h, idx) (*(h)->ph_read)((h), (idx)) -#define pcic_write(h, idx, data) (*(h)->ph_write)((h), (idx), (data)) - -/* - * bus/device/etc routines - */ -int pcic_activate_resource(device_t dev, device_t child, int type, int rid, - struct resource *r); -struct resource *pcic_alloc_resource(device_t dev, device_t child, int type, - int *rid, u_long start, u_long end, u_long count, u_int flags); -void pcic_deactivate(device_t dev); -int pcic_deactivate_resource(device_t dev, device_t child, int type, int rid, - struct resource *r); -int pcic_detach(device_t dev); -int pcic_release_resource(device_t dev, device_t child, int type, int rid, - struct resource *r); -int pcic_setup_intr(device_t dev, device_t child, struct resource *irq, - int flags, driver_intr_t intr, void *arg, void **cookiep); -int pcic_teardown_intr(device_t dev, device_t child, struct resource *irq, - void *cookiep); -int pcic_suspend(device_t dev); -int pcic_resume(device_t dev); -int pcic_enable_socket(device_t dev, device_t child); -int pcic_disable_socket(device_t dev, device_t child); -int pcic_set_res_flags(device_t dev, device_t child, int type, int rid, - u_int32_t flags); -int pcic_set_memory_offset(device_t dev, device_t child, int rid, - u_int32_t offset, u_int32_t *deltap); - -#define PCIC_SOFTC(d) (struct pcic_softc *) device_get_softc(d)