summaryrefslogtreecommitdiffstats
path: root/sys/pccard
diff options
context:
space:
mode:
Diffstat (limited to 'sys/pccard')
-rw-r--r--sys/pccard/driver.h5
-rw-r--r--sys/pccard/pccard.c443
-rw-r--r--sys/pccard/pccard_compat.c218
-rw-r--r--sys/pccard/pccard_nbk.c176
-rw-r--r--sys/pccard/pccard_nbk.h6
-rw-r--r--sys/pccard/pcic.c427
-rw-r--r--sys/pccard/pcic.h14
-rw-r--r--sys/pccard/skel.c98
-rw-r--r--sys/pccard/slot.h57
9 files changed, 322 insertions, 1122 deletions
diff --git a/sys/pccard/driver.h b/sys/pccard/driver.h
index 4f1ae15..1cd030b 100644
--- a/sys/pccard/driver.h
+++ b/sys/pccard/driver.h
@@ -12,11 +12,6 @@
struct pccard_device;
void pccard_add_driver __P((struct pccard_device *));
-#ifdef _I386_ISA_ISA_DEVICE_H_ /* XXX actually if ointhand2_t is declared */
-int pccard_alloc_intr __P((u_int imask, ointhand2_t *hand, int unit,
- u_int *maskp, u_int *pcic_imask));
-#endif
-void pccard_remove_driver __P((struct pccard_device *));
enum beepstate { BEEP_ON, BEEP_OFF };
diff --git a/sys/pccard/pccard.c b/sys/pccard/pccard.c
index 44c6993..111ae3b 100644
--- a/sys/pccard/pccard.c
+++ b/sys/pccard/pccard.c
@@ -95,16 +95,10 @@ SYSCTL_INT(_machdep_pccard, OID_AUTO, pcic_resume_reset, CTLFLAG_RW,
static int allocate_driver(struct slot *, struct dev_desc *);
static void inserted(void *);
-static void unregister_device_interrupt(struct pccard_devinfo *);
static void disable_slot(struct slot *);
static int invalid_io_memory(unsigned long, int);
-static struct pccard_device *find_driver(char *);
-static ointhand2_t slot_irq_handler;
static void power_off_slot(void *);
-static void pccard_configure(void *);
-SYSINIT(pccard, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE + 1, pccard_configure, NULL);
-
#if NAPM > 0
/*
* For the APM stuff, the apmhook structure is kept
@@ -121,7 +115,6 @@ static struct apmhook r_hook[MAXSLOT]; /* APM resume */
static struct slot *pccard_slots[MAXSLOT]; /* slot entries */
static struct slot *slot_list;
static struct slot_ctrl *cont_list;
-static struct pccard_device *drivers; /* Card drivers */
/*
* The driver interface for read/write uses a block
@@ -156,173 +149,6 @@ static struct cdevsw crd_cdevsw = {
/* bmaj */ -1
};
-
-/*
- * pccard_configure - called by autoconf code.
- * Probes for various PC-CARD controllers, and
- * initialises data structures to point to the
- * various slots.
- *
- * Each controller indicates the number of slots
- * that it sees, and these are mapped to a master
- * slot number accessed via the character device entries.
- *
- * XXX this is a relic. Each controller has it's own probe
- * configuration hook. Printing a list of configured devices
- * with pccard support probably isn't all that useful.
- */
-static void
-pccard_configure(dummy)
- void *dummy;
-{
- struct pccard_device *drv;
-
- /* This isn't strictly correct, but works because of initialize order */
- printf("pccard: initalizing drivers:");
- for (drv = drivers; drv != NULL; drv = drv->next) {
- pccnbk_wrap_old_driver(drv);
- printf(" %s", drv->name);
- }
- cdevsw_add(&crd_cdevsw);
- printf("\n");
-}
-
-int
-pccard_module_handler(module_t mod, int what, void *arg)
-{
- struct pccard_device *drv = (struct pccard_device *)arg;
-
- switch(what) {
- case MOD_LOAD:
- pccard_add_driver(drv);
- break;
- case MOD_UNLOAD:
- pccard_remove_driver(drv);
- break;
- default:
- break;
- }
- return 0;
-}
-
-/*
- * pccard_add_driver - Add a new driver to the list of
- * drivers available for allocation.
- */
-void
-pccard_add_driver(struct pccard_device *drv)
-{
- /*
- * If already loaded, then reject the driver.
- */
- if (find_driver(drv->name)) {
- printf("pccard: driver %s already loaded\n", drv->name);
- return;
- }
- drv->next = drivers;
- drivers = drv;
-}
-
-/*
- * pccard_remove_driver - called to unlink driver
- * from devices. Usually called when drivers are
- * unloaded from kernel.
- */
-void
-pccard_remove_driver(struct pccard_device *drv)
-{
- struct slot *slt;
- struct pccard_devinfo *devi, *next;
- struct pccard_device *drvlist;
-
- for (slt = slot_list; slt; slt = slt->next)
- for (devi = slt->devices; devi; devi = next) {
- next = devi->next;
- if (devi->drv == drv)
- pccard_remove_device(devi);
- }
- /*
- * Once all the devices belonging to this driver have been
- * freed, then remove the driver from the list
- * of registered drivers.
- */
- if (drivers == drv)
- drivers = drv->next;
- else
- for (drvlist = drivers; drvlist->next; drvlist = drvlist->next)
- if (drvlist->next == drv) {
- drvlist->next = drv->next;
- break;
- }
-}
-
-/*
- * pccard_remove_controller - Called when the slot
- * driver is unloaded. The plan is to unload
- * drivers from the slots, and then remove the
- * slots from the slot list, and then finally
- * remove the controller structure. Messy...
- */
-void
-pccard_remove_controller(struct slot_ctrl *ctrl)
-{
- struct slot *slt, *next, *last = 0;
- struct slot_ctrl *cl;
- struct pccard_devinfo *devi;
-
- for (slt = slot_list; slt; slt = next) {
- next = slt->next;
- /*
- * If this slot belongs to this controller,
- * remove this slot.
- */
- if (slt->ctrl == ctrl) {
- pccard_slots[slt->slotnum] = 0;
- if (slt->insert_seq)
- untimeout(inserted, (void *)slt, slt->insert_ch);
- /*
- * Unload the drivers attached to this slot.
- */
- while ((devi = slt->devices) != NULL)
- pccard_remove_device(devi);
- /*
- * Disable the slot and unlink the slot from the
- * slot list.
- */
- disable_slot(slt);
- if (last)
- last->next = next;
- else
- slot_list = next;
-#if NAPM > 0
- apm_hook_disestablish(APM_HOOK_SUSPEND,
- &s_hook[slt->slotnum]);
- apm_hook_disestablish(APM_HOOK_RESUME,
- &r_hook[slt->slotnum]);
-#endif
- if (ctrl->extra && slt->cdata)
- FREE(slt->cdata, M_DEVBUF);
- FREE(slt, M_DEVBUF);
- /*
- * Can't use slot after we have freed it.
- */
- } else {
- last = slt;
- }
- }
- /*
- * Unlink controller structure from controller list.
- */
- if (cont_list == ctrl)
- cont_list = ctrl->next;
- else
- for (cl = cont_list; cl->next; cl = cl->next)
- if (cl->next == ctrl) {
- cl->next = ctrl->next;
- break;
- }
-}
-
/*
* Power off the slot.
* (doing it immediately makes the removal of some cards unstable)
@@ -331,39 +157,19 @@ 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.
+ */
+ s = splhigh();
/* Power off the slot. */
slt->pwr_off_pending = 0;
slt->ctrl->disable(slt);
-}
-
-/*
- * unregister_device_interrupt - Disable the interrupt generation to
- * the device driver which is handling it, so we can remove it.
- */
-static void
-unregister_device_interrupt(struct pccard_devinfo *devi)
-{
- struct slot *slt = devi->slt;
- int s;
-
- if (devi->running) {
- s = splhigh();
- devi->drv->disable(devi);
- devi->running = 0;
- if (devi->isahd.id_irq && --slt->irqref <= 0) {
- slt->ctrl->mapirq(slt, 0);
- INTRDIS(1<<slt->irq);
- unregister_pcic_intr(slt->irq, slot_irq_handler);
- if (devi->drv->imask)
- INTRUNMASK(*devi->drv->imask,(1<<slt->irq));
- /* Remove from the PCIC controller imask */
- if (slt->ctrl->imask)
- INTRUNMASK(*(slt->ctrl->imask), (1<<slt->irq));
- slt->irq = 0;
- }
- splx(s);
- }
+ splx(s);
}
/*
@@ -390,9 +196,7 @@ disable_slot(struct slot *slt)
*/
pccarddev = devclass_get_device(pccard_devclass, 0);
for (devi = slt->devices; devi; devi = devi->next) {
- unregister_device_interrupt(devi);
if (devi->isahd.id_device != 0) {
- pccnbk_release_resources(devi->isahd.id_device);
device_delete_child(pccarddev, devi->isahd.id_device);
devi->isahd.id_device = 0;
}
@@ -408,11 +212,6 @@ disable_slot(struct slot *slt)
slt->mem[i].flags = 0;
(void)slt->ctrl->mapmem(slt, i);
}
- for (i = 0; i < slt->ctrl->maxio; i++)
- if (slt->io[i].flags & IODF_ACTIVE) {
- slt->io[i].flags = 0;
- (void)slt->ctrl->mapio(slt, i);
- }
}
/*
@@ -427,6 +226,7 @@ slot_suspend(void *arg)
/* This code stolen from pccard_event:card_removed */
if (slt->state == filled) {
int s = splhigh();
+printf("splhigh -- slot_suspend\n");
disable_slot(slt);
slt->laststate = filled;
slt->state = suspend;
@@ -529,35 +329,36 @@ pccard_alloc_slot(struct slot_ctrl *ctrl)
}
/*
- * pccard_alloc_intr - allocate an interrupt from the
- * free interrupts and return its number. The interrupts
- * allowed are passed as a mask.
+ * Allocate resources for this device in the rman system.
*/
-int
-pccard_alloc_intr(u_int imask, ointhand2_t *hand, int unit,
- u_int *maskp, u_int *pcic_imask)
+static int
+pccard_alloc_resources(device_t dev)
{
- int irq;
- unsigned int mask;
-
- for (irq = 1; irq < ICU_LEN; irq++) {
- mask = 1ul << irq;
- if (!(mask & imask))
- continue;
- INTRMASK(*maskp, mask);
- if (register_pcic_intr(irq, unit, 0, hand, maskp, unit) == 0) {
- /* add this to the PCIC controller's mask */
- if (pcic_imask)
- INTRMASK(*pcic_imask, (1 << irq));
- update_intr_masks();
- INTREN(mask);
- return(irq);
- }
- /* No luck, remove from mask again... */
- INTRUNMASK(*maskp, mask);
- update_intr_masks();
+ /* XXX NEED TO DO MEMORY TOO XXX */
+ struct pccard_devinfo *devi = device_get_ivars(dev);
+ int rid;
+ u_long start;
+ u_long count;
+ int e;
+
+ start = devi->isahd.id_iobase;
+ count = devi->isahd.id_iosize;
+
+ rid = 0;
+ e = bus_set_resource(dev, SYS_RES_IOPORT, rid, start, count);
+ if (e) {
+ printf("ioport error %d\n", e);
+ return e;
+ }
+ rid = 0;
+ start = ffs(devi->isahd.id_irq) - 1;
+ count = 1;
+ e = bus_set_resource(dev, SYS_RES_IRQ, rid, start, count);
+ if (e) {
+ printf("irq error %d\n", e);
+ return e;
}
- return(-1);
+ return(0);
}
/*
@@ -568,80 +369,20 @@ static int
allocate_driver(struct slot *slt, struct dev_desc *desc)
{
struct pccard_devinfo *devi;
- struct pccard_device *drv;
device_t pccarddev;
- char devnam[128];
int err, irq = 0;
+ device_t child;
pccarddev = devclass_get_device(pccard_devclass, 0);
- snprintf(devnam, sizeof(devnam), "pccard-%s", desc->name);
- drv = find_driver(desc->name);
- if (drv == 0)
- return(ENXIO);
- /*
- * If an instance of this driver is already installed,
- * but not running, then remove it. If it is running,
- * then reject the request.
- */
- for (devi = slt->devices; devi; devi = devi->next) {
- if (devi->drv == drv && devi->isahd.id_unit == desc->unit) {
- if (devi->running) {
- printf("pccard: %s%d still running\n",
- devi->drv->name, desc->unit);
- return(EBUSY);
- }
- pccard_remove_device(devi);
- break;
- }
- }
- /*
- * If an interrupt mask has been given, then check it
- * against the slot interrupt (if one has been allocated).
- */
- if (desc->irqmask && drv->imask) {
- if ((slt->ctrl->irqs & desc->irqmask) == 0) {
- printf("pccard: PIOCSDRV requested irq (mask 0x%x) is "
- "not free (available mask 0x%x)\n", desc->irqmask,
- slt->ctrl->irqs);
- return(EINVAL);
- }
- if (slt->irq) {
- if (((1 << slt->irq) & desc->irqmask) == 0) {
- printf("pccard: PIOSCDRIV irq %d not in "
- "available mask 0x%x\n", slt->irq,
- desc->irqmask);
- return(EINVAL);
- }
- slt->irqref++;
- irq = slt->irq;
- } else {
- /*
- * Attempt to allocate an interrupt.
- * XXX We lose at the moment if the second
- * device relies on a different interrupt mask.
- */
- irq = pccard_alloc_intr(desc->irqmask,
- slot_irq_handler, (int)slt,
- drv->imask, slt->ctrl->imask);
- if (irq < 0) {
- printf("pccard: alloc intr failed irq %d\n",
- irq);
- return(EINVAL);
- }
- slt->irq = irq;
- slt->irqref = 1;
- slt->ctrl->mapirq(slt, slt->irq);
- }
- }
+ irq = ffs(desc->irqmask) - 1;
MALLOC(devi, struct pccard_devinfo *, sizeof(*devi), M_DEVBUF, M_WAITOK);
bzero(devi, sizeof(*devi));
+ strcpy(devi->name, desc->name);
/*
* Create an entry for the device under this slot.
*/
devi->running = 1;
- devi->drv = drv;
devi->slt = slt;
- devi->isahd.id_irq = irq;
devi->isahd.id_unit = desc->unit;
devi->isahd.id_msize = desc->memsize;
devi->isahd.id_iobase = desc->iobase;
@@ -661,52 +402,18 @@ allocate_driver(struct slot *slt, struct dev_desc *desc)
/*
* XXX I think the following should be done in an attach
* routine, but can't seem to slip the knot to get it working
- * right. This is one reason I call this a kludge
+ * right. This is one reason I call this a kludge...
*/
- devi->isahd.id_device = device_add_child(pccarddev, devnam,
+ resource_list_init(&devi->resources);
+ child = devi->isahd.id_device = device_add_child(pccarddev, devi->name,
devi->isahd.id_unit, devi);
- if ((err = pccnbk_alloc_resources(devi->isahd.id_device)) != 0) {
- device_delete_child(pccarddev, devi->isahd.id_device);
- devi->isahd.id_device = 0;
- free(devi, M_DEVBUF);
- return(err);
- }
- err = device_probe_and_attach(devi->isahd.id_device);
+ pccard_alloc_resources(child);
+ err = device_probe_and_attach(child);
+ if (err)
+ device_delete_child(pccarddev, child);
return err;
}
-void
-pccard_remove_device(struct pccard_devinfo *devi)
-{
- struct slot *slt = devi->slt;
- struct pccard_devinfo *list;
-
- /*
- * If an interrupt is enabled on this slot,
- * then unregister it if no-one else is using it.
- */
- unregister_device_interrupt(devi);
- if (devi->isahd.id_device)
- pccnbk_release_resources(devi->isahd.id_device);
- devi->isahd.id_device = NULL;
-
- /*
- * Remove from device list on this slot.
- */
- if (slt->devices == devi)
- slt->devices = devi->next;
- else
- for (list = slt->devices; list->next; list = list->next)
- if (list->next == devi) {
- list->next = devi->next;
- break;
- }
- /*
- * Finally, free the memory space.
- */
- FREE(devi, M_DEVBUF);
-}
-
/*
* card insert routine - Called from a timeout to debounce
* insertion events.
@@ -758,6 +465,7 @@ pccard_event(struct slot *slt, enum card_event event)
*/
if (slt->state == filled) {
int s = splhigh();
+printf("splhigh card_removed\n");
disable_slot(slt);
slt->state = empty;
splx(s);
@@ -775,32 +483,6 @@ pccard_event(struct slot *slt, enum card_event event)
}
/*
- * slot_irq_handler - Interrupt handler for shared irq devices.
- */
-static void
-slot_irq_handler(int arg)
-{
- struct pccard_devinfo *devi;
- struct slot *slt = (struct slot *)arg;
-
- /*
- * For each device that has the shared interrupt,
- * call the interrupt handler. If the interrupt was
- * caught, the handler returns true.
- */
- for (devi = slt->devices; devi; devi = devi->next)
- if (devi->isahd.id_irq && devi->running &&
- devi->drv->handler(devi))
- return;
- /*
- * XXX - Should 'debounce' these for drivers that have recently
- * been removed.
- */
- printf("pccard: slot %d, unfielded interrupt (%d)\n", slt->slotnum,
- slt->irq);
-}
-
-/*
* Device driver interface.
*/
static int
@@ -853,10 +535,6 @@ crdread(dev_t dev, struct uio *uio, int ioflag)
mp = &slt->mem[win];
oldmap = *mp;
mp->flags = slt->rwmem|MDF_ACTIVE;
-#if 0
- printf("Rd at offs %d, size %d\n", (int)uio->uio_offset,
- uio->uio_resid);
-#endif
while (uio->uio_resid && error == 0) {
mp->card = uio->uio_offset;
mp->size = PCCARD_MEMSIZE;
@@ -896,17 +574,13 @@ crdwrite(dev_t dev, struct uio *uio, int ioflag)
if (pccard_mem == 0)
return(ENOMEM);
for (win = 0; win < slt->ctrl->maxmem; win++)
- if ((slt->mem[win].flags & MDF_ACTIVE)==0)
+ if ((slt->mem[win].flags & MDF_ACTIVE) == 0)
break;
if (win >= slt->ctrl->maxmem)
return(EBUSY);
mp = &slt->mem[win];
oldmap = *mp;
mp->flags = slt->rwmem|MDF_ACTIVE;
-#if 0
- printf("Wr at offs %d, size %d\n", (int)uio->uio_offset,
- uio->uio_resid);
-#endif
while (uio->uio_resid && error == 0) {
mp->card = uio->uio_offset;
mp->size = PCCARD_MEMSIZE;
@@ -916,9 +590,6 @@ crdwrite(dev_t dev, struct uio *uio, int ioflag)
offs = (unsigned int)uio->uio_offset & (PCCARD_MEMSIZE - 1);
p = pccard_kmem + offs;
count = MIN(PCCARD_MEMSIZE - offs, uio->uio_resid);
-#if 0
- printf("Writing %d bytes to address 0x%x\n", count, p);
-#endif
error = uiomove(p, count, uio);
}
/*
@@ -963,7 +634,7 @@ crdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
splx(s);
((struct slotstate *)data)->maxmem = slt->ctrl->maxmem;
((struct slotstate *)data)->maxio = slt->ctrl->maxio;
- ((struct slotstate *)data)->irqs = slt->ctrl->irqs;
+ ((struct slotstate *)data)->irqs = 0;
break;
/*
* Get memory context.
@@ -1017,7 +688,8 @@ crdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
if (s < 0 || s >= slt->ctrl->maxio)
return(EINVAL);
slt->io[s] = *((struct io_desc *)data);
- return(slt->ctrl->mapio(slt, s));
+ /* XXX Don't actually map */
+ return 0;
break;
/*
* Set memory window flags for read/write interface.
@@ -1126,14 +798,3 @@ invalid_io_memory(unsigned long adr, int size)
return(1);
return(0);
}
-
-static struct pccard_device *
-find_driver(char *name)
-{
- struct pccard_device *drv;
-
- for (drv = drivers; drv; drv = drv->next)
- if (strcmp(drv->name, name)==0)
- return(drv);
- return(0);
-}
diff --git a/sys/pccard/pccard_compat.c b/sys/pccard/pccard_compat.c
deleted file mode 100644
index 9bc435a..0000000
--- a/sys/pccard/pccard_compat.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (c) 1999, 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$
- */
-
-#include "opt_bus.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/queue.h>
-#include <sys/select.h>
-#include <sys/types.h>
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <machine/resource.h>
-
-#include <i386/isa/isa_device.h>
-#include <pccard/cardinfo.h>
-#include <pccard/driver.h>
-#include <pccard/pcic.h>
-#include <pccard/slot.h>
-#include <pccard/pccard_nbk.h>
-
-/* ============================================================ */
-
-static int
-pccnbk_probe(device_t dev)
-{
- char devnam[128];
- const char *name;
- struct pccard_devinfo *devi = device_get_ivars(dev);
-
- if (devi) {
- name = device_get_name(dev);
- snprintf(devnam, sizeof(devnam), "pccard-%s",
- devi->drv->name);
- if (!name || strcmp(name, devnam) != 0)
- return ENXIO;
- device_set_desc(dev, devi->drv->name);
- return 0;
- }
- return ENXIO;
-}
-
-static int
-pccnbk_attach(device_t dev)
-{
- struct pccard_devinfo *devi = device_get_ivars(dev);
- struct pccard_device *drv;
- struct slot *slt;
- int err;
- int s;
-
- slt = devi->slt;
- drv = devi->drv;
- devi->next = slt->devices;
- slt->devices = devi;
- s = splhigh();
- err = drv->enable(devi);
- splx(s);
- /*
- * If the enable functions returns no error, then the
- * device has been successfully installed. If so, then
- * attach it to the slot, otherwise free it and return
- * the error. We assume that when we free the device,
- * it will also set 'running' to off.
- */
- if (err) {
- printf("pccard: %s%d Enable failed %d\n", devi->drv->name,
- devi->isahd.id_unit, err);
- pccard_remove_device(devi);
- }
- return(err);
-}
-
-/*
- * Allocate resources for this device in the rman system.
- */
-int
-pccnbk_alloc_resources(device_t dev)
-{
- struct pccard_devinfo *devi = device_get_ivars(dev);
- int rid;
- u_long start;
- u_long end;
- u_long count;
-
- start = devi->isahd.id_iobase;
- count = devi->isahd.id_iosize;
- end = start + count - 1;
-
- rid = 0;
- devi->iorv = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
- SYS_RES_IOPORT, &rid, start, end, count, RF_ACTIVE);
- if (!devi->iorv) {
- printf("Cannot allocate ports 0x%lx-0x%lx\n", start, end);
- return (ENOMEM);
- }
- rid = 0;
- start = end = ffs(devi->isahd.id_irq) - 1;
- count = 1;
- devi->irqrv = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
- SYS_RES_IRQ, &rid, start, end, count, RF_ACTIVE);
- if (!devi->irqrv) {
- return (ENOMEM);
- }
- return(0);
-}
-
-void
-pccnbk_release_resources(device_t dev)
-{
- struct pccard_devinfo *devi = device_get_ivars(dev);
- u_long start;
- u_long end;
- u_long count;
-
- start = devi->isahd.id_iobase;
- count = devi->isahd.id_iosize;
- end = start + count - 1;
-
- if (devi->iorv) {
- BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
- SYS_RES_IOPORT, 0, devi->iorv);
- devi->iorv = NULL;
- }
- if (devi->irqrv) {
- BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, SYS_RES_IRQ,
- 0, devi->irqrv);
- devi->irqrv = NULL;
- }
-}
-
-static device_method_t pccnbk_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, pccnbk_probe),
- DEVMETHOD(device_attach, pccnbk_attach),
- 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_driver_added, bus_generic_driver_added),
- DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_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),
-
- { 0, 0 }
-};
-
-void
-pccnbk_wrap_old_driver(struct pccard_device *drv)
-{
- char devnam[128];
- char *nm;
- driver_t *driver;
-
- snprintf(devnam, sizeof(devnam), "pccard-%s", drv->name);
- driver = malloc(sizeof(driver_t), M_DEVBUF, M_NOWAIT);
- if (!driver)
- return;
- bzero(driver, sizeof(driver_t));
- /* XXX May create a memory leak for load/unload :-( XXX */
- nm = malloc(strlen(devnam) + 1, M_DEVBUF, M_NOWAIT);
- strcpy(nm, devnam);
- driver->name = nm;
- driver->methods = pccnbk_methods;
- driver->softc = sizeof(struct pccard_device);
- driver->priv = drv;
- devclass_add_driver(pccard_devclass, driver);
- drv->driver = driver;
-}
-
-#if 0
-static devclass_t pccnbk_devclass;
-
-static driver_t pccnbk_driver = {
- "pccnbk",
- pccnbk_methods,
- 1, /* no softc */
-};
-
-DRIVER_MODULE(pccnbk, pccard, pccnbk_driver, pccnbk_devclass, 0, 0);
-#endif
diff --git a/sys/pccard/pccard_nbk.c b/sys/pccard/pccard_nbk.c
index a10f0e2..1fc9bee 100644
--- a/sys/pccard/pccard_nbk.c
+++ b/sys/pccard/pccard_nbk.c
@@ -76,6 +76,11 @@
devclass_t pccard_devclass;
+#define PCCARD_NPORT 2
+#define PCCARD_NMEM 5
+#define PCCARD_NIRQ 1
+#define PCCARD_NDRQ 0
+
static int
pccard_add_children(device_t dev, int busno)
{
@@ -90,28 +95,54 @@ pccard_probe(device_t dev)
return pccard_add_children(dev, device_get_unit(dev));
}
+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 = device_get_ivars(child);
+ struct resource_list *rl = &devi->resources;
int retval = 0;
retval += bus_print_child_header(dev, child);
retval += printf(" at");
if (devi) {
- if (devi->iorv) {
- retval += printf(" port 0x%lx",
- rman_get_start(devi->iorv));
- if (rman_get_start(devi->iorv) !=
- rman_get_end(devi->iorv))
- retval += printf("-0x%lx",
- rman_get_end(devi->iorv));
- }
- if (devi->irqrv) {
- retval += printf(" irq %ld",
- rman_get_start(devi->irqrv));
- }
+ 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");
retval += printf(" slot %d", devi->slt->slotnum);
}
@@ -120,22 +151,116 @@ pccard_print_child(device_t dev, device_t child)
return (retval);
}
-/*
- * Create "connection point"
- */
+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 = device_get_ivars(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 = device_get_ivars(child);
+ struct resource_list *rl = &devi->resources;
+ struct resource_list_entry *rle;
+
+ rle = resource_list_find(rl, type, rid);
+ if (!rle)
+ return ENOENT;
+
+ *startp = rle->start;
+ *countp = rle->count;
+
+ return 0;
+}
+
static void
-pccard_identify(driver_t *driver, device_t parent)
+pccard_delete_resource(device_t dev, device_t child, int type, int rid)
{
- device_t child;
+ struct pccard_devinfo *devi = device_get_ivars(child);
+ struct resource_list *rl = &devi->resources;
+ resource_list_delete(rl, type, rid);
+}
- child = BUS_ADD_CHILD(parent, 0, "pccard", 0);
- if (child == NULL)
- panic("pccard_identify");
+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-3 for memory and 0-1 for ports
+ */
+ int passthrough = (device_get_parent(child) != bus);
+ int isdefault = (start == 0UL && end == ~0UL);
+ struct pccard_devinfo *devi = device_get_ivars(child);
+ struct resource_list *rl = &devi->resources;
+ struct resource_list_entry *rle;
+
+ if (!passthrough && !isdefault) {
+ rle = resource_list_find(rl, type, *rid);
+ if (!rle) {
+ if (*rid < 0)
+ return 0;
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (*rid >= PCCARD_NIRQ)
+ return 0;
+ break;
+ case SYS_RES_DRQ:
+ if (*rid >= PCCARD_NDRQ)
+ return 0;
+ break;
+ case SYS_RES_MEMORY:
+ if (*rid >= PCCARD_NMEM)
+ return 0;
+ break;
+ case SYS_RES_IOPORT:
+ if (*rid >= PCCARD_NPORT)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ resource_list_add(rl, type, *rid, start, end, count);
+ }
+ }
+
+ return resource_list_alloc(rl, bus, child, type, rid,
+ start, end, count, flags);
+}
+
+static int
+pccard_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct pccard_devinfo *devi = device_get_ivars(child);
+ struct resource_list *rl = &devi->resources;
+ return resource_list_release(rl, bus, child, type, rid, r);
}
static device_method_t pccard_methods[] = {
/* Device interface */
- DEVMETHOD(device_identify, pccard_identify),
DEVMETHOD(device_probe, pccard_probe),
DEVMETHOD(device_attach, bus_generic_attach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
@@ -144,14 +269,17 @@ static device_method_t pccard_methods[] = {
/* Bus interface */
DEVMETHOD(bus_print_child, pccard_print_child),
-/* DEVMETHOD(bus_probe_nomatch, pccard_probe_nomatch),*/
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
- DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ 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),
+
{ 0, 0 }
};
diff --git a/sys/pccard/pccard_nbk.h b/sys/pccard/pccard_nbk.h
index 971191e..bf0a20c 100644
--- a/sys/pccard/pccard_nbk.h
+++ b/sys/pccard/pccard_nbk.h
@@ -31,11 +31,5 @@
struct pccard_device;
extern devclass_t pccard_devclass;
-extern int pccnbk_alloc_resources(device_t);
-extern void pccnbk_release_resources(device_t);
-extern void pccnbk_wrap_old_driver(struct pccard_device *);
-
-/* kludges */
-extern void pccard_remove_device(struct pccard_devinfo *);
#endif /* ! PCCARD_PCCARD_NBK_H */
diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c
index 1d8f39a..e186403 100644
--- a/sys/pccard/pcic.c
+++ b/sys/pccard/pcic.c
@@ -30,11 +30,6 @@
* $FreeBSD$
*/
-/*
- * pcic98 : PC9801 original PCMCIA controller code for NS/A,Ne,NX/C,NR/L.
- * by Noriyuki Hosobuchi <yj8n-hsbc@asahi-net.or.jp>
- */
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -44,14 +39,13 @@
#include <machine/clock.h>
+#if 0
#include <i386/isa/icu.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/intr_machdep.h>
+#endif
#include <pccard/i82365.h>
-#ifdef PC98
-#include <pccard/pcic98reg.h>
-#endif
#include <pccard/cardinfo.h>
#include <pccard/driver.h>
@@ -95,7 +89,6 @@ static struct pcic_slot {
} pcic_slots[PCIC_MAX_SLOTS];
static int pcic_irq;
-static unsigned pcic_imask;
static struct slot_ctrl cinfo;
@@ -112,12 +105,6 @@ getb1(struct pcic_slot *sp, int reg)
return inb(sp->data);
}
-static __inline unsigned char
-getb2(struct pcic_slot *sp, int reg)
-{
- return (sp->regs[reg]);
-}
-
/*
* Write a register on the PCIC
*/
@@ -128,12 +115,6 @@ putb1(struct pcic_slot *sp, int reg, unsigned char val)
outb(sp->data, val);
}
-static __inline void
-putb2(struct pcic_slot *sp, int reg, unsigned char val)
-{
- sp->regs[reg] = val;
-}
-
/*
* Clear bit(s) of a register.
*/
@@ -162,71 +143,6 @@ putw(struct pcic_slot *sp, int reg, unsigned short word)
sp->putb(sp, reg + 1, (word >> 8) & 0xff);
}
-
-/*
- * Gerneral functions for registering and unregistering interrupts.
- * isa_to_apic() is used to map the ISA IRQ onto the APIC IRQ to
- * check if the APIC IRQ is used or free.
- */
-#ifdef APIC_IO
-int register_pcic_intr(int intr, int device_id, u_int flags,
- ointhand2_t handler, u_int *maskptr, int unit)
-{
- int apic_intr;
- apic_intr = isa_apic_irq(intr);
- if (apic_intr <0)
- return -1;
- else
- return register_intr(apic_intr, device_id, flags, handler,
- maskptr, unit);
-}
-
-int unregister_pcic_intr(int intr, ointhand2_t handler)
-{
- int apic_intr;
- apic_intr = isa_apic_irq(intr);
- return unregister_intr(apic_intr, handler);
-}
-
-#else /* Not APIC_IO */
-
-int register_pcic_intr(int intr, int device_id, u_int flags,
- ointhand2_t handler, u_int *maskptr, int unit)
-{
- return register_intr(intr, device_id, flags, handler, maskptr, unit);
-}
-
-int unregister_pcic_intr(int intr, ointhand2_t handler)
-{
- return unregister_intr(intr, handler);
-}
-
-#endif /* APIC_IO */
-
-#if 0
-static void
-pcic_dump_attributes(unsigned char *scratch, int maxlen)
-{
- int i,j,k;
-
- i = 0;
- while (scratch[i] != 0xff && i < maxlen) {
- unsigned char link = scratch[i+2];
-
- /*
- * Dump attribute memory
- */
- if (scratch[i]) {
- printf("[%02x] ", i);
- for (j = 0; j < 2 * link + 4 && j < 128; j += 2)
- printf("%02x ", scratch[j + i]);
- printf("\n");
- }
- i += 4 + 2 * link;
- }
-}
-#endif
-
/*
* entry point from main code to map/unmap memory context.
*/
@@ -237,49 +153,6 @@ pcic_memory(struct slot *slt, int win)
struct mem_desc *mp = &slt->mem[win];
int reg = mp->window * PCIC_MEMSIZE + PCIC_MEMBASE;
-#ifdef PC98
- if (sp->controller == PCIC_PC98) {
- if (mp->flags & MDF_ACTIVE) {
- /* slot = 0, window = 0, sys_addr = 0xda000, length = 8KB */
- unsigned char x;
-
- if ((unsigned long)mp->start != 0xda000) {
- printf("sys_addr must be 0xda000. requested address = 0x%x\n",
- mp->start);
- return(EINVAL);
- }
-
- /* omajinai ??? */
- outb(PCIC98_REG0, 0);
- x = inb(PCIC98_REG1);
- x &= 0xfc;
- x |= 0x02;
- outb(PCIC98_REG1, x);
-
- outw(PCIC98_REG_PAGOFS, 0);
-
- if (mp->flags & MDF_ATTR) {
- outb(PCIC98_REG6, inb(PCIC98_REG6) | PCIC98_ATTRMEM);
- }else{
- outb(PCIC98_REG6, inb(PCIC98_REG6) & (~PCIC98_ATTRMEM));
- }
-
- outb(PCIC98_REG_WINSEL, PCIC98_MAPWIN);
-
-#if 0
- if ((mp->flags & MDF_16BITS) == 1) { /* 16bit */
- outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_8BIT));
- }else{ /* 8bit */
- outb(PCIC98_REG2, inb(PCIC98_REG2) | PCIC98_8BIT);
- }
-#endif
- }else{
- outb(PCIC98_REG_WINSEL, PCIC98_UNMAPWIN);
- }
- return 0;
- }
-#endif /* PC98 */
-
if (mp->flags & MDF_ACTIVE) {
unsigned long sys_addr = (uintptr_t)(void *)mp->start >> 12;
/*
@@ -290,11 +163,6 @@ pcic_memory(struct slot *slt, int win)
putw(sp, reg, sys_addr & 0xFFF);
putw(sp, reg+2, (sys_addr + (mp->size >> 12) - 1) & 0xFFF);
putw(sp, reg+4, ((mp->card >> 12) - sys_addr) & 0x3FFF);
-#if 0
- printf("card offs = card_adr = 0x%x 0x%x, sys_addr = 0x%x\n",
- mp->card, ((mp->card >> 12) - sys_addr) & 0x3FFF,
- sys_addr);
-#endif
/*
* Each 16 bit register has some flags in the upper bits.
*/
@@ -310,26 +178,12 @@ pcic_memory(struct slot *slt, int win)
setb(sp, reg+5, PCIC_REG);
if (mp->flags & MDF_WP)
setb(sp, reg+5, PCIC_WP);
-#if 0
- printf("Slot number %d, reg 0x%x, offs 0x%x\n",
- sp->slotnum, reg, sp->offset);
- printf("Map window to sys addr 0x%x for %d bytes, card 0x%x\n",
- mp->start, mp->size, mp->card);
- printf("regs are: 0x%02x%02x 0x%02x%02x 0x%02x%02x flags 0x%x\n",
- sp->getb(sp, reg), sp->getb(sp, reg+1),
- sp->getb(sp, reg+2), sp->getb(sp, reg+3),
- sp->getb(sp, reg+4), sp->getb(sp, reg+5),
- mp->flags);
-#endif
/*
* Enable the memory window. By experiment, we need a delay.
*/
setb(sp, PCIC_ADDRWINE, (1<<win) | PCIC_MEMCS16);
DELAY(50);
} else {
-#if 0
- printf("Unmapping window %d\n", win);
-#endif
clrb(sp, PCIC_ADDRWINE, 1<<win);
putw(sp, reg, 0);
putw(sp, reg+2, 0);
@@ -347,46 +201,6 @@ pcic_io(struct slot *slt, int win)
int mask, reg;
struct pcic_slot *sp = slt->cdata;
struct io_desc *ip = &slt->io[win];
-#ifdef PC98
- if (sp->controller == PCIC_PC98) {
- unsigned char x;
-
-#if 0
- if (win =! 0) {
- printf("pcic98:Illegal PCIC I/O window request(%d)!", win);
- return(EINVAL);
- }
-#endif
-
- if (ip->flags & IODF_ACTIVE) {
- unsigned short base;
-
- x = inb(PCIC98_REG2) & 0x0f;
- if (! (ip->flags & IODF_16BIT))
- x |= PCIC98_8BIT;
-
- if (ip->size > 16) /* 128bytes mapping */
- x |= PCIC98_MAP128;
-
- x |= PCIC98_IOMEMORY;
- outb(PCIC98_REG2, x);
-
- base = 0x80d0;
- outw(PCIC98_REG4, base); /* 98side IO base */
- outw(PCIC98_REG5, ip->start); /* card side IO base */
-
-#ifdef PCIC_DEBUG
- printf("pcic98: IO mapped 0x%04x(98) -> 0x%04x(Card) and width %d bytes\n",
- base, ip->start, ip->size);
-#endif
- ip->start = base;
-
- }else{
- outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_IOMEMORY));
- }
- return 0;
- }
-#endif
switch (win) {
case 0:
mask = PCIC_IO0_EN;
@@ -402,9 +216,6 @@ pcic_io(struct slot *slt, int win)
if (ip->flags & IODF_ACTIVE) {
unsigned char x, ioctlv;
-#ifdef PCIC_DEBUG
-printf("Map I/O 0x%x (size 0x%x) on Window %d\n", ip->start, ip->size, win);
-#endif /* PCIC_DEBUG */
putw(sp, reg, ip->start);
putw(sp, reg+2, ip->start+ip->size-1);
x = 0;
@@ -457,7 +268,6 @@ static int
pcic_probe(device_t dev)
{
int slotnum, validslots = 0;
- u_int free_irqs;
struct slot *slt;
struct pcic_slot *sp;
unsigned char c;
@@ -472,9 +282,6 @@ pcic_probe(device_t dev)
if (device_get_unit(dev) != 0)
return ENXIO;
- /* Determine the list of free interrupts */
- free_irqs = PCIC_INT_MASK_ALLOWED;
-
/*
* Initialise controller information structure.
*/
@@ -488,8 +295,6 @@ pcic_probe(device_t dev)
cinfo.resume = pcic_resume;
cinfo.maxmem = PCIC_MEM_WIN;
cinfo.maxio = PCIC_IO_WIN;
- cinfo.irqs = free_irqs;
- cinfo.imask = &pcic_imask;
sp = pcic_slots;
for (slotnum = 0; slotnum < PCIC_MAX_SLOTS; slotnum++, sp++) {
@@ -653,8 +458,8 @@ pcic_probe(device_t dev)
slt->cdata = sp;
sp->slt = slt;
/*
- * If we haven't allocated an interrupt for the controller,
- * then attempt to get one.
+ * If we haven't allocated an interrupt for the controller,
+ * then attempt to get one.
*/
if (pcic_irq == 0) {
/* See if the user has requested a specific IRQ */
@@ -704,42 +509,6 @@ pcic_probe(device_t dev)
if (pcic_irq > 0)
sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
}
-#ifdef PC98
- if (validslots == 0) {
- sp = pcic_slots;
- slotnum = 0;
- if (inb(PCIC98_REG0) != 0xff) {
- sp->controller = PCIC_PC98;
- sp->revision = 0;
- name = "PC98 Original";
- device_set_desc(dev, name);
- cinfo.maxmem = 1;
- cinfo.maxio = 1;
-/* cinfo.irqs = PCIC_INT_MASK_ALLOWED;*/
- cinfo.irqs = 0x1468;
- validslots++;
- sp->slotnum = slotnum;
-
- slt = pccard_alloc_slot(&cinfo);
- if (slt == 0) {
- printf("pcic98: slt == NULL\n");
- goto pcic98_probe_end;
- }
- slt->cdata = sp;
- sp->slt = slt;
-
- /* Check for a card in this slot */
- if (inb(PCIC98_REG1) & PCIC98_CARDEXIST) {
- /* PCMCIA card exist */
- slt->laststate = slt->state = filled;
- pccard_event(sp->slt, card_inserted);
- } else {
- slt->laststate = slt->state = empty;
- }
- }
- pcic98_probe_end:
- }
-#endif /* PC98 */
if (validslots && pcic_irq <= 0)
pcictimeout_ch = timeout(pcictimeout, 0, hz/2);
if (validslots) {
@@ -787,35 +556,6 @@ pcic_power(struct slot *slt)
struct pcic_slot *sp = slt->cdata;
switch(sp->controller) {
-#ifdef PC98
- case PCIC_PC98:
- reg = inb(PCIC98_REG6) & (~PCIC98_VPP12V);
- switch(slt->pwr.vpp) {
- default:
- return(EINVAL);
- case 50:
- break;
- case 120:
- reg |= PCIC98_VPP12V;
- break;
- }
- outb(PCIC98_REG6, reg);
- DELAY(100*1000);
-
- reg = inb(PCIC98_REG2) & (~PCIC98_VCC3P3V);
- switch(slt->pwr.vcc) {
- default:
- return(EINVAL);
- case 33:
- reg |= PCIC98_VCC3P3V;
- break;
- case 50:
- break;
- }
- outb(PCIC98_REG2, reg);
- DELAY(100*1000);
- return (0);
-#endif
case PCIC_PD672X:
case PCIC_PD6710:
case PCIC_VG365:
@@ -900,35 +640,6 @@ static void
pcic_mapirq(struct slot *slt, int irq)
{
struct pcic_slot *sp = slt->cdata;
-#ifdef PC98
- if (sp->controller == PCIC_PC98) {
- unsigned char x;
- switch (irq) {
- case 3:
- x = PCIC98_INT0; break;
- case 5:
- x = PCIC98_INT1; break;
- case 6:
- x = PCIC98_INT2; break;
- case 10:
- x = PCIC98_INT4; break;
- case 12:
- x = PCIC98_INT5; break;
- case 0: /* disable */
- x = PCIC98_INTDISABLE;
- break;
- default:
- printf("pcic98: illegal irq %d\n", irq);
- return;
- }
-#ifdef PCIC_DEBUG
- printf("pcic98: irq=%d mapped.\n", irq);
-#endif
- outb(PCIC98_REG3, x);
-
- return;
- }
-#endif
if (irq == 0)
clrb(sp, PCIC_INT_GEN, 0xF);
else
@@ -945,19 +656,6 @@ pcic_reset(void *chan)
struct slot *slt = chan;
struct pcic_slot *sp = slt->cdata;
-#ifdef PC98
- if (sp->controller == PCIC_PC98) {
- outb(PCIC98_REG0, 0);
- outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_IOMEMORY));
- outb(PCIC98_REG3, PCIC98_INTDISABLE);
- outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_VCC3P3V));
- outb(PCIC98_REG6, inb(PCIC98_REG6) & (~PCIC98_VPP12V));
- outb(PCIC98_REG1, 0);
-
- selwakeup(&slt->selp);
- return;
- }
-#endif
switch (slt->insert_seq) {
case 0: /* Something funny happended on the way to the pub... */
return;
@@ -997,11 +695,6 @@ pcic_disable(struct slot *slt)
{
struct pcic_slot *sp = slt->cdata;
-#ifdef PC98
- if (sp->controller == PCIC_PC98) {
- return;
- }
-#endif
sp->putb(sp, PCIC_INT_GEN, 0);
sp->putb(sp, PCIC_POWER, 0);
}
@@ -1030,26 +723,13 @@ pcicintr(void *arg)
int slot, s;
unsigned char chg;
struct pcic_slot *sp = pcic_slots;
+ static int count = 0;
+
+ if (count++ > 20)
+ Debugger("Trapdoor");
-#ifdef PC98
- if (sp->controller == PCIC_PC98) {
- slot = 0;
- s = splhigh();
- /* Check for a card in this slot */
- if (inb(PCIC98_REG1) & PCIC98_CARDEXIST) {
- if (sp->slt->laststate != filled) {
- pccard_event(sp->slt, card_inserted);
- }
- } else {
- if (sp->slt->laststate != empty) {
- pccard_event(sp->slt, card_removed);
- }
- }
- splx(s);
- return;
- }
-#endif /* PC98 */
s = splhigh();
+printf("splhigh for pcicintr\n");
for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++)
if (sp->slt && (chg = sp->getb(sp, PCIC_STAT_CHG)) != 0)
if (chg & PCIC_CDTCH) {
@@ -1060,6 +740,7 @@ pcicintr(void *arg)
pccard_event(sp->slt, card_removed);
}
}
+printf("splx\n");
splx(s);
}
@@ -1070,6 +751,7 @@ static void
pcic_resume(struct slot *slt)
{
struct pcic_slot *sp = slt->cdata;
+
if (pcic_irq > 0)
sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
if (sp->controller == PCIC_PD672X) {
@@ -1078,6 +760,85 @@ pcic_resume(struct slot *slt)
}
}
+static 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);
+ struct io_desc *ip = &devi->slt->io[rid];
+ int err;
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+#if 0
+ if (ip->flags & IODF_ACTIVE)
+ return EBUSY;
+#endif
+ 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:
+ pcic_mapirq(devi->slt, rman_get_start(r));
+ break;
+ case SYS_RES_MEMORY:
+ default:
+ break;
+ }
+ err = bus_generic_activate_resource(dev, child, type, rid, r);
+ return err;
+}
+
+static 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);
+ struct io_desc *ip = &devi->slt->io[rid];
+ int err;
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+#if 0
+ if (ip->flags & IODF_ACTIVE)
+ return EBUSY;
+#endif
+ ip->flags &= ~IODF_ACTIVE;
+ err = pcic_io(devi->slt, rid);
+ if (err) {
+ return err;
+ }
+ break;
+ case SYS_RES_IRQ:
+ pcic_mapirq(devi->slt, 0);
+ break;
+ case SYS_RES_MEMORY:
+ default:
+ break;
+ }
+ err = bus_generic_deactivate_resource(dev, child, type, rid, r);
+ return err;
+}
+
+static int
+pcic_setup_intr(device_t dev, device_t child, struct resource *irq,
+ int flags, driver_intr_t *intr, void *arg, void **cookiep)
+{
+ return (bus_generic_setup_intr(dev, child, irq, flags, intr, arg,
+ cookiep));
+}
+
+static int
+pcic_teardown_intr(device_t dev, device_t child, struct resource *irq,
+ void *cookie)
+{
+ return (bus_generic_teardown_intr(dev, child, irq, cookie));
+}
+
static device_method_t pcic_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pcic_probe),
@@ -1091,10 +852,10 @@ static device_method_t pcic_methods[] = {
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, 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_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),
{ 0, 0 }
};
diff --git a/sys/pccard/pcic.h b/sys/pccard/pcic.h
index 53839a3..3019e36 100644
--- a/sys/pccard/pcic.h
+++ b/sys/pccard/pcic.h
@@ -31,6 +31,14 @@
* $FreeBSD$
*/
-int register_pcic_intr(int intr, int device_id, u_int flags,
- ointhand2_t handler, u_int *maskptr, int unit);
-int unregister_pcic_intr(int intr, ointhand2_t handler);
+#define PCIC_RF_IODF_WS (0x01 << 16)
+#define PCIC_RF_IODF_16BIT (0x02 << 16)
+#define PCIC_RF_IODF_CS16 (0x04 << 16)
+#define PCIC_RF_IODF_ZEROWS (0x08 << 16)
+
+#define PCIC_RF_MDF_16BITS (0x01 << 16)
+#define PCIC_RF_MDF_ZEROWS (0x02 << 16)
+#define PCIC_RF_MDF_WS0 (0x04 << 16)
+#define PCIC_RF_MDF_WS1 (0x08 << 16)
+#define PCIC_RF_MDF_ATTR (0x10 << 16)
+#define PCIC_RF_MDF_WP (0x20 << 16)
diff --git a/sys/pccard/skel.c b/sys/pccard/skel.c
deleted file mode 100644
index 7c8c6a9..0000000
--- a/sys/pccard/skel.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Loadable kernel module skeleton driver
- * 11 July 1995 Andrew McRae
- *
- *-------------------------------------------------------------------------
- *
- * 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.
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/conf.h>
-#include <sys/mount.h>
-#include <sys/sysent.h>
-#include <sys/exec.h>
-
-#include <i386/isa/isa_device.h>
-
-#include <sys/select.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <pccard/cardinfo.h>
-#include <pccard/driver.h>
-#include <pccard/slot.h>
-
-static int skelinit(struct pccard_devinfo *); /* init device */
-static void skelunload(struct pccard_devinfo *); /* Disable driver */
-static int skelintr(struct pccard_devinfo *); /* Interrupt handler */
-
-PCCARD_MODULE(skel, skelinit, skelunload, skelintr, 0, net_imask);
-
-static int opened; /* Rather minimal device state... */
-
-/*
- * Skeleton driver entry points for PCCARD configuration.
- */
-/*
- * Initialize the device.
- */
-static int
-skelinit(struct pccard_devinfo *devi)
-{
- int unit = devi->isahd.id_unit;
-
- if (opened & (1 << unit))
- return(EBUSY);
- opened |= 1 << unit;
- printf("%s%d: init\n", devi->drv->name, unit);
- printf("%s%d: irq %d iobase 0x%x maddr 0x%x memlen %d\n",
- devi->drv->name, unit, devi->isahd.id_irq,
- devi->isahd.id_iobase, devi->isahd.id_maddr,
- devi->isahd.id_msize);
- return(0);
-}
-/*
- * The device entry is being removed. Shut it down,
- * and turn off interrupts etc. Not called unless
- * the device was successfully installed.
- */
-static void
-skelunload(struct pccard_devinfo *devi)
-{
- int unit = devi->isahd.id_unit;
-
- printf("%s%d: unload\n", devi->drv->name, unit);
- opened &= ~(1 << unit);
-}
-/*
- * Interrupt handler.
- * Returns true if the interrupt is for us.
- */
-static int
-skelintr(struct pccard_devinfo *devi)
-{
- return(0);
-}
diff --git a/sys/pccard/slot.h b/sys/pccard/slot.h
index 07e4d0d..18ffc62 100644
--- a/sys/pccard/slot.h
+++ b/sys/pccard/slot.h
@@ -72,8 +72,6 @@ struct slot_ctrl {
int extra; /* Controller specific size */
int maxmem; /* Number of allowed memory windows */
int maxio; /* Number of allowed I/O windows */
- int irqs; /* IRQ's that are allowed */
- u_int *imask; /* IRQ mask for the PCIC controller */
/*
* The rest is maintained by the mainline PC-CARD code.
@@ -83,43 +81,6 @@ struct slot_ctrl {
};
/*
- * Driver structure - each driver registers itself
- * with the mainline PC-CARD code. These drivers are
- * then available for linking to the devices.
- */
-struct pccard_devinfo;
-
-struct pccard_device {
- char *name; /* Driver name */
- int (*enable)(struct pccard_devinfo *); /* init/enable driver */
- void (*disable)(struct pccard_devinfo *); /* disable driver */
- int (*handler)(struct pccard_devinfo *); /* interrupt handler */
- int attr; /* driver attributes */
- unsigned int *imask; /* Interrupt mask ptr */
- driver_t *driver; /* Driver */
-
- struct pccard_device *next;
-};
-
-int pccard_module_handler __P((module_t mod, int what, void *arg));
-
-#define PCCARD_MODULE(name, enable, disable, handler, attr, imask) \
-static struct pccard_device name ## _info = { \
- #name, \
- enable, \
- disable, \
- handler, \
- attr, \
- &imask \
-}; \
-static moduledata_t name ## _mod = { \
- "pccard_" #name, \
- pccard_module_handler, \
- &name ## _info \
-}; \
-DECLARE_MODULE(name, name ## _mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
-
-/*
* Device structure for cards. Each card may have one
* or more pccard drivers attached to it; each driver is assumed
* to require at most one interrupt handler, one I/O block
@@ -127,14 +88,13 @@ DECLARE_MODULE(name, name ## _mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
* devices together.
*/
struct pccard_devinfo {
- struct pccard_device *drv;
- struct isa_device isahd; /* Device details */
+ u_char name[128];
+ struct isa_device isahd;
int running; /* Current state of driver */
u_char misc[128]; /* For any random info */
struct slot *slt; /* Back pointer to slot */
- struct resource *iorv; /* Kludge: keep track of io resource */
- struct resource *irqrv; /* Kludge: keep track of irq */
+ struct resource_list resources;
struct pccard_devinfo *next; /* List of drivers */
};
@@ -170,6 +130,15 @@ enum card_event { card_removed, card_inserted };
struct slot *pccard_alloc_slot(struct slot_ctrl *);
void pccard_event(struct slot *, enum card_event);
-void pccard_remove_controller(struct slot_ctrl *);
+
+static __inline__ const char *
+pccard_get_name(device_t dev)
+{
+ struct pccard_devinfo *devi = (struct pccard_devinfo *)
+ device_get_ivars(dev);
+ if (!devi)
+ return ("anonymous");
+ return (devi->name);
+}
#endif /* !_PCCARD_SLOT_H */
OpenPOWER on IntegriCloud