summaryrefslogtreecommitdiffstats
path: root/sys/pccard/pcic.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/pccard/pcic.c')
-rw-r--r--sys/pccard/pcic.c427
1 files changed, 94 insertions, 333 deletions
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 }
};
OpenPOWER on IntegriCloud