Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Oct 2008 21:12:40 +0000 (14:12 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Oct 2008 21:12:40 +0000 (14:12 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: (49 commits)
  pcmcia: ioctl-internal definitions
  pcmcia: cistpl header cleanup
  pcmcia: remove unused argument to pcmcia_parse_tuple()
  pcmcia: card services header cleanup
  pcmcia: device_id header cleanup
  pcmcia: encapsulate ioaddr_t
  pcmcia: cleanup device driver header file
  pcmcia: cleanup socket services header file
  pcmcia: merge ds_internal.h into cs_internal.h
  pcmcia: cleanup cs_internal.h
  pcmcia: cs_internal.h is internal
  pcmcia: use dev_printk for cs_error()
  pcmcia: remove CS_ error codes alltogether
  pcmcia: deprecate CS_BAD_TUPLE
  pcmcia: deprecate CS_BAD_ARGS
  pcmcia: deprecate CS_BAD_BASE, CS_BAD_IRQ, CS_BAD_OFFSET and CS_BAD_SIZE
  pcmcia: deprecate CS_BAD_ATTRIBUTE, CS_BAD_TYPE and CS_BAD_PAGE
  pcmcia: deprecate CS_NO_MORE_ITEMS
  pcmcia: deprecate CS_IN_USE
  pcmcia: deprecate CS_CONFIGURATION_LOCKED
  ...

Fix trivial conflict in drivers/pcmcia/ds.c manually

21 files changed:
1  2 
drivers/bluetooth/bt3c_cs.c
drivers/char/pcmcia/synclink_cs.c
drivers/ide/legacy/ide-cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/wireless/airo_cs.c
drivers/net/wireless/atmel_cs.c
drivers/net/wireless/libertas/if_cs.c
drivers/net/wireless/netwave_cs.c
drivers/net/wireless/orinoco_cs.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/spectrum_cs.c
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wl3501_cs.c
drivers/pcmcia/Makefile
drivers/pcmcia/ds.c
drivers/pcmcia/pxa2xx_base.c
drivers/pcmcia/rsrc_nonstatic.c
drivers/pcmcia/soc_common.c
drivers/scsi/pcmcia/nsp_cs.c

index 27058477cc8b7722bdc901ec7edb21e1d503be27,156edfd7e10d7eabbb950deed39713654875bdd2..2cbe70b66470eb7189a7232fa54e8c79d5db70fe
@@@ -60,7 -60,7 +60,7 @@@
  /* ======================== Module parameters ======================== */
  
  
 -MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
  MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
  MODULE_LICENSE("GPL");
  MODULE_FIRMWARE("BT3CPCC.bin");
@@@ -678,101 -678,78 +678,78 @@@ static void bt3c_detach(struct pcmcia_d
        kfree(info);
  }
  
- static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
+ static int bt3c_check_config(struct pcmcia_device *p_dev,
+                            cistpl_cftable_entry_t *cf,
+                            cistpl_cftable_entry_t *dflt,
+                            unsigned int vcc,
+                            void *priv_data)
  {
-       int i;
-       i = pcmcia_get_tuple_data(handle, tuple);
-       if (i != CS_SUCCESS)
-               return i;
-       return pcmcia_parse_tuple(handle, tuple, parse);
- }
- static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
- {
-       if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
-               return CS_NO_MORE_ITEMS;
-       return get_tuple(handle, tuple, parse);
+       unsigned long try = (unsigned long) priv_data;
+       if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+       if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
+           (cf->io.win[0].base != 0)) {
+               p_dev->io.BasePort1 = cf->io.win[0].base;
+               p_dev->io.IOAddrLines = (try == 0) ? 16 :
+                       cf->io.flags & CISTPL_IO_LINES_MASK;
+               if (!pcmcia_request_io(p_dev, &p_dev->io))
+                       return 0;
+       }
+       return -ENODEV;
  }
  
- static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
+ static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
+                                     cistpl_cftable_entry_t *cf,
+                                     cistpl_cftable_entry_t *dflt,
+                                     unsigned int vcc,
+                                     void *priv_data)
  {
-       if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
-               return CS_NO_MORE_ITEMS;
-       return get_tuple(handle, tuple, parse);
+       static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
+       int j;
+       if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
+               for (j = 0; j < 5; j++) {
+                       p_dev->io.BasePort1 = base[j];
+                       p_dev->io.IOAddrLines = base[j] ? 16 : 3;
+                       if (!pcmcia_request_io(p_dev, &p_dev->io))
+                               return 0;
+               }
+       }
+       return -ENODEV;
  }
  
  static int bt3c_config(struct pcmcia_device *link)
  {
-       static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
        bt3c_info_t *info = link->priv;
-       tuple_t tuple;
-       u_short buf[256];
-       cisparse_t parse;
-       cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-       int i, j, try;
-       /* First pass: look for a config entry that looks normal. */
-       tuple.TupleData = (cisdata_t *)buf;
-       tuple.TupleOffset = 0;
-       tuple.TupleDataMax = 255;
-       tuple.Attributes = 0;
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       /* Two tries: without IO aliases, then with aliases */
-       for (try = 0; try < 2; try++) {
-               i = first_tuple(link, &tuple, &parse);
-               while (i != CS_NO_MORE_ITEMS) {
-                       if (i != CS_SUCCESS)
-                               goto next_entry;
-                       if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-                               link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-                       if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
-                               link->conf.ConfigIndex = cf->index;
-                               link->io.BasePort1 = cf->io.win[0].base;
-                               link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-                               i = pcmcia_request_io(link, &link->io);
-                               if (i == CS_SUCCESS)
-                                       goto found_port;
-                       }
- next_entry:
-                       i = next_tuple(link, &tuple, &parse);
-               }
-       }
+       int i;
+       unsigned long try;
+       /* First pass: look for a config entry that looks normal.
+          Two tries: without IO aliases, then with aliases */
+       for (try = 0; try < 2; try++)
+               if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
+                       goto found_port;
  
        /* Second pass: try to find an entry that isn't picky about
           its base address, then try to grab any standard serial port
           address, and finally try to get any free port. */
-       i = first_tuple(link, &tuple, &parse);
-       while (i != CS_NO_MORE_ITEMS) {
-               if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-                       link->conf.ConfigIndex = cf->index;
-                       for (j = 0; j < 5; j++) {
-                               link->io.BasePort1 = base[j];
-                               link->io.IOAddrLines = base[j] ? 16 : 3;
-                               i = pcmcia_request_io(link, &link->io);
-                               if (i == CS_SUCCESS)
-                                       goto found_port;
-                       }
-               }
-               i = next_tuple(link, &tuple, &parse);
-       }
+       if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
+               goto found_port;
  
- found_port:
-       if (i != CS_SUCCESS) {
-               BT_ERR("No usable port range found");
-               cs_error(link, RequestIO, i);
-               goto failed;
-       }
+       BT_ERR("No usable port range found");
+       cs_error(link, RequestIO, -ENODEV);
+       goto failed;
  
+ found_port:
        i = pcmcia_request_irq(link, &link->irq);
-       if (i != CS_SUCCESS) {
+       if (i != 0) {
                cs_error(link, RequestIRQ, i);
                link->irq.AssignedIRQ = 0;
        }
  
        i = pcmcia_request_configuration(link, &link->conf);
-       if (i != CS_SUCCESS) {
+       if (i != 0) {
                cs_error(link, RequestConfiguration, i);
                goto failed;
        }
index c240562c218b735b985883528458272733294eff,05bf9c55ecc21dd4e60da4bd6d6a2267c0d33c68..9a626e50b793ba65ce21d269d64a3536546e970c
@@@ -232,6 -232,7 +232,6 @@@ typedef struct _mgslpc_info 
  
        /* SPPP/Cisco HDLC device parts */
        int netcount;
 -      int dosyncppp;
        spinlock_t netlock;
  
  #if SYNCLINK_GENERIC_HDLC
@@@ -458,11 -459,13 +458,11 @@@ static int ttymajor=0
  
  static int debug_level = 0;
  static int maxframe[MAX_DEVICE_COUNT] = {0,};
 -static int dosyncppp[MAX_DEVICE_COUNT] = {1,1,1,1};
  
  module_param(break_on_load, bool, 0);
  module_param(ttymajor, int, 0);
  module_param(debug_level, int, 0);
  module_param_array(maxframe, int, NULL, 0);
 -module_param_array(dosyncppp, int, NULL, 0);
  
  MODULE_LICENSE("GPL");
  
@@@ -601,7 -604,7 +601,7 @@@ static int mgslpc_config(struct pcmcia_
  
      cfg = &(parse.cftable_entry);
      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-     CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
+     CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
  
      if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
      if (cfg->index == 0)
@@@ -2912,6 -2915,7 +2912,6 @@@ static void mgslpc_add_device(MGSLPC_IN
        if (info->line < MAX_DEVICE_COUNT) {
                if (maxframe[info->line])
                        info->max_frame_size = maxframe[info->line];
 -              info->dosyncppp = dosyncppp[info->line];
        }
  
        mgslpc_device_count++;
index ee6fc30d5e2bec793b93099a5068b7c5cccdaa4c,fe20cdbd56f57cfbad1712570b24671afa1f1350..cb199c815b534234bbd115c0ea19df7fea3a48e9
@@@ -38,6 -38,7 +38,6 @@@
  #include <linux/timer.h>
  #include <linux/ioport.h>
  #include <linux/ide.h>
 -#include <linux/hdreg.h>
  #include <linux/major.h>
  #include <linux/delay.h>
  #include <asm/io.h>
@@@ -219,103 -220,91 +219,91 @@@ out_release
  #define CS_CHECK(fn, ret) \
  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
  
+ struct pcmcia_config_check {
+       unsigned long ctl_base;
+       int skip_vcc;
+       int is_kme;
+ };
+ static int pcmcia_check_one_config(struct pcmcia_device *pdev,
+                                  cistpl_cftable_entry_t *cfg,
+                                  cistpl_cftable_entry_t *dflt,
+                                  unsigned int vcc,
+                                  void *priv_data)
+ {
+       struct pcmcia_config_check *stk = priv_data;
+       /* Check for matching Vcc, unless we're desperate */
+       if (!stk->skip_vcc) {
+               if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+                       if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
+                               return -ENODEV;
+               } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+                       if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
+                               return -ENODEV;
+               }
+       }
+       if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
+               pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+       else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
+               pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+       if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+               cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               pdev->conf.ConfigIndex = cfg->index;
+               pdev->io.BasePort1 = io->win[0].base;
+               pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+               if (!(io->flags & CISTPL_IO_16BIT))
+                       pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               if (io->nwin == 2) {
+                       pdev->io.NumPorts1 = 8;
+                       pdev->io.BasePort2 = io->win[1].base;
+                       pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
+                       if (pcmcia_request_io(pdev, &pdev->io) != 0)
+                               return -ENODEV;
+                       stk->ctl_base = pdev->io.BasePort2;
+               } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
+                       pdev->io.NumPorts1 = io->win[0].len;
+                       pdev->io.NumPorts2 = 0;
+                       if (pcmcia_request_io(pdev, &pdev->io) != 0)
+                               return -ENODEV;
+                       stk->ctl_base = pdev->io.BasePort1 + 0x0e;
+               } else
+                       return -ENODEV;
+               /* If we've got this far, we're done */
+               return 0;
+       }
+       return -ENODEV;
+ }
  static int ide_config(struct pcmcia_device *link)
  {
      ide_info_t *info = link->priv;
-     tuple_t tuple;
-     struct {
-       u_short         buf[128];
-       cisparse_t      parse;
-       config_info_t   conf;
-       cistpl_cftable_entry_t dflt;
-     } *stk = NULL;
-     cistpl_cftable_entry_t *cfg;
-     int pass, last_ret = 0, last_fn = 0, is_kme = 0;
+     struct pcmcia_config_check *stk = NULL;
+     int last_ret = 0, last_fn = 0, is_kme = 0;
      unsigned long io_base, ctl_base;
      struct ide_host *host;
  
      DEBUG(0, "ide_config(0x%p)\n", link);
  
-     stk = kzalloc(sizeof(*stk), GFP_KERNEL);
-     if (!stk) goto err_mem;
-     cfg = &stk->parse.cftable_entry;
-     tuple.TupleData = (cisdata_t *)&stk->buf;
-     tuple.TupleOffset = 0;
-     tuple.TupleDataMax = 255;
-     tuple.Attributes = 0;
      is_kme = ((link->manf_id == MANFID_KME) &&
              ((link->card_id == PRODID_KME_KXLC005_A) ||
               (link->card_id == PRODID_KME_KXLC005_B)));
  
-     /* Not sure if this is right... look up the current Vcc */
-     CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
-     pass = io_base = ctl_base = 0;
-     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-     tuple.Attributes = 0;
-     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-     while (1) {
-       if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry;
-       if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry;
-       /* Check for matching Vcc, unless we're desperate */
-       if (!pass) {
-           if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
-               if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
-                   goto next_entry;
-           } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
-               if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
-                   goto next_entry;
-           }
-       }
-       if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
-           link->conf.Vpp =
-               cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-       else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
-           link->conf.Vpp =
-               stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
-       if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
-           cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
-           link->conf.ConfigIndex = cfg->index;
-           link->io.BasePort1 = io->win[0].base;
-           link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-           if (!(io->flags & CISTPL_IO_16BIT))
-               link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-           if (io->nwin == 2) {
-               link->io.NumPorts1 = 8;
-               link->io.BasePort2 = io->win[1].base;
-               link->io.NumPorts2 = (is_kme) ? 2 : 1;
-               if (pcmcia_request_io(link, &link->io) != 0)
-                       goto next_entry;
-               io_base = link->io.BasePort1;
-               ctl_base = link->io.BasePort2;
-           } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
-               link->io.NumPorts1 = io->win[0].len;
-               link->io.NumPorts2 = 0;
-               if (pcmcia_request_io(link, &link->io) != 0)
-                       goto next_entry;
-               io_base = link->io.BasePort1;
-               ctl_base = link->io.BasePort1 + 0x0e;
-           } else goto next_entry;
-           /* If we've got this far, we're done */
-           break;
-       }
-     next_entry:
-       if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-           memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
-       if (pass) {
-           CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
-       } else if (pcmcia_get_next_tuple(link, &tuple) != 0) {
-           CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-           memset(&stk->dflt, 0, sizeof(stk->dflt));
-           pass++;
-       }
+     stk = kzalloc(sizeof(*stk), GFP_KERNEL);
+     if (!stk)
+           goto err_mem;
+     stk->is_kme = is_kme;
+     stk->skip_vcc = io_base = ctl_base = 0;
+     if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) {
+           stk->skip_vcc = 1;
+           if (pcmcia_loop_config(link, pcmcia_check_one_config, stk))
+                   goto failed; /* No suitable config found */
      }
+     io_base = link->io.BasePort1;
+     ctl_base = stk->ctl_base;
  
      CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
      CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
@@@ -403,8 -392,10 +391,10 @@@ static struct pcmcia_device_id ide_ids[
        PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000),        /* I-O Data CFA */
        PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001),        /* Mitsubishi CFA */
        PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
+       PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904),
        PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),        /* SanDisk CFA */
        PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000),        /* Kingston */
+       PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620),        /* TI emulated */
        PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),        /* Toshiba */
        PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
        PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),        /* Samsung */
index 52bf11b73c6e950e0829bed0dcee087f98c52b38,0bc641adce196a1b6229b4464f53c4ce42fdc1d7..b37a498939ae7d1a16f6e1a5c0ad8545f6d32380
@@@ -262,7 -262,7 +262,7 @@@ static int try_io_port(struct pcmcia_de
        if (link->io.NumPorts2 > 0) {
            /* for master/slave multifunction cards */
            link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-           link->irq.Attributes = 
+           link->irq.Attributes =
                IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
        }
      } else {
            link->io.BasePort1 = j ^ 0x300;
            link->io.BasePort2 = (j ^ 0x300) + 0x10;
            ret = pcmcia_request_io(link, &link->io);
-           if (ret == CS_SUCCESS) return ret;
+           if (ret == 0)
+                   return ret;
        }
        return ret;
      } else {
      }
  }
  
+ static int axnet_configcheck(struct pcmcia_device *p_dev,
+                            cistpl_cftable_entry_t *cfg,
+                            cistpl_cftable_entry_t *dflt,
+                            unsigned int vcc,
+                            void *priv_data)
+ {
+       int i;
+       cistpl_io_t *io = &cfg->io;
+       if (cfg->index == 0 || cfg->io.nwin == 0)
+               return -ENODEV;
+       p_dev->conf.ConfigIndex = 0x05;
+       /* For multifunction cards, by convention, we configure the
+          network function with window 0, and serial with window 1 */
+       if (io->nwin > 1) {
+               i = (io->win[1].len > io->win[0].len);
+               p_dev->io.BasePort2 = io->win[1-i].base;
+               p_dev->io.NumPorts2 = io->win[1-i].len;
+       } else {
+               i = p_dev->io.NumPorts2 = 0;
+       }
+       p_dev->io.BasePort1 = io->win[i].base;
+       p_dev->io.NumPorts1 = io->win[i].len;
+       p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+       if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
+               return try_io_port(p_dev);
+       return -ENODEV;
+ }
  static int axnet_config(struct pcmcia_device *link)
  {
      struct net_device *dev = link->priv;
      axnet_dev_t *info = PRIV(dev);
-     tuple_t tuple;
-     cisparse_t parse;
      int i, j, last_ret, last_fn;
-     u_short buf[64];
      DECLARE_MAC_BUF(mac);
  
      DEBUG(0, "axnet_config(0x%p)\n", link);
  
-     tuple.Attributes = 0;
-     tuple.TupleData = (cisdata_t *)buf;
-     tuple.TupleDataMax = sizeof(buf);
-     tuple.TupleOffset = 0;
      /* don't trust the CIS on this; Linksys got it wrong */
      link->conf.Present = 0x63;
-     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-     tuple.Attributes = 0;
-     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-     while (last_ret == CS_SUCCESS) {
-       cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-       cistpl_io_t *io = &(parse.cftable_entry.io);
-       
-       if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
-               pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
-               cfg->index == 0 || cfg->io.nwin == 0)
-           goto next_entry;
-       
-       link->conf.ConfigIndex = 0x05;
-       /* For multifunction cards, by convention, we configure the
-          network function with window 0, and serial with window 1 */
-       if (io->nwin > 1) {
-           i = (io->win[1].len > io->win[0].len);
-           link->io.BasePort2 = io->win[1-i].base;
-           link->io.NumPorts2 = io->win[1-i].len;
-       } else {
-           i = link->io.NumPorts2 = 0;
-       }
-       link->io.BasePort1 = io->win[i].base;
-       link->io.NumPorts1 = io->win[i].len;
-       link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-       if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
-           last_ret = try_io_port(link);
-           if (last_ret == CS_SUCCESS) break;
-       }
-     next_entry:
-       last_ret = pcmcia_get_next_tuple(link, &tuple);
-     }
-     if (last_ret != CS_SUCCESS) {
+     last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
+     if (last_ret != 0) {
        cs_error(link, RequestIO, last_ret);
        goto failed;
      }
@@@ -784,7 -776,6 +776,7 @@@ static struct pcmcia_device_id axnet_id
        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXD", 0x5261440f, 0x436768c5),
        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEtherII PCC-TXD", 0x5261440f, 0x730df72e),
        PCMCIA_DEVICE_PROD_ID12("Dynalink", "L100C16", 0x55632fd5, 0x66bc2a90),
 +      PCMCIA_DEVICE_PROD_ID12("IO DATA", "ETXPCM", 0x547e66dc, 0x233adac2),
        PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8),
        PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC3-TX", 0x481e0094, 0xf91af609),
        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "100BASE", 0x281f1c5d, 0x7c2add04),
index ebc1ae6bcbe5fc27f7152add5064a8dde48b9f70,1758952b3a38b45437f5a299393aecba7a29e35d..e40d6301aa7aaf1084b9e0cef1bfbf7588d692c3
@@@ -310,7 -310,7 +310,7 @@@ static hw_info_t *get_hwinfo(struct pcm
      req.Base = 0; req.Size = 0;
      req.AccessSpeed = 0;
      i = pcmcia_request_window(&link, &req, &link->win);
-     if (i != CS_SUCCESS) {
+     if (i != 0) {
        cs_error(link, RequestWindow, i);
        return NULL;
      }
  
      iounmap(virt);
      j = pcmcia_release_window(link->win);
-     if (j != CS_SUCCESS)
+     if (j != 0)
        cs_error(link, ReleaseWindow, j);
      return (i < NR_INFO) ? hw_info+i : NULL;
  } /* get_hwinfo */
@@@ -504,7 -504,8 +504,8 @@@ static int try_io_port(struct pcmcia_de
            link->io.BasePort1 = j ^ 0x300;
            link->io.BasePort2 = (j ^ 0x300) + 0x10;
            ret = pcmcia_request_io(link, &link->io);
-           if (ret == CS_SUCCESS) return ret;
+           if (ret == 0)
+                   return ret;
        }
        return ret;
      } else {
      }
  }
  
+ static int pcnet_confcheck(struct pcmcia_device *p_dev,
+                          cistpl_cftable_entry_t *cfg,
+                          cistpl_cftable_entry_t *dflt,
+                          unsigned int vcc,
+                          void *priv_data)
+ {
+       int *has_shmem = priv_data;
+       int i;
+       cistpl_io_t *io = &cfg->io;
+       if (cfg->index == 0 || cfg->io.nwin == 0)
+               return -EINVAL;
+       /* For multifunction cards, by convention, we configure the
+          network function with window 0, and serial with window 1 */
+       if (io->nwin > 1) {
+               i = (io->win[1].len > io->win[0].len);
+               p_dev->io.BasePort2 = io->win[1-i].base;
+               p_dev->io.NumPorts2 = io->win[1-i].len;
+       } else {
+               i = p_dev->io.NumPorts2 = 0;
+       }
+       *has_shmem = ((cfg->mem.nwin == 1) &&
+                     (cfg->mem.win[0].len >= 0x4000));
+       p_dev->io.BasePort1 = io->win[i].base;
+       p_dev->io.NumPorts1 = io->win[i].len;
+       p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+       if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
+               return try_io_port(p_dev);
+       return 0;
+ }
  static int pcnet_config(struct pcmcia_device *link)
  {
      struct net_device *dev = link->priv;
      pcnet_dev_t *info = PRIV(dev);
-     tuple_t tuple;
-     cisparse_t parse;
-     int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
+     int last_ret, last_fn, start_pg, stop_pg, cm_offset;
      int has_shmem = 0;
-     u_short buf[64];
      hw_info_t *local_hw_info;
      DECLARE_MAC_BUF(mac);
  
      DEBUG(0, "pcnet_config(0x%p)\n", link);
  
-     tuple.TupleData = (cisdata_t *)buf;
-     tuple.TupleDataMax = sizeof(buf);
-     tuple.TupleOffset = 0;
-     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-     tuple.Attributes = 0;
-     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-     while (last_ret == CS_SUCCESS) {
-       cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-       cistpl_io_t *io = &(parse.cftable_entry.io);
-       if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
-                       pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
-                       cfg->index == 0 || cfg->io.nwin == 0)
-               goto next_entry;
-       link->conf.ConfigIndex = cfg->index;
-       /* For multifunction cards, by convention, we configure the
-          network function with window 0, and serial with window 1 */
-       if (io->nwin > 1) {
-           i = (io->win[1].len > io->win[0].len);
-           link->io.BasePort2 = io->win[1-i].base;
-           link->io.NumPorts2 = io->win[1-i].len;
-       } else {
-           i = link->io.NumPorts2 = 0;
-       }
-       has_shmem = ((cfg->mem.nwin == 1) &&
-                    (cfg->mem.win[0].len >= 0x4000));
-       link->io.BasePort1 = io->win[i].base;
-       link->io.NumPorts1 = io->win[i].len;
-       link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-       if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
-           last_ret = try_io_port(link);
-           if (last_ret == CS_SUCCESS) break;
-       }
-     next_entry:
-       last_ret = pcmcia_get_next_tuple(link, &tuple);
-     }
-     if (last_ret != CS_SUCCESS) {
+     last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
+     if (last_ret) {
        cs_error(link, RequestIO, last_ret);
        goto failed;
      }
@@@ -1626,7 -1622,6 +1622,7 @@@ static struct pcmcia_device_id pcnet_id
        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-TD", 0x5261440f, 0xc49bd73d),
        PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d),
        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-T", 0x5261440f, 0x6705fcaa),
 +      PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-TD", 0x5261440f, 0x47d5ca83),
        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FastEther PCC-TX", 0x5261440f, 0x485e85d9),
        PCMCIA_DEVICE_PROD_ID12("Corega,K.K.", "Ethernet LAN Card", 0x110d26d9, 0x9fd2f0a2),
        PCMCIA_DEVICE_PROD_ID12("corega,K.K.", "Ethernet LAN Card", 0x9791a90e, 0x9fd2f0a2),
        PCMCIA_DEVICE_PROD_ID1("CyQ've 10 Base-T LAN CARD", 0x94faf360),
        PCMCIA_DEVICE_PROD_ID1("EP-210 PCMCIA LAN CARD.", 0x8850b4de),
        PCMCIA_DEVICE_PROD_ID1("ETHER-C16", 0x06a8514f),
 -      PCMCIA_DEVICE_PROD_ID1("IC-CARD", 0x60cb09a6),
        PCMCIA_DEVICE_PROD_ID1("NE2000 Compatible", 0x75b8ad5a),
        PCMCIA_DEVICE_PROD_ID2("EN-6200P2", 0xa996d078),
        /* too generic! */
index c33a3d523566194a24dfba5289a823bd87217e1a,8366bfc7d28ce78de48d355e7ce814572bc3be10..e1fd585e71315ea15ec07a6ed9b2e675db1df4d2
@@@ -353,7 -353,7 +353,7 @@@ typedef struct local_info_t 
   * Some more prototypes
   */
  static int do_start_xmit(struct sk_buff *skb, struct net_device *dev);
 -static void do_tx_timeout(struct net_device *dev);
 +static void xirc_tx_timeout(struct net_device *dev);
  static void xirc2ps_tx_timeout_task(struct work_struct *work);
  static struct net_device_stats *do_get_stats(struct net_device *dev);
  static void set_addresses(struct net_device *dev);
@@@ -377,7 -377,7 +377,7 @@@ first_tuple(struct pcmcia_device *handl
  
        if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
                        (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
-               err = pcmcia_parse_tuple(handle, tuple, parse);
+               err = pcmcia_parse_tuple(tuple, parse);
        return err;
  }
  
@@@ -388,7 -388,7 +388,7 @@@ next_tuple(struct pcmcia_device *handle
  
        if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
                        (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
-               err = pcmcia_parse_tuple(handle, tuple, parse);
+               err = pcmcia_parse_tuple(tuple, parse);
        return err;
  }
  
@@@ -590,7 -590,7 +590,7 @@@ xirc2ps_probe(struct pcmcia_device *lin
      dev->open = &do_open;
      dev->stop = &do_stop;
  #ifdef HAVE_TX_TIMEOUT
 -    dev->tx_timeout = do_tx_timeout;
 +    dev->tx_timeout = xirc_tx_timeout;
      dev->watchdog_timeo = TX_TIMEOUT;
      INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task);
  #endif
@@@ -715,6 -715,47 +715,47 @@@ has_ce2_string(struct pcmcia_device * p
        return 0;
  }
  
+ static int
+ xirc2ps_config_modem(struct pcmcia_device *p_dev,
+                    cistpl_cftable_entry_t *cf,
+                    cistpl_cftable_entry_t *dflt,
+                    unsigned int vcc,
+                    void *priv_data)
+ {
+       unsigned int ioaddr;
+       if (cf->io.nwin > 0  &&  (cf->io.win[0].base & 0xf) == 8) {
+               for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
+                       p_dev->io.BasePort2 = cf->io.win[0].base;
+                       p_dev->io.BasePort1 = ioaddr;
+                       if (!pcmcia_request_io(p_dev, &p_dev->io))
+                               return 0;
+               }
+       }
+       return -ENODEV;
+ }
+ static int
+ xirc2ps_config_check(struct pcmcia_device *p_dev,
+                    cistpl_cftable_entry_t *cf,
+                    cistpl_cftable_entry_t *dflt,
+                    unsigned int vcc,
+                    void *priv_data)
+ {
+       int *pass = priv_data;
+       if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
+               p_dev->io.BasePort2 = cf->io.win[0].base;
+               p_dev->io.BasePort1 = p_dev->io.BasePort2
+                       + (*pass ? (cf->index & 0x20 ? -24:8)
+                          : (cf->index & 0x20 ?   8:-24));
+               if (!pcmcia_request_io(p_dev, &p_dev->io))
+                       return 0;
+       }
+       return -ENODEV;
+ }
  /****************
   * xirc2ps_config() is scheduled to run after a CARD_INSERTION event
   * is received, to configure the PCMCIA socket, and to make the
@@@ -725,13 -766,12 +766,12 @@@ xirc2ps_config(struct pcmcia_device * l
  {
      struct net_device *dev = link->priv;
      local_info_t *local = netdev_priv(dev);
+     unsigned int ioaddr;
      tuple_t tuple;
      cisparse_t parse;
-     unsigned int ioaddr;
      int err, i;
      u_char buf[64];
      cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
-     cistpl_cftable_entry_t *cf = &parse.cftable_entry;
      DECLARE_MAC_BUF(mac);
  
      local->dingo_ccr = NULL;
            /* Take the Modem IO port from the CIS and scan for a free
             * Ethernet port */
            link->io.NumPorts1 = 16; /* no Mako stuff anymore */
-           tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-           for (err = first_tuple(link, &tuple, &parse); !err;
-                                err = next_tuple(link, &tuple, &parse)) {
-               if (cf->io.nwin > 0  &&  (cf->io.win[0].base & 0xf) == 8) {
-                   for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
-                       link->conf.ConfigIndex = cf->index ;
-                       link->io.BasePort2 = cf->io.win[0].base;
-                       link->io.BasePort1 = ioaddr;
-                       if (!(err=pcmcia_request_io(link, &link->io)))
-                           goto port_found;
-                   }
-               }
-           }
+           if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
+                   goto port_found;
        } else {
            link->io.NumPorts1 = 18;
            /* We do 2 passes here: The first one uses the regular mapping and
             * mirrored every 32 bytes. Actually we use a mirrored port for
             * the Mako if (on the first pass) the COR bit 5 is set.
             */
-           for (pass=0; pass < 2; pass++) {
-               tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-               for (err = first_tuple(link, &tuple, &parse); !err;
-                                    err = next_tuple(link, &tuple, &parse)){
-                   if (cf->io.nwin > 0  &&  (cf->io.win[0].base & 0xf) == 8){
-                       link->conf.ConfigIndex = cf->index ;
-                       link->io.BasePort2 = cf->io.win[0].base;
-                       link->io.BasePort1 = link->io.BasePort2
-                                   + (pass ? (cf->index & 0x20 ? -24:8)
-                                           : (cf->index & 0x20 ?   8:-24));
-                       if (!(err=pcmcia_request_io(link, &link->io)))
+           for (pass=0; pass < 2; pass++)
+                   if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass))
                            goto port_found;
-                   }
-               }
-           }
            /* if special option:
             * try to configure as Ethernet only.
             * .... */
@@@ -1335,7 -1352,7 +1352,7 @@@ xirc2ps_tx_timeout_task(struct work_str
  }
  
  static void
 -do_tx_timeout(struct net_device *dev)
 +xirc_tx_timeout(struct net_device *dev)
  {
      local_info_t *lp = netdev_priv(dev);
      lp->stats.tx_errors++;
index fd72e427cb2830183b729fbae965ee88b5003da2,fac1526e49aa84281f1f1af0acb0919da47cb8ca..27696c20f4c2cf4d8fd10a8abaa41d843fd0974e
@@@ -147,7 -147,7 +147,7 @@@ static int airo_probe(struct pcmcia_dev
        DEBUG(0, "airo_attach()\n");
  
        /* Interrupt setup */
 -      p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
 +      p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
        p_dev->irq.Handler = NULL;
        
@@@ -206,126 -206,123 +206,123 @@@ static void airo_detach(struct pcmcia_d
  #define CS_CHECK(fn, ret) \
  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
  
+ static int airo_cs_config_check(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;
+       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;
+       }
+       /* Use power settings for Vcc and Vpp if present */
+       /*  Note that the CIS values need to be rescaled */
+       if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
+       else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
+       /* 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.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;
+       /*
+         Now set up a common memory window, if needed.  There is room
+         in the struct pcmcia_device structure for one memory window handle,
+         but if the base addresses need to be saved, or if multiple
+         windows are needed, the info should go in the private data
+         structure for this device.
+         Note that the memory window base is a physical address, and
+         needs to be mapped to virtual space with ioremap() before it
+         is used.
+       */
+       if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
+               cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
+               memreq_t map;
+               req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
+               req->Base = mem->win[0].host_addr;
+               req->Size = mem->win[0].len;
+               req->AccessSpeed = 0;
+               if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
+                       return -ENODEV;
+               map.Page = 0;
+               map.CardOffset = mem->win[0].card_addr;
+               if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
+                       return -ENODEV;
+       }
+       /* If we got this far, we're cool! */
+       return 0;
+ }
  static int airo_config(struct pcmcia_device *link)
  {
-       tuple_t tuple;
-       cisparse_t parse;
        local_info_t *dev;
+       win_req_t *req;
        int last_fn, last_ret;
-       u_char buf[64];
-       win_req_t req;
-       memreq_t map;
  
        dev = link->priv;
  
        DEBUG(0, "airo_config(0x%p)\n", link);
  
+       req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
+       if (!req)
+               return -ENOMEM;
+       /*
+        * In this loop, we scan the CIS for configuration table
+        * entries, each of which describes a valid card
+        * configuration, including voltage, IO window, memory window,
+        * and interrupt settings.
+        *
+        * We make no assumptions about the card to be configured: we
+        * use just the information available in the CIS.  In an ideal
+        * world, this would work for any PCMCIA card, but it requires
+        * a complete and accurate CIS.  In practice, a driver usually
+        * "knows" most of these things without consulting the CIS,
+        * and most client drivers will only use the CIS to fill in
+        * implementation-defined details.
+        */
+       last_ret = pcmcia_loop_config(link, airo_cs_config_check, req);
+       if (last_ret)
+               goto failed;
        /*
-         In this loop, we scan the CIS for configuration table entries,
-         each of which describes a valid card configuration, including
-         voltage, IO window, memory window, and interrupt settings.
-         
-         We make no assumptions about the card to be configured: we use
-         just the information available in the CIS.  In an ideal world,
-         this would work for any PCMCIA card, but it requires a complete
-         and accurate CIS.  In practice, a driver usually "knows" most of
-         these things without consulting the CIS, and most client drivers
-         will only use the CIS to fill in implementation-defined details.
+         Allocate an interrupt line.  Note that this does not assign a
+         handler to the interrupt, unless the 'Handler' member of the
+         irq structure is initialized.
        */
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-       while (1) {
-               cistpl_cftable_entry_t dflt = { 0 };
-               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-               if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
-                               pcmcia_parse_tuple(link, &tuple, &parse) != 0)
-                       goto next_entry;
-               
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
-               if (cfg->index == 0) goto next_entry;
-               link->conf.ConfigIndex = cfg->index;
-               
-               /* Does this card need audio output? */
-               if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
-                       link->conf.Attributes |= CONF_ENABLE_SPKR;
-                       link->conf.Status = CCSR_AUDIO_ENA;
-               }
-               
-               /* Use power settings for Vcc and Vpp if present */
-               /*  Note that the CIS values need to be rescaled */
-               if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
-                       link->conf.Vpp =
-                               cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
-               else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
-                       link->conf.Vpp =
-                               dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
-               
-               /* Do we need to allocate an interrupt? */
-               if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
-                       link->conf.Attributes |= CONF_ENABLE_IRQ;
-               
-               /* IO window settings */
-               link->io.NumPorts1 = link->io.NumPorts2 = 0;
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-                       if (!(io->flags & CISTPL_IO_8BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-                       if (!(io->flags & CISTPL_IO_16BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
-                       if (io->nwin > 1) {
-                               link->io.Attributes2 = link->io.Attributes1;
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
-                       }
-               }
-               
-               /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(link, &link->io) != 0)
-                       goto next_entry;
-               
-               /*
-                 Now set up a common memory window, if needed.  There is room
-                 in the struct pcmcia_device structure for one memory window handle,
-                 but if the base addresses need to be saved, or if multiple
-                 windows are needed, the info should go in the private data
-                 structure for this device.
-                 
-                 Note that the memory window base is a physical address, and
-                 needs to be mapped to virtual space with ioremap() before it
-                 is used.
-               */
-               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.Base = mem->win[0].host_addr;
-                       req.Size = mem->win[0].len;
-                       req.AccessSpeed = 0;
-                       if (pcmcia_request_window(&link, &req, &link->win) != 0)
-                               goto next_entry;
-                       map.Page = 0; map.CardOffset = mem->win[0].card_addr;
-                       if (pcmcia_map_mem_page(link->win, &map) != 0)
-                               goto next_entry;
-               }
-               /* If we got this far, we're cool! */
-               break;
-               
-       next_entry:
-               CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
-       }
-       
-     /*
-       Allocate an interrupt line.  Note that this does not assign a
-       handler to the interrupt, unless the 'Handler' member of the
-       irq structure is initialized.
-     */
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
                CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
        
                printk(" & 0x%04x-0x%04x", link->io.BasePort2,
                       link->io.BasePort2+link->io.NumPorts2-1);
        if (link->win)
-               printk(", mem 0x%06lx-0x%06lx", req.Base,
-                      req.Base+req.Size-1);
+               printk(", mem 0x%06lx-0x%06lx", req->Base,
+                      req->Base+req->Size-1);
        printk("\n");
+       kfree(req);
        return 0;
  
   cs_failed:
        cs_error(link, last_fn, last_ret);
+  failed:
        airo_release(link);
+       kfree(req);
        return -ENODEV;
  } /* airo_config */
  
index d2388e8d179a440dce544ec598d857cc3e8b5b5f,4830d51900a3dd7567a9ba447bcf1e4edde33dd1..77406245dc7b8fb171f82802bd8d4e494747f20e
@@@ -158,7 -158,7 +158,7 @@@ static int atmel_probe(struct pcmcia_de
        DEBUG(0, "atmel_attach()\n");
  
        /* Interrupt setup */
 -      p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
 +      p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
        p_dev->irq.Handler = NULL;
  
@@@ -224,13 -224,58 +224,58 @@@ static int card_present(void *arg
        return 0;
  }
  
+ static int atmel_config_check(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;
+       /* 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;
+       }
+       /* Use power settings for Vcc and Vpp if present */
+       /*  Note that the CIS values need to be rescaled */
+       if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
+       else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
+       /* 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.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);
+ }
  static int atmel_config(struct pcmcia_device *link)
  {
-       tuple_t tuple;
-       cisparse_t parse;
        local_info_t *dev;
        int last_fn, last_ret;
-       u_char buf[64];
        struct pcmcia_device_id *did;
  
        dev = link->priv;
  
        DEBUG(0, "atmel_config(0x%p)\n", link);
  
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
        /*
          In this loop, we scan the CIS for configuration table entries,
          each of which describes a valid card configuration, including
          these things without consulting the CIS, and most client drivers
          will only use the CIS to fill in implementation-defined details.
        */
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-       while (1) {
-               cistpl_cftable_entry_t dflt = { 0 };
-               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-               if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
-                               pcmcia_parse_tuple(link, &tuple, &parse) != 0)
-                       goto next_entry;
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
-               if (cfg->index == 0) goto next_entry;
-               link->conf.ConfigIndex = cfg->index;
-               /* Does this card need audio output? */
-               if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
-                       link->conf.Attributes |= CONF_ENABLE_SPKR;
-                       link->conf.Status = CCSR_AUDIO_ENA;
-               }
-               /* Use power settings for Vcc and Vpp if present */
-               /*  Note that the CIS values need to be rescaled */
-               if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
-                       link->conf.Vpp =
-                               cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
-               else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
-                       link->conf.Vpp =
-                               dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
-               /* Do we need to allocate an interrupt? */
-               if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
-                       link->conf.Attributes |= CONF_ENABLE_IRQ;
-               /* IO window settings */
-               link->io.NumPorts1 = link->io.NumPorts2 = 0;
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-                       if (!(io->flags & CISTPL_IO_8BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-                       if (!(io->flags & CISTPL_IO_16BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
-                       if (io->nwin > 1) {
-                               link->io.Attributes2 = link->io.Attributes1;
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
-                       }
-               }
-               /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(link, &link->io) != 0)
-                       goto next_entry;
-               /* If we got this far, we're cool! */
-               break;
-       next_entry:
-               CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
-       }
+       if (pcmcia_loop_config(link, atmel_config_check, NULL))
+               goto failed;
  
        /*
          Allocate an interrupt line.  Note that this does not assign a
  
   cs_failed:
        cs_error(link, last_fn, last_ret);
+  failed:
        atmel_release(link);
        return -ENODEV;
  }
index e3505c110af696f2bd81ae32983c7f9e52b03762,e2fe2d677324418f33c3ac6820be79f22665d6d7..842a08d1f1063427a1550062c436b62e2fde8701
@@@ -595,7 -595,7 +595,7 @@@ static int if_cs_prog_helper(struct if_
                if (ret < 0) {
                        lbs_pr_err("can't download helper at 0x%x, ret %d\n",
                                sent, ret);
 -                      goto done;
 +                      goto err_release;
                }
  
                if (count == 0)
                sent += count;
        }
  
 +err_release:
        release_firmware(fw);
 -      ret = 0;
 -
  done:
        lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
        return ret;
@@@ -675,8 -676,14 +675,8 @@@ static int if_cs_prog_real(struct if_cs
        }
  
        ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a);
 -      if (ret < 0) {
 +      if (ret < 0)
                lbs_pr_err("firmware download failed\n");
 -              goto err_release;
 -      }
 -
 -      ret = 0;
 -      goto done;
 -
  
  err_release:
        release_firmware(fw);
@@@ -713,7 -720,7 +713,7 @@@ static int if_cs_host_to_card(struct lb
                ret = if_cs_send_cmd(priv, buf, nb);
                break;
        default:
 -              lbs_pr_err("%s: unsupported type %d\n", __FUNCTION__, type);
 +              lbs_pr_err("%s: unsupported type %d\n", __func__, type);
        }
  
        lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
@@@ -791,7 -798,7 +791,7 @@@ static int if_cs_probe(struct pcmcia_de
        tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
        if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 ||
            (ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 ||
-           (ret = pcmcia_parse_tuple(p_dev, &tuple, &parse)) != 0)
+           (ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
        {
                lbs_pr_err("error in pcmcia_get_first_tuple etc\n");
                goto out1;
index 25bae7933aa587fa22ba5b4b402c80011f3f49bf,bf2dd1057928de77c7d45a328ff2e2b81ab2ecea..a670f36b5f3f3c1e3222d0e45c27491132caed7d
@@@ -398,7 -398,7 +398,7 @@@ static int netwave_probe(struct pcmcia_
      link->io.IOAddrLines = 5;
      
      /* Interrupt setup */
 -    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
 +    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
      link->irq.IRQInfo1 = IRQ_LEVEL_ID;
      link->irq.Handler = &netwave_interrupt;
      
@@@ -749,9 -749,10 +749,10 @@@ static int netwave_pcmcia_config(struc
      for (i = j = 0x0; j < 0x400; j += 0x20) {
        link->io.BasePort1 = j ^ 0x300;
        i = pcmcia_request_io(link, &link->io);
-       if (i == CS_SUCCESS) break;
+       if (i == 0)
+               break;
      }
-     if (i != CS_SUCCESS) {
+     if (i != 0) {
        cs_error(link, RequestIO, i);
        goto failed;
      }
index 9eaa252c2430b441bf6671a9a9a354ad9bbe4c0d,f8d9de2fb4cf5decc3f842b7fe7ba7adc6da680f..e585684e59a00012025c1e10990c979a8f0bf0eb
@@@ -80,7 -80,7 +80,7 @@@ orinoco_cs_hard_reset(struct orinoco_pr
        /* We need atomic ops here, because we're not holding the lock */
        set_bit(0, &card->hard_reset_in_progress);
  
-       err = pcmcia_reset_card(link, NULL);
+       err = pcmcia_reset_card(link->socket);
        if (err)
                return err;
  
@@@ -109,8 -109,7 +109,8 @@@ orinoco_cs_probe(struct pcmcia_device *
        struct orinoco_private *priv;
        struct orinoco_pccard *card;
  
 -      dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
 +      dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
 +                             orinoco_cs_hard_reset, NULL);
        if (! dev)
                return -ENOMEM;
        priv = netdev_priv(dev);
        link->priv = dev;
  
        /* Interrupt setup */
 -      link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
 +      link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
        link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->irq.Handler = orinoco_interrupt;
        link->irq.Instance = dev; 
@@@ -165,6 -164,70 +165,70 @@@ static void orinoco_cs_detach(struct pc
                last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
        } while (0)
  
+ static int orinoco_cs_config_check(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)
+               goto next_entry;
+       /* Use power settings for Vcc and Vpp if present */
+       /* Note that the CIS values need to be rescaled */
+       if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+               if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
+                       if (!ignore_cis_vcc)
+                               goto next_entry;
+               }
+       } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+               if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
+                       if (!ignore_cis_vcc)
+                               goto next_entry;
+               }
+       }
+       if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp =
+                       cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+       else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp =
+                       dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+       /* Do we need to allocate an interrupt? */
+       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)
+                       goto next_entry;
+       }
+       return 0;
+ next_entry:
+       pcmcia_disable_device(p_dev);
+       return -ENODEV;
+ };
  static int
  orinoco_cs_config(struct pcmcia_device *link)
  {
        struct orinoco_pccard *card = priv->card;
        hermes_t *hw = &priv->hw;
        int last_fn, last_ret;
-       u_char buf[64];
-       config_info_t conf;
-       tuple_t tuple;
-       cisparse_t parse;
        void __iomem *mem;
  
-       /* Look up the current Vcc */
-       CS_CHECK(GetConfigurationInfo,
-                pcmcia_get_configuration_info(link, &conf));
        /*
         * In this loop, we scan the CIS for configuration table
         * entries, each of which describes a valid card
         * and most client drivers will only use the CIS to fill in
         * implementation-defined details.
         */
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-       while (1) {
-               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-               cistpl_cftable_entry_t dflt = { .index = 0 };
-               if ( (pcmcia_get_tuple_data(link, &tuple) != 0)
-                   || (pcmcia_parse_tuple(link, &tuple, &parse) != 0))
-                       goto next_entry;
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-                       dflt = *cfg;
-               if (cfg->index == 0)
-                       goto next_entry;
-               link->conf.ConfigIndex = cfg->index;
-               /* Use power settings for Vcc and Vpp if present */
-               /* Note that the CIS values need to be rescaled */
-               if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
-                       if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
-                               DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, cfg CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
-                               if (!ignore_cis_vcc)
-                                       goto next_entry;
-                       }
-               } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
-                       if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
-                               DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, dflt CIS = %d)\n",  conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
-                               if(!ignore_cis_vcc)
-                                       goto next_entry;
-                       }
-               }
-               if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
-                       link->conf.Vpp =
-                           cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-               else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
-                       link->conf.Vpp =
-                           dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
-               
-               /* Do we need to allocate an interrupt? */
-               link->conf.Attributes |= CONF_ENABLE_IRQ;
-               /* IO window settings */
-               link->io.NumPorts1 = link->io.NumPorts2 = 0;
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io =
-                           (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-                       if (!(io->flags & CISTPL_IO_8BIT))
-                               link->io.Attributes1 =
-                                   IO_DATA_PATH_WIDTH_16;
-                       if (!(io->flags & CISTPL_IO_16BIT))
-                               link->io.Attributes1 =
-                                   IO_DATA_PATH_WIDTH_8;
-                       link->io.IOAddrLines =
-                           io->flags & CISTPL_IO_LINES_MASK;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
-                       if (io->nwin > 1) {
-                               link->io.Attributes2 =
-                                   link->io.Attributes1;
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
-                       }
-                       /* This reserves IO space but doesn't actually enable it */
-                       if (pcmcia_request_io(link, &link->io) != 0)
-                               goto next_entry;
-               }
-               /* If we got this far, we're cool! */
-               break;
-               
-       next_entry:
-               pcmcia_disable_device(link);
-               last_ret = pcmcia_get_next_tuple(link, &tuple);
-               if (last_ret  == CS_NO_MORE_ITEMS) {
+       last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
+       if (last_ret) {
+               if (!ignore_cis_vcc)
                        printk(KERN_ERR PFX "GetNextTuple(): No matching "
                               "CIS configuration.  Maybe you need the "
                               "ignore_cis_vcc=1 parameter.\n");
-                       goto cs_failed;
-               }
+               cs_error(link, RequestIO, last_ret);
+               goto failed;
        }
  
        /*
               "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id,
               link->irq.AssignedIRQ, link->io.BasePort1,
               link->io.BasePort1 + link->io.NumPorts1 - 1);
        return 0;
  
   cs_failed:
index 44da0d19b5c8d9c0ed8a96d5996e88c5d2b452fe,99c7c8bc25732e5a370a7474dd704262dc1bdfc7..1404a57175207f71d39ac28b12ad78651610d0c1
@@@ -325,7 -325,7 +325,7 @@@ static int ray_probe(struct pcmcia_devi
      p_dev->io.IOAddrLines = 5;
  
      /* Interrupt setup. For PCMCIA, driver takes what's given */
 -    p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
 +    p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
      p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
      p_dev->irq.Handler = &ray_interrupt;
  
@@@ -798,9 -798,9 +798,9 @@@ static void ray_release(struct pcmcia_d
      iounmap(local->amem);
      /* Do bother checking to see if these succeed or not */
      i = pcmcia_release_window(local->amem_handle);
-     if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
+     if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
      i = pcmcia_release_window(local->rmem_handle);
-     if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
+     if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
      pcmcia_disable_device(link);
  
      DEBUG(2,"ray_release ending\n");
index 67b26d3c3cd50548a1b4639ffb949b4345a98906,d7e9d9c3042cb51dad9dad2c50d283f426814b7a..b0c71c3be46769f3f08318c2bb81e51dee195f87
@@@ -25,6 -25,7 +25,6 @@@
  #include <linux/kernel.h>
  #include <linux/init.h>
  #include <linux/delay.h>
 -#include <linux/firmware.h>
  #include <pcmcia/cs_types.h>
  #include <pcmcia/cs.h>
  #include <pcmcia/cistpl.h>
@@@ -33,6 -34,9 +33,6 @@@
  
  #include "orinoco.h"
  
 -static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
 -static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
 -
  /********************************************************************/
  /* Module stuff                                                           */
  /********************************************************************/
@@@ -67,11 -71,161 +67,11 @@@ struct orinoco_pccard 
  static int spectrum_cs_config(struct pcmcia_device *link);
  static void spectrum_cs_release(struct pcmcia_device *link);
  
 -/********************************************************************/
 -/* Firmware downloader                                                    */
 -/********************************************************************/
 -
 -/* Position of PDA in the adapter memory */
 -#define EEPROM_ADDR   0x3000
 -#define EEPROM_LEN    0x200
 -#define PDA_OFFSET    0x100
 -
 -#define PDA_ADDR      (EEPROM_ADDR + PDA_OFFSET)
 -#define PDA_WORDS     ((EEPROM_LEN - PDA_OFFSET) / 2)
 -
  /* Constants for the CISREG_CCSR register */
  #define HCR_RUN               0x07    /* run firmware after reset */
  #define HCR_IDLE      0x0E    /* don't run firmware after reset */
  #define HCR_MEM16     0x10    /* memory width bit, should be preserved */
  
 -/*
 - * AUX port access.  To unlock the AUX port write the access keys to the
 - * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
 - * register.  Then read it and make sure it's HERMES_AUX_ENABLED.
 - */
 -#define HERMES_AUX_ENABLE     0x8000  /* Enable auxiliary port access */
 -#define HERMES_AUX_DISABLE    0x4000  /* Disable to auxiliary port access */
 -#define HERMES_AUX_ENABLED    0xC000  /* Auxiliary port is open */
 -
 -#define HERMES_AUX_PW0        0xFE01
 -#define HERMES_AUX_PW1        0xDC23
 -#define HERMES_AUX_PW2        0xBA45
 -
 -/* End markers */
 -#define PDI_END               0x00000000      /* End of PDA */
 -#define BLOCK_END     0xFFFFFFFF      /* Last image block */
 -#define TEXT_END      0x1A            /* End of text header */
 -
 -/*
 - * The following structures have little-endian fields denoted by
 - * the leading underscore.  Don't access them directly - use inline
 - * functions defined below.
 - */
 -
 -/*
 - * The binary image to be downloaded consists of series of data blocks.
 - * Each block has the following structure.
 - */
 -struct dblock {
 -      __le32 addr;            /* adapter address where to write the block */
 -      __le16 len;             /* length of the data only, in bytes */
 -      char data[0];           /* data to be written */
 -} __attribute__ ((packed));
 -
 -/*
 - * Plug Data References are located in in the image after the last data
 - * block.  They refer to areas in the adapter memory where the plug data
 - * items with matching ID should be written.
 - */
 -struct pdr {
 -      __le32 id;              /* record ID */
 -      __le32 addr;            /* adapter address where to write the data */
 -      __le32 len;             /* expected length of the data, in bytes */
 -      char next[0];           /* next PDR starts here */
 -} __attribute__ ((packed));
 -
 -
 -/*
 - * Plug Data Items are located in the EEPROM read from the adapter by
 - * primary firmware.  They refer to the device-specific data that should
 - * be plugged into the secondary firmware.
 - */
 -struct pdi {
 -      __le16 len;             /* length of ID and data, in words */
 -      __le16 id;              /* record ID */
 -      char data[0];           /* plug data */
 -} __attribute__ ((packed));
 -
 -
 -/* Functions for access to little-endian data */
 -static inline u32
 -dblock_addr(const struct dblock *blk)
 -{
 -      return le32_to_cpu(blk->addr);
 -}
 -
 -static inline u32
 -dblock_len(const struct dblock *blk)
 -{
 -      return le16_to_cpu(blk->len);
 -}
 -
 -static inline u32
 -pdr_id(const struct pdr *pdr)
 -{
 -      return le32_to_cpu(pdr->id);
 -}
 -
 -static inline u32
 -pdr_addr(const struct pdr *pdr)
 -{
 -      return le32_to_cpu(pdr->addr);
 -}
 -
 -static inline u32
 -pdr_len(const struct pdr *pdr)
 -{
 -      return le32_to_cpu(pdr->len);
 -}
 -
 -static inline u32
 -pdi_id(const struct pdi *pdi)
 -{
 -      return le16_to_cpu(pdi->id);
 -}
 -
 -/* Return length of the data only, in bytes */
 -static inline u32
 -pdi_len(const struct pdi *pdi)
 -{
 -      return 2 * (le16_to_cpu(pdi->len) - 1);
 -}
 -
 -
 -/* Set address of the auxiliary port */
 -static inline void
 -spectrum_aux_setaddr(hermes_t *hw, u32 addr)
 -{
 -      hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
 -      hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
 -}
 -
 -
 -/* Open access to the auxiliary port */
 -static int
 -spectrum_aux_open(hermes_t *hw)
 -{
 -      int i;
 -
 -      /* Already open? */
 -      if (hermes_read_reg(hw, HERMES_CONTROL) == HERMES_AUX_ENABLED)
 -              return 0;
 -
 -      hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
 -      hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
 -      hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
 -      hermes_write_reg(hw, HERMES_CONTROL, HERMES_AUX_ENABLE);
 -
 -      for (i = 0; i < 20; i++) {
 -              udelay(10);
 -              if (hermes_read_reg(hw, HERMES_CONTROL) ==
 -                  HERMES_AUX_ENABLED)
 -                      return 0;
 -      }
 -
 -      return -EBUSY;
 -}
 -
  
  #define CS_CHECK(fn, ret) \
    do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
@@@ -138,29 -292,275 +138,29 @@@ spectrum_reset(struct pcmcia_device *li
        return -ENODEV;
  }
  
 +/********************************************************************/
 +/* Device methods                                                         */
 +/********************************************************************/
  
 -/*
 - * Scan PDR for the record with the specified RECORD_ID.
 - * If it's not found, return NULL.
 - */
 -static struct pdr *
 -spectrum_find_pdr(struct pdr *first_pdr, u32 record_id)
 -{
 -      struct pdr *pdr = first_pdr;
 -
 -      while (pdr_id(pdr) != PDI_END) {
 -              /*
 -               * PDR area is currently not terminated by PDI_END.
 -               * It's followed by CRC records, which have the type
 -               * field where PDR has length.  The type can be 0 or 1.
 -               */
 -              if (pdr_len(pdr) < 2)
 -                      return NULL;
 -
 -              /* If the record ID matches, we are done */
 -              if (pdr_id(pdr) == record_id)
 -                      return pdr;
 -
 -              pdr = (struct pdr *) pdr->next;
 -      }
 -      return NULL;
 -}
 -
 -
 -/* Process one Plug Data Item - find corresponding PDR and plug it */
 -static int
 -spectrum_plug_pdi(hermes_t *hw, struct pdr *first_pdr, struct pdi *pdi)
 -{
 -      struct pdr *pdr;
 -
 -      /* Find the PDI corresponding to this PDR */
 -      pdr = spectrum_find_pdr(first_pdr, pdi_id(pdi));
 -
 -      /* No match is found, safe to ignore */
 -      if (!pdr)
 -              return 0;
 -
 -      /* Lengths of the data in PDI and PDR must match */
 -      if (pdi_len(pdi) != pdr_len(pdr))
 -              return -EINVAL;
 -
 -      /* do the actual plugging */
 -      spectrum_aux_setaddr(hw, pdr_addr(pdr));
 -      hermes_write_bytes(hw, HERMES_AUXDATA, pdi->data, pdi_len(pdi));
 -
 -      return 0;
 -}
 -
 -
 -/* Read PDA from the adapter */
 -static int
 -spectrum_read_pda(hermes_t *hw, __le16 *pda, int pda_len)
 -{
 -      int ret;
 -      int pda_size;
 -
 -      /* Issue command to read EEPROM */
 -      ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
 -      if (ret)
 -              return ret;
 -
 -      /* Open auxiliary port */
 -      ret = spectrum_aux_open(hw);
 -      if (ret)
 -              return ret;
 -
 -      /* read PDA from EEPROM */
 -      spectrum_aux_setaddr(hw, PDA_ADDR);
 -      hermes_read_words(hw, HERMES_AUXDATA, pda, pda_len / 2);
 -
 -      /* Check PDA length */
 -      pda_size = le16_to_cpu(pda[0]);
 -      if (pda_size > pda_len)
 -              return -EINVAL;
 -
 -      return 0;
 -}
 -
 -
 -/* Parse PDA and write the records into the adapter */
 -static int
 -spectrum_apply_pda(hermes_t *hw, const struct dblock *first_block,
 -                 __le16 *pda)
 -{
 -      int ret;
 -      struct pdi *pdi;
 -      struct pdr *first_pdr;
 -      const struct dblock *blk = first_block;
 -
 -      /* Skip all blocks to locate Plug Data References */
 -      while (dblock_addr(blk) != BLOCK_END)
 -              blk = (struct dblock *) &blk->data[dblock_len(blk)];
 -
 -      first_pdr = (struct pdr *) blk;
 -
 -      /* Go through every PDI and plug them into the adapter */
 -      pdi = (struct pdi *) (pda + 2);
 -      while (pdi_id(pdi) != PDI_END) {
 -              ret = spectrum_plug_pdi(hw, first_pdr, pdi);
 -              if (ret)
 -                      return ret;
 -
 -              /* Increment to the next PDI */
 -              pdi = (struct pdi *) &pdi->data[pdi_len(pdi)];
 -      }
 -      return 0;
 -}
 -
 -
 -/* Load firmware blocks into the adapter */
 -static int
 -spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block)
 -{
 -      const struct dblock *blk;
 -      u32 blkaddr;
 -      u32 blklen;
 -
 -      blk = first_block;
 -      blkaddr = dblock_addr(blk);
 -      blklen = dblock_len(blk);
 -
 -      while (dblock_addr(blk) != BLOCK_END) {
 -              spectrum_aux_setaddr(hw, blkaddr);
 -              hermes_write_bytes(hw, HERMES_AUXDATA, blk->data,
 -                                 blklen);
 -
 -              blk = (struct dblock *) &blk->data[blklen];
 -              blkaddr = dblock_addr(blk);
 -              blklen = dblock_len(blk);
 -      }
 -      return 0;
 -}
 -
 -
 -/*
 - * Process a firmware image - stop the card, load the firmware, reset
 - * the card and make sure it responds.  For the secondary firmware take
 - * care of the PDA - read it and then write it on top of the firmware.
 - */
  static int
 -spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
 -                const unsigned char *image, int secondary)
 +spectrum_cs_hard_reset(struct orinoco_private *priv)
  {
 -      int ret;
 -      const unsigned char *ptr;
 -      const struct dblock *first_block;
 -
 -      /* Plug Data Area (PDA) */
 -      __le16 pda[PDA_WORDS];
 -
 -      /* Binary block begins after the 0x1A marker */
 -      ptr = image;
 -      while (*ptr++ != TEXT_END);
 -      first_block = (const struct dblock *) ptr;
 -
 -      /* Read the PDA */
 -      if (secondary) {
 -              ret = spectrum_read_pda(hw, pda, sizeof(pda));
 -              if (ret)
 -                      return ret;
 -      }
 -
 -      /* Stop the firmware, so that it can be safely rewritten */
 -      ret = spectrum_reset(link, 1);
 -      if (ret)
 -              return ret;
 -
 -      /* Program the adapter with new firmware */
 -      ret = spectrum_load_blocks(hw, first_block);
 -      if (ret)
 -              return ret;
 -
 -      /* Write the PDA to the adapter */
 -      if (secondary) {
 -              ret = spectrum_apply_pda(hw, first_block, pda);
 -              if (ret)
 -                      return ret;
 -      }
 -
 -      /* Run the firmware */
 -      ret = spectrum_reset(link, 0);
 -      if (ret)
 -              return ret;
 -
 -      /* Reset hermes chip and make sure it responds */
 -      ret = hermes_init(hw);
 -
 -      /* hermes_reset() should return 0 with the secondary firmware */
 -      if (secondary && ret != 0)
 -              return -ENODEV;
 +      struct orinoco_pccard *card = priv->card;
 +      struct pcmcia_device *link = card->p_dev;
  
 -      /* And this should work with any firmware */
 -      if (!hermes_present(hw))
 -              return -ENODEV;
 +      /* Soft reset using COR and HCR */
 +      spectrum_reset(link, 0);
  
        return 0;
  }
  
 -
 -/*
 - * Download the firmware into the card, this also does a PCMCIA soft
 - * reset on the card, to make sure it's in a sane state.
 - */
  static int
 -spectrum_dl_firmware(hermes_t *hw, struct pcmcia_device *link)
 -{
 -      int ret;
 -      const struct firmware *fw_entry;
 -
 -      if (request_firmware(&fw_entry, primary_fw_name,
 -                           &handle_to_dev(link)) != 0) {
 -              printk(KERN_ERR PFX "Cannot find firmware: %s\n",
 -                     primary_fw_name);
 -              return -ENOENT;
 -      }
 -
 -      /* Load primary firmware */
 -      ret = spectrum_dl_image(hw, link, fw_entry->data, 0);
 -      release_firmware(fw_entry);
 -      if (ret) {
 -              printk(KERN_ERR PFX "Primary firmware download failed\n");
 -              return ret;
 -      }
 -
 -      if (request_firmware(&fw_entry, secondary_fw_name,
 -                           &handle_to_dev(link)) != 0) {
 -              printk(KERN_ERR PFX "Cannot find firmware: %s\n",
 -                     secondary_fw_name);
 -              return -ENOENT;
 -      }
 -
 -      /* Load secondary firmware */
 -      ret = spectrum_dl_image(hw, link, fw_entry->data, 1);
 -      release_firmware(fw_entry);
 -      if (ret) {
 -              printk(KERN_ERR PFX "Secondary firmware download failed\n");
 -      }
 -
 -      return ret;
 -}
 -
 -/********************************************************************/
 -/* Device methods                                                         */
 -/********************************************************************/
 -
 -static int
 -spectrum_cs_hard_reset(struct orinoco_private *priv)
 +spectrum_cs_stop_firmware(struct orinoco_private *priv, int idle)
  {
        struct orinoco_pccard *card = priv->card;
        struct pcmcia_device *link = card->p_dev;
 -      int err;
  
 -      if (!hermes_present(&priv->hw)) {
 -              /* The firmware needs to be reloaded */
 -              if (spectrum_dl_firmware(&priv->hw, link) != 0) {
 -                      printk(KERN_ERR PFX "Firmware download failed\n");
 -                      err = -ENODEV;
 -              }
 -      } else {
 -              /* Soft reset using COR and HCR */
 -              spectrum_reset(link, 0);
 -      }
 -
 -      return 0;
 +      return spectrum_reset(link, idle);
  }
  
  /********************************************************************/
@@@ -182,9 -582,7 +182,9 @@@ spectrum_cs_probe(struct pcmcia_device 
        struct orinoco_private *priv;
        struct orinoco_pccard *card;
  
 -      dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
 +      dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
 +                             spectrum_cs_hard_reset,
 +                             spectrum_cs_stop_firmware);
        if (! dev)
                return -ENOMEM;
        priv = netdev_priv(dev);
        link->priv = dev;
  
        /* Interrupt setup */
 -      link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
 +      link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
        link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->irq.Handler = orinoco_interrupt;
        link->irq.Instance = dev; 
@@@ -235,6 -633,70 +235,70 @@@ static void spectrum_cs_detach(struct p
   * device available to the system.
   */
  
+ static int spectrum_cs_config_check(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)
+               goto next_entry;
+       /* Use power settings for Vcc and Vpp if present */
+       /* Note that the CIS values need to be rescaled */
+       if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+               if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
+                       if (!ignore_cis_vcc)
+                               goto next_entry;
+               }
+       } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+               if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
+                       if (!ignore_cis_vcc)
+                               goto next_entry;
+               }
+       }
+       if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp =
+                       cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+       else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp =
+                       dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+       /* Do we need to allocate an interrupt? */
+       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)
+                       goto next_entry;
+       }
+       return 0;
+ next_entry:
+       pcmcia_disable_device(p_dev);
+       return -ENODEV;
+ };
  static int
  spectrum_cs_config(struct pcmcia_device *link)
  {
        struct orinoco_pccard *card = priv->card;
        hermes_t *hw = &priv->hw;
        int last_fn, last_ret;
-       u_char buf[64];
-       config_info_t conf;
-       tuple_t tuple;
-       cisparse_t parse;
        void __iomem *mem;
  
-       /* Look up the current Vcc */
-       CS_CHECK(GetConfigurationInfo,
-                pcmcia_get_configuration_info(link, &conf));
        /*
         * In this loop, we scan the CIS for configuration table
         * entries, each of which describes a valid card
         * and most client drivers will only use the CIS to fill in
         * implementation-defined details.
         */
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-       while (1) {
-               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-               cistpl_cftable_entry_t dflt = { .index = 0 };
-               if ( (pcmcia_get_tuple_data(link, &tuple) != 0)
-                   || (pcmcia_parse_tuple(link, &tuple, &parse) != 0))
-                       goto next_entry;
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-                       dflt = *cfg;
-               if (cfg->index == 0)
-                       goto next_entry;
-               link->conf.ConfigIndex = cfg->index;
-               /* Use power settings for Vcc and Vpp if present */
-               /* Note that the CIS values need to be rescaled */
-               if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
-                       if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
-                               DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
-                               if (!ignore_cis_vcc)
-                                       goto next_entry;
-                       }
-               } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
-                       if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
-                               DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
-                               if(!ignore_cis_vcc)
-                                       goto next_entry;
-                       }
-               }
-               if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
-                       link->conf.Vpp =
-                           cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-               else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
-                       link->conf.Vpp =
-                           dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
-               
-               /* Do we need to allocate an interrupt? */
-               link->conf.Attributes |= CONF_ENABLE_IRQ;
-               /* IO window settings */
-               link->io.NumPorts1 = link->io.NumPorts2 = 0;
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io =
-                           (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-                       if (!(io->flags & CISTPL_IO_8BIT))
-                               link->io.Attributes1 =
-                                   IO_DATA_PATH_WIDTH_16;
-                       if (!(io->flags & CISTPL_IO_16BIT))
-                               link->io.Attributes1 =
-                                   IO_DATA_PATH_WIDTH_8;
-                       link->io.IOAddrLines =
-                           io->flags & CISTPL_IO_LINES_MASK;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
-                       if (io->nwin > 1) {
-                               link->io.Attributes2 =
-                                   link->io.Attributes1;
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
-                       }
-                       /* This reserves IO space but doesn't actually enable it */
-                       if (pcmcia_request_io(link, &link->io) != 0)
-                               goto next_entry;
-               }
-               /* If we got this far, we're cool! */
-               break;
-               
-       next_entry:
-               pcmcia_disable_device(link);
-               last_ret = pcmcia_get_next_tuple(link, &tuple);
-               if (last_ret  == CS_NO_MORE_ITEMS) {
+       last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
+       if (last_ret) {
+               if (!ignore_cis_vcc)
                        printk(KERN_ERR PFX "GetNextTuple(): No matching "
                               "CIS configuration.  Maybe you need the "
                               "ignore_cis_vcc=1 parameter.\n");
-                       goto cs_failed;
-               }
+               cs_error(link, RequestIO, last_ret);
+               goto failed;
        }
  
        /*
        dev->irq = link->irq.AssignedIRQ;
        card->node.major = card->node.minor = 0;
  
 -      /* Reset card and download firmware */
 +      /* Reset card */
        if (spectrum_cs_hard_reset(priv) != 0) {
                goto failed;
        }
index b5de38a9b791bd3611678051e8d26d1d252e627b,fee9a02505343d4e0e8e1fd68abc953a79e5c2ed..e124b1d6267afa03cc5e3c149d8ab77080159b2c
@@@ -1412,6 -1412,9 +1412,6 @@@ wavelan_set_multicast_list(struct net_d
          lp->mc_count = 0;
  
          wv_82593_reconfig(dev);
 -
 -        /* Tell the kernel that we are doing a really bad job... */
 -        dev->flags |= IFF_PROMISC;
        }
      }
    else
            lp->mc_count = 0;
  
            wv_82593_reconfig(dev);
 -
 -          /* Tell the kernel that we are doing a really bad job... */
 -          dev->flags |= IFF_ALLMULTI;
          }
        }
      else
@@@ -3702,7 -3708,7 +3702,7 @@@ wv_pcmcia_reset(struct net_device *     dev
  #endif
  
    i = pcmcia_access_configuration_register(link, &reg);
-   if(i != CS_SUCCESS)
+   if (i != 0)
      {
        cs_error(link, AccessConfigurationRegister, i);
        return FALSE;
    reg.Action = CS_WRITE;
    reg.Value = reg.Value | COR_SW_RESET;
    i = pcmcia_access_configuration_register(link, &reg);
-   if(i != CS_SUCCESS)
+   if (i != 0)
      {
        cs_error(link, AccessConfigurationRegister, i);
        return FALSE;
    reg.Action = CS_WRITE;
    reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
    i = pcmcia_access_configuration_register(link, &reg);
-   if(i != CS_SUCCESS)
+   if (i != 0)
      {
        cs_error(link, AccessConfigurationRegister, i);
        return FALSE;
@@@ -3903,7 -3909,7 +3903,7 @@@ wv_pcmcia_config(struct pcmcia_device 
    do
      {
        i = pcmcia_request_io(link, &link->io);
-       if(i != CS_SUCCESS)
+       if (i != 0)
        {
          cs_error(link, RequestIO, i);
          break;
         * actually assign a handler to the interrupt.
         */
        i = pcmcia_request_irq(link, &link->irq);
-       if(i != CS_SUCCESS)
+       if (i != 0)
        {
          cs_error(link, RequestIRQ, i);
          break;
         */
        link->conf.ConfigIndex = 1;
        i = pcmcia_request_configuration(link, &link->conf);
-       if(i != CS_SUCCESS)
+       if (i != 0)
        {
          cs_error(link, RequestConfiguration, i);
          break;
        req.Base = req.Size = 0;
        req.AccessSpeed = mem_speed;
        i = pcmcia_request_window(&link, &req, &link->win);
-       if(i != CS_SUCCESS)
+       if (i != 0)
        {
          cs_error(link, RequestWindow, i);
          break;
  
        mem.CardOffset = 0; mem.Page = 0;
        i = pcmcia_map_mem_page(link->win, &mem);
-       if(i != CS_SUCCESS)
+       if (i != 0)
        {
          cs_error(link, MapMemPage, i);
          break;
@@@ -4496,7 -4502,7 +4496,7 @@@ wavelan_probe(struct pcmcia_device *p_d
    p_dev->io.IOAddrLines = 3;
  
    /* Interrupt setup */
 -  p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
 +  p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
    p_dev->irq.Handler = wavelan_interrupt;
  
index 74a5ad2f1223cc23c21c7e593a3f42b8ebd3e41f,969f53fd705bcb4b25270715bbafcba574bdd5d3..68789c6e1ce9ac96cb180b7c8a6d798719764294
@@@ -79,7 -79,7 +79,7 @@@ static int pc_debug = PCMCIA_DEBUG
  module_param(pc_debug, int, 0);
  #define dprintk(n, format, args...) \
        { if (pc_debug > (n)) \
 -              printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##args); }
 +              printk(KERN_INFO "%s: " format "\n", __func__ , ##args); }
  #else
  #define dprintk(n, format, args...)
  #endif
@@@ -470,7 -470,7 +470,7 @@@ static int wl3501_pwr_mgmt(struct wl350
                        spin_unlock_irqrestore(&this->lock, flags);
                        rc = wait_event_interruptible(this->wait,
                                this->sig_pwr_mgmt_confirm.status != 255);
 -                      printk(KERN_INFO "%s: %s status=%d\n", __FUNCTION__,
 +                      printk(KERN_INFO "%s: %s status=%d\n", __func__,
                               suspend ? "suspend" : "resume",
                               this->sig_pwr_mgmt_confirm.status);
                        goto out;
@@@ -1199,7 -1199,7 +1199,7 @@@ static int wl3501_reset_board(struct wl
                }
                WL3501_NOPLOOP(10);
        }
 -      printk(KERN_WARNING "%s: failed to reset the board!\n", __FUNCTION__);
 +      printk(KERN_WARNING "%s: failed to reset the board!\n", __func__);
        rc = -ENODEV;
  out:
        return rc;
@@@ -1250,7 -1250,7 +1250,7 @@@ static int wl3501_init_firmware(struct 
  out:
        return rc;
  fail:
 -      printk(KERN_WARNING "%s: failed!\n", __FUNCTION__);
 +      printk(KERN_WARNING "%s: failed!\n", __func__);
        goto out;
  }
  
@@@ -1917,7 -1917,7 +1917,7 @@@ static int wl3501_probe(struct pcmcia_d
        p_dev->io.IOAddrLines   = 5;
  
        /* Interrupt setup */
 -      p_dev->irq.Attributes   = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
 +      p_dev->irq.Attributes   = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
        p_dev->irq.IRQInfo1     = IRQ_LEVEL_ID;
        p_dev->irq.Handler = wl3501_interrupt;
  
@@@ -1977,10 -1977,10 +1977,10 @@@ static int wl3501_config(struct pcmcia_
                link->io.BasePort1 = j;
                link->io.BasePort2 = link->io.BasePort1 + 0x10;
                i = pcmcia_request_io(link, &link->io);
-               if (i == CS_SUCCESS)
+               if (i == 0)
                        break;
        }
-       if (i != CS_SUCCESS) {
+       if (i != 0) {
                cs_error(link, RequestIO, i);
                goto failed;
        }
diff --combined drivers/pcmcia/Makefile
index a87902de8d3b9ec187b66a69c9ea97931577c504,2ea5d46a40334cf812816cd2a1027b5d65a3815d..74d1c906c5d6f61cff812db070ac3bda68e19299
@@@ -2,10 -2,6 +2,6 @@@
  # Makefile for the kernel pcmcia subsystem (c/o David Hinds)
  #
  
- ifeq ($(CONFIG_PCMCIA_DEBUG),y)
- EXTRA_CFLAGS += -DDEBUG
- endif
  pcmcia_core-y                                 += cs.o cistpl.o rsrc_mgr.o socket_sysfs.o
  pcmcia_core-$(CONFIG_CARDBUS)                 += cardbus.o
  obj-$(CONFIG_PCCARD)                          += pcmcia_core.o
@@@ -29,6 -25,7 +25,6 @@@ obj-$(CONFIG_PCMCIA_M8XX)                     += m8xx_pcm
  obj-$(CONFIG_HD64465_PCMCIA)                  += hd64465_ss.o
  obj-$(CONFIG_PCMCIA_SA1100)                   += sa11xx_core.o sa1100_cs.o
  obj-$(CONFIG_PCMCIA_SA1111)                   += sa11xx_core.o sa1111_cs.o
 -obj-$(CONFIG_PCMCIA_PXA2XX)                     += pxa2xx_core.o pxa2xx_cs.o
  obj-$(CONFIG_M32R_PCC)                                += m32r_pcc.o
  obj-$(CONFIG_M32R_CFC)                                += m32r_cfc.o
  obj-$(CONFIG_PCMCIA_AU1X00)                   += au1x00_ss.o
@@@ -67,14 -64,9 +63,14 @@@ sa1100_cs-$(CONFIG_SA1100_H3600)            += sa
  sa1100_cs-$(CONFIG_SA1100_SHANNON)            += sa1100_shannon.o
  sa1100_cs-$(CONFIG_SA1100_SIMPAD)             += sa1100_simpad.o
  
 -pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK)              += pxa2xx_lubbock.o sa1111_generic.o
 -pxa2xx_cs-$(CONFIG_MACH_MAINSTONE)            += pxa2xx_mainstone.o
 -pxa2xx_cs-$(CONFIG_PXA_SHARPSL)                       += pxa2xx_sharpsl.o
 -pxa2xx_cs-$(CONFIG_MACH_ARMCORE)              += pxa2xx_cm_x270.o
 -pxa2xx_cs-$(CONFIG_MACH_PALMTX)               += pxa2xx_palmtx.o
 +pxa2xx_lubbock_cs-y                           += pxa2xx_lubbock.o sa1111_generic.o
 +pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK)             += pxa2xx_lubbock_cs.o
 +pxa2xx-obj-$(CONFIG_MACH_MAINSTONE)           += pxa2xx_mainstone.o
 +pxa2xx-obj-$(CONFIG_PXA_SHARPSL)              += pxa2xx_sharpsl.o
 +pxa2xx-obj-$(CONFIG_MACH_ARMCORE)             += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
 +pxa2xx-obj-$(CONFIG_ARCH_VIPER)                       += pxa2xx_viper.o
 +pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA)           += pxa2xx_trizeps.o
 +pxa2xx-obj-$(CONFIG_MACH_PALMTX)              += pxa2xx_palmtx.o
 +pxa2xx-obj-$(CONFIG_MACH_PALMLD)              += pxa2xx_palmld.o
  
 +obj-$(CONFIG_PCMCIA_PXA2XX)                   += pxa2xx_core.o $(pxa2xx-obj-y)
diff --combined drivers/pcmcia/ds.c
index 34c83d3ca0fac69df37ece4e352a99697ae515cd,604249a170c5bb0d079a323f31d71cb545e8f991..7956602554901297f86055cea142707f7eead769
@@@ -32,7 -32,6 +32,6 @@@
  #include <pcmcia/ss.h>
  
  #include "cs_internal.h"
- #include "ds_internal.h"
  
  /*====================================================================*/
  
@@@ -42,17 -41,22 +41,22 @@@ MODULE_AUTHOR("David Hinds <dahinds@use
  MODULE_DESCRIPTION("PCMCIA Driver Services");
  MODULE_LICENSE("GPL");
  
- #ifdef DEBUG
+ #ifdef CONFIG_PCMCIA_DEBUG
  int ds_pc_debug;
  
  module_param_named(pc_debug, ds_pc_debug, int, 0644);
  
  #define ds_dbg(lvl, fmt, arg...) do {                         \
-       if (ds_pc_debug > (lvl))                                        \
+       if (ds_pc_debug > (lvl))                                \
                printk(KERN_DEBUG "ds: " fmt , ## arg);         \
  } while (0)
+ #define ds_dev_dbg(lvl, dev, fmt, arg...) do {                                \
+       if (ds_pc_debug > (lvl))                                        \
+               dev_printk(KERN_DEBUG, dev, "ds: " fmt , ## arg);       \
+ } while (0)
  #else
  #define ds_dbg(lvl, fmt, arg...) do { } while (0)
+ #define ds_dev_dbg(lvl, dev, fmt, arg...) do { } while (0)
  #endif
  
  spinlock_t pcmcia_dev_list_lock;
  /* String tables for error messages */
  
  typedef struct lookup_t {
-     int key;
-     char *msg;
+     const int key;
+     const char *msg;
  } lookup_t;
  
  static const lookup_t error_table[] = {
-     { CS_SUCCESS,             "Operation succeeded" },
-     { CS_BAD_ADAPTER,         "Bad adapter" },
-     { CS_BAD_ATTRIBUTE,       "Bad attribute", },
-     { CS_BAD_BASE,            "Bad base address" },
-     { CS_BAD_EDC,             "Bad EDC" },
-     { CS_BAD_IRQ,             "Bad IRQ" },
-     { CS_BAD_OFFSET,          "Bad offset" },
-     { CS_BAD_PAGE,            "Bad page number" },
-     { CS_READ_FAILURE,                "Read failure" },
-     { CS_BAD_SIZE,            "Bad size" },
-     { CS_BAD_SOCKET,          "Bad socket" },
-     { CS_BAD_TYPE,            "Bad type" },
-     { CS_BAD_VCC,             "Bad Vcc" },
-     { CS_BAD_VPP,             "Bad Vpp" },
-     { CS_BAD_WINDOW,          "Bad window" },
-     { CS_WRITE_FAILURE,               "Write failure" },
-     { CS_NO_CARD,             "No card present" },
-     { CS_UNSUPPORTED_FUNCTION,        "Usupported function" },
-     { CS_UNSUPPORTED_MODE,    "Unsupported mode" },
-     { CS_BAD_SPEED,           "Bad speed" },
-     { CS_BUSY,                        "Resource busy" },
-     { CS_GENERAL_FAILURE,     "General failure" },
-     { CS_WRITE_PROTECTED,     "Write protected" },
-     { CS_BAD_ARG_LENGTH,      "Bad argument length" },
-     { CS_BAD_ARGS,            "Bad arguments" },
-     { CS_CONFIGURATION_LOCKED,        "Configuration locked" },
-     { CS_IN_USE,              "Resource in use" },
-     { CS_NO_MORE_ITEMS,               "No more items" },
-     { CS_OUT_OF_RESOURCE,     "Out of resource" },
-     { CS_BAD_HANDLE,          "Bad handle" },
-     { CS_BAD_TUPLE,           "Bad CIS tuple" }
+     { 0,                      "Operation succeeded" },
+     { -EIO,                   "Input/Output error" },
+     { -ENODEV,                        "No card present" },
+     { -EINVAL,                        "Bad parameter" },
+     { -EACCES,                        "Configuration locked" },
+     { -EBUSY,                 "Resource in use" },
+     { -ENOSPC,                        "No more items" },
+     { -ENOMEM,                        "Out of resource" },
  };
  
  
@@@ -155,46 -136,32 +136,32 @@@ static const lookup_t service_table[] 
      { ReplaceCIS,                     "ReplaceCIS" }
  };
  
- static int pcmcia_report_error(struct pcmcia_device *p_dev, error_info_t *err)
+ const char *pcmcia_error_func(int func)
  {
        int i;
-       char *serv;
-       if (!p_dev)
-               printk(KERN_NOTICE);
-       else
-               printk(KERN_NOTICE "%s: ", p_dev->dev.bus_id);
  
        for (i = 0; i < ARRAY_SIZE(service_table); i++)
-               if (service_table[i].key == err->func)
-                       break;
-       if (i < ARRAY_SIZE(service_table))
-               serv = service_table[i].msg;
-       else
-               serv = "Unknown service number";
+               if (service_table[i].key == func)
+                       return service_table[i].msg;
  
-       for (i = 0; i < ARRAY_SIZE(error_table); i++)
-               if (error_table[i].key == err->retcode)
-                       break;
-       if (i < ARRAY_SIZE(error_table))
-               printk("%s: %s\n", serv, error_table[i].msg);
-       else
-               printk("%s: Unknown error code %#x\n", serv, err->retcode);
+       return "Unknown service number";
+ }
+ EXPORT_SYMBOL(pcmcia_error_func);
  
-       return CS_SUCCESS;
- } /* report_error */
+ const char *pcmcia_error_ret(int ret)
+ {
+       int i;
+       for (i = 0; i < ARRAY_SIZE(error_table); i++)
+               if (error_table[i].key == ret)
+                       return error_table[i].msg;
  
- /* end of code which was in cs.c before */
+       return "unknown";
+ }
+ EXPORT_SYMBOL(pcmcia_error_ret);
  
  /*======================================================================*/
  
- void cs_error(struct pcmcia_device *p_dev, int func, int ret)
- {
-       error_info_t err = { func, ret };
-       pcmcia_report_error(p_dev, &err);
- }
- EXPORT_SYMBOL(cs_error);
  
  
  static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
@@@ -391,7 -358,7 +358,7 @@@ static void pcmcia_release_function(str
  static void pcmcia_release_dev(struct device *dev)
  {
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
-       ds_dbg(1, "releasing device %s\n", p_dev->dev.bus_id);
+       ds_dev_dbg(1, dev, "releasing device\n");
        pcmcia_put_socket(p_dev->socket);
        kfree(p_dev->devname);
        kref_put(&p_dev->function_config->ref, pcmcia_release_function);
  static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc)
  {
        if (!s->pcmcia_state.device_add_pending) {
-               ds_dbg(1, "scheduling to add %s secondary"
+               ds_dev_dbg(1, &s->dev, "scheduling to add %s secondary"
                       " device to %d\n", mfc ? "mfc" : "pfc", s->sock);
                s->pcmcia_state.device_add_pending = 1;
                s->pcmcia_state.mfc_pfc = mfc;
@@@ -427,20 -394,7 +394,19 @@@ static int pcmcia_device_probe(struct d
        p_drv = to_pcmcia_drv(dev->driver);
        s = p_dev->socket;
  
-       ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id,
-              p_drv->drv.name);
 +      /* The PCMCIA code passes the match data in via dev->driver_data
 +       * which is an ugly hack. Once the driver probe is called it may
 +       * and often will overwrite the match data so we must save it first
 +       *
 +       * handle pseudo multifunction devices:
 +       * there are at most two pseudo multifunction devices.
 +       * if we're matching against the first, schedule a
 +       * call which will then check whether there are two
 +       * pseudo devices, and if not, add the second one.
 +       */
 +      did = p_dev->dev.driver_data;
 +
+       ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name);
  
        if ((!p_drv->probe) || (!p_dev->function_config) ||
            (!try_module_get(p_drv->owner))) {
                p_dev->conf.ConfigBase = cis_config.base;
                p_dev->conf.Present = cis_config.rmask[0];
        } else {
-               printk(KERN_INFO "pcmcia: could not parse base and rmask0 of CIS\n");
+               dev_printk(KERN_INFO, dev,
+                          "pcmcia: could not parse base and rmask0 of CIS\n");
                p_dev->conf.ConfigBase = 0;
                p_dev->conf.Present = 0;
        }
  
        ret = p_drv->probe(p_dev);
        if (ret) {
-               ds_dbg(1, "binding %s to %s failed with %d\n",
-                      p_dev->dev.bus_id, p_drv->drv.name, ret);
+               ds_dev_dbg(1, dev, "binding to %s failed with %d\n",
+                          p_drv->drv.name, ret);
                goto put_module;
        }
  
 -      /* handle pseudo multifunction devices:
 -       * there are at most two pseudo multifunction devices.
 -       * if we're matching against the first, schedule a
 -       * call which will then check whether there are two
 -       * pseudo devices, and if not, add the second one.
 -       */
 -      did = p_dev->dev.driver_data;
        if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
            (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
                pcmcia_add_device_later(p_dev->socket, 0);
  
 - put_module:
 +put_module:
        if (ret)
                module_put(p_drv->owner);
 - put_dev:
 +put_dev:
        if (ret)
                put_device(dev);
        return (ret);
@@@ -490,8 -452,9 +457,9 @@@ static void pcmcia_card_remove(struct p
        struct pcmcia_device    *tmp;
        unsigned long           flags;
  
-       ds_dbg(2, "pcmcia_card_remove(%d) %s\n", s->sock,
-              leftover ? leftover->devname : "");
+       ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev,
+                  "pcmcia_card_remove(%d) %s\n", s->sock,
+                  leftover ? leftover->devname : "");
  
        if (!leftover)
                s->device_count = 0;
                p_dev->_removed=1;
                spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
  
-               ds_dbg(2, "unregistering device %s\n", p_dev->dev.bus_id);
+               ds_dev_dbg(2, &p_dev->dev, "unregistering device\n");
                device_unregister(&p_dev->dev);
        }
  
@@@ -525,7 -488,7 +493,7 @@@ static int pcmcia_device_remove(struct 
        p_dev = to_pcmcia_dev(dev);
        p_drv = to_pcmcia_drv(dev->driver);
  
-       ds_dbg(1, "removing device %s\n", p_dev->dev.bus_id);
+       ds_dev_dbg(1, dev, "removing device\n");
  
        /* If we're removing the primary module driving a
         * pseudo multi-function card, we need to unbind
  
        /* check for proper unloading */
        if (p_dev->_irq || p_dev->_io || p_dev->_locked)
-               printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
-                      p_drv->drv.name);
+               dev_printk(KERN_INFO, dev,
+                       "pcmcia: driver %s did not release config properly\n",
+                       p_drv->drv.name);
  
        for (i = 0; i < MAX_WIN; i++)
                if (p_dev->_win & CLIENT_WIN_REQ(i))
-                       printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
-                              p_drv->drv.name);
+                       dev_printk(KERN_INFO, dev,
+                         "pcmcia: driver %s did not release window properly\n",
+                          p_drv->drv.name);
  
        /* references from pcmcia_probe_device */
        pcmcia_put_dev(p_dev);
@@@ -603,8 -568,9 +573,9 @@@ static int pcmcia_device_query(struct p
                }
                if (!pccard_read_tuple(p_dev->socket, p_dev->func,
                                      CISTPL_DEVICE_GEO, devgeo)) {
-                       ds_dbg(0, "mem device geometry probably means "
-                              "FUNCID_MEMORY\n");
+                       ds_dev_dbg(0, &p_dev->dev,
+                                  "mem device geometry probably means "
+                                  "FUNCID_MEMORY\n");
                        p_dev->func_id = CISTPL_FUNCID_MEMORY;
                        p_dev->has_func_id = 1;
                }
@@@ -685,7 -651,7 +656,7 @@@ struct pcmcia_device * pcmcia_device_ad
        if (!p_dev->devname)
                goto err_free;
        sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id);
-       ds_dbg(3, "devname is %s\n", p_dev->devname);
+       ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname);
  
        spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
  
        spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
  
        if (!p_dev->function_config) {
-               ds_dbg(3, "creating config_t for %s\n", p_dev->dev.bus_id);
+               ds_dev_dbg(3, &p_dev->dev, "creating config_t\n");
                p_dev->function_config = kzalloc(sizeof(struct config_t),
                                                 GFP_KERNEL);
                if (!p_dev->function_config)
                kref_init(&p_dev->function_config->ref);
        }
  
-       printk(KERN_NOTICE "pcmcia: registering new device %s\n",
-              p_dev->devname);
+       dev_printk(KERN_NOTICE, &p_dev->dev,
+                  "pcmcia: registering new device %s\n",
+                  p_dev->devname);
  
        pcmcia_device_query(p_dev);
  
@@@ -750,19 -717,20 +722,20 @@@ static int pcmcia_card_add(struct pcmci
        int ret = 0;
  
        if (!(s->resource_setup_done)) {
-               ds_dbg(3, "no resources available, delaying card_add\n");
+               ds_dev_dbg(3, &s->dev,
+                          "no resources available, delaying card_add\n");
                return -EAGAIN; /* try again, but later... */
        }
  
        if (pcmcia_validate_mem(s)) {
-               ds_dbg(3, "validating mem resources failed, "
+               ds_dev_dbg(3, &s->dev, "validating mem resources failed, "
                       "delaying card_add\n");
                return -EAGAIN; /* try again, but later... */
        }
  
        ret = pccard_validate_cis(s, BIND_FN_ALL, &no_chains);
        if (ret || !no_chains) {
-               ds_dbg(0, "invalid CIS or invalid resources\n");
+               ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n");
                return -ENODEV;
        }
  
@@@ -783,7 -751,7 +756,7 @@@ static void pcmcia_delayed_add_device(s
  {
        struct pcmcia_socket *s =
                container_of(work, struct pcmcia_socket, device_add);
-       ds_dbg(1, "adding additional device to %d\n", s->sock);
+       ds_dev_dbg(1, &s->dev, "adding additional device to %d\n", s->sock);
        pcmcia_device_add(s, s->pcmcia_state.mfc_pfc);
        s->pcmcia_state.device_add_pending = 0;
        s->pcmcia_state.mfc_pfc = 0;
@@@ -793,8 -761,7 +766,7 @@@ static int pcmcia_requery(struct devic
  {
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
        if (!p_dev->dev.driver) {
-               ds_dbg(1, "update device information for %s\n",
-                      p_dev->dev.bus_id);
+               ds_dev_dbg(1, dev, "update device information\n");
                pcmcia_device_query(p_dev);
        }
  
@@@ -808,7 -775,7 +780,7 @@@ static void pcmcia_bus_rescan(struct pc
        unsigned long flags;
  
        /* must be called with skt_mutex held */
-       ds_dbg(0, "re-scanning socket %d\n", skt->sock);
+       ds_dev_dbg(0, &skt->dev, "re-scanning socket %d\n", skt->sock);
  
        spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
        if (list_empty(&skt->devices_list))
@@@ -859,17 -826,17 +831,17 @@@ static int pcmcia_load_firmware(struct 
        int ret = -ENOMEM;
        int no_funcs;
        int old_funcs;
-       cisdump_t *cis;
        cistpl_longlink_mfc_t mfc;
  
        if (!filename)
                return -EINVAL;
  
-       ds_dbg(1, "trying to load CIS file %s\n", filename);
+       ds_dev_dbg(1, &dev->dev, "trying to load CIS file %s\n", filename);
  
        if (strlen(filename) > (FIRMWARE_NAME_MAX - 1)) {
-               printk(KERN_WARNING "pcmcia: CIS filename is too long [%s]\n",
-                       filename);
+               dev_printk(KERN_WARNING, &dev->dev,
+                          "pcmcia: CIS filename is too long [%s]\n",
+                          filename);
                return -EINVAL;
        }
  
        if (request_firmware(&fw, path, &dev->dev) == 0) {
                if (fw->size >= CISTPL_MAX_CIS_SIZE) {
                        ret = -EINVAL;
-                       printk(KERN_ERR "pcmcia: CIS override is too big\n");
+                       dev_printk(KERN_ERR, &dev->dev,
+                                  "pcmcia: CIS override is too big\n");
                        goto release;
                }
  
-               cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
-               if (!cis) {
-                       ret = -ENOMEM;
-                       goto release;
-               }
-               cis->Length = fw->size + 1;
-               memcpy(cis->Data, fw->data, fw->size);
-               if (!pcmcia_replace_cis(s, cis))
+               if (!pcmcia_replace_cis(s, fw->data, fw->size))
                        ret = 0;
                else {
-                       printk(KERN_ERR "pcmcia: CIS override failed\n");
+                       dev_printk(KERN_ERR, &dev->dev,
+                                  "pcmcia: CIS override failed\n");
                        goto release;
                }
  
@@@ -998,14 -958,14 +963,14 @@@ static inline int pcmcia_devmatch(struc
                 * after it has re-checked that there is no possible module
                 * with a prod_id/manf_id/card_id match.
                 */
-               ds_dbg(0, "skipping FUNC_ID match for %s until userspace "
-                      "interaction\n", dev->dev.bus_id);
+               ds_dev_dbg(0, &dev->dev,
+                       "skipping FUNC_ID match until userspace interaction\n");
                if (!dev->allow_func_id_match)
                        return 0;
        }
  
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
-               ds_dbg(0, "device %s needs a fake CIS\n", dev->dev.bus_id);
+               ds_dev_dbg(0, &dev->dev, "device needs a fake CIS\n");
                if (!dev->socket->fake_cis)
                        pcmcia_load_firmware(dev, did->cisfile);
  
@@@ -1037,11 -997,9 +1002,9 @@@ static int pcmcia_bus_match(struct devi
        /* match dynamic devices first */
        spin_lock(&p_drv->dynids.lock);
        list_for_each_entry(dynid, &p_drv->dynids.list, node) {
-               ds_dbg(3, "trying to match %s to %s\n", dev->bus_id,
-                      drv->name);
+               ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
                if (pcmcia_devmatch(p_dev, &dynid->id)) {
-                       ds_dbg(0, "matched %s to %s\n", dev->bus_id,
-                              drv->name);
+                       ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
                        spin_unlock(&p_drv->dynids.lock);
                        return 1;
                }
  #ifdef CONFIG_PCMCIA_IOCTL
        /* matching by cardmgr */
        if (p_dev->cardmgr == p_drv) {
-               ds_dbg(0, "cardmgr matched %s to %s\n", dev->bus_id,
-                      drv->name);
+               ds_dev_dbg(0, dev, "cardmgr matched to %s\n", drv->name);
                return 1;
        }
  #endif
  
        while (did && did->match_flags) {
-               ds_dbg(3, "trying to match %s to %s\n", dev->bus_id,
-                      drv->name);
+               ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
                if (pcmcia_devmatch(p_dev, did)) {
-                       ds_dbg(0, "matched %s to %s\n", dev->bus_id,
-                              drv->name);
+                       ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
                        return 1;
                }
                did++;
@@@ -1268,7 -1223,7 +1228,7 @@@ static int pcmcia_dev_suspend(struct de
        if (p_dev->suspended)
                return 0;
  
-       ds_dbg(2, "suspending %s\n", dev->bus_id);
+       ds_dev_dbg(2, dev, "suspending\n");
  
        if (dev->driver)
                p_drv = to_pcmcia_drv(dev->driver);
        if (p_drv->suspend) {
                ret = p_drv->suspend(p_dev);
                if (ret) {
-                       printk(KERN_ERR "pcmcia: device %s (driver %s) did "
-                              "not want to go to sleep (%d)\n",
-                              p_dev->devname, p_drv->drv.name, ret);
+                       dev_printk(KERN_ERR, dev,
+                                  "pcmcia: device %s (driver %s) did "
+                                  "not want to go to sleep (%d)\n",
+                                  p_dev->devname, p_drv->drv.name, ret);
                        goto out;
                }
        }
  
        if (p_dev->device_no == p_dev->func) {
-               ds_dbg(2, "releasing configuration for %s\n", dev->bus_id);
+               ds_dev_dbg(2, dev, "releasing configuration\n");
                pcmcia_release_configuration(p_dev);
        }
  
@@@ -1307,7 -1263,7 +1268,7 @@@ static int pcmcia_dev_resume(struct dev
        if (!p_dev->suspended)
                return 0;
  
-       ds_dbg(2, "resuming %s\n", dev->bus_id);
+       ds_dev_dbg(2, dev, "resuming\n");
  
        if (dev->driver)
                p_drv = to_pcmcia_drv(dev->driver);
                goto out;
  
        if (p_dev->device_no == p_dev->func) {
-               ds_dbg(2, "requesting configuration for %s\n", dev->bus_id);
+               ds_dev_dbg(2, dev, "requesting configuration\n");
                ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
                if (ret)
                        goto out;
@@@ -1358,14 -1314,14 +1319,14 @@@ static int pcmcia_bus_resume_callback(s
  
  static int pcmcia_bus_resume(struct pcmcia_socket *skt)
  {
-       ds_dbg(2, "resuming socket %d\n", skt->sock);
+       ds_dev_dbg(2, &skt->dev, "resuming socket %d\n", skt->sock);
        bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
        return 0;
  }
  
  static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
  {
-       ds_dbg(2, "suspending socket %d\n", skt->sock);
+       ds_dev_dbg(2, &skt->dev, "suspending socket %d\n", skt->sock);
        if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
                             pcmcia_bus_suspend_callback)) {
                pcmcia_bus_resume(skt);
@@@ -1391,13 -1347,14 +1352,14 @@@ static int ds_event(struct pcmcia_socke
        struct pcmcia_socket *s = pcmcia_get_socket(skt);
  
        if (!s) {
-               printk(KERN_ERR "PCMCIA obtaining reference to socket %p " \
-                       "failed, event 0x%x lost!\n", skt, event);
+               dev_printk(KERN_ERR, &skt->dev,
+                          "PCMCIA obtaining reference to socket "      \
+                          "failed, event 0x%x lost!\n", event);
                return -ENODEV;
        }
  
-       ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
-              event, priority, skt);
+       ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
+                  event, priority, skt);
  
        switch (event) {
        case CS_EVENT_CARD_REMOVAL:
@@@ -1472,7 -1429,8 +1434,8 @@@ static int __devinit pcmcia_bus_add_soc
  
        socket = pcmcia_get_socket(socket);
        if (!socket) {
-               printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket);
+               dev_printk(KERN_ERR, dev,
+                          "PCMCIA obtaining reference to socket failed\n");
                return -ENODEV;
        }
  
  
        ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback);
        if (ret) {
-               printk(KERN_ERR "PCMCIA registration PCCard core failed for socket %p\n", socket);
+               dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n");
                pcmcia_put_socket(socket);
                return (ret);
        }
index 13f1e0fd3f31cf096b5c07cf10392278e0308bdc,7bdf3635784650e785fd61b49249f12ee3b1919f..bb9ddb9532e35a6790aa6f50dcaa1a5a7aba7b75
  #include <linux/spinlock.h>
  #include <linux/platform_device.h>
  
 -#include <asm/hardware.h>
 +#include <mach/hardware.h>
  #include <asm/io.h>
  #include <asm/irq.h>
  #include <asm/system.h>
 -#include <asm/arch/pxa-regs.h>
 -#include <asm/arch/pxa2xx-regs.h>
 +#include <mach/pxa-regs.h>
 +#include <mach/pxa2xx-regs.h>
 +#include <asm/mach-types.h>
  
  #include <pcmcia/cs_types.h>
  #include <pcmcia/ss.h>
  #include <pcmcia/cistpl.h>
  
- #include "cs_internal.h"
  #include "soc_common.h"
  #include "pxa2xx_base.h"
  
@@@ -167,32 -165,18 +166,32 @@@ pxa2xx_pcmcia_frequency_change(struct s
  }
  #endif
  
 +static void pxa2xx_configure_sockets(struct device *dev)
 +{
 +      struct pcmcia_low_level *ops = dev->platform_data;
 +
 +      /*
 +       * We have at least one socket, so set MECR:CIT
 +       * (Card Is There)
 +       */
 +      MECR |= MECR_CIT;
 +
 +      /* Set MECR:NOS (Number Of Sockets) */
 +      if (ops->nr > 1 || machine_is_viper())
 +              MECR |= MECR_NOS;
 +      else
 +              MECR &= ~MECR_NOS;
 +}
 +
  int __pxa2xx_drv_pcmcia_probe(struct device *dev)
  {
        int ret;
        struct pcmcia_low_level *ops;
 -      int first, nr;
  
        if (!dev || !dev->platform_data)
                return -ENODEV;
  
        ops = (struct pcmcia_low_level *)dev->platform_data;
 -      first = ops->first;
 -      nr = ops->nr;
  
        /* Provide our PXA2xx specific timing routines. */
        ops->set_timing  = pxa2xx_pcmcia_set_timing;
        ops->frequency_change = pxa2xx_pcmcia_frequency_change;
  #endif
  
 -      ret = soc_common_drv_pcmcia_probe(dev, ops, first, nr);
 +      ret = soc_common_drv_pcmcia_probe(dev, ops, ops->first, ops->nr);
  
 -      if (ret == 0) {
 -              /*
 -               * We have at least one socket, so set MECR:CIT
 -               * (Card Is There)
 -               */
 -              MECR |= MECR_CIT;
 -
 -              /* Set MECR:NOS (Number Of Sockets) */
 -              if (nr > 1)
 -                      MECR |= MECR_NOS;
 -              else
 -                      MECR &= ~MECR_NOS;
 -      }
 +      if (!ret)
 +              pxa2xx_configure_sockets(dev);
  
        return ret;
  }
@@@ -227,7 -222,11 +226,7 @@@ static int pxa2xx_drv_pcmcia_suspend(st
  
  static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev)
  {
 -      struct pcmcia_low_level *ops = dev->dev.platform_data;
 -      int nr = ops ? ops->nr : 0;
 -
 -      MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
 -
 +      pxa2xx_configure_sockets(&dev->dev);
        return pcmcia_socket_dev_resume(&dev->dev);
  }
  
index 203e579ebbd22e77e5413f86995bce689cc87508,0e4141bac7b1b099b3e47eae12576936f4805c45..17f4ecf1c0c5b214af03b7188ecedca3e516d8b5
@@@ -122,19 -122,22 +122,22 @@@ static void free_region(struct resourc
  
  static int add_interval(struct resource_map *map, u_long base, u_long num)
  {
-     struct resource_map *p, *q;
+       struct resource_map *p, *q;
  
-     for (p = map; ; p = p->next) {
-       if ((p != map) && (p->base+p->num-1 >= base))
-           return -1;
-       if ((p->next == map) || (p->next->base > base+num-1))
-           break;
-     }
-     q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
-     if (!q) return CS_OUT_OF_RESOURCE;
-     q->base = base; q->num = num;
-     q->next = p->next; p->next = q;
-     return CS_SUCCESS;
+       for (p = map; ; p = p->next) {
+               if ((p != map) && (p->base+p->num-1 >= base))
+                       return -1;
+               if ((p->next == map) || (p->next->base > base+num-1))
+                       break;
+       }
+       q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
+       if (!q) {
+               printk(KERN_WARNING "out of memory to update resources\n");
+               return -ENOMEM;
+       }
+       q->base = base; q->num = num;
+       q->next = p->next; p->next = q;
+       return 0;
  }
  
  /*====================================================================*/
@@@ -166,7 -169,10 +169,10 @@@ static int sub_interval(struct resource
            } else {
                /* Split the block into two pieces */
                p = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
-               if (!p) return CS_OUT_OF_RESOURCE;
+               if (!p) {
+                   printk(KERN_WARNING "out of memory to update resources\n");
+                   return -ENOMEM;
+               }
                p->base = base+num;
                p->num = q->base+q->num - p->base;
                q->num = base - q->base;
            }
        }
      }
-     return CS_SUCCESS;
+     return 0;
  }
  
  /*======================================================================
@@@ -194,13 -200,14 +200,14 @@@ static void do_io_probe(struct pcmcia_s
      int any;
      u_char *b, hole, most;
  
-     printk(KERN_INFO "cs: IO port probe %#x-%#x:",
-          base, base+num-1);
+     dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
+              base, base+num-1);
  
      /* First, what does a floating port look like? */
      b = kzalloc(256, GFP_KERNEL);
      if (!b) {
-             printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
+           dev_printk(KERN_ERR, &s->dev,
+                  "do_io_probe: unable to kmalloc 256 bytes");
              return;
      }
      for (i = base, most = 0; i < base+num; i += 8) {
@@@ -275,7 -282,7 +282,7 @@@ static int readable(struct pcmcia_socke
                destroy_cis_cache(s);
        }
        s->cis_mem.res = NULL;
 -      if ((ret != 0) || (count == 0))
 +      if ((ret != 0) || (*count == 0))
                return 0;
        return 1;
  }
@@@ -366,8 -373,8 +373,8 @@@ static int do_mem_probe(u_long base, u_
      struct socket_data *s_data = s->resource_data;
      u_long i, j, bad, fail, step;
  
-     printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:",
-          base, base+num-1);
+     dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
+              base, base+num-1);
      bad = fail = 0;
      step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
      /* don't allow too large steps */
@@@ -431,8 -438,8 +438,8 @@@ static int validate_mem(struct pcmcia_s
        if (probe_mask & MEM_PROBE_HIGH) {
                if (inv_probe(s_data->mem_db.next, s) > 0)
                        return 0;
-               printk(KERN_NOTICE "cs: warning: no high memory space "
-                      "available!\n");
+               dev_printk(KERN_NOTICE, &s->dev,
+                          "cs: warning: no high memory space available!\n");
                return -ENODEV;
        }
  
@@@ -794,10 -801,11 +801,11 @@@ static int nonstatic_autoadd_resources(
                if (res->flags & IORESOURCE_IO) {
                        if (res == &ioport_resource)
                                continue;
-                       printk(KERN_INFO "pcmcia: parent PCI bridge I/O "
-                               "window: 0x%llx - 0x%llx\n",
-                               (unsigned long long)res->start,
-                               (unsigned long long)res->end);
+                       dev_printk(KERN_INFO, &s->cb_dev->dev,
+                                  "pcmcia: parent PCI bridge I/O "
+                                  "window: 0x%llx - 0x%llx\n",
+                                  (unsigned long long)res->start,
+                                  (unsigned long long)res->end);
                        if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
                                done |= IORESOURCE_IO;
  
                if (res->flags & IORESOURCE_MEM) {
                        if (res == &iomem_resource)
                                continue;
-                       printk(KERN_INFO "pcmcia: parent PCI bridge Memory "
-                               "window: 0x%llx - 0x%llx\n",
-                               (unsigned long long)res->start,
-                               (unsigned long long)res->end);
+                       dev_printk(KERN_INFO, &s->cb_dev->dev,
+                                  "pcmcia: parent PCI bridge Memory "
+                                  "window: 0x%llx - 0x%llx\n",
+                                  (unsigned long long)res->start,
+                                  (unsigned long long)res->end);
                        if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
                                done |= IORESOURCE_MEM;
                }
index da3972153226a019c424ae98972ae8796e274f89,89edcbc3bfd2f6214a6d378ebb3b2e1675cbf232..f49ac6666153bca4718a4813878bb5fba5f7b429
@@@ -43,7 -43,7 +43,7 @@@
  #include <linux/spinlock.h>
  #include <linux/cpufreq.h>
  
 -#include <asm/hardware.h>
 +#include <mach/hardware.h>
  #include <asm/io.h>
  #include <asm/system.h>
  
  
  /* FIXME: platform dependent resource declaration has to move out of this file */
  #ifdef CONFIG_ARCH_PXA
 -#include <asm/arch/pxa-regs.h>
 +#include <mach/pxa-regs.h>
  #endif
  
- #ifdef DEBUG
+ #ifdef CONFIG_PCMCIA_DEBUG
  
  static int pc_debug;
  module_param(pc_debug, int, 0644);
@@@ -748,9 -748,7 +748,9 @@@ int soc_common_drv_pcmcia_probe(struct 
  
                add_timer(&skt->poll_timer);
  
 -              device_create_file(&skt->socket.dev, &dev_attr_status);
 +              ret = device_create_file(&skt->socket.dev, &dev_attr_status);
 +              if (ret)
 +                      goto out_err_8;
        }
  
        dev_set_drvdata(dev, sinfo);
        do {
                skt = &sinfo->skt[i];
  
 +              device_remove_file(&skt->socket.dev, &dev_attr_status);
 + out_err_8:
                del_timer_sync(&skt->poll_timer);
                pcmcia_unregister_socket(&skt->socket);
  
index 24e6cb8396e35e9bcebe890e9352f1cddc613c80,7c19bf264873949d8e91797a481093f5a5b73d54..11a61ea8d5d917d8d6e8478313885ee99cb20ad8
@@@ -25,6 -25,7 +25,6 @@@
  
  ***********************************************************************/
  
 -#include <linux/version.h>
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/init.h>
@@@ -1606,133 -1607,129 +1606,129 @@@ static void nsp_cs_detach(struct pcmcia
      is received, to configure the PCMCIA socket, and to make the
      ethernet device available to the system.
  ======================================================================*/
- #define CS_CHECK(fn, ret) \
- do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
- /*====================================================================*/
- static int nsp_cs_config(struct pcmcia_device *link)
- {
-       int               ret;
-       scsi_info_t      *info   = link->priv;
-       tuple_t           tuple;
-       cisparse_t        parse;
-       int               last_ret, last_fn;
-       unsigned char     tuple_data[64];
-       config_info_t     conf;
-       win_req_t         req;
-       memreq_t          map;
-       cistpl_cftable_entry_t dflt = { 0 };
-       struct Scsi_Host *host;
-       nsp_hw_data      *data = &nsp_data_base;
-       nsp_dbg(NSP_DEBUG_INIT, "in");
-       tuple.Attributes      = 0;
-       tuple.TupleData       = tuple_data;
-       tuple.TupleDataMax    = sizeof(tuple_data);
-       tuple.TupleOffset     = 0;
-       /* Look up the current Vcc */
-       CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
  
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-       while (1) {
              cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ struct nsp_cs_configdata {
+       nsp_hw_data             *data;
+       win_req_t               req;
};
  
-               if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
-                               pcmcia_parse_tuple(link, &tuple, &parse) != 0)
-                       goto next_entry;
+ static int nsp_cs_config_check(struct pcmcia_device *p_dev,
+                              cistpl_cftable_entry_t *cfg,
+                              cistpl_cftable_entry_t *dflt,
+                              unsigned int vcc,
+                              void *priv_data)
+ {
+       struct nsp_cs_configdata *cfg_mem = priv_data;
  
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
-               if (cfg->index == 0) { goto next_entry; }
-               link->conf.ConfigIndex = cfg->index;
+       if (cfg->index == 0)
+               return -ENODEV;
  
-               /* Does this card need audio output? */
-               if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
-                       link->conf.Attributes |= CONF_ENABLE_SPKR;
-                       link->conf.Status = CCSR_AUDIO_ENA;
-               }
+       /* 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;
+       }
  
-               /* Use power settings for Vcc and Vpp if present */
-               /*  Note that the CIS values need to be rescaled */
-               if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
-                       if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
-                               goto next_entry;
-                       }
-               } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
-                       if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
-                               goto next_entry;
-                       }
+       /* Use power settings for Vcc and Vpp if present */
+       /*  Note that the CIS values need to be rescaled */
+       if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
+               if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
+                       return -ENODEV;
+               else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
+                       if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000)
+                               return -ENODEV;
                }
  
                if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
-                       link->conf.Vpp =
+                       p_dev->conf.Vpp =
                                cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-               } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
-                       link->conf.Vpp =
-                               dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
+               } else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
+                       p_dev->conf.Vpp =
+                               dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
                }
  
                /* Do we need to allocate an interrupt? */
-               if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
-                       link->conf.Attributes |= CONF_ENABLE_IRQ;
-               }
+               if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+                       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
  
                /* IO window settings */
-               link->io.NumPorts1 = link->io.NumPorts2 = 0;
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+               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))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+                               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
                        if (!(io->flags & CISTPL_IO_16BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-                       link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
+                               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) {
-                               link->io.Attributes2 = link->io.Attributes1;
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
+                               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(link, &link->io) != 0)
+                       if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
                                goto next_entry;
                }
  
-               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(&link, &req, &link->win) != 0)
+               if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
+                       memreq_t        map;
+                       cistpl_mem_t    *mem =
+                               (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
+                       cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
+                       cfg_mem->req.Attributes |= WIN_ENABLE;
+                       cfg_mem->req.Base = mem->win[0].host_addr;
+                       cfg_mem->req.Size = mem->win[0].len;
+                       if (cfg_mem->req.Size < 0x1000)
+                               cfg_mem->req.Size = 0x1000;
+                       cfg_mem->req.AccessSpeed = 0;
+                       if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0)
                                goto next_entry;
                        map.Page = 0; map.CardOffset = mem->win[0].card_addr;
-                       if (pcmcia_map_mem_page(link->win, &map) != 0)
+                       if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
                                goto next_entry;
  
-                       data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
-                       data->MmioLength  = req.Size;
+                       cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size);
+                       cfg_mem->data->MmioLength  = cfg_mem->req.Size;
                }
                /* If we got this far, we're cool! */
-               break;
-       next_entry:
-               nsp_dbg(NSP_DEBUG_INIT, "next");
-               pcmcia_disable_device(link);
-               CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
+               return 0;
        }
  
+ next_entry:
+       nsp_dbg(NSP_DEBUG_INIT, "next");
+       pcmcia_disable_device(p_dev);
+       return -ENODEV;
+ }
+ static int nsp_cs_config(struct pcmcia_device *link)
+ {
+       int               ret;
+       scsi_info_t      *info   = link->priv;
+       struct nsp_cs_configdata *cfg_mem;
+       struct Scsi_Host *host;
+       nsp_hw_data      *data = &nsp_data_base;
+       nsp_dbg(NSP_DEBUG_INIT, "in");
+       cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL);
+       if (!cfg_mem)
+               return -ENOMEM;
+       cfg_mem->data = data;
+       ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem);
+               goto cs_failed;
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+               if (pcmcia_request_irq(link, &link->irq))
+                       goto cs_failed;
        }
-       CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto cs_failed;
  
        if (free_ports) {
                if (link->io.BasePort1) {
                printk(" & 0x%04x-0x%04x", link->io.BasePort2,
                       link->io.BasePort2+link->io.NumPorts2-1);
        if (link->win)
-               printk(", mem 0x%06lx-0x%06lx", req.Base,
-                      req.Base+req.Size-1);
+               printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base,
+                      cfg_mem->req.Base+cfg_mem->req.Size-1);
        printk("\n");
  
+       kfree(cfg_mem);
        return 0;
  
   cs_failed:
        nsp_dbg(NSP_DEBUG_INIT, "config fail");
-       cs_error(link, last_fn, last_ret);
        nsp_cs_release(link);
+       kfree(cfg_mem);
  
        return -ENODEV;
  } /* nsp_cs_config */
- #undef CS_CHECK
  
  
  /*======================================================================