IRQ routing on PCMCIA

Michael Buesch mb at bu3sch.de
Mon Mar 17 07:24:43 EDT 2008


Hi,

I'm developing a PCMCIA layer for the b43 driver.
But I'm having major problems with IRQs not working.
The IRQs don't seem to get routed from the core of the card
to the host computer. I'm not sure where the actual bug is, so
I need some advise from someone who has a clue about the PCMCIA
subsystem. :)

I wrote a firmware for the device that triggers the device IRQ line.
On a PCI device that works fine and the IRQ reaches the kernel. On
a PCMCIA device, however, nothing happens.
In my opinion there are two points of failure and I'd like to rule
one out. One being the routing on the on-chip BUS and another being
the routing in the PCMCIA controller to the host.

So what's needed to set up an IRQ on a PCMCIA device?
Here's my probe code:

static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
{
	struct ssb_bus *ssb;
	win_req_t win;
	memreq_t mem;
	tuple_t tuple;
	cisparse_t parse;
	int err = -ENOMEM;
	int res = 0;
	unsigned char buf[64];

	ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
	if (!ssb)
		goto out_error;

	err = -ENODEV;
	tuple.DesiredTuple = CISTPL_CONFIG;
	tuple.Attributes = 0;
	tuple.TupleData = buf;
	tuple.TupleDataMax = sizeof(buf);
	tuple.TupleOffset = 0;

	res = pcmcia_get_first_tuple(dev, &tuple);
	if (res != CS_SUCCESS)
		goto err_kfree_ssb;
	res = pcmcia_get_tuple_data(dev, &tuple);
	if (res != CS_SUCCESS)
		goto err_kfree_ssb;
	res = pcmcia_parse_tuple(dev, &tuple, &parse);
	if (res != CS_SUCCESS)
		goto err_kfree_ssb;

	dev->conf.ConfigBase = parse.config.base;
	dev->conf.Present = parse.config.rmask[0];

	dev->io.BasePort2 = 0;
	dev->io.NumPorts2 = 0;
	dev->io.Attributes2 = 0;

	win.Attributes = WIN_ADDR_SPACE_MEM | WIN_MEMORY_TYPE_CM |
			 WIN_ENABLE | WIN_DATA_WIDTH_16 |
			 WIN_USE_WAIT;
	win.Base = 0;
	win.Size = SSB_CORE_SIZE;
	win.AccessSpeed = 250;
	res = pcmcia_request_window(&dev, &win, &dev->win);
	if (res != CS_SUCCESS)
		goto err_kfree_ssb;

	mem.CardOffset = 0;
	mem.Page = 0;
	res = pcmcia_map_mem_page(dev->win, &mem);
	if (res != CS_SUCCESS)
		goto err_disable;

	dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED;
	dev->irq.IRQInfo1 = IRQ_LEVEL_ID | IRQ_SHARE_ID;
	dev->irq.Handler = NULL; /* The handler is registered later. */
	dev->irq.Instance = NULL;
	res = pcmcia_request_irq(dev, &dev->irq);
	if (res != CS_SUCCESS)
		goto err_disable;

	res = pcmcia_request_configuration(dev, &dev->conf);
	if (res != CS_SUCCESS)
		goto err_disable;

	err = ssb_bus_pcmciabus_register(ssb, dev, win.Base);
	if (err)
		goto err_disable;
	dev->priv = ssb;

	return 0;

err_disable:
	pcmcia_disable_device(dev);
err_kfree_ssb:
	kfree(ssb);
out_error:
	printk(KERN_ERR "b43-pcmcia: Initialization failed (%d, %d)\n",
	       res, err);
	return err;
}


In the code I later call request_irq() with pcmcia_device->irq.AssignedIRQ as
IRQ ID cookie.

Does someone have an idea what could go wrong?
Or, can somebody tell me if I do everything PCMCIA-IRQ related right, so
I can rule PCMCIA-IRQ breakage out, so it must be a routing problem on
the on-chip bus?

-- 
Greetings Michael.



More information about the linux-pcmcia mailing list