From: Ian Abbott Date: Tue, 22 Jun 2010 16:12:24 +0000 (+0000) Subject: PCMCIA support broke with the 2.6.33 kernel, so add support back in. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=0162db242bc4eb88c734f331bfb69658c8175bb9;p=comedi.git PCMCIA support broke with the 2.6.33 kernel, so add support back in. I don't know if it works, but at least it should compile! The driver source code changes are very inelegant. Note that the IRQ attributes have been changed from IRQ_TYPE_EXCLUSIVE to IRQ_TYPE_DYNAMIC_SHARING. --- diff --git a/comedi/drivers/cb_das16_cs.c b/comedi/drivers/cb_das16_cs.c index d1f312e3..4229d476 100644 --- a/comedi/drivers/cb_das16_cs.c +++ b/comedi/drivers/cb_das16_cs.c @@ -127,6 +127,7 @@ static int das16cs_timer_insn_read(comedi_device * dev, comedi_subdevice * s, static int das16cs_timer_insn_config(comedi_device * dev, comedi_subdevice * s, comedi_insn * insn, lsampl_t * data); +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE static int get_prodid(comedi_device * dev, struct pcmcia_device *link) { tuple_t tuple; @@ -145,6 +146,7 @@ static int get_prodid(comedi_device * dev, struct pcmcia_device *link) return prodid; } +#endif static const das16cs_board *das16cs_probe(comedi_device * dev, struct pcmcia_device *link) @@ -152,7 +154,11 @@ static const das16cs_board *das16cs_probe(comedi_device * dev, int id; int i; +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + id = link->card_id; +#else id = get_prodid(dev, link); +#endif for (i = 0; i < n_boards; i++) { if (das16cs_boards[i].device_id == id) { @@ -719,8 +725,10 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link) /* Initialize the pcmcia_device structure */ /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE link->irq.IRQInfo1 = IRQ_LEVEL_ID; +#endif link->irq.Handler = NULL; link->conf.Attributes = 0; @@ -746,17 +754,66 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link) kfree(link->priv); } /* das16cs_pcmcia_detach */ +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE +static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + if (cfg->index == 0) + return -EINVAL; + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; + } + /* This reserves IO space but doesn't actually enable it */ + return pcmcia_request_io(p_dev, &p_dev->io); + } + + return 0; +} +#endif + static void das16cs_pcmcia_config(struct pcmcia_device *link) { local_info_t *dev = link->priv; + int last_ret; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE tuple_t tuple; cisparse_t parse; - int last_fn, last_ret; + int last_fn; u_char buf[64]; cistpl_cftable_entry_t dflt = { 0 }; +#endif DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link); +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL); + if (last_ret) { + dev_warn(&link->dev, "no configuration found\n"); + goto cs_failed; + } +#else /* This reads the card's CONFIG tuple to find its configuration registers. @@ -847,6 +904,7 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) goto cs_failed; } +#endif /* Allocate an interrupt line. Note that this does not assign a @@ -854,7 +912,9 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) { +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE last_fn = RequestIRQ; +#endif if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) goto cs_failed; } @@ -863,7 +923,9 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE last_fn = RequestConfiguration; +#endif if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) goto cs_failed; @@ -891,7 +953,9 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link) return; cs_failed: +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE cs_error(link, last_fn, last_ret); +#endif das16cs_pcmcia_release(link); } /* das16cs_pcmcia_config */ diff --git a/comedi/drivers/das08_cs.c b/comedi/drivers/das08_cs.c index d1883807..70203075 100644 --- a/comedi/drivers/das08_cs.c +++ b/comedi/drivers/das08_cs.c @@ -190,8 +190,10 @@ static int das08_pcmcia_attach(struct pcmcia_device *link) link->priv = local; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE link->irq.IRQInfo1 = IRQ_LEVEL_ID; +#endif link->irq.Handler = NULL; /* @@ -244,17 +246,65 @@ static void das08_pcmcia_detach(struct pcmcia_device *link) ======================================================================*/ +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE +static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + if (cfg->index == 0) + return -ENODEV; + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; + } + /* This reserves IO space but doesn't actually enable it */ + return pcmcia_request_io(p_dev, &p_dev->io); + } + return 0; +} +#endif + static void das08_pcmcia_config(struct pcmcia_device *link) { local_info_t *dev = link->priv; + int last_ret; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE tuple_t tuple; cisparse_t parse; - int last_fn, last_ret; + int last_fn; u_char buf[64]; cistpl_cftable_entry_t dflt = { 0 }; +#endif DEBUG(0, "das08_pcmcia_config(0x%p)\n", link); +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL); + if (last_ret) { + dev_warn(&link->dev, "no configuration found\n"); + goto cs_failed; + } +#else /* This reads the card's CONFIG tuple to find its configuration registers. @@ -345,9 +395,12 @@ static void das08_pcmcia_config(struct pcmcia_device *link) if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) goto cs_failed; } +#endif if (link->conf.Attributes & CONF_ENABLE_IRQ) { +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE last_fn = RequestIRQ; +#endif if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) goto cs_failed; } @@ -357,7 +410,9 @@ static void das08_pcmcia_config(struct pcmcia_device *link) the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE last_fn = RequestConfiguration; +#endif if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) goto cs_failed; @@ -385,7 +440,9 @@ static void das08_pcmcia_config(struct pcmcia_device *link) return; cs_failed: +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE cs_error(link, last_fn, last_ret); +#endif das08_pcmcia_release(link); } /* das08_pcmcia_config */ diff --git a/comedi/drivers/ni_daq_700.c b/comedi/drivers/ni_daq_700.c index 0e0f2f07..44f16939 100644 --- a/comedi/drivers/ni_daq_700.c +++ b/comedi/drivers/ni_daq_700.c @@ -513,8 +513,10 @@ static int dio700_cs_attach(struct pcmcia_device *link) link->priv = local; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE link->irq.IRQInfo1 = IRQ_LEVEL_ID; +#endif link->irq.Handler = NULL; /* @@ -569,21 +571,98 @@ static void dio700_cs_detach(struct pcmcia_device *link) ======================================================================*/ +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE +static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + win_req_t *req = priv_data; + memreq_t map; + + if (cfg->index == 0) + return -ENODEV; + + /* Does this card need audio output? */ + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { + p_dev->conf.Attributes |= CONF_ENABLE_SPKR; + p_dev->conf.Status = CCSR_AUDIO_ENA; + } + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; + } + /* This reserves IO space but doesn't actually enable it */ + if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + return -ENODEV; + } + + if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) { + cistpl_mem_t *mem = + (cfg->mem.nwin) ? &cfg->mem : &dflt->mem; + req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM; + req->Attributes |= WIN_ENABLE; + req->Base = mem->win[0].host_addr; + req->Size = mem->win[0].len; + if (req->Size < 0x1000) + req->Size = 0x1000; + req->AccessSpeed = 0; + if (pcmcia_request_window(p_dev, req, &p_dev->win)) + return -ENODEV; + map.Page = 0; + map.CardOffset = mem->win[0].card_addr; + if (pcmcia_map_mem_page(p_dev, p_dev->win, &map)) + return -ENODEV; + } + /* If we got this far, we're cool! */ + return 0; +} +#endif + static void dio700_config(struct pcmcia_device *link) { local_info_t *dev = link->priv; + int last_ret; + win_req_t req; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE tuple_t tuple; cisparse_t parse; - int last_ret; + int last_fn; u_char buf[64]; - win_req_t req; memreq_t map; cistpl_cftable_entry_t dflt = { 0 }; +#endif printk(KERN_INFO "ni_daq_700: cs-config\n"); DEBUG(0, "dio700_config(0x%p)\n", link); +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, &req); + if (last_ret) { + dev_warn(&link->dev, "no configuration found\n"); + goto cs_failed; + } +#else /* This reads the card's CONFIG tuple to find its configuration registers. @@ -593,16 +672,16 @@ static void dio700_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + last_fn = GetFirstTuple; if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) { - cs_error(link, GetFirstTuple, last_ret); goto cs_failed; } + last_fn = GetTupleData; if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) { - cs_error(link, GetTupleData, last_ret); goto cs_failed; } + last_fn = ParseTuple; if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) { - cs_error(link, ParseTuple, last_ret); goto cs_failed; } link->conf.ConfigBase = parse.config.base; @@ -621,8 +700,8 @@ static void dio700_config(struct pcmcia_device *link) will only use the CIS to fill in implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + last_fn = GetFirstTuple; if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) { - cs_error(link, GetFirstTuple, last_ret); goto cs_failed; } while (1) { @@ -691,11 +770,12 @@ static void dio700_config(struct pcmcia_device *link) break; next_entry: + last_fn = GetNextTuple; if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) { - cs_error(link, GetNextTuple, last_ret); goto cs_failed; } } +#endif /* Allocate an interrupt line. Note that this does not assign a @@ -703,8 +783,10 @@ static void dio700_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_fn = RequestIRQ; +#endif if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) { - cs_error(link, RequestIRQ, last_ret); goto cs_failed; } @@ -713,8 +795,10 @@ static void dio700_config(struct pcmcia_device *link) the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_fn = RequestConfiguration; +#endif if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) { - cs_error(link, RequestConfiguration, last_ret); goto cs_failed; } @@ -745,6 +829,9 @@ static void dio700_config(struct pcmcia_device *link) return; cs_failed: +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + cs_error(link, last_fn, last_ret); +#endif printk(KERN_INFO "ni_daq_700 cs failed"); dio700_release(link); diff --git a/comedi/drivers/ni_daq_dio24.c b/comedi/drivers/ni_daq_dio24.c index 7c3c30db..35755cc4 100644 --- a/comedi/drivers/ni_daq_dio24.c +++ b/comedi/drivers/ni_daq_dio24.c @@ -270,8 +270,10 @@ static int dio24_cs_attach(struct pcmcia_device *link) link->priv = local; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE link->irq.IRQInfo1 = IRQ_LEVEL_ID; +#endif link->irq.Handler = NULL; /* @@ -326,21 +328,98 @@ static void dio24_cs_detach(struct pcmcia_device *link) ======================================================================*/ +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE +static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + win_req_t *req = priv_data; + memreq_t map; + + if (cfg->index == 0) + return -ENODEV; + + /* Does this card need audio output? */ + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { + p_dev->conf.Attributes |= CONF_ENABLE_SPKR; + p_dev->conf.Status = CCSR_AUDIO_ENA; + } + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; + } + /* This reserves IO space but doesn't actually enable it */ + if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + return -ENODEV; + } + + if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) { + cistpl_mem_t *mem = + (cfg->mem.nwin) ? &cfg->mem : &dflt->mem; + req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM; + req->Attributes |= WIN_ENABLE; + req->Base = mem->win[0].host_addr; + req->Size = mem->win[0].len; + if (req->Size < 0x1000) + req->Size = 0x1000; + req->AccessSpeed = 0; + if (pcmcia_request_window(p_dev, req, &p_dev->win)) + return -ENODEV; + map.Page = 0; + map.CardOffset = mem->win[0].card_addr; + if (pcmcia_map_mem_page(p_dev, p_dev->win, &map)) + return -ENODEV; + } + /* If we got this far, we're cool! */ + return 0; +} +#endif + static void dio24_config(struct pcmcia_device *link) { local_info_t *dev = link->priv; + int last_ret; + win_req_t req; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE tuple_t tuple; cisparse_t parse; - int last_ret; + int last_fn; u_char buf[64]; - win_req_t req; memreq_t map; cistpl_cftable_entry_t dflt = { 0 }; +#endif printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n"); DEBUG(0, "dio24_config(0x%p)\n", link); +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, &req); + if (last_ret) { + dev_warn(&link->dev, "no configuration found\n"); + goto cs_failed; + } +#else /* This reads the card's CONFIG tuple to find its configuration registers. @@ -350,16 +429,16 @@ static void dio24_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + last_fn = GetFirstTuple; if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) { - cs_error(link, GetFirstTuple, last_ret); goto cs_failed; } + last_fn = GetTupleData; if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) { - cs_error(link, GetTupleData, last_ret); goto cs_failed; } + last_fn = ParseTuple; if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) { - cs_error(link, ParseTuple, last_ret); goto cs_failed; } link->conf.ConfigBase = parse.config.base; @@ -378,8 +457,8 @@ static void dio24_config(struct pcmcia_device *link) will only use the CIS to fill in implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + last_fn = GetFirstTuple; if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) { - cs_error(link, GetFirstTuple, last_ret); goto cs_failed; } while (1) { @@ -448,11 +527,12 @@ static void dio24_config(struct pcmcia_device *link) break; next_entry: + last_fn = GetNextTuple; if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) { - cs_error(link, GetNextTuple, last_ret); goto cs_failed; } } +#endif /* Allocate an interrupt line. Note that this does not assign a @@ -460,8 +540,10 @@ static void dio24_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_fn = RequestIRQ; +#endif if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) { - cs_error(link, RequestIRQ, last_ret); goto cs_failed; } @@ -470,8 +552,10 @@ static void dio24_config(struct pcmcia_device *link) the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_fn = RequestConfiguration; +#endif if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) { - cs_error(link, RequestConfiguration, last_ret); goto cs_failed; } @@ -502,6 +586,9 @@ static void dio24_config(struct pcmcia_device *link) return; cs_failed: +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + cs_error(link, last_fn, last_ret); +#endif printk(KERN_INFO "Fallo"); dio24_release(link); diff --git a/comedi/drivers/ni_labpc_cs.c b/comedi/drivers/ni_labpc_cs.c index 89d452ff..28c538c1 100644 --- a/comedi/drivers/ni_labpc_cs.c +++ b/comedi/drivers/ni_labpc_cs.c @@ -247,8 +247,10 @@ static int labpc_cs_attach(struct pcmcia_device *link) link->priv = local; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID; +#endif link->irq.Handler = NULL; /* @@ -306,19 +308,96 @@ static void labpc_cs_detach(struct pcmcia_device *link) ======================================================================*/ +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE +static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + win_req_t *req = priv_data; + memreq_t map; + + if (cfg->index == 0) + return -ENODEV; + + /* Does this card need audio output? */ + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { + p_dev->conf.Attributes |= CONF_ENABLE_SPKR; + p_dev->conf.Status = CCSR_AUDIO_ENA; + } + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; + } + /* This reserves IO space but doesn't actually enable it */ + if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + return -ENODEV; + } + + if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) { + cistpl_mem_t *mem = + (cfg->mem.nwin) ? &cfg->mem : &dflt->mem; + req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM; + req->Attributes |= WIN_ENABLE; + req->Base = mem->win[0].host_addr; + req->Size = mem->win[0].len; + if (req->Size < 0x1000) + req->Size = 0x1000; + req->AccessSpeed = 0; + if (pcmcia_request_window(p_dev, req, &p_dev->win)) + return -ENODEV; + map.Page = 0; + map.CardOffset = mem->win[0].card_addr; + if (pcmcia_map_mem_page(p_dev, p_dev->win, &map)) + return -ENODEV; + } + /* If we got this far, we're cool! */ + return 0; +} +#endif + static void labpc_config(struct pcmcia_device *link) { local_info_t *dev = link->priv; + int last_ret; + win_req_t req; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE tuple_t tuple; cisparse_t parse; - int last_ret; + int last_fn; u_char buf[64]; - win_req_t req; memreq_t map; cistpl_cftable_entry_t dflt = { 0 }; +#endif DEBUG(0, "labpc_config(0x%p)\n", link); +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, &req); + if (last_ret) { + dev_warn(&link->dev, "no configuration found\n"); + goto cs_failed; + } +#else /* This reads the card's CONFIG tuple to find its configuration registers. @@ -328,16 +407,16 @@ static void labpc_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + last_fn = GetFirstTuple; if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) { - cs_error(link, GetFirstTuple, last_ret); goto cs_failed; } + last_fn = GetTupleData; if ((last_ret = pcmcia_get_tuple_data(link, &tuple))) { - cs_error(link, GetTupleData, last_ret); goto cs_failed; } + last_fn = ParseTuple; if ((last_ret = pcmcia_parse_tuple(&tuple, &parse))) { - cs_error(link, ParseTuple, last_ret); goto cs_failed; } link->conf.ConfigBase = parse.config.base; @@ -356,8 +435,8 @@ static void labpc_config(struct pcmcia_device *link) will only use the CIS to fill in implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + last_fn = GetFirstTuple; if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) { - cs_error(link, GetFirstTuple, last_ret); goto cs_failed; } while (1) { @@ -423,11 +502,12 @@ static void labpc_config(struct pcmcia_device *link) break; next_entry: + last_fn = GetNextTuple; if ((last_ret = pcmcia_get_next_tuple(link, &tuple))) { - cs_error(link, GetNextTuple, last_ret); goto cs_failed; } } +#endif /* Allocate an interrupt line. Note that this does not assign a @@ -435,8 +515,10 @@ static void labpc_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_fn = RequestIRQ; +#endif if ((last_ret = pcmcia_request_irq(link, &link->irq))) { - cs_error(link, RequestIRQ, last_ret); goto cs_failed; } @@ -445,8 +527,10 @@ static void labpc_config(struct pcmcia_device *link) the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_fn = RequestConfiguration; +#endif if ((last_ret = pcmcia_request_configuration(link, &link->conf))) { - cs_error(link, RequestConfiguration, last_ret); goto cs_failed; } @@ -477,6 +561,9 @@ static void labpc_config(struct pcmcia_device *link) return; cs_failed: +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + cs_error(link, last_fn, last_ret); +#endif labpc_release(link); } /* labpc_config */ diff --git a/comedi/drivers/ni_mio_cs.c b/comedi/drivers/ni_mio_cs.c index b1a57441..277f7580 100644 --- a/comedi/drivers/ni_mio_cs.c +++ b/comedi/drivers/ni_mio_cs.c @@ -269,8 +269,10 @@ static int cs_attach(struct pcmcia_device *link) { link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->io.NumPorts1 = 16; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE link->irq.IRQInfo1 = IRQ_LEVEL_ID; +#endif link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -308,16 +310,48 @@ static int mio_cs_resume(struct pcmcia_device *link) return 0; } +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE +static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + int base, ret; + + p_dev->io.NumPorts1 = cfg->io.win[0].len; + p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; + p_dev->io.NumPorts2 = 0; + + for (base = 0x000; base < 0x400; base += 0x20) { + p_dev->io.BasePort1 = base; + ret = pcmcia_request_io(p_dev, &p_dev->io); + if (!ret) + return 0; + } + return -ENODEV; +} +#endif + static void mio_cs_config(struct pcmcia_device *link) { +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE tuple_t tuple; u_short buf[128]; cisparse_t parse; int manfid = 0, prodid = 0; +#endif int ret; DPRINTK("mio_cs_config(link=%p)\n", link); +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + ret = pcmcia_loop_config(link, mio_pcmcia_config_loop, NULL); + if (ret) { + dev_warn(&link->dev, "no configuration found\n"); + return; + } +#else tuple.TupleData = (cisdata_t *) buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; @@ -388,13 +422,16 @@ static void mio_cs_config(struct pcmcia_device *link) link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1; link->irq.IRQInfo2 = parse.cftable_entry.irq.IRQInfo2; +#endif ret = pcmcia_request_irq(link, &link->irq); if (ret) { printk("pcmcia_request_irq() returned error: %i\n", ret); } //printk("RequestIRQ 0x%02x\n",ret); +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE link->conf.ConfigIndex = 1; +#endif ret = pcmcia_request_configuration(link, &link->conf); //printk("RequestConfiguration %d\n",ret); @@ -467,6 +504,7 @@ static int mio_cs_attach(comedi_device * dev, comedi_devconfig * it) return 0; } +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE static int get_prodid(comedi_device * dev, struct pcmcia_device *link) { tuple_t tuple; @@ -485,13 +523,18 @@ static int get_prodid(comedi_device * dev, struct pcmcia_device *link) return prodid; } +#endif static int ni_getboardtype(comedi_device * dev, struct pcmcia_device *link) { int id; int i; +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + id = link->card_id; +#else id = get_prodid(dev, link); +#endif for (i = 0; i < n_ni_boards; i++) { if (ni_boards[i].device_id == id) { diff --git a/comedi/drivers/quatech_daqp_cs.c b/comedi/drivers/quatech_daqp_cs.c index 2e7e7109..e4832b5c 100644 --- a/comedi/drivers/quatech_daqp_cs.c +++ b/comedi/drivers/quatech_daqp_cs.c @@ -262,8 +262,19 @@ static int daqp_ai_cancel(comedi_device * dev, comedi_subdevice * s) * comedi kernel module, and signal various comedi callback routines, * which run pretty quick. */ +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE +typedef irqreturn_t my_irqreturn_t; +#define MY_IRQ_NONE IRQ_NONE +#define MY_IRQ_HANDLED IRQ_HANDLED +#define MY_IRQ_RETVAL(x) IRQ_RETVAL(x) +#else +typedef void my_irqreturn_t; +#define MY_IRQ_NONE +#define MY_IRQ_HANDLED +#define MY_IRQ_RETVAL(x) ((void)(x)) +#endif -static void daqp_interrupt(int irq, void *dev_id PT_REGS_ARG) +static my_irqreturn_t daqp_interrupt(int irq, void *dev_id PT_REGS_ARG) { local_info_t *local = (local_info_t *) dev_id; comedi_device *dev; @@ -274,32 +285,32 @@ static void daqp_interrupt(int irq, void *dev_id PT_REGS_ARG) if (local == NULL) { printk(KERN_WARNING "daqp_interrupt(): irq %d for unknown device.\n", irq); - return; + return MY_IRQ_NONE; } dev = local->dev; if (dev == NULL) { printk(KERN_WARNING "daqp_interrupt(): NULL comedi_device.\n"); - return; + return MY_IRQ_NONE; } if (!dev->attached) { printk(KERN_WARNING "daqp_interrupt(): comedi_device not yet attached.\n"); - return; + return MY_IRQ_NONE; } s = local->s; if (s == NULL) { printk(KERN_WARNING "daqp_interrupt(): NULL comedi_subdevice.\n"); - return; + return MY_IRQ_NONE; } if ((local_info_t *) s->private != local) { printk(KERN_WARNING "daqp_interrupt(): invalid comedi_subdevice.\n"); - return; + return MY_IRQ_NONE; } switch (local->interrupt_mode) { @@ -358,6 +369,7 @@ static void daqp_interrupt(int irq, void *dev_id PT_REGS_ARG) comedi_event(dev, s); } + return MY_IRQ_HANDLED; } /* One-shot analog data acquisition routine */ @@ -861,8 +873,10 @@ static int daqp_attach(comedi_device * dev, comedi_devconfig * it) { int ret; local_info_t *local = dev_table[it->options[0]]; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE tuple_t tuple; int i; +#endif comedi_subdevice *s; if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) { @@ -882,6 +896,14 @@ static int daqp_attach(comedi_device * dev, comedi_devconfig * it) strcpy(local->board_name, "DAQP"); dev->board_name = local->board_name; +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + if (local->link->prod_id[2]) { + if (strncmp(local->link->prod_id[2], "DAQP", 4) == 0) { + strncpy(local->board_name, local->link->prod_id[2], + sizeof(local->board_name)); + } + } +#else tuple.DesiredTuple = CISTPL_VERS_1; if (pcmcia_get_first_tuple(local->link, &tuple) == 0) { u_char buf[128]; @@ -906,6 +928,7 @@ static int daqp_attach(comedi_device * dev, comedi_devconfig * it) } } } +#endif dev->iobase = local->link->io.BasePort1; @@ -1076,10 +1099,14 @@ static int daqp_cs_attach(struct pcmcia_device *link) link->priv = local; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE link->irq.IRQInfo1 = IRQ_LEVEL_ID; +#endif link->irq.Handler = daqp_interrupt; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE link->irq.Instance = local; +#endif /* General socket configuration defaults can go here. In this @@ -1131,16 +1158,64 @@ static void daqp_cs_detach(struct pcmcia_device *link) ======================================================================*/ +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE +static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + if (cfg->index == 0) + return -ENODEV; + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; + } + } + + /* This reserves IO space but doesn't actually enable it */ + return pcmcia_request_io(p_dev, &p_dev->io); +} +#endif + static void daqp_cs_config(struct pcmcia_device *link) { local_info_t *dev = link->priv; + int last_ret; +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE tuple_t tuple; cisparse_t parse; - int last_ret; + int last_fn; u_char buf[64]; +#endif DEBUG(0, "daqp_cs_config(0x%p)\n", link); +#ifdef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL); + if (last_ret) { + dev_warn(&link->dev, "no configuration found\n"); + goto cs_failed; + } +#else /* This reads the card's CONFIG tuple to find its configuration registers. @@ -1150,16 +1225,16 @@ static void daqp_cs_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + last_fn = GetFirstTuple; if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) { - cs_error(link, GetFirstTuple, last_ret); goto cs_failed; } + last_fn = GetTupleData; if ((last_ret = pcmcia_get_tuple_data(link, &tuple))) { - cs_error(link, GetTupleData, last_ret); goto cs_failed; } + last_fn = ParseTuple; if ((last_ret = pcmcia_parse_tuple(&tuple, &parse))) { - cs_error(link, ParseTuple, last_ret); goto cs_failed; } link->conf.ConfigBase = parse.config.base; @@ -1178,8 +1253,8 @@ static void daqp_cs_config(struct pcmcia_device *link) will only use the CIS to fill in implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + last_fn = GetFirstTuple; if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) { - cs_error(link, GetFirstTuple, last_ret); goto cs_failed; } while (1) { @@ -1227,11 +1302,12 @@ static void daqp_cs_config(struct pcmcia_device *link) break; next_entry: + last_fn = GetNextTuple; if ((last_ret = pcmcia_get_next_tuple(link, &tuple))) { - cs_error(link, GetNextTuple, last_ret); goto cs_failed; } } +#endif /* Allocate an interrupt line. Note that this does not assign a @@ -1239,8 +1315,10 @@ static void daqp_cs_config(struct pcmcia_device *link) irq structure is initialized. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_fn = RequestIRQ; +#endif if ((last_ret = pcmcia_request_irq(link, &link->irq))) { - cs_error(link, RequestIRQ, last_ret); goto cs_failed; } @@ -1249,8 +1327,10 @@ static void daqp_cs_config(struct pcmcia_device *link) the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + last_fn = RequestConfiguration; +#endif if ((last_ret = pcmcia_request_configuration(link, &link->conf))) { - cs_error(link, RequestConfiguration, last_ret); goto cs_failed; } @@ -1282,6 +1362,9 @@ static void daqp_cs_config(struct pcmcia_device *link) return; cs_failed: +#ifndef CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE + cs_error(link, last_fn, last_ret); +#endif daqp_cs_release(link); } /* daqp_cs_config */ diff --git a/configure.ac b/configure.ac index 7b056f07..25abece9 100644 --- a/configure.ac +++ b/configure.ac @@ -110,6 +110,12 @@ else fi AM_CONDITIONAL([CONFIG_COMEDI_PCMCIA],[test "$USE_PCMCIA" = "yes"]) +COMEDI_CHECK_PCMCIA_LOOP_TUPLE([$LINUX_SRC_DIR], + [HAVE_PCMCIA_LOOP_TUPLE="yes"], [HAVE_PCMCIA_LOOP_TUPLE="no"]) +if test "$HAVE_PCMCIA_LOOP_TUPLE" = "yes" ; then + AC_DEFINE([CONFIG_COMEDI_HAVE_PCMCIA_LOOP_TUPLE],[true],[Define if Linux kernel source has pcmcia_loop_tuple function]) +fi + AS_CHECK_LINUX_CONFIG_OPTION([CONFIG_USB],[HAVE_USB="yes"],[HAVE_USB="yes"],[HAVE_USB="no"]) AM_CONDITIONAL([CONFIG_USB],[test "$HAVE_USB" = "yes"]) AC_ARG_ENABLE([usb],[ --disable-usb Disable support for USB devices], diff --git a/m4/as-linux.m4 b/m4/as-linux.m4 index 1248f0b0..b0ee39f9 100644 --- a/m4/as-linux.m4 +++ b/m4/as-linux.m4 @@ -786,6 +786,23 @@ AC_DEFUN([COMEDI_CHECK_PCMCIA_PROBE], fi ]) +# COMEDI_CHECK_PCMCIA_LOOP_TUPLE([LINUX_SOURCE_PATH], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# ------------------------------------------------------------- +# +# Check if kernel pcmcia support is new enough to have the pcmcia_loop_tuple +# function. +AC_DEFUN([COMEDI_CHECK_PCMCIA_LOOP_TUPLE], +[ + AC_MSG_CHECKING([$1 for pcmcia_loop_tuple function]) + if [grep -q 'int[[:space:]]\+pcmcia_loop_tuple[[:space:]]*(' "$1/include/pcmcia/ds.h"] 2>/dev/null ; then + AC_MSG_RESULT([yes]) + $2 + else + AC_MSG_RESULT([no]) + $3 + fi +]) + # COMEDI_CHECK_HAVE_MUTEX_H([LINUX_SOURCE_PATH], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # ------------------------------------------------------------- #