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:
parent
9b3a4c562d
commit
4765b33331
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=14172
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user