Subject: Questions about writing PCMCIA card driver
To: None <tech-kern@netbsd.org>
From: Johnny C. Lam <lamj@stat.cmu.edu>
List: tech-kern
Date: 11/18/2000 23:42:22
I've been trying to extend the mhzc(4) driver to attach to my Linksys
EtherFast 10/100 + 56K Modem PC Card (PCMLM56).  With the modified driver,
the modem currently probes as a com device and the Ethernet device as a
ne device.  I've included the relevant portions of the dmesg below from
my 1.5J i386 laptop.  My questions follow the dmesg.

com0 at pnpbios0 index 14 (PNP0501)
com0: io 3f8-3ff, irq 4
com0: ns16550a, working fifo
com1 at pnpbios0 index 15 (CHE0002, attached as PNP0511)
com1: io 2f8-2ff, irq 3, dma 3
com1: ns16550a, working fifo
...
cbb0 at pci0 dev 19 function 0: O2 Micro Inc product 0x6872 (rev. 0x05)
...
cbb0: interrupting at irq 9
cbb0: cacheline 0x0 lattimer 0x20
cbb0: bhlc 0x22000 lscp 0x20020200
cardslot0 at cbb0 slot 0 flags 0
cardbus0 at cardslot0: bus 2 device 0 cacheline 0x0, lattimer 0x20
pcmcia0 at cardslot0
...
biomask ef45 netmask ef45 ttymask ffc7
...
pcmcia0: CIS version PCMCIA 2.0 or 2.1
pcmcia0: CIS info: Linksys, EtherFast 10&100 + 56K PC Card (PCMLM56)
pcmcia0: Manufacturer code 0x143, product 0xc0ab
pcmcia0: function 0: multi-function, ccr addr ffe0 mask 67
pcmcia0: function 0, config table entry 3: I/O card; irq mask 9e38; iomask a, iospace 2f8-2ff 300-31f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 5: I/O card; irq mask 9e38; iomask a, iospace 3e8-3ef 300-31f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 7: I/O card; irq mask 9e38; iomask a, iospace 2e8-2ef 300-31f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 9: I/O card; irq mask 9e38; iomask a, iospace 2f8-2ff 320-33f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 11: I/O card; irq mask 9e38; iomask a, iospace 3e8-3ef 320-33f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 13: I/O card; irq mask 9e38; iomask a, iospace 2e8-2ef 320-33f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 15: I/O card; irq mask 9e38; iomask a, iospace 2f8-2ff 340-35f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 17: I/O card; irq mask 9e38; iomask a, iospace 3e8-3ef 340-35f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 19: I/O card; irq mask 9e38; iomask a, iospace 2e8-2ef 340-35f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 21: I/O card; irq mask 9e38; iomask a, iospace 2f8-2ff 220-23f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 23: I/O card; irq mask 9e38; iomask a, iospace 3e8-3ef 220-23f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 25: I/O card; irq mask 9e38; iomask a, iospace 2e8-2ef 220-23f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
pcmcia0: function 0, config table entry 27: I/O card; irq mask 9e38; iomask a, iospace 2f8-2ff 240-24f; rdybsy_active io8 io16 irqshare irqpulse irqlevel powerdown audio
mhzc0 at pcmcia0 function 0: Linksys EtherFast 10/100 + 56K Modem PC Card
mhzc0: using config table entry 3
com2 at mhzc0: serial device
com2: ns8250 or ns16450, no fifo
ne0 at mhzc0: Ethernet device
ne0: unable to map ASIC I/O space
...

The mhzc_attach() function allocates i/o spaces for the modem and Ethernet
devices.  But why is config table entry 3 being used?  The i/o space for
the modem 0x2f8-0x2ff is the same as for the com1 device.  Shouldn't the
allocation fail at this step and move on to the next table entry?  Plus,
since this is supposed to be a 56K modem, it should have probed as a
"ns16550a, working fifo", right?  Incidentally, I can't talk to the com2
device with cu(1), so despite attaching, it doesn't work.

The error in mapping the ASIC I/O space occurs in the following code
fragment in ne_mhzc_attach() (stolen from if_ne_pcmcia.c):

	/* some cards claim to be io16, but they're lying. */
	if (pcmcia_io_map(msc->sc_pf, PCMCIA_WIDTH_IO8,
	    NE2000_NIC_OFFSET, NE2000_NIC_NPORTS,
	    &msc->sc_ethernet_pcioh, &msc->sc_ethernet_io_window[0])) {
		printf(": unable to map I/O space\n");
		return;
	}
	if (pcmcia_io_map(msc->sc_pf, PCMCIA_WIDTH_IO16,
	    NE2000_ASIC_OFFSET, NE2000_ASIC_NPORTS,
	    &msc->sc_ethernet_pcioh, &msc->sc_ethernet_io_window[1])) {
		printf(": unable to map ASIC I/O space\n");
		goto map_asic_io_window_failed;
	}

I check earlier that length of the Ethernet's I/O space is NE2000_NPORTS,
and it is apparently allocated correctly in mhzc_attach().  The dmesg tells
me that I can map the first window, but not the second one.  Why does that
happen, given that:

	NE2000_NPORTS = 0x20
	NE2000_NIC_NPORTS = 0x10
	NE2000_ASIC_NPORTS = 0x10
	NE2000_NIC_OFFSET = 0
	NE2000_ASIC_OFFSET = 0x10

What would be reasons why both of the 0x10-byte windows don't fit in
the allocated 0x20-byte space?

Thanks for any help or understanding you can give to me on this.

     -- Johnny C. Lam <lamj@stat.cmu.edu>
        Department of Statistics, Carnegie Mellon University
        http://www.stat.cmu.edu/~lamj/