diff options
author | asami <asami@FreeBSD.org> | 1996-06-14 11:02:28 +0000 |
---|---|---|
committer | asami <asami@FreeBSD.org> | 1996-06-14 11:02:28 +0000 |
commit | 36a1932601c730683d263ee933dd90cd6dae96bf (patch) | |
tree | d76ce0bf0a31500c82596831333ff034e969773b /sys/pccard | |
parent | 5fa995752f02a42fcb2b0ca54149fef141f98060 (diff) | |
download | FreeBSD-src-36a1932601c730683d263ee933dd90cd6dae96bf.zip FreeBSD-src-36a1932601c730683d263ee933dd90cd6dae96bf.tar.gz |
The Great PC98 Merge.
All new code is "#ifdef PC98"ed so this should make no difference to
PC/AT (and its clones) users.
Ok'd by: core
Submitted by: FreeBSD(98) development team
Diffstat (limited to 'sys/pccard')
-rw-r--r-- | sys/pccard/i82365.h | 3 | ||||
-rw-r--r-- | sys/pccard/pccard.c | 14 | ||||
-rw-r--r-- | sys/pccard/pcic.c | 235 | ||||
-rw-r--r-- | sys/pccard/slot.h | 4 |
4 files changed, 256 insertions, 0 deletions
diff --git a/sys/pccard/i82365.h b/sys/pccard/i82365.h index c50c0f9..f6140ef 100644 --- a/sys/pccard/i82365.h +++ b/sys/pccard/i82365.h @@ -43,6 +43,9 @@ #define PCIC_VG469 7 #define PCIC_RF5C396 8 /* Ricoh RF5C396 */ #define PCIC_IBM_KING 9 /* IBM KING PCMCIA Controller */ +#ifdef PC98 +#define PCIC_PC98 10 +#endif /* * Address of the controllers. Each controller can manage * two PCMCIA slots. Up to 8 slots are supported in total. diff --git a/sys/pccard/pccard.c b/sys/pccard/pccard.c index 3f223a8..ac6466d 100644 --- a/sys/pccard/pccard.c +++ b/sys/pccard/pccard.c @@ -47,9 +47,15 @@ #include <sys/devfsext.h> #endif /*DEVFS*/ +#ifdef PC98 +#include <pc98/pc98/pc98.h> +#include <pc98/pc98/pc98_device.h> +#include <pc98/pc98/icu.h> +#else #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> #include <i386/isa/icu.h> +#endif /* PC98 */ #include "apm.h" #if NAPM > 0 @@ -480,6 +486,8 @@ allocate_driver(struct slot *sp, struct drv_desc *drvp) struct pccard_drv *dp; int err, irq = 0, s; +/* BUCHI */ + dp = find_driver(drvp->name); if (dp == 0) return(ENXIO); @@ -499,6 +507,12 @@ allocate_driver(struct slot *sp, struct drv_desc *drvp) * If an interrupt mask has been given, then check it * against the slot interrupt (if one has been allocated). */ +/* BUCHI */ +#if 0 +printf("drvp->irqmask=0x%x, dp->imask=0x%x, sp->irq=0x%x, sp->ctrl->irqs=0x%x\n", drvp->irqmask, dp->imask, sp->irq, sp->ctrl->irqs); +printf("name=%s, unit=%d, mem=0x%x, memsz=%d, iobase=0x%x, irqmask=0x%x\n", drvp->name, drvp->unit, drvp->mem, drvp->memsize, drvp->iobase, drvp->irqmask); +#endif + if (drvp->irqmask && dp->imask) { if ((sp->ctrl->irqs & drvp->irqmask)==0) return(EINVAL); diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c index 456b251..a5ffb12 100644 --- a/sys/pccard/pcic.c +++ b/sys/pccard/pcic.c @@ -28,6 +28,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * pcic98 : PC9801 original PCMCIA controller code for NS/A,Ne,NX/C,NR/L. + * by Noriyuki Hosobuchi <yj8n-hsbc@asahi-net.or.jp> + */ + #ifdef LKM #define NPCIC 1 #else @@ -51,11 +56,20 @@ #include <machine/clock.h> #include <machine/laptops.h> +#ifdef PC98 +#include <pc98/pc98/pc98.h> +#include <pc98/pc98/pc98_device.h> +#include <pc98/pc98/icu.h> +#else #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> #include <i386/isa/icu.h> +#endif #include <pccard/i82365.h> +#ifdef PC98 +#include <pccard/pcic98reg.h> +#endif #include <pccard/card.h> #include <pccard/driver.h> #include <pccard/slot.h> @@ -295,6 +309,49 @@ pcic_memory(struct slot *slotp, int win) struct mem_desc *mp = &slotp->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 = (unsigned long)mp->start >> 12; @@ -365,7 +422,46 @@ pcic_io(struct slot *slotp, int win) int mask, reg; struct pcic_slot *sp = slotp->cdata; struct io_desc *ip = &slotp->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; @@ -649,8 +745,52 @@ pcic_probe () if (pcic_irq > 0) putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF); } +#ifdef PC98 + if (validslots == 0){ + sp = pcic_slots; slot = 0; + if (inb(PCIC98_REG0) != 0xff){ + sp->controller = PCIC_PC98; + sp->revision = 0; + cinfo.name = "PC98 Original"; + cinfo.maxmem = 1; + cinfo.maxio = 1; +/* cinfo.irqs = PCIC_INT_MASK_ALLOWED;*/ + cinfo.irqs = 0x1468; + validslots++; + sp->slot = slot; + if (kdc_pcic[slot].kdc_state == DC_UNKNOWN) { + if (slot != 0) + kdc_pcic[slot] = kdc_pcic[0]; + kdc_pcic[slot].kdc_unit = slot; + kdc_pcic[slot].kdc_state = DC_UNCONFIGURED; + kdc_pcic[slot].kdc_description = cinfo.name; + dev_attach(kdc_pcic+slot); + } + + slotp = pccard_alloc_slot(&cinfo); + if (slotp == 0){ + printf("pcic98: slotp == NULL\n"); + goto pcic98_probe_end; + } + kdc_pcic[slot].kdc_state = DC_IDLE; + slotp->cdata = sp; + sp->slotp = slotp; + + /* Check for a card in this slot */ + if (inb(PCIC98_REG1) & PCIC98_CARDEXIST){ + /* PCMCIA card exist */ + slotp->laststate = slotp->state = filled; + pccard_event(sp->slotp, card_inserted); + } else { + slotp->laststate = slotp->state = empty; + } + } + pcic98_probe_end: + } +#endif /* PC98 */ if (validslots) timeout(pcictimeout,0,hz/2); +/* BUCHI */ return(validslots); } @@ -690,6 +830,35 @@ pcic_power(struct slot *slotp) struct pcic_slot *sp = slotp->cdata; switch(sp->controller) { +#ifdef PC98 + case PCIC_PC98: + reg = inb(PCIC98_REG6) & (~PCIC98_VPP12V); + switch(slotp->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(slotp->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_VG468: @@ -760,7 +929,35 @@ static void pcic_mapirq (struct slot *slotp, int irq) { struct pcic_slot *sp = slotp->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 @@ -777,6 +974,19 @@ pcic_reset(void *chan) struct slot *slotp = chan; struct pcic_slot *sp = slotp->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(&slotp->selp); + return; + } +#endif switch (slotp->insert_seq) { case 0: /* Something funny happended on the way to the pub... */ return; @@ -816,6 +1026,11 @@ pcic_disable(struct slot *slotp) { struct pcic_slot *sp = slotp->cdata; +#ifdef PC98 + if (sp->controller == PCIC_PC98){ + return; + } +#endif putb(sp, PCIC_INT_GEN, 0); putb(sp, PCIC_POWER, 0); } @@ -845,6 +1060,26 @@ pcicintr(int unit) unsigned char chg; struct pcic_slot *sp = pcic_slots; +#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->slotp->laststate != filled){ + kdc_pcic[slot].kdc_state = DC_BUSY;; + pccard_event(sp->slotp, card_inserted); + } + } else { + if (sp->slotp->laststate != empty){ + kdc_pcic[slot].kdc_state = DC_IDLE;; + pccard_event(sp->slotp, card_removed); + } + } + splx(s); + return; + } +#endif /* PC98 */ s = splhigh(); for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) if (sp->slotp && (chg = getb(sp, PCIC_STAT_CHG)) != 0) diff --git a/sys/pccard/slot.h b/sys/pccard/slot.h index fb9b23e..af19e5e 100644 --- a/sys/pccard/slot.h +++ b/sys/pccard/slot.h @@ -93,7 +93,11 @@ struct pccard_drv { */ struct pccard_dev { struct pccard_dev *next; /* List of drivers */ +#ifdef PC98 + struct pc98_device isahd; /* Device details */ +#else struct isa_device isahd; /* Device details */ +#endif struct pccard_drv *drv; void *arg; /* Device argument */ struct slot *sp; /* Back pointer to slot */ |