summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2005-09-25 21:29:32 +0000
committerimp <imp@FreeBSD.org>2005-09-25 21:29:32 +0000
commitadd8494ccf5a9aa94810202202861f80378b7d2e (patch)
tree58cc7567434699af9d901ac0a0ab8c262f3b1f22
parent7844c3547462f26592f7a7a3a00ee89693fa5862 (diff)
downloadFreeBSD-src-add8494ccf5a9aa94810202202861f80378b7d2e.zip
FreeBSD-src-add8494ccf5a9aa94810202202861f80378b7d2e.tar.gz
Remove the kernel portion of OLDCARD. I'm working on a replacement
for pccardc dumpcis, but until I'm done with that, I'm leaving pccardc in place. As such, I'm leaving the .h files in place for the moment.
-rw-r--r--sys/pccard/mecia.c767
-rw-r--r--sys/pccard/pccard.c731
-rw-r--r--sys/pccard/pccard_beep.c138
-rw-r--r--sys/pccard/pccard_nbk.c436
-rw-r--r--sys/pccard/pcic.c1344
-rw-r--r--sys/pccard/pcic_isa.c399
-rw-r--r--sys/pccard/pcic_pci.c1586
7 files changed, 0 insertions, 5401 deletions
diff --git a/sys/pccard/mecia.c b/sys/pccard/mecia.c
deleted file mode 100644
index ce0b756..0000000
--- a/sys/pccard/mecia.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * NEC MECIA controller.
- *-------------------------------------------------------------------------
- */
-/*-
- * Copyright (c) 2001 M. Warner Losh. 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.
- *
- * 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.
- *
- * $FreeBSD$
- *
- * Based heavily on the FreeBSD pcic driver's pcic98 support, derived
- * from PAO3 tree. This copyright notice likely needs modification for
- * such a linage. The only authorship I could find was:
- *
- * PC9801 original PCMCIA controller code for NS/A,Ne,NX/C,NR/L.
- * by Noriyuki Hosobuchi <hoso@ce.mbn.or.jp>
- */
-
-#include <sys/param.h>
-#include <sys/bus.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-
-#include <pccard/meciareg.h>
-#include <pccard/cardinfo.h>
-#include <pccard/slot.h>
-#ifndef MECIA_IOBASE
-#define MECIA_IOBASE 0x80d0
-#endif
-
-/* Get pnp IDs */
-#include <isa/isavar.h>
-
-#include <dev/pccard/pccardvar.h>
-#include "card_if.h"
-
-#define MECIA_DEVICE2SOFTC(dev) ((struct mecia_slot *) device_get_softc(dev))
-
-/*
- * Prototypes for interrupt handler.
- */
-static driver_intr_t meciaintr;
-static int mecia_ioctl(struct slot *, int, caddr_t);
-static int mecia_power(struct slot *);
-static void mecia_mapirq(struct slot *, int);
-static timeout_t mecia_reset;
-static void mecia_resume(struct slot *);
-static void mecia_disable(struct slot *);
-static timeout_t meciatimeout;
-static struct callout_handle meciatimeout_ch
- = CALLOUT_HANDLE_INITIALIZER(&meciatimeout_ch);
-static int mecia_memory(struct slot *, int);
-static int mecia_io(struct slot *, int);
-
-/*
- * Per-slot data table.
- */
-struct mecia_slot {
- int unit; /* Unit number */
- int slotnum; /* My slot number */
- struct slot *slt; /* Back ptr to slot */
- device_t dev; /* My device */
- u_char last_reg1; /* Last value of change reg */
-};
-
-static struct slot_ctrl mecia_cinfo = {
- mecia_mapirq,
- mecia_memory,
- mecia_io,
- mecia_reset,
- mecia_disable,
- mecia_power,
- mecia_ioctl,
- mecia_resume,
- 1,
-#if 0
- 1
-#else
- 2 /* Fake for UE2212 LAN card */
-#endif
-};
-
-static int validunits = 0;
-
-/*
- * Look for an NEC MECIA.
- * For each available slot, allocate a PC-CARD slot.
- */
-
-static int
-mecia_probe(device_t dev)
-{
- int validslots = 0;
-
- /* Check isapnp ids */
- if (isa_get_logicalid(dev)) /* skip PnP probes */
- return (ENXIO);
-
- if (inb(MECIA_REG0) != 0xff) {
- validslots++;
- /* XXX need to allocated the port resources */
- device_set_desc(dev, "MECIA PC98 Original PCMCIA Controller");
- }
- return (validslots ? 0 : ENXIO);
-}
-
-static int
-mecia_attach(device_t dev)
-{
- int error;
- int irq;
- void *ih;
- device_t kid;
- struct resource *r;
- int rid;
- struct slot *slt;
- struct mecia_slot *sp;
-
- sp = MECIA_DEVICE2SOFTC(dev);
- sp->unit = validunits++;
- kid = device_add_child(dev, NULL, -1);
- if (kid == NULL) {
- device_printf(dev, "Can't add pccard bus slot 0\n");
- return (ENXIO);
- }
- device_probe_and_attach(kid);
- slt = pccard_init_slot(kid, &mecia_cinfo);
- if (slt == 0) {
- device_printf(dev, "Can't get pccard info slot 0\n");
- return (ENXIO);
- }
- slt->cdata = sp;
- sp->slt = slt;
- validunits++;
-
- rid = 0;
- r = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
- if (!r)
- return (ENXIO);
-
- irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0);
- if (irq == 0) {
- /* See if the user has requested a specific IRQ */
- if (!getenv_int("machdep.pccard.mecia_irq", &irq))
- irq = 0;
- }
- rid = 0;
- r = 0;
- if (irq > 0) {
- r = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq,
- irq, 1, RF_ACTIVE);
- }
- if (r && ((1 << (rman_get_start(r))) & MECIA_INT_MASK_ALLOWED) == 0) {
- device_printf(dev,
- "Hardware does not support irq %d, trying polling.\n",
- irq);
- bus_release_resource(dev, SYS_RES_IRQ, rid, r);
- r = 0;
- irq = 0;
- }
- if (r) {
- error = bus_setup_intr(dev, r, INTR_TYPE_MISC,
- meciaintr, (void *) sp, &ih);
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, rid, r);
- return (error);
- }
- irq = rman_get_start(r);
- device_printf(dev, "management irq %d\n", irq);
- } else {
- irq = 0;
- }
- if (irq == 0) {
- meciatimeout_ch = timeout(meciatimeout, (void *) sp, hz/2);
- device_printf(dev, "Polling mode\n");
- }
-
- sp->last_reg1 = inb(MECIA_REG1);
- if (sp->last_reg1 & MECIA_CARDEXIST) {
- /* PCMCIA card exist */
- sp->slt->laststate = sp->slt->state = filled;
- pccard_event(sp->slt, card_inserted);
- } else {
- sp->slt->laststate = sp->slt->state = empty;
- }
- sp->slt->irq = irq;
-
- return (bus_generic_attach(dev));
-}
-
-static int
-mecia_sresource(struct slot *slt, caddr_t data)
-{
- struct pccard_resource *pr;
- struct resource *r;
- int flags;
- int rid = 0;
- device_t pccarddev = slt->dev;
-
- pr = (struct pccard_resource *)data;
- pr->resource_addr = ~0ul;
- switch(pr->type) {
- default:
- return (EINVAL);
- case SYS_RES_MEMORY:
- case SYS_RES_IRQ:
- case SYS_RES_IOPORT:
- break;
- }
- flags = rman_make_alignment_flags(pr->size);
- r = bus_alloc_resource(pccarddev, pr->type, &rid, pr->min, pr->max,
- pr->size, flags);
- if (r != NULL) {
- pr->resource_addr = (u_long)rman_get_start(r);
- bus_release_resource(bridgedev, pr->type, rid, r);
- }
- return (0);
-}
-
-/*
- * ioctl calls - Controller specific ioctls
- */
-static int
-mecia_ioctl(struct slot *slt, int cmd, caddr_t data)
-{
- switch(cmd) {
- default:
- return (ENOTTY);
- case PIOCSRESOURCE: /* Can I use this resource? */
- mecia_sresource(slt, data);
- break;
- }
- return (0);
-}
-
-/*
- * MECIA timer. If the controller doesn't have a free IRQ to use
- * or if interrupt steering doesn't work, poll the controller for
- * insertion/removal events.
- */
-static void
-meciatimeout(void *chan)
-{
- meciaintr(chan);
- meciatimeout_ch = timeout(meciatimeout, chan, hz/2);
-}
-
-/*
- * MECIA Interrupt handler.
- * Check the slot and report any changes.
- */
-static void
-meciaintr(void *arg)
-{
- u_char reg1;
- int s;
- struct mecia_slot *sp = (struct mecia_slot *) arg;
-
- s = splhigh();
- /* Check for a card in this slot */
- reg1 = inb(MECIA_REG1);
- if ((sp->last_reg1 ^ reg1) & MECIA_CARDEXIST) {
- sp->last_reg1 = reg1;
- if (reg1 & MECIA_CARDEXIST)
- pccard_event(sp->slt, card_inserted);
- else
- pccard_event(sp->slt, card_removed);
- }
- splx(s);
-}
-
-/*
- * local functions for PC-98 Original PC-Card controller
- */
-#define MECIA_ALWAYS_128MAPPING 1 /* trick for using UE2212 */
-
-int mecia_mode = 0; /* almost the same as the value in MECIA_REG2 */
-
-static unsigned char reg_winsel = MECIA_UNMAPWIN;
-static unsigned short reg_pagofs = 0;
-
-static int
-mecia_memory(struct slot *slt, int win)
-{
- struct mem_desc *mp = &slt->mem[win];
- unsigned char x;
-
- if (mp->flags & MDF_ACTIVE) {
- /* slot = 0, window = 0, sys_addr = 0xda000, length = 8KB */
- if ((unsigned long)mp->start != 0xda000) {
- printf(
- "sys_addr must be 0xda000. requested address = %p\n",
- mp->start);
- return (EINVAL);
- }
-
- /* omajinai ??? */
- outb(MECIA_REG0, 0);
- x = inb(MECIA_REG1);
- x &= 0xfc;
- x |= 0x02;
- outb(MECIA_REG1, x);
- reg_winsel = inb(MECIA_REG_WINSEL);
- reg_pagofs = inw(MECIA_REG_PAGOFS);
- outb(MECIA_REG_WINSEL, MECIA_MAPWIN);
- outw(MECIA_REG_PAGOFS, (mp->card >> 13)); /* 8KB */
-
- if (mp->flags & MDF_ATTR)
- outb(MECIA_REG7, inb(MECIA_REG7) | MECIA_ATTRMEM);
- else
- outb(MECIA_REG7, inb(MECIA_REG7) & (~MECIA_ATTRMEM));
-
- outb(MECIA_REG_WINSEL, MECIA_MAPWIN);
-#if 0
- if ((mp->flags & MDF_16BITS) == 1) /* 16bit */
- outb(MECIA_REG2, inb(MECIA_REG2) & (~MECIA_8BIT));
- else /* 8bit */
- outb(MECIA_REG2, inb(MECIA_REG2) | MECIA_8BIT);
-#endif
- } else { /* !(mp->flags & MDF_ACTIVE) */
- outb(MECIA_REG0, 0);
- x = inb(MECIA_REG1);
- x &= 0xfc;
- x |= 0x02;
- outb(MECIA_REG1, x);
-#if 0
- outb(MECIA_REG_WINSEL, MECIA_UNMAPWIN);
- outw(MECIA_REG_PAGOFS, 0);
-#else
- outb(MECIA_REG_WINSEL, reg_winsel);
- outw(MECIA_REG_PAGOFS, reg_pagofs);
-#endif
- }
- return (0);
-}
-
-static int
-mecia_io(struct slot *slt, int win)
-{
- struct io_desc *ip = &slt->io[win];
- unsigned char x;
- unsigned short cardbase;
- u_short ofst;
-
- if (win != 0) {
- /* ignore for UE2212 */
- printf(
- "mecia:Illegal MECIA I/O window(%d) request! Ignored.\n", win);
-/* return (EINVAL);*/
- return (0);
- }
-
- if (ip->flags & IODF_ACTIVE) {
- x = inb(MECIA_REG2) & 0x0f;
-#if 0
- if (! (ip->flags & IODF_CS16))
- x |= MECIA_8BIT;
-#else
- if (! (ip->flags & IODF_16BIT)) {
- x |= MECIA_8BIT;
- mecia_mode |= MECIA_8BIT;
- }
-#endif
-
- ofst = ip->start & 0xf;
- cardbase = ip->start & ~0xf;
-#ifndef MECIA_ALWAYS_128MAPPING
- if (ip->size + ofst > 16)
-#endif
- { /* 128bytes mapping */
- x |= MECIA_MAP128;
- mecia_mode |= MECIA_MAP128;
- ofst |= ((cardbase & 0x70) << 4);
- cardbase &= ~0x70;
- }
-
- x |= MECIA_MAPIO;
- outb(MECIA_REG2, x);
-
- outw(MECIA_REG4, MECIA_IOBASE); /* 98side I/O base */
- outw(MECIA_REG5, cardbase); /* card side I/O base */
-
- if (bootverbose) {
- printf("mecia: I/O mapped 0x%04x(98) -> "
- "0x%04x(Card) and width %d bytes\n",
- MECIA_IOBASE+ofst, ip->start, ip->size);
- printf("mecia: reg2=0x%02x reg3=0x%02x reg7=0x%02x\n",
- inb(MECIA_REG2), inb(MECIA_REG3),
- inb(MECIA_REG7));
- printf("mecia: mode=%d\n", mecia_mode);
- }
-
- ip->start = MECIA_IOBASE + ofst;
- } else {
- outb(MECIA_REG2, inb(MECIA_REG2) & (~MECIA_MAPIO));
- mecia_mode = 0;
- }
- return (0);
-}
-
-static int
-mecia_power(struct slot *slt)
-{
- unsigned char reg;
-
- reg = inb(MECIA_REG7) & (~MECIA_VPP12V);
- switch(slt->pwr.vpp) {
- default:
- return (EINVAL);
- case 50:
- break;
- case 120:
- reg |= MECIA_VPP12V;
- break;
- }
- outb(MECIA_REG7, reg);
- DELAY(100*1000);
-
- reg = inb(MECIA_REG2) & (~MECIA_VCC3P3V);
- switch(slt->pwr.vcc) {
- default:
- return (EINVAL);
- case 33:
- reg |= MECIA_VCC3P3V;
- break;
- case 50:
- break;
- }
- outb(MECIA_REG2, reg);
- DELAY(100*1000);
- return (0);
-}
-
-static void
-mecia_mapirq(struct slot *slt, int irq)
-{
- u_char x;
-
- switch (irq) {
- case 3:
- x = MECIA_INT0;
- break;
- case 5:
- x = MECIA_INT1;
- break;
- case 6:
- x = MECIA_INT2;
- break;
- case 10:
- x = MECIA_INT4;
- break;
- case 12:
- x = MECIA_INT5;
- break;
- case 0: /* disable */
- x = MECIA_INTDISABLE;
- break;
- default:
- printf("mecia: illegal irq %d\n", irq);
- return;
- }
-#ifdef MECIA_DEBUG
- printf("mecia: irq=%d mapped.\n", irq);
-#endif
- outb(MECIA_REG3, x);
-}
-
-static void
-mecia_reset(void *chan)
-{
- struct slot *slt = chan;
-
- outb(MECIA_REG0, 0);
- outb(MECIA_REG2, inb(MECIA_REG2) & (~MECIA_MAPIO));
- outb(MECIA_REG3, MECIA_INTDISABLE);
-#if 0
-/* mecia_reset() is called after mecia_power() */
- outb(MECIA_REG2, inb(MECIA_REG2) & (~MECIA_VCC3P3V));
- outb(MECIA_REG7, inb(MECIA_REG7) & (~MECIA_VPP12V));
-#endif
- outb(MECIA_REG1, 0);
-
- selwakeuppri(&slt->selp, PZERO);
-}
-
-static void
-mecia_disable(struct slot *slt)
-{
- /* null function */
-}
-
-static void
-mecia_resume(struct slot *slt)
-{
- /* XXX MECIA How ? */
-}
-
-static int
-mecia_activate_resource(device_t dev, device_t child, int type, int rid,
- struct resource *r)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- int err;
-
- if (dev != device_get_parent(device_get_parent(child)) || devi == NULL)
- return (bus_generic_activate_resource(dev, child, type,
- rid, r));
-
- switch (type) {
- case SYS_RES_IOPORT: {
- struct io_desc *ip;
- ip = &devi->slt->io[rid];
- if (ip->flags == 0) {
- if (rid == 0)
- ip->flags = IODF_WS | IODF_16BIT | IODF_CS16;
- else
- ip->flags = devi->slt->io[0].flags;
- }
- ip->flags |= IODF_ACTIVE;
- ip->start = rman_get_start(r);
- ip->size = rman_get_end(r) - rman_get_start(r) + 1;
- err = mecia_cinfo.mapio(devi->slt, rid);
- if (err)
- return (err);
- break;
- }
- case SYS_RES_IRQ:
- /*
- * We actually defer the activation of the IRQ resource
- * until the interrupt is registered to avoid stray
- * interrupt messages.
- */
- break;
- case SYS_RES_MEMORY: {
- struct mem_desc *mp;
- if (rid >= NUM_MEM_WINDOWS)
- return (EINVAL);
- mp = &devi->slt->mem[rid];
- mp->flags |= MDF_ACTIVE;
- mp->start = (caddr_t) rman_get_start(r);
- mp->size = rman_get_end(r) - rman_get_start(r) + 1;
- err = mecia_cinfo.mapmem(devi->slt, rid);
- if (err)
- return (err);
- break;
- }
- default:
- break;
- }
- err = bus_generic_activate_resource(dev, child, type, rid, r);
- return (err);
-}
-
-static int
-mecia_deactivate_resource(device_t dev, device_t child, int type, int rid,
- struct resource *r)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- int err;
-
- if (dev != device_get_parent(device_get_parent(child)) || devi == NULL)
- return (bus_generic_deactivate_resource(dev, child, type,
- rid, r));
-
- switch (type) {
- case SYS_RES_IOPORT: {
- struct io_desc *ip = &devi->slt->io[rid];
- ip->flags &= ~IODF_ACTIVE;
- err = mecia_cinfo.mapio(devi->slt, rid);
- if (err)
- return (err);
- break;
- }
- case SYS_RES_IRQ:
- break;
- case SYS_RES_MEMORY: {
- struct mem_desc *mp = &devi->slt->mem[rid];
- mp->flags &= ~(MDF_ACTIVE | MDF_ATTR);
- err = mecia_cinfo.mapmem(devi->slt, rid);
- if (err)
- return (err);
- break;
- }
- default:
- break;
- }
- err = bus_generic_deactivate_resource(dev, child, type, rid, r);
- return (err);
-}
-
-static int
-mecia_setup_intr(device_t dev, device_t child, struct resource *irq,
- int flags, driver_intr_t *intr, void *arg, void **cookiep)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- int err;
-
- if (((1 << rman_get_start(irq)) & MECIA_INT_MASK_ALLOWED) == 0) {
- device_printf(dev, "Hardware does not support irq %ld.\n",
- rman_get_start(irq));
- return (EINVAL);
- }
-
- err = bus_generic_setup_intr(dev, child, irq, flags, intr, arg,
- cookiep);
- if (err == 0)
- mecia_cinfo.mapirq(devi->slt, rman_get_start(irq));
- else
- device_printf(dev, "Error %d irq %ld\n", err,
- rman_get_start(irq));
- return (err);
-}
-
-static int
-mecia_teardown_intr(device_t dev, device_t child, struct resource *irq,
- void *cookie)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
-
- mecia_cinfo.mapirq(devi->slt, 0);
- return (bus_generic_teardown_intr(dev, child, irq, cookie));
-}
-
-static int
-mecia_set_res_flags(device_t bus, device_t child, int restype, int rid,
- u_long value)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- int err = 0;
-
- switch (restype) {
- case SYS_RES_MEMORY: {
- struct mem_desc *mp = &devi->slt->mem[rid];
- switch (value) {
- case PCCARD_A_MEM_COM:
- mp->flags &= ~MDF_ATTR;
- break;
- case PCCARD_A_MEM_ATTR:
- mp->flags |= MDF_ATTR;
- break;
- case PCCARD_A_MEM_8BIT:
- mp->flags &= ~MDF_16BITS;
- break;
- case PCCARD_A_MEM_16BIT:
- mp->flags |= MDF_16BITS;
- break;
- }
- err = mecia_cinfo.mapmem(devi->slt, rid);
- break;
- }
- default:
- err = EOPNOTSUPP;
- }
- return (err);
-}
-
-static int
-mecia_get_res_flags(device_t bus, device_t child, int restype, int rid,
- u_long *value)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- int err = 0;
-
- if (value == 0)
- return (ENOMEM);
-
- switch (restype) {
- case SYS_RES_IOPORT: {
- struct io_desc *ip = &devi->slt->io[rid];
- *value = ip->flags;
- break;
- }
- case SYS_RES_MEMORY: {
- struct mem_desc *mp = &devi->slt->mem[rid];
- *value = mp->flags;
- break;
- }
- default:
- err = EOPNOTSUPP;
- }
- return (err);
-}
-
-static int
-mecia_set_memory_offset(device_t bus, device_t child, int rid,
- u_int32_t offset, u_int32_t *deltap)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- struct mem_desc *mp = &devi->slt->mem[rid];
-
- mp->card = offset;
- if (deltap)
- *deltap = 0; /* XXX BAD XXX */
- return (mecia_cinfo.mapmem(devi->slt, rid));
-}
-
-static int
-mecia_get_memory_offset(device_t bus, device_t child, int rid,
- u_int32_t *offset)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- struct mem_desc *mp = &devi->slt->mem[rid];
-
- if (offset == 0)
- return (ENOMEM);
-
- *offset = mp->card;
-
- return (0);
-}
-
-static device_method_t mecia_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, mecia_probe),
- DEVMETHOD(device_attach, mecia_attach),
- DEVMETHOD(device_detach, bus_generic_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_release_resource),
- DEVMETHOD(bus_activate_resource, mecia_activate_resource),
- DEVMETHOD(bus_deactivate_resource, mecia_deactivate_resource),
- DEVMETHOD(bus_setup_intr, mecia_setup_intr),
- DEVMETHOD(bus_teardown_intr, mecia_teardown_intr),
-
- /* Card interface */
- DEVMETHOD(card_set_res_flags, mecia_set_res_flags),
- DEVMETHOD(card_get_res_flags, mecia_get_res_flags),
- DEVMETHOD(card_set_memory_offset, mecia_set_memory_offset),
- DEVMETHOD(card_get_memory_offset, mecia_get_memory_offset),
-
- { 0, 0 }
-};
-
-devclass_t mecia_devclass;
-
-static driver_t mecia_driver = {
- "mecia",
- mecia_methods,
- sizeof(struct mecia_slot)
-};
-
-DRIVER_MODULE(mecia, isa, mecia_driver, mecia_devclass, 0, 0);
diff --git a/sys/pccard/pccard.c b/sys/pccard/pccard.c
deleted file mode 100644
index b8ebea9..0000000
--- a/sys/pccard/pccard.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * pccard.c - Interface code for PC-CARD controllers.
- *
- * June 1995, Andrew McRae (andrew@mega.com.au)
- *-------------------------------------------------------------------------
- */
-/*-
- * Copyright (c) 2001 M. Warner Losh. All rights reserved.
- * Copyright (c) 1995 Andrew McRae. 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. 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.
- *
- * $FreeBSD$
- */
-
-#define OBSOLETE_IN_6
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/sysctl.h>
-#include <sys/conf.h>
-#include <sys/uio.h>
-#include <sys/poll.h>
-#include <sys/bus.h>
-#include <sys/proc.h>
-#include <machine/bus.h>
-
-#include <pccard/cardinfo.h>
-#include <pccard/driver.h>
-#include <pccard/slot.h>
-#include <pccard/pccard_nbk.h>
-
-#include <machine/md_var.h>
-
-static int allocate_driver(struct slot *, struct dev_desc *);
-static void inserted(void *);
-static void disable_slot(struct slot *);
-static void disable_slot_to(struct slot *);
-static void power_off_slot(void *);
-
-/*
- * The driver interface for read/write uses a block
- * of memory in the ISA I/O memory space allocated via
- * an ioctl setting.
- *
- * Now that we have different bus attachments, we should really
- * use a better algorythm to allocate memory.
- */
-static unsigned long pccard_mem; /* Physical memory */
-static unsigned char *pccard_kmem; /* Kernel virtual address */
-static struct resource *pccard_mem_res;
-static int pccard_mem_rid;
-
-static d_open_t crdopen;
-static d_close_t crdclose;
-static d_read_t crdread;
-static d_write_t crdwrite;
-static d_ioctl_t crdioctl;
-static d_poll_t crdpoll;
-
-static struct cdevsw crd_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = crdopen,
- .d_close = crdclose,
- .d_read = crdread,
- .d_write = crdwrite,
- .d_ioctl = crdioctl,
- .d_poll = crdpoll,
- .d_name = "crd",
-};
-
-/*
- * Power off the slot.
- * (doing it immediately makes the removal of some cards unstable)
- */
-static void
-power_off_slot(void *arg)
-{
- struct slot *slt = (struct slot *)arg;
- int s;
-
- /*
- * The following will generate an interrupt. So, to hold off
- * the interrupt unitl after disable runs so that we can get rid
- * rid of the interrupt before it becomes unsafe to touch the
- * device.
- *
- * XXX In current, the spl stuff is a nop.
- */
- s = splhigh();
- /* Power off the slot. */
- slt->pwr_off_pending = 0;
- slt->ctrl->disable(slt);
- splx(s);
-}
-
-/*
- * disable_slot - Disables the slot by removing
- * the power and unmapping the I/O
- */
-static void
-disable_slot(struct slot *slt)
-{
- device_t pccarddev;
- device_t *kids;
- int nkids;
- int i;
- int ret;
-
- /*
- * Note that a race condition is possible here; if a
- * driver is accessing the device and it is removed, then
- * all bets are off...
- */
- pccarddev = slt->dev;
- device_get_children(pccarddev, &kids, &nkids);
- for (i = 0; i < nkids; i++) {
- if ((ret = device_delete_child(pccarddev, kids[i])) != 0)
- printf("pccard: delete of %s failed: %d\n",
- device_get_nameunit(kids[i]), ret);
- }
- free(kids, M_TEMP);
-
- /* Power off the slot 1/2 second after removal of the card */
- slt->poff_ch = timeout(power_off_slot, (caddr_t)slt, hz / 2);
- slt->pwr_off_pending = 1;
-}
-
-static void
-disable_slot_to(struct slot *slt)
-{
- disable_slot(slt);
- if (slt->state == empty)
- printf("pccard: card removed, slot %d\n", slt->slotnum);
- else
- printf("pccard: card deactivated, slot %d\n", slt->slotnum);
- pccard_remove_beep();
- selwakeuppri(&slt->selp, PZERO);
-}
-
-/*
- * pccard_init_slot - Initialize the slot controller and attach various
- * things to it. We also make the device for it. We create the device that
- * will be exported to devfs.
- */
-struct slot *
-pccard_init_slot(device_t dev, struct slot_ctrl *ctrl)
-{
- int slotno;
- struct slot *slt;
-
- slt = PCCARD_DEVICE2SOFTC(dev);
- slotno = device_get_unit(dev);
- slt->dev = dev;
- slt->d = make_dev(&crd_cdevsw, slotno, 0, 0, 0600, "card%d", slotno);
- slt->d->si_drv1 = slt;
- slt->ctrl = ctrl;
- slt->slotnum = slotno;
- callout_handle_init(&slt->insert_ch);
- callout_handle_init(&slt->poff_ch);
-
- return (slt);
-}
-
-/*
- * allocate_driver - Create a new device entry for this
- * slot, and attach a driver to it.
- */
-static int
-allocate_driver(struct slot *slt, struct dev_desc *desc)
-{
- struct pccard_devinfo *devi;
- device_t pccarddev;
- int err, irq = 0;
- device_t child;
- device_t *devs;
- int count;
-
- pccarddev = slt->dev;
- err = device_get_children(pccarddev, &devs, &count);
- if (err != 0)
- return (err);
- free(devs, M_TEMP);
- if (count) {
- device_printf(pccarddev,
- "Can not attach more than one child.\n");
- return (EIO);
- }
- irq = ffs(desc->irqmask) - 1;
- MALLOC(devi, struct pccard_devinfo *, sizeof(*devi), M_DEVBUF,
- M_WAITOK | M_ZERO);
- strcpy(devi->name, desc->name);
- /*
- * Create an entry for the device under this slot.
- */
- devi->running = 1;
- devi->slt = slt;
- bcopy(desc->misc, devi->misc, sizeof(desc->misc));
- strcpy(devi->manufstr, desc->manufstr);
- strcpy(devi->versstr, desc->versstr);
- strcpy(devi->cis3str, desc->cis3str);
- strcpy(devi->cis4str, desc->cis4str);
- devi->manufacturer = desc->manufacturer;
- devi->product = desc->product;
- devi->prodext = desc->prodext;
- resource_list_init(&devi->resources);
- child = device_add_child(pccarddev, devi->name, desc->unit);
- if (child == NULL) {
- if (desc->unit != -1)
- device_printf(pccarddev,
- "Unit %d failed for %s, try a different unit\n",
- desc->unit, devi->name);
- else
- device_printf(pccarddev,
- "No units available for %s. Impossible?\n",
- devi->name);
- return (EIO);
- }
- device_set_flags(child, desc->flags);
- device_set_ivars(child, devi);
- if (bootverbose) {
- device_printf(pccarddev, "Assigning %s:",
- device_get_nameunit(child));
- if (desc->iobase)
- printf(" io 0x%x-0x%x",
- desc->iobase, desc->iobase + desc->iosize - 1);
- if (irq)
- printf(" irq %d", irq);
- if (desc->mem)
- printf(" mem 0x%lx-0x%lx", desc->mem,
- desc->mem + desc->memsize - 1);
- printf(" flags 0x%x\n", desc->flags);
- }
- err = bus_set_resource(child, SYS_RES_IOPORT, 0, desc->iobase,
- desc->iosize);
- if (err)
- goto err;
- if (irq)
- err = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
- if (err)
- goto err;
- if (desc->memsize) {
- err = bus_set_resource(child, SYS_RES_MEMORY, 0, desc->mem,
- desc->memsize);
- if (err)
- goto err;
- }
- err = device_probe_and_attach(child);
- /*
- * XXX We unwisely assume that the detach code won't run while the
- * XXX the attach code is attaching. Someone should put some
- * XXX interlock code. This can happen if probe/attach takes a while
- * XXX and the user ejects the card, which causes the detach
- * XXX function to be called.
- */
- strncpy(desc->name, device_get_nameunit(child), sizeof(desc->name));
- desc->name[sizeof(desc->name) - 1] = '\0';
-err:
- if (err)
- device_delete_child(pccarddev, child);
- return (err);
-}
-
-/*
- * card insert routine - Called from a timeout to debounce
- * insertion events.
- */
-static void
-inserted(void *arg)
-{
- struct slot *slt = arg;
-
- slt->state = filled;
- /*
- * Disable any pending timeouts for this slot, and explicitly
- * power it off right now. Then, re-enable the power using
- * the (possibly new) power settings.
- */
- untimeout(power_off_slot, (caddr_t)slt, slt->poff_ch);
- power_off_slot(slt);
-
- /*
- * Enable 5V to the card so that the CIS can be read. Well,
- * enable the most natural voltage so that the CIS can be read.
- */
- slt->pwr.vcc = -1;
- slt->pwr.vpp = -1;
- slt->ctrl->power(slt);
-
- printf("pccard: card inserted, slot %d\n", slt->slotnum);
- pccard_insert_beep();
- slt->ctrl->reset(slt);
-}
-
-/*
- * Card event callback. Called at splhigh to prevent
- * device interrupts from interceding.
- */
-void
-pccard_event(struct slot *slt, enum card_event event)
-{
- if (slt->insert_seq) {
- slt->insert_seq = 0;
- untimeout(inserted, (void *)slt, slt->insert_ch);
- }
-
- switch(event) {
- case card_removed:
- case card_deactivated:
- if (slt->state == filled || slt->state == inactive) {
- if (event == card_removed)
- slt->state = empty;
- else
- slt->state = inactive;
- disable_slot_to(slt);
- }
- break;
- case card_inserted:
- slt->insert_seq = 1;
- slt->insert_ch = timeout(inserted, (void *)slt, hz/4);
- break;
- }
-}
-
-/*
- * Device driver interface.
- */
-static int
-crdopen(struct cdev *dev, int oflags, int devtype, d_thread_t *td)
-{
- struct slot *slt = PCCARD_DEV2SOFTC(dev);
-
- if (slt == NULL)
- return (ENXIO);
- if (slt->rwmem == 0)
- slt->rwmem = MDF_ATTR;
- return (0);
-}
-
-/*
- * Close doesn't de-allocate any resources, since
- * slots may be assigned to drivers already.
- */
-static int
-crdclose(struct cdev *dev, int fflag, int devtype, d_thread_t *td)
-{
- return (0);
-}
-
-/*
- * read interface. Map memory at lseek offset,
- * then transfer to user space.
- */
-static int
-crdread(struct cdev *dev, struct uio *uio, int ioflag)
-{
- struct slot *slt = PCCARD_DEV2SOFTC(dev);
- struct mem_desc *mp, oldmap;
- unsigned char *p;
- unsigned int offs;
- int error = 0, win, count;
-
- if (slt == 0 || slt->state != filled)
- return (ENXIO);
- if (pccard_mem == 0)
- return (ENOMEM);
- for (win = slt->ctrl->maxmem - 1; win >= 0; win--)
- if ((slt->mem[win].flags & MDF_ACTIVE) == 0)
- break;
- if (win < 0)
- return (EBUSY);
- mp = &slt->mem[win];
- oldmap = *mp;
- mp->flags = slt->rwmem | MDF_ACTIVE;
- while (uio->uio_resid && error == 0) {
- mp->card = uio->uio_offset;
- mp->size = PCCARD_MEMSIZE;
- mp->start = (caddr_t)(void *)(uintptr_t)pccard_mem;
- if ((error = slt->ctrl->mapmem(slt, win)) != 0)
- break;
- offs = (unsigned int)uio->uio_offset & (PCCARD_MEMSIZE - 1);
- p = pccard_kmem + offs;
- count = MIN(PCCARD_MEMSIZE - offs, uio->uio_resid);
- error = uiomove(p, count, uio);
- }
- /*
- * Restore original map.
- */
- *mp = oldmap;
- slt->ctrl->mapmem(slt, win);
-
- return (error);
-}
-
-/*
- * crdwrite - Write data to card memory.
- * Handles wrap around so that only one memory
- * window is used.
- */
-static int
-crdwrite(struct cdev *dev, struct uio *uio, int ioflag)
-{
- struct slot *slt = PCCARD_DEV2SOFTC(dev);
- struct mem_desc *mp, oldmap;
- unsigned char *p;
- unsigned int offs;
- int error = 0, win, count;
-
- if (slt == 0 || slt->state != filled)
- return (ENXIO);
- if (pccard_mem == 0)
- return (ENOMEM);
- for (win = slt->ctrl->maxmem - 1; win >= 0; win--)
- if ((slt->mem[win].flags & MDF_ACTIVE) == 0)
- break;
- if (win < 0)
- return (EBUSY);
- mp = &slt->mem[win];
- oldmap = *mp;
- mp->flags = slt->rwmem | MDF_ACTIVE;
- while (uio->uio_resid && error == 0) {
- mp->card = uio->uio_offset;
- mp->size = PCCARD_MEMSIZE;
- mp->start = (caddr_t)(void *)(uintptr_t)pccard_mem;
- if ((error = slt->ctrl->mapmem(slt, win)) != 0)
- break;
- offs = (unsigned int)uio->uio_offset & (PCCARD_MEMSIZE - 1);
- p = pccard_kmem + offs;
- count = MIN(PCCARD_MEMSIZE - offs, uio->uio_resid);
- error = uiomove(p, count, uio);
- }
- /*
- * Restore original map.
- */
- *mp = oldmap;
- slt->ctrl->mapmem(slt, win);
-
- return (error);
-}
-
-/*
- * ioctl calls - allows setting/getting of memory and I/O
- * descriptors, and assignment of drivers.
- */
-static int
-crdioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, d_thread_t *td)
-{
- u_int32_t addr;
- int err;
- struct io_desc *ip;
- struct mem_desc *mp;
- device_t pccarddev;
- int pwval;
- int s;
- struct slot *slt = PCCARD_DEV2SOFTC(dev);
-/*XXX*/#if __FreeBSD_version < 5000000 /* 4.x compatibility only. */
- struct dev_desc d;
- struct dev_desc_old *odp;
-/*XXX*/#endif
-
- if (slt == 0 && cmd != PIOCRWMEM)
- return (ENXIO);
- switch(cmd) {
- default:
- if (slt->ctrl->ioctl)
- return (slt->ctrl->ioctl(slt, cmd, data));
- return (ENOTTY);
- /*
- * Get slot state.
- */
- case PIOCGSTATE:
- s = splhigh();
- ((struct slotstate *)data)->state = slt->state;
- ((struct slotstate *)data)->laststate = slt->laststate;
- slt->laststate = slt->state;
- splx(s);
- ((struct slotstate *)data)->maxmem = slt->ctrl->maxmem;
- ((struct slotstate *)data)->maxio = slt->ctrl->maxio;
- ((struct slotstate *)data)->irqs = 0;
- break;
- /*
- * Get memory context.
- */
- case PIOCGMEM:
- s = ((struct mem_desc *)data)->window;
- if (s < 0 || s >= slt->ctrl->maxmem)
- return (EINVAL);
- mp = &slt->mem[s];
- ((struct mem_desc *)data)->flags = mp->flags;
- ((struct mem_desc *)data)->start = mp->start;
- ((struct mem_desc *)data)->size = mp->size;
- ((struct mem_desc *)data)->card = mp->card;
- break;
- /*
- * Set memory context. If context already active, then unmap it.
- * It is hard to see how the parameters can be checked.
- * At the very least, we only allow root to set the context.
- */
- case PIOCSMEM:
- if (suser(td))
- return (EPERM);
- if (slt->state != filled)
- return (ENXIO);
- s = ((struct mem_desc *)data)->window;
- if (s < 0 || s >= slt->ctrl->maxmem)
- return (EINVAL);
- slt->mem[s] = *((struct mem_desc *)data);
- return (slt->ctrl->mapmem(slt, s));
- /*
- * Get I/O port context.
- */
- case PIOCGIO:
- s = ((struct io_desc *)data)->window;
- if (s < 0 || s >= slt->ctrl->maxio)
- return (EINVAL);
- ip = &slt->io[s];
- ((struct io_desc *)data)->flags = ip->flags;
- ((struct io_desc *)data)->start = ip->start;
- ((struct io_desc *)data)->size = ip->size;
- break;
- /*
- * Set I/O port context.
- */
- case PIOCSIO:
- if (suser(td))
- return (EPERM);
- if (slt->state != filled)
- return (ENXIO);
- s = ((struct io_desc *)data)->window;
- if (s < 0 || s >= slt->ctrl->maxio)
- return (EINVAL);
- slt->io[s] = *((struct io_desc *)data);
- /* XXX Don't actually map */
- return (0);
- break;
- /*
- * Set memory window flags for read/write interface.
- */
- case PIOCRWFLAG:
- slt->rwmem = *(int *)data;
- break;
- /*
- * Set the memory window to be used for the read/write interface.
- */
- case PIOCRWMEM:
- if (*(unsigned long *)data == 0) {
- *(unsigned long *)data = pccard_mem;
- break;
- }
- if (suser(td))
- return (EPERM);
- /*
- * Validate the memory by checking it against the I/O
- * memory range. It must also start on an aligned block size.
- */
- if (*(unsigned long *)data & (PCCARD_MEMSIZE-1))
- return (EINVAL);
- pccarddev = PCCARD_DEV2SOFTC(dev)->dev;
- pccard_mem_rid = 0;
- addr = *(unsigned long *)data;
- if (pccard_mem_res)
- bus_release_resource(pccarddev, SYS_RES_MEMORY,
- pccard_mem_rid, pccard_mem_res);
- pccard_mem_res = bus_alloc_resource(pccarddev, SYS_RES_MEMORY,
- &pccard_mem_rid, addr, addr, PCCARD_MEMSIZE,
- RF_ACTIVE | rman_make_alignment_flags(PCCARD_MEMSIZE));
- if (pccard_mem_res == NULL)
- return (EINVAL);
- pccard_mem = rman_get_start(pccard_mem_res);
- pccard_kmem = rman_get_virtual(pccard_mem_res);
- break;
- /*
- * Set power values.
- */
- case PIOCSPOW:
- slt->pwr = *(struct power *)data;
- return (slt->ctrl->power(slt));
- /*
- * Allocate a driver to this slot.
- */
- case PIOCSDRV:
- if (suser(td))
- return (EPERM);
- err = allocate_driver(slt, (struct dev_desc *)data);
- if (!err)
- pccard_success_beep();
- else
- pccard_failure_beep();
- return (err);
-/***/#if __FreeBSD_version < 5000000 /* 4.x compatibility only. */
- case PIOCSDRVOLD:
- if (suser(td))
- return (EPERM);
- odp = (struct dev_desc_old *) data;
- strlcpy(d.name, odp->name, sizeof(d.name));
- d.unit = odp->unit;
- d.mem = odp->mem;
- d.memsize = odp->memsize;
- d.iobase = odp->iobase;
- d.iosize = odp->iosize;
- d.irqmask = odp->irqmask;
- d.flags = odp->flags;
- memcpy(d.misc, odp->misc, sizeof(odp->misc));
- strlcpy(d.manufstr, odp->manufstr, sizeof(d.manufstr));
- strlcpy(d.versstr, odp->versstr, sizeof(d.versstr));
- *d.cis3str = '\0';
- *d.cis4str = '\0';
- d.manufacturer = odp->manufacturer;
- d.product = odp->product;
- d.prodext = odp->prodext;
- err = allocate_driver(slt, &d);
- if (!err)
- pccard_success_beep();
- else
- pccard_failure_beep();
- return (err);
-/***/#endif
- /*
- * Virtual removal/insertion
- */
- case PIOCSVIR:
- pwval = *(int *)data;
- if (!pwval) {
- if (slt->state != filled)
- return (EINVAL);
- pccard_event(slt, card_deactivated);
- } else {
- if (slt->state != empty && slt->state != inactive)
- return (EINVAL);
- pccard_event(slt, card_inserted);
- }
- break;
- case PIOCSBEEP:
- if (pccard_beep_select(*(int *)data)) {
- return (EINVAL);
- }
- break;
- }
- return (0);
-}
-
-/*
- * poll - Poll on exceptions will return true
- * when a change in card status occurs.
- */
-static int
-crdpoll(struct cdev *dev, int events, d_thread_t *td)
-{
- int revents = 0;
- int s;
- struct slot *slt = PCCARD_DEV2SOFTC(dev);
-
- if (events & (POLLIN | POLLRDNORM))
- revents |= events & (POLLIN | POLLRDNORM);
-
- if (events & (POLLOUT | POLLWRNORM))
- revents |= events & (POLLIN | POLLRDNORM);
-
- s = splhigh();
- /*
- * select for exception - card event.
- */
- if (events & POLLRDBAND)
- if (slt == 0 || slt->laststate != slt->state)
- revents |= POLLRDBAND;
-
- if (revents == 0)
- selrecord(td, &slt->selp);
-
- splx(s);
- return (revents);
-}
-
-/*
- * APM hooks for suspending and resuming.
- */
-int
-pccard_suspend(device_t dev)
-{
- struct slot *slt = PCCARD_DEVICE2SOFTC(dev);
-
- /* This code stolen from pccard_event:card_removed */
- if (slt->state == filled) {
- int s = splhigh(); /* nop on current */
- disable_slot(slt);
- slt->laststate = suspend; /* for pccardd */
- slt->state = empty;
- splx(s);
- printf("pccard: card disabled, slot %d\n", slt->slotnum);
- }
- /*
- * Disable any pending timeouts for this slot since we're
- * powering it down/disabling now.
- */
- untimeout(power_off_slot, (caddr_t)slt, slt->poff_ch);
- slt->ctrl->disable(slt);
- return (0);
-}
-
-int
-pccard_resume(device_t dev)
-{
- struct slot *slt = PCCARD_DEVICE2SOFTC(dev);
-
- slt->ctrl->resume(slt);
- return (0);
-}
diff --git a/sys/pccard/pccard_beep.c b/sys/pccard/pccard_beep.c
deleted file mode 100644
index e608dc1..0000000
--- a/sys/pccard/pccard_beep.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*-
- * pccard noise interface.
- * Nate Williams, October 1997.
- * This file is in the public domain.
- */
-/* $FreeBSD$ */
-
-#define OBSOLETE_IN_6
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-
-#include <machine/clock.h>
-
-#include <pccard/driver.h>
-
-static enum beepstate allow_beep = BEEP_OFF;
-static int melody_type = 0;
-
-#define MAX_TONE_MODE 3
-#define MAX_STATE 4
-
-struct tone {
- int pitch;
- int duration;
-};
-
-static struct tone silent_beep[] = {
- {0, 0}
-};
-
-static struct tone success_beep[] = {
- {1200, 40}, {0, 0}
-};
-static struct tone failure_beep[] = {
- {3200, 40}, {0, 0}
-};
-static struct tone insert_remove_beep[] = {
- {1600, 20}, {0, 0}
-};
-
-static struct tone success_melody_beep[] = {
- {1200, 7}, {1000, 7}, { 800, 15}, {0, 0}
-};
-static struct tone failure_melody_beep[] = {
- {2000, 7}, {2400, 7}, {2800, 15}, {0, 0}
-};
-static struct tone insert_melody_beep[] = {
- {1600, 10}, {1200, 5}, {0, 0}
-};
-static struct tone remove_melody_beep[] = {
- {1200, 10}, {1600, 5}, {0, 0}
-};
-
-static struct tone *melody_table[MAX_TONE_MODE][MAX_STATE] = {
- { /* silent mode */
- silent_beep, silent_beep, silent_beep, silent_beep,
- },
- { /* simple beep mode */
- success_beep, failure_beep,
- insert_remove_beep, insert_remove_beep,
- },
- { /* melody beep mode */
- success_melody_beep, failure_melody_beep,
- insert_melody_beep, remove_melody_beep,
- },
-};
-
-
-static void
-pccard_beep_sub(void *arg)
-{
- struct tone *melody;
- melody = (struct tone *)arg;
-
- if (melody->pitch != 0) {
- sysbeep(melody->pitch, (melody->duration * hz + 99) / 100);
- timeout(pccard_beep_sub, melody + 1,
- (melody->duration * hz + 99) / 100);
- } else
- allow_beep = BEEP_ON;
-}
-
-static void
-pccard_beep_start(void *arg)
-{
- struct tone *melody;
- melody = (struct tone *)arg;
-
- if (allow_beep == BEEP_ON && melody->pitch != 0) {
- allow_beep = BEEP_OFF;
- sysbeep(melody->pitch, (melody->duration * hz + 99) / 100);
- timeout(pccard_beep_sub, melody + 1,
- (melody->duration * hz + 99) / 100);
- }
-}
-
-void
-pccard_success_beep(void)
-{
- pccard_beep_start(melody_table[melody_type][0]);
-}
-
-void
-pccard_failure_beep(void)
-{
- pccard_beep_start(melody_table[melody_type][1]);
-}
-
-void
-pccard_insert_beep(void)
-{
- pccard_beep_start(melody_table[melody_type][2]);
-}
-
-void
-pccard_remove_beep(void)
-{
- pccard_beep_start(melody_table[melody_type][3]);
-}
-
-int
-pccard_beep_select(int type)
-{
- int errcode = 0;
-
- if (type == 0) {
- allow_beep = BEEP_OFF;
- melody_type = 0;
- } else if (type < 0 || MAX_TONE_MODE - 1 < type) {
- errcode = 1;
- } else {
- allow_beep = BEEP_ON;
- melody_type = type;
- }
- return (errcode);
-}
diff --git a/sys/pccard/pccard_nbk.c b/sys/pccard/pccard_nbk.c
deleted file mode 100644
index bda9db1..0000000
--- a/sys/pccard/pccard_nbk.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/*-
- * Copyright (c) 1999, 2001 M. Warner Losh. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * $FreeBSD$
- */
-
-/*
- * This file contains various kludges to allow the legacy pccard system to
- * work in the newbus system until the pccard system can be converted
- * wholesale to newbus. As that is a while off, I'm providing this glue to
- * allow newbus drivers to have pccard attachments.
- *
- * We do *NOT* implement ISA ivars at all. We are not an isa bus, and drivers
- * that abuse isa_{set,get}_* must be fixed in order to work with pccard.
- * We use ivars for something else anyway, so it becomes fairly awkward
- * to do so.
- *
- * Here's a summary of the glue that we do to make things work.
- *
- * First, we have pccard node in the device and driver trees. The pccard
- * device lives in the instance tree attached to the nexus. The pccard
- * attachments will be attached to that node. This allows one to pass things
- * up the tree that terminates at the nexus, like other buses. The pccard
- * code will create a device instance for each of the drivers that are to
- * be attached.
- *
- * These compatibility nodes are called pccnbk. PCCard New Bus Kludge.
- */
-
-#define OBSOLETE_IN_6
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/module.h>
-#include <sys/kernel.h>
-#include <sys/sysctl.h>
-#include <sys/queue.h>
-#include <sys/types.h>
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-#include <machine/resource.h>
-
-/* XXX Shouldn't reach into the MD code here */
-#ifdef PC98
-#include <pc98/cbus/cbus.h>
-#else
-#include <i386/isa/isa.h>
-#endif
-
-#include <pccard/cardinfo.h>
-#include <pccard/slot.h>
-
-#include <dev/pccard/pccardvar.h>
-#include <net/ethernet.h>
-
-#include "card_if.h"
-
-devclass_t pccard_devclass;
-
-#define PCCARD_NPORT 2
-#define PCCARD_NMEM 5
-#define PCCARD_NIRQ 1
-#define PCCARD_NDRQ 0
-
-#define PCCARD_DEVINFO(d) (struct pccard_devinfo *) device_get_ivars(d)
-
-SYSCTL_NODE(_machdep, OID_AUTO, pccard, CTLFLAG_RW, 0, "pccard");
-
-#ifdef UNSAFE
-static u_long mem_start = IOM_BEGIN;
-static u_long mem_end = IOM_END;
-#else
-static u_long mem_start = 0xd0000;
-static u_long mem_end = 0xeffff;
-#endif
-
-SYSCTL_ULONG(_machdep_pccard, OID_AUTO, mem_start, CTLFLAG_RW,
- &mem_start, 0, "");
-SYSCTL_ULONG(_machdep_pccard, OID_AUTO, mem_end, CTLFLAG_RW,
- &mem_end, 0, "");
-
-#if __FreeBSD_version >= 500000
-/*
- * glue for NEWCARD/OLDCARD compat layer
- */
-static int
-pccard_compat_do_probe(device_t bus, device_t dev)
-{
- return (CARD_COMPAT_PROBE(dev));
-}
-
-static int
-pccard_compat_do_attach(device_t bus, device_t dev)
-{
- return (CARD_COMPAT_ATTACH(dev));
-}
-#endif
-
-static int
-pccard_probe(device_t dev)
-{
- device_set_desc(dev, "PC Card 16-bit bus (classic)");
- return (0);
-}
-
-static int
-pccard_attach(device_t dev)
-{
- return (0);
-}
-
-static void
-pccard_print_resources(struct resource_list *rl, const char *name, int type,
- int count, const char *format)
-{
- struct resource_list_entry *rle;
- int printed;
- int i;
-
- printed = 0;
- for (i = 0; i < count; i++) {
- rle = resource_list_find(rl, type, i);
- if (rle) {
- if (printed == 0)
- printf(" %s ", name);
- else if (printed > 0)
- printf(",");
- printed++;
- printf(format, rle->start);
- if (rle->count > 1) {
- printf("-");
- printf(format, rle->start + rle->count - 1);
- }
- } else if (i > 3) {
- /* check the first few regardless */
- break;
- }
- }
-}
-
-static int
-pccard_print_child(device_t dev, device_t child)
-{
- struct pccard_devinfo *devi = PCCARD_DEVINFO(child);
- struct resource_list *rl = &devi->resources;
- int retval = 0;
- int flags = device_get_flags(child);
-
- retval += bus_print_child_header(dev, child);
- retval += printf(" at");
-
- if (devi) {
- pccard_print_resources(rl, "port", SYS_RES_IOPORT,
- PCCARD_NPORT, "%#lx");
- pccard_print_resources(rl, "iomem", SYS_RES_MEMORY,
- PCCARD_NMEM, "%#lx");
- pccard_print_resources(rl, "irq", SYS_RES_IRQ, PCCARD_NIRQ,
- "%ld");
- pccard_print_resources(rl, "drq", SYS_RES_DRQ, PCCARD_NDRQ,
- "%ld");
- if (flags != 0)
- retval += printf(" flags 0x%x", flags);
- retval += printf(" slot %d", devi->slt->slotnum);
- }
-
- retval += bus_print_child_footer(dev, child);
-
- return (retval);
-}
-
-static int
-pccard_set_resource(device_t dev, device_t child, int type, int rid,
- u_long start, u_long count)
-{
- struct pccard_devinfo *devi = PCCARD_DEVINFO(child);
- struct resource_list *rl = &devi->resources;
-
- if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY
- && type != SYS_RES_IRQ && type != SYS_RES_DRQ)
- return (EINVAL);
- if (rid < 0)
- return (EINVAL);
- if (type == SYS_RES_IOPORT && rid >= PCCARD_NPORT)
- return (EINVAL);
- if (type == SYS_RES_MEMORY && rid >= PCCARD_NMEM)
- return (EINVAL);
- if (type == SYS_RES_IRQ && rid >= PCCARD_NIRQ)
- return (EINVAL);
- if (type == SYS_RES_DRQ && rid >= PCCARD_NDRQ)
- return (EINVAL);
-
- resource_list_add(rl, type, rid, start, start + count - 1, count);
-
- return (0);
-}
-
-static int
-pccard_get_resource(device_t dev, device_t child, int type, int rid,
- u_long *startp, u_long *countp)
-{
- struct pccard_devinfo *devi = PCCARD_DEVINFO(child);
- struct resource_list *rl = &devi->resources;
- struct resource_list_entry *rle;
-
- rle = resource_list_find(rl, type, rid);
- if (!rle)
- return (ENOENT);
-
- if (startp)
- *startp = rle->start;
- if (countp)
- *countp = rle->count;
-
- return (0);
-}
-
-static void
-pccard_delete_resource(device_t dev, device_t child, int type, int rid)
-{
- struct pccard_devinfo *devi = PCCARD_DEVINFO(child);
- struct resource_list *rl = &devi->resources;
- resource_list_delete(rl, type, rid);
-}
-
-static struct resource *
-pccard_alloc_resource(device_t bus, device_t child, int type, int *rid,
- u_long start, u_long end, u_long count, u_int flags)
-{
- /*
- * Consider adding a resource definition. We allow rid 0 for
- * irq, 0-4 for memory and 0-1 for ports
- */
- int passthrough = (device_get_parent(child) != bus);
- int isdefault;
- struct pccard_devinfo *devi = device_get_ivars(child);
- struct resource_list *rl = &devi->resources;
- struct resource_list_entry *rle;
- struct resource *res;
-
- if (start == 0 && end == ~0 && type == SYS_RES_MEMORY && count != 1) {
- start = mem_start;
- end = mem_end;
- }
- isdefault = (start == 0UL && end == ~0UL);
- if (!passthrough && !isdefault) {
- rle = resource_list_find(rl, type, *rid);
- if (!rle) {
- if (*rid < 0)
- return (NULL);
- switch (type) {
- case SYS_RES_IRQ:
- if (*rid >= PCCARD_NIRQ)
- return (NULL);
- break;
- case SYS_RES_DRQ:
- if (*rid >= PCCARD_NDRQ)
- return (NULL);
- break;
- case SYS_RES_MEMORY:
- if (*rid >= PCCARD_NMEM)
- return (NULL);
- break;
- case SYS_RES_IOPORT:
- if (*rid >= PCCARD_NPORT)
- return (NULL);
- break;
- default:
- return (NULL);
- }
- resource_list_add(rl, type, *rid, start, end, count);
- }
- }
- res = resource_list_alloc(rl, bus, child, type, rid, start, end,
- count, flags);
- return (res);
-}
-
-static int
-pccard_release_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
- struct pccard_devinfo *devi = PCCARD_DEVINFO(child);
- struct resource_list *rl = &devi->resources;
- return (resource_list_release(rl, bus, child, type, rid, r));
-}
-
-static int
-pccard_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
-{
- struct pccard_devinfo *devi = PCCARD_DEVINFO(child);
-
- switch (which) {
- case PCCARD_IVAR_ETHADDR:
- bcopy(devi->misc, result, ETHER_ADDR_LEN);
- return (0);
- case PCCARD_IVAR_VENDOR:
- *(u_int32_t *) result = devi->manufacturer;
- return (0);
- case PCCARD_IVAR_PRODUCT:
- *(u_int32_t *) result = devi->product;
- return (0);
- case PCCARD_IVAR_PRODEXT:
- *(u_int16_t *) result = devi->prodext;
- return (0);
- case PCCARD_IVAR_VENDOR_STR:
- *(char **) result = devi->manufstr;
- break;
- case PCCARD_IVAR_PRODUCT_STR:
- *(char **) result = devi->versstr;
- break;
- case PCCARD_IVAR_CIS3_STR:
- *(char **) result = devi->cis3str;
- break;
- case PCCARD_IVAR_CIS4_STR:
- *(char **) result = devi->cis4str;
- break;
- }
- return (ENOENT);
-}
-
-static int
-pccard_set_res_flags(device_t bus, device_t child, int restype, int rid,
- u_long value)
-{
- return (CARD_SET_RES_FLAGS(device_get_parent(bus), child, restype,
- rid, value));
-}
-
-static int
-pccard_get_res_flags(device_t bus, device_t child, int restype, int rid,
- u_long *value)
-{
- return (CARD_GET_RES_FLAGS(device_get_parent(bus), child, restype,
- rid, value));
-}
-
-static int
-pccard_set_memory_offset(device_t bus, device_t child, int rid,
- u_int32_t offset
-#if __FreeBSD_version >= 500000
- , u_int32_t *deltap
-#endif
-)
-{
- return (CARD_SET_MEMORY_OFFSET(device_get_parent(bus), child, rid,
- offset
-#if __FreeBSD_version >= 500000
- , deltap
-#endif
- ));
-}
-
-static int
-pccard_get_memory_offset(device_t bus, device_t child, int rid,
- u_int32_t *offset)
-{
- return (CARD_GET_MEMORY_OFFSET(device_get_parent(bus), child, rid,
- offset));
-}
-
-#if __FreeBSD_version >= 500000
-static const struct pccard_product *
-pccard_do_product_lookup(device_t bus, device_t dev,
- const struct pccard_product *tab,
- size_t ent_size, pccard_product_match_fn matchfn)
-{
- return (NULL);
-}
-#endif
-
-static device_method_t pccard_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, pccard_probe),
- DEVMETHOD(device_attach, pccard_attach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, pccard_suspend),
- DEVMETHOD(device_resume, pccard_resume),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, pccard_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
- DEVMETHOD(bus_alloc_resource, pccard_alloc_resource),
- DEVMETHOD(bus_release_resource, pccard_release_resource),
- DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
- DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
- DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
- DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
- DEVMETHOD(bus_set_resource, pccard_set_resource),
- DEVMETHOD(bus_get_resource, pccard_get_resource),
- DEVMETHOD(bus_delete_resource, pccard_delete_resource),
- DEVMETHOD(bus_read_ivar, pccard_read_ivar),
-
- /* Card interface */
- DEVMETHOD(card_set_res_flags, pccard_set_res_flags),
- DEVMETHOD(card_get_res_flags, pccard_get_res_flags),
- DEVMETHOD(card_set_memory_offset, pccard_set_memory_offset),
- DEVMETHOD(card_get_memory_offset, pccard_get_memory_offset),
-#if __FreeBSD_version >= 500000
- DEVMETHOD(card_compat_do_probe, pccard_compat_do_probe),
- DEVMETHOD(card_compat_do_attach, pccard_compat_do_attach),
- DEVMETHOD(card_do_product_lookup, pccard_do_product_lookup),
-#endif
- { 0, 0 }
-};
-
-static driver_t pccard_driver = {
- "pccard",
- pccard_methods,
- sizeof(struct slot)
-};
-
-DRIVER_MODULE(pccard, pcic, pccard_driver, pccard_devclass, 0, 0);
-DRIVER_MODULE(pccard, mecia, pccard_driver, pccard_devclass, 0, 0);
-MODULE_VERSION(pccard, 1);
diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c
deleted file mode 100644
index be4fea8..0000000
--- a/sys/pccard/pcic.c
+++ /dev/null
@@ -1,1344 +0,0 @@
-/*
- * Intel PCIC or compatible Controller driver
- *-------------------------------------------------------------------------
- */
-
-/*-
- * Copyright (c) 2001 M. Warner Losh. All rights reserved.
- * Copyright (c) 1995 Andrew McRae. 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. 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.
- *
- * $FreeBSD$
- */
-
-#define OBSOLETE_IN_6
-
-#include <sys/param.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/sysctl.h>
-#include <sys/systm.h>
-
-#include <machine/clock.h>
-#include <pccard/i82365.h>
-#include <pccard/pcic_pci.h>
-#include <pccard/cardinfo.h>
-#include <pccard/slot.h>
-#include <pccard/pcicvar.h>
-
-/* Get pnp IDs */
-#include <isa/isavar.h>
-
-#include <dev/pccard/pccardvar.h>
-#include "card_if.h"
-
-/*
- * Prototypes for interrupt handler.
- */
-static int pcic_ioctl(struct slot *, int, caddr_t);
-static int pcic_power(struct slot *);
-static void pcic_mapirq(struct slot *, int);
-static timeout_t pcic_reset;
-static void pcic_resume(struct slot *);
-static void pcic_disable(struct slot *);
-static int pcic_memory(struct slot *, int);
-static int pcic_io(struct slot *, int);
-
-devclass_t pcic_devclass;
-
-static struct slot_ctrl pcic_cinfo = {
- pcic_mapirq,
- pcic_memory,
- pcic_io,
- pcic_reset,
- pcic_disable,
- pcic_power,
- pcic_ioctl,
- pcic_resume,
- PCIC_MEM_WIN,
- PCIC_IO_WIN
-};
-
-/* sysctl vars */
-SYSCTL_NODE(_hw, OID_AUTO, pcic, CTLFLAG_RD, 0, "PCIC parameters");
-
-int pcic_override_irq = 0;
-TUNABLE_INT("machdep.pccard.pcic_irq", &pcic_override_irq);
-TUNABLE_INT("hw.pcic.irq", &pcic_override_irq);
-SYSCTL_INT(_hw_pcic, OID_AUTO, irq, CTLFLAG_RDTUN,
- &pcic_override_irq, 0,
- "Override the IRQ configured by the config system for all pcic devices");
-
-int pcic_boot_deactivated = 0;
-TUNABLE_INT("hw.pcic.boot_deactivated", &pcic_boot_deactivated);
-SYSCTL_INT(_hw_pcic, OID_AUTO, boot_deactivated, CTLFLAG_RDTUN,
- &pcic_boot_deactivated, 0,
- "Override the automatic powering up of pccards at boot. This works\n\
-around what turns out to be an old bug in the code that has since been\n\
-corrected. It is now deprecated and will be removed completely before\n\
-FreeBSD 4.8.");
-
-/*
- * CL-PD6722's VSENSE method
- * 0: NO VSENSE (assume a 5.0V card)
- * 1: 6710's method (default)
- * 2: 6729's method
- */
-int pcic_pd6722_vsense = 1;
-TUNABLE_INT("hw.pcic.pd6722_vsense", &pcic_pd6722_vsense);
-SYSCTL_INT(_hw_pcic, OID_AUTO, pd6722_vsense, CTLFLAG_RDTUN,
- &pcic_pd6722_vsense, 1,
- "Select CL-PD6722's VSENSE method. VSENSE is used to determine the\n\
-volatage of inserted cards. The CL-PD6722 has two methods to determine the\n\
-voltage of the card. 0 means assume a 5.0V card and do not check. 1 means\n\
-use the same method that the CL-PD6710 uses (default). 2 means use the\n\
-same method as the CL-PD6729. 2 is documented in the datasheet as being\n\
-the correct way, but 1 seems to give better results on more laptops.");
-
-/*
- * Read a register from the PCIC.
- */
-unsigned char
-pcic_getb_io(struct pcic_slot *sp, int reg)
-{
- bus_space_write_1(sp->bst, sp->bsh, PCIC_INDEX, sp->offset + reg);
- return (bus_space_read_1(sp->bst, sp->bsh, PCIC_DATA));
-}
-
-/*
- * Write a register on the PCIC
- */
-void
-pcic_putb_io(struct pcic_slot *sp, int reg, unsigned char val)
-{
- /*
- * Many datasheets recommend using outw rather than outb to save
- * a microsecond. Maybe we should do this, but we'd likely only
- * save 20-30us on card activation.
- */
- bus_space_write_1(sp->bst, sp->bsh, PCIC_INDEX, sp->offset + reg);
- bus_space_write_1(sp->bst, sp->bsh, PCIC_DATA, val);
-}
-
-/*
- * Clear bit(s) of a register.
- */
-__inline void
-pcic_clrb(struct pcic_slot *sp, int reg, unsigned char mask)
-{
- sp->putb(sp, reg, sp->getb(sp, reg) & ~mask);
-}
-
-/*
- * Set bit(s) of a register
- */
-__inline void
-pcic_setb(struct pcic_slot *sp, int reg, unsigned char mask)
-{
- sp->putb(sp, reg, sp->getb(sp, reg) | mask);
-}
-
-/*
- * Write a 16 bit value to 2 adjacent PCIC registers
- */
-static __inline void
-pcic_putw(struct pcic_slot *sp, int reg, unsigned short word)
-{
- sp->putb(sp, reg, word & 0xFF);
- sp->putb(sp, reg + 1, (word >> 8) & 0xff);
-}
-
-/*
- * pc98 cbus cards introduce a slight wrinkle here. They route the irq7 pin
- * from the pcic chip to INT 2 on the cbus. INT 2 is normally mapped to
- * irq 6 on the pc98 architecture, so if we get a request for irq 6
- * lie to the hardware and say it is 7. All the other usual mappings for
- * cbus INT into irq space are the same as the rest of the system.
- */
-static __inline int
-host_irq_to_pcic(int irq)
-{
-#ifdef PC98
- if (irq == 6)
- irq = 7;
-#endif
- return (irq);
-}
-
-/*
- * Free up resources allocated so far.
- */
-void
-pcic_dealloc(device_t dev)
-{
- struct pcic_softc *sc;
-
- sc = (struct pcic_softc *) device_get_softc(dev);
- if (sc->slot_poll)
- untimeout(sc->slot_poll, sc, sc->timeout_ch);
- if (sc->iores)
- bus_release_resource(dev, SYS_RES_IOPORT, sc->iorid,
- sc->iores);
- if (sc->memres)
- bus_release_resource(dev, SYS_RES_MEMORY, sc->memrid,
- sc->memres);
- if (sc->ih)
- bus_teardown_intr(dev, sc->irqres, sc->ih);
- if (sc->irqres)
- bus_release_resource(dev, SYS_RES_IRQ, sc->irqrid, sc->irqres);
-}
-
-/*
- * entry point from main code to map/unmap memory context.
- */
-static int
-pcic_memory(struct slot *slt, int win)
-{
- struct pcic_slot *sp = slt->cdata;
- struct mem_desc *mp = &slt->mem[win];
- int reg = win * PCIC_MEMSIZE + PCIC_MEMBASE;
-
- if (win < 0 || win >= slt->ctrl->maxmem) {
- printf("Illegal PCIC MEMORY window request %d\n", win);
- return (ENXIO);
- }
- if (mp->flags & MDF_ACTIVE) {
- unsigned long sys_addr = (uintptr_t)(void *)mp->start >> 12;
- if ((sys_addr >> 12) != 0 &&
- (sp->sc->flags & PCIC_YENTA_HIGH_MEMORY) == 0) {
- printf("This pcic does not support mapping > 24M\n");
- return (ENXIO);
- }
- /*
- * Write the addresses, card offsets and length.
- * The values are all stored as the upper 12 bits of the
- * 24 bit address i.e everything is allocated as 4 Kb chunks.
- * Memory mapped cardbus bridges extend this slightly to allow
- * one to set the upper 8 bits of the 32bit address as well.
- * If the chip supports it, then go ahead and write those
- * upper 8 bits.
- */
- pcic_putw(sp, reg, sys_addr & 0xFFF);
- pcic_putw(sp, reg+2, (sys_addr + (mp->size >> 12) - 1) & 0xFFF);
- pcic_putw(sp, reg+4, ((mp->card >> 12) - sys_addr) & 0x3FFF);
- if (sp->sc->flags & PCIC_YENTA_HIGH_MEMORY)
- sp->putb(sp, PCIC_MEMORY_HIGH0 + win, sys_addr >> 12);
- /*
- * Each 16 bit register has some flags in the upper bits.
- */
- if (mp->flags & MDF_16BITS)
- pcic_setb(sp, reg+1, PCIC_DATA16);
- if (mp->flags & MDF_ZEROWS)
- pcic_setb(sp, reg+1, PCIC_ZEROWS);
- if (mp->flags & MDF_WS0)
- pcic_setb(sp, reg+3, PCIC_MW0);
- if (mp->flags & MDF_WS1)
- pcic_setb(sp, reg+3, PCIC_MW1);
- if (mp->flags & MDF_ATTR)
- pcic_setb(sp, reg+5, PCIC_REG);
- if (mp->flags & MDF_WP)
- pcic_setb(sp, reg+5, PCIC_WP);
- /*
- * Enable the memory window. By experiment, we need a delay.
- */
- pcic_setb(sp, PCIC_ADDRWINE, (1<<win) | PCIC_MEMCS16);
- DELAY(50);
- } else {
- pcic_clrb(sp, PCIC_ADDRWINE, 1<<win);
- pcic_putw(sp, reg, 0);
- pcic_putw(sp, reg+2, 0);
- pcic_putw(sp, reg+4, 0);
- }
- if (bootverbose)
- printf("pcic: mem addr %p: reg %d: %x %x %x %x %x %x %x\n",
- mp->start, reg, sp->getb(sp, reg), sp->getb(sp, reg+1),
- sp->getb(sp, reg+2), sp->getb(sp, reg+3),
- sp->getb(sp, reg+3), sp->getb(sp, reg+5),
- sp->getb(sp, PCIC_ADDRWINE));
- return (0);
-}
-
-/*
- * pcic_io - map or unmap I/O context
- */
-static int
-pcic_io(struct slot *slt, int win)
-{
- int mask, reg;
- struct pcic_slot *sp = slt->cdata;
- struct io_desc *ip = &slt->io[win];
- if (bootverbose) {
- printf("pcic: I/O win %d flags %x %x-%x\n", win, ip->flags,
- ip->start, ip->start + ip->size - 1);
- }
-
- switch (win) {
- case 0:
- mask = PCIC_IO0_EN;
- reg = PCIC_IO0;
- break;
- case 1:
- mask = PCIC_IO1_EN;
- reg = PCIC_IO1;
- break;
- default:
- printf("Illegal PCIC I/O window request %d\n", win);
- return (ENXIO);
- }
- if (ip->flags & IODF_ACTIVE) {
- unsigned char x, ioctlv;
-
- pcic_putw(sp, reg, ip->start);
- pcic_putw(sp, reg+2, ip->start + ip->size - 1);
- x = 0;
- if (ip->flags & IODF_ZEROWS)
- x |= PCIC_IO_0WS;
- if (ip->flags & IODF_WS)
- x |= PCIC_IO_WS;
- if (ip->flags & IODF_CS16)
- x |= PCIC_IO_CS16;
- if (ip->flags & IODF_16BIT)
- x |= PCIC_IO_16BIT;
- /*
- * Extract the current flags and merge with new flags.
- * Flags for window 0 in lower nybble, and in upper nybble
- * for window 1.
- */
- ioctlv = sp->getb(sp, PCIC_IOCTL);
- DELAY(100);
- switch (win) {
- case 0:
- sp->putb(sp, PCIC_IOCTL, x | (ioctlv & 0xf0));
- break;
- case 1:
- sp->putb(sp, PCIC_IOCTL, (x << 4) | (ioctlv & 0xf));
- break;
- }
- DELAY(100);
- pcic_setb(sp, PCIC_ADDRWINE, mask);
- DELAY(100);
- } else {
- pcic_clrb(sp, PCIC_ADDRWINE, mask);
- DELAY(100);
- pcic_putw(sp, reg, 0);
- pcic_putw(sp, reg + 2, 0);
- }
- return (0);
-}
-
-static void
-pcic_do_mgt_irq(struct pcic_slot *sp, int irq)
-{
- u_int32_t reg;
-
- if (sp->sc->csc_route == pcic_iw_pci) {
- /* Do the PCI side of things: Enable the Card Change int */
- reg = CB_SM_CD;
- bus_space_write_4(sp->bst, sp->bsh, CB_SOCKET_MASK, reg);
- /*
- * TI Chips need us to set the following. We tell the
- * controller to route things via PCI interrupts. Also
- * we clear the interrupt number in the STAT_INT register
- * as well. The TI-12xx and newer chips require one or the
- * other of these to happen, depending on what is set in the
- * diagnostic register. I do both on the theory that other
- * chips might need one or the other and that no harm will
- * come from it. If there is harm, then I'll make it a bit
- * in the tables.
- */
- pcic_setb(sp, PCIC_INT_GEN, PCIC_INTR_ENA);
- pcic_clrb(sp, PCIC_STAT_INT, PCIC_CSCSELECT);
- } else {
- /* Management IRQ changes */
- /*
- * The PCIC_INTR_ENA bit means either "tie the function
- * and csc interrupts together" or "Route csc interrupts
- * via PCI" or "Reserved". In any case, we want to clear
- * it since we're using ISA interrupts.
- */
- pcic_clrb(sp, PCIC_INT_GEN, PCIC_INTR_ENA);
- irq = host_irq_to_pcic(irq);
- sp->putb(sp, PCIC_STAT_INT, (irq << PCIC_SI_IRQ_SHIFT) |
- PCIC_CDEN);
- }
-}
-
-int
-pcic_attach(device_t dev)
-{
- int i;
- device_t kid;
- struct pcic_softc *sc;
- struct slot *slt;
- struct pcic_slot *sp;
-
- sc = (struct pcic_softc *) device_get_softc(dev);
- callout_handle_init(&sc->timeout_ch);
- sp = &sc->slots[0];
- for (i = 0; i < PCIC_CARD_SLOTS; i++, sp++) {
- if (!sp->slt)
- continue;
- sp->slt = 0;
- kid = device_add_child(dev, NULL, -1);
- if (kid == NULL) {
- device_printf(dev, "Can't add pccard bus slot %d", i);
- return (ENXIO);
- }
- device_probe_and_attach(kid);
- slt = pccard_init_slot(kid, &pcic_cinfo);
- if (slt == 0) {
- device_printf(dev, "Can't get pccard info slot %d", i);
- return (ENXIO);
- }
- sc->slotmask |= (1 << i);
- slt->cdata = sp;
- sp->slt = slt;
- sp->sc = sc;
- }
-
- sp = &sc->slots[0];
- for (i = 0; i < PCIC_CARD_SLOTS; i++, sp++) {
- if (sp->slt == NULL)
- continue;
-
- pcic_do_mgt_irq(sp, sc->irq);
- sp->slt->irq = sc->irq;
-
- /* Check for changes */
- sp->slt->laststate = sp->slt->state = empty;
- if (pcic_boot_deactivated) {
- sp->putb(sp, PCIC_POWER, 0);
- if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) == PCIC_CD) {
- sp->slt->state = inactive;
- pccard_event(sp->slt, card_deactivated);
- }
- } else {
- pcic_do_stat_delta(sp);
- }
- }
-
- return (bus_generic_attach(dev));
-}
-
-
-static int
-pcic_sresource(struct slot *slt, caddr_t data)
-{
- struct pccard_resource *pr;
- struct resource *r;
- int flags;
- int rid = 0;
- device_t bridgedev = slt->dev;
- struct pcic_slot *sp = slt->cdata;
-
- pr = (struct pccard_resource *)data;
- pr->resource_addr = ~0ul;
-
- /*
- * If we're using PCI interrupt routing, then force the IRQ to
- * use and to heck with what the user requested. If they want
- * to be able to request IRQs, they must use ISA interrupt
- * routing. If we don't give them an irq, and it is the
- * pccardd 0,0 case, then just return (giving the "bad resource"
- * return in pr->resource_addr).
- */
- if (pr->type == SYS_RES_IRQ) {
- if (sp->sc->func_route >= pcic_iw_pci) {
- pr->resource_addr = sp->sc->irq;
- return (0);
- }
- if (pr->min == 0 && pr->max == 0)
- return (0);
- }
-
- /*
- * Make sure we grok this type.
- */
- switch(pr->type) {
- default:
- return (EINVAL);
- case SYS_RES_MEMORY:
- case SYS_RES_IRQ:
- case SYS_RES_IOPORT:
- break;
- }
-
- /*
- * Allocate the resource, and align it to the most natural
- * size. If we get it, then tell userland what we actually got
- * in the range they requested.
- */
- flags = rman_make_alignment_flags(pr->size);
- r = bus_alloc_resource(bridgedev, pr->type, &rid, pr->min, pr->max,
- pr->size, flags);
- if (r != NULL) {
- pr->resource_addr = (u_long)rman_get_start(r);
- bus_release_resource(bridgedev, pr->type, rid, r);
- }
- return (0);
-}
-
-/*
- * ioctl calls - Controller specific ioctls
- */
-static int
-pcic_ioctl(struct slot *slt, int cmd, caddr_t data)
-{
- struct pcic_slot *sp = slt->cdata;
- struct pcic_reg *preg = (struct pcic_reg *) data;
-
- switch(cmd) {
- default:
- return (ENOTTY);
- case PIOCGREG: /* Get pcic register */
- preg->value = sp->getb(sp, preg->reg);
- break; /* Set pcic register */
- case PIOCSREG:
- sp->putb(sp, preg->reg, preg->value);
- break;
- case PIOCSRESOURCE: /* Can I use this resource? */
- pcic_sresource(slt, data);
- break;
- }
- return (0);
-}
-
-/*
- * pcic_cardbus_power
- *
- * Power the card up, as specified, using the cardbus power
- * registers to control power. Microsoft recommends that cardbus
- * vendors support powering the card via cardbus registers because
- * there is no standard for 3.3V cards. Since at least a few of the
- * cardbus bridges have minor issues with power via the ExCA registers,
- * go ahead and do it all via cardbus registers.
- *
- * An expamination of the code will show the relative ease that we do
- * Vpp in comparison to the ExCA case (which may be partially broken).
- */
-static int
-pcic_cardbus_power(struct pcic_slot *sp, struct slot *slt)
-{
- uint32_t power;
- uint32_t state;
-
- /*
- * If we're doing an auto-detect, and we're in a badvcc state, then
- * we need to force the socket to rescan the card. We don't do this
- * all the time because the socket can take up to 200ms to do the deed,
- * and that's too long to busy wait. Since this is a relatively rare
- * event (some BIOSes, and earlier versions of OLDCARD caused it), we
- * test for it special.
- */
- state = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_STATE);
- if (slt->pwr.vcc == -1 && (state & CB_SS_BADVCC)) {
- /*
- * Force the bridge to scan the card for the proper voltages
- * that it supports.
- */
- bus_space_write_4(sp->bst, sp->bsh, CB_SOCKET_FORCE,
- CB_SF_INTCVS);
- state = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_STATE);
- /* This while loop can take 100-150ms */
- while ((state & CB_SS_CARD_MASK) == 0) {
- DELAY(10 * 1000);
- state = bus_space_read_4(sp->bst, sp->bsh,
- CB_SOCKET_STATE);
- }
- }
-
-
- /*
- * Preserve the clock stop bit of the socket power register. Not
- * sure that we want to do that, but maybe we should set it based
- * on the power state.
- */
- power = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_POWER);
- power = 0;
-
- /*
- * vcc == -1 means automatically detect the voltage of the card.
- * Do so and apply the right amount of power.
- */
- if (slt->pwr.vcc == -1) {
- if (state & CB_SS_5VCARD)
- slt->pwr.vcc = 50;
- else if (state & CB_SS_3VCARD)
- slt->pwr.vcc = 33;
- else if (state & CB_SS_XVCARD)
- slt->pwr.vcc = 22;
- else if (state & CB_SS_YVCARD)
- slt->pwr.vcc = 11;
- if (bootverbose && slt->pwr.vcc != -1)
- device_printf(sp->sc->dev,
- "Autodetected %d.%dV card\n",
- slt->pwr.vcc / 10, slt->pwr.vcc % 10);
- }
-
- switch(slt->pwr.vcc) {
- default:
- return (EINVAL);
- case 0:
- power |= CB_SP_VCC_0V;
- break;
- case 11:
- power |= CB_SP_VCC_YV;
- break;
- case 22:
- power |= CB_SP_VCC_XV;
- break;
- case 33:
- power |= CB_SP_VCC_3V;
- break;
- case 50:
- power |= CB_SP_VCC_5V;
- break;
- }
-
- /*
- * vpp == -1 means use vcc voltage.
- */
- if (slt->pwr.vpp == -1)
- slt->pwr.vpp = slt->pwr.vcc;
- switch(slt->pwr.vpp) {
- default:
- return (EINVAL);
- case 0:
- power |= CB_SP_VPP_0V;
- break;
- case 11:
- power |= CB_SP_VPP_YV;
- break;
- case 22:
- power |= CB_SP_VPP_XV;
- break;
- case 33:
- power |= CB_SP_VPP_3V;
- break;
- case 50:
- power |= CB_SP_VPP_5V;
- break;
- case 120:
- power |= CB_SP_VPP_12V;
- break;
- }
- bus_space_write_4(sp->bst, sp->bsh, CB_SOCKET_POWER, power);
-
- /*
- * OK. We need to bring the card out of reset. Let the power
- * stabilize for 300ms (why 300?) and then enable the outputs
- * and then wait 100ms (why 100?) for it to stabilize. These numbers
- * were stolen from the dim, dark past of OLDCARD and I have no clue
- * how they were derived. I also use the bit setting routines here
- * as a measure of conservatism.
- */
- if (power) {
- pcic_setb(sp, PCIC_POWER, PCIC_DISRST);
- DELAY(300*1000);
- pcic_setb(sp, PCIC_POWER, PCIC_DISRST | PCIC_OUTENA);
- DELAY(100*1000);
- } else {
- pcic_clrb(sp, PCIC_POWER, PCIC_DISRST | PCIC_OUTENA);
- }
-
- return (0);
-}
-
-/*
- * pcic_power - Enable the power of the slot according to
- * the parameters in the power structure(s).
- */
-static int
-pcic_power(struct slot *slt)
-{
- unsigned char c, c2;
- unsigned char reg = PCIC_DISRST | PCIC_PCPWRE;
- struct pcic_slot *sp = slt->cdata;
- struct pcic_slot *sp2;
- struct pcic_softc *sc = sp->sc;
- int dodefault = 0;
- char controller;
-
- /*
- * Cardbus power registers are completely different.
- */
- if (sc->flags & PCIC_CARDBUS_POWER)
- return (pcic_cardbus_power(sp, slt));
-
- if (bootverbose)
- device_printf(sc->dev, "Power: Vcc=%d Vpp=%d\n", slt->pwr.vcc,
- slt->pwr.vpp);
- /*
- * If we're automatically detecting what voltage to use, then we need
- * to ask the bridge what type (voltage-wise) the card is.
- */
- if (slt->pwr.vcc == -1) {
- if (sc->flags & PCIC_DF_POWER) {
- /*
- * Look at the VS[12]# bits on the card. If VS1 is
- * clear then the card needs 3.3V instead of 5.0V.
- */
- c = sp->getb(sp, PCIC_CDGC);
- if ((c & PCIC_VS1STAT) == 0)
- slt->pwr.vcc = 33;
- else
- slt->pwr.vcc = 50;
- }
- if (sc->flags & PCIC_PD_POWER) {
- /*
- * The 6710 does it one way, and the '22 and '29 do it
- * another. The '22 can also do it the same way as a
- * '10 does it, despite what the datasheets say. Some
- * laptops with '22 don't seem to have the signals
- * wired right for the '29 method to work. The
- * laptops that don't work hang solid when the pccard
- * memory is accessed.
- *
- * To allow for both types of laptops,
- * hw.pcic.pd6722_vsense will select which one to use.
- * 0 - none, 1 - the '10 way and 2 - the '29 way.
- */
- controller = sp->controller;
- if (controller == PCIC_PD6722) {
- switch (pcic_pd6722_vsense) {
- case 1:
- controller = PCIC_PD6710;
- break;
- case 2:
- controller = PCIC_PD6729;
- break;
- }
- }
-
- switch (controller) {
- case PCIC_PD6710:
- c = sp->getb(sp, PCIC_MISC1);
- if ((c & PCIC_MISC1_5V_DETECT) == 0)
- slt->pwr.vcc = 33;
- else
- slt->pwr.vcc = 50;
- break;
- case PCIC_PD6722: /* see above for why we do */
- break; /* none here */
- case PCIC_PD6729:
- /*
- * VS[12] signals are in slot1's
- * extended reg 0xa for both slots.
- */
- sp2 = &sc->slots[1];
- sp2->putb(sp2, PCIC_EXT_IND, PCIC_EXT_DATA);
- c = sp2->getb(sp2, PCIC_EXTENDED);
- if (sp == sp2) /* slot 1 */
- c >>= 2;
- if ((c & PCIC_VS1A) == 0)
- slt->pwr.vcc = 33;
- else
- slt->pwr.vcc = 50;
- break;
- default:
- /* I have no idea how to do this for others */
- break;
- }
-
- /*
- * Regardless of the above, setting the Auto Power
- * Switch Enable appears to help.
- */
- reg |= PCIC_APSENA;
- }
- if (sc->flags & PCIC_RICOH_POWER) {
- /*
- * The ISA bridge have the 5V/3.3V in register
- * 1, bit 7. However, 3.3V cards can only be
- * detected if GPI_EN is disabled.
- */
- c = sp->getb(sp, PCIC_STATUS);
- c2 = sp->getb(sp, PCIC_CDGC);
- if ((c & PCIC_RICOH_5VCARD) && (c2 & PCIC_GPI_EN) == 0)
- slt->pwr.vcc = 33;
- else
- slt->pwr.vcc = 50;
- }
- /* Other power schemes here */
-
- if (bootverbose && slt->pwr.vcc != -1)
- device_printf(sc->dev, "Autodetected %d.%dV card\n",
- slt->pwr.vcc / 10, slt->pwr.vcc %10);
- }
- if (slt->pwr.vcc == -1) {
- if (bootverbose)
- device_printf(sc->dev,
- "Couldn't autodetect voltage, assuming 5.0V\n");
- dodefault = 1;
- slt->pwr.vcc = 50;
- }
-
- /*
- * XXX Note: The Vpp controls varies quit a bit between bridge chips
- * and the following might not be right in all cases. The Linux
- * code and wildboar code bases are more complex. However, most
- * applications want vpp == vcc and the following code does appear
- * to do that for all bridge sets.
- */
- if (slt->pwr.vpp == -1)
- slt->pwr.vpp = slt->pwr.vcc;
- switch(slt->pwr.vpp) {
- default:
- return (EINVAL);
- case 0:
- break;
- case 50:
- case 33:
- reg |= PCIC_VPP_5V;
- break;
- case 120:
- reg |= PCIC_VPP_12V;
- break;
- }
-
- if (slt->pwr.vcc)
- reg |= PCIC_VCC_ON; /* Turn on Vcc */
- switch(slt->pwr.vcc) {
- default:
- return (EINVAL);
- case 0:
- break;
- case 33:
- /*
- * The wildboar code has comments that state that
- * the IBM KING controller doesn't support 3.3V
- * on the "IBM Smart PC card drive". The code
- * intemates that's the only place they have seen
- * it used and that there's a boatload of issues
- * with it. I'm not even sure this is right because
- * the only docs I've been able to find say this is for
- * 5V power. Of course, this "doc" is just code comments
- * so who knows for sure.
- */
- if (sc->flags & PCIC_KING_POWER) {
- reg |= PCIC_VCC_5V_KING;
- break;
- }
- if (sc->flags & PCIC_VG_POWER) {
- pcic_setb(sp, PCIC_CVSR, PCIC_CVSR_VS);
- break;
- }
- if (sc->flags & PCIC_PD_POWER) {
- pcic_setb(sp, PCIC_MISC1, PCIC_MISC1_VCC_33);
- break;
- }
- if (sc->flags & PCIC_RICOH_POWER) {
- pcic_setb(sp, PCIC_RICOH_MCR2, PCIC_MCR2_VCC_33);
- break;
- }
- if (sc->flags & PCIC_DF_POWER)
- reg |= PCIC_VCC_3V;
- break;
- case 50:
- if (sc->flags & PCIC_KING_POWER)
- reg |= PCIC_VCC_5V_KING;
- /*
- * For all of the variant power schemes for 3.3V go
- * ahead and turn off the 3.3V enable bit. For all
- * bridges, the setting the Vcc on bit does the rest.
- * Note that we don't have to turn off the 3.3V bit
- * for the '365 step D since with the reg assigments
- * to this point it doesn't get turned on.
- */
- if (sc->flags & PCIC_VG_POWER)
- pcic_clrb(sp, PCIC_CVSR, PCIC_CVSR_VS);
- if (sc->flags & PCIC_PD_POWER)
- pcic_clrb(sp, PCIC_MISC1, PCIC_MISC1_VCC_33);
- if (sc->flags & PCIC_RICOH_POWER)
- pcic_clrb(sp, PCIC_RICOH_MCR2, PCIC_MCR2_VCC_33);
- break;
- }
- sp->putb(sp, PCIC_POWER, reg);
- if (bootverbose)
- device_printf(sc->dev, "Power applied\n");
- DELAY(300*1000);
- if (slt->pwr.vcc) {
- reg |= PCIC_OUTENA;
- sp->putb(sp, PCIC_POWER, reg);
- if (bootverbose)
- device_printf(sc->dev, "Output enabled\n");
- DELAY(100*1000);
- if (bootverbose)
- device_printf(sc->dev, "Settling complete\n");
- }
-
- /*
- * Some chipsets will attempt to preclude us from supplying
- * 5.0V to cards that only handle 3.3V. We seem to need to
- * try 3.3V to paper over some power handling issues in other
- * parts of the system. Maybe the proper detection of 3.3V cards
- * now obviates the need for this hack, so put a printf in to
- * warn the world about it.
- */
- if (!(sp->getb(sp, PCIC_STATUS) & PCIC_POW) && dodefault) {
- slt->pwr.vcc = 33;
- slt->pwr.vpp = 0;
- device_printf(sc->dev,
- "Failed at 5.0V. Trying 3.3V. Please report message to mobile@freebsd.org\n");
- return (pcic_power(slt));
- }
- if (bootverbose)
- printf("Power complete.\n");
- return (0);
-}
-
-/*
- * tell the PCIC which irq we want to use. only the following are legal:
- * 3, 4, 5, 7, 9, 10, 11, 12, 14, 15. We require the callers of this
- * routine to do the check for legality.
- */
-static void
-pcic_mapirq(struct slot *slt, int irq)
-{
- struct pcic_slot *sp = slt->cdata;
-
- sp->sc->chip->map_irq(sp, irq);
-}
-
-/*
- * pcic_reset - Reset the card and enable initial power. This may
- * need to be interrupt driven in the future. We should likely turn
- * the reset on, DELAY for a period of time < 250ms, turn it off and
- * tsleep for a while and check it when we're woken up. I think that
- * we're running afoul of the card status interrupt glitching, causing
- * an interrupt storm because the card doesn't seem to be able to
- * clear this pin while in reset.
- */
-static void
-pcic_reset(void *chan)
-{
- struct slot *slt = chan;
- struct pcic_slot *sp = slt->cdata;
-
- if (bootverbose)
- device_printf(sp->sc->dev, "reset %d ", slt->insert_seq);
- switch (slt->insert_seq) {
- case 0: /* Something funny happended on the way to the pub... */
- if (bootverbose)
- printf("\n");
- return;
- case 1: /* Assert reset */
- pcic_clrb(sp, PCIC_INT_GEN, PCIC_CARDRESET);
- if (bootverbose)
- printf("int is %x stat is %x\n",
- sp->getb(sp, PCIC_INT_GEN),
- sp->getb(sp, PCIC_STATUS));
- slt->insert_seq = 2;
- timeout(pcic_reset, (void *)slt, hz/4);
- return;
- case 2: /* Deassert it again */
- pcic_setb(sp, PCIC_INT_GEN, PCIC_CARDRESET | PCIC_IOCARD);
- if (bootverbose)
- printf("int is %x stat is %x\n",
- sp->getb(sp, PCIC_INT_GEN),
- sp->getb(sp, PCIC_STATUS));
- slt->insert_seq = 3;
- timeout(pcic_reset, (void *)slt, hz/4);
- return;
- case 3: /* Wait if card needs more time */
- if (bootverbose)
- printf("int is %x stat is %x\n",
- sp->getb(sp, PCIC_INT_GEN),
- sp->getb(sp, PCIC_STATUS));
- if ((sp->getb(sp, PCIC_STATUS) & PCIC_READY) == 0) {
- timeout(pcic_reset, (void *)slt, hz/10);
- return;
- }
- }
- slt->insert_seq = 0;
- if (sp->controller == PCIC_PD6722 || sp->controller == PCIC_PD6710) {
- sp->putb(sp, PCIC_TIME_SETUP0, 0x1);
- sp->putb(sp, PCIC_TIME_CMD0, 0x6);
- sp->putb(sp, PCIC_TIME_RECOV0, 0x0);
- sp->putb(sp, PCIC_TIME_SETUP1, 1);
- sp->putb(sp, PCIC_TIME_CMD1, 0xf);
- sp->putb(sp, PCIC_TIME_RECOV1, 0);
- }
- selwakeuppri(&slt->selp, PZERO);
-}
-
-/*
- * pcic_disable - Disable the slot. I wonder if these operations can
- * cause an interrupt we need to acknowledge? XXX
- */
-static void
-pcic_disable(struct slot *slt)
-{
- struct pcic_slot *sp = slt->cdata;
-
- pcic_clrb(sp, PCIC_INT_GEN, PCIC_CARDTYPE | PCIC_CARDRESET);
- pcic_mapirq(slt, 0);
- slt->pwr.vcc = slt->pwr.vpp = 0;
- pcic_power(slt);
-}
-
-/*
- * pcic_resume - Suspend/resume support for PCIC
- */
-static void
-pcic_resume(struct slot *slt)
-{
- struct pcic_slot *sp = slt->cdata;
-
- pcic_do_mgt_irq(sp, slt->irq);
- if (sp->controller == PCIC_PD6722) {
- pcic_setb(sp, PCIC_MISC1, PCIC_MISC1_SPEAKER);
- pcic_setb(sp, PCIC_MISC2, PCIC_LPDM_EN);
- }
- if (sp->slt->state != inactive)
- pcic_do_stat_delta(sp);
-}
-
-int
-pcic_activate_resource(device_t dev, device_t child, int type, int rid,
- struct resource *r)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- int err;
-
- if (dev != device_get_parent(device_get_parent(child)) || devi == NULL)
- return (bus_generic_activate_resource(dev, child, type,
- rid, r));
-
- switch (type) {
- case SYS_RES_IOPORT: {
- struct io_desc *ip;
- ip = &devi->slt->io[rid];
- if (ip->flags == 0) {
- if (rid == 0)
- ip->flags = IODF_WS | IODF_16BIT | IODF_CS16;
- else
- ip->flags = devi->slt->io[0].flags;
- }
- ip->flags |= IODF_ACTIVE;
- ip->start = rman_get_start(r);
- ip->size = rman_get_end(r) - rman_get_start(r) + 1;
- err = pcic_io(devi->slt, rid);
- if (err)
- return (err);
- break;
- }
- case SYS_RES_IRQ:
- /*
- * We actually defer the activation of the IRQ resource
- * until the interrupt is registered to avoid stray
- * interrupt messages.
- */
- break;
- case SYS_RES_MEMORY: {
- struct mem_desc *mp;
- if (rid >= NUM_MEM_WINDOWS)
- return (EINVAL);
- mp = &devi->slt->mem[rid];
- mp->flags |= MDF_ACTIVE;
- mp->start = (caddr_t) rman_get_start(r);
- mp->size = rman_get_end(r) - rman_get_start(r) + 1;
- err = pcic_memory(devi->slt, rid);
- if (err)
- return (err);
- break;
- }
- default:
- break;
- }
- err = bus_generic_activate_resource(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 pccard_devinfo *devi = device_get_ivars(child);
- int err;
-
- if (dev != device_get_parent(device_get_parent(child)) || devi == NULL)
- return (bus_generic_deactivate_resource(dev, child, type,
- rid, r));
-
- switch (type) {
- case SYS_RES_IOPORT: {
- struct io_desc *ip = &devi->slt->io[rid];
- ip->flags &= ~IODF_ACTIVE;
- err = pcic_io(devi->slt, rid);
- if (err)
- return (err);
- break;
- }
- case SYS_RES_IRQ:
- break;
- case SYS_RES_MEMORY: {
- struct mem_desc *mp = &devi->slt->mem[rid];
- mp->flags &= ~(MDF_ACTIVE | MDF_ATTR);
- err = pcic_memory(devi->slt, rid);
- if (err)
- return (err);
- break;
- }
- default:
- break;
- }
- err = bus_generic_deactivate_resource(dev, child, type, rid, r);
- return (err);
-}
-
-int
-pcic_setup_intr(device_t dev, device_t child, struct resource *irq,
- int flags, driver_intr_t *intr, void *arg, void **cookiep)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- int err;
-
- if (((1 << rman_get_start(irq)) & PCIC_INT_MASK_ALLOWED) == 0) {
- device_printf(dev, "Hardware does not support irq %ld.\n",
- rman_get_start(irq));
- return (EINVAL);
- }
-
- err = bus_generic_setup_intr(dev, child, irq, flags, intr, arg,
- cookiep);
- if (err == 0)
- pcic_mapirq(devi->slt, rman_get_start(irq));
- else
- device_printf(dev, "Error %d irq %ld\n", err,
- rman_get_start(irq));
- return (err);
-}
-
-int
-pcic_teardown_intr(device_t dev, device_t child, struct resource *irq,
- void *cookie)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
-
- pcic_mapirq(devi->slt, 0);
- return (bus_generic_teardown_intr(dev, child, irq, cookie));
-}
-
-int
-pcic_set_res_flags(device_t bus, device_t child, int restype, int rid,
- u_long value)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- int err = 0;
-
- switch (restype) {
- case SYS_RES_MEMORY: {
- struct mem_desc *mp = &devi->slt->mem[rid];
- switch (value) {
- case PCCARD_A_MEM_COM:
- mp->flags &= ~MDF_ATTR;
- break;
- case PCCARD_A_MEM_ATTR:
- mp->flags |= MDF_ATTR;
- break;
- case PCCARD_A_MEM_8BIT:
- mp->flags &= ~MDF_16BITS;
- break;
- case PCCARD_A_MEM_16BIT:
- mp->flags |= MDF_16BITS;
- break;
- }
- err = pcic_memory(devi->slt, rid);
- break;
- }
- default:
- err = EOPNOTSUPP;
- }
- return (err);
-}
-
-int
-pcic_get_res_flags(device_t bus, device_t child, int restype, int rid,
- u_long *value)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- int err = 0;
-
- if (value == 0)
- return (ENOMEM);
-
- switch (restype) {
- case SYS_RES_IOPORT: {
- struct io_desc *ip = &devi->slt->io[rid];
- *value = ip->flags;
- break;
- }
- case SYS_RES_MEMORY: {
- struct mem_desc *mp = &devi->slt->mem[rid];
- *value = mp->flags;
- break;
- }
- default:
- err = EOPNOTSUPP;
- }
- return (err);
-}
-
-int
-pcic_set_memory_offset(device_t bus, device_t child, int rid, u_int32_t offset
-#if __FreeBSD_version >= 500000
- ,u_int32_t *deltap
-#endif
- )
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- struct mem_desc *mp = &devi->slt->mem[rid];
-
- mp->card = offset;
-#if __FreeBSD_version >= 500000
- if (deltap)
- *deltap = 0; /* XXX BAD XXX */
-#endif
- return (pcic_memory(devi->slt, rid));
-}
-
-int
-pcic_get_memory_offset(device_t bus, device_t child, int rid, u_int32_t *offset)
-{
- struct pccard_devinfo *devi = device_get_ivars(child);
- struct mem_desc *mp = &devi->slt->mem[rid];
-
- if (offset == 0)
- return (ENOMEM);
-
- *offset = mp->card;
-
- return (0);
-}
-
-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)
-{
- struct pcic_softc *sc = device_get_softc(dev);
-
- /*
- * If we're routing via pci, we can share.
- */
- if (sc->func_route == pcic_iw_pci && type == SYS_RES_IRQ) {
- if (bootverbose)
- device_printf(child, "Forcing IRQ to %d\n", sc->irq);
- start = end = sc->irq;
- flags |= RF_SHAREABLE;
- }
-
- return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
- count, flags));
-}
-
-void
-pcic_do_stat_delta(struct pcic_slot *sp)
-{
- if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) != PCIC_CD)
- pccard_event(sp->slt, card_removed);
- else
- pccard_event(sp->slt, card_inserted);
-}
-/*
- * Wrapper function for pcicintr so that signatures match.
- */
-void
-pcic_isa_intr(void *arg)
-{
- pcic_isa_intr1(arg);
-}
-
-/*
- * PCIC timer. If the controller doesn't have a free IRQ to use
- * or if interrupt steering doesn't work, poll the controller for
- * insertion/removal events.
- */
-void
-pcic_timeout(void *chan)
-{
- struct pcic_softc *sc = (struct pcic_softc *) chan;
-
- if (pcic_isa_intr1(chan) != 0) {
- device_printf(sc->dev,
- "Static bug detected, ignoring hardware.");
- sc->slot_poll = 0;
- return;
- }
- sc->timeout_ch = timeout(sc->slot_poll, chan, hz/2);
-}
-
-/*
- * PCIC Interrupt handler.
- * Check each slot in turn, and read the card status change
- * register. If this is non-zero, then a change has occurred
- * on this card, so send an event to the main code.
- */
-int
-pcic_isa_intr1(void *arg)
-{
- int slot, s;
- u_int8_t chg;
- struct pcic_softc *sc = (struct pcic_softc *) arg;
- struct pcic_slot *sp = &sc->slots[0];
-
- s = splhigh();
- for (slot = 0; slot < PCIC_CARD_SLOTS; slot++, sp++) {
- if (sp->slt == NULL)
- continue;
- if ((chg = sp->getb(sp, PCIC_STAT_CHG)) != 0) {
- /*
- * if chg is 0xff, then we know that we've hit
- * the famous "static bug" for some desktop
- * pcmcia cards. This is caused by static
- * discharge frying the poor card's mind and
- * it starts return 0xff forever. We return
- * an error and stop polling the card. When
- * we're interrupt based, we never see this.
- * The card just goes away silently.
- */
- if (chg == 0xff) {
- splx(s);
- return (EIO);
- }
- if (chg & PCIC_CDTCH)
- pcic_do_stat_delta(sp);
- }
- }
- splx(s);
- return (0);
-}
-
-int
-pcic_isa_mapirq(struct pcic_slot *sp, int irq)
-{
- irq = host_irq_to_pcic(irq);
- if (irq == 0)
- pcic_clrb(sp, PCIC_INT_GEN, 0xF);
- else
- sp->putb(sp, PCIC_INT_GEN,
- (sp->getb(sp, PCIC_INT_GEN) & 0xF0) | irq);
- return (0);
-}
diff --git a/sys/pccard/pcic_isa.c b/sys/pccard/pcic_isa.c
deleted file mode 100644
index a013346..0000000
--- a/sys/pccard/pcic_isa.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*-
- * Copyright (c) 2001 M. Warner Losh. 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.
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#define OBSOLETE_IN_6
-
-#include <sys/param.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/sysctl.h>
-#include <sys/systm.h>
-
-#include <pccard/i82365.h>
-#include <pccard/cardinfo.h>
-#include <pccard/slot.h>
-#include <pccard/pcicvar.h>
-
-/* Get pnp IDs */
-#include <isa/isavar.h>
-
-#include <dev/pccard/pccardvar.h>
-#include "card_if.h"
-
-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 */
- {PCIC_NEC_PC9801_102, NULL}, /* NEC8091 */
- {PCIC_NEC_PC9821RA_E01, NULL}, /* NEC8121 */
- {0}
-};
-
-static struct {
- const char *name;
- u_int32_t flags;
-} bridges[] = {
- { "Intel i82365SL-A/B", PCIC_AB_POWER},
- { "IBM PCIC", PCIC_AB_POWER},
- { "VLSI 82C146", PCIC_AB_POWER},
- { "Cirrus logic 6722", PCIC_PD_POWER},
- { "Cirrus logic 6710", PCIC_PD_POWER},
- { "Vadem 365", PCIC_VG_POWER},
- { "Vadem 465", PCIC_VG_POWER},
- { "Vadem 468", PCIC_VG_POWER},
- { "Vadem 469", PCIC_VG_POWER},
- { "Ricoh RF5C296", PCIC_RICOH_POWER},
- { "Ricoh RF5C396", PCIC_RICOH_POWER},
- { "IBM KING", PCIC_KING_POWER},
- { "Intel i82365SL-DF", PCIC_DF_POWER}
-};
-
-static pcic_intr_way_t pcic_isa_intr_way;
-static pcic_init_t pcic_isa_init;
-
-struct pcic_chip pcic_isa_chip = {
- pcic_isa_intr_way,
- pcic_isa_intr_way,
- pcic_isa_mapirq,
- pcic_isa_init
-};
-
-/*
- * Look for an Intel PCIC (or compatible).
- * For each available slot, allocate a PC-CARD slot.
- */
-static int
-pcic_isa_probe(device_t dev)
-{
- int slotnum, validslots = 0;
- struct pcic_slot *sp;
- struct pcic_slot *sp0;
- struct pcic_slot *sp1;
- struct pcic_slot spsave;
- unsigned char c;
- struct resource *r;
- int rid;
- struct pcic_softc *sc;
- int error;
-
- /* Check isapnp ids */
- error = ISA_PNP_PROBE(device_get_parent(dev), dev, pcic_ids);
- if (error == ENXIO)
- return (ENXIO);
-
- if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0)
- bus_set_resource(dev, SYS_RES_IOPORT, 0, PCIC_PORT_0,
- PCIC_NPORT);
- rid = 0;
- r = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
- if (!r) {
- if (bootverbose)
- device_printf(dev, "Cannot get I/O range\n");
- return (ENOMEM);
- }
-
- sc = (struct pcic_softc *) device_get_softc(dev);
- sc->dev = dev;
- sp = &sc->slots[0];
- for (slotnum = 0; slotnum < PCIC_CARD_SLOTS; slotnum++, sp++) {
- /*
- * Initialise the PCIC slot table.
- */
- sp->getb = pcic_getb_io;
- sp->putb = pcic_putb_io;
- sp->bst = rman_get_bustag(r);
- sp->bsh = rman_get_bushandle(r);
- sp->offset = slotnum * PCIC_SLOT_SIZE;
- sp->controller = -1;
- }
-
- /*
- * Prescan for the broken VLSI chips.
- *
- * According to the Linux PCMCIA code from David Hinds,
- * working chipsets return 0x84 from their (correct) ID ports,
- * while the broken ones would need to be probed at the new
- * offset we set after we assume it's broken.
- *
- * Note: because of this, we may incorrectly detect a single
- * slot vlsi chip as an i82365sl step D. I cannot find a
- * datasheet for the affected chip, so that's the best we can
- * do for now.
- */
- sp0 = &sc->slots[0];
- sp1 = &sc->slots[1];
- if (sp0->getb(sp0, PCIC_ID_REV) == PCIC_VLSI82C146 &&
- sp1->getb(sp1, PCIC_ID_REV) != PCIC_VLSI82C146) {
- spsave = *sp1;
- sp1->bsh += 4;
- sp1->offset = PCIC_SLOT_SIZE << 1;
- if (sp1->getb(sp1, PCIC_ID_REV) != PCIC_VLSI82C146) {
- *sp1 = spsave;
- } else {
- sp0->controller = PCIC_VLSI;
- sp1->controller = PCIC_VLSI;
- }
- }
-
- /*
- * Look for normal chipsets here.
- */
- sp = &sc->slots[0];
- for (slotnum = 0; slotnum < PCIC_CARD_SLOTS; slotnum++, sp++) {
- /*
- * see if there's a PCMCIA controller here
- * Intel PCMCIA controllers use 0x82 and 0x83
- * IBM clone chips use 0x88 and 0x89, apparently
- */
- c = sp->getb(sp, PCIC_ID_REV);
- sp->revision = -1;
- switch(c) {
- /*
- * 82365 or clones.
- */
- case PCIC_INTEL0:
- case PCIC_INTEL1:
- sp->controller = PCIC_I82365;
- sp->revision = c & 1;
- /*
- * Check for Vadem chips by unlocking their extra
- * registers and looking for valid ID. Bit 3 in
- * the ID register is normally 0, except when
- * PCIC_VADEMREV is set. Other bridges appear
- * to ignore this frobbing.
- */
- bus_space_write_1(sp->bst, sp->bsh, PCIC_INDEX, 0x0E);
- bus_space_write_1(sp->bst, sp->bsh, PCIC_INDEX, 0x37);
- pcic_setb(sp, PCIC_VMISC, PCIC_VADEMREV);
- c = sp->getb(sp, PCIC_ID_REV);
- if (c & 0x08) {
- switch (sp->revision = c & 7) {
- case 1:
- sp->controller = PCIC_VG365;
- break;
- case 2:
- sp->controller = PCIC_VG465;
- break;
- case 3:
- sp->controller = PCIC_VG468;
- break;
- default:
- sp->controller = PCIC_VG469;
- break;
- }
- pcic_clrb(sp, PCIC_VMISC, PCIC_VADEMREV);
- }
-
- /*
- * Check for RICOH RF5C[23]96 PCMCIA Controller
- */
- c = sp->getb(sp, PCIC_RICOH_ID);
- if (c == PCIC_RID_396)
- sp->controller = PCIC_RF5C396;
- else if (c == PCIC_RID_296)
- sp->controller = PCIC_RF5C296;
-
- break;
- /*
- * Intel i82365sl-DF step or maybe a vlsi 82c146
- * we detected the vlsi case earlier, so if the controller
- * isn't set, we know it is an i82365sl step D.
- */
- case PCIC_INTEL2:
- if (sp->controller == -1)
- sp->controller = PCIC_I82365SL_DF;
- break;
- case PCIC_IBM1:
- case PCIC_IBM2:
- sp->controller = PCIC_IBM;
- sp->revision = c & 1;
- break;
- case PCIC_IBM3:
- sp->controller = PCIC_IBM_KING;
- sp->revision = c & 1;
- break;
- default:
- continue;
- }
- /*
- * Check for Cirrus logic chips.
- */
- sp->putb(sp, PCIC_CLCHIP, 0);
- c = sp->getb(sp, PCIC_CLCHIP);
- if ((c & PCIC_CLC_TOGGLE) == PCIC_CLC_TOGGLE) {
- c = sp->getb(sp, PCIC_CLCHIP);
- if ((c & PCIC_CLC_TOGGLE) == 0) {
- if (c & PCIC_CLC_DUAL)
- sp->controller = PCIC_PD6722;
- else
- sp->controller = PCIC_PD6710;
- sp->revision = 8 - ((c & 0x1F) >> 2);
- }
- }
- device_set_desc(dev, bridges[(int) sp->controller].name);
- sc->flags = bridges[(int) sp->controller].flags;
- /*
- * OK it seems we have a PCIC or lookalike.
- * Allocate a slot and initialise the data structures.
- */
- validslots++;
- sp->slt = (struct slot *) 1;
- /*
- * Modem cards send the speaker audio (dialing noises)
- * to the host's speaker. Cirrus Logic PCIC chips must
- * enable this. There is also a Low Power Dynamic Mode bit
- * that claims to reduce power consumption by 30%, so
- * enable it and hope for the best.
- */
- if (sp->controller == PCIC_PD6722) {
- pcic_setb(sp, PCIC_MISC1, PCIC_MISC1_SPEAKER);
- pcic_setb(sp, PCIC_MISC2, PCIC_LPDM_EN);
- }
- }
- bus_release_resource(dev, SYS_RES_IOPORT, rid, r);
- return (validslots ? 0 : ENXIO);
-}
-
-static int
-pcic_isa_attach(device_t dev)
-{
- struct pcic_softc *sc;
- int rid;
- struct resource *r;
- int irq = 0;
- int error;
-
- sc = device_get_softc(dev);
- rid = 0;
- r = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
- if (!r) {
- pcic_dealloc(dev);
- return (ENXIO);
- }
- sc->iorid = rid;
- sc->iores = r;
- sc->csc_route = pcic_iw_isa;
- sc->func_route = pcic_iw_isa;
- sc->chip = &pcic_isa_chip;
-
- rid = 0;
- r = NULL;
- r = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE);
- if (r == NULL && pcic_override_irq != 0) {
- irq = pcic_override_irq;
- r = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq, irq, 1,
- RF_ACTIVE);
- }
- if (r && ((1 << (rman_get_start(r))) & PCIC_INT_MASK_ALLOWED) == 0) {
- device_printf(dev,
- "Hardware does not support irq %d, trying polling.\n",
- irq);
- bus_release_resource(dev, SYS_RES_IRQ, rid, r);
- irq = 0;
- r = NULL;
- }
- sc->irqrid = rid;
- sc->irqres = r;
- irq = 0;
- if (r != NULL) {
- error = bus_setup_intr(dev, r, INTR_TYPE_MISC,
- pcic_isa_intr, (void *) sc, &sc->ih);
- if (error) {
- pcic_dealloc(dev);
- return (error);
- }
- irq = rman_get_start(r);
- device_printf(dev, "management irq %d\n", irq);
- }
- sc->irq = irq;
- if (irq == 0) {
- sc->slot_poll = pcic_timeout;
- sc->timeout_ch = timeout(sc->slot_poll, (void *) sc, hz/2);
- device_printf(dev, "Polling mode\n");
- }
-
- return (pcic_attach(dev));
-}
-
-/*
- * ISA cards can only do ISA interrupts. There's no need to do
- * anything but check args for sanity.
- */
-static int
-pcic_isa_intr_way(struct pcic_slot *sp, enum pcic_intr_way iw)
-{
- if (iw != pcic_iw_isa)
- return (EINVAL);
- return (0);
-}
-
-/*
- * No speicial initialization is necesary for ISA cards.
- */
-static void
-pcic_isa_init(device_t dev)
-{
-}
-
-static device_method_t pcic_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, pcic_isa_probe),
- DEVMETHOD(device_attach, pcic_isa_attach),
- DEVMETHOD(device_detach, bus_generic_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_alloc_resource, pcic_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_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),
-
- /* Card interface */
- DEVMETHOD(card_set_res_flags, pcic_set_res_flags),
- DEVMETHOD(card_get_res_flags, pcic_get_res_flags),
- DEVMETHOD(card_set_memory_offset, pcic_set_memory_offset),
- DEVMETHOD(card_get_memory_offset, pcic_get_memory_offset),
-
- { 0, 0 }
-};
-
-static driver_t pcic_driver = {
- "pcic",
- pcic_methods,
- sizeof(struct pcic_softc)
-};
-
-DRIVER_MODULE(pcic, isa, pcic_driver, pcic_devclass, 0, 0);
diff --git a/sys/pccard/pcic_pci.c b/sys/pccard/pcic_pci.c
deleted file mode 100644
index 227043f..0000000
--- a/sys/pccard/pcic_pci.c
+++ /dev/null
@@ -1,1586 +0,0 @@
-/*-
- * Copyright (c) 2000, 2002 M. Warner Losh. All Rights Reserved.
- * Copyright (c) 1997 Ted Faber 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 immediately at the beginning of the file, without modification,
- * 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. Absolutely no warranty of function or purpose is made by the author
- * Ted Faber.
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#define OBSOLETE_IN_6
-
-#include <sys/param.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/sysctl.h>
-#include <sys/systm.h>
-
-#if __FreeBSD_version < 500000
-#include <pci/pcireg.h>
-#include <pci/pcivar.h>
-#else
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-#endif
-
-#include <pccard/pcic_pci.h>
-#include <pccard/i82365.h>
-#include <pccard/cardinfo.h>
-#include <pccard/slot.h>
-#include <pccard/pcicvar.h>
-
-#include <dev/pccard/pccardvar.h>
-#include "card_if.h"
-
-#define PRVERB(x) do { \
- if (bootverbose) { device_printf x; } \
- } while (0)
-
-static int pcic_pci_get_memory(device_t dev);
-
-SYSCTL_DECL(_hw_pcic);
-
-static int pcic_ignore_function_1 = 0;
-TUNABLE_INT("hw.pcic.ignore_function_1", &pcic_ignore_function_1);
-SYSCTL_INT(_hw_pcic, OID_AUTO, ignore_function_1, CTLFLAG_RDTUN,
- &pcic_ignore_function_1, 0,
- "When set, driver ignores pci function 1 of the bridge. This option\n\
-is obsolete and will be deleted before FreeBSD 4.8.");
-
-/*
- * The following should be a hint, so we can do it on a per device
- * instance, but this is convenient. Do not set this unless pci
- * routing doesn't work. It is purposely vague and undocumented
- * at the moment. Sadly, this seems to be needed way too often.
- */
-static int pcic_intr_path = (int)pcic_iw_pci;
-TUNABLE_INT("hw.pcic.intr_path", &pcic_intr_path);
-SYSCTL_INT(_hw_pcic, OID_AUTO, intr_path, CTLFLAG_RDTUN, &pcic_intr_path, 0,
- "Which path to send the interrupts over. Normally interrupts for\n\
-cardbus bridges are routed over the PCI bus (2). However, some laptops\n\
-will hang when using PCI interrupts due to bugs in this code. Those\n\
-bugs can be worked around by forcings ISA interrupts (1).");
-
-static int pcic_init_routing = 0;
-TUNABLE_INT("hw.pcic.init_routing", &pcic_init_routing);
-SYSCTL_INT(_hw_pcic, OID_AUTO, init_routing, CTLFLAG_RDTUN,
- &pcic_init_routing, 0,
- "Force the interrupt routing to be initialized on those bridges where\n\
-doing so will cause probelms. This is very rare and generally is not\n\
-needed. The default of 0 is almost always appropriate. Only set to 1 if\n\
-instructed to do so for debugging. Only TI bridges are affected by this\n\
-option, and what the code does is of dubious value. This option is obsolete\n\
-and will be deleted before FreeBSD 4.8.");
-
-static int pcic_ignore_pci = 0;
-TUNABLE_INT("hw.pcic.ignore_pci", &pcic_ignore_pci);
-SYSCTL_INT(_hw_pcic, OID_AUTO, ignore_pci, CTLFLAG_RDTUN,
- &pcic_ignore_pci, 0,
- "When set, driver ignores pci cardbus bridges it would otherwise claim.\n\
-Generally speaking, this option is not needed for anything other than as an\n\
-aid in debugging.");
-
-static int pcic_pd6729_intr_path = (int)pcic_iw_isa;
-TUNABLE_INT("hw.pcic.pd6729_intr_path", &pcic_pd6729_intr_path);
-SYSCTL_INT(_hw_pcic, OID_AUTO, pd6729_intr_path, CTLFLAG_RDTUN,
- &pcic_pd6729_intr_path, 0,
- "Determine the interrupt path or method for Cirrus Logic PD6729 and\n\
-similar I/O space based pcmcia bridge. Chips on a PCI expansion card need\n\
-a value of 2, while chips installed in a laptop need a value of 1 (which is\n\
-also the default). This is similar to hw.pcic.intr_path, but separate so\n\
-that it can default to ISA when intr_path defaults to PCI.");
-
-static int pcic_ti12xx_enable_pci_clock = 0;
-TUNABLE_INT("hw.pcic.ti12xx_enable_pci_clock", &pcic_ti12xx_enable_pci_clock);
-SYSCTL_INT(_hw_pcic, OID_AUTO, ti12xx_enable_pci_clock, CTLFLAG_RDTUN,
- &pcic_ti12xx_enable_pci_clock, 0,
- "Some TI-12xx parts need to have the PCI clock enabled. These designs do\n\
-not provide a clock themselves. Most of the reference boards have the\n\
-required oscillator parts, so the number of machines that needs this to be\n\
-set is vanishingly small.");
-
-static void pcic_pci_cardbus_init(device_t);
-static pcic_intr_way_t pcic_pci_gen_func;
-static pcic_intr_way_t pcic_pci_gen_csc;
-static pcic_intr_mapirq_t pcic_pci_gen_mapirq;
-
-static pcic_intr_way_t pcic_pci_oz67xx_func;
-static pcic_intr_way_t pcic_pci_oz67xx_csc;
-static pcic_init_t pcic_pci_oz67xx_init;
-
-static pcic_intr_way_t pcic_pci_oz68xx_func;
-static pcic_intr_way_t pcic_pci_oz68xx_csc;
-static pcic_init_t pcic_pci_oz68xx_init;
-
-static pcic_intr_way_t pcic_pci_pd6729_func;
-static pcic_intr_way_t pcic_pci_pd6729_csc;
-static pcic_init_t pcic_pci_pd6729_init;
-
-static pcic_intr_way_t pcic_pci_pd68xx_func;
-static pcic_intr_way_t pcic_pci_pd68xx_csc;
-static pcic_init_t pcic_pci_pd68xx_init;
-
-static pcic_intr_way_t pcic_pci_ricoh_func;
-static pcic_intr_way_t pcic_pci_ricoh_csc;
-static pcic_init_t pcic_pci_ricoh_init;
-
-static pcic_intr_way_t pcic_pci_ti113x_func;
-static pcic_intr_way_t pcic_pci_ti113x_csc;
-static pcic_init_t pcic_pci_ti_init;
-
-static pcic_intr_way_t pcic_pci_ti12xx_func;
-static pcic_intr_way_t pcic_pci_ti12xx_csc;
-
-static pcic_intr_way_t pcic_pci_topic_func;
-static pcic_intr_way_t pcic_pci_topic_csc;
-static pcic_init_t pcic_pci_topic_init;
-
-static struct pcic_chip pcic_pci_oz67xx_chip = {
- pcic_pci_oz67xx_func,
- pcic_pci_oz67xx_csc,
- pcic_pci_gen_mapirq,
- pcic_pci_oz67xx_init
-};
-
-static struct pcic_chip pcic_pci_oz68xx_chip = {
- pcic_pci_oz68xx_func,
- pcic_pci_oz68xx_csc,
- pcic_pci_gen_mapirq,
- pcic_pci_oz68xx_init
-};
-
-static struct pcic_chip pcic_pci_pd6729_chip = {
- pcic_pci_pd6729_func,
- pcic_pci_pd6729_csc,
- pcic_pci_gen_mapirq,
- pcic_pci_pd6729_init
-};
-
-static struct pcic_chip pcic_pci_pd68xx_chip = {
- pcic_pci_pd68xx_func,
- pcic_pci_pd68xx_csc,
- pcic_pci_gen_mapirq,
- pcic_pci_pd68xx_init
-};
-
-static struct pcic_chip pcic_pci_ricoh_chip = {
- pcic_pci_ricoh_func,
- pcic_pci_ricoh_csc,
- pcic_pci_gen_mapirq,
- pcic_pci_ricoh_init
-};
-
-static struct pcic_chip pcic_pci_ti113x_chip = {
- pcic_pci_ti113x_func,
- pcic_pci_ti113x_csc,
- pcic_pci_gen_mapirq,
- pcic_pci_ti_init
-};
-
-static struct pcic_chip pcic_pci_ti12xx_chip = {
- pcic_pci_ti12xx_func,
- pcic_pci_ti12xx_csc,
- pcic_pci_gen_mapirq,
- pcic_pci_ti_init
-};
-
-static struct pcic_chip pcic_pci_topic_chip = {
- pcic_pci_topic_func,
- pcic_pci_topic_csc,
- pcic_pci_gen_mapirq,
- pcic_pci_topic_init
-};
-
-static struct pcic_chip pcic_pci_generic_chip = {
- pcic_pci_gen_func,
- pcic_pci_gen_csc,
- pcic_pci_gen_mapirq,
- pcic_pci_cardbus_init
-};
-
-/* Chipset specific flags */
-#define TI_NO_MFUNC 0x10000
-
-struct pcic_pci_table
-{
- u_int32_t devid;
- const char *descr;
- int type;
- u_int32_t flags;
- struct pcic_chip *chip;
-} pcic_pci_devs[] = {
- { PCIC_ID_OMEGA_82C094, "Omega 82C094G",
- PCIC_I82365, PCIC_DF_POWER, &pcic_pci_pd6729_chip },
- { PCIC_ID_CLPD6729, "Cirrus Logic PD6729/6730 PCI-PCMCIA Bridge",
- PCIC_PD6729, PCIC_PD_POWER, &pcic_pci_pd6729_chip },
- { PCIC_ID_CLPD6832, "Cirrus Logic PD6832 PCI-CardBus Bridge",
- PCIC_PD673X, PCIC_CARDBUS_POWER, &pcic_pci_pd68xx_chip },
- { PCIC_ID_CLPD6833, "Cirrus Logic PD6833 PCI-CardBus Bridge",
- PCIC_PD673X, PCIC_CARDBUS_POWER, &pcic_pci_pd68xx_chip },
- { PCIC_ID_CLPD6834, "Cirrus Logic PD6834 PCI-CardBus Bridge",
- PCIC_PD673X, PCIC_CARDBUS_POWER, &pcic_pci_pd68xx_chip },
- { PCIC_ID_OZ6729, "O2micro OZ6729 PC-Card Bridge",
- PCIC_I82365, PCIC_AB_POWER, &pcic_pci_oz67xx_chip },
- { PCIC_ID_OZ6730, "O2micro OZ6730 PC-Card Bridge",
- PCIC_I82365, PCIC_AB_POWER, &pcic_pci_oz67xx_chip },
- { PCIC_ID_OZ6832, "O2micro 6832/6833 PCI-Cardbus Bridge",
- PCIC_I82365, PCIC_CARDBUS_POWER, &pcic_pci_oz68xx_chip },
- { PCIC_ID_OZ6860, "O2micro 6836/6860 PCI-Cardbus Bridge",
- PCIC_I82365, PCIC_CARDBUS_POWER, &pcic_pci_oz68xx_chip },
- { PCIC_ID_OZ6872, "O2micro 6812/6872 PCI-Cardbus Bridge",
- PCIC_I82365, PCIC_CARDBUS_POWER, &pcic_pci_oz68xx_chip },
- { PCIC_ID_OZ6912, "O2micro 6912 PCI-Cardbus Bridge",
- PCIC_I82365, PCIC_CARDBUS_POWER, &pcic_pci_oz68xx_chip },
- { PCIC_ID_OZ6922, "O2micro 6922 PCI-Cardbus Bridge",
- PCIC_I82365, PCIC_AB_POWER, &pcic_pci_oz68xx_chip },
- { PCIC_ID_OZ6933, "O2micro 6933 PCI-Cardbus Bridge",
- PCIC_I82365, PCIC_AB_POWER, &pcic_pci_oz68xx_chip },
- { PCIC_ID_RICOH_RL5C465, "Ricoh RL5C465 PCI-CardBus Bridge",
- PCIC_RF5C296, PCIC_CARDBUS_POWER, &pcic_pci_ricoh_chip },
- { PCIC_ID_RICOH_RL5C475, "Ricoh RL5C475 PCI-CardBus Bridge",
- PCIC_RF5C296, PCIC_CARDBUS_POWER, &pcic_pci_ricoh_chip },
- { PCIC_ID_RICOH_RL5C476, "Ricoh RL5C476 PCI-CardBus Bridge",
- PCIC_RF5C296, PCIC_CARDBUS_POWER, &pcic_pci_ricoh_chip },
- { PCIC_ID_RICOH_RL5C477, "Ricoh RL5C477 PCI-CardBus Bridge",
- PCIC_RF5C296, PCIC_CARDBUS_POWER, &pcic_pci_ricoh_chip },
- { PCIC_ID_RICOH_RL5C478, "Ricoh RL5C478 PCI-CardBus Bridge",
- PCIC_RF5C296, PCIC_CARDBUS_POWER, &pcic_pci_ricoh_chip },
- { PCIC_ID_SMC_34C90, "SMC 34C90 PCI-CardBus Bridge",
- PCIC_RF5C296, PCIC_CARDBUS_POWER, &pcic_pci_generic_chip },
- { PCIC_ID_TI1031, "TI PCI-1031 PCI-PCMCIA Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti113x_chip },
- { PCIC_ID_TI1130, "TI PCI-1130 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti113x_chip },
- { PCIC_ID_TI1131, "TI PCI-1131 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti113x_chip },
- { PCIC_ID_TI1210, "TI PCI-1210 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1211, "TI PCI-1211 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1220, "TI PCI-1220 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1221, "TI PCI-1221 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1225, "TI PCI-1225 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1250, "TI PCI-1250 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER | TI_NO_MFUNC,
- &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1251, "TI PCI-1251 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER | TI_NO_MFUNC,
- &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1251B, "TI PCI-1251B PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER | TI_NO_MFUNC,
- &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1260, "TI PCI-1260 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1260B, "TI PCI-1260B PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1410, "TI PCI-1410 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1420, "TI PCI-1420 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1421, "TI PCI-1421 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1450, "TI PCI-1450 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER | TI_NO_MFUNC,
- &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1451, "TI PCI-1451 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1510, "TI PCI-1510 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI1520, "TI PCI-1520 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI4410, "TI PCI-4410 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI4450, "TI PCI-4450 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI4451, "TI PCI-4451 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TI4510, "TI PCI-4510 PCI-CardBus Bridge",
- PCIC_I82365SL_DF, PCIC_CARDBUS_POWER, &pcic_pci_ti12xx_chip },
- { PCIC_ID_TOPIC95, "Toshiba ToPIC95 PCI-CardBus Bridge",
- PCIC_I82365, PCIC_CARDBUS_POWER, &pcic_pci_topic_chip },
- { PCIC_ID_TOPIC95B, "Toshiba ToPIC95B PCI-CardBus Bridge",
- PCIC_I82365, PCIC_CARDBUS_POWER, &pcic_pci_topic_chip },
- { PCIC_ID_TOPIC97, "Toshiba ToPIC97 PCI-CardBus Bridge",
- PCIC_I82365, PCIC_CARDBUS_POWER, &pcic_pci_topic_chip },
- { PCIC_ID_TOPIC100, "Toshiba ToPIC100 PCI-CardBus Bridge",
- PCIC_I82365, PCIC_CARDBUS_POWER, &pcic_pci_topic_chip },
- { 0, NULL, 0, 0, NULL }
-};
-
-/*
- * Read a register from the PCIC.
- */
-static unsigned char
-pcic_pci_getb2(struct pcic_slot *sp, int reg)
-{
- return (bus_space_read_1(sp->bst, sp->bsh, sp->offset + reg));
-}
-
-/*
- * Write a register on the PCIC
- */
-static void
-pcic_pci_putb2(struct pcic_slot *sp, int reg, unsigned char val)
-{
- bus_space_write_1(sp->bst, sp->bsh, sp->offset + reg, val);
-}
-
-/*
- * lookup inside the table
- */
-static struct pcic_pci_table *
-pcic_pci_lookup(u_int32_t devid, struct pcic_pci_table *tbl)
-{
- while (tbl->devid) {
- if (tbl->devid == devid)
- return (tbl);
- tbl++;
- }
- return (NULL);
-}
-
-/*
- * The standard way to control fuction interrupts is via bit 7 in the BCR
- * register. Some data sheets indicate that this is just for "intterupts"
- * while others are clear that it is for function interrupts. When this
- * bit is set, function interrupts are routed via the ExCA register. When
- * this bit is clear, they are routed via the PCI bus, usually via the int
- * in the INTPIN register.
- */
-static int
-pcic_pci_gen_func(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- u_int16_t bcr;
-
- bcr = pci_read_config(sp->sc->dev, CB_PCI_BRIDGE_CTRL, 2);
- if (way == pcic_iw_pci)
- bcr &= ~CB_BCR_INT_EXCA;
- else
- bcr |= CB_BCR_INT_EXCA;
- pci_write_config(sp->sc->dev, CB_PCI_BRIDGE_CTRL, bcr, 2);
- return (0);
-}
-
-static int
-pcic_pci_gen_csc(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- return (0);
-}
-
-/*
- * The O2micro OZ67xx chips functions.
- */
-static int
-pcic_pci_oz67xx_func(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- return (pcic_pci_gen_func(sp, way));
-}
-
-static int
-pcic_pci_oz67xx_csc(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- /*
- * Need datasheet to find out what's going on. However, the
- * 68xx datasheets are so vague that it is hard to know what
- * the right thing to do is.
- */
- /* XXX */
- return (0);
-}
-
-
-static void
-pcic_pci_oz67xx_init(device_t dev)
-{
- device_printf(dev, "Warning: O2micro OZ67xx chips may not work\n");
- pcic_pci_cardbus_init(dev);
-}
-
-/*
- * The O2micro OZ68xx chips functions.
- */
-static int
-pcic_pci_oz68xx_func(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- return (pcic_pci_gen_func(sp, way));
-}
-
-static int
-pcic_pci_oz68xx_csc(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- /*
- * The 68xx datasheets make it hard to know what the right thing
- * to do here is. We do what we know, which is nothing, and
- * hope for the best.
- *
- * XXX NEWCARD may have some useful code here.
- */
- /* XXX */
- return (0);
-}
-
-static void
-pcic_pci_oz68xx_init(device_t dev)
-{
- /*
- * This is almost certainly incomplete.
- */
- device_printf(dev, "Warning: O2micro OZ68xx chips may not work\n");
- pcic_pci_cardbus_init(dev);
-}
-
-/*
- * The Cirrus Logic PD6729/30. These are weird beasts, so be careful.
- * They are ISA parts glued to the PCI bus and do not follow the yenta
- * specification for cardbus bridges. They seem to be similar to the
- * intel parts that were also cloned by o2micro and maybe others, but
- * they are so much more common that the author doesn't have experience
- * with them to know for sure.
- */
-static int
-pcic_pci_pd6729_func(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- /*
- * For pci interrupts, we need to set bit 3 of extension register
- * 3 to 1. For ISA interrupts, we need to clear it.
- */
- sp->putb(sp, PCIC_EXT_IND, PCIC_EXTCTRL1);
- if (way == pcic_iw_pci)
- pcic_setb(sp, PCIC_EXTENDED, PCIC_EC1_CARD_IRQ_INV);
- else
- pcic_clrb(sp, PCIC_EXTENDED, PCIC_EC1_CARD_IRQ_INV);
-
- return (0);
-}
-
-static int
-pcic_pci_pd6729_csc(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- /*
- * For pci interrupts, we need to set bit 4 of extension register
- * 3 to 1. For ISA interrupts, we need to clear it.
- */
- sp->putb(sp, PCIC_EXT_IND, PCIC_EXTCTRL1);
- if (way == pcic_iw_pci)
- pcic_setb(sp, PCIC_EXTENDED, PCIC_EC1_CSC_IRQ_INV);
- else
- pcic_clrb(sp, PCIC_EXTENDED, PCIC_EC1_CSC_IRQ_INV);
-
- return (0);
-}
-
-
-static void
-pcic_pci_pd6729_init(device_t dev)
-{
- struct pcic_softc *sc = device_get_softc(dev);
-
- /*
- * Tell the chip to do its routing thing.
- */
- pcic_pci_pd6729_func(&sc->slots[0], sc->func_route);
- pcic_pci_pd6729_csc(&sc->slots[0], sc->csc_route);
-}
-
-/*
- * Set up the CL-PD6832, 6833 and 6834.
- */
-static int
-pcic_pci_pd68xx_func(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- return (pcic_pci_gen_func(sp, way));
-}
-
-static int
-pcic_pci_pd68xx_csc(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- struct pcic_softc *sc = sp->sc;
- device_t dev = sc->dev;
- u_int32_t device_id = pci_get_devid(dev);
- u_long bcr;
- u_long cm1;
-
- /*
- * CLPD6832 management interrupt enable bit is bit 11
- * (MGMT_IRQ_ENA) in bridge control register(offset 0x3d).
- * When on, card status interrupts are ISA controlled by
- * the ExCA register 0x05.
- *
- * The CLPD6833 does things differently. It doesn't have bit
- * 11 in the bridge control register. Instead, this
- * functionality appears to be in the "Configuration
- * Miscellaneous 1" register bit 1.
- *
- * I'm assuming that the CLPD6834 does things like the '33
- */
- if (device_id == PCIC_ID_CLPD6832) {
- bcr = pci_read_config(dev, CB_PCI_BRIDGE_CTRL, 2);
- if (way == pcic_iw_pci)
- bcr &= ~CLPD6832_BCR_MGMT_IRQ_ENA;
- else
- bcr |= CLPD6832_BCR_MGMT_IRQ_ENA;
- pci_write_config(dev, CB_PCI_BRIDGE_CTRL, bcr, 2);
- }
- if (device_id != PCIC_ID_CLPD6832) {
- cm1 = pci_read_config(dev, CLPD6833_CFG_MISC_1, 4);
- if (way == pcic_iw_pci)
- cm1 &= ~CLPD6833_CM1_MGMT_EXCA_ENA;
- else
- cm1 |= CLPD6833_CM1_MGMT_EXCA_ENA;
- pci_write_config(dev, CLPD6833_CFG_MISC_1, cm1, 4);
- }
- return (0);
-}
-
-static void
-pcic_pci_pd68xx_init(device_t dev)
-{
- pcic_pci_cardbus_init(dev);
-}
-
-static int
-pcic_pci_ricoh_func(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- return (pcic_pci_gen_func(sp, way));
-}
-
-static int
-pcic_pci_ricoh_csc(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- struct pcic_softc *sc = sp->sc;
- device_t dev = sc->dev;
- u_int16_t mcr2;
-
- /*
- * For CSC interrupts via ISA, we can't do that exactly.
- * However, we can disable INT# routing, which is usually what
- * we want. This is bit 7 in the field. Note, bit 6 looks
- * interesting, but appears to be unnecessary.
- */
- mcr2 = pci_read_config(dev, R5C47X_MISC_CONTROL_REGISTER_2, 2);
- if (way == pcic_iw_pci)
- mcr2 &= ~R5C47X_MCR2_CSC_TO_INTX_DISABLE;
- else
- mcr2 |= R5C47X_MCR2_CSC_TO_INTX_DISABLE;
- pci_write_config(dev, R5C47X_MISC_CONTROL_REGISTER_2, mcr2, 2);
-
- return (0);
-}
-
-static void
-pcic_pci_ricoh_init(device_t dev)
-{
- u_int16_t brgcntl;
- u_int32_t device_id = pci_get_devid(dev);
-
- switch (device_id) {
- case PCIC_ID_RICOH_RL5C465:
- case PCIC_ID_RICOH_RL5C466:
- /*
- * Ricoh chips have a legacy bridge enable different than most
- * Code cribbed from NEWBUS's bridge code since I can't find a
- * datasheet for them that has register definitions.
- */
- brgcntl = pci_read_config(dev, CB_PCI_BRIDGE_CTRL, 2);
- brgcntl &= ~(CB_BCR_RL_3E2_EN | CB_BCR_RL_3E0_EN);
- pci_write_config(dev, CB_PCI_BRIDGE_CTRL, brgcntl, 2);
- break;
- }
- pcic_pci_cardbus_init(dev);
-}
-
-/*
- * TI 1030, 1130, and 1131.
- */
-static int
-pcic_pci_ti113x_func(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- u_int32_t cardcntl;
- device_t dev = sp->sc->dev;
-
- /*
- * The TI-1130 (and 1030 and 1131) have a different interrupt
- * routing control than the newer chips. assume we're not
- * routing either csc or func interrupts via PCI, but enable
- * as necessary when we find someone uses PCI interrupts. In
- * order to get any pci interrupts, PCI_IRQ_ENA (bit 5) must
- * be set. If either PCI_IREQ (bit 4) or PCI_CSC (bit 3) are
- * set, then set bit 5 at the same time, since setting them
- * enables the PCI interrupt routing.
- *
- * It also appears necessary to set the function routing bit
- * in the bridge control register, but cardbus_init does that
- * for us.
- */
- cardcntl = pci_read_config(dev, TI113X_PCI_CARD_CONTROL, 1);
- if (way == pcic_iw_pci)
- cardcntl |= TI113X_CARDCNTL_PCI_IREQ;
- else
- cardcntl &= ~TI113X_CARDCNTL_PCI_IREQ;
- if (cardcntl & (TI113X_CARDCNTL_PCI_IREQ | TI113X_CARDCNTL_PCI_CSC))
- cardcntl |= TI113X_CARDCNTL_PCI_IRQ_ENA;
- else
- cardcntl &= ~TI113X_CARDCNTL_PCI_IRQ_ENA;
- pci_write_config(dev, TI113X_PCI_CARD_CONTROL, cardcntl, 1);
-
- return (pcic_pci_gen_func(sp, way));
-}
-
-static int
-pcic_pci_ti113x_csc(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- u_int32_t cardcntl;
- device_t dev = sp->sc->dev;
-
- /*
- * The TI-1130 (and 1030 and 1131) have a different interrupt
- * routing control than the newer cards. assume we're not
- * routing PCI, but enable as necessary when we find someone
- * uses PCI interrupts. In order to get any pci interrupts,
- * PCI_IRQ_ENA (bit 5) must be set. If either PCI_IREQ (bit
- * 4) or PCI_CSC (bit 3) are set, then set bit 5 at the same
- * time, since setting them enables the PCI interrupt routing.
- *
- * It also appears necessary to set the function routing bit
- * in the bridge control register, but cardbus_init does that
- * for us.
- */
- cardcntl = pci_read_config(dev, TI113X_PCI_CARD_CONTROL, 1);
- if (way == pcic_iw_pci)
- cardcntl |= TI113X_CARDCNTL_PCI_CSC;
- else
- cardcntl &= ~TI113X_CARDCNTL_PCI_CSC;
- if (cardcntl & (TI113X_CARDCNTL_PCI_IREQ | TI113X_CARDCNTL_PCI_CSC))
- cardcntl |= TI113X_CARDCNTL_PCI_IRQ_ENA;
- else
- cardcntl &= ~TI113X_CARDCNTL_PCI_IRQ_ENA;
- pci_write_config(dev, TI113X_PCI_CARD_CONTROL, cardcntl, 1);
-
- return (0);
-}
-
-static int
-pcic_pci_ti12xx_func(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- u_int32_t syscntl, devcntl, cardcntl, mfunc;
- device_t dev = sp->sc->dev;
-
- syscntl = pci_read_config(dev, TI113X_PCI_SYSTEM_CONTROL, 4);
- devcntl = pci_read_config(dev, TI113X_PCI_DEVICE_CONTROL, 1);
- cardcntl = pci_read_config(dev, TI113X_PCI_CARD_CONTROL, 1);
-
- /*
- * Special code for the Orinoco cards (and a few others). They
- * seem to need this special code to make them work only over pci
- * interrupts. Sadly, doing this code also causes problems for
- * many laptops, so we have to make it controlled by a tunable.
- * Actually, experience has shown that this rarely, if ever,
- * helps.
- */
- if (way == pcic_iw_pci) {
- /*
- * pcic_init_routing seems to do nothing useful towards
- * fixing the hang problems. I plan on removing it in
- * 4.8 or so.
- */
- if (pcic_init_routing) {
- devcntl &= ~TI113X_DEVCNTL_INTR_MASK;
- pci_write_config(dev, TI113X_PCI_DEVICE_CONTROL,
- devcntl, 1);
- syscntl |= TI113X_SYSCNTL_INTRTIE;
- }
-
- /*
- * I've had reports that we need the pci clock enabled,
- * provide a hook to do so. The number of cards that
- * require this is quite small.
- */
- if (pcic_ti12xx_enable_pci_clock) {
- syscntl |= TI12XX_SYSCNTL_PCI_CLOCK;
- pci_write_config(dev, TI113X_PCI_SYSTEM_CONTROL,
- syscntl, 4);
- }
-
- /*
- * Some PCI add-in cards don't have good EEPROMs on them,
- * so they get this MUX register wrong. The MUX register
- * defaults to 0, which is usually wrong for this register,
- * so we initialize it to make sense.
- *
- * We don't bother to turn it off in the ISA case since it
- * is an initialization issue.
- *
- * A few weird TI bridges don't have MFUNC, so filter
- * those out too.
- */
- if ((sp->sc->flags & TI_NO_MFUNC) == 0) {
- mfunc = pci_read_config(dev, TI12XX_PCI_MFUNC, 4);
- if (mfunc == 0) {
- mfunc = (mfunc & ~TI12XX_MFUNC_PIN0) |
- TI12XX_MFUNC_PIN0_INTA;
- if ((syscntl & TI113X_SYSCNTL_INTRTIE) == 0)
- mfunc = (mfunc & ~TI12XX_MFUNC_PIN1) |
- TI12XX_MFUNC_PIN1_INTB;
- pci_write_config(dev, TI12XX_PCI_MFUNC, mfunc,
- 4);
- }
- }
-
- }
- return (pcic_pci_gen_func(sp, way));
-}
-
-static int
-pcic_pci_ti12xx_csc(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- /*
- * Nothing happens here. The TI12xx parts will route the
- * CSC interrupt via PCI if ExCA register tells it to use
- * interrupt 0. And via IRQ otherwise (except for reserved
- * values which may or may not do anything).
- *
- * We just hope for the best here that doing nothing is the
- * right thing to do.
- */
- return (0);
-}
-
-/*
- * TI PCI-CardBus Host Adapter specific function code.
- * This function is separated from pcic_pci_attach().
- * Takeshi Shibagaki(shiba@jp.freebsd.org).
- */
-static void
-pcic_pci_ti_init(device_t dev)
-{
- u_int32_t syscntl, diagctl, devcntl, cardcntl;
- u_int32_t device_id = pci_get_devid(dev);
- int ti113x = (device_id == PCIC_ID_TI1031) ||
- (device_id == PCIC_ID_TI1130) ||
- (device_id == PCIC_ID_TI1131);
-
- syscntl = pci_read_config(dev, TI113X_PCI_SYSTEM_CONTROL, 4);
- devcntl = pci_read_config(dev, TI113X_PCI_DEVICE_CONTROL, 1);
- cardcntl = pci_read_config(dev, TI113X_PCI_CARD_CONTROL, 1);
-
- if (ti113x) {
- device_printf(dev, "TI113X PCI Config Reg: ");
- if (syscntl & TI113X_SYSCNTL_CLKRUN_ENA) {
- if (syscntl & TI113X_SYSCNTL_CLKRUN_SEL)
- printf("[clkrun irq 12]");
- else
- printf("[clkrun irq 10]");
- }
- } else {
- device_printf(dev, "TI12XX PCI Config Reg: ");
-
- /*
- * Turn on async CSC interrupts. This appears to
- * be the default, but the old, pre pci-aware, code
- * did this and it appears PAO does as well.
- */
- diagctl = pci_read_config(dev, TI12XX_PCI_DIAGNOSTIC, 1);
- diagctl |= TI12XX_DIAG_CSC_INTR;
- pci_write_config(dev, TI12XX_PCI_DIAGNOSTIC, diagctl, 1);
-
- /*
- * Turn off Zoom Video. Some cards have this enabled,
- * some do not but it causes problems when enabled. This
- * register doesn't exist on the 1130 (and likely the 1131,
- * but without a datasheet it is impossible to know).
- * Some 12xx chips may not have it, but setting it is
- * believed to be harmless on those models.
- */
- pci_write_config(dev, TI12XX_PCI_MULTIMEDIA_CONTROL, 0, 4);
- }
- if (cardcntl & TI113X_CARDCNTL_RING_ENA)
- printf("[ring enable]");
- if (cardcntl & TI113X_CARDCNTL_SPKR_ENA)
- printf("[speaker enable]");
- if (syscntl & TI113X_SYSCNTL_PWRSAVINGS)
- printf("[pwr save]");
- switch(devcntl & TI113X_DEVCNTL_INTR_MASK){
- case TI113X_DEVCNTL_INTR_ISA :
- printf("[CSC parallel isa irq]");
- break;
- case TI113X_DEVCNTL_INTR_SERIAL :
- printf("[CSC serial isa irq]");
- break;
- case TI113X_DEVCNTL_INTR_NONE :
- printf("[pci only]");
- break;
- case TI12XX_DEVCNTL_INTR_ALLSERIAL :
- printf("[FUNC pci int + CSC serial isa irq]");
- break;
- }
- printf("\n");
- pcic_pci_cardbus_init(dev);
-}
-
-/*
- * Code for TOPIC chips
- */
-static int
-pcic_pci_topic_func(struct pcic_slot *sp, enum pcic_intr_way way)
-{
-#ifdef THIS_BRAEKS_THINGS
- device_t dev = sp->sc->dev;
- u_int32_t scr;
-
- scr = pci_read_config(dev, TOPIC_SOCKET_CTRL, 4);
- if (way == pcic_iw_pci)
- scr |= TOPIC_SOCKET_CTRL_SCR_IRQSEL;
- else
- scr &= ~TOPIC_SOCKET_CTRL_SCR_IRQSEL;
- pci_write_config(dev, TOPIC_SLOT_CTRL, scr, 4);
-#endif
- return (pcic_pci_gen_func(sp, way));
-}
-
-static int
-pcic_pci_topic_csc(struct pcic_slot *sp, enum pcic_intr_way way)
-{
- device_t dev = sp->sc->dev;
- u_int32_t scr;
- u_int32_t device_id;
-
- device_id = pci_get_devid(dev);
- if (device_id == PCIC_ID_TOPIC100 || device_id == PCIC_ID_TOPIC97) {
- scr = pci_read_config(dev, TOPIC_SLOT_CTRL, 4);
- if (way == pcic_iw_pci)
- scr |= TOPIC97_SLOT_CTRL_PCIINT;
- else
- scr &= ~TOPIC97_SLOT_CTRL_PCIINT;
- pci_write_config(dev, TOPIC_SLOT_CTRL, scr, 4);
- }
-
- return (0);
-}
-
-static void
-pcic_pci_topic_init(device_t dev)
-{
- struct pcic_softc *sc = device_get_softc(dev);
- u_int32_t reg;
- u_int32_t device_id;
-
- device_id = pci_get_devid(dev);
- reg = pci_read_config(dev, TOPIC_SLOT_CTRL, 4);
- reg |= (TOPIC_SLOT_CTRL_SLOTON | TOPIC_SLOT_CTRL_SLOTEN |
- TOPIC_SLOT_CTRL_ID_LOCK | TOPIC_SLOT_CTRL_CARDBUS);
- reg &= ~TOPIC_SLOT_CTRL_SWDETECT;
- if (device_id == PCIC_ID_TOPIC100 || device_id == PCIC_ID_TOPIC97) {
- reg |= TOPIC97_SLOT_CTRL_PCIINT;
- reg &= ~(TOPIC97_SLOT_CTRL_STSIRQP | TOPIC97_SLOT_CTRL_IRQP);
- }
- pci_write_config(dev, TOPIC_SLOT_CTRL, reg, 4);
- pcic_pci_cardbus_init(dev);
-
- if (device_id == PCIC_ID_TOPIC100 || device_id == PCIC_ID_TOPIC97) {
- /*
- * We need to enable voltage sense and 3V cards explicitly
- * in the bridge. The datasheets I have for both the
- * ToPIC 97 and 100 both lists these ports. Without
- * datasheets for the ToPIC95s, I can't tell if we need
- * to do it there or not.
- */
- pcic_setb(&sc->slots[0], PCIC_TOPIC_FCR,
- PCIC_FCR_3V_EN | PCIC_FCR_VS_EN);
- }
-}
-
-static void
-pcic_pci_cardbus_init(device_t dev)
-{
- struct pcic_softc *sc = device_get_softc(dev);
- u_int16_t brgcntl;
- int unit;
-
- unit = device_get_unit(dev);
-
- brgcntl = pci_read_config(dev, CB_PCI_BRIDGE_CTRL, 2);
- brgcntl |= CB_BCR_WRITE_POST_EN | CB_BCR_MASTER_ABORT;
- pci_write_config(dev, CB_PCI_BRIDGE_CTRL, brgcntl, 2);
-
- /* Turn off legacy address */
- pci_write_config(dev, CB_PCI_LEGACY16_IOADDR, 0, 2);
-
- /*
- * Write zeros into the remaining memory I/O windows. This
- * seems to turn off the pci configuration of these things and
- * make the cardbus bridge use the values for memory
- * programmed into the pcic registers.
- */
- pci_write_config(dev, CB_PCI_MEMBASE0, 0, 4);
- pci_write_config(dev, CB_PCI_MEMLIMIT0, 0, 4);
- pci_write_config(dev, CB_PCI_MEMBASE1, 0, 4);
- pci_write_config(dev, CB_PCI_MEMLIMIT1, 0, 4);
- pci_write_config(dev, CB_PCI_IOBASE0, 0, 4);
- pci_write_config(dev, CB_PCI_IOLIMIT0, 0, 4);
- pci_write_config(dev, CB_PCI_IOBASE1, 0, 4);
- pci_write_config(dev, CB_PCI_IOLIMIT1, 0, 4);
-
- /*
- * Tell the chip to do its routing thing.
- */
- sc->chip->func_intr_way(&sc->slots[0], sc->func_route);
- sc->chip->csc_intr_way(&sc->slots[0], sc->csc_route);
-
- return;
-}
-
-static const char *
-pcic_pci_cardtype(u_int32_t stat)
-{
- if (stat & CB_SS_NOTCARD)
- return ("unrecognized by bridge");
- if ((stat & (CB_SS_16BIT | CB_SS_CB)) == (CB_SS_16BIT | CB_SS_CB))
- return ("16-bit and 32-bit (can't happen)");
- if (stat & CB_SS_16BIT)
- return ("16-bit pccard");
- if (stat & CB_SS_CB)
- return ("32-bit cardbus");
- return ("none (can't happen)");
-}
-
-/*
- * Card insertion and removal code. The insertion events need to be
- * debounced so that the noisy insertion/removal events don't result
- * in the hardware being initialized many times, only to be torn down
- * as well. This may also cause races with pccardd. Instead, we wait
- * for the insertion signal to be stable for 0.5 seconds before we declare
- * it to be a real insertion event. Removal is also debounced. We turn
- * off interrupt servicing during the settling time to prevent infinite
- * loops in the driver.
- *
- * Note: We only handle the card detect change events. We don't handle
- * power events and status change events.
- */
-static void
-pcic_cd_change(void *arg)
-{
- struct pcic_softc *sc = (struct pcic_softc *) arg;
- struct pcic_slot *sp = &sc->slots[0];
- u_int32_t stat;
-
- sc->cd_pending = 0;
- stat = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_STATE);
-
- /* Status changed while present; remove the card from the system. */
- if (sc->cd_present) {
- sc->cd_present = 0;
- pccard_event(sp->slt, card_removed);
- }
- /* Nothing to do if the debounced state is 'not present'. */
- if ((stat & CB_SS_CD) != 0)
- return;
-
- sc->cd_present = 1;
- if (bootverbose && (stat & CB_SS_BADVCC) != 0)
- device_printf(sc->dev, "BAD Vcc request: 0x%x\n", stat);
- if ((stat & CB_SS_16BIT) == 0)
- device_printf(sp->sc->dev, "Card type %s is unsupported\n",
- pcic_pci_cardtype(stat));
- else
- pccard_event(sp->slt, card_inserted);
-}
-
-static void
-pcic_pci_intr(void *arg)
-{
- struct pcic_softc *sc = (struct pcic_softc *) arg;
- struct pcic_slot *sp = &sc->slots[0];
- u_int32_t event;
-
- event = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_EVENT);
- if (event != 0) {
- if (bootverbose)
- device_printf(sc->dev, "Event mask 0x%x\n", event);
-
- /*
- * Treat all card-detect signal transitions the same way
- * since we can't reliably tell if this is an insert or a
- * remove event. Stop the card from getting interrupts and
- * defer the insert/remove event until the CB_SOCKET_STATE
- * signals have had time to settle.
- */
- if ((event & CB_SE_CD) != 0) {
- if (sc->cd_pending) {
- untimeout(pcic_cd_change, arg, sc->cd_ch);
- sc->cd_pending = 0;
- }
- sc->cd_pending = 1;
- sc->cd_ch = timeout(pcic_cd_change, arg, hz/2);
- sc->func_intr = NULL;
- }
-
- /* Ack the interrupt */
- bus_space_write_4(sp->bst, sp->bsh, 0, event);
- }
-
- /*
- * Some TI chips also require us to read the old ExCA register for
- * card status change when we route CSC via PCI! So, we go ahead
- * and read it to clear the bits. Maybe we should check the status
- * ala the ISA interrupt handler, but those changes should be caught
- * in the CD change.
- *
- * We have to check it every interrupt because these bits can sometimes
- * show up indepentently of the CB_SOCKET_EVENT register above.
- */
- sp->getb(sp, PCIC_STAT_CHG);
-}
-
-/*
- * Return the ID string for the controller if the vendor/product id
- * matches, NULL otherwise.
- */
-static int
-pcic_pci_probe(device_t dev)
-{
- u_int8_t subclass;
- u_int8_t progif;
- const char *desc;
- u_int32_t device_id;
- struct pcic_pci_table *itm;
- struct resource *res;
- int rid;
-
- if (pcic_ignore_pci)
- return (ENXIO);
- device_id = pci_get_devid(dev);
- desc = NULL;
- itm = pcic_pci_lookup(device_id, &pcic_pci_devs[0]);
- if (pcic_ignore_function_1 && pci_get_function(dev) == 1) {
- if (itm != NULL)
- PRVERB((dev, "Ignoring function 1\n"));
- return (ENXIO);
- }
- if (itm != NULL)
- desc = itm->descr;
- if (desc == NULL && pci_get_class(dev) == PCIC_BRIDGE) {
- subclass = pci_get_subclass(dev);
- progif = pci_get_progif(dev);
- if (subclass == PCIS_BRIDGE_PCMCIA && progif == 0)
- desc = "Generic PCI-PCMCIA Bridge";
- if (subclass == PCIS_BRIDGE_CARDBUS && progif == 0)
- desc = "YENTA PCI-CardBus Bridge";
- if (bootverbose && desc)
- printf("Found unknown %s devid 0x%x\n", desc, device_id);
- }
- if (desc == NULL)
- return (ENXIO);
- device_set_desc(dev, desc);
-
- /*
- * Take us out of power down mode, if necessary. It also
- * appears that even reading the power register is enough on
- * some systems to cause correct behavior.
- */
- if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
- /* Reset the power state. */
- device_printf(dev, "chip is in D%d power mode "
- "-- setting to D0\n", pci_get_powerstate(dev));
- pci_set_powerstate(dev, PCI_POWERSTATE_D0);
- }
-
- /*
- * Allocated/deallocate interrupt. This forces the PCI BIOS or
- * other MD method to route the interrupts to this card.
- * This so we get the interrupt number in the probe message.
- * We only need to route interrupts when we're doing pci
- * parallel interrupt routing.
- *
- * We use two different variables for the memory based and I/O
- * based cards, so the check here is a little more complex than
- * one would otherwise hope.
- *
- * XXX The bus code for PCI really should do this for us.
- */
- if ((pcic_intr_path == pcic_iw_pci &&
- device_id != PCIC_ID_CLPD6729) ||
- (pcic_pd6729_intr_path == pcic_iw_pci &&
- device_id == PCIC_ID_CLPD6729)) {
- rid = 0;
-#ifdef __i386__
- /*
- * IRQ 0 is invalid on x86, but not other platforms.
- * If we have irq 0, then write 255 to force a new, non-
- * bogus one to be assigned. I think that in -current
- * the code in this ifdef may be obsolete with the new
- * invalid mapping that we're doing in the pci layer -- imp
- */
- if (pci_get_irq(dev) == 0) {
- pci_set_irq(dev, 255);
- pci_write_config(dev, PCIR_INTLINE, 255, 1);
- }
-#endif
- res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_ACTIVE);
- if (res)
- bus_release_resource(dev, SYS_RES_IRQ, rid, res);
- }
-
- return (0);
-}
-
-static void
-pcic_pci_shutdown(device_t dev)
-{
-/*
- * More reports of things working w/o this code than with it.
- */
-#if 0
- struct pcic_softc *sc;
- struct pcic_slot *sp;
-
- sc = (struct pcic_softc *) device_get_softc(dev);
- sp = &sc->slots[0];
-
- /*
- * Turn off the power to the slot in an attempt to
- * keep the system from hanging on reboot. We also turn off
- * card interrupts in an attempt to control interrupt storms.
- * on some (all?) this has the effect of also turning off
- * card status change interrupts. A side effect of writing 0
- * to INT_GEN is that the card is placed into "reset" mode
- * where nothing happens until it is taken out of "reset"
- * mode.
- *
- * Also, turn off the generation of status interrupts too.
- */
- sp->putb(sp, PCIC_INT_GEN, 0);
- sp->putb(sp, PCIC_STAT_INT, 0);
- sp->putb(sp, PCIC_POWER, 0);
- DELAY(4000);
-
- /*
- * Writing to INT_GEN can cause an interrupt, so we blindly
- * ack all possible interrupts here. Reading the stat change
- * shouldn't be necessary, but some TI chipsets need it in the
- * normal course of operations, so we do it here too. We can't
- * lose any interrupts after this point, so go ahead and ack
- * everything. The bits in INT_GEN clear upon reading them.
- * We also set the interrupt mask to 0, in an effort to avoid
- * getting further interrupts.
- */
- bus_space_write_4(sp->bst, sp->bsh, CB_SOCKET_MASK, 0);
- bus_space_write_4(sp->bst, sp->bsh, CB_SOCKET_EVENT, 0xffffffff);
- sp->getb(sp, PCIC_STAT_CHG);
-#endif
-}
-
-/*
- * Print out the config space
- */
-static void
-pcic_pci_print_config(device_t dev)
-{
- int i;
-
- device_printf(dev, "PCI Configuration space:");
- for (i = 0; i < 256; i += 4) {
- if (i % 16 == 0)
- printf("\n 0x%02x: ", i);
- printf("0x%08x ", pci_read_config(dev, i, 4));
- }
- printf("\n");
-}
-
-/*
- * Generic pci interrupt attach routine. It tries to understand all parts,
- * and do sane things for those parts it does not understand.
- */
-static int
-pcic_pci_attach(device_t dev)
-{
- u_int32_t device_id = pci_get_devid(dev);
- u_long command;
- struct pcic_slot *sp;
- struct pcic_softc *sc;
- u_int32_t sockbase;
- u_int32_t stat;
- struct pcic_pci_table *itm;
- int rid;
- int i;
- struct resource *r = NULL;
- int error;
- u_long irq = 0;
- driver_intr_t *intr = NULL;
-
- /*
- * In sys/pci/pcireg.h, PCIR_COMMAND must be separated
- * PCI_COMMAND_REG(0x04) and PCI_STATUS_REG(0x06).
- * Takeshi Shibagaki(shiba@jp.freebsd.org).
- */
- command = pci_read_config(dev, PCIR_COMMAND, 4);
- command |= PCIM_CMD_PORTEN | PCIM_CMD_MEMEN;
- pci_write_config(dev, PCIR_COMMAND, command, 4);
-
- sc = (struct pcic_softc *) device_get_softc(dev);
- sp = &sc->slots[0];
- sp->sc = sc;
- sockbase = pci_read_config(dev, 0x10, 4);
- if (sockbase & 0x1) {
- sc->iorid = CB_PCI_SOCKET_BASE;
- sc->iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
- &sc->iorid, RF_ACTIVE | RF_SHAREABLE);
- if (sc->iores == NULL)
- return (ENOMEM);
-
- sc->flags = PCIC_PD_POWER;
- itm = pcic_pci_lookup(device_id, &pcic_pci_devs[0]);
- for (i = 0; i < 2; i++) {
- sp[i].bst = rman_get_bustag(sc->iores);
- sp[i].bsh = rman_get_bushandle(sc->iores);
- sp[i].sc = sc;
- sp[i].revision = 0;
- sp[i].getb = pcic_getb_io;
- sp[i].putb = pcic_putb_io;
- sp[i].offset = i * PCIC_SLOT_SIZE;
- sp[i].controller = itm ? itm->type : PCIC_PD6729;
- if ((sp[i].getb(&sp[i], PCIC_ID_REV) & 0xc0) == 0x80)
- sp[i].slt = (struct slot *) 1;
- }
- sc->csc_route = sc->func_route = pcic_pd6729_intr_path;
- if (itm)
- sc->flags = itm->flags;
- /*
- * We have to use the ISA interrupt routine for status
- * changes since we don't have any "yenta" pci registers.
- * We have to do this even when we're using pci type
- * interrupts because on these cards the interrupts are
- * cleared in the same way that the ISA cards clear them.
- */
- intr = pcic_isa_intr;
- } else {
- sc->memrid = CB_PCI_SOCKET_BASE;
- sc->memres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
- &sc->memrid, RF_ACTIVE);
- if (sc->memres == NULL && pcic_pci_get_memory(dev) != 0)
- return (ENOMEM);
- sp->getb = pcic_pci_getb2;
- sp->putb = pcic_pci_putb2;
- sp->offset = CB_EXCA_OFFSET;
- sp->bst = rman_get_bustag(sc->memres);
- sp->bsh = rman_get_bushandle(sc->memres);
- itm = pcic_pci_lookup(device_id, &pcic_pci_devs[0]);
- if (itm != NULL) {
- sp->controller = itm->type;
- sp->revision = 0;
- sc->flags = itm->flags;
- } else {
- /* By default, assume we're a D step compatible */
- sp->controller = PCIC_I82365SL_DF;
- sp->revision = 0;
- sc->flags = PCIC_CARDBUS_POWER;
- }
- /* All memory mapped cardbus bridges have these registers */
- sc->flags |= PCIC_YENTA_HIGH_MEMORY;
- sp->slt = (struct slot *) 1;
- sc->csc_route = pcic_intr_path;
- sc->func_route = pcic_intr_path;
- stat = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_STATE);
- sc->cd_present = (stat & CB_SS_CD) == 0;
- }
- sc->dev = dev;
- if (itm)
- sc->chip = itm->chip;
- else
- sc->chip = &pcic_pci_generic_chip;
-
- if (sc->csc_route == pcic_iw_pci) {
- rid = 0;
- r = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_ACTIVE | RF_SHAREABLE);
- if (r == NULL) {
- sc->csc_route = pcic_iw_isa;
- sc->func_route = pcic_iw_isa;
- device_printf(dev,
- "No PCI interrupt routed, trying ISA.\n");
- } else {
- if (intr == NULL)
- intr = pcic_pci_intr;
- irq = rman_get_start(r);
- }
- }
- if (sc->csc_route == pcic_iw_isa) {
- rid = 0;
- irq = pcic_override_irq;
- if (irq != 0) {
- r = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq,
- irq, 1, RF_ACTIVE);
- if (r == NULL) {
- device_printf(dev,
- "Can't route ISA CSC interrupt.\n");
- pcic_dealloc(dev);
- return (ENXIO);
- }
- device_printf(dev,
- "Management interrupt on ISA IRQ %ld\n", irq);
- if (intr == NULL)
- intr = pcic_isa_intr;
- } else {
- sc->slot_poll = pcic_timeout;
- sc->timeout_ch = timeout(sc->slot_poll, sc, hz/2);
- device_printf(dev, "Polling mode\n");
- intr = NULL;
- }
- }
-
- /*
- * Initialize AFTER we figure out what kind of interrupt we're
- * going to be using, if any.
- */
- if (!sc->chip)
- panic("Bug: sc->chip not set!\n");
- sc->chip->init(dev);
-
- /*
- * Now install the interrupt handler, if necessary.
- */
- sc->irqrid = rid;
- sc->irqres = r;
- sc->irq = irq;
- if (intr) {
- error = bus_setup_intr(dev, r, INTR_TYPE_AV, intr, sc, &sc->ih);
- if (error) {
- pcic_dealloc(dev);
- return (error);
- }
- }
- if (bootverbose)
- pcic_pci_print_config(dev);
- return (pcic_attach(dev));
-}
-
-static int
-pcic_pci_detach(device_t dev)
-{
- return (EBUSY); /* Can't detach this device */
-}
-
-/*
- * The PCI bus should do this for us. However, it doesn't quite yet, so
- * we cope by doing it ourselves. If it ever does, this code can go quietly
- * into that good night.
- */
-static int
-pcic_pci_get_memory(device_t dev)
-{
- struct pcic_softc *sc;
- u_int32_t sockbase;
-
- sc = (struct pcic_softc *) device_get_softc(dev);
- sockbase = pci_read_config(dev, sc->memrid, 4);
- if (sockbase >= 0x100000 && sockbase < 0xfffffff0) {
- device_printf(dev, "Could not map register memory 0x%x\n",
- sockbase);
- return (ENOMEM);
- }
- pci_write_config(dev, sc->memrid, 0xffffffff, 4);
- sockbase = pci_read_config(dev, sc->memrid, 4);
- sockbase = (sockbase & 0xfffffff0) & -(sockbase & 0xfffffff0);
-#define CARDBUS_SYS_RES_MEMORY_START 0x88000000
-#define CARDBUS_SYS_RES_MEMORY_END 0xFFFFFFFF
- sc->memres = bus_generic_alloc_resource(device_get_parent(dev),
- dev, SYS_RES_MEMORY, &sc->memrid,
- CARDBUS_SYS_RES_MEMORY_START, CARDBUS_SYS_RES_MEMORY_END,
- sockbase, RF_ACTIVE | rman_make_alignment_flags(sockbase));
- if (sc->memres == NULL) {
- device_printf(dev, "Could not grab register memory\n");
- return (ENOMEM);
- }
- sockbase = rman_get_start(sc->memres);
- pci_write_config(dev, sc->memrid, sockbase, 4);
- device_printf(dev, "PCI Memory allocated: 0x%08x\n", sockbase);
- return (0);
-}
-
-static int
-pcic_pci_gen_mapirq(struct pcic_slot *sp, int irq)
-{
- /*
- * If we're doing ISA interrupt routing, then just go to the
- * generic ISA routine. Also, irq 0 means turn off the interrupts
- * at the bridge.
- */
- if (sp->sc->func_route == pcic_iw_isa || irq == 0)
- return (pcic_isa_mapirq(sp, irq));
-
- /*
- * Ohterwise we're doing PCI interrupts. For those cardbus bridges
- * that follow yenta (and the one pcmcia bridge that does), we don't
- * do a thing to get the IRQ mapped into the system. However,
- * for other controllers that are PCI, but not yetna compliant, we
- * need to do some special mapping.
- *
- * XXX Maybe we shouldn't assume INTA#, but rather as the function
- * XXX what Intline to use.
- */
- if (sp->controller == PCIC_PD6729) {
- /*
- * INTA - 3
- * INTB - 4
- * INTC - 5
- * INTD - 7
- */
- sp->putb(sp, PCIC_INT_GEN, /* Assume INTA# */
- (sp->getb(sp, PCIC_INT_GEN) & 0xF0) | 3);
- return (0);
- }
- return (0);
-}
-
-static void
-pcic_pci_func_intr(void *arg)
-{
- struct pcic_softc *sc = (struct pcic_softc *) arg;
- struct pcic_slot *sp = &sc->slots[0];
- u_int32_t stat;
- int doit = 0;
-
- /*
- * The 6729 controller is a weird one, and we have to use
- * the ISA registers to check to see if the card is there.
- * Otherwise we look at the PCI state register to find out
- * if the card is there.
- */
- if (sp->controller == PCIC_PD6729) {
- if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) == PCIC_CD)
- doit = 1;
- }
- else {
- stat = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_STATE);
- if ((stat & CB_SS_CD) == 0 && sc->func_intr != 0)
- doit = 1;
- }
- if (doit && sc->func_intr != NULL)
- sc->func_intr(sc->func_arg);
-}
-
-static int
-pcic_pci_setup_intr(device_t dev, device_t child, struct resource *irq,
- int flags, driver_intr_t *intr, void *arg, void **cookiep)
-{
- struct pcic_softc *sc = device_get_softc(dev);
- struct pcic_slot *sp = &sc->slots[0];
- int err;
-
- if (sc->func_route == pcic_iw_isa)
- return(pcic_setup_intr(dev, child, irq, flags, intr, arg,
- cookiep));
-
-#if __FreeBSD_version >= 500000
- if ((flags & INTR_FAST) != 0)
-#else
- if ((flags & INTR_TYPE_FAST) != 0)
-#endif
- return (EINVAL);
- if (sc->func_intr != NULL) {
- device_printf(child, "Can't establish another ISR\n");
- return (EINVAL);
- }
-
- err = bus_generic_setup_intr(dev, child, irq, flags,
- pcic_pci_func_intr, sc, cookiep);
- if (err != 0)
- return (err);
- sc->chip->map_irq(sp, rman_get_start(irq));
- sc->func_intr = intr;
- sc->func_arg = arg;
- return (0);
-}
-
-static int
-pcic_pci_teardown_intr(device_t dev, device_t child, struct resource *irq,
- void *cookie)
-{
- struct pcic_softc *sc = device_get_softc(dev);
-
- if (sc->func_route == pcic_iw_isa)
- return (pcic_teardown_intr(dev, child, irq, cookie));
- sc->func_intr = NULL;
- return (bus_generic_teardown_intr(dev, child, irq, cookie));
-}
-
-static int
-pcic_pci_resume(device_t dev)
-{
- struct pcic_softc *sc = device_get_softc(dev);
-
- /*
- * Some BIOSes will not save the BARs for the pci chips, so we
- * must do it ourselves. If the BAR is reset to 0 for an I/O
- * device, it will read back as 0x1, so no explicit test for
- * memory devices are needed.
- *
- * Note: The PCI bus code should do this automatically for us on
- * suspend/resume, but until it does, we have to cope.
- */
- if (pci_read_config(dev, CB_PCI_SOCKET_BASE, 4) == 0)
- pci_write_config(dev, CB_PCI_SOCKET_BASE,
- rman_get_start(sc->memres), 4);
- return (bus_generic_resume(dev));
-}
-
-static device_method_t pcic_pci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, pcic_pci_probe),
- DEVMETHOD(device_attach, pcic_pci_attach),
- DEVMETHOD(device_detach, pcic_pci_detach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, pcic_pci_resume),
- DEVMETHOD(device_shutdown, pcic_pci_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_alloc_resource, pcic_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_release_resource),
- DEVMETHOD(bus_activate_resource, pcic_activate_resource),
- DEVMETHOD(bus_deactivate_resource, pcic_deactivate_resource),
- DEVMETHOD(bus_setup_intr, pcic_pci_setup_intr),
- DEVMETHOD(bus_teardown_intr, pcic_pci_teardown_intr),
-
- /* Card interface */
- DEVMETHOD(card_set_res_flags, pcic_set_res_flags),
- DEVMETHOD(card_get_res_flags, pcic_get_res_flags),
- DEVMETHOD(card_set_memory_offset, pcic_set_memory_offset),
- DEVMETHOD(card_get_memory_offset, pcic_get_memory_offset),
-
- {0, 0}
-};
-
-static driver_t pcic_pci_driver = {
- "pcic",
- pcic_pci_methods,
- sizeof(struct pcic_softc)
-};
-
-DRIVER_MODULE(pcic, pci, pcic_pci_driver, pcic_devclass, 0, 0);
OpenPOWER on IntegriCloud