In accordance with Murphy's law, 4.0-RELEASE seems to have broken pccard
support for me. I have a WaveLAN wireless LAN card and use the optional
ISA-to-pccard bridge. On a two week old -current, it was working just
fine, displaying the following:
pcic: polling mode
pcic: polling mode
pcic0: <Vadem 469> at port 0x3e0 iomem 0xd0000 on isa0
pccard0: <PC Card bus -- kludge version> on pcic0
pccard1: <PC Card bus -- kludge version> on pcic0
My kernel config file says:
device pcic0 at isa? port 0x3e0 iomem 0xd0000
device wi
Notice that I don't specify an irq for pcic0, because I am really short of
them. So pcic is run in polling mode. I also tried specifying an irq with
exactly the same result.
With a 4.0-RELEASE kernel it does not work, pcic0 is simply not found and
absolutely no message is being displayed. Applying the below patch which
effectively backs out revision 1.89 of sys/pccard/pcic.c makes the card
work again. It is very unfortunate that it is too late to fix this :(
Blaz Zupan, [EMAIL PROTECTED], http://home.amis.net/blaz/
Medinet d.o.o., Linhartova 21, 2000 Maribor, Slovenia
Index: pcic.c
===================================================================
RCS file: /ftp/pub/FreeBSD/development/FreeBSD-CVS/src/sys/pccard/pcic.c,v
retrieving revision 1.89
retrieving revision 1.88
diff -u -r1.89 -r1.88
--- pcic.c 2000/03/10 05:43:28 1.89
+++ pcic.c 2000/02/21 06:56:29 1.88
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/sys/pccard/pcic.c,v 1.89 2000/03/10 05:43:28 imp Exp $
+ * $FreeBSD: src/sys/pccard/pcic.c,v 1.88 2000/02/21 06:56:29 imp Exp $
*/
#include <sys/param.h>
@@ -44,10 +44,6 @@
#include <pccard/slot.h>
#include <pccard/pcic.h>
-/* Get pnp IDs */
-#include <isa/isavar.h>
-#include <dev/pcic/i82365reg.h>
-
/*
* Prototypes for interrupt handler.
*/
@@ -80,20 +76,9 @@
u_char *regs; /* Pointer to regs in mem */
} pcic_slots[PCIC_MAX_SLOTS];
+static int pcic_irq;
static struct slot_ctrl cinfo;
-static struct isa_pnp_id pcic_ids[] = {
- {PCIC_PNP_82365, NULL}, /* PNP0E00 */
- {PCIC_PNP_CL_PD6720, NULL}, /* PNP0E01 */
- {PCIC_PNP_VLSI_82C146, NULL}, /* PNP0E02 */
- {PCIC_PNP_82365_CARDBUS, NULL}, /* PNP0E03 */
- {0}
-};
-
-static int validunits = 0;
-
-#define GET_UNIT(d) *(int *)device_get_softc(d)
-#define SET_UNIT(d,u) *(int *)device_get_softc(d) = (u)
/*
* Internal inline functions for accessing the PCIC.
@@ -279,16 +264,16 @@
struct slot *slt;
struct pcic_slot *sp;
unsigned char c;
+ void *ih;
char *name;
+ int i;
int error;
- struct resource *r;
+ struct resource *res = 0;
int rid;
static int maybe_vlsi = 0;
- /* Check isapnp ids */
- error = ISA_PNP_PROBE(device_get_parent(dev), dev, pcic_ids);
- if (error == ENXIO)
- return (ENXIO);
+ if (device_get_unit(dev) != 0)
+ return ENXIO;
/*
* Initialise controller information structure.
@@ -304,26 +289,22 @@
cinfo.maxmem = PCIC_MEM_WIN;
cinfo.maxio = PCIC_IO_WIN;
- if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0)
- bus_set_resource(dev, SYS_RES_IOPORT, 0, PCIC_INDEX0, 2);
- rid = 0;
- r = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
- if (!r) {
- if (bootverbose)
- device_printf(dev, "Cannot get I/O range\n");
- return ENOMEM;
- }
-
- sp = &pcic_slots[validunits * PCIC_CARD_SLOTS];
- for (slotnum = 0; slotnum < PCIC_CARD_SLOTS; slotnum++, sp++) {
+ sp = pcic_slots;
+ for (slotnum = 0; slotnum < PCIC_MAX_SLOTS; slotnum++, sp++) {
/*
* Initialise the PCIC slot table.
*/
sp->getb = getb1;
sp->putb = putb1;
- sp->index = rman_get_start(r);
- sp->data = sp->index + 1;
- sp->offset = slotnum * PCIC_SLOT_SIZE;
+ if (slotnum < 4) {
+ sp->index = PCIC_INDEX_0;
+ sp->data = PCIC_DATA_0;
+ sp->offset = slotnum * PCIC_SLOT_SIZE;
+ } else {
+ sp->index = PCIC_INDEX_1;
+ sp->data = PCIC_DATA_1;
+ sp->offset = (slotnum - 4) * PCIC_SLOT_SIZE;
+ }
/*
* XXX - Screwed up slot 1 on the VLSI chips. According to
* the Linux PCMCIA code from David Hinds, working chipsets
@@ -463,13 +444,47 @@
* Allocate a slot and initialise the data structures.
*/
validslots++;
- sp->slotnum = slotnum + validunits * PCIC_CARD_SLOTS;
+ sp->slotnum = slotnum;
slt = pccard_alloc_slot(&cinfo);
if (slt == 0)
continue;
slt->cdata = sp;
sp->slt = slt;
/*
+ * If we haven't allocated an interrupt for the controller,
+ * then attempt to get one.
+ */
+ if (pcic_irq == 0) {
+ /* See if the user has requested a specific IRQ */
+ if (!getenv_int("machdep.pccard.pcic_irq", &pcic_irq))
+ pcic_irq = -1;
+ rid = 0;
+ if (pcic_irq) {
+ if (pcic_irq < 0)
+ pcic_irq = 0;
+ res = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &rid, pcic_irq, ~0, 1, RF_ACTIVE);
+ }
+ if (res) {
+ error = bus_setup_intr(dev, res,
+ INTR_TYPE_MISC, pcicintr, NULL, &ih);
+ if (error) {
+ bus_release_resource(dev, SYS_RES_IRQ,
+ rid, res);
+ return error;
+ }
+ pcic_irq = rman_get_start(res);
+ printf("pcic: management irq %d\n", pcic_irq);
+ } else {
+ if (pcic_irq)
+ printf("pcic: polling mode, can't alloc %d\n",
+ pcic_irq);
+ else
+ printf("pcic: polling mode\n");
+ pcic_irq = 0;
+ }
+ }
+ /*
* Modem cards send the speaker audio (dialing noises)
* to the host's speaker. Cirrus Logic PCIC chips must
* enable this. There is also a Low Power Dynamic Mode bit
@@ -479,86 +494,33 @@
if (sp->controller == PCIC_PD672X) {
setb(sp, PCIC_MISC1, PCIC_SPKR_EN);
setb(sp, PCIC_MISC2, PCIC_LPDM_EN);
- }
- }
- bus_release_resource(dev, SYS_RES_IOPORT, rid, r);
- return(validslots ? 0 : ENXIO);
-}
-
-static int
-pcic_attach(device_t dev)
-{
- void *ih;
- int rid;
- struct resource *r;
- int irq;
- int error;
- struct pcic_slot *sp;
- int i;
-
- sp = &pcic_slots[GET_UNIT(dev) * PCIC_CARD_SLOTS];
- for (i = 0; i < PCIC_CARD_SLOTS; i++, sp++) {
- if (sp->slt)
- device_add_child(dev, NULL, -1);
- }
- SET_UNIT(dev, validunits);
- validunits++;
-
- rid = 0;
- r = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
- if (!r) {
- return ENXIO;
- }
-
- irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0);
- if (irq == 0) {
- /* See if the user has requested a specific IRQ */
- if (!getenv_int("machdep.pccard.pcic_irq", &irq))
- irq = 0;
- }
- rid = 0;
- r = 0;
- if (irq >= 0) {
- r = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq,
- ~0, 1, RF_ACTIVE);
- }
- if (r) {
- error = bus_setup_intr(dev, r, INTR_TYPE_MISC,
- pcicintr, (void *) GET_UNIT(dev), &ih);
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, rid, r);
- return error;
}
- irq = rman_get_start(r);
- device_printf(dev, "management irq %d\n", irq);
- } else {
- irq = 0;
- }
- if (irq == 0) {
- pcictimeout_ch = timeout(pcictimeout, (void *) GET_UNIT(dev),
- hz/2);
- device_printf(dev, "Polling mode\n");
- }
-
- sp = &pcic_slots[GET_UNIT(dev) * PCIC_CARD_SLOTS];
- for (i = 0; i < PCIC_CARD_SLOTS; i++, sp++) {
- /* Assign IRQ */
- sp->putb(sp, PCIC_STAT_INT, (irq << 4) | 0xF);
-
- /* Check for changes */
+ /*
+ * Check for a card in this slot.
+ */
setb(sp, PCIC_POWER, PCIC_PCPWRE| PCIC_DISRST);
- if (sp->slt == NULL)
- continue;
if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) != PCIC_CD) {
- sp->slt->laststate = sp->slt->state = empty;
+ slt->laststate = slt->state = empty;
} else {
- sp->slt->laststate = sp->slt->state = filled;
+ slt->laststate = slt->state = filled;
pccard_event(sp->slt, card_inserted);
}
- sp->slt->irq = irq;
+ /*
+ * Assign IRQ for slot changes
+ */
+ if (pcic_irq > 0)
+ sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
+ else if (pcic_irq == 0)
+ sp->putb(sp, PCIC_STAT_INT, 0xF);
+ }
+ if (validslots && pcic_irq <= 0)
+ pcictimeout_ch = timeout(pcictimeout, 0, hz/2);
+ if (validslots) {
+ for (i = 0; i < validslots; i++) {
+ device_add_child(dev, NULL, -1);
+ }
}
-
- return (bus_generic_attach(dev));
+ return(validslots ? 0 : ENXIO);
}
/*
@@ -749,8 +711,8 @@
static void
pcictimeout(void *chan)
{
- pcicintr(chan);
- pcictimeout_ch = timeout(pcictimeout, chan, hz/2);
+ pcicintr(0);
+ pcictimeout_ch = timeout(pcictimeout, 0, hz/2);
}
/*
@@ -764,11 +726,10 @@
{
int slot, s;
unsigned char chg;
- int unit = (int) arg;
- struct pcic_slot *sp = &pcic_slots[unit * PCIC_CARD_SLOTS];
+ struct pcic_slot *sp = pcic_slots;
s = splhigh();
- for (slot = 0; slot < PCIC_CARD_SLOTS; slot++, sp++) {
+ for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) {
if (sp->slt && (chg = sp->getb(sp, PCIC_STAT_CHG)) != 0) {
if (chg & PCIC_CDTCH) {
if ((sp->getb(sp, PCIC_STATUS) & PCIC_CD) ==
@@ -791,7 +752,8 @@
{
struct pcic_slot *sp = slt->cdata;
- sp->putb(sp, PCIC_STAT_INT, (slt->irq << 4) | 0xF);
+ if (pcic_irq > 0)
+ sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
if (sp->controller == PCIC_PD672X) {
setb(sp, PCIC_MISC1, PCIC_SPKR_EN);
setb(sp, PCIC_MISC2, PCIC_LPDM_EN);
@@ -919,7 +881,7 @@
static device_method_t pcic_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pcic_probe),
- DEVMETHOD(device_attach, pcic_attach),
+ DEVMETHOD(device_attach, bus_generic_attach),
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
@@ -942,7 +904,7 @@
static driver_t pcic_driver = {
"pcic",
pcic_methods,
- sizeof(int)
+ 1, /* no softc */
};
DRIVER_MODULE(pcic, isa, pcic_driver, pcic_devclass, 0, 0);
Index: i82365.h
===================================================================
RCS file: /ftp/pub/FreeBSD/development/FreeBSD-CVS/src/sys/pccard/i82365.h,v
retrieving revision 1.10
retrieving revision 1.9
diff -u -r1.10 -r1.9
--- i82365.h 2000/03/10 05:43:28 1.10
+++ i82365.h 1998/08/25 22:46:44 1.9
@@ -31,8 +31,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/pccard/i82365.h,v 1.10 2000/03/10 05:43:28 imp Exp $
*/
#define PCIC_I82365 0 /* Intel chip */
@@ -61,11 +59,10 @@
* identify the port number, and the lower 6 bits
* select one of the 64 possible data registers.
*/
-#define PCIC_INDEX_0 0x3e0 /* index reg, chips 0 and 1 */
+#define PCIC_INDEX_0 0x3E0 /* index reg, chips 0 and 1 */
#define PCIC_DATA_0 (PCIC_INDEX_0 + 1) /* data reg, chips 0 and 1 */
#define PCIC_INDEX_1 (PCIC_INDEX_0 + 2) /* index reg, chips 2 and 3 */
#define PCIC_DATA_1 (PCIC_INDEX_1 + 1) /* data reg, chips 2 and 3 */
-
/*
* Register index addresses.
*/
@@ -226,6 +223,4 @@
#define PCIC_IO_WIN 2
#define PCIC_MEM_WIN 5
-#define PCIC_CARD_SLOTS 4
-#define PCIC_MAX_CARDS 2
-#define PCIC_MAX_SLOTS (PCIC_MAX_CARDS * PCIC_CARD_SLOTS)
+#define PCIC_MAX_SLOTS 8
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message