Subject: help needed, any PCMCIA gurus out there?
To: None <>
From: Martin Husemann <>
List: tech-kern
Date: 10/12/1998 17:59:50
Sorry to ask stupid questions here; I need a little hint to get on the
right track.

I'm writting an pcmcia bus attachment for an ISDN driver, and this happens
to be the first time PCMCIA got in my way. As it seems to be completely 
undocumented in -current right now, I had a look at the few drivers in
sys/dev/pcmcia and copied from them what made sense to me.

Now I get this far:

pcic0 at isa0 port 0x3e0-0x3e1 iomem 0xd0000-0xd3fff: using irq 3
pcic0: controller 0 (Intel 82365SL Revision 1) has sockets A and B
pcmcia0 at pcic0 controller 0 socket 0
pcmcia0: CIS version PCMCIA 2.0 or 2.1
pcmcia0: CIS info: AVM, ISDN A, !\^B\^F, \^Z\^E\^A\^B
pcmcia0: Manufacturer code 0xffffffff, product 0xffffffff
pcmcia0: function 0: network adapter, ccr addr 400 mask 1
pcmcia0: function 0, config table entry 1: I/O card; irq mask 9cf8; iomask 10, iospace 140-147; rdybsy_active wp_active bvd_active io8 irqlevel
pcmcia0: function 0, config table entry 2: I/O card; irq mask 9cf8; iomask 10, iospace 300-307; rdybsy_active wp_active bvd_active io8 irqlevel
isic0 at pcmcia0 function 0 port 0x330-0x337
isic_attach_fritzpcmcia: tag = 0x0, handle = 0x330
Fritz!Card: read_reg(ISAC, 0x2a) [outb(332, 2a), inb(333)] -> 0x2a
Fritz!Card: read_reg(HSCX A, 0x2e) [outb(332, ae), inb(333)] -> 0xae
isic0: Error, HSCX version 14 unknown!
pcmcia0: card irq 5
pcmcia1 at pcic0 controller 0 socket 1

Please ignore my debugging output in there for a moment. The documentation
tells me to expect an 8 port (8bit) i/o range for the card. Most stuff is
done by writing an address to the port at offset 2 and reading data from
or writing it to the port at offset 3.

I don't understand anything about PCMCIA, and the above output doesn't
make much sense to me: the card seems to have two acceptable configurations,
both 8 ports long, either starting at 0x140 or 0x300. Somehow the kernel
decided to put the card at port 0x330. This coresponds to the bus_space_handle
that I get (and use) and the bus_space_tag (I'm using an i386, so tag = 0
means I/O port, and the handle is the base port number). So I'm trying
to access the card by the following code:

static u_int8_t
avma1_pcmcia_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
	bus_space_tag_t t = sc->sc_maps[0].t;
	bus_space_handle_t h = sc->sc_maps[0].h;
	u_int8_t res;
	static const char *what_name[] = { "ISAC", "HSCX A", "HSCX B" };

	bus_space_write_1(t, h, ADDR_REG_OFFSET, what_map[what]+offs);
	res = bus_space_read_1(t, h, DATA_REG_OFFSET);

	printf("Fritz!Card: read_reg(%s, 0x%02x) [outb(%x, %x), inb(%x)] -> 0x%02x\n",
		what_name[what], (u_int)offs, (u_int)h+ADDR_REG_OFFSET,
		what_map[what]+(u_int)offs, (u_int)h+DATA_REG_OFFSET, res);
	return res;

The what_map and what_name just map the "what" parameter to a chip offset
and chip name, the resulting address bytes in the above debug output 
are correct.

If I understand this correctly and my interpretation of what happens with
the bus_space_read/write macros is correct (as printed in the debug output)
*AND* it is correct for the kernel to map the card to that address - then
it should work. It doesn't.

Is the address mapping wrong - probably my fault in the attach routine?
What I'm doing there is basically (validation and error stuff left out):

	psc->sc_pf = pa->pf;
	cfe = pa->pf->cfe_head.sqh_first;
	pcmcia_function_init(pa->pf, cfe);

	if (pcmcia_io_alloc(pa->pf, 0, cfe->iospace[0].length,
	    cfe->iospace[0].length, &psc->sc_pcioh))
		printf(": can't allocate i/o space\n");

	if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ?
	    cfe->iospace[0].length, &psc->sc_pcioh, &psc->sc_io_window)) {
		printf(": can't map i/o space\n");

	sc->sc_maps[0].t = psc->sc_pcioh.iot;
	sc->sc_maps[0].h = psc->sc_pcioh.ioh;

Where sc and psc both point to my struct softc, sc to the generic version
and psc to the pcmcia specific sub-class.

Any hints greatly appreciated,