Next step towards pcic_pci: the ability to allocate mapped memory in attach.

o Introduce flags word to the softc.  This will be used to control various
  aspects of the driver.  Right now there are two bits defined, PCIC_IO_MAPPED
  and PCIC_MEM_MAPPED.  One for ISA cards that are I/O mapped, the other is
  for PCI cards that are memory mapped.  Only the ISA side is implemented
  with this commit.
o Introduce a pcic_dealloc which will cleanly dealloc resources used.  Right
  now it is only supported when called from probe/attach.
o Keep track of resources allocated in the pcic_softc.
o move pcictimeout_ch to the softc so we can support multiple devices
  in polling mode.
o In ISA probe, set PCIC_IO_MAPPED.
o Introduce and compute the slot mask.  This will be used later when
  we expand the number of slots on ISA from 2 to 4.  In such a case, we
  appear to have to use polling mode otherwise we get two different cards
  trying to drive the same interrupt line.  I don't have hardware to
  test this configuration, so I'll stop here.
This commit is contained in:
Warner Losh 2001-05-21 03:22:52 +00:00
parent da76f18bc6
commit e67316366d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=76917
3 changed files with 72 additions and 11 deletions

View File

@ -59,8 +59,6 @@ static timeout_t pcic_reset;
static void pcic_resume(struct slot *);
static void pcic_disable(struct slot *);
static timeout_t pcictimeout;
static struct callout_handle pcictimeout_ch
= CALLOUT_HANDLE_INITIALIZER(&pcictimeout_ch);
static int pcic_memory(struct slot *, int);
static int pcic_io(struct slot *, int);
@ -107,6 +105,29 @@ putw(struct pcic_slot *sp, int reg, unsigned short word)
sp->putb(sp, reg + 1, (word >> 8) & 0xff);
}
/*
* Free up resources allocated so far.
*/
static void
pcic_dealloc(device_t dev)
{
struct pcic_softc *sc;
sc = (struct pcic_softc *) device_get_softc(dev);
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);
untimeout(pcictimeout, sc, sc->timeout_ch);
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.
*/
@ -242,7 +263,6 @@ pcic_attach(device_t dev)
int error;
int irq;
int i;
void *ih;
device_t kid;
struct resource *r;
int rid;
@ -252,6 +272,7 @@ pcic_attach(device_t dev)
int stat;
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)
@ -268,14 +289,34 @@ pcic_attach(device_t dev)
device_printf(dev, "Can't get pccard info slot %d", i);
return (ENXIO);
}
sc->slotmask |= (1 << i);
slt->cdata = sp;
sp->slt = slt;
}
rid = 0;
r = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
if (!r)
return (ENXIO);
if (sc->flags & PCIC_IO_MAPPED) {
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;
}
if (sc->flags & PCIC_MEM_MAPPED) {
rid = 0;
r = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1,
RF_ACTIVE);
if (!r) {
pcic_dealloc(dev);
return (ENXIO);
}
sc->memrid = rid;
sc->memres = r;
}
irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0);
if (irq == 0) {
@ -297,11 +338,13 @@ pcic_attach(device_t dev)
r = 0;
irq = 0;
}
sc->irqrid = rid;
sc->irqres = r;
if (r) {
error = bus_setup_intr(dev, r, INTR_TYPE_MISC,
pcicintr, (void *) sc, &ih);
pcicintr, (void *) sc, &sc->ih);
if (error) {
bus_release_resource(dev, SYS_RES_IRQ, rid, r);
pcic_dealloc(dev);
return (error);
}
irq = rman_get_start(r);
@ -310,7 +353,7 @@ pcic_attach(device_t dev)
irq = 0;
}
if (irq == 0) {
pcictimeout_ch = timeout(pcictimeout, (void *) sc, hz/2);
sc->timeout_ch = timeout(pcictimeout, (void *) sc, hz/2);
device_printf(dev, "Polling mode\n");
}
@ -557,12 +600,14 @@ pcicintr(void *arg)
static void
pcictimeout(void *chan)
{
struct pcic_softc *sc = (struct pcic_softc *) chan;
if (pcicintr1(chan) != 0) {
printf("pcic%d: Static bug detected, ignoring hardware.\n",
((struct pcic_softc *)chan)->unit);
return;
}
pcictimeout_ch = timeout(pcictimeout, chan, hz/2);
sc->timeout_ch = timeout(pcictimeout, chan, hz/2);
}
/*

View File

@ -282,6 +282,10 @@ pcic_isa_probe(device_t dev)
static int
pcic_isa_attach(device_t dev)
{
struct pcic_softc *sc;
sc = device_get_softc(dev);
sc->flags |= PCIC_IO_MAPPED;
return (pcic_attach(dev));
}

View File

@ -41,7 +41,19 @@ struct pcic_slot {
struct pcic_softc
{
u_int32_t slotmask; /* Mask of valid slots */
u_int32_t flags; /* Interesting flags */
#define PCIC_IO_MAPPED 0x00000001
#define PCIC_MEM_MAPPED 0x00000002
int iorid; /* Rid of I/O region */
struct resource *iores; /* resource for I/O region */
int memrid;
struct resource *memres;
int irqrid;
struct resource *irqres;
void *ih;
int unit;
struct callout_handle timeout_ch;
struct pcic_slot slots[PCIC_MAX_SLOTS];
};