PCMCIA support broke with the 2.6.33 kernel, so add support back in.
authorIan Abbott <abbotti@mev.co.uk>
Tue, 22 Jun 2010 16:12:24 +0000 (16:12 +0000)
committerIan Abbott <abbotti@mev.co.uk>
Tue, 22 Jun 2010 16:12:24 +0000 (16:12 +0000)
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.

comedi/drivers/cb_das16_cs.c
comedi/drivers/das08_cs.c
comedi/drivers/ni_daq_700.c
comedi/drivers/ni_daq_dio24.c
comedi/drivers/ni_labpc_cs.c
comedi/drivers/ni_mio_cs.c
comedi/drivers/quatech_daqp_cs.c
configure.ac
m4/as-linux.m4

index d1f312e346129ecd76bdab62bbe64f337fde7d52..4229d47698d94ff3bf695362d2273b34f970b252 100644 (file)
@@ -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 */
 
index d1883807c45bd3d21936ce5e4bb2809b40e8ef73..702030753ecfcc71fd52fd9218e2c2c63ea98bc2 100644 (file)
@@ -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 */
index 0e0f2f0722f91f7e31175e23f14380358cb9c2c6..44f16939611116d272effa5f921b8cb199ca26ab 100644 (file)
@@ -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);
 
index 7c3c30dbe56693940ece4fd0ef291b4c2afafb94..35755cc49cab6addf47b14ce1d1ac9884df500c0 100644 (file)
@@ -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);
 
index 89d452ff0f365f73196df6a48f8375e611b8a619..28c538c1f4a4dfbedc22ed79acd4360bd0d698dd 100644 (file)
@@ -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 */
index b1a574413344f8caa9f4acf7d178a146e527277d..277f758088d342dfe3976ef560b845a17ca47287 100644 (file)
@@ -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) {
index 2e7e71098d6f91a751d677228e6cfd3badadbff9..e4832b5cae9f0d2ca185184719f9717c2576cd12 100644 (file)
@@ -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 */
index 7b056f07b7d90e84d90b052c02f2cbb1909c49cf..25abece947f60d2f78a4a43baa370cfedcb3d5f7 100644 (file)
@@ -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],
index 1248f0b03cb7f4af8caf240faf5938c94342c064..b0ee39f93645356f07a26c58d7343ada4da8442c 100644 (file)
@@ -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])
 # -------------------------------------------------------------
 #