It turns out that Intel's i82365sl-DF step has the same ID as the VLSI

82C146.  The Intel i82365SL-DF supports 3.3V cards.  The Step A/B/C
parts do not appear to support this.  This is hard to know for sure
since it was deduced from "compatible" parts' data sheets and the
article mentioned below.

Rework the VLSI detection to be a little nicer and not depend on
scanning cards twice.  This would allow bad VLSI cards to coexist with
a good intel card, for example.  We now detect i82365SL-DF cards where
before we'd detect a VLSI.  For the most part, this is good, but we
run a small chance of detecting a single slot 82C146 as a i82365SL-DF.
Since I can't find a datasheet for the 82c146, I don't know if this is
a problem or not.

This work is based on an excellent article, in Japanese, by NAKAGAWA,
Yoshihisa-san that appeared in FreeBSD Press Number 4.  He provided a
patch against PAO3 in his article.  Since the pcic.c code has changed
some since then, I've gone ahead and cleaned up his patch somewhat and
changed how the code detects the buggy '146 cards.

I also removed the comment asking if there were other cards that
matched the 82C146 since we found one and additional information isn't
necessary.
This commit is contained in:
imp 2001-05-19 04:53:20 +00:00
parent 8aa6c173b0
commit 26885aebf5
2 changed files with 62 additions and 31 deletions

View File

@ -35,7 +35,7 @@
* $FreeBSD$
*/
#define PCIC_I82365 0 /* Intel chip */
#define PCIC_I82365 0 /* Intel i82365SL-A/B or clone */
#define PCIC_IBM 1 /* IBM clone */
#define PCIC_VLSI 2 /* VLSI chip */
#define PCIC_PD672X 3 /* Cirrus logic 672x */
@ -46,9 +46,7 @@
#define PCIC_VG469 8 /* Vadem 469 */
#define PCIC_RF5C396 9 /* Ricoh RF5C396 */
#define PCIC_IBM_KING 10 /* IBM KING PCMCIA Controller */
#define PCIC_PC98 11 /* NEC PC98 PCMCIA Controller */
/* These last ones aren't in normal freebsd */
#define PCIC_TI1130 12 /* TI PCI1130 CardBus */
#define PCIC_I82365SL_DF 11 /* Intel i82365sl-DF step */
/*
* Address of the controllers. Each controller can manage
@ -103,6 +101,7 @@
/* For Identification and Revision (PCIC_ID_REV) */
#define PCIC_INTEL0 0x82 /* Intel 82365SL Rev. 0; Both Memory and I/O */
#define PCIC_INTEL1 0x83 /* Intel 82365SL Rev. 1; Both Memory and I/O */
#define PCIC_INTEL2 0x84 /* Intel 82365SL step D */
#define PCIC_VLSI82C146 0x84 /* VLSI 82C146 */
#define PCIC_IBM1 0x88 /* IBM PCIC clone; Both Memory and I/O */
#define PCIC_IBM2 0x89 /* IBM PCIC clone; Both Memory and I/O */

View File

@ -70,7 +70,7 @@ static struct slot_ctrl cinfo;
static char *bridges[] =
{
"Intel i82365",
"Intel i82365SL-A/B",
"IBM PCIC",
"VLSI 82C146",
"Cirrus logic 672x",
@ -81,6 +81,7 @@ static char *bridges[] =
"Vadem 469",
"Ricoh RF5C396",
"IBM KING PCMCIA Controller",
"Intel i82365SL-DF"
};
/*
@ -256,21 +257,17 @@ pcic_io(struct slot *slt, int win)
* Look for an Intel PCIC (or compatible).
* For each available slot, allocate a PC-CARD slot.
*/
/*
* VLSI 82C146 has incompatibilities about the I/O address of slot 1.
* Assume it's the only PCIC whose vendor ID is 0x84,
* contact Warner Losh <imp@freebsd.org> if correct.
*/
int
pcic_probe(device_t dev)
{
int slotnum, validslots = 0;
struct pcic_slot *sp;
struct pcic_slot *sp0;
struct pcic_slot *sp1;
struct pcic_slot spsave;
unsigned char c;
struct resource *r;
int rid;
static int maybe_vlsi = 0;
struct pcic_softc *sc;
/*
@ -309,19 +306,43 @@ pcic_probe(device_t dev)
sp->index = rman_get_start(r);
sp->data = sp->index + 1;
sp->offset = slotnum * PCIC_SLOT_SIZE;
/*
* XXX - Screwed up slot 1 on the VLSI chips. According to
* the Linux PCMCIA code from David Hinds, working chipsets
* return 0x84 from their (correct) ID ports, while the broken
* ones would need to be probed at the new offset we set after
* we assume it's broken.
*/
if (slotnum == 1 && maybe_vlsi &&
sp->getb(sp, PCIC_ID_REV) != PCIC_VLSI82C146) {
sp->index += 4;
sp->data += 4;
sp->offset = PCIC_SLOT_SIZE << 1;
sp->controller = -1;
}
/*
* Prescan for the broken VLSI chips.
*
* According to the Linux PCMCIA code from David Hinds,
* working chipsets return 0x84 from their (correct) ID ports,
* while the broken ones would need to be probed at the new
* offset we set after we assume it's broken.
*
* Note: because of this, we may incorrectly detect a single
* slot vlsi chip as a i82365sl step D. I cannot find a
* datasheet for the affected chip, so that's the best we can
* do for now.
*/
sp0 = &sc->slots[0];
sp1 = &sc->slots[1];
if (sp0->getb(sp0, PCIC_ID_REV) == PCIC_VLSI82C146 &&
sp1->getb(sp1, PCIC_ID_REV) != PCIC_VLSI82C146) {
spsave = *sp1;
sp1->index += 4;
sp1->data += 4;
sp1->offset = PCIC_SLOT_SIZE << 1;
if (sp1->getb(sp1, PCIC_ID_REV) != PCIC_VLSI82C146) {
*sp1 = spsave;
} else {
sp0->controller = PCIC_VLSI;
sp1->controller = PCIC_VLSI;
}
}
/*
* Look for normal chipsets here.
*/
sp = &sc->slots[0];
for (slotnum = 0; slotnum < PCIC_CARD_SLOTS; slotnum++, sp++) {
/*
* see if there's a PCMCIA controller here
* Intel PCMCIA controllers use 0x82 and 0x83
@ -372,11 +393,13 @@ pcic_probe(device_t dev)
break;
/*
* VLSI chips.
* Intel i82365D or maybe a vlsi 82c146
* we detected the vlsi case earlier, so if the controller
* isn't set, we know it is a i82365sl step D.
*/
case PCIC_VLSI82C146:
sp->controller = PCIC_VLSI;
maybe_vlsi = 1;
case PCIC_INTEL2:
if (sp->controller == -1)
sp->controller = PCIC_I82365SL_DF;
break;
case PCIC_IBM1:
case PCIC_IBM2:
@ -571,10 +594,20 @@ pcic_ioctl(struct slot *slt, int cmd, caddr_t data)
static int
pcic_power(struct slot *slt)
{
unsigned char c;
unsigned char reg = PCIC_DISRST|PCIC_PCPWRE;
struct pcic_slot *sp = slt->cdata;
switch(sp->controller) {
case PCIC_I82365SL_DF:
/*
* Check to see if the power on bit is clear. If so, we're
* using the wrong voltage and should try 3.3V instead.
*/
c = sp->getb(sp, PCIC_CDGC);
if ((c & PCIC_POW) == 0)
slt->pwr.vcc = 33;
/* FALL THROUGH */
case PCIC_PD672X:
case PCIC_PD6710:
case PCIC_VG365:
@ -582,9 +615,7 @@ pcic_power(struct slot *slt)
case PCIC_VG468:
case PCIC_VG469:
case PCIC_RF5C396:
case PCIC_VLSI:
case PCIC_IBM_KING:
case PCIC_I82365:
switch(slt->pwr.vpp) {
default:
return (EINVAL);
@ -641,7 +672,8 @@ pcic_power(struct slot *slt)
sp->putb(sp, PCIC_POWER, reg);
DELAY(100*1000);
}
/* Some chips are smarter than us it seems, so if we weren't
/*
* Some chips are smarter than us it seems, so if we weren't
* allowed to use 5V, try 3.3 instead
*/
if (!(sp->getb(sp, PCIC_STATUS) & PCIC_POW) && slt->pwr.vcc == 50) {