From 4765b33331fdc4fa3ce6aeb08484881a62957722 Mon Sep 17 00:00:00 2001 From: Nate Williams Date: Wed, 21 Feb 1996 23:20:21 +0000 Subject: [PATCH] Updated PC-CARD support to contain most of the code from the latest Japanese BSD-Nomad release. Reviewed by: phk Submitted by: hosokawa@mt.cs.keio.ac.jp and the rest of the Nomads --- sys/pccard/card.h | 10 ++++ sys/pccard/cardinfo.h | 10 ++++ sys/pccard/i82365.h | 6 ++- sys/pccard/pccard.c | 38 +++++++++++--- sys/pccard/pcic.c | 115 +++++++++++++++++++++++++++++++++++++----- 5 files changed, 160 insertions(+), 19 deletions(-) diff --git a/sys/pccard/card.h b/sys/pccard/card.h index 575253f346bb..424098b65c12 100644 --- a/sys/pccard/card.h +++ b/sys/pccard/card.h @@ -121,6 +121,16 @@ struct power { int vpp; }; +/* + * Beep parameters + */ +#define PCCARD_BEEP_PITCH0 1600 /* inserted/removed */ +#define PCCARD_BEEP_DURATION0 20 +#define PCCARD_BEEP_PITCH1 1200 /* successed */ +#define PCCARD_BEEP_DURATION1 40 +#define PCCARD_BEEP_PITCH2 3200 /* failed */ +#define PCCARD_BEEP_DURATION2 40 + /* * Other system limits */ diff --git a/sys/pccard/cardinfo.h b/sys/pccard/cardinfo.h index 575253f346bb..424098b65c12 100644 --- a/sys/pccard/cardinfo.h +++ b/sys/pccard/cardinfo.h @@ -121,6 +121,16 @@ struct power { int vpp; }; +/* + * Beep parameters + */ +#define PCCARD_BEEP_PITCH0 1600 /* inserted/removed */ +#define PCCARD_BEEP_DURATION0 20 +#define PCCARD_BEEP_PITCH1 1200 /* successed */ +#define PCCARD_BEEP_DURATION1 40 +#define PCCARD_BEEP_PITCH2 3200 /* failed */ +#define PCCARD_BEEP_DURATION2 40 + /* * Other system limits */ diff --git a/sys/pccard/i82365.h b/sys/pccard/i82365.h index a6cec01c4d89..c50c0f94440f 100644 --- a/sys/pccard/i82365.h +++ b/sys/pccard/i82365.h @@ -37,10 +37,12 @@ #define PCIC_IBM 1 /* IBM clone */ #define PCIC_VLSI 2 /* VLSI chip */ #define PCIC_PD672X 3 /* Cirrus logic 627x */ -#define PCIC_PD6710 4 +#define PCIC_PD6710 4 /* Cirrus logic 6710 */ #define PCIC_CL6729 5 #define PCIC_VG468 6 #define PCIC_VG469 7 +#define PCIC_RF5C396 8 /* Ricoh RF5C396 */ +#define PCIC_IBM_KING 9 /* IBM KING PCMCIA Controller */ /* * Address of the controllers. Each controller can manage * two PCMCIA slots. Up to 8 slots are supported in total. @@ -89,6 +91,7 @@ #define PCIC_INTEL1 0x83 /* Intel 82365SL Rev. 1; Both Memory and I/O */ #define PCIC_IBM1 0x88 /* IBM PCIC clone; Both Memory and I/O */ #define PCIC_IBM2 0x89 /* IBM PCIC clone; Both Memory and I/O */ +#define PCIC_IBM3 0x8a /* IBM KING PCIC clone; Both Memory and I/O */ /* For Interface Status register (PCIC_STATUS) */ #define PCIC_VPPV 0x80 /* Vpp_valid */ @@ -106,6 +109,7 @@ #define PCIC_VCC 0x18 /* Vcc control bits */ #define PCIC_VCC_5V 0x10 /* 5 volts */ #define PCIC_VCC_3V 0x18 /* 3 volts */ +#define PCIC_VCC_5V_KING 0x14 /* 5 volts for KING PCIC */ #define PCIC_VPP 0x0C /* Vpp control bits */ #define PCIC_VPP_5V 0x01 /* 5 volts */ #define PCIC_VPP_12V 0x02 /* 12 volts */ diff --git a/sys/pccard/pccard.c b/sys/pccard/pccard.c index 0c0c45295767..fd99cdfed755 100644 --- a/sys/pccard/pccard.c +++ b/sys/pccard/pccard.c @@ -55,7 +55,7 @@ #include #include - +#include extern struct kern_devconf kdc_cpu0; @@ -144,6 +144,7 @@ pccard_add_driver(struct pccard_drv *dp) printf("Driver %s already loaded\n", dp->name); return; } + printf("pccard driver %s added\n", dp->name); dp->next = drivers; drivers = dp; } @@ -357,12 +358,17 @@ pccard_alloc_intr(int imask, inthand2_t *hand, int unit, int *maskp) int irq; unsigned int mask; +#if 0 + /* + * this overrides IRQ masks specified by pccardd, + * so I removed this code. (hosokawa@mt.cs.keio.ac.jp) + */ imask = 1<< 3; imask |= 1<< 5; imask |= 1<< 9; imask |= 1<<11; imask |= 1<<15; - +#endif for (irq = 1; irq < 16; irq++) { mask = 1ul << irq; @@ -541,6 +547,17 @@ inserted(void *arg) sp->ctrl->reset(sp); } +/* + * Insert/Remove beep + */ + +static int beepok = 1; + +static void enable_beep(void *dummy) +{ + beepok = 1; +} + /* * Card event callback. Called at splhigh to prevent * device interrupts from interceding. @@ -566,12 +583,18 @@ int s; sp->state = empty; splx(s); printf("Card removed, slot %d\n", sp->slot); + sysbeep(PCCARD_BEEP_PITCH0, PCCARD_BEEP_DURATION0); + beepok = 0; + timeout(enable_beep, (void *)NULL, hz/5); selwakeup(&sp->selp); } break; case card_inserted: sp->insert_seq = 1; timeout(inserted, (void *)sp, hz/4); + sysbeep(PCCARD_BEEP_PITCH0, PCCARD_BEEP_DURATION0); + beepok = 0; + timeout(enable_beep, (void *)NULL, hz/5); break; } } @@ -733,7 +756,7 @@ crdwrite(dev_t dev, struct uio *uio, int ioflag) static int crdioctl(dev_t dev, int cmd, caddr_t data, int fflag, struct proc *p) { - int s; + int s, err; struct slot *sp = pccard_slots[minor(dev)]; struct mem_desc *mp; struct io_desc *ip; @@ -853,7 +876,12 @@ crdioctl(dev_t dev, int cmd, caddr_t data, int fflag, struct proc *p) case PIOCSDRV: if (suser(p->p_ucred, &p->p_acflag)) return(EPERM); - return(allocate_driver(sp, (struct drv_desc *)data)); + err = allocate_driver(sp, (struct drv_desc *)data); + if (!err) + sysbeep(PCCARD_BEEP_PITCH1, PCCARD_BEEP_DURATION1); + else + sysbeep(PCCARD_BEEP_PITCH2, PCCARD_BEEP_DURATION2); + return err; } return(0); } @@ -929,5 +957,3 @@ crd_drvinit(void *unused) } SYSINIT(crddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,crd_drvinit,NULL) - - diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c index 5fe35ad1d07f..30b97d802230 100644 --- a/sys/pccard/pcic.c +++ b/sys/pccard/pcic.c @@ -59,6 +59,8 @@ #include #include +#include + extern struct kern_devconf kdc_pccard0; struct kern_devconf kdc_pcic[PCIC_MAX_SLOTS] = { @@ -363,40 +365,56 @@ pcic_io(struct slot *slotp, int win) struct pcic_slot *sp = slotp->cdata; struct io_desc *ip = &slotp->io[win]; - if (win) { + switch (win) { + case 0: mask = PCIC_IO0_EN; reg = PCIC_IO0; - } else { + break; + case 1: mask = PCIC_IO1_EN; reg = PCIC_IO1; + break; + default: + panic("Illegal PCIC I/O window request!"); } if (ip->flags & IODF_ACTIVE) { - unsigned char x = 0; + 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; if (ip->flags & IODF_ZEROWS) - x = PCIC_IO_0WS; + x |= PCIC_IO_0WS; if (ip->flags & IODF_WS) x |= PCIC_IO_WS; if (ip->flags & IODF_CS16) x |= PCIC_IO_CS16; - else if (ip->flags & IODF_16BIT) + if (ip->flags & IODF_16BIT) x |= PCIC_IO_16BIT; /* * Extract the current flags and merge with new flags. * Flags for window 0 in lower nybble, and in upper nybble * for window 1. */ - if (win) - putb(sp, PCIC_IOCTL, (x << 4) | - (getb(sp, PCIC_IOCTL) & 0xF)); - else - putb(sp, PCIC_IOCTL, x | (getb(sp, PCIC_IOCTL) & 0xF0)); + ioctlv = getb(sp, PCIC_IOCTL); + DELAY(100); + switch (win) { + case 0: + putb(sp, PCIC_IOCTL, x | (ioctlv & 0xf0)); + break; + case 1: + putb(sp, PCIC_IOCTL, (x << 4) | (ioctlv & 0xf)); + break; + } + DELAY(100); setb (sp, PCIC_ADDRWINE, mask); DELAY(100); } else { clrb (sp, PCIC_ADDRWINE, mask); + DELAY(100); putw (sp, reg, 0); putw (sp, reg + 2, 0); } @@ -408,6 +426,14 @@ pcic_io(struct slot *slotp, int win) * For each available slot, allocate a PC-CARD slot. */ +/* + * VLSI 82C146 has incompatibilities about the I/O address + * of slot 1. If it's the only PCIC whose vendor ID is 0x84, + * I want to remove this #define and corresponding #ifdef's. + * HOSOKAWA, Tatsumi + */ +#define VLSI_SLOT1 1 + int pcic_probe () { @@ -415,6 +441,9 @@ pcic_probe () struct slot *slotp; struct pcic_slot *sp; unsigned char c; +#ifdef VLSI_SLOT1 + static int vs = 0; +#endif /* VLSI_SLOT1 */ /* * Initialise controller information structure. @@ -439,9 +468,21 @@ pcic_probe () * Initialise the PCIC slot table. */ if (slot < 4) { +#ifdef VLSI_SLOT1 + if (slot == 1 && vs) { + sp->index = PCIC_INDEX_0 + 4; + sp->data = PCIC_DATA_0 + 4; + sp->offset = PCIC_SLOT_SIZE << 1; + } else { + sp->index = PCIC_INDEX_0; + sp->data = PCIC_DATA_0; + sp->offset = slot * PCIC_SLOT_SIZE; + } +#else /* VLSI_SLOT1 */ sp->index = PCIC_INDEX_0; sp->data = PCIC_DATA_0; sp->offset = slot * PCIC_SLOT_SIZE; +#endif /* VLSI_SLOT1 */ } else { sp->index = PCIC_INDEX_1; sp->data = PCIC_DATA_1; @@ -474,18 +515,34 @@ pcic_probe () PCIC_VG469 : PCIC_VG468 ; clrb(sp, 0x3A, 0x40); } + + /* + * Check for RICOH RF5C396 PCMCIA Controller + */ + c = getb (sp, 0x3a); + if (c == 0xb2) { + sp->controller = PCIC_RF5C396; + } + break; /* * VLSI chips. */ case 0x84: sp->controller = PCIC_VLSI; +#ifdef VLSI_SLOT1 + vs = 1; +#endif /* VLSI_SLOT1 */ break; case 0x88: case 0x89: sp->controller = PCIC_IBM; sp->revision = c & 1; break; + case 0x8a: + sp->controller = PCIC_IBM_KING; + sp->revision = c & 1; + break; default: continue; } @@ -511,6 +568,9 @@ pcic_probe () case PCIC_IBM: cinfo.name = "IBM PCIC"; break; + case PCIC_IBM_KING: + cinfo.name = "IBM KING PCMCIA Controller"; + break; case PCIC_PD672X: cinfo.name = "Cirrus Logic PD672X"; break; @@ -523,15 +583,23 @@ pcic_probe () case PCIC_VG469: cinfo.name = "Vadem 469"; break; + case PCIC_RF5C396: + cinfo.name = "Ricoh RF5C396"; + break; + case PCIC_VLSI: + cinfo.name = "VLSI 82C146"; + break; default: cinfo.name = "Unknown!"; break; } +#ifndef PCIC_NOCLRREGS /* * clear out the registers. */ for (i = 2; i < 0x40; i++) putb(sp, i, 0); +#endif /* PCIC_NOCLRREGS */ /* * OK it seems we have a PCIC or lookalike. * Allocate a slot and initialise the data structures. @@ -621,7 +689,11 @@ pcic_power(struct slot *slotp) switch(sp->controller) { case PCIC_PD672X: case PCIC_PD6710: + case PCIC_VG468: case PCIC_VG469: + case PCIC_RF5C396: + case PCIC_VLSI: + case PCIC_IBM_KING: switch(slotp->pwr.vpp) { default: return(EINVAL); @@ -641,20 +713,31 @@ pcic_power(struct slot *slotp) case 0: break; case 33: + if (sp->controller == PCIC_IBM_KING) { + reg |= PCIC_VCC_5V_KING; + break; + } reg |= PCIC_VCC_5V; - if (sp->controller == PCIC_VG469) + if ((sp->controller == PCIC_VG468)|| + (sp->controller == PCIC_VG469)) setb(sp, 0x2f, 0x03) ; else setb(sp, 0x16, 0x02); break; case 50: + if (sp->controller == PCIC_IBM_KING) { + reg |= PCIC_VCC_5V_KING; + break; + } reg |= PCIC_VCC_5V; - if (sp->controller == PCIC_VG469) + if ((sp->controller == PCIC_VG468)|| + (sp->controller == PCIC_VG469)) clrb(sp, 0x2f, 0x03) ; else clrb(sp, 0x16, 0x02); break; } + break; } putb (sp, PCIC_POWER, reg); DELAY(300*1000); @@ -695,25 +778,33 @@ pcic_reset(void *chan) case 0: /* Something funny happended on the way to the pub... */ return; case 1: /* Assert reset */ +#if 0 printf("R"); +#endif clrb (sp, PCIC_INT_GEN, PCIC_CARDRESET); slotp->insert_seq = 2; timeout(pcic_reset, (void*) slotp, hz/4); return; case 2: /* Deassert it again */ +#if 0 printf("r"); +#endif setb (sp, PCIC_INT_GEN, PCIC_CARDRESET|PCIC_IOCARD); slotp->insert_seq = 3; timeout(pcic_reset, (void*) slotp, hz/4); return; case 3: /* Wait if card needs more time */ if (!getb(sp, PCIC_STATUS) & PCIC_READY) { +#if 0 printf("_"); +#endif timeout(pcic_reset, (void*) slotp, hz/10); return; } } +#if 0 printf(".\n"); +#endif slotp->insert_seq = 0; if (sp->controller == PCIC_PD672X || sp->controller == PCIC_PD6710) { putb(sp, PCIC_TIME_SETUP0, 0x1);