summaryrefslogtreecommitdiffstats
path: root/sys/pccard
diff options
context:
space:
mode:
authorasami <asami@FreeBSD.org>1996-06-14 11:02:28 +0000
committerasami <asami@FreeBSD.org>1996-06-14 11:02:28 +0000
commit36a1932601c730683d263ee933dd90cd6dae96bf (patch)
treed76ce0bf0a31500c82596831333ff034e969773b /sys/pccard
parent5fa995752f02a42fcb2b0ca54149fef141f98060 (diff)
downloadFreeBSD-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.h3
-rw-r--r--sys/pccard/pccard.c14
-rw-r--r--sys/pccard/pcic.c235
-rw-r--r--sys/pccard/slot.h4
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 */
OpenPOWER on IntegriCloud