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
This commit is contained in:
Nate Williams 1996-02-21 23:20:21 +00:00
parent 9b3a4c562d
commit 4765b33331
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=14172
5 changed files with 160 additions and 19 deletions

View File

@ -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
*/

View File

@ -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
*/

View File

@ -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 */

View File

@ -55,7 +55,7 @@
#include <pccard/driver.h>
#include <pccard/slot.h>
#include <i386/include/laptops.h>
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)

View File

@ -59,6 +59,8 @@
#include <pccard/driver.h>
#include <pccard/slot.h>
#include <i386/include/laptops.h>
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 <hosokawa@mt.cs.keio.ac.jp>
*/
#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);