Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6

* 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
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index 96f155e..0599343 100644
--- a/Documentation/pcmcia/driver-changes.txt
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -1,5 +1,11 @@
 This file details changes in 2.6 which affect PCMCIA card driver authors:
 
+* New configuration loop helper (as of 2.6.28)
+   By calling pcmcia_loop_config(), a driver can iterate over all available
+   configuration options. During a driver's probe() phase, one doesn't need
+   to use pcmcia_get_{first,next}_tuple, pcmcia_get_tuple_data and
+   pcmcia_parse_tuple directly in most if not all cases.
+
 * New release helper (as of 2.6.17)
    Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's
    necessary now is calling pcmcia_disable_device. As there is no valid
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 41b4361..02b596b 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -148,6 +148,64 @@
 #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->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;
+}
+
 /**
  *	pcmcia_init_one		-	attach a PCMCIA interface
  *	@pdev: pcmcia device
@@ -161,19 +219,11 @@
 	struct ata_host *host;
 	struct ata_port *ap;
 	struct ata_pcmcia_info *info;
-	tuple_t tuple;
-	struct {
-		unsigned 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, ret = -ENOMEM, p;
+	struct pcmcia_config_check *stk = NULL;
+	int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
 	unsigned long io_base, ctl_base;
 	void __iomem *io_addr, *ctl_addr;
 	int n_ports = 1;
-
 	struct ata_port_operations *ops = &pcmcia_port_ops;
 
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -193,96 +243,27 @@
 	pdev->conf.Attributes = CONF_ENABLE_IRQ;
 	pdev->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Allocate resoure probing structures */
-
-	stk = kzalloc(sizeof(*stk), GFP_KERNEL);
-	if (!stk)
-		goto out1;
-
-	cfg = &stk->parse.cftable_entry;
-
-	/* Tuples we are walking */
-	tuple.TupleData = (cisdata_t *)&stk->buf;
-	tuple.TupleOffset = 0;
-	tuple.TupleDataMax = 255;
-	tuple.Attributes = 0;
-
 	/* See if we have a manufacturer identifier. Use it to set is_kme for
 	   vendor quirks */
 	is_kme = ((pdev->manf_id == MANFID_KME) &&
 		  ((pdev->card_id == PRODID_KME_KXLC005_A) ||
 		   (pdev->card_id == PRODID_KME_KXLC005_B)));
 
-	/* Not sure if this is right... look up the current Vcc */
-	CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf));
-/*	link->conf.Vcc = stk->conf.Vcc; */
+	/* Allocate resoure probing structures */
 
-	pass = io_base = ctl_base = 0;
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	tuple.Attributes = 0;
-	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
+	stk = kzalloc(sizeof(*stk), GFP_KERNEL);
+	if (!stk)
+		goto out1;
+	stk->is_kme = is_kme;
+	stk->skip_vcc = io_base = ctl_base = 0;
 
-	/* Now munch the resources looking for a suitable set */
-	while (1) {
-		if (pcmcia_get_tuple_data(pdev, &tuple) != 0)
-			goto next_entry;
-		if (pcmcia_parse_tuple(pdev, &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))
-			pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-		else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
-			pdev->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;
-			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 = (is_kme) ? 2 : 1;
-				if (pcmcia_request_io(pdev, &pdev->io) != 0)
-					goto next_entry;
-				io_base = pdev->io.BasePort1;
-				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)
-					goto next_entry;
-				io_base = pdev->io.BasePort1;
-				ctl_base = pdev->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(pdev, &tuple));
-		} else if (pcmcia_get_next_tuple(pdev, &tuple) != 0) {
-			CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
-			memset(&stk->dflt, 0, sizeof(stk->dflt));
-			pass++;
-		}
+	if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) {
+		stk->skip_vcc = 1;
+		if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk))
+			goto failed; /* No suitable config found */
 	}
-
+	io_base = pdev->io.BasePort1;
+	ctl_base = stk->ctl_base;
 	CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
 	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
 
@@ -384,6 +365,7 @@
 	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),
@@ -404,9 +386,9 @@
 	PCMCIA_DEVICE_PROD_ID12("EXP   ", "CD-ROM", 0x0a5c52fd, 0x66536591),
 	PCMCIA_DEVICE_PROD_ID12("EXP   ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
 	PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
-	PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
 	PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
 	PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
+	PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
 	PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
 	PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
 	PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index bcf5792..e6ee21d 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -901,23 +901,23 @@
 	for (n = 0; n < 0x400; n += 0x40) {
 		link->io.BasePort1 = n ^ 0x300;
 		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;
 	}
 
 	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;
 	}
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 2705847..2cbe70b 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -678,101 +678,78 @@
 	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;
+	unsigned long try = (unsigned long) priv_data;
 
-	i = pcmcia_get_tuple_data(handle, tuple);
-	if (i != CS_SUCCESS)
-		return i;
-
-	return pcmcia_parse_tuple(handle, tuple, parse);
+	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 first_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_first_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;
 
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
-	if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
-		return CS_NO_MORE_ITEMS;
-	return get_tuple(handle, tuple, parse);
+	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;
+	int i;
+	unsigned long 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);
-		}
-	}
+	/* 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;
+
+	BT_ERR("No usable port range found");
+	cs_error(link, RequestIO, -ENODEV);
+	goto failed;
 
 found_port:
-	if (i != CS_SUCCESS) {
-		BT_ERR("No usable port range found");
-		cs_error(link, RequestIO, i);
-		goto failed;
-	}
-
 	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;
 	}
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 68d1d25..8e556b7 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -607,102 +607,78 @@
 	kfree(info);
 }
 
-static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
+static int btuart_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;
+	int *try = priv_data;
 
-	i = pcmcia_get_tuple_data(handle, tuple);
-	if (i != CS_SUCCESS)
-		return i;
-
-	return pcmcia_parse_tuple(handle, tuple, parse);
+	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 first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
+static int btuart_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_first_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;
 
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
-	if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
-		return CS_NO_MORE_ITEMS;
-	return get_tuple(handle, tuple, parse);
+	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 btuart_config(struct pcmcia_device *link)
 {
-	static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
 	btuart_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;
+	int i;
+	int 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);
-		}
-	}
+	/* 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, btuart_check_config, &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, btuart_check_config_notpicky, NULL))
+		goto found_port;
+
+	BT_ERR("No usable port range found");
+	cs_error(link, RequestIO, -ENODEV);
+	goto failed;
 
 found_port:
-	if (i != CS_SUCCESS) {
-		BT_ERR("No usable port range found");
-		cs_error(link, RequestIO, i);
-		goto failed;
-	}
-
 	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;
 	}
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index dae45cd..e6e6b03 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -590,75 +590,40 @@
 	kfree(info);
 }
 
-static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
+static int dtl1_confcheck(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);
-}
-
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
-	if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
-		return CS_NO_MORE_ITEMS;
-	return get_tuple(handle, tuple, parse);
+	if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
+		p_dev->io.BasePort1 = cf->io.win[0].base;
+		p_dev->io.NumPorts1 = cf->io.win[0].len;	/*yo */
+		p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
+		if (!pcmcia_request_io(p_dev, &p_dev->io))
+			return 0;
+	}
+	return -ENODEV;
 }
 
 static int dtl1_config(struct pcmcia_device *link)
 {
 	dtl1_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;
 
-	tuple.TupleData = (cisdata_t *)buf;
-	tuple.TupleOffset = 0;
-	tuple.TupleDataMax = 255;
-	tuple.Attributes = 0;
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
 	/* Look for a generic full-sized window */
 	link->io.NumPorts1 = 8;
-	i = first_tuple(link, &tuple, &parse);
-	while (i != CS_NO_MORE_ITEMS) {
-		if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
-			link->conf.ConfigIndex = cf->index;
-			link->io.BasePort1 = cf->io.win[0].base;
-			link->io.NumPorts1 = cf->io.win[0].len;	/*yo */
-			link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-			i = pcmcia_request_io(link, &link->io);
-			if (i == CS_SUCCESS)
-				break;
-		}
-		i = next_tuple(link, &tuple, &parse);
-	}
-
-	if (i != CS_SUCCESS) {
-		cs_error(link, RequestIO, i);
+	if (!pcmcia_loop_config(link, dtl1_confcheck, NULL))
 		goto failed;
-	}
 
 	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;
 	}
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index f070ae7..1c5bf99 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1759,65 +1759,40 @@
 
 /*==== Interface to PCMCIA Layer =======================================*/
 
+static int cm4000_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->io.nwin)
+		return -ENODEV;
+
+	/* Get the IOaddr */
+	p_dev->io.BasePort1 = cfg->io.win[0].base;
+	p_dev->io.NumPorts1 = cfg->io.win[0].len;
+	p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+	if (!(cfg->io.flags & CISTPL_IO_8BIT))
+		p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+	if (!(cfg->io.flags & CISTPL_IO_16BIT))
+		p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+	p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+
+	return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
 static int cm4000_config(struct pcmcia_device * link, int devno)
 {
 	struct cm4000_dev *dev;
-	tuple_t tuple;
-	cisparse_t parse;
-	u_char buf[64];
-	int fail_fn, fail_rc;
-	int rc;
 
 	/* read the config-tuples */
-	tuple.Attributes = 0;
-	tuple.TupleData = buf;
-	tuple.TupleDataMax = sizeof(buf);
-	tuple.TupleOffset = 0;
-
-	link->io.BasePort2 = 0;
-	link->io.NumPorts2 = 0;
-	link->io.Attributes2 = 0;
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	for (rc = pcmcia_get_first_tuple(link, &tuple);
-	     rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(link, &tuple)) {
-
-		rc = pcmcia_get_tuple_data(link, &tuple);
-		if (rc != CS_SUCCESS)
-			continue;
-		rc = pcmcia_parse_tuple(link, &tuple, &parse);
-		if (rc != CS_SUCCESS)
-			continue;
-
-		link->conf.ConfigIndex = parse.cftable_entry.index;
-
-		if (!parse.cftable_entry.io.nwin)
-			continue;
-
-		/* Get the IOaddr */
-		link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
-		link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
-		link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-		if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
-			link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-		if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
-			link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-		link->io.IOAddrLines = parse.cftable_entry.io.flags
-		    & CISTPL_IO_LINES_MASK;
-
-		rc = pcmcia_request_io(link, &link->io);
-		if (rc == CS_SUCCESS)
-			break;	/* we are done */
-	}
-	if (rc != CS_SUCCESS)
+	if (pcmcia_loop_config(link, cm4000_config_check, NULL))
 		goto cs_release;
 
 	link->conf.IntType = 00000002;
 
-	if ((fail_rc =
-	     pcmcia_request_configuration(link, &link->conf)) != CS_SUCCESS) {
-		fail_fn = RequestConfiguration;
+	if (pcmcia_request_configuration(link, &link->conf))
 		goto cs_release;
-	}
 
 	dev = link->priv;
 	sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 0b5934b..2d7c906 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -526,65 +526,49 @@
 	return;
 }
 
+static int cm4040_config_check(struct pcmcia_device *p_dev,
+			       cistpl_cftable_entry_t *cfg,
+			       cistpl_cftable_entry_t *dflt,
+			       unsigned int vcc,
+			       void *priv_data)
+{
+	int rc;
+	if (!cfg->io.nwin)
+		return -ENODEV;
+
+	/* Get the IOaddr */
+	p_dev->io.BasePort1 = cfg->io.win[0].base;
+	p_dev->io.NumPorts1 = cfg->io.win[0].len;
+	p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+	if (!(cfg->io.flags & CISTPL_IO_8BIT))
+		p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+	if (!(cfg->io.flags & CISTPL_IO_16BIT))
+		p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+	p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+
+	rc = pcmcia_request_io(p_dev, &p_dev->io);
+	dev_printk(KERN_INFO, &handle_to_dev(p_dev),
+		   "pcmcia_request_io returned 0x%x\n", rc);
+	return rc;
+}
+
+
 static int reader_config(struct pcmcia_device *link, int devno)
 {
 	struct reader_dev *dev;
-	tuple_t tuple;
-	cisparse_t parse;
-	u_char buf[64];
-	int fail_fn, fail_rc;
-	int rc;
-
-	tuple.Attributes = 0;
-	tuple.TupleData = buf;
-	tuple.TupleDataMax = sizeof(buf);
- 	tuple.TupleOffset = 0;
+	int fail_rc;
 
 	link->io.BasePort2 = 0;
 	link->io.NumPorts2 = 0;
 	link->io.Attributes2 = 0;
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	for (rc = pcmcia_get_first_tuple(link, &tuple);
-	     rc == CS_SUCCESS;
-	     rc = pcmcia_get_next_tuple(link, &tuple)) {
-		rc = pcmcia_get_tuple_data(link, &tuple);
-		if (rc != CS_SUCCESS)
-			continue;
-		rc = pcmcia_parse_tuple(link, &tuple, &parse);
-		if (rc != CS_SUCCESS)
-			continue;
 
-		link->conf.ConfigIndex = parse.cftable_entry.index;
-
-		if (!parse.cftable_entry.io.nwin)
-			continue;
-
-		link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
-		link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
-		link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-		if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
-			link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-		if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
-			link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-		link->io.IOAddrLines = parse.cftable_entry.io.flags
-						& CISTPL_IO_LINES_MASK;
-		rc = pcmcia_request_io(link, &link->io);
-
-		dev_printk(KERN_INFO, &handle_to_dev(link), "foo");
-		if (rc == CS_SUCCESS)
-			break;
-		else
-			dev_printk(KERN_INFO, &handle_to_dev(link),
-				   "pcmcia_request_io failed 0x%x\n", rc);
-	}
-	if (rc != CS_SUCCESS)
+	if (pcmcia_loop_config(link, cm4040_config_check, NULL))
 		goto cs_release;
 
 	link->conf.IntType = 00000002;
 
-	if ((fail_rc = pcmcia_request_configuration(link,&link->conf))
-								!=CS_SUCCESS) {
-		fail_fn = RequestConfiguration;
+	fail_rc = pcmcia_request_configuration(link, &link->conf);
+	if (fail_rc != 0) {
 		dev_printk(KERN_INFO, &handle_to_dev(link),
 			   "pcmcia_request_configuration failed 0x%x\n",
 			   fail_rc);
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c
index 5eca7a9..5216fce 100644
--- a/drivers/char/pcmcia/ipwireless/main.c
+++ b/drivers/char/pcmcia/ipwireless/main.c
@@ -65,9 +65,9 @@
 	struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev,
 			work_reboot);
 	struct pcmcia_device *link = ipw->link;
-	int ret = pccard_reset_card(link->socket);
+	int ret = pcmcia_reset_card(link->socket);
 
-	if (ret != CS_SUCCESS)
+	if (ret != 0)
 		cs_error(link, ResetCard, ret);
 }
 
@@ -83,7 +83,6 @@
 {
 	struct pcmcia_device *link = ipw->link;
 	int ret;
-	config_info_t conf;
 	tuple_t tuple;
 	unsigned short buf[64];
 	cisparse_t parse;
@@ -105,7 +104,7 @@
 	while (ret == 0) {
 		ret = pcmcia_get_tuple_data(link, &tuple);
 
-		if (ret != CS_SUCCESS) {
+		if (ret != 0) {
 			cs_error(link, GetTupleData, ret);
 			goto exit0;
 		}
@@ -116,21 +115,21 @@
 
 	ret = pcmcia_get_first_tuple(link, &tuple);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, GetFirstTuple, ret);
 		goto exit0;
 	}
 
 	ret = pcmcia_get_tuple_data(link, &tuple);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, GetTupleData, ret);
 		goto exit0;
 	}
 
-	ret = pcmcia_parse_tuple(link, &tuple, &parse);
+	ret = pcmcia_parse_tuple(&tuple, &parse);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, ParseTuple, ret);
 		goto exit0;
 	}
@@ -152,21 +151,21 @@
 
 	ret = pcmcia_get_first_tuple(link, &tuple);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, GetFirstTuple, ret);
 		goto exit0;
 	}
 
 	ret = pcmcia_get_tuple_data(link, &tuple);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, GetTupleData, ret);
 		goto exit0;
 	}
 
-	ret = pcmcia_parse_tuple(link, &tuple, &parse);
+	ret = pcmcia_parse_tuple(&tuple, &parse);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, GetTupleData, ret);
 		goto exit0;
 	}
@@ -181,7 +180,7 @@
 
 	ret = pcmcia_request_io(link, &link->io);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, RequestIO, ret);
 		goto exit0;
 	}
@@ -195,21 +194,21 @@
 
 	ret = pcmcia_get_first_tuple(link, &tuple);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, GetFirstTuple, ret);
 		goto exit1;
 	}
 
 	ret = pcmcia_get_tuple_data(link, &tuple);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, GetTupleData, ret);
 		goto exit1;
 	}
 
-	ret = pcmcia_parse_tuple(link, &tuple, &parse);
+	ret = pcmcia_parse_tuple(&tuple, &parse);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, ParseTuple, ret);
 		goto exit1;
 	}
@@ -227,7 +226,7 @@
 		ret = pcmcia_request_window(&link, &ipw->request_common_memory,
 				&ipw->handle_common_memory);
 
-		if (ret != CS_SUCCESS) {
+		if (ret != 0) {
 			cs_error(link, RequestWindow, ret);
 			goto exit1;
 		}
@@ -239,7 +238,7 @@
 		ret = pcmcia_map_mem_page(ipw->handle_common_memory,
 				&memreq_common_memory);
 
-		if (ret != CS_SUCCESS) {
+		if (ret != 0) {
 			cs_error(link, MapMemPage, ret);
 			goto exit1;
 		}
@@ -261,7 +260,7 @@
 		ret = pcmcia_request_window(&link, &ipw->request_attr_memory,
 				&ipw->handle_attr_memory);
 
-		if (ret != CS_SUCCESS) {
+		if (ret != 0) {
 			cs_error(link, RequestWindow, ret);
 			goto exit2;
 		}
@@ -272,7 +271,7 @@
 		ret = pcmcia_map_mem_page(ipw->handle_attr_memory,
 				&memreq_attr_memory);
 
-		if (ret != CS_SUCCESS) {
+		if (ret != 0) {
 			cs_error(link, MapMemPage, ret);
 			goto exit2;
 		}
@@ -292,20 +291,11 @@
 
 	ret = pcmcia_request_irq(link, &link->irq);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, RequestIRQ, ret);
 		goto exit3;
 	}
 
-	/* Look up current Vcc */
-
-	ret = pcmcia_get_configuration_info(link, &conf);
-
-	if (ret != CS_SUCCESS) {
-		cs_error(link, GetConfigurationInfo, ret);
-		goto exit4;
-	}
-
 	printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
 			ipw->is_v2_card ? "V2/V3" : "V1");
 	printk(KERN_INFO IPWIRELESS_PCCARD_NAME
@@ -341,7 +331,7 @@
 	 */
 	ret = pcmcia_request_configuration(link, &link->conf);
 
-	if (ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, RequestConfiguration, ret);
 		goto exit4;
 	}
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index c240562..9a626e5 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -601,7 +601,7 @@
 
     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)
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index ee6fc30..cb199c8 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -219,103 +219,91 @@
 #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));
+    stk = kzalloc(sizeof(*stk), GFP_KERNEL);
+    if (!stk)
+	    goto err_mem;
+    stk->is_kme = is_kme;
+    stk->skip_vcc = io_base = ctl_base = 0;
 
-    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++;
-	}
+    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 +391,10 @@
 	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 */
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index a5b941c..c725655 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -154,83 +154,50 @@
     
 ======================================================================*/
 
-static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-		     cisparse_t *parse)
+static int avmcs_configcheck(struct pcmcia_device *p_dev,
+			     cistpl_cftable_entry_t *cf,
+			     cistpl_cftable_entry_t *dflt,
+			     unsigned int vcc,
+			     void *priv_data)
 {
-    int i = pcmcia_get_tuple_data(handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    return pcmcia_parse_tuple(handle, tuple, parse);
-}
+	if (cf->io.nwin <= 0)
+		return -ENODEV;
 
-static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-		     cisparse_t *parse)
-{
-    int i = pcmcia_get_first_tuple(handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    return get_tuple(handle, tuple, parse);
-}
-
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-		     cisparse_t *parse)
-{
-    int i = pcmcia_get_next_tuple(handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    return get_tuple(handle, tuple, parse);
+	p_dev->io.BasePort1 = cf->io.win[0].base;
+	p_dev->io.NumPorts1 = cf->io.win[0].len;
+	p_dev->io.NumPorts2 = 0;
+	printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
+	       p_dev->io.BasePort1,
+	       p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
+	return pcmcia_request_io(p_dev, &p_dev->io);
 }
 
 static int avmcs_config(struct pcmcia_device *link)
 {
-    tuple_t tuple;
-    cisparse_t parse;
-    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
     local_info_t *dev;
     int i;
-    u_char buf[64];
     char devname[128];
     int cardtype;
     int (*addcard)(unsigned int port, unsigned irq);
 
     dev = link->priv;
 
+    devname[0] = 0;
+    if (link->prod_id[1])
+	    strlcpy(devname, link->prod_id[1], sizeof(devname));
+
+    /*
+     * find IO port
+     */
+    if (pcmcia_loop_config(link, avmcs_configcheck, NULL))
+	    return -ENODEV;
+
     do {
-	devname[0] = 0;
-	if (link->prod_id[1])
-		strlcpy(devname, link->prod_id[1], sizeof(devname));
-
-	/*
-         * find IO port
-         */
-	tuple.TupleData = (cisdata_t *)buf;
-	tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
-	tuple.Attributes = 0;
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	i = first_tuple(link, &tuple, &parse);
-	while (i == CS_SUCCESS) {
-	    if (cf->io.nwin > 0) {
-		link->conf.ConfigIndex = cf->index;
-		link->io.BasePort1 = cf->io.win[0].base;
-		link->io.NumPorts1 = cf->io.win[0].len;
-		link->io.NumPorts2 = 0;
-                printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
-			link->io.BasePort1,
-		        link->io.BasePort1+link->io.NumPorts1-1);
-		i = pcmcia_request_io(link, &link->io);
-		if (i == CS_SUCCESS) goto found_port;
-	    }
-	    i = next_tuple(link, &tuple, &parse);
-	}
-
-found_port:
-	if (i != CS_SUCCESS) {
-	    cs_error(link, RequestIO, i);
-	    break;
-	}
-
 	/*
 	 * allocate an interrupt line
 	 */
 	i = pcmcia_request_irq(link, &link->irq);
-	if (i != CS_SUCCESS) {
+	if (i != 0) {
 	    cs_error(link, RequestIRQ, i);
 	    /* undo */
 	    pcmcia_disable_device(link);
@@ -241,7 +208,7 @@
          * configure the PCMCIA socket
 	  */
 	i = pcmcia_request_configuration(link, &link->conf);
-	if (i != CS_SUCCESS) {
+	if (i != 0) {
 	    cs_error(link, RequestConfiguration, i);
 	    pcmcia_disable_device(link);
 	    break;
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index fc6cc2c..23560c8 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -174,38 +174,29 @@
     
 ======================================================================*/
 
-static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-		     cisparse_t *parse)
+static int avma1cs_configcheck(struct pcmcia_device *p_dev,
+			       cistpl_cftable_entry_t *cf,
+			       cistpl_cftable_entry_t *dflt,
+			       unsigned int vcc,
+			       void *priv_data)
 {
-    int i = pcmcia_get_tuple_data(handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    return pcmcia_parse_tuple(handle, tuple, parse);
+	if (cf->io.nwin <= 0)
+		return -ENODEV;
+
+	p_dev->io.BasePort1 = cf->io.win[0].base;
+	p_dev->io.NumPorts1 = cf->io.win[0].len;
+	p_dev->io.NumPorts2 = 0;
+	printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
+	       p_dev->io.BasePort1,
+	       p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
+	return pcmcia_request_io(p_dev, &p_dev->io);
 }
 
-static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-		     cisparse_t *parse)
-{
-    int i = pcmcia_get_first_tuple(handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    return get_tuple(handle, tuple, parse);
-}
-
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-		     cisparse_t *parse)
-{
-    int i = pcmcia_get_next_tuple(handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    return get_tuple(handle, tuple, parse);
-}
 
 static int avma1cs_config(struct pcmcia_device *link)
 {
-    tuple_t tuple;
-    cisparse_t parse;
-    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
     local_info_t *dev;
     int i;
-    u_char buf[64];
     char devname[128];
     IsdnCard_t	icard;
     int busy = 0;
@@ -214,45 +205,19 @@
 
     DEBUG(0, "avma1cs_config(0x%p)\n", link);
 
+    devname[0] = 0;
+    if (link->prod_id[1])
+	    strlcpy(devname, link->prod_id[1], sizeof(devname));
+
+    if (pcmcia_loop_config(link, avma1cs_configcheck, NULL))
+	    return -ENODEV;
+
     do {
-	devname[0] = 0;
-	if (link->prod_id[1])
-		strlcpy(devname, link->prod_id[1], sizeof(devname));
-
-	/*
-         * find IO port
-         */
-	tuple.TupleData = (cisdata_t *)buf;
-	tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
-	tuple.Attributes = 0;
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	i = first_tuple(link, &tuple, &parse);
-	while (i == CS_SUCCESS) {
-	    if (cf->io.nwin > 0) {
-		link->conf.ConfigIndex = cf->index;
-		link->io.BasePort1 = cf->io.win[0].base;
-		link->io.NumPorts1 = cf->io.win[0].len;
-		link->io.NumPorts2 = 0;
-		printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
-			link->io.BasePort1,
-			link->io.BasePort1+link->io.NumPorts1 - 1);
-		i = pcmcia_request_io(link, &link->io);
-		if (i == CS_SUCCESS) goto found_port;
-	    }
-	    i = next_tuple(link, &tuple, &parse);
-	}
-
-found_port:
-	if (i != CS_SUCCESS) {
-	    cs_error(link, RequestIO, i);
-	    break;
-	}
-	
 	/*
 	 * allocate an interrupt line
 	 */
 	i = pcmcia_request_irq(link, &link->irq);
-	if (i != CS_SUCCESS) {
+	if (i != 0) {
 	    cs_error(link, RequestIRQ, i);
 	    /* undo */
 	    pcmcia_disable_device(link);
@@ -263,7 +228,7 @@
 	 * configure the PCMCIA socket
 	 */
 	i = pcmcia_request_configuration(link, &link->conf);
-	if (i != CS_SUCCESS) {
+	if (i != 0) {
 	    cs_error(link, RequestConfiguration, i);
 	    pcmcia_disable_device(link);
 	    break;
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index db7e644..f4d0fe2 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -203,82 +203,55 @@
     device available to the system.
 
 ======================================================================*/
-static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-                     cisparse_t *parse)
-{
-    int 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)
+static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
+			       cistpl_cftable_entry_t *cf,
+			       cistpl_cftable_entry_t *dflt,
+			       unsigned int vcc,
+			       void *priv_data)
 {
-    int i = pcmcia_get_first_tuple(handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    return get_tuple(handle, tuple, parse);
-}
+	int j;
 
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-                     cisparse_t *parse)
-{
-    int i = pcmcia_get_next_tuple(handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    return get_tuple(handle, tuple, parse);
+	if ((cf->io.nwin > 0) && cf->io.win[0].base) {
+		printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
+		p_dev->io.BasePort1 = cf->io.win[0].base;
+		if (!pcmcia_request_io(p_dev, &p_dev->io))
+			return 0;
+	} else {
+		printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
+		for (j = 0x2f0; j > 0x100; j -= 0x10) {
+			p_dev->io.BasePort1 = j;
+			if (!pcmcia_request_io(p_dev, &p_dev->io))
+				return 0;
+		}
+	}
+	return -ENODEV;
 }
 
 static int elsa_cs_config(struct pcmcia_device *link)
 {
-    tuple_t tuple;
-    cisparse_t parse;
     local_info_t *dev;
-    int i, j, last_fn;
-    u_short buf[128];
-    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
+    int i, last_fn;
     IsdnCard_t icard;
 
     DEBUG(0, "elsa_config(0x%p)\n", link);
     dev = link->priv;
 
-    tuple.TupleData = (cisdata_t *)buf;
-    tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
-    tuple.Attributes = 0;
-    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-    i = first_tuple(link, &tuple, &parse);
-    while (i == CS_SUCCESS) {
-        if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
-            printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
-            link->conf.ConfigIndex = cf->index;
-            link->io.BasePort1 = cf->io.win[0].base;
-            i = pcmcia_request_io(link, &link->io);
-            if (i == CS_SUCCESS) break;
-        } else {
-          printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
-          link->conf.ConfigIndex = cf->index;
-          for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
-            link->io.BasePort1 = j;
-            i = pcmcia_request_io(link, &link->io);
-            if (i == CS_SUCCESS) break;
-          }
-          break;
-        }
-        i = next_tuple(link, &tuple, &parse);
-    }
-
-    if (i != CS_SUCCESS) {
+    i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
+    if (i != 0) {
 	last_fn = RequestIO;
 	goto cs_failed;
     }
 
     i = pcmcia_request_irq(link, &link->irq);
-    if (i != CS_SUCCESS) {
+    if (i != 0) {
         link->irq.AssignedIRQ = 0;
 	last_fn = RequestIRQ;
         goto cs_failed;
     }
 
     i = pcmcia_request_configuration(link, &link->conf);
-    if (i != CS_SUCCESS) {
+    if (i != 0) {
       last_fn = RequestConfiguration;
       goto cs_failed;
     }
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 439cb53..9a3c9f5 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -217,101 +217,61 @@
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
-static int sedlbauer_config(struct pcmcia_device *link)
+static int sedlbauer_config_check(struct pcmcia_device *p_dev,
+				  cistpl_cftable_entry_t *cfg,
+				  cistpl_cftable_entry_t *dflt,
+				  unsigned int vcc,
+				  void *priv_data)
 {
-    local_info_t *dev = link->priv;
-    tuple_t tuple;
-    cisparse_t parse;
-    int last_fn, last_ret;
-    u8 buf[64];
-    config_info_t conf;
-    win_req_t req;
-    memreq_t map;
-    IsdnCard_t  icard;
+	win_req_t *req = priv_data;
 
-    DEBUG(0, "sedlbauer_config(0x%p)\n", link);
+	if (cfg->index == 0)
+		return -ENODEV;
 
-    tuple.Attributes = 0;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = sizeof(buf);
-    tuple.TupleOffset = 0;
-
-    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 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.
-    */
-    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;
+		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;
+		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 =
-		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;
-	
+		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)
-	    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;
-	    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;
-/* new in dummy.cs 2001/01/28 MN 
-            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;
+	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;
 	}
 
 	/*
@@ -325,30 +285,54 @@
 	  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.Attributes |= WIN_ENABLE;
-	    req.Base = mem->win[0].host_addr;
-	    req.Size = mem->win[0].len;
-/* new in dummy.cs 2001/01/28 MN 
-            if (req.Size < 0x1000)
-                req.Size = 0x1000;
-*/
-	    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 ((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->Attributes |= WIN_ENABLE;
+		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! */
-	break;
+	return 0;
+}
 
-    next_entry:
-	CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
-    }
+
+
+static int sedlbauer_config(struct pcmcia_device *link)
+{
+    local_info_t *dev = link->priv;
+    win_req_t *req;
+    int last_fn, last_ret;
+    IsdnCard_t  icard;
+
+    DEBUG(0, "sedlbauer_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, sedlbauer_config_check, req);
+    if (last_ret)
+	    goto failed;
 
     /*
        Allocate an interrupt line.  Note that this does not assign a
@@ -387,8 +371,8 @@
 	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");
 
     icard.para[0] = link->irq.AssignedIRQ;
@@ -409,6 +393,7 @@
 
 cs_failed:
     cs_error(link, last_fn, last_ret);
+failed:
     sedlbauer_release(link);
     return -ENODEV;
 
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index ab4bd45..623d111 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -193,82 +193,55 @@
     device available to the system.
 
 ======================================================================*/
-static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-                     cisparse_t *parse)
-{
-    int 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)
+static int teles_cs_configcheck(struct pcmcia_device *p_dev,
+				cistpl_cftable_entry_t *cf,
+				cistpl_cftable_entry_t *dflt,
+				unsigned int vcc,
+				void *priv_data)
 {
-    int i = pcmcia_get_first_tuple(handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    return get_tuple(handle, tuple, parse);
-}
+	int j;
 
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-                     cisparse_t *parse)
-{
-    int i = pcmcia_get_next_tuple(handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    return get_tuple(handle, tuple, parse);
+	if ((cf->io.nwin > 0) && cf->io.win[0].base) {
+		printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
+		p_dev->io.BasePort1 = cf->io.win[0].base;
+		if (!pcmcia_request_io(p_dev, &p_dev->io))
+			return 0;
+	} else {
+		printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
+		for (j = 0x2f0; j > 0x100; j -= 0x10) {
+			p_dev->io.BasePort1 = j;
+			if (!pcmcia_request_io(p_dev, &p_dev->io))
+				return 0;
+		}
+	}
+	return -ENODEV;
 }
 
 static int teles_cs_config(struct pcmcia_device *link)
 {
-    tuple_t tuple;
-    cisparse_t parse;
     local_info_t *dev;
-    int i, j, last_fn;
-    u_short buf[128];
-    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
+    int i, last_fn;
     IsdnCard_t icard;
 
     DEBUG(0, "teles_config(0x%p)\n", link);
     dev = link->priv;
 
-    tuple.TupleData = (cisdata_t *)buf;
-    tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
-    tuple.Attributes = 0;
-    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-    i = first_tuple(link, &tuple, &parse);
-    while (i == CS_SUCCESS) {
-        if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
-            printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
-            link->conf.ConfigIndex = cf->index;
-            link->io.BasePort1 = cf->io.win[0].base;
-            i = pcmcia_request_io(link, &link->io);
-            if (i == CS_SUCCESS) break;
-        } else {
-          printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
-          link->conf.ConfigIndex = cf->index;
-          for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
-            link->io.BasePort1 = j;
-            i = pcmcia_request_io(link, &link->io);
-            if (i == CS_SUCCESS) break;
-          }
-          break;
-        }
-        i = next_tuple(link, &tuple, &parse);
-    }
-
-    if (i != CS_SUCCESS) {
+    i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
+    if (i != 0) {
 	last_fn = RequestIO;
 	goto cs_failed;
     }
 
     i = pcmcia_request_irq(link, &link->irq);
-    if (i != CS_SUCCESS) {
+    if (i != 0) {
         link->irq.AssignedIRQ = 0;
 	last_fn = RequestIRQ;
         goto cs_failed;
     }
 
     i = pcmcia_request_configuration(link, &link->conf);
-    if (i != CS_SUCCESS) {
+    if (i != 0) {
       last_fn = RequestConfiguration;
       goto cs_failed;
     }
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index 90924fb..d600c2d 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -118,7 +118,8 @@
 		DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
 		      dev->offset, mrq.CardOffset);
 		mrq.Page = 0;
-		if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) {
+		ret = pcmcia_map_mem_page(win, &mrq);
+		if (ret != 0) {
 			cs_error(dev->p_dev, MapMemPage, ret);
 			return NULL;
 		}
@@ -326,9 +327,8 @@
 
 	DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
 	ret = pcmcia_modify_configuration(link, &mod);
-	if(ret != CS_SUCCESS) {
+	if (ret != 0)
 		cs_error(link, ModifyConfiguration, ret);
-	}
 }
 
 
@@ -368,14 +368,14 @@
 	tuple.DesiredTuple = RETURN_FIRST_TUPLE;
 
 	rc = pcmcia_get_first_tuple(link, &tuple);
-	while(rc == CS_SUCCESS) {
+	while (rc == 0) {
 		rc = pcmcia_get_tuple_data(link, &tuple);
-		if(rc != CS_SUCCESS) {
+		if (rc != 0) {
 			cs_error(link, GetTupleData, rc);
 			break;
 		}
-		rc = pcmcia_parse_tuple(link, &tuple, &parse);
-		if(rc != CS_SUCCESS) {
+		rc = pcmcia_parse_tuple(&tuple, &parse);
+		if (rc != 0) {
 			cs_error(link, ParseTuple, rc);
 			break;
 		}
@@ -493,18 +493,11 @@
 	int last_ret = 0, last_fn = 0;
 	int ret;
 	int i;
-	config_info_t t;
 	static char *probes[] = { "jedec_probe", "cfi_probe" };
 	int new_name = 0;
 
 	DEBUG(3, "link=0x%p", link);
 
-	DEBUG(2, "Validating CIS");
-	ret = pcmcia_validate_cis(link, NULL);
-	if(ret != CS_SUCCESS) {
-		cs_error(link, GetTupleData, ret);
-	}
-
 	card_settings(dev, link, &new_name);
 
 	dev->pcmcia_map.phys = NO_XIP;
@@ -571,10 +564,7 @@
 	dev->pcmcia_map.map_priv_1 = (unsigned long)dev;
 	dev->pcmcia_map.map_priv_2 = (unsigned long)link->win;
 
-	DEBUG(2, "Getting configuration");
-	CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &t));
-	DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2);
-	dev->vpp = (vpp) ? vpp : t.Vpp1;
+	dev->vpp = (vpp) ? vpp : link->socket.socket.Vpp;
 	link->conf.Attributes = 0;
 	if(setvpp == 2) {
 		link->conf.Vpp = dev->vpp;
@@ -583,16 +573,10 @@
 	}
 
 	link->conf.IntType = INT_MEMORY;
-	link->conf.ConfigBase = t.ConfigBase;
-	link->conf.Status = t.Status;
-	link->conf.Pin = t.Pin;
-	link->conf.Copy = t.Copy;
-	link->conf.ExtStatus = t.ExtStatus;
 	link->conf.ConfigIndex = 0;
-	link->conf.Present = t.Present;
 	DEBUG(2, "Setting Configuration");
 	ret = pcmcia_request_configuration(link, &link->conf);
-	if(ret != CS_SUCCESS) {
+	if (ret != 0) {
 		cs_error(link, RequestConfiguration, ret);
 		if (dev->win_base) {
 			iounmap(dev->win_base);
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 7112fd5..08c4dd8 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -355,9 +355,10 @@
 	for (i = j = 0; 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;
 	}
@@ -377,7 +378,7 @@
 	tuple.TupleDataMax = 64;
 	tuple.TupleOffset = 0;
 	tuple.DesiredTuple = 0x88;
-	if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
+	if (pcmcia_get_first_tuple(link, &tuple) == 0) {
 		pcmcia_get_tuple_data(link, &tuple);
 		for (i = 0; i < 3; i++)
 			phys_addr[i] = htons(le16_to_cpu(buf[i]));
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 549a645..0b28d0d 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -278,9 +278,10 @@
 	if (multi && (j & 0x80)) continue;
 	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;
     }
@@ -295,7 +296,7 @@
     /* The 3c589 has an extra EEPROM for configuration info, including
        the hardware address.  The 3c562 puts the address in the CIS. */
     tuple.DesiredTuple = 0x88;
-    if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
+    if (pcmcia_get_first_tuple(link, &tuple) == 0) {
 	pcmcia_get_tuple_data(link, &tuple);
 	for (i = 0; i < 3; i++)
 	    phys_addr[i] = htons(le16_to_cpu(buf[i]));
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 52bf11b..b37a498 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -262,7 +262,7 @@
 	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 {
@@ -276,7 +276,8 @@
 	    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 {
@@ -284,59 +285,50 @@
     }
 }
 
+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;
     }
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index ea9414c..831090c 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -260,21 +260,21 @@
     DEBUG(0, "com20020_config(0x%p)\n", link);
 
     DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
-    i = !CS_SUCCESS;
+    i = -ENODEV;
     if (!link->io.BasePort1)
     {
 	for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
 	{
 	    link->io.BasePort1 = ioaddr;
 	    i = pcmcia_request_io(link, &link->io);
-	    if (i == CS_SUCCESS)
+	    if (i == 0)
 		break;
 	}
     }
     else
 	i = pcmcia_request_io(link, &link->io);
     
-    if (i != CS_SUCCESS)
+    if (i != 0)
     {
 	DEBUG(1,"arcnet: requestIO failed totally!\n");
 	goto failed;
@@ -287,7 +287,7 @@
 	   link->irq.AssignedIRQ,
 	   link->irq.IRQInfo1, link->irq.IRQInfo2);
     i = pcmcia_request_irq(link, &link->irq);
-    if (i != CS_SUCCESS)
+    if (i != 0)
     {
 	DEBUG(1,"arcnet: requestIRQ failed totally!\n");
 	goto failed;
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index a550c9b..69d916d 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -309,7 +309,8 @@
 	    printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n");
 	}
 	ret = pcmcia_request_io(link, &link->io);
-	if (ret == CS_SUCCESS) return ret;
+	if (ret == 0)
+		return ret;
     }
     return ret;
 }
@@ -325,7 +326,7 @@
     for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) {
 	link->io.BasePort1 = ioaddr;
 	ret = pcmcia_request_io(link, &link->io);
-	if (ret == CS_SUCCESS) {
+	if (ret == 0) {
 	    /* calculate ConfigIndex value */
 	    link->conf.ConfigIndex = 
 		((link->io.BasePort1 & 0x0f0) >> 3) | 0x22;
@@ -356,12 +357,12 @@
     tuple.TupleOffset = 0;
     tuple.DesiredTuple = CISTPL_FUNCE;
     tuple.TupleOffset = 0;
-    if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
+    if (pcmcia_get_first_tuple(link, &tuple) == 0) {
 	/* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
 	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
 	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
 	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));
 	link->conf.ConfigIndex = parse.cftable_entry.index;
 	switch (link->manf_id) {
 	case MANFID_TDK:
@@ -430,10 +431,10 @@
     	link->irq.Attributes =
 		IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
 	ret = mfc_try_io_port(link);
-	if (ret != CS_SUCCESS) goto cs_failed;
+	if (ret != 0) goto cs_failed;
     } else if (cardtype == UNGERMANN) {
 	ret = ungermann_try_io_port(link);
-	if (ret != CS_SUCCESS) goto cs_failed;
+	if (ret != 0) goto cs_failed;
     } else { 
 	CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
     }
@@ -565,7 +566,7 @@
     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 -1;
     }
@@ -599,7 +600,7 @@
 
     iounmap(base);
     j = pcmcia_release_window(link->win);
-    if (j != CS_SUCCESS)
+    if (j != 0)
 	cs_error(link, ReleaseWindow, j);
     return (i != 0x200) ? 0 : -1;
 
@@ -620,7 +621,7 @@
     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 -1;
     }
@@ -642,7 +643,7 @@
 
     iounmap(base);
     j = pcmcia_release_window(link->win);
-    if (j != CS_SUCCESS)
+    if (j != 0)
 	cs_error(link, ReleaseWindow, j);
     return 0;
 
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index 4eafa4f..cf3cca4 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -238,7 +238,7 @@
     /* Try PRIMARY card at 0xA20-0xA23 */
     link->io.BasePort1 = 0xA20;
     i = pcmcia_request_io(link, &link->io);
-    if (i != CS_SUCCESS) {
+    if (i != 0) {
 	/* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */
 	link->io.BasePort1 = 0xA24;
 	CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index cfcbea9..54df34f 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -925,7 +925,7 @@
   printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name);
 #if RESET_ON_TIMEOUT
   printk("resetting card\n");
-  pcmcia_reset_card(link, NULL);
+  pcmcia_reset_card(link->socket);
 #else /* #if RESET_ON_TIMEOUT */
   printk("NOT resetting card\n");
 #endif /* #if RESET_ON_TIMEOUT */
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index ebc1ae6..e40d630 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -310,7 +310,7 @@
     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;
     }
@@ -333,7 +333,7 @@
 
     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 @@
 	    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 {
@@ -512,58 +513,53 @@
     }
 }
 
+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;
     }
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 250eb19..c74d665 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -409,10 +409,13 @@
 {
 	int i;
 
-	if ((i = pcmcia_get_first_tuple(handle, tuple)) != CS_SUCCESS ||
-			(i = pcmcia_get_tuple_data(handle, tuple)) != CS_SUCCESS)
+	i = pcmcia_get_first_tuple(handle, tuple);
+	if (i != 0)
 		return i;
-	return pcmcia_parse_tuple(handle, tuple, parse);
+	i = pcmcia_get_tuple_data(handle, tuple);
+	if (i != 0)
+		return i;
+	return pcmcia_parse_tuple(tuple, parse);
 }
 
 static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
@@ -420,10 +423,10 @@
 {
 	int i;
 
-	if ((i = pcmcia_get_next_tuple(handle, tuple)) != CS_SUCCESS ||
-			(i = pcmcia_get_tuple_data(handle, tuple)) != CS_SUCCESS)
+	if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
+			(i = pcmcia_get_tuple_data(handle, tuple)) != 0)
 		return i;
-	return pcmcia_parse_tuple(handle, tuple, parse);
+	return pcmcia_parse_tuple(tuple, parse);
 }
 
 /*======================================================================
@@ -459,27 +462,36 @@
     return 0;
 }
 
+static int mhz_mfc_config_check(struct pcmcia_device *p_dev,
+				cistpl_cftable_entry_t *cf,
+				cistpl_cftable_entry_t *dflt,
+				unsigned int vcc,
+				void *priv_data)
+{
+	int k;
+	p_dev->io.BasePort2 = cf->io.win[0].base;
+	for (k = 0; k < 0x400; k += 0x10) {
+		if (k & 0x80)
+			continue;
+		p_dev->io.BasePort1 = k ^ 0x300;
+		if (!pcmcia_request_io(p_dev, &p_dev->io))
+			return 0;
+	}
+	return -ENODEV;
+}
+
 static int mhz_mfc_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
     struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    cisparse_t *parse;
-    cistpl_cftable_entry_t *cf;
-    u_char *buf;
     win_req_t req;
     memreq_t mem;
-    int i, k;
+    int i;
 
     cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
     if (!cfg_mem)
-        return CS_OUT_OF_RESOURCE;
-
-    tuple = &cfg_mem->tuple;
-    parse = &cfg_mem->parse;
-    cf = &parse->cftable_entry;
-    buf = cfg_mem->buf;
+	    return -ENOMEM;
 
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
@@ -489,27 +501,9 @@
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
 
-    tuple->Attributes = tuple->TupleOffset = 0;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
-    tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
-    i = first_tuple(link, tuple, parse);
     /* The Megahertz combo cards have modem-like CIS entries, so
        we have to explicitly try a bunch of port combinations. */
-    while (i == CS_SUCCESS) {
-	link->conf.ConfigIndex = cf->index;
-	link->io.BasePort2 = cf->io.win[0].base;
-	for (k = 0; k < 0x400; k += 0x10) {
-	    if (k & 0x80) continue;
-	    link->io.BasePort1 = k ^ 0x300;
-	    i = pcmcia_request_io(link, &link->io);
-	    if (i == CS_SUCCESS) break;
-	}
-	if (i == CS_SUCCESS) break;
-	i = next_tuple(link, tuple, parse);
-    }
-    if (i != CS_SUCCESS)
+    if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
 	goto free_cfg_mem;
     dev->base_addr = link->io.BasePort1;
 
@@ -518,7 +512,7 @@
     req.Base = req.Size = 0;
     req.AccessSpeed = 0;
     i = pcmcia_request_window(&link, &req, &link->win);
-    if (i != CS_SUCCESS)
+    if (i != 0)
 	goto free_cfg_mem;
     smc->base = ioremap(req.Base, req.Size);
     mem.CardOffset = mem.Page = 0;
@@ -526,14 +520,14 @@
 	mem.CardOffset = link->conf.ConfigBase;
     i = pcmcia_map_mem_page(link->win, &mem);
 
-    if ((i == CS_SUCCESS)
+    if ((i == 0)
 	&& (smc->manfid == MANFID_MEGAHERTZ)
 	&& (smc->cardid == PRODID_MEGAHERTZ_EM3288))
 	mhz_3288_power(link);
 
 free_cfg_mem:
     kfree(cfg_mem);
-    return i;
+    return -ENODEV;
 }
 
 static int mhz_setup(struct pcmcia_device *link)
@@ -560,12 +554,12 @@
     /* Read the station address from the CIS.  It is stored as the last
        (fourth) string in the Version 1 Version/ID tuple. */
     tuple->DesiredTuple = CISTPL_VERS_1;
-    if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
+    if (first_tuple(link, tuple, parse) != 0) {
 	rc = -1;
 	goto free_cfg_mem;
     }
     /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
-    if (next_tuple(link, tuple, parse) != CS_SUCCESS)
+    if (next_tuple(link, tuple, parse) != 0)
 	first_tuple(link, tuple, parse);
     if (parse->version_1.ns > 3) {
 	station_addr = parse->version_1.str + parse->version_1.ofs[3];
@@ -577,11 +571,11 @@
 
     /* Another possibility: for the EM3288, in a special tuple */
     tuple->DesiredTuple = 0x81;
-    if (pcmcia_get_first_tuple(link, tuple) != CS_SUCCESS) {
+    if (pcmcia_get_first_tuple(link, tuple) != 0) {
 	rc = -1;
 	goto free_cfg_mem;
     }
-    if (pcmcia_get_tuple_data(link, tuple) != CS_SUCCESS) {
+    if (pcmcia_get_tuple_data(link, tuple) != 0) {
 	rc = -1;
 	goto free_cfg_mem;
     }
@@ -660,46 +654,27 @@
 
 /*====================================================================*/
 
+static int smc_configcheck(struct pcmcia_device *p_dev,
+			   cistpl_cftable_entry_t *cf,
+			   cistpl_cftable_entry_t *dflt,
+			   unsigned int vcc,
+			   void *priv_data)
+{
+	p_dev->io.BasePort1 = cf->io.win[0].base;
+	p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
+	return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
 static int smc_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    cisparse_t *parse;
-    cistpl_cftable_entry_t *cf;
-    u_char *buf;
     int i;
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-	return CS_OUT_OF_RESOURCE;
-
-    tuple = &cfg_mem->tuple;
-    parse = &cfg_mem->parse;
-    cf = &parse->cftable_entry;
-    buf = cfg_mem->buf;
-
-    tuple->Attributes = tuple->TupleOffset = 0;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
-    tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
     link->io.NumPorts1 = 16;
-    i = first_tuple(link, tuple, parse);
-    while (i != CS_NO_MORE_ITEMS) {
-	if (i == CS_SUCCESS) {
-	    link->conf.ConfigIndex = cf->index;
-	    link->io.BasePort1 = cf->io.win[0].base;
-	    link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-	    i = pcmcia_request_io(link, &link->io);
-	    if (i == CS_SUCCESS) break;
-	}
-	i = next_tuple(link, tuple, parse);
-    }
-    if (i == CS_SUCCESS)
-	dev->base_addr = link->io.BasePort1;
+    i = pcmcia_loop_config(link, smc_configcheck, NULL);
+    if (!i)
+	    dev->base_addr = link->io.BasePort1;
 
-    kfree(cfg_mem);
     return i;
 }
 
@@ -715,7 +690,7 @@
 
     cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
     if (!cfg_mem)
-	return CS_OUT_OF_RESOURCE;
+	    return -ENOMEM;
 
     tuple = &cfg_mem->tuple;
     parse = &cfg_mem->parse;
@@ -728,12 +703,12 @@
     /* Check for a LAN function extension tuple */
     tuple->DesiredTuple = CISTPL_FUNCE;
     i = first_tuple(link, tuple, parse);
-    while (i == CS_SUCCESS) {
+    while (i == 0) {
 	if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
 	    break;
 	i = next_tuple(link, tuple, parse);
     }
-    if (i == CS_SUCCESS) {
+    if (i == 0) {
 	node_id = (cistpl_lan_node_id_t *)parse->funce.data;
 	if (node_id->nb == 6) {
 	    for (i = 0; i < 6; i++)
@@ -780,9 +755,10 @@
     for (i = j = 0; j < 4; j++) {
 	link->io.BasePort2 = com[j];
 	i = pcmcia_request_io(link, &link->io);
-	if (i == CS_SUCCESS) break;
+	if (i == 0)
+		break;
     }
-    if (i != CS_SUCCESS) {
+    if (i != 0) {
 	/* Fallback: turn off hard decode */
 	link->conf.ConfigIndex = 0x03;
 	link->io.NumPorts2 = 0;
@@ -815,13 +791,13 @@
     /* Read the station address from tuple 0x90, subtuple 0x04 */
     tuple->DesiredTuple = 0x90;
     i = pcmcia_get_first_tuple(link, tuple);
-    while (i == CS_SUCCESS) {
+    while (i == 0) {
 	i = pcmcia_get_tuple_data(link, tuple);
-	if ((i != CS_SUCCESS) || (buf[0] == 0x04))
+	if ((i != 0) || (buf[0] == 0x04))
 	    break;
 	i = pcmcia_get_next_tuple(link, tuple);
     }
-    if (i != CS_SUCCESS) {
+    if (i != 0) {
 	rc = -1;
 	goto free_cfg_mem;
     }
@@ -959,8 +935,11 @@
 
 ======================================================================*/
 
-#define CS_EXIT_TEST(ret, svc, label) \
-if (ret != CS_SUCCESS) { cs_error(link, svc, ret); goto label; }
+#define CS_EXIT_TEST(ret, svc, label)	\
+if (ret != 0) {				\
+	cs_error(link, svc, ret);	\
+	goto label; 			\
+}
 
 static int smc91c92_config(struct pcmcia_device *link)
 {
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index c33a3d5..e1fd585 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -377,7 +377,7 @@
 
 	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 @@
 
 	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;
 }
 
@@ -715,6 +715,47 @@
 	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 @@
 {
     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;
@@ -846,19 +886,8 @@
 	    /* 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
@@ -866,21 +895,9 @@
 	     * 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.
 	     * .... */
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index fd72e42..27696c2 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -206,126 +206,123 @@
 #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.
+	 * 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;
+
+	/*
+	  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));
 	
@@ -362,14 +359,17 @@
 		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 */
 
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index d2388e8..7740624 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -224,13 +224,58 @@
 	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;
@@ -238,11 +283,6 @@
 
 	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
@@ -255,66 +295,8 @@
 	  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
@@ -360,6 +342,7 @@
 
  cs_failed:
 	cs_error(link, last_fn, last_ret);
+ failed:
 	atmel_release(link);
 	return -ENODEV;
 }
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c
index b8aa163..3cfc303 100644
--- a/drivers/net/wireless/b43/pcmcia.c
+++ b/drivers/net/wireless/b43/pcmcia.c
@@ -82,13 +82,13 @@
 	tuple.TupleOffset = 0;
 
 	res = pcmcia_get_first_tuple(dev, &tuple);
-	if (res != CS_SUCCESS)
+	if (res != 0)
 		goto err_kfree_ssb;
 	res = pcmcia_get_tuple_data(dev, &tuple);
-	if (res != CS_SUCCESS)
+	if (res != 0)
 		goto err_kfree_ssb;
-	res = pcmcia_parse_tuple(dev, &tuple, &parse);
-	if (res != CS_SUCCESS)
+	res = pcmcia_parse_tuple(&tuple, &parse);
+	if (res != 0)
 		goto err_kfree_ssb;
 
 	dev->conf.ConfigBase = parse.config.base;
@@ -107,13 +107,13 @@
 	win.Size = SSB_CORE_SIZE;
 	win.AccessSpeed = 250;
 	res = pcmcia_request_window(&dev, &win, &dev->win);
-	if (res != CS_SUCCESS)
+	if (res != 0)
 		goto err_kfree_ssb;
 
 	mem.CardOffset = 0;
 	mem.Page = 0;
 	res = pcmcia_map_mem_page(dev->win, &mem);
-	if (res != CS_SUCCESS)
+	if (res != 0)
 		goto err_disable;
 
 	dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
@@ -121,11 +121,11 @@
 	dev->irq.Handler = NULL; /* The handler is registered later. */
 	dev->irq.Instance = NULL;
 	res = pcmcia_request_irq(dev, &dev->irq);
-	if (res != CS_SUCCESS)
+	if (res != 0)
 		goto err_disable;
 
 	res = pcmcia_request_configuration(dev, &dev->conf);
-	if (res != CS_SUCCESS)
+	if (res != 0)
 		goto err_disable;
 
 	err = ssb_bus_pcmciabus_register(ssb, dev, win.Base);
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 3b4e55c..6337402 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -234,7 +234,7 @@
 	reg.Value = hw_priv->link->io.BasePort1 & 0x00ff;
 	res = pcmcia_access_configuration_register(hw_priv->link,
 						   &reg);
-	if (res != CS_SUCCESS) {
+	if (res != 0) {
 		printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -"
 		       " res=%d\n", res);
 	}
@@ -246,7 +246,7 @@
 	reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8;
 	res = pcmcia_access_configuration_register(hw_priv->link,
 						   &reg);
-	if (res != CS_SUCCESS) {
+	if (res != 0) {
 		printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -"
 		       " res=%d\n", res);
 	}
@@ -305,7 +305,7 @@
 	tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
 	if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
 	    pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
-	    pcmcia_parse_tuple(hw_priv->link, &tuple, parse) ||
+	    pcmcia_parse_tuple(&tuple, parse) ||
 		parse->longlink_mfc.nfn < 2) {
 		/* No multi-function links found */
 		ret = -ENODEV;
@@ -322,7 +322,7 @@
 	reg.Value = COR_SOFT_RESET;
 	res = pcmcia_access_configuration_register(hw_priv->link,
 						   &reg);
-	if (res != CS_SUCCESS) {
+	if (res != 0) {
 		printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
 		       dev->name, res);
 		goto done;
@@ -339,7 +339,7 @@
 	reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA;
 	res = pcmcia_access_configuration_register(hw_priv->link,
 						   &reg);
-	if (res != CS_SUCCESS) {
+	if (res != 0) {
 		printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
 		       dev->name, res);
 		goto done;
@@ -374,7 +374,7 @@
 	reg.Value = 0;
 	res = pcmcia_access_configuration_register(hw_priv->link,
 						   &reg);
-	if (res != CS_SUCCESS) {
+	if (res != 0) {
 		printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n",
 		       res);
 		return;
@@ -386,7 +386,7 @@
 	reg.Value |= COR_SOFT_RESET;
 	res = pcmcia_access_configuration_register(hw_priv->link,
 						   &reg);
-	if (res != CS_SUCCESS) {
+	if (res != 0) {
 		printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n",
 		       res);
 		return;
@@ -399,7 +399,7 @@
 		reg.Value |= COR_IREQ_ENA;
 	res = pcmcia_access_configuration_register(hw_priv->link,
 						   &reg);
-	if (res != CS_SUCCESS) {
+	if (res != 0) {
 		printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n",
 		       res);
 		return;
@@ -433,7 +433,7 @@
 	reg.Value = 0;
 	res = pcmcia_access_configuration_register(hw_priv->link,
 						   &reg);
-	if (res != CS_SUCCESS) {
+	if (res != 0) {
 		printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 "
 		       "(%d)\n", res);
 		return;
@@ -446,7 +446,7 @@
 	reg.Value |= COR_SOFT_RESET;
 	res = pcmcia_access_configuration_register(hw_priv->link,
 						   &reg);
-	if (res != CS_SUCCESS) {
+	if (res != 0) {
 		printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 "
 		       "(%d)\n", res);
 		return;
@@ -460,7 +460,7 @@
 	reg.Offset = CISREG_CCSR;
 	res = pcmcia_access_configuration_register(hw_priv->link,
 						   &reg);
-	if (res != CS_SUCCESS) {
+	if (res != 0) {
 		printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 "
 		       "(%d)\n", res);
 		return;
@@ -472,7 +472,7 @@
 	reg.Value = old_cor & ~COR_SOFT_RESET;
 	res = pcmcia_access_configuration_register(hw_priv->link,
 						   &reg);
-	if (res != CS_SUCCESS) {
+	if (res != 0) {
 		printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 "
 		       "(%d)\n", res);
 		return;
@@ -532,145 +532,118 @@
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
-#define CFG_CHECK2(fn, retf) \
-do { int _ret = (retf); \
-if (_ret != 0) { \
-	PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \
-	cs_error(link, fn, _ret); \
-	goto next_entry; \
-} \
-} while (0)
-
 
 /* run after a CARD_INSERTION event is received to configure the PCMCIA
  * socket and make the device available to the system */
+
+static int prism2_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;
+
+	PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
+	       "(default 0x%02X)\n", cfg->index, dflt->index);
+
+	/* 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 (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
+		    10000 && !ignore_cis_vcc) {
+			PDEBUG(DEBUG_EXTRA, "  Vcc mismatch - skipping"
+			       " this entry\n");
+			return -ENODEV;
+		}
+	} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+		if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] /
+		    10000 && !ignore_cis_vcc) {
+			PDEBUG(DEBUG_EXTRA, "  Vcc (default) mismatch "
+			       "- skipping this entry\n");
+			return -ENODEV;
+		}
+	}
+
+	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;
+	else if (!(p_dev->conf.Attributes & CONF_ENABLE_IRQ)) {
+		/* At least Compaq WL200 does not have IRQInfo1 set,
+		 * but it does not work without interrupts.. */
+		printk(KERN_WARNING "Config has no IRQ info, but trying to "
+		       "enable IRQ anyway..\n");
+		p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+	}
+
+	/* IO window settings */
+	PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
+	       "dflt->io.nwin=%d\n",
+	       cfg->io.nwin, dflt->io.nwin);
+	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;
+		PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
+		       "io.base=0x%04x, len=%d\n", io->flags,
+		       io->win[0].base, io->win[0].len);
+		if (!(io->flags & CISTPL_IO_8BIT))
+			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+		if (!(io->flags & CISTPL_IO_16BIT))
+			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+		p_dev->io.IOAddrLines = io->flags &
+			CISTPL_IO_LINES_MASK;
+		p_dev->io.BasePort1 = io->win[0].base;
+		p_dev->io.NumPorts1 = io->win[0].len;
+		if (io->nwin > 1) {
+			p_dev->io.Attributes2 = p_dev->io.Attributes1;
+			p_dev->io.BasePort2 = io->win[1].base;
+			p_dev->io.NumPorts2 = io->win[1].len;
+		}
+	}
+
+	/* This reserves IO space but doesn't actually enable it */
+	return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
 static int prism2_config(struct pcmcia_device *link)
 {
 	struct net_device *dev;
 	struct hostap_interface *iface;
 	local_info_t *local;
 	int ret = 1;
-	tuple_t tuple;
-	cisparse_t *parse;
 	int last_fn, last_ret;
-	u_char buf[64];
-	config_info_t conf;
-	cistpl_cftable_entry_t dflt = { 0 };
 	struct hostap_cs_priv *hw_priv;
 
 	PDEBUG(DEBUG_FLOW, "prism2_config()\n");
 
-	parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
 	hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
-	if (parse == NULL || hw_priv == NULL) {
+	if (hw_priv == NULL) {
 		ret = -ENOMEM;
 		goto failed;
 	}
 
-	tuple.Attributes = 0;
-	tuple.TupleData = buf;
-	tuple.TupleDataMax = sizeof(buf);
-	tuple.TupleOffset = 0;
-
-	CS_CHECK(GetConfigurationInfo,
-		 pcmcia_get_configuration_info(link, &conf));
-
 	/* Look for an appropriate configuration table entry in the CIS */
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-	for (;;) {
-		cistpl_cftable_entry_t *cfg = &(parse->cftable_entry);
-		CFG_CHECK2(GetTupleData,
-			   pcmcia_get_tuple_data(link, &tuple));
-		CFG_CHECK2(ParseTuple,
-			   pcmcia_parse_tuple(link, &tuple, parse));
-
-		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-			dflt = *cfg;
-		if (cfg->index == 0)
-			goto next_entry;
-		link->conf.ConfigIndex = cfg->index;
-		PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
-		       "(default 0x%02X)\n", cfg->index, dflt.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->vcc.present & (1 << CISTPL_POWER_VNOM)) {
-			if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
-			    10000 && !ignore_cis_vcc) {
-				PDEBUG(DEBUG_EXTRA, "  Vcc mismatch - skipping"
-				       " this entry\n");
-				goto next_entry;
-			}
-		} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
-			if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] /
-			    10000 && !ignore_cis_vcc) {
-				PDEBUG(DEBUG_EXTRA, "  Vcc (default) mismatch "
-				       "- skipping this entry\n");
-				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? */
-		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
-			link->conf.Attributes |= CONF_ENABLE_IRQ;
-		else if (!(link->conf.Attributes & CONF_ENABLE_IRQ)) {
-			/* At least Compaq WL200 does not have IRQInfo1 set,
-			 * but it does not work without interrupts.. */
-			printk("Config has no IRQ info, but trying to enable "
-			       "IRQ anyway..\n");
-			link->conf.Attributes |= CONF_ENABLE_IRQ;
-		}
-
-		/* IO window settings */
-		PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
-		       "dflt.io.nwin=%d\n",
-		       cfg->io.nwin, dflt.io.nwin);
-		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;
-			PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
-			       "io.base=0x%04x, len=%d\n", io->flags,
-			       io->win[0].base, io->win[0].len);
-			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 */
-		CFG_CHECK2(RequestIO,
-			   pcmcia_request_io(link, &link->io));
-
-		/* This configuration table entry is OK */
-		break;
-
-	next_entry:
-		CS_CHECK(GetNextTuple,
-			 pcmcia_get_next_tuple(link, &tuple));
+	last_ret = pcmcia_loop_config(link, prism2_config_check, NULL);
+	if (last_ret) {
+		if (!ignore_cis_vcc)
+			printk(KERN_ERR "GetNextTuple(): No matching "
+			       "CIS configuration.  Maybe you need the "
+			       "ignore_cis_vcc=1 parameter.\n");
+		cs_error(link, RequestIO, last_ret);
+		goto failed;
 	}
 
 	/* Need to allocate net_device before requesting IRQ handler */
@@ -738,14 +711,12 @@
 		if (ret == 0 && local->ddev)
 			strcpy(hw_priv->node.dev_name, local->ddev->name);
 	}
-	kfree(parse);
 	return ret;
 
  cs_failed:
 	cs_error(link, last_fn, last_ret);
 
  failed:
-	kfree(parse);
 	kfree(hw_priv);
 	prism2_release((u_long)link);
 	return ret;
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index e3505c1..842a08d 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -791,7 +791,7 @@
 	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;
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 25bae79..a670f36b 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -749,9 +749,10 @@
     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;
     }
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index 9eaa252..e585684 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -80,7 +80,7 @@
 	/* 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;
 
@@ -165,6 +165,70 @@
 		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)
 {
@@ -173,16 +237,8 @@
 	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
@@ -197,94 +253,14 @@
 	 * 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;
 	}
 
 	/*
@@ -335,7 +311,6 @@
 	       "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:
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 44da0d1..1404a57 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -798,9 +798,9 @@
     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");
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 67b26d3..b0c71c3 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -235,6 +235,70 @@
  * 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)
 {
@@ -243,16 +307,8 @@
 	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
@@ -267,94 +323,14 @@
 	 * 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;
 	}
 
 	/*
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index b5de38a..e124b1d 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -3702,7 +3702,7 @@
 #endif
 
   i = pcmcia_access_configuration_register(link, &reg);
-  if(i != CS_SUCCESS)
+  if (i != 0)
     {
       cs_error(link, AccessConfigurationRegister, i);
       return FALSE;
@@ -3716,7 +3716,7 @@
   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;
@@ -3725,7 +3725,7 @@
   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 +3903,7 @@
   do
     {
       i = pcmcia_request_io(link, &link->io);
-      if(i != CS_SUCCESS)
+      if (i != 0)
 	{
 	  cs_error(link, RequestIO, i);
 	  break;
@@ -3914,7 +3914,7 @@
        * 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;
@@ -3926,7 +3926,7 @@
        */
       link->conf.ConfigIndex = 1;
       i = pcmcia_request_configuration(link, &link->conf);
-      if(i != CS_SUCCESS)
+      if (i != 0)
 	{
 	  cs_error(link, RequestConfiguration, i);
 	  break;
@@ -3942,7 +3942,7 @@
       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;
@@ -3954,7 +3954,7 @@
 
       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;
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 74a5ad2..68789c6 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1977,10 +1977,10 @@
 		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 --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 00e1d96..b1899e9 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -149,52 +149,44 @@
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
+static int parport_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->io.nwin > 0) || (dflt->io.nwin > 0)) {
+		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+		if (epp_mode)
+			p_dev->conf.ConfigIndex |= FORCE_EPP_MODE;
+		p_dev->io.BasePort1 = io->win[0].base;
+		p_dev->io.NumPorts1 = io->win[0].len;
+		p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+		if (io->nwin == 2) {
+			p_dev->io.BasePort2 = io->win[1].base;
+			p_dev->io.NumPorts2 = io->win[1].len;
+		}
+		if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+			return -ENODEV;
+		return 0;
+	}
+	return -ENODEV;
+}
+
 static int parport_config(struct pcmcia_device *link)
 {
     parport_info_t *info = link->priv;
-    tuple_t tuple;
-    u_short buf[128];
-    cisparse_t parse;
-    cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
-    cistpl_cftable_entry_t dflt = { 0 };
     struct parport *p;
     int last_ret, last_fn;
-    
-    DEBUG(0, "parport_config(0x%p)\n", link);
-    
-    tuple.TupleData = (cisdata_t *)buf;
-    tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
-    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 ||
-		pcmcia_parse_tuple(link, &tuple, &parse) != 0)
-	    goto next_entry;
 
-	if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-	    cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-	    link->conf.ConfigIndex = cfg->index;
-	    if (epp_mode)
-		link->conf.ConfigIndex |= FORCE_EPP_MODE;
-	    link->io.BasePort1 = io->win[0].base;
-	    link->io.NumPorts1 = io->win[0].len;
-	    link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-	    if (io->nwin == 2) {
-		link->io.BasePort2 = io->win[1].base;
-		link->io.NumPorts2 = io->win[1].len;
-	    }
-	    if (pcmcia_request_io(link, &link->io) != 0)
-		goto next_entry;
-	    /* If we've got this far, we're done */
-	    break;
-	}
-	
-    next_entry:
-	if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
-	CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
+    DEBUG(0, "parport_config(0x%p)\n", link);
+
+    last_ret = pcmcia_loop_config(link, parport_config_check, NULL);
+    if (last_ret) {
+	    cs_error(link, RequestIO, last_ret);
+	    goto failed;
     }
-    
+
     CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
     CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
 
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index a87902d..74d1c90 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -2,10 +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
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index 75e8f85..fc1de46 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -292,7 +292,7 @@
 		skt->spd_io[map->map] = speed;
 	}
 
-	map->start=(ioaddr_t)(u32)skt->virt_io;
+	map->start=(unsigned int)(u32)skt->virt_io;
 	map->stop=map->start+MAP_SIZE;
 	return 0;
 
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
index a53ef59..13a4fbc 100644
--- a/drivers/pcmcia/au1000_generic.h
+++ b/drivers/pcmcia/au1000_generic.h
@@ -116,7 +116,7 @@
 	struct resource		res_attr;
 
 	void *                 	virt_io;
-	ioaddr_t              	phys_io;
+	unsigned int		phys_io;
 	unsigned int           	phys_attr;
 	unsigned int           	phys_mem;
 	unsigned short        	speed_io, speed_attr, speed_mem;
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index aa1cd4d..d6b4bd1 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -37,7 +37,6 @@
 #include <pcmcia/ss.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/bus_ops.h>
-#include "cs_internal.h"
 
 #include <asm/io.h>
 #include <asm/irq.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index 8a9b18c..9627390 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -41,7 +41,6 @@
 #include <pcmcia/ss.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/bus_ops.h>
-#include "cs_internal.h"
 
 #include <asm/io.h>
 #include <asm/irq.h>
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 911ca0e..db77e1f 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -238,7 +238,7 @@
 	pci_bus_add_devices(bus);
 
 	s->irq.AssignedIRQ = s->pci_irq;
-	return CS_SUCCESS;
+	return 0;
 }
 
 void cb_free(struct pcmcia_socket * s)
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 65129b5..dcce9f5 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -92,7 +92,8 @@
 	if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
 		mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s);
 		if (mem->res == NULL) {
-			printk(KERN_NOTICE "cs: unable to map card memory!\n");
+			dev_printk(KERN_NOTICE, &s->dev,
+				   "cs: unable to map card memory!\n");
 			return NULL;
 		}
 		s->cis_virt = NULL;
@@ -265,13 +266,13 @@
 ======================================================================*/
 
 static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
-			   u_int len, void *ptr)
+			   size_t len, void *ptr)
 {
     struct cis_cache_entry *cis;
     int ret;
 
     if (s->fake_cis) {
-	if (s->fake_cis_len > addr+len)
+	if (s->fake_cis_len >= addr+len)
 	    memcpy(ptr, s->fake_cis+addr, len);
 	else
 	    memset(ptr, 0xff, len);
@@ -351,7 +352,9 @@
 
 	buf = kmalloc(256, GFP_KERNEL);
 	if (buf == NULL)
-		return -1;
+		dev_printk(KERN_WARNING, &s->dev,
+			   "no memory for verifying CIS\n");
+		return -ENOMEM;
 	list_for_each_entry(cis, &s->cis_cache, node) {
 		int len = cis->len;
 
@@ -380,18 +383,22 @@
     
 ======================================================================*/
 
-int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis)
+int pcmcia_replace_cis(struct pcmcia_socket *s,
+		       const u8 *data, const size_t len)
 {
-    kfree(s->fake_cis);
-    s->fake_cis = NULL;
-    if (cis->Length > CISTPL_MAX_CIS_SIZE)
-	return CS_BAD_SIZE;
-    s->fake_cis = kmalloc(cis->Length, GFP_KERNEL);
-    if (s->fake_cis == NULL)
-	return CS_OUT_OF_RESOURCE;
-    s->fake_cis_len = cis->Length;
-    memcpy(s->fake_cis, cis->Data, cis->Length);
-    return CS_SUCCESS;
+	if (len > CISTPL_MAX_CIS_SIZE) {
+		dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n");
+		return -EINVAL;
+	}
+	kfree(s->fake_cis);
+	s->fake_cis = kmalloc(len, GFP_KERNEL);
+	if (s->fake_cis == NULL) {
+		dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n");
+		return -ENOMEM;
+	}
+	s->fake_cis_len = len;
+	memcpy(s->fake_cis, data, len);
+	return 0;
 }
 EXPORT_SYMBOL(pcmcia_replace_cis);
 
@@ -418,9 +425,9 @@
 int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
 {
     if (!s)
-	return CS_BAD_HANDLE;
+	return -EINVAL;
     if (!(s->state & SOCKET_PRESENT))
-	return CS_NO_CARD;
+	return -ENODEV;
     tuple->TupleLink = tuple->Flags = 0;
 #ifdef CONFIG_CARDBUS
     if (s->state & SOCKET_CARDBUS) {
@@ -440,10 +447,10 @@
 	!(tuple->Attributes & TUPLE_RETURN_COMMON)) {
 	cisdata_t req = tuple->DesiredTuple;
 	tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
-	if (pccard_get_next_tuple(s, function, tuple) == CS_SUCCESS) {
+	if (pccard_get_next_tuple(s, function, tuple) == 0) {
 	    tuple->DesiredTuple = CISTPL_LINKTARGET;
-	    if (pccard_get_next_tuple(s, function, tuple) != CS_SUCCESS)
-		return CS_NO_MORE_ITEMS;
+	    if (pccard_get_next_tuple(s, function, tuple) != 0)
+		return -ENOSPC;
 	} else
 	    tuple->CISOffset = tuple->TupleLink = 0;
 	tuple->DesiredTuple = req;
@@ -498,9 +505,9 @@
     int ofs, i, attr;
 
     if (!s)
-	return CS_BAD_HANDLE;
+	return -EINVAL;
     if (!(s->state & SOCKET_PRESENT))
-	return CS_NO_CARD;
+	return -ENODEV;
 
     link[1] = tuple->TupleLink;
     ofs = tuple->CISOffset + tuple->TupleLink;
@@ -519,7 +526,7 @@
 	/* End of chain?  Follow long link if possible */
 	if (link[0] == CISTPL_END) {
 	    if ((ofs = follow_link(s, tuple)) < 0)
-		return CS_NO_MORE_ITEMS;
+		return -ENOSPC;
 	    attr = SPACE(tuple->Flags);
 	    read_cis_cache(s, attr, ofs, 2, link);
 	}
@@ -577,13 +584,13 @@
     }
     if (i == MAX_TUPLES) {
 	cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n");
-	return CS_NO_MORE_ITEMS;
+	return -ENOSPC;
     }
     
     tuple->TupleCode = link[0];
     tuple->TupleLink = link[1];
     tuple->CISOffset = ofs + 2;
-    return CS_SUCCESS;
+    return 0;
 }
 EXPORT_SYMBOL(pccard_get_next_tuple);
 
@@ -596,18 +603,18 @@
     u_int len;
 
     if (!s)
-	return CS_BAD_HANDLE;
+	return -EINVAL;
 
     if (tuple->TupleLink < tuple->TupleOffset)
-	return CS_NO_MORE_ITEMS;
+	return -ENOSPC;
     len = tuple->TupleLink - tuple->TupleOffset;
     tuple->TupleDataLen = tuple->TupleLink;
     if (len == 0)
-	return CS_SUCCESS;
+	return 0;
     read_cis_cache(s, SPACE(tuple->Flags),
 		   tuple->CISOffset + tuple->TupleOffset,
 		   _MIN(len, tuple->TupleDataMax), tuple->TupleData);
-    return CS_SUCCESS;
+    return 0;
 }
 EXPORT_SYMBOL(pccard_get_tuple_data);
 
@@ -640,25 +647,31 @@
 	case 3: device->dev[i].speed = 150; break;
 	case 4: device->dev[i].speed = 100; break;
 	case 7:
-	    if (++p == q) return CS_BAD_TUPLE;
+	    if (++p == q)
+		    return -EINVAL;
 	    device->dev[i].speed = SPEED_CVT(*p);
 	    while (*p & 0x80)
-		if (++p == q) return CS_BAD_TUPLE;
+		if (++p == q)
+			return -EINVAL;
 	    break;
 	default:
-	    return CS_BAD_TUPLE;
+	    return -EINVAL;
 	}
 
-	if (++p == q) return CS_BAD_TUPLE;
-	if (*p == 0xff) break;
+	if (++p == q)
+		return -EINVAL;
+	if (*p == 0xff)
+		break;
 	scale = *p & 7;
-	if (scale == 7) return CS_BAD_TUPLE;
+	if (scale == 7)
+		return -EINVAL;
 	device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));
 	device->ndev++;
-	if (++p == q) break;
+	if (++p == q)
+		break;
     }
     
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
@@ -667,12 +680,12 @@
 {
     u_char *p;
     if (tuple->TupleDataLen < 5)
-	return CS_BAD_TUPLE;
+	return -EINVAL;
     p = (u_char *) tuple->TupleData;
     csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2;
     csum->len = get_unaligned_le16(p + 2);
     csum->sum = *(p + 4);
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
@@ -680,9 +693,9 @@
 static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
 {
     if (tuple->TupleDataLen < 4)
-	return CS_BAD_TUPLE;
+	return -EINVAL;
     link->addr = get_unaligned_le32(tuple->TupleData);
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
@@ -697,13 +710,13 @@
     
     link->nfn = *p; p++;
     if (tuple->TupleDataLen <= link->nfn*5)
-	return CS_BAD_TUPLE;
+	return -EINVAL;
     for (i = 0; i < link->nfn; i++) {
 	link->fn[i].space = *p; p++;
 	link->fn[i].addr = get_unaligned_le32(p);
 	p += 4;
     }
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
@@ -713,24 +726,27 @@
 {
     int i, j, ns;
 
-    if (p == q) return CS_BAD_TUPLE;
+    if (p == q)
+	    return -EINVAL;
     ns = 0; j = 0;
     for (i = 0; i < max; i++) {
-	if (*p == 0xff) break;
+	if (*p == 0xff)
+		break;
 	ofs[i] = j;
 	ns++;
 	for (;;) {
 	    s[j++] = (*p == 0xff) ? '\0' : *p;
 	    if ((*p == '\0') || (*p == 0xff)) break;
-	    if (++p == q) return CS_BAD_TUPLE;
+	    if (++p == q)
+		    return -EINVAL;
 	}
 	if ((*p == 0xff) || (++p == q)) break;
     }
     if (found) {
 	*found = ns;
-	return CS_SUCCESS;
+	return 0;
     } else {
-	return (ns == max) ? CS_SUCCESS : CS_BAD_TUPLE;
+	return (ns == max) ? 0 : -EINVAL;
     }
 }
 
@@ -745,7 +761,8 @@
     
     vers_1->major = *p; p++;
     vers_1->minor = *p; p++;
-    if (p >= q) return CS_BAD_TUPLE;
+    if (p >= q)
+	    return -EINVAL;
 
     return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,
 			 vers_1->str, vers_1->ofs, &vers_1->ns);
@@ -781,7 +798,7 @@
 	p += 2;
     }
     jedec->nid = nid;
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
@@ -789,10 +806,10 @@
 static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
 {
     if (tuple->TupleDataLen < 4)
-	return CS_BAD_TUPLE;
+	return -EINVAL;
     m->manf = get_unaligned_le16(tuple->TupleData);
     m->card = get_unaligned_le16(tuple->TupleData + 2);
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
@@ -801,11 +818,11 @@
 {
     u_char *p;
     if (tuple->TupleDataLen < 2)
-	return CS_BAD_TUPLE;
+	return -EINVAL;
     p = (u_char *)tuple->TupleData;
     f->func = p[0];
     f->sysinit = p[1];
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
@@ -815,12 +832,12 @@
     u_char *p;
     int i;
     if (tuple->TupleDataLen < 1)
-	return CS_BAD_TUPLE;
+	return -EINVAL;
     p = (u_char *)tuple->TupleData;
     f->type = p[0];
     for (i = 1; i < tuple->TupleDataLen; i++)
 	f->data[i-1] = p[i];
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
@@ -834,7 +851,7 @@
     rasz = *p & 0x03;
     rmsz = (*p & 0x3c) >> 2;
     if (tuple->TupleDataLen < rasz+rmsz+4)
-	return CS_BAD_TUPLE;
+	return -EINVAL;
     config->last_idx = *(++p);
     p++;
     config->base = 0;
@@ -846,7 +863,7 @@
     for (i = 0; i <= rmsz; i++)
 	config->rmask[i>>2] += p[i] << (8*(i%4));
     config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4);
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*======================================================================
@@ -1002,10 +1019,12 @@
 
 static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq)
 {
-    if (p == q) return NULL;
+    if (p == q)
+	    return NULL;
     irq->IRQInfo1 = *p; p++;
     if (irq->IRQInfo1 & IRQ_INFO2_VALID) {
-	if (p+2 > q) return NULL;
+	if (p+2 > q)
+		return NULL;
 	irq->IRQInfo2 = (p[1]<<8) + p[0];
 	p += 2;
     }
@@ -1026,7 +1045,8 @@
     if (*p & 0x40)
 	entry->flags |= CISTPL_CFTABLE_DEFAULT;
     if (*p & 0x80) {
-	if (++p == q) return CS_BAD_TUPLE;
+	if (++p == q)
+		return -EINVAL;
 	if (*p & 0x10)
 	    entry->flags |= CISTPL_CFTABLE_BVDS;
 	if (*p & 0x20)
@@ -1040,30 +1060,35 @@
 	entry->interface = 0;
 
     /* Process optional features */
-    if (++p == q) return CS_BAD_TUPLE;
+    if (++p == q)
+	    return -EINVAL;
     features = *p; p++;
 
     /* Power options */
     if ((features & 3) > 0) {
 	p = parse_power(p, q, &entry->vcc);
-	if (p == NULL) return CS_BAD_TUPLE;
+	if (p == NULL)
+		return -EINVAL;
     } else
 	entry->vcc.present = 0;
     if ((features & 3) > 1) {
 	p = parse_power(p, q, &entry->vpp1);
-	if (p == NULL) return CS_BAD_TUPLE;
+	if (p == NULL)
+		return -EINVAL;
     } else
 	entry->vpp1.present = 0;
     if ((features & 3) > 2) {
 	p = parse_power(p, q, &entry->vpp2);
-	if (p == NULL) return CS_BAD_TUPLE;
+	if (p == NULL)
+		return -EINVAL;
     } else
 	entry->vpp2.present = 0;
 
     /* Timing options */
     if (features & 0x04) {
 	p = parse_timing(p, q, &entry->timing);
-	if (p == NULL) return CS_BAD_TUPLE;
+	if (p == NULL)
+		return -EINVAL;
     } else {
 	entry->timing.wait = 0;
 	entry->timing.ready = 0;
@@ -1073,14 +1098,16 @@
     /* I/O window options */
     if (features & 0x08) {
 	p = parse_io(p, q, &entry->io);
-	if (p == NULL) return CS_BAD_TUPLE;
+	if (p == NULL)
+		return -EINVAL;
     } else
 	entry->io.nwin = 0;
     
     /* Interrupt options */
     if (features & 0x10) {
 	p = parse_irq(p, q, &entry->irq);
-	if (p == NULL) return CS_BAD_TUPLE;
+	if (p == NULL)
+		return -EINVAL;
     } else
 	entry->irq.IRQInfo1 = 0;
 
@@ -1094,7 +1121,8 @@
 	entry->mem.win[0].card_addr = 0;
 	entry->mem.win[0].host_addr = 0;
 	p += 2;
-	if (p > q) return CS_BAD_TUPLE;
+	if (p > q)
+		return -EINVAL;
 	break;
     case 0x40:
 	entry->mem.nwin = 1;
@@ -1102,26 +1130,30 @@
 	entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
 	entry->mem.win[0].host_addr = 0;
 	p += 4;
-	if (p > q) return CS_BAD_TUPLE;
+	if (p > q)
+		return -EINVAL;
 	break;
     case 0x60:
 	p = parse_mem(p, q, &entry->mem);
-	if (p == NULL) return CS_BAD_TUPLE;
+	if (p == NULL)
+		return -EINVAL;
 	break;
     }
 
     /* Misc features */
     if (features & 0x80) {
-	if (p == q) return CS_BAD_TUPLE;
+	if (p == q)
+		return -EINVAL;
 	entry->flags |= (*p << 8);
 	while (*p & 0x80)
-	    if (++p == q) return CS_BAD_TUPLE;
+	    if (++p == q)
+		    return -EINVAL;
 	p++;
     }
 
     entry->subtuples = q-p;
     
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
@@ -1132,12 +1164,12 @@
 {
     u_char *p;
     if (tuple->TupleDataLen < 6)
-	return CS_BAD_TUPLE;
+	return -EINVAL;
     p = (u_char *)tuple->TupleData;
     bar->attr = *p;
     p += 2;
     bar->size = get_unaligned_le32(p);
-    return CS_SUCCESS;
+    return 0;
 }
 
 static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
@@ -1146,12 +1178,12 @@
     
     p = (u_char *)tuple->TupleData;
     if ((*p != 3) || (tuple->TupleDataLen < 6))
-	return CS_BAD_TUPLE;
+	return -EINVAL;
     config->last_idx = *(++p);
     p++;
     config->base = get_unaligned_le32(p);
     config->subtuples = tuple->TupleDataLen - 6;
-    return CS_SUCCESS;
+    return 0;
 }
 
 static int parse_cftable_entry_cb(tuple_t *tuple,
@@ -1167,29 +1199,34 @@
 	entry->flags |= CISTPL_CFTABLE_DEFAULT;
 
     /* Process optional features */
-    if (++p == q) return CS_BAD_TUPLE;
+    if (++p == q)
+	    return -EINVAL;
     features = *p; p++;
 
     /* Power options */
     if ((features & 3) > 0) {
 	p = parse_power(p, q, &entry->vcc);
-	if (p == NULL) return CS_BAD_TUPLE;
+	if (p == NULL)
+		return -EINVAL;
     } else
 	entry->vcc.present = 0;
     if ((features & 3) > 1) {
 	p = parse_power(p, q, &entry->vpp1);
-	if (p == NULL) return CS_BAD_TUPLE;
+	if (p == NULL)
+		return -EINVAL;
     } else
 	entry->vpp1.present = 0;
     if ((features & 3) > 2) {
 	p = parse_power(p, q, &entry->vpp2);
-	if (p == NULL) return CS_BAD_TUPLE;
+	if (p == NULL)
+		return -EINVAL;
     } else
 	entry->vpp2.present = 0;
 
     /* I/O window options */
     if (features & 0x08) {
-	if (p == q) return CS_BAD_TUPLE;
+	if (p == q)
+		return -EINVAL;
 	entry->io = *p; p++;
     } else
 	entry->io = 0;
@@ -1197,32 +1234,37 @@
     /* Interrupt options */
     if (features & 0x10) {
 	p = parse_irq(p, q, &entry->irq);
-	if (p == NULL) return CS_BAD_TUPLE;
+	if (p == NULL)
+		return -EINVAL;
     } else
 	entry->irq.IRQInfo1 = 0;
 
     if (features & 0x20) {
-	if (p == q) return CS_BAD_TUPLE;
+	if (p == q)
+		return -EINVAL;
 	entry->mem = *p; p++;
     } else
 	entry->mem = 0;
 
     /* Misc features */
     if (features & 0x80) {
-	if (p == q) return CS_BAD_TUPLE;
+	if (p == q)
+		return -EINVAL;
 	entry->flags |= (*p << 8);
 	if (*p & 0x80) {
-	    if (++p == q) return CS_BAD_TUPLE;
+	    if (++p == q)
+		    return -EINVAL;
 	    entry->flags |= (*p << 16);
 	}
 	while (*p & 0x80)
-	    if (++p == q) return CS_BAD_TUPLE;
+	    if (++p == q)
+		    return -EINVAL;
 	p++;
     }
 
     entry->subtuples = q-p;
     
-    return CS_SUCCESS;
+    return 0;
 }
 
 #endif
@@ -1248,7 +1290,7 @@
 	p += 6;
     }
     geo->ngeo = n;
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
@@ -1258,7 +1300,7 @@
     u_char *p, *q;
 
     if (tuple->TupleDataLen < 10)
-	return CS_BAD_TUPLE;
+	return -EINVAL;
     
     p = tuple->TupleData;
     q = p + tuple->TupleDataLen;
@@ -1282,15 +1324,18 @@
     
     p = tuple->TupleData;
     q = p + tuple->TupleDataLen;
-    if (p == q) return CS_BAD_TUPLE;
+    if (p == q)
+	    return -EINVAL;
     org->data_org = *p;
-    if (++p == q) return CS_BAD_TUPLE;
+    if (++p == q)
+	    return -EINVAL;
     for (i = 0; i < 30; i++) {
 	org->desc[i] = *p;
 	if (*p == '\0') break;
-	if (++p == q) return CS_BAD_TUPLE;
+	if (++p == q)
+		return -EINVAL;
     }
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
@@ -1300,7 +1345,7 @@
     u_char *p;
 
     if (tuple->TupleDataLen < 10)
-	return CS_BAD_TUPLE;
+	return -EINVAL;
 
     p = tuple->TupleData;
 
@@ -1309,17 +1354,17 @@
     fmt->offset = get_unaligned_le32(p + 2);
     fmt->length = get_unaligned_le32(p + 6);
 
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*====================================================================*/
 
-int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse)
+int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
 {
-    int ret = CS_SUCCESS;
+    int ret = 0;
     
     if (tuple->TupleDataLen > tuple->TupleDataMax)
-	return CS_BAD_TUPLE;
+	return -EINVAL;
     switch (tuple->TupleCode) {
     case CISTPL_DEVICE:
     case CISTPL_DEVICE_A:
@@ -1387,15 +1432,17 @@
 	break;
     case CISTPL_NO_LINK:
     case CISTPL_LINKTARGET:
-	ret = CS_SUCCESS;
+	ret = 0;
 	break;
     default:
-	ret = CS_UNSUPPORTED_FUNCTION;
+	ret = -EINVAL;
 	break;
     }
+    if (ret)
+	    __cs_dbg(0, "parse_tuple failed %d\n", ret);
     return ret;
 }
-EXPORT_SYMBOL(pccard_parse_tuple);
+EXPORT_SYMBOL(pcmcia_parse_tuple);
 
 /*======================================================================
 
@@ -1410,18 +1457,22 @@
     int ret;
 
     buf = kmalloc(256, GFP_KERNEL);
-    if (buf == NULL)
-	return CS_OUT_OF_RESOURCE;
+    if (buf == NULL) {
+	    dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
+	    return -ENOMEM;
+    }
     tuple.DesiredTuple = code;
     tuple.Attributes = TUPLE_RETURN_COMMON;
     ret = pccard_get_first_tuple(s, function, &tuple);
-    if (ret != CS_SUCCESS) goto done;
+    if (ret != 0)
+	    goto done;
     tuple.TupleData = buf;
     tuple.TupleOffset = 0;
     tuple.TupleDataMax = 255;
     ret = pccard_get_tuple_data(s, &tuple);
-    if (ret != CS_SUCCESS) goto done;
-    ret = pccard_parse_tuple(&tuple, parse);
+    if (ret != 0)
+	    goto done;
+    ret = pcmcia_parse_tuple(&tuple, parse);
 done:
     kfree(buf);
     return ret;
@@ -1446,37 +1497,40 @@
     int ret, reserved, dev_ok = 0, ident_ok = 0;
 
     if (!s)
-	return CS_BAD_HANDLE;
+	return -EINVAL;
 
     tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
-    if (tuple == NULL)
-	return CS_OUT_OF_RESOURCE;
+    if (tuple == NULL) {
+	    dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
+	    return -ENOMEM;
+    }
     p = kmalloc(sizeof(*p), GFP_KERNEL);
     if (p == NULL) {
-	kfree(tuple);
-	return CS_OUT_OF_RESOURCE;
+	    kfree(tuple);
+	    dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
+	    return -ENOMEM;
     }
 
     count = reserved = 0;
     tuple->DesiredTuple = RETURN_FIRST_TUPLE;
     tuple->Attributes = TUPLE_RETURN_COMMON;
     ret = pccard_get_first_tuple(s, function, tuple);
-    if (ret != CS_SUCCESS)
+    if (ret != 0)
 	goto done;
 
     /* First tuple should be DEVICE; we should really have either that
        or a CFTABLE_ENTRY of some sort */
     if ((tuple->TupleCode == CISTPL_DEVICE) ||
-	(pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) ||
-	(pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS))
+	(pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == 0) ||
+	(pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
 	dev_ok++;
 
     /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
        tuple, for card identification.  Certain old D-Link and Linksys
        cards have only a broken VERS_2 tuple; hence the bogus test. */
-    if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == CS_SUCCESS) ||
-	(pccard_read_tuple(s, function, CISTPL_VERS_1, p) == CS_SUCCESS) ||
-	(pccard_read_tuple(s, function, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS))
+    if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == 0) ||
+	(pccard_read_tuple(s, function, CISTPL_VERS_1, p) == 0) ||
+	(pccard_read_tuple(s, function, CISTPL_VERS_2, p) != -ENOSPC))
 	ident_ok++;
 
     if (!dev_ok && !ident_ok)
@@ -1484,7 +1538,8 @@
 
     for (count = 1; count < MAX_TUPLES; count++) {
 	ret = pccard_get_next_tuple(s, function, tuple);
-	if (ret != CS_SUCCESS) break;
+	if (ret != 0)
+		break;
 	if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
 	    ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
 	    ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
@@ -1499,6 +1554,6 @@
 	    *info = count;
     kfree(tuple);
     kfree(p);
-    return CS_SUCCESS;
+    return 0;
 }
 EXPORT_SYMBOL(pccard_validate_cis);
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index d120739..c68c5d3 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -61,7 +61,7 @@
 /* Access speed for attribute memory windows */
 INT_MODULE_PARM(cis_speed,	300);		/* ns */
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 static int pc_debug;
 
 module_param(pc_debug, int, 0644);
@@ -247,7 +247,8 @@
 
 	wait_for_completion(&socket->thread_done);
 	if (!socket->thread) {
-		printk(KERN_WARNING "PCMCIA: warning: socket thread for socket %p did not start\n", socket);
+		dev_printk(KERN_WARNING, &socket->dev,
+			   "PCMCIA: warning: socket thread did not start\n");
 		return -EIO;
 	}
 
@@ -366,16 +367,16 @@
 		skt->ops->get_status(skt, &status);
 
 		if (!(status & SS_DETECT))
-			return CS_NO_CARD;
+			return -ENODEV;
 
 		if (status & SS_READY)
-			return CS_SUCCESS;
+			return 0;
 
 		msleep(unreset_check * 10);
 	}
 
 	cs_err(skt, "time out after reset.\n");
-	return CS_GENERAL_FAILURE;
+	return -ETIMEDOUT;
 }
 
 /*
@@ -412,7 +413,8 @@
 
 	s->ops->get_status(s, &status);
 	if (status & SS_POWERON) {
-		printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
+		dev_printk(KERN_ERR, &s->dev,
+			   "*** DANGER *** unable to remove socket power\n");
 	}
 
 	cs_socket_put(s);
@@ -426,14 +428,14 @@
 
 	skt->ops->get_status(skt, &status);
 	if (!(status & SS_DETECT))
-		return CS_NO_CARD;
+		return -ENODEV;
 
 	msleep(initial_delay * 10);
 
 	for (i = 0; i < 100; i++) {
 		skt->ops->get_status(skt, &status);
 		if (!(status & SS_DETECT))
-			return CS_NO_CARD;
+			return -ENODEV;
 
 		if (!(status & SS_PENDING))
 			break;
@@ -443,13 +445,13 @@
 
 	if (status & SS_PENDING) {
 		cs_err(skt, "voltage interrogation timed out.\n");
-		return CS_GENERAL_FAILURE;
+		return -ETIMEDOUT;
 	}
 
 	if (status & SS_CARDBUS) {
 		if (!(skt->features & SS_CAP_CARDBUS)) {
 			cs_err(skt, "cardbus cards are not supported.\n");
-			return CS_BAD_TYPE;
+			return -EINVAL;
 		}
 		skt->state |= SOCKET_CARDBUS;
 	}
@@ -463,7 +465,7 @@
 		skt->socket.Vcc = skt->socket.Vpp = 50;
 	else {
 		cs_err(skt, "unsupported voltage key.\n");
-		return CS_BAD_TYPE;
+		return -EIO;
 	}
 
 	if (skt->power_hook)
@@ -480,7 +482,7 @@
 	skt->ops->get_status(skt, &status);
 	if (!(status & SS_POWERON)) {
 		cs_err(skt, "unable to apply power.\n");
-		return CS_BAD_TYPE;
+		return -EIO;
 	}
 
 	status = socket_reset(skt);
@@ -502,15 +504,16 @@
 	cs_dbg(skt, 4, "insert\n");
 
 	if (!cs_socket_get(skt))
-		return CS_NO_CARD;
+		return -ENODEV;
 
 	ret = socket_setup(skt, setup_delay);
-	if (ret == CS_SUCCESS) {
+	if (ret == 0) {
 		skt->state |= SOCKET_PRESENT;
 
-		printk(KERN_NOTICE "pccard: %s card inserted into slot %d\n",
-		       (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
-		       skt->sock);
+		dev_printk(KERN_NOTICE, &skt->dev,
+			   "pccard: %s card inserted into slot %d\n",
+			   (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
+			   skt->sock);
 
 #ifdef CONFIG_CARDBUS
 		if (skt->state & SOCKET_CARDBUS) {
@@ -531,7 +534,7 @@
 static int socket_suspend(struct pcmcia_socket *skt)
 {
 	if (skt->state & SOCKET_SUSPEND)
-		return CS_IN_USE;
+		return -EBUSY;
 
 	send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
 	skt->socket = dead_socket;
@@ -540,7 +543,7 @@
 		skt->ops->suspend(skt);
 	skt->state |= SOCKET_SUSPEND;
 
-	return CS_SUCCESS;
+	return 0;
 }
 
 /*
@@ -553,7 +556,7 @@
 	int ret;
 
 	if (!(skt->state & SOCKET_SUSPEND))
-		return CS_IN_USE;
+		return -EBUSY;
 
 	skt->socket = dead_socket;
 	skt->ops->init(skt);
@@ -565,7 +568,7 @@
 	}
 
 	ret = socket_setup(skt, resume_delay);
-	if (ret == CS_SUCCESS) {
+	if (ret == 0) {
 		/*
 		 * FIXME: need a better check here for cardbus cards.
 		 */
@@ -590,12 +593,13 @@
 
 	skt->state &= ~SOCKET_SUSPEND;
 
-	return CS_SUCCESS;
+	return 0;
 }
 
 static void socket_remove(struct pcmcia_socket *skt)
 {
-	printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock);
+	dev_printk(KERN_NOTICE, &skt->dev,
+		   "pccard: card ejected from slot %d\n", skt->sock);
 	socket_shutdown(skt);
 }
 
@@ -641,8 +645,8 @@
 	/* register with the device core */
 	ret = device_register(&skt->dev);
 	if (ret) {
-		printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n",
-			skt);
+		dev_printk(KERN_WARNING, &skt->dev,
+			   "PCMCIA: unable to register socket\n");
 		skt->thread = NULL;
 		complete(&skt->thread_done);
 		return 0;
@@ -748,7 +752,7 @@
  * CIS register.
  */
 
-int pccard_reset_card(struct pcmcia_socket *skt)
+int pcmcia_reset_card(struct pcmcia_socket *skt)
 {
 	int ret;
 
@@ -757,15 +761,15 @@
 	mutex_lock(&skt->skt_mutex);
 	do {
 		if (!(skt->state & SOCKET_PRESENT)) {
-			ret = CS_NO_CARD;
+			ret = -ENODEV;
 			break;
 		}
 		if (skt->state & SOCKET_SUSPEND) {
-			ret = CS_IN_USE;
+			ret = -EBUSY;
 			break;
 		}
 		if (skt->state & SOCKET_CARDBUS) {
-			ret = CS_UNSUPPORTED_FUNCTION;
+			ret = -EPERM;
 			break;
 		}
 
@@ -774,20 +778,20 @@
 			send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
 			if (skt->callback)
 				skt->callback->suspend(skt);
-			if (socket_reset(skt) == CS_SUCCESS) {
+			if (socket_reset(skt) == 0) {
 				send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
 				if (skt->callback)
 					skt->callback->resume(skt);
 			}
 		}
 
-		ret = CS_SUCCESS;
+		ret = 0;
 	} while (0);
 	mutex_unlock(&skt->skt_mutex);
 
 	return ret;
 } /* reset_card */
-EXPORT_SYMBOL(pccard_reset_card);
+EXPORT_SYMBOL(pcmcia_reset_card);
 
 
 /* These shut down or wake up a socket.  They are sort of user
@@ -802,11 +806,11 @@
 	mutex_lock(&skt->skt_mutex);
 	do {
 		if (!(skt->state & SOCKET_PRESENT)) {
-			ret = CS_NO_CARD;
+			ret = -ENODEV;
 			break;
 		}
 		if (skt->state & SOCKET_CARDBUS) {
-			ret = CS_UNSUPPORTED_FUNCTION;
+			ret = -EPERM;
 			break;
 		}
 		if (skt->callback) {
@@ -832,11 +836,11 @@
 	mutex_lock(&skt->skt_mutex);
 	do {
 		if (!(skt->state & SOCKET_PRESENT)) {
-			ret = CS_NO_CARD;
+			ret = -ENODEV;
 			break;
 		}
 		if (skt->state & SOCKET_CARDBUS) {
-			ret = CS_UNSUPPORTED_FUNCTION;
+			ret = -EPERM;
 			break;
 		}
 		ret = socket_resume(skt);
@@ -892,7 +896,7 @@
 			ret = -EBUSY;
 			break;
 		}
-		if (socket_insert(skt) == CS_NO_CARD) {
+		if (socket_insert(skt) == -ENODEV) {
 			ret = -ENODEV;
 			break;
 		}
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 63dc1a2..79615e6 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -1,5 +1,5 @@
 /*
- * cs_internal.h
+ * cs_internal.h -- definitions internal to the PCMCIA core modules
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -10,6 +10,12 @@
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * (C) 1999		David A. Hinds
+ * (C) 2003 - 2008	Dominik Brodowski
+ *
+ *
+ * This file contains definitions _only_ needed by the PCMCIA core modules.
+ * It must not be included by PCMCIA socket drivers or by PCMCIA device
+ * drivers.
  */
 
 #ifndef _LINUX_CS_INTERNAL_H
@@ -18,29 +24,24 @@
 #include <linux/kref.h>
 
 /* Flags in client state */
-#define CLIENT_CONFIG_LOCKED	0x0001
-#define CLIENT_IRQ_REQ		0x0002
-#define CLIENT_IO_REQ		0x0004
-#define CLIENT_UNBOUND		0x0008
-#define CLIENT_STALE		0x0010
 #define CLIENT_WIN_REQ(i)	(0x1<<(i))
-#define CLIENT_CARDBUS		0x8000
 
 /* Each card function gets one of these guys */
 typedef struct config_t {
 	struct kref	ref;
-    u_int		state;
-    u_int		Attributes;
-    u_int		IntType;
-    u_int		ConfigBase;
-    u_char		Status, Pin, Copy, Option, ExtStatus;
-    u_int		CardValues;
-    io_req_t		io;
-    struct {
-	u_int		Attributes;
-    } irq;
+	unsigned int	state;
+	unsigned int	Attributes;
+	unsigned int	IntType;
+	unsigned int	ConfigBase;
+	unsigned char	Status, Pin, Copy, Option, ExtStatus;
+	unsigned int	CardValues;
+	io_req_t	io;
+	struct {
+		u_int	Attributes;
+	} irq;
 } config_t;
 
+
 struct cis_cache_entry {
 	struct list_head	node;
 	unsigned int		addr;
@@ -49,6 +50,30 @@
 	unsigned char		cache[0];
 };
 
+struct pccard_resource_ops {
+	int	(*validate_mem)		(struct pcmcia_socket *s);
+	int	(*adjust_io_region)	(struct resource *res,
+					 unsigned long r_start,
+					 unsigned long r_end,
+					 struct pcmcia_socket *s);
+	struct resource* (*find_io)	(unsigned long base, int num,
+					 unsigned long align,
+					 struct pcmcia_socket *s);
+	struct resource* (*find_mem)	(unsigned long base, unsigned long num,
+					 unsigned long align, int low,
+					 struct pcmcia_socket *s);
+	int	(*add_io)		(struct pcmcia_socket *s,
+					 unsigned int action,
+					 unsigned long r_start,
+					 unsigned long r_end);
+	int	(*add_mem)		(struct pcmcia_socket *s,
+					 unsigned int action,
+					 unsigned long r_start,
+					 unsigned long r_end);
+	int	(*init)			(struct pcmcia_socket *s);
+	void	(*exit)			(struct pcmcia_socket *s);
+};
+
 /* Flags in config state */
 #define CONFIG_LOCKED		0x01
 #define CONFIG_IRQ_REQ		0x02
@@ -59,7 +84,6 @@
 #define SOCKET_INUSE		0x0010
 #define SOCKET_SUSPEND		0x0080
 #define SOCKET_WIN_REQ(i)	(0x0100<<(i))
-#define SOCKET_REGION_INFO	0x4000
 #define SOCKET_CARDBUS		0x8000
 #define SOCKET_CARDBUS_CONFIG	0x10000
 
@@ -83,69 +107,153 @@
 	}
 }
 
-/* In cardbus.c */
-int cb_alloc(struct pcmcia_socket *s);
-void cb_free(struct pcmcia_socket *s);
-int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, void *ptr);
+#ifdef CONFIG_PCMCIA_DEBUG
+extern int cs_debug_level(int);
 
-/* In cistpl.c */
-int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
-		 u_int addr, u_int len, void *ptr);
-void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
-		   u_int addr, u_int len, void *ptr);
-void release_cis_mem(struct pcmcia_socket *s);
-void destroy_cis_cache(struct pcmcia_socket *s);
+#define cs_dbg(skt, lvl, fmt, arg...) do {		\
+	if (cs_debug_level(lvl))			\
+		dev_printk(KERN_DEBUG, &skt->dev,	\
+		 "cs: " fmt, ## arg);			\
+} while (0)
+#define __cs_dbg(lvl, fmt, arg...) do {			\
+	if (cs_debug_level(lvl))			\
+		printk(KERN_DEBUG 			\
+		 "cs: " fmt, ## arg);			\
+} while (0)
+
+#else
+#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
+#define __cs_dbg(lvl, fmt, arg...) do { } while (0)
+#endif
+
+#define cs_err(skt, fmt, arg...) \
+	dev_printk(KERN_ERR, &skt->dev, "cs: " fmt, ## arg)
+
+
+/*
+ * Stuff internal to module "pcmcia_core":
+ */
+
+/* cistpl.c */
 int verify_cis_cache(struct pcmcia_socket *s);
-int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse);
 
-/* In rsrc_mgr */
-int pcmcia_validate_mem(struct pcmcia_socket *s);
-struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align,
-		   struct pcmcia_socket *s);
-int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
-		     unsigned long r_end, struct pcmcia_socket *s);
-struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
-		    int low, struct pcmcia_socket *s);
+/* rsrc_mgr.c */
 void release_resource_db(struct pcmcia_socket *s);
 
-/* In socket_sysfs.c */
+/* socket_sysfs.c */
 extern int pccard_sysfs_add_socket(struct device *dev);
 extern void pccard_sysfs_remove_socket(struct device *dev);
 
-/* In cs.c */
-extern struct rw_semaphore pcmcia_socket_list_rwsem;
-extern struct list_head pcmcia_socket_list;
-int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req);
-int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config);
-int pccard_reset_card(struct pcmcia_socket *skt);
+/* cardbus.c */
+int cb_alloc(struct pcmcia_socket *s);
+void cb_free(struct pcmcia_socket *s);
+int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len,
+		void *ptr);
 
 
+
+/*
+ * Stuff exported by module "pcmcia_core" to module "pcmcia"
+ */
+
 struct pcmcia_callback{
 	struct module	*owner;
-	int		(*event) (struct pcmcia_socket *s, event_t event, int priority);
+	int		(*event) (struct pcmcia_socket *s,
+				  event_t event, int priority);
 	void		(*requery) (struct pcmcia_socket *s, int new_cis);
 	int		(*suspend) (struct pcmcia_socket *s);
 	int		(*resume) (struct pcmcia_socket *s);
 };
 
+/* cs.c */
+extern struct rw_semaphore pcmcia_socket_list_rwsem;
+extern struct list_head pcmcia_socket_list;
+extern struct class pcmcia_socket_class;
+
+int pcmcia_get_window(struct pcmcia_socket *s,
+		      window_handle_t *handle,
+		      int idx,
+		      win_req_t *req);
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
+struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr);
 
-#define cs_socket_name(skt)	((skt)->dev.bus_id)
+int pcmcia_suspend_card(struct pcmcia_socket *skt);
+int pcmcia_resume_card(struct pcmcia_socket *skt);
 
-#ifdef DEBUG
-extern int cs_debug_level(int);
+int pcmcia_eject_card(struct pcmcia_socket *skt);
+int pcmcia_insert_card(struct pcmcia_socket *skt);
 
-#define cs_dbg(skt, lvl, fmt, arg...) do {		\
-	if (cs_debug_level(lvl))			\
-		printk(KERN_DEBUG "cs: %s: " fmt, 	\
-		       cs_socket_name(skt) , ## arg);	\
-} while (0)
+struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt);
+void pcmcia_put_socket(struct pcmcia_socket *skt);
 
-#else
-#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
-#endif
+/* cistpl.c */
+int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
+			u_int addr, u_int len, void *ptr);
+void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
+			  u_int addr, u_int len, void *ptr);
+void release_cis_mem(struct pcmcia_socket *s);
+void destroy_cis_cache(struct pcmcia_socket *s);
+int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
+		      cisdata_t code, void *parse);
+int pcmcia_replace_cis(struct pcmcia_socket *s,
+		       const u8 *data, const size_t len);
+int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function,
+			unsigned int *count);
 
-#define cs_err(skt, fmt, arg...) \
-	printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.bus_id , ## arg)
+/* rsrc_mgr.c */
+int pcmcia_validate_mem(struct pcmcia_socket *s);
+struct resource *pcmcia_find_io_region(unsigned long base,
+				       int num,
+				       unsigned long align,
+				       struct pcmcia_socket *s);
+int pcmcia_adjust_io_region(struct resource *res,
+			    unsigned long r_start,
+			    unsigned long r_end,
+			    struct pcmcia_socket *s);
+struct resource *pcmcia_find_mem_region(u_long base,
+					u_long num,
+					u_long align,
+					int low,
+					struct pcmcia_socket *s);
+
+/*
+ * Stuff internal to module "pcmcia".
+ */
+/* ds.c */
+extern struct bus_type pcmcia_bus_type;
+
+/* pcmcia_resource.c */
+extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
+
+#ifdef CONFIG_PCMCIA_IOCTL
+/* ds.c */
+extern spinlock_t pcmcia_dev_list_lock;
+
+extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev);
+extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
+
+struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
+					unsigned int function);
+
+/* pcmcia_ioctl.c */
+extern void __init pcmcia_setup_ioctl(void);
+extern void __exit pcmcia_cleanup_ioctl(void);
+extern void handle_event(struct pcmcia_socket *s, event_t event);
+extern int handle_request(struct pcmcia_socket *s, event_t event);
+
+#else /* CONFIG_PCMCIA_IOCTL */
+
+static inline void __init pcmcia_setup_ioctl(void) { return; }
+static inline void __exit pcmcia_cleanup_ioctl(void) { return; }
+static inline void handle_event(struct pcmcia_socket *s, event_t event)
+{
+	return;
+}
+static inline int handle_request(struct pcmcia_socket *s, event_t event)
+{
+	return 0;
+}
+
+#endif /* CONFIG_PCMCIA_IOCTL */
 
 #endif /* _LINUX_CS_INTERNAL_H */
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 34c83d3..7956602 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -32,7 +32,6 @@
 #include <pcmcia/ss.h>
 
 #include "cs_internal.h"
-#include "ds_internal.h"
 
 /*====================================================================*/
 
@@ -42,17 +41,22 @@
 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;
@@ -64,42 +68,19 @@
 /* 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 @@
     { 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;
+
+	return "Unknown service number";
+}
+EXPORT_SYMBOL(pcmcia_error_func);
+
+const char *pcmcia_error_ret(int ret)
+{
+	int i;
 
 	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);
+		if (error_table[i].key == ret)
+			return error_table[i].msg;
 
-	return CS_SUCCESS;
-} /* report_error */
-
-/* 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 @@
 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);
@@ -401,7 +368,7 @@
 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;
@@ -439,8 +406,7 @@
 	 */
 	did = p_dev->dev.driver_data;
 
-	ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id,
-	       p_drv->drv.name);
+	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))) {
@@ -455,15 +421,16 @@
 		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;
 	}
 
@@ -490,8 +457,9 @@
 	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;
@@ -508,7 +476,7 @@
 		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 +493,7 @@
 	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
@@ -548,13 +516,15 @@
 
 	/* 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 +573,9 @@
 		}
 		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 +656,7 @@
 	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);
 
@@ -706,7 +677,7 @@
 	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)
@@ -714,8 +685,9 @@
 		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 +722,20 @@
 	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 +756,7 @@
 {
 	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 +766,7 @@
 {
 	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 +780,7 @@
 	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 +831,17 @@
 	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;
 	}
 
@@ -878,23 +850,16 @@
 	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 +963,14 @@
 		 * 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 +1002,9 @@
 	/* 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;
 		}
@@ -1051,18 +1014,15 @@
 #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 +1228,7 @@
 	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);
@@ -1279,15 +1239,16 @@
 	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 +1268,7 @@
 	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);
@@ -1316,7 +1277,7 @@
 		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 +1319,14 @@
 
 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 +1352,14 @@
 	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 +1434,8 @@
 
 	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;
 	}
 
@@ -1492,7 +1455,7 @@
 
 	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);
 	}
diff --git a/drivers/pcmcia/ds_internal.h b/drivers/pcmcia/ds_internal.h
deleted file mode 100644
index 3a2b25e..0000000
--- a/drivers/pcmcia/ds_internal.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* ds_internal.h - internal header for 16-bit PCMCIA devices management */
-
-extern spinlock_t pcmcia_dev_list_lock;
-extern struct bus_type pcmcia_bus_type;
-
-extern struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev);
-extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
-
-struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function);
-
-extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
-
-#ifdef CONFIG_PCMCIA_IOCTL
-extern void __init pcmcia_setup_ioctl(void);
-extern void __exit pcmcia_cleanup_ioctl(void);
-extern void handle_event(struct pcmcia_socket *s, event_t event);
-extern int handle_request(struct pcmcia_socket *s, event_t event);
-#else
-static inline void __init pcmcia_setup_ioctl(void) { return; }
-static inline void __exit pcmcia_cleanup_ioctl(void) { return; }
-static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; }
-static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; }
-#endif
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index fb2bc1f..117dc12 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -46,7 +46,6 @@
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
 #include <pcmcia/ss.h>
-#include "cs_internal.h"
 
 #define MODNAME "hd64465_ss"
 
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 68f6b27..71653ab 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -63,7 +63,7 @@
 #include "vg468.h"
 #include "ricoh.h"
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 static const char version[] =
 "i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)";
 
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 3616da2..2ab4f22 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -38,7 +38,7 @@
 
 #include "m32r_cfc.h"
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 static int m32r_cfc_debug;
 module_param(m32r_cfc_debug, int, 0644);
 #define debug(lvl, fmt, arg...) do {				\
@@ -505,7 +505,7 @@
 		pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
 	}
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 	if(state->flags & SS_IOCARD){
 		debug(3, ":IOCARD");
 	}
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 2b42b71..2f108c2 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -45,7 +45,7 @@
 
 #define PCC_DEBUG_DBEX
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 static int m32r_pcc_debug;
 module_param(m32r_pcc_debug, int, 0644);
 #define debug(lvl, fmt, arg...) do {				\
@@ -460,7 +460,7 @@
 
 	pcc_set(sock,PCCSIGCR,reg);
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 	if(state->flags & SS_IOCARD){
 		debug(3, ":IOCARD");
 	}
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index ff66604..d1ad096 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -64,8 +64,8 @@
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
+#ifdef CONFIG_PCMCIA_DEBUG
+static int pc_debug;
 module_param(pc_debug, int, 0);
 #define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
 #else
diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h
index a234ce1..5554015 100644
--- a/drivers/pcmcia/o2micro.h
+++ b/drivers/pcmcia/o2micro.h
@@ -140,7 +140,8 @@
 		a = config_readb(socket, O2_RESERVED1);
 		b = config_readb(socket, O2_RESERVED2);
 
-		printk(KERN_INFO "Yenta O2: res at 0x94/0xD4: %02x/%02x\n", a, b);
+		dev_printk(KERN_INFO, &socket->dev->dev,
+			   "O2: res at 0x94/0xD4: %02x/%02x\n", a, b);
 
 		switch (socket->dev->device) {
 		/*
@@ -153,7 +154,9 @@
 		case PCI_DEVICE_ID_O2_6812:
 		case PCI_DEVICE_ID_O2_6832:
 		case PCI_DEVICE_ID_O2_6836:
-			printk(KERN_INFO "Yenta O2: old bridge, disabling read prefetch/write burst\n");
+			dev_printk(KERN_INFO, &socket->dev->dev,
+				   "Yenta O2: old bridge, disabling read "
+				   "prefetch/write burst\n");
 			config_writeb(socket, O2_RESERVED1,
 			              a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
 			config_writeb(socket, O2_RESERVED2,
@@ -161,7 +164,8 @@
 			break;
 
 		default:
-			printk(KERN_INFO "Yenta O2: enabling read prefetch/write burst\n");
+			dev_printk(KERN_INFO , &socket->dev->dev,
+				   "O2: enabling read prefetch/write burst\n");
 			config_writeb(socket, O2_RESERVED1,
 			              a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
 			config_writeb(socket, O2_RESERVED2,
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 419f97f..1703b20 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -38,7 +38,6 @@
 #include <pcmcia/ss.h>
 
 #include "cs_internal.h"
-#include "ds_internal.h"
 
 static int major_dev = -1;
 
@@ -58,7 +57,7 @@
 } user_info_t;
 
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 extern int ds_pc_debug;
 
 #define ds_dbg(lvl, fmt, arg...) do {		\
@@ -149,7 +148,7 @@
 
 	irq = adj->resource.irq.IRQ;
 	if ((irq < 0) || (irq > 15))
-		return CS_BAD_IRQ;
+		return -EINVAL;
 
 	if (adj->Action != REMOVE_MANAGED_RESOURCE)
 		return 0;
@@ -167,7 +166,7 @@
 #else
 
 static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
-	return CS_SUCCESS;
+	return 0;
 }
 
 #endif
@@ -175,7 +174,7 @@
 static int pcmcia_adjust_resource_info(adjust_t *adj)
 {
 	struct pcmcia_socket *s;
-	int ret = CS_UNSUPPORTED_FUNCTION;
+	int ret = -ENOSYS;
 	unsigned long flags;
 
 	down_read(&pcmcia_socket_list_rwsem);
@@ -248,7 +247,7 @@
 	if (s->state & SOCKET_SUSPEND)
 		status->CardState |= CS_EVENT_PM_SUSPEND;
 	if (!(s->state & SOCKET_PRESENT))
-		return CS_NO_CARD;
+		return -ENODEV;
 
 	c = (p_dev) ? p_dev->function_config : NULL;
 
@@ -274,7 +273,7 @@
 			status->CardState |=
 				(reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
 		}
-		return CS_SUCCESS;
+		return 0;
 	}
 	status->CardState |=
 		(val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
@@ -284,9 +283,81 @@
 		(val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
 	status->CardState |=
 		(val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
-	return CS_SUCCESS;
+	return 0;
 } /* pccard_get_status */
 
+int pccard_get_configuration_info(struct pcmcia_socket *s,
+				  struct pcmcia_device *p_dev,
+				  config_info_t *config)
+{
+	config_t *c;
+
+	if (!(s->state & SOCKET_PRESENT))
+		return -ENODEV;
+
+
+#ifdef CONFIG_CARDBUS
+	if (s->state & SOCKET_CARDBUS) {
+		memset(config, 0, sizeof(config_info_t));
+		config->Vcc = s->socket.Vcc;
+		config->Vpp1 = config->Vpp2 = s->socket.Vpp;
+		config->Option = s->cb_dev->subordinate->number;
+		if (s->state & SOCKET_CARDBUS_CONFIG) {
+			config->Attributes = CONF_VALID_CLIENT;
+			config->IntType = INT_CARDBUS;
+			config->AssignedIRQ = s->irq.AssignedIRQ;
+			if (config->AssignedIRQ)
+				config->Attributes |= CONF_ENABLE_IRQ;
+			if (s->io[0].res) {
+				config->BasePort1 = s->io[0].res->start;
+				config->NumPorts1 = s->io[0].res->end -
+					config->BasePort1 + 1;
+			}
+		}
+		return 0;
+	}
+#endif
+
+	if (p_dev) {
+		c = p_dev->function_config;
+		config->Function = p_dev->func;
+	} else {
+		c = NULL;
+		config->Function = 0;
+	}
+
+	if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
+		config->Attributes = 0;
+		config->Vcc = s->socket.Vcc;
+		config->Vpp1 = config->Vpp2 = s->socket.Vpp;
+		return 0;
+	}
+
+	config->Attributes = c->Attributes | CONF_VALID_CLIENT;
+	config->Vcc = s->socket.Vcc;
+	config->Vpp1 = config->Vpp2 = s->socket.Vpp;
+	config->IntType = c->IntType;
+	config->ConfigBase = c->ConfigBase;
+	config->Status = c->Status;
+	config->Pin = c->Pin;
+	config->Copy = c->Copy;
+	config->Option = c->Option;
+	config->ExtStatus = c->ExtStatus;
+	config->Present = config->CardValues = c->CardValues;
+	config->IRQAttributes = c->irq.Attributes;
+	config->AssignedIRQ = s->irq.AssignedIRQ;
+	config->BasePort1 = c->io.BasePort1;
+	config->NumPorts1 = c->io.NumPorts1;
+	config->Attributes1 = c->io.Attributes1;
+	config->BasePort2 = c->io.BasePort2;
+	config->NumPorts2 = c->io.NumPorts2;
+	config->Attributes2 = c->io.Attributes2;
+	config->IOAddrLines = c->io.IOAddrLines;
+
+	return 0;
+} /* pccard_get_configuration_info */
+
+
 /*======================================================================
 
     These manage a ring buffer of events pending for one user process
@@ -764,7 +835,7 @@
     case DS_GET_CONFIGURATION_INFO:
 	if (buf->config.Function &&
 	   (buf->config.Function >= s->functions))
-	    ret = CS_BAD_ARGS;
+	    ret = -EINVAL;
 	else {
 	    struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
 	    ret = pccard_get_configuration_info(s, p_dev, &buf->config);
@@ -787,15 +858,15 @@
 	break;
     case DS_PARSE_TUPLE:
 	buf->tuple.TupleData = buf->tuple_parse.data;
-	ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
+	ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
 	break;
     case DS_RESET_CARD:
-	ret = pccard_reset_card(s);
+	ret = pcmcia_reset_card(s);
 	break;
     case DS_GET_STATUS:
 	    if (buf->status.Function &&
 		(buf->status.Function >= s->functions))
-		    ret = CS_BAD_ARGS;
+		    ret = -EINVAL;
 	    else {
 		    struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
 		    ret = pccard_get_status(s, p_dev, &buf->status);
@@ -826,7 +897,7 @@
 	    goto free_out;
 	}
 
-	ret = CS_BAD_ARGS;
+	ret = -EINVAL;
 
 	if (!(buf->conf_reg.Function &&
 	     (buf->conf_reg.Function >= s->functions))) {
@@ -867,7 +938,7 @@
 			   &buf->win_info.map);
 	break;
     case DS_REPLACE_CIS:
-	ret = pcmcia_replace_cis(s, &buf->cisdump);
+	ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length);
 	break;
     case DS_BIND_REQUEST:
 	if (!capable(CAP_SYS_ADMIN)) {
@@ -889,22 +960,19 @@
 	err = -EINVAL;
     }
 
-    if ((err == 0) && (ret != CS_SUCCESS)) {
+    if ((err == 0) && (ret != 0)) {
 	ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
 	switch (ret) {
-	case CS_BAD_SOCKET: case CS_NO_CARD:
-	    err = -ENODEV; break;
-	case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
-	case CS_BAD_TUPLE:
-	    err = -EINVAL; break;
-	case CS_IN_USE:
-	    err = -EBUSY; break;
-	case CS_OUT_OF_RESOURCE:
+	case -ENODEV:
+	case -EINVAL:
+	case -EBUSY:
+	case -ENOSYS:
+	    err = ret;
+	    break;
+	case -ENOMEM:
 	    err = -ENOSPC; break;
-	case CS_NO_MORE_ITEMS:
+	case -ENOSPC:
 	    err = -ENODATA; break;
-	case CS_UNSUPPORTED_FUNCTION:
-	    err = -ENOSYS; break;
 	default:
 	    err = -EIO; break;
 	}
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 4884a18..afea2b2 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -29,7 +29,6 @@
 #include <pcmcia/ds.h>
 
 #include "cs_internal.h"
-#include "ds_internal.h"
 
 
 /* Access speed for IO windows */
@@ -44,16 +43,17 @@
 #endif
 
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 extern int ds_pc_debug;
 
 #define ds_dbg(skt, lvl, fmt, arg...) do {			\
 	if (ds_pc_debug >= lvl)					\
-		printk(KERN_DEBUG "pcmcia_resource: %s: " fmt,	\
-			cs_socket_name(skt) , ## arg);		\
+		dev_printk(KERN_DEBUG, &skt->dev,		\
+			   "pcmcia_resource: " fmt,		\
+			   ## arg);				\
 } while (0)
 #else
-#define ds_dbg(lvl, fmt, arg...) do { } while (0)
+#define ds_dbg(skt, lvl, fmt, arg...) do { } while (0)
 #endif
 
 
@@ -168,13 +168,13 @@
 	u_char val;
 
 	if (!p_dev || !p_dev->function_config)
-		return CS_NO_CARD;
+		return -EINVAL;
 
 	s = p_dev->socket;
 	c = p_dev->function_config;
 
 	if (!(c->state & CONFIG_LOCKED))
-		return CS_CONFIGURATION_LOCKED;
+		return -EACCES;
 
 	addr = (c->ConfigBase + reg->Offset) >> 1;
 
@@ -188,93 +188,14 @@
 		pcmcia_write_cis_mem(s, 1, addr, 1, &val);
 		break;
 	default:
-		return CS_BAD_ARGS;
+		return -EINVAL;
 		break;
 	}
-	return CS_SUCCESS;
+	return 0;
 } /* pcmcia_access_configuration_register */
 EXPORT_SYMBOL(pcmcia_access_configuration_register);
 
 
-int pccard_get_configuration_info(struct pcmcia_socket *s,
-				  struct pcmcia_device *p_dev,
-				  config_info_t *config)
-{
-	config_t *c;
-
-	if (!(s->state & SOCKET_PRESENT))
-		return CS_NO_CARD;
-
-
-#ifdef CONFIG_CARDBUS
-	if (s->state & SOCKET_CARDBUS) {
-		memset(config, 0, sizeof(config_info_t));
-		config->Vcc = s->socket.Vcc;
-		config->Vpp1 = config->Vpp2 = s->socket.Vpp;
-		config->Option = s->cb_dev->subordinate->number;
-		if (s->state & SOCKET_CARDBUS_CONFIG) {
-			config->Attributes = CONF_VALID_CLIENT;
-			config->IntType = INT_CARDBUS;
-			config->AssignedIRQ = s->irq.AssignedIRQ;
-			if (config->AssignedIRQ)
-				config->Attributes |= CONF_ENABLE_IRQ;
-			if (s->io[0].res) {
-				config->BasePort1 = s->io[0].res->start;
-				config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1;
-			}
-		}
-		return CS_SUCCESS;
-	}
-#endif
-
-	if (p_dev) {
-		c = p_dev->function_config;
-		config->Function = p_dev->func;
-	} else {
-		c = NULL;
-		config->Function = 0;
-	}
-
-	if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
-		config->Attributes = 0;
-		config->Vcc = s->socket.Vcc;
-		config->Vpp1 = config->Vpp2 = s->socket.Vpp;
-		return CS_SUCCESS;
-	}
-
-	config->Attributes = c->Attributes | CONF_VALID_CLIENT;
-	config->Vcc = s->socket.Vcc;
-	config->Vpp1 = config->Vpp2 = s->socket.Vpp;
-	config->IntType = c->IntType;
-	config->ConfigBase = c->ConfigBase;
-	config->Status = c->Status;
-	config->Pin = c->Pin;
-	config->Copy = c->Copy;
-	config->Option = c->Option;
-	config->ExtStatus = c->ExtStatus;
-	config->Present = config->CardValues = c->CardValues;
-	config->IRQAttributes = c->irq.Attributes;
-	config->AssignedIRQ = s->irq.AssignedIRQ;
-	config->BasePort1 = c->io.BasePort1;
-	config->NumPorts1 = c->io.NumPorts1;
-	config->Attributes1 = c->io.Attributes1;
-	config->BasePort2 = c->io.BasePort2;
-	config->NumPorts2 = c->io.NumPorts2;
-	config->Attributes2 = c->io.Attributes2;
-	config->IOAddrLines = c->io.IOAddrLines;
-
-	return CS_SUCCESS;
-} /* pccard_get_configuration_info */
-
-int pcmcia_get_configuration_info(struct pcmcia_device *p_dev,
-				  config_info_t *config)
-{
-	return pccard_get_configuration_info(p_dev->socket, p_dev,
-					     config);
-}
-EXPORT_SYMBOL(pcmcia_get_configuration_info);
-
-
 /** pcmcia_get_window
  */
 int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
@@ -284,12 +205,12 @@
 	int w;
 
 	if (!s || !(s->state & SOCKET_PRESENT))
-		return CS_NO_CARD;
+		return -ENODEV;
 	for (w = idx; w < MAX_WIN; w++)
 		if (s->state & SOCKET_WIN_REQ(w))
 			break;
 	if (w == MAX_WIN)
-		return CS_NO_MORE_ITEMS;
+		return -EINVAL;
 	win = &s->win[w];
 	req->Base = win->ctl.res->start;
 	req->Size = win->ctl.res->end - win->ctl.res->start + 1;
@@ -304,7 +225,7 @@
 	if (win->ctl.flags & MAP_USE_WAIT)
 		req->Attributes |= WIN_USE_WAIT;
 	*handle = win;
-	return CS_SUCCESS;
+	return 0;
 } /* pcmcia_get_window */
 EXPORT_SYMBOL(pcmcia_get_window);
 
@@ -316,10 +237,10 @@
 int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
 {
 	if ((win == NULL) || (win->magic != WINDOW_MAGIC))
-		return CS_BAD_HANDLE;
+		return -EINVAL;
 	req->Page = 0;
 	req->CardOffset = win->ctl.card_start;
-	return CS_SUCCESS;
+	return 0;
 } /* pcmcia_get_mem_page */
 EXPORT_SYMBOL(pcmcia_get_mem_page);
 
@@ -328,14 +249,18 @@
 {
 	struct pcmcia_socket *s;
 	if ((win == NULL) || (win->magic != WINDOW_MAGIC))
-		return CS_BAD_HANDLE;
-	if (req->Page != 0)
-		return CS_BAD_PAGE;
+		return -EINVAL;
 	s = win->sock;
+	if (req->Page != 0) {
+		ds_dbg(s, 0, "failure: requested page is zero\n");
+		return -EINVAL;
+	}
 	win->ctl.card_start = req->CardOffset;
-	if (s->ops->set_mem_map(s, &win->ctl) != 0)
-		return CS_BAD_OFFSET;
-	return CS_SUCCESS;
+	if (s->ops->set_mem_map(s, &win->ctl) != 0) {
+		ds_dbg(s, 0, "failed to set_mem_map\n");
+		return -EIO;
+	}
+	return 0;
 } /* pcmcia_map_mem_page */
 EXPORT_SYMBOL(pcmcia_map_mem_page);
 
@@ -354,9 +279,9 @@
 	c = p_dev->function_config;
 
 	if (!(s->state & SOCKET_PRESENT))
-		return CS_NO_CARD;
+		return -ENODEV;
 	if (!(c->state & CONFIG_LOCKED))
-		return CS_CONFIGURATION_LOCKED;
+		return -EACCES;
 
 	if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
 		if (mod->Attributes & CONF_ENABLE_IRQ) {
@@ -369,20 +294,28 @@
 		s->ops->set_socket(s, &s->socket);
 	}
 
-	if (mod->Attributes & CONF_VCC_CHANGE_VALID)
-		return CS_BAD_VCC;
+	if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
+		ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
+		return -EINVAL;
+	}
 
 	/* We only allow changing Vpp1 and Vpp2 to the same value */
 	if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
 	    (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
 		if (mod->Vpp1 != mod->Vpp2)
-			return CS_BAD_VPP;
+			ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n");
+			return -EINVAL;
 		s->socket.Vpp = mod->Vpp1;
-		if (s->ops->set_socket(s, &s->socket))
-			return CS_BAD_VPP;
+		if (s->ops->set_socket(s, &s->socket)) {
+			dev_printk(KERN_WARNING, &s->dev,
+				   "Unable to set VPP\n");
+			return -EIO;
+		}
 	} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
-		   (mod->Attributes & CONF_VPP2_CHANGE_VALID))
-		return CS_BAD_VPP;
+		   (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
+		ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
+		return -EINVAL;
+	}
 
 	if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
 		pccard_io_map io_off = { 0, 0, 0, 0, 1 };
@@ -406,7 +339,7 @@
 		}
 	}
 
-	return CS_SUCCESS;
+	return 0;
 } /* modify_configuration */
 EXPORT_SYMBOL(pcmcia_modify_configuration);
 
@@ -441,7 +374,7 @@
 			}
 	}
 
-	return CS_SUCCESS;
+	return 0;
 } /* pcmcia_release_configuration */
 
 
@@ -459,7 +392,7 @@
 	config_t *c = p_dev->function_config;
 
 	if (!p_dev->_io )
-		return CS_BAD_HANDLE;
+		return -EINVAL;
 
 	p_dev->_io = 0;
 
@@ -467,7 +400,7 @@
 	    (c->io.NumPorts1 != req->NumPorts1) ||
 	    (c->io.BasePort2 != req->BasePort2) ||
 	    (c->io.NumPorts2 != req->NumPorts2))
-		return CS_BAD_ARGS;
+		return -EINVAL;
 
 	c->state &= ~CONFIG_IO_REQ;
 
@@ -475,7 +408,7 @@
 	if (req->NumPorts2)
 		release_io_space(s, req->BasePort2, req->NumPorts2);
 
-	return CS_SUCCESS;
+	return 0;
 } /* pcmcia_release_io */
 
 
@@ -485,15 +418,19 @@
 	config_t *c= p_dev->function_config;
 
 	if (!p_dev->_irq)
-		return CS_BAD_HANDLE;
+		return -EINVAL;
 	p_dev->_irq = 0;
 
 	if (c->state & CONFIG_LOCKED)
-		return CS_CONFIGURATION_LOCKED;
-	if (c->irq.Attributes != req->Attributes)
-		return CS_BAD_ATTRIBUTE;
-	if (s->irq.AssignedIRQ != req->AssignedIRQ)
-		return CS_BAD_IRQ;
+		return -EACCES;
+	if (c->irq.Attributes != req->Attributes) {
+		ds_dbg(s, 0, "IRQ attributes must match assigned ones\n");
+		return -EINVAL;
+	}
+	if (s->irq.AssignedIRQ != req->AssignedIRQ) {
+		ds_dbg(s, 0, "IRQ must match assigned one\n");
+		return -EINVAL;
+	}
 	if (--s->irq.Config == 0) {
 		c->state &= ~CONFIG_IRQ_REQ;
 		s->irq.AssignedIRQ = 0;
@@ -507,7 +444,7 @@
 	pcmcia_used_irq[req->AssignedIRQ]--;
 #endif
 
-	return CS_SUCCESS;
+	return 0;
 } /* pcmcia_release_irq */
 
 
@@ -516,10 +453,10 @@
 	struct pcmcia_socket *s;
 
 	if ((win == NULL) || (win->magic != WINDOW_MAGIC))
-		return CS_BAD_HANDLE;
+		return -EINVAL;
 	s = win->sock;
 	if (!(win->handle->_win & CLIENT_WIN_REQ(win->index)))
-		return CS_BAD_HANDLE;
+		return -EINVAL;
 
 	/* Shut down memory window */
 	win->ctl.flags &= ~MAP_ACTIVE;
@@ -536,7 +473,7 @@
 
 	win->magic = 0;
 
-	return CS_SUCCESS;
+	return 0;
 } /* pcmcia_release_window */
 EXPORT_SYMBOL(pcmcia_release_window);
 
@@ -551,18 +488,23 @@
 	pccard_io_map iomap;
 
 	if (!(s->state & SOCKET_PRESENT))
-		return CS_NO_CARD;
+		return -ENODEV;;
 
-	if (req->IntType & INT_CARDBUS)
-		return CS_UNSUPPORTED_MODE;
+	if (req->IntType & INT_CARDBUS) {
+		ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n");
+		return -EINVAL;
+	}
 	c = p_dev->function_config;
 	if (c->state & CONFIG_LOCKED)
-		return CS_CONFIGURATION_LOCKED;
+		return -EACCES;
 
 	/* Do power control.  We don't allow changes in Vcc. */
 	s->socket.Vpp = req->Vpp;
-	if (s->ops->set_socket(s, &s->socket))
-		return CS_BAD_VPP;
+	if (s->ops->set_socket(s, &s->socket)) {
+		dev_printk(KERN_WARNING, &s->dev,
+			   "Unable to set socket state\n");
+		return -EINVAL;
+	}
 
 	/* Pick memory or I/O card, DMA mode, interrupt */
 	c->IntType = req->IntType;
@@ -651,7 +593,7 @@
 
 	c->state |= CONFIG_LOCKED;
 	p_dev->_locked = 1;
-	return CS_SUCCESS;
+	return 0;
 } /* pcmcia_request_configuration */
 EXPORT_SYMBOL(pcmcia_request_configuration);
 
@@ -667,37 +609,48 @@
 	config_t *c;
 
 	if (!(s->state & SOCKET_PRESENT))
-		return CS_NO_CARD;
+		return -ENODEV;
 
 	if (!req)
-		return CS_UNSUPPORTED_MODE;
+		return -EINVAL;
 	c = p_dev->function_config;
 	if (c->state & CONFIG_LOCKED)
-		return CS_CONFIGURATION_LOCKED;
-	if (c->state & CONFIG_IO_REQ)
-		return CS_IN_USE;
-	if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))
-		return CS_BAD_ATTRIBUTE;
+		return -EACCES;
+	if (c->state & CONFIG_IO_REQ) {
+		ds_dbg(s, 0, "IO already configured\n");
+		return -EBUSY;
+	}
+	if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) {
+		ds_dbg(s, 0, "bad attribute setting for IO region 1\n");
+		return -EINVAL;
+	}
 	if ((req->NumPorts2 > 0) &&
-	    (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))
-		return CS_BAD_ATTRIBUTE;
+	    (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) {
+		ds_dbg(s, 0, "bad attribute setting for IO region 2\n");
+		return -EINVAL;
+	}
 
+	ds_dbg(s, 1, "trying to allocate resource 1\n");
 	if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
-			   req->NumPorts1, req->IOAddrLines))
-		return CS_IN_USE;
+			   req->NumPorts1, req->IOAddrLines)) {
+		ds_dbg(s, 0, "allocation of resource 1 failed\n");
+		return -EBUSY;
+	}
 
 	if (req->NumPorts2) {
+		ds_dbg(s, 1, "trying to allocate resource 2\n");
 		if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
 				   req->NumPorts2, req->IOAddrLines)) {
+			ds_dbg(s, 0, "allocation of resource 2 failed\n");
 			release_io_space(s, req->BasePort1, req->NumPorts1);
-			return CS_IN_USE;
+			return -EBUSY;
 		}
 	}
 
 	c->io = *req;
 	c->state |= CONFIG_IO_REQ;
 	p_dev->_io = 1;
-	return CS_SUCCESS;
+	return 0;
 } /* pcmcia_request_io */
 EXPORT_SYMBOL(pcmcia_request_io);
 
@@ -723,16 +676,18 @@
 {
 	struct pcmcia_socket *s = p_dev->socket;
 	config_t *c;
-	int ret = CS_IN_USE, irq = 0;
+	int ret = -EINVAL, irq = 0;
 	int type;
 
 	if (!(s->state & SOCKET_PRESENT))
-		return CS_NO_CARD;
+		return -ENODEV;
 	c = p_dev->function_config;
 	if (c->state & CONFIG_LOCKED)
-		return CS_CONFIGURATION_LOCKED;
-	if (c->state & CONFIG_IRQ_REQ)
-		return CS_IN_USE;
+		return -EACCES;
+	if (c->state & CONFIG_IRQ_REQ) {
+		ds_dbg(s, 0, "IRQ already configured\n");
+		return -EBUSY;
+	}
 
 	/* Decide what type of interrupt we are registering */
 	type = 0;
@@ -795,15 +750,19 @@
 	}
 
 	if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) {
-		if (request_irq(irq, req->Handler, type,  p_dev->devname, req->Instance))
-			return CS_IN_USE;
+		ret = request_irq(irq, req->Handler, type,
+				  p_dev->devname, req->Instance);
+		if (ret)
+			return ret;
 	}
 
 	/* Make sure the fact the request type was overridden is passed back */
 	if (type == IRQF_SHARED && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) {
 		req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
-		printk(KERN_WARNING "pcmcia: request for exclusive IRQ could not be fulfilled.\n");
-		printk(KERN_WARNING "pcmcia: the driver needs updating to supported shared IRQ lines.\n");
+		dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: "
+			"request for exclusive IRQ could not be fulfilled.\n");
+		dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver "
+			"needs updating to supported shared IRQ lines.\n");
 	}
 	c->irq.Attributes = req->Attributes;
 	s->irq.AssignedIRQ = req->AssignedIRQ = irq;
@@ -816,7 +775,7 @@
 	pcmcia_used_irq[irq]++;
 #endif
 
-	return CS_SUCCESS;
+	return 0;
 } /* pcmcia_request_irq */
 EXPORT_SYMBOL(pcmcia_request_irq);
 
@@ -834,9 +793,11 @@
 	int w;
 
 	if (!(s->state & SOCKET_PRESENT))
-		return CS_NO_CARD;
-	if (req->Attributes & (WIN_PAGED | WIN_SHARED))
-		return CS_BAD_ATTRIBUTE;
+		return -ENODEV;
+	if (req->Attributes & (WIN_PAGED | WIN_SHARED)) {
+		ds_dbg(s, 0, "bad attribute setting for iomem region\n");
+		return -EINVAL;
+	}
 
 	/* Window size defaults to smallest available */
 	if (req->Size == 0)
@@ -844,19 +805,25 @@
 	align = (((s->features & SS_CAP_MEM_ALIGN) ||
 		  (req->Attributes & WIN_STRICT_ALIGN)) ?
 		 req->Size : s->map_size);
-	if (req->Size & (s->map_size-1))
-		return CS_BAD_SIZE;
+	if (req->Size & (s->map_size-1)) {
+		ds_dbg(s, 0, "invalid map size\n");
+		return -EINVAL;
+	}
 	if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
-	    (req->Base & (align-1)))
-		return CS_BAD_BASE;
+	    (req->Base & (align-1))) {
+		ds_dbg(s, 0, "invalid base address\n");
+		return -EINVAL;
+	}
 	if (req->Base)
 		align = 0;
 
 	/* Allocate system memory window */
 	for (w = 0; w < MAX_WIN; w++)
 		if (!(s->state & SOCKET_WIN_REQ(w))) break;
-	if (w == MAX_WIN)
-		return CS_OUT_OF_RESOURCE;
+	if (w == MAX_WIN) {
+		ds_dbg(s, 0, "all windows are used already\n");
+		return -EINVAL;
+	}
 
 	win = &s->win[w];
 	win->magic = WINDOW_MAGIC;
@@ -867,8 +834,10 @@
 	if (!(s->features & SS_CAP_STATIC_MAP)) {
 		win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,
 						      (req->Attributes & WIN_MAP_BELOW_1MB), s);
-		if (!win->ctl.res)
-			return CS_IN_USE;
+		if (!win->ctl.res) {
+			ds_dbg(s, 0, "allocating mem region failed\n");
+			return -EINVAL;
+		}
 	}
 	(*p_dev)->_win |= CLIENT_WIN_REQ(w);
 
@@ -885,8 +854,10 @@
 	if (req->Attributes & WIN_USE_WAIT)
 		win->ctl.flags |= MAP_USE_WAIT;
 	win->ctl.card_start = 0;
-	if (s->ops->set_mem_map(s, &win->ctl) != 0)
-		return CS_BAD_ARGS;
+	if (s->ops->set_mem_map(s, &win->ctl) != 0) {
+		ds_dbg(s, 0, "failed to set memory mapping\n");
+		return -EIO;
+	}
 	s->state |= SOCKET_WIN_REQ(w);
 
 	/* Return window handle */
@@ -897,7 +868,7 @@
 	}
 	*wh = win;
 
-	return CS_SUCCESS;
+	return 0;
 } /* pcmcia_request_window */
 EXPORT_SYMBOL(pcmcia_request_window);
 
@@ -909,3 +880,79 @@
 		pcmcia_release_window(p_dev->win);
 }
 EXPORT_SYMBOL(pcmcia_disable_device);
+
+
+struct pcmcia_cfg_mem {
+	tuple_t tuple;
+	cisparse_t parse;
+	u8 buf[256];
+	cistpl_cftable_entry_t dflt;
+};
+
+/**
+ * pcmcia_loop_config() - loop over configuration options
+ * @p_dev:	the struct pcmcia_device which we need to loop for.
+ * @conf_check:	function to call for each configuration option.
+ *		It gets passed the struct pcmcia_device, the CIS data
+ *		describing the configuration option, and private data
+ *		being passed to pcmcia_loop_config()
+ * @priv_data:	private data to be passed to the conf_check function.
+ *
+ * pcmcia_loop_config() loops over all configuration options, and calls
+ * the driver-specific conf_check() for each one, checking whether
+ * it is a valid one.
+ */
+int pcmcia_loop_config(struct pcmcia_device *p_dev,
+		       int	(*conf_check)	(struct pcmcia_device *p_dev,
+						 cistpl_cftable_entry_t *cfg,
+						 cistpl_cftable_entry_t *dflt,
+						 unsigned int vcc,
+						 void *priv_data),
+		       void *priv_data)
+{
+	struct pcmcia_cfg_mem *cfg_mem;
+
+	tuple_t *tuple;
+	int ret = -ENODEV;
+	unsigned int vcc;
+
+	cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
+	if (cfg_mem == NULL)
+		return -ENOMEM;
+
+	/* get the current Vcc setting */
+	vcc = p_dev->socket->socket.Vcc;
+
+	tuple = &cfg_mem->tuple;
+	tuple->TupleData = cfg_mem->buf;
+	tuple->TupleDataMax = 255;
+	tuple->TupleOffset = 0;
+	tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	tuple->Attributes = 0;
+
+	ret = pcmcia_get_first_tuple(p_dev, tuple);
+	while (!ret) {
+		cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry;
+
+		if (pcmcia_get_tuple_data(p_dev, tuple))
+			goto next_entry;
+
+		if (pcmcia_parse_tuple(tuple, &cfg_mem->parse))
+			goto next_entry;
+
+		/* default values */
+		p_dev->conf.ConfigIndex = cfg->index;
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+			cfg_mem->dflt = *cfg;
+
+		ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data);
+		if (!ret)
+			break;
+
+next_entry:
+		ret = pcmcia_get_next_tuple(p_dev, tuple);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(pcmcia_loop_config);
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 13f1e0f..bb9ddb9 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -36,7 +36,6 @@
 #include <pcmcia/ss.h>
 #include <pcmcia/cistpl.h>
 
-#include "cs_internal.h"
 #include "soc_common.h"
 #include "pxa2xx_base.h"
 
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 203e579..17f4ecf 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -122,19 +122,22 @@
 
 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 @@
 	    } 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;
@@ -174,7 +180,7 @@
 	    }
 	}
     }
-    return CS_SUCCESS;
+    return 0;
 }
 
 /*======================================================================
@@ -194,13 +200,14 @@
     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) {
@@ -366,8 +373,8 @@
     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 @@
 	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 @@
 		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;
 
@@ -806,10 +814,11 @@
 		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;
 		}
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index da39721..f49ac66 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -54,7 +54,7 @@
 #include <mach/pxa-regs.h>
 #endif
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 
 static int pc_debug;
 module_param(pc_debug, int, 0644);
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 91ef6a0..38c6737 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -15,7 +15,6 @@
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cistpl.h>
-#include "cs_internal.h"
 
 
 struct device;
@@ -137,7 +136,7 @@
 extern int soc_common_drv_pcmcia_remove(struct device *dev);
 
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 
 extern void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
 			     int lvl, const char *fmt, ...);
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 006a29e..ff9a3bb 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -316,27 +316,18 @@
 				char *buf, loff_t off, size_t count)
 {
 	struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
-	cisdump_t *cis;
 	int error;
 
 	if (off)
 		return -EINVAL;
 
-	if (count >= 0x200)
+	if (count >= CISTPL_MAX_CIS_SIZE)
 		return -EINVAL;
 
 	if (!(s->state & SOCKET_PRESENT))
 		return -ENODEV;
 
-	cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
-	if (!cis)
-		return -ENOMEM;
-
-	cis->Length = count + 1;
-	memcpy(cis->Data, buf, count);
-
-	error = pcmcia_replace_cis(s, cis);
-	kfree(cis);
+	error = pcmcia_replace_cis(s, buf, count);
 	if (error)
 		return -EIO;
 
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 5792bd5..2a613e9 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -55,7 +55,7 @@
 #include <pcmcia/ss.h>
 #include "tcic.h"
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 static int pc_debug;
 
 module_param(pc_debug, int, 0644);
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index 129db7b..aaa7022 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -339,8 +339,8 @@
 
 	mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
 	devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
-	printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
-	       pci_name(socket->dev), mfunc, devctl);
+	dev_printk(KERN_INFO, &socket->dev->dev,
+		   "TI: mfunc 0x%08x, devctl 0x%02x\n", mfunc, devctl);
 
 	/* make sure PCI interrupts are enabled before probing */
 	ti_init(socket);
@@ -354,8 +354,8 @@
 	 * We're here which means PCI interrupts are _not_ delivered. try to
 	 * find the right setting (all serial or parallel)
 	 */
-	printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n",
-	       pci_name(socket->dev));
+	dev_printk(KERN_INFO, &socket->dev->dev,
+		   "TI: probing PCI interrupt failed, trying to fix\n");
 
 	/* for serial PCI make sure MFUNC3 is set to IRQSER */
 	if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {
@@ -379,8 +379,8 @@
 
 				pci_irq_status = yenta_probe_cb_irq(socket);
 				if (pci_irq_status == 1) {
-					printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts ok\n",
-					       pci_name(socket->dev));
+					dev_printk(KERN_INFO, &socket->dev->dev,
+					    "TI: all-serial interrupts ok\n");
 					mfunc_old = mfunc;
 					goto out;
 				}
@@ -395,8 +395,8 @@
 		}
 
 		/* serial PCI interrupts not working fall back to parallel */
-		printk(KERN_INFO "Yenta TI: socket %s falling back to parallel PCI interrupts\n",
-		       pci_name(socket->dev));
+		dev_printk(KERN_INFO, &socket->dev->dev,
+			   "TI: falling back to parallel PCI interrupts\n");
 		devctl &= ~TI113X_DCR_IMODE_MASK;
 		devctl |= TI113X_DCR_IMODE_SERIAL; /* serial ISA could be right */
 		config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
@@ -427,8 +427,8 @@
 	pci_irq_status = yenta_probe_cb_irq(socket);
 	if (pci_irq_status == 1) {
 		mfunc_old = mfunc;
-		printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n",
-		       pci_name(socket->dev));
+		dev_printk(KERN_INFO, &socket->dev->dev,
+			   "TI: parallel PCI interrupts ok\n");
 	} else {
 		/* not working, back to old value */
 		mfunc = mfunc_old;
@@ -440,8 +440,9 @@
 out:
 	if (pci_irq_status < 1) {
 		socket->cb_irq = 0;
-		printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n",
-		       pci_name(socket->dev));
+		dev_printk(KERN_INFO, &socket->dev->dev,
+			   "Yenta TI: no PCI interrupts. Fish. "
+			   "Please report.\n");
 	}
 }
 
@@ -513,8 +514,9 @@
 
 	mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
 	devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
-	printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
-	       pci_name(socket->dev), mfunc, devctl);
+	dev_printk(KERN_INFO, &socket->dev->dev,
+		   "TI: mfunc 0x%08x, devctl 0x%02x\n",
+		   mfunc, devctl);
 
 	/* if IRQs are configured as tied, align irq of func1 with func0 */
 	sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
@@ -533,9 +535,8 @@
 	 * We're here which means PCI interrupts are _not_ delivered. try to
 	 * find the right setting
 	 */
-	printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n",
-	       pci_name(socket->dev));
-
+	dev_printk(KERN_INFO, &socket->dev->dev,
+		   "TI: probing PCI interrupt failed, trying to fix\n");
 
 	/* if all serial: set INTRTIE, probe again */
 	if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {
@@ -544,8 +545,8 @@
 		if (ti12xx_tie_interrupts(socket, &old_irq)) {
 			pci_irq_status = yenta_probe_cb_irq(socket);
 			if (pci_irq_status == 1) {
-				printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts, tied ok\n",
-				       pci_name(socket->dev));
+				dev_printk(KERN_INFO, &socket->dev->dev,
+					"TI: all-serial interrupts, tied ok\n");
 				goto out;
 			}
 
@@ -582,8 +583,8 @@
 
 			pci_irq_status = yenta_probe_cb_irq(socket);
 			if (pci_irq_status == 1) {
-				printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n",
-				       pci_name(socket->dev));
+				dev_printk(KERN_INFO, &socket->dev->dev,
+					   "TI: parallel PCI interrupts ok\n");
 				goto out;
 			}
 
@@ -593,13 +594,13 @@
 			if (pci_irq_status == -1)
 				goto out;
 		}
-		
+
 		/* still nothing: set INTRTIE */
 		if (ti12xx_tie_interrupts(socket, &old_irq)) {
 			pci_irq_status = yenta_probe_cb_irq(socket);
 			if (pci_irq_status == 1) {
-				printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts, tied ok\n",
-				       pci_name(socket->dev));
+				dev_printk(KERN_INFO, &socket->dev->dev,
+				    "TI: parallel PCI interrupts, tied ok\n");
 				goto out;
 			}
 
@@ -610,8 +611,8 @@
 out:
 	if (pci_irq_status < 1) {
 		socket->cb_irq = 0;
-		printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n",
-		       pci_name(socket->dev));
+		dev_printk(KERN_INFO, &socket->dev->dev,
+			   "TI: no PCI interrupts. Fish. Please report.\n");
 	}
 }
 
@@ -815,11 +816,13 @@
 	/* make sure that memory burst is active */
 	val_orig = val = config_readl(socket, TI113X_SYSTEM_CONTROL);
 	if (disable_clkrun && PCI_FUNC(socket->dev->devfn) == 0) {
-		printk(KERN_INFO "Yenta: Disabling CLKRUN feature\n");
+		dev_printk(KERN_INFO, &socket->dev->dev,
+			   "Disabling CLKRUN feature\n");
 		val |= TI113X_SCR_KEEPCLK;
 	}
 	if (!(val & TI122X_SCR_MRBURSTUP)) {
-		printk(KERN_INFO "Yenta: Enabling burst memory read transactions\n");
+		dev_printk(KERN_INFO, &socket->dev->dev,
+			   "Enabling burst memory read transactions\n");
 		val |= TI122X_SCR_MRBURSTUP;
 	}
 	if (val_orig != val)
@@ -830,10 +833,12 @@
 	 * CSC interrupts to PCI rather than INTVAL.
 	 */
 	val = config_readb(socket, TI1250_DIAGNOSTIC);
-	printk(KERN_INFO "Yenta: Using %s to route CSC interrupts to PCI\n",
-		(val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");
-	printk(KERN_INFO "Yenta: Routing CardBus interrupts to %s\n",
-		(val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
+	dev_printk(KERN_INFO, &socket->dev->dev,
+		   "Using %s to route CSC interrupts to PCI\n",
+		   (val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");
+	dev_printk(KERN_INFO, &socket->dev->dev,
+		   "Routing CardBus interrupts to %s\n",
+		   (val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
 
 	/* do irqrouting, depending on function */
 	if (PCI_FUNC(socket->dev->devfn) == 0)
@@ -858,8 +863,9 @@
 		diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
 
 	if (diag != old) {
-		printk(KERN_INFO "Yenta: adjusting diagnostic: %02x -> %02x\n",
-			old, diag);
+		dev_printk(KERN_INFO, &socket->dev->dev,
+			   "adjusting diagnostic: %02x -> %02x\n",
+			   old, diag);
 		config_writeb(socket, TI1250_DIAGNOSTIC, diag);
 	}
 
@@ -924,7 +930,9 @@
 		/* default to clear TLTEnable bit, old behaviour */
 		test_c9 &= ~ENE_TEST_C9_TLTENABLE;
 
-	printk(KERN_INFO "yenta EnE: chaning testregister 0xC9, %02x -> %02x\n", old_c9, test_c9);
+	dev_printk(KERN_INFO, &socket->dev->dev,
+		   "EnE: chaning testregister 0xC9, %02x -> %02x\n",
+		   old_c9, test_c9);
 	config_writeb(socket, ENE_TEST_C9, test_c9);
 }
 
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 0ab1fb6..3ecd7c9 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -38,11 +38,7 @@
 module_param(pwr_irqs_off, bool, 0644);
 MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
 
-#if 0
-#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
-#else
-#define debug(x,args...)
-#endif
+#define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args)
 
 /* Don't ask.. */
 #define to_cycles(ns)	((ns)/120)
@@ -69,13 +65,13 @@
 static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg)
 {
 	u32 val = readl(socket->base + reg);
-	debug("%p %04x %08x\n", socket, reg, val);
+	debug("%04x %08x\n", socket, reg, val);
 	return val;
 }
 
 static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
 {
-	debug("%p %04x %08x\n", socket, reg, val);
+	debug("%04x %08x\n", socket, reg, val);
 	writel(val, socket->base + reg);
 	readl(socket->base + reg); /* avoid problems with PCI write posting */
 }
@@ -84,7 +80,7 @@
 {
 	u8 val;
 	pci_read_config_byte(socket->dev, offset, &val);
-	debug("%p %04x %02x\n", socket, offset, val);
+	debug("%04x %02x\n", socket, offset, val);
 	return val;
 }
 
@@ -92,7 +88,7 @@
 {
 	u16 val;
 	pci_read_config_word(socket->dev, offset, &val);
-	debug("%p %04x %04x\n", socket, offset, val);
+	debug("%04x %04x\n", socket, offset, val);
 	return val;
 }
 
@@ -100,32 +96,32 @@
 {
 	u32 val;
 	pci_read_config_dword(socket->dev, offset, &val);
-	debug("%p %04x %08x\n", socket, offset, val);
+	debug("%04x %08x\n", socket, offset, val);
 	return val;
 }
 
 static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val)
 {
-	debug("%p %04x %02x\n", socket, offset, val);
+	debug("%04x %02x\n", socket, offset, val);
 	pci_write_config_byte(socket->dev, offset, val);
 }
 
 static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val)
 {
-	debug("%p %04x %04x\n", socket, offset, val);
+	debug("%04x %04x\n", socket, offset, val);
 	pci_write_config_word(socket->dev, offset, val);
 }
 
 static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val)
 {
-	debug("%p %04x %08x\n", socket, offset, val);
+	debug("%04x %08x\n", socket, offset, val);
 	pci_write_config_dword(socket->dev, offset, val);
 }
 
 static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg)
 {
 	u8 val = readb(socket->base + 0x800 + reg);
-	debug("%p %04x %02x\n", socket, reg, val);
+	debug("%04x %02x\n", socket, reg, val);
 	return val;
 }
 
@@ -134,20 +130,20 @@
 	u16 val;
 	val = readb(socket->base + 0x800 + reg);
 	val |= readb(socket->base + 0x800 + reg + 1) << 8;
-	debug("%p %04x %04x\n", socket, reg, val);
+	debug("%04x %04x\n", socket, reg, val);
 	return val;
 }
 
 static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val)
 {
-	debug("%p %04x %02x\n", socket, reg, val);
+	debug("%04x %02x\n", socket, reg, val);
 	writeb(val, socket->base + 0x800 + reg);
 	readb(socket->base + 0x800 + reg); /* PCI write posting... */
 }
 
 static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
 {
-	debug("%p %04x %04x\n", socket, reg, val);
+	debug("%04x %04x\n", socket, reg, val);
 	writeb(val, socket->base + 0x800 + reg);
 	writeb(val >> 8, socket->base + 0x800 + reg + 1);
 
@@ -207,7 +203,7 @@
 
 
 	if (state & CB_CBCARD) {
-		val |= SS_CARDBUS;	
+		val |= SS_CARDBUS;
 		val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
 		val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
 		val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
@@ -650,8 +646,10 @@
 		root = pci_find_parent_resource(socket->dev, res);
 		if (root && (request_resource(root, res) == 0))
 			return 0;
-		printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
-				pci_name(socket->dev), nr);
+		dev_printk(KERN_INFO, &socket->dev->dev,
+			   "Preassigned resource %d busy or not available, "
+			   "reconfiguring...\n",
+			   nr);
 	}
 
 	if (type & IORESOURCE_IO) {
@@ -674,8 +672,9 @@
 			return 1;
 	}
 
-	printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
-	       pci_name(socket->dev), type);
+	dev_printk(KERN_INFO, &socket->dev->dev,
+		   "no resource of type %x available, trying to continue...\n",
+		   type);
 	res->start = res->end = res->flags = 0;
 	return 0;
 }
@@ -923,7 +922,8 @@
 	socket->probe_status = 0;
 
 	if (request_irq(socket->cb_irq, yenta_probe_handler, IRQF_SHARED, "yenta", socket)) {
-		printk(KERN_WARNING "Yenta: request_irq() in yenta_probe_cb_irq() failed!\n");
+		dev_printk(KERN_WARNING, &socket->dev->dev,
+			   "request_irq() in yenta_probe_cb_irq() failed!\n");
 		return -1;
 	}
 
@@ -960,8 +960,9 @@
 	else
 		socket->socket.irq_mask = 0;
 
-	printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
-	       socket->socket.irq_mask, socket->cb_irq);
+	dev_printk(KERN_INFO, &socket->dev->dev,
+		   "ISA IRQ mask 0x%04x, PCI irq %d\n",
+		   socket->socket.irq_mask, socket->cb_irq);
 }
 
 /*
@@ -1051,8 +1052,9 @@
 
 	/* Show that the wanted subordinate number is not possible: */
 	if (cardbus_bridge->subordinate > upper_limit)
-		printk(KERN_WARNING "Yenta: Upper limit for fixing this "
-			"bridge's parent bridge: #%02x\n", upper_limit);
+		dev_printk(KERN_WARNING, &cardbus_bridge->dev,
+			   "Upper limit for fixing this "
+			   "bridge's parent bridge: #%02x\n", upper_limit);
 
 	/* If we have room to increase the bridge's subordinate number, */
 	if (bridge_to_fix->subordinate < upper_limit) {
@@ -1061,10 +1063,11 @@
 		unsigned char subordinate_to_assign =
 			min(cardbus_bridge->subordinate, upper_limit);
 
-		printk(KERN_INFO "Yenta: Raising subordinate bus# of parent "
-			"bus (#%02x) from #%02x to #%02x\n",
-			bridge_to_fix->number,
-			bridge_to_fix->subordinate, subordinate_to_assign);
+		dev_printk(KERN_INFO, &bridge_to_fix->dev,
+			   "Raising subordinate bus# of parent "
+			   "bus (#%02x) from #%02x to #%02x\n",
+			   bridge_to_fix->number,
+			   bridge_to_fix->subordinate, subordinate_to_assign);
 
 		/* Save the new subordinate in the bus struct of the bridge */
 		bridge_to_fix->subordinate = subordinate_to_assign;
@@ -1091,8 +1094,8 @@
 	 * Bail out if so.
 	 */
 	if (!dev->subordinate) {
-		printk(KERN_ERR "Yenta: no bus associated with %s! "
-			"(try 'pci=assign-busses')\n", pci_name(dev));
+		dev_printk(KERN_ERR, &dev->dev, "no bus associated! "
+			   "(try 'pci=assign-busses')\n");
 		return -ENODEV;
 	}
 
@@ -1127,7 +1130,7 @@
 		goto disable;
 
 	if (!pci_resource_start(dev, 0)) {
-		printk(KERN_ERR "No cardbus resource!\n");
+		dev_printk(KERN_ERR, &dev->dev, "No cardbus resource!\n");
 		ret = -ENODEV;
 		goto release;
 	}
@@ -1146,8 +1149,8 @@
 	 * report the subsystem vendor and device for help debugging
 	 * the irq stuff...
 	 */
-	printk(KERN_INFO "Yenta: CardBus bridge found at %s [%04x:%04x]\n",
-		pci_name(dev), dev->subsystem_vendor, dev->subsystem_device);
+	dev_printk(KERN_INFO, &dev->dev, "CardBus bridge found [%04x:%04x]\n",
+		   dev->subsystem_vendor, dev->subsystem_device);
 
 	yenta_config_init(socket);
 
@@ -1179,8 +1182,12 @@
 		socket->poll_timer.data = (unsigned long)socket;
 		socket->poll_timer.expires = jiffies + HZ;
 		add_timer(&socket->poll_timer);
-		printk(KERN_INFO "Yenta: no PCI IRQ, CardBus support disabled for this socket.\n"
-		       KERN_INFO "Yenta: check your BIOS CardBus, BIOS IRQ or ACPI settings.\n");
+		dev_printk(KERN_INFO, &dev->dev,
+			   "no PCI IRQ, CardBus support disabled for this "
+			   "socket.\n");
+		dev_printk(KERN_INFO, &dev->dev,
+			   "check your BIOS CardBus, BIOS IRQ or ACPI "
+			   "settings.\n");
 	} else {
 		socket->socket.features |= SS_CAP_CARDBUS;
 	}
@@ -1188,7 +1195,8 @@
 	/* Figure out what the dang thing can do for the PCMCIA layer... */
 	yenta_interrogate(socket);
 	yenta_get_socket_capabilities(socket, isa_interrupts);
-	printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
+	dev_printk(KERN_INFO, &dev->dev,
+		   "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
 
 	yenta_fixup_parent_bridge(dev->subordinate);
 
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 2dd0dc9..165ff88 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -140,44 +140,41 @@
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
+static int aha152x_config_check(struct pcmcia_device *p_dev,
+				cistpl_cftable_entry_t *cfg,
+				cistpl_cftable_entry_t *dflt,
+				unsigned int vcc,
+				void *priv_data)
+{
+	/* For New Media T&J, look for a SCSI window */
+	if (cfg->io.win[0].len >= 0x20)
+		p_dev->io.BasePort1 = cfg->io.win[0].base;
+	else if ((cfg->io.nwin > 1) &&
+		 (cfg->io.win[1].len >= 0x20))
+		p_dev->io.BasePort1 = cfg->io.win[1].base;
+	if ((cfg->io.nwin > 0) &&
+	    (p_dev->io.BasePort1 < 0xffff)) {
+		if (!pcmcia_request_io(p_dev, &p_dev->io))
+			return 0;
+	}
+	return -EINVAL;
+}
+
 static int aha152x_config_cs(struct pcmcia_device *link)
 {
     scsi_info_t *info = link->priv;
     struct aha152x_setup s;
-    tuple_t tuple;
-    cisparse_t parse;
-    int i, last_ret, last_fn;
-    u_char tuple_data[64];
+    int last_ret, last_fn;
     struct Scsi_Host *host;
-    
+
     DEBUG(0, "aha152x_config(0x%p)\n", link);
 
-    tuple.TupleData = tuple_data;
-    tuple.TupleDataMax = 64;
-    tuple.TupleOffset = 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 ||
-		pcmcia_parse_tuple(link, &tuple, &parse) != 0)
-	    goto next_entry;
-	/* For New Media T&J, look for a SCSI window */
-	if (parse.cftable_entry.io.win[0].len >= 0x20)
-	    link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
-	else if ((parse.cftable_entry.io.nwin > 1) &&
-		 (parse.cftable_entry.io.win[1].len >= 0x20))
-	    link->io.BasePort1 = parse.cftable_entry.io.win[1].base;
-	if ((parse.cftable_entry.io.nwin > 0) &&
-	    (link->io.BasePort1 < 0xffff)) {
-	    link->conf.ConfigIndex = parse.cftable_entry.index;
-	    i = pcmcia_request_io(link, &link->io);
-	    if (i == CS_SUCCESS) break;
-	}
-    next_entry:
-	CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
+    last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
+    if (last_ret) {
+	cs_error(link, RequestIO, last_ret);
+	goto failed;
     }
-    
+
     CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
     CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
     
@@ -208,6 +205,7 @@
 
 cs_failed:
     cs_error(link, last_fn, last_ret);
+failed:
     aha152x_release_cs(link);
     return -ENODEV;
 }
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index d8b9935..06254f4 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -123,34 +123,30 @@
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
+static int fdomain_config_check(struct pcmcia_device *p_dev,
+				cistpl_cftable_entry_t *cfg,
+				cistpl_cftable_entry_t *dflt,
+				unsigned int vcc,
+				void *priv_data)
+{
+	p_dev->io.BasePort1 = cfg->io.win[0].base;
+	return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
+
 static int fdomain_config(struct pcmcia_device *link)
 {
     scsi_info_t *info = link->priv;
-    tuple_t tuple;
-    cisparse_t parse;
-    int i, last_ret, last_fn;
-    u_char tuple_data[64];
+    int last_ret, last_fn;
     char str[22];
     struct Scsi_Host *host;
 
     DEBUG(0, "fdomain_config(0x%p)\n", link);
 
-    tuple.TupleData = tuple_data;
-    tuple.TupleDataMax = 64;
-    tuple.TupleOffset = 0;
-
-    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-    while (1) {
-	if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
-		pcmcia_parse_tuple(link, &tuple, &parse) != 0)
-	    goto next_entry;
-	link->conf.ConfigIndex = parse.cftable_entry.index;
-	link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
-	i = pcmcia_request_io(link, &link->io);
-	if (i == CS_SUCCESS) break;
-    next_entry:
-	CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
+    last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
+    if (last_ret) {
+	    cs_error(link, RequestIO, last_ret);
+	    goto failed;
     }
 
     CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@@ -181,6 +177,7 @@
 
 cs_failed:
     cs_error(link, last_fn, last_ret);
+failed:
     fdomain_release(link);
     return -ENODEV;
 } /* fdomain_config */
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 24e6cb8..11a61ea 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1606,133 +1606,129 @@
     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)
-/*====================================================================*/
+
+struct nsp_cs_configdata {
+	nsp_hw_data		*data;
+	win_req_t		req;
+};
+
+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->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->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)) {
+			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.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;
+		}
+
+		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(p_dev->win, &map) != 0)
+				goto next_entry;
+
+			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! */
+		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;
-	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 nsp_cs_configdata *cfg_mem;
 	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;
+	cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL);
+	if (!cfg_mem)
+		return -ENOMEM;
+	cfg_mem->data = data;
 
-	/* 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);
-
-		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->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;
-			}
-		}
-
-		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.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 ((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)
-				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;
-
-			data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
-			data->MmioLength  = 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));
-	}
+	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) {
@@ -1790,20 +1786,20 @@
 		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
 
 
 /*======================================================================
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 67c5a58..20c3e5e 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -195,39 +195,33 @@
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
+static int qlogic_config_check(struct pcmcia_device *p_dev,
+			       cistpl_cftable_entry_t *cfg,
+			       cistpl_cftable_entry_t *dflt,
+			       unsigned int vcc,
+			       void *priv_data)
+{
+	p_dev->io.BasePort1 = cfg->io.win[0].base;
+	p_dev->io.NumPorts1 = cfg->io.win[0].len;
+
+	if (p_dev->io.BasePort1 == 0)
+		return -ENODEV;
+
+	return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
 static int qlogic_config(struct pcmcia_device * link)
 {
 	scsi_info_t *info = link->priv;
-	tuple_t tuple;
-	cisparse_t parse;
-	int i, last_ret, last_fn;
-	unsigned short tuple_data[32];
+	int last_ret, last_fn;
 	struct Scsi_Host *host;
 
 	DEBUG(0, "qlogic_config(0x%p)\n", link);
 
-	info->manf_id = link->manf_id;
-
-	tuple.TupleData = (cisdata_t *) tuple_data;
-	tuple.TupleDataMax = 64;
-	tuple.TupleOffset = 0;
-
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-	while (1) {
-		if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
-				pcmcia_parse_tuple(link, &tuple, &parse) != 0)
-			goto next_entry;
-		link->conf.ConfigIndex = parse.cftable_entry.index;
-		link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
-		link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
-		if (link->io.BasePort1 != 0) {
-			i = pcmcia_request_io(link, &link->io);
-			if (i == CS_SUCCESS)
-				break;
-		}
-	      next_entry:
-		CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
+	last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
+	if (last_ret) {
+		cs_error(link, RequestIO, last_ret);
+		goto failed;
 	}
 
 	CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@@ -262,6 +256,7 @@
 cs_failed:
 	cs_error(link, last_fn, last_ret);
 	pcmcia_disable_device(link);
+failed:
 	return -ENODEV;
 
 }				/* qlogic_config */
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 0be232b..b330c11 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -700,15 +700,27 @@
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
+static int SYM53C500_config_check(struct pcmcia_device *p_dev,
+				  cistpl_cftable_entry_t *cfg,
+				  cistpl_cftable_entry_t *dflt,
+				  unsigned int vcc,
+				  void *priv_data)
+{
+	p_dev->io.BasePort1 = cfg->io.win[0].base;
+	p_dev->io.NumPorts1 = cfg->io.win[0].len;
+
+	if (p_dev->io.BasePort1 == 0)
+		return -ENODEV;
+
+	return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
 static int
 SYM53C500_config(struct pcmcia_device *link)
 {
 	struct scsi_info_t *info = link->priv;
-	tuple_t tuple;
-	cisparse_t parse;
-	int i, last_ret, last_fn;
+	int last_ret, last_fn;
 	int irq_level, port_base;
-	unsigned short tuple_data[32];
 	struct Scsi_Host *host;
 	struct scsi_host_template *tpnt = &sym53c500_driver_template;
 	struct sym53c500_data *data;
@@ -717,27 +729,10 @@
 
 	info->manf_id = link->manf_id;
 
-	tuple.TupleData = (cisdata_t *)tuple_data;
-	tuple.TupleDataMax = 64;
-	tuple.TupleOffset = 0;
-
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-	while (1) {
-		if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
-		    pcmcia_parse_tuple(link, &tuple, &parse) != 0)
-			goto next_entry;
-		link->conf.ConfigIndex = parse.cftable_entry.index;
-		link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
-		link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
-
-		if (link->io.BasePort1 != 0) {
-			i = pcmcia_request_io(link, &link->io);
-			if (i == CS_SUCCESS)
-				break;
-		}
-next_entry:
-		CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
+	last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
+	if (last_ret) {
+		cs_error(link, RequestIO, last_ret);
+		goto failed;
 	}
 
 	CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@@ -831,6 +826,7 @@
 
 cs_failed:
 	cs_error(link, last_fn, last_ret);
+failed:
 	SYM53C500_release(link);
 	return -ENODEV;
 } /* SYM53C500_config */
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 164d2a4..7546aa8 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -431,131 +431,103 @@
 {
 	int i;
 	i = pcmcia_get_first_tuple(handle, tuple);
-	if (i != CS_SUCCESS)
-		return CS_NO_MORE_ITEMS;
-	i = pcmcia_get_tuple_data(handle, tuple);
-	if (i != CS_SUCCESS)
+	if (i != 0)
 		return i;
-	return pcmcia_parse_tuple(handle, tuple, parse);
-}
-
-static int
-next_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
-{
-	int i;
-	i = pcmcia_get_next_tuple(handle, tuple);
-	if (i != CS_SUCCESS)
-		return CS_NO_MORE_ITEMS;
 	i = pcmcia_get_tuple_data(handle, tuple);
-	if (i != CS_SUCCESS)
+	if (i != 0)
 		return i;
-	return pcmcia_parse_tuple(handle, tuple, parse);
+	return pcmcia_parse_tuple(tuple, parse);
 }
 
 /*====================================================================*/
 
-static int simple_config(struct pcmcia_device *link)
+static int simple_config_check(struct pcmcia_device *p_dev,
+			       cistpl_cftable_entry_t *cf,
+			       cistpl_cftable_entry_t *dflt,
+			       unsigned int vcc,
+			       void *priv_data)
+{
+	static const int size_table[2] = { 8, 16 };
+	int *try = 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 == size_table[(*try >> 1)])
+	    && (cf->io.win[0].base != 0)) {
+		p_dev->io.BasePort1 = cf->io.win[0].base;
+		p_dev->io.IOAddrLines = ((*try & 0x1) == 0) ?
+			16 : cf->io.flags & CISTPL_IO_LINES_MASK;
+		if (!pcmcia_request_io(p_dev, &p_dev->io))
+			return 0;
+	}
+	return -EINVAL;
+}
+
+static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
+					cistpl_cftable_entry_t *cf,
+					cistpl_cftable_entry_t *dflt,
+					unsigned int vcc,
+					void *priv_data)
 {
 	static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
-	static const int size_table[2] = { 8, 16 };
+	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 simple_config(struct pcmcia_device *link)
+{
 	struct serial_info *info = link->priv;
-	struct serial_cfg_mem *cfg_mem;
-	tuple_t *tuple;
-	u_char *buf;
-	cisparse_t *parse;
-	cistpl_cftable_entry_t *cf;
-	config_info_t config;
-	int i, j, try;
-	int s;
-
-	cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
-	if (!cfg_mem)
-		return -1;
-
-	tuple = &cfg_mem->tuple;
-	parse = &cfg_mem->parse;
-	cf = &parse->cftable_entry;
-	buf = cfg_mem->buf;
+	int i = -ENODEV, try;
 
 	/* If the card is already configured, look up the port and irq */
-	i = pcmcia_get_configuration_info(link, &config);
-	if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
+	if (link->function_config) {
 		unsigned int port = 0;
-		if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
-			port = config.BasePort2;
+		if ((link->io.BasePort2 != 0) &&
+		    (link->io.NumPorts2 == 8)) {
+			port = link->io.BasePort2;
 			info->slave = 1;
 		} else if ((info->manfid == MANFID_OSITECH) &&
-			   (config.NumPorts1 == 0x40)) {
-			port = config.BasePort1 + 0x28;
+			   (link->io.NumPorts1 == 0x40)) {
+			port = link->io.BasePort1 + 0x28;
 			info->slave = 1;
 		}
 		if (info->slave) {
-			kfree(cfg_mem);
-			return setup_serial(link, info, port, config.AssignedIRQ);
+			return setup_serial(link, info, port,
+					    link->irq.AssignedIRQ);
 		}
 	}
 
-	/* 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 (s = 0; s < 2; s++) {
-		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 == size_table[s]) &&
-					    (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);
-			}
-		}
-	}
+	/* First pass: look for a config entry that looks normal.
+	 * Two tries: without IO aliases, then with aliases */
+	for (try = 0; try < 4; try++)
+		if (!pcmcia_loop_config(link, simple_config_check, &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, simple_config_check_notpicky, NULL))
+		goto found_port;
 
-      found_port:
-	if (i != CS_SUCCESS) {
-		printk(KERN_NOTICE
-		       "serial_cs: no usable port range found, giving up\n");
-		cs_error(link, RequestIO, i);
-		kfree(cfg_mem);
-		return -1;
-	}
+	printk(KERN_NOTICE
+	       "serial_cs: no usable port range found, giving up\n");
+	cs_error(link, RequestIO, i);
+	return -1;
 
+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;
 	}
@@ -569,88 +541,76 @@
 		info->quirk->config(link);
 
 	i = pcmcia_request_configuration(link, &link->conf);
-	if (i != CS_SUCCESS) {
+	if (i != 0) {
 		cs_error(link, RequestConfiguration, i);
-		kfree(cfg_mem);
 		return -1;
 	}
-	kfree(cfg_mem);
 	return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
 }
 
-static int multi_config(struct pcmcia_device * link)
+static int multi_config_check(struct pcmcia_device *p_dev,
+			      cistpl_cftable_entry_t *cf,
+			      cistpl_cftable_entry_t *dflt,
+			      unsigned int vcc,
+			      void *priv_data)
+{
+	int *base2 = priv_data;
+
+	/* The quad port cards have bad CIS's, so just look for a
+	   window larger than 8 ports and assume it will be right */
+	if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
+		p_dev->io.BasePort1 = cf->io.win[0].base;
+		p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
+		if (!pcmcia_request_io(p_dev, &p_dev->io)) {
+			*base2 = p_dev->io.BasePort1 + 8;
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
+static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
+				       cistpl_cftable_entry_t *cf,
+				       cistpl_cftable_entry_t *dflt,
+				       unsigned int vcc,
+				       void *priv_data)
+{
+	int *base2 = priv_data;
+
+	if (cf->io.nwin == 2) {
+		p_dev->io.BasePort1 = cf->io.win[0].base;
+		p_dev->io.BasePort2 = cf->io.win[1].base;
+		p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
+		if (!pcmcia_request_io(p_dev, &p_dev->io)) {
+			*base2 = p_dev->io.BasePort2;
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
+static int multi_config(struct pcmcia_device *link)
 {
 	struct serial_info *info = link->priv;
-	struct serial_cfg_mem *cfg_mem;
-	tuple_t *tuple;
-	u_char *buf;
-	cisparse_t *parse;
-	cistpl_cftable_entry_t *cf;
-	int i, rc, base2 = 0;
-
-	cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
-	if (!cfg_mem)
-		return -1;
-	tuple = &cfg_mem->tuple;
-	parse = &cfg_mem->parse;
-	cf = &parse->cftable_entry;
-	buf = cfg_mem->buf;
-
-	tuple->TupleData = (cisdata_t *) buf;
-	tuple->TupleOffset = 0;
-	tuple->TupleDataMax = 255;
-	tuple->Attributes = 0;
-	tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	int i, base2 = 0;
 
 	/* First, look for a generic full-sized window */
 	link->io.NumPorts1 = info->multi * 8;
-	i = first_tuple(link, tuple, parse);
-	while (i != CS_NO_MORE_ITEMS) {
-		/* The quad port cards have bad CIS's, so just look for a
-		   window larger than 8 ports and assume it will be right */
-		if ((i == CS_SUCCESS) && (cf->io.nwin == 1) &&
-		    (cf->io.win[0].len > 8)) {
-			link->conf.ConfigIndex = cf->index;
-			link->io.BasePort1 = cf->io.win[0].base;
-			link->io.IOAddrLines =
-			    cf->io.flags & CISTPL_IO_LINES_MASK;
-			i = pcmcia_request_io(link, &link->io);
-			base2 = link->io.BasePort1 + 8;
-			if (i == CS_SUCCESS)
-				break;
-		}
-		i = next_tuple(link, tuple, parse);
-	}
-
-	/* If that didn't work, look for two windows */
-	if (i != CS_SUCCESS) {
+	if (pcmcia_loop_config(link, multi_config_check, &base2)) {
+		/* If that didn't work, look for two windows */
 		link->io.NumPorts1 = link->io.NumPorts2 = 8;
 		info->multi = 2;
-		i = first_tuple(link, tuple, parse);
-		while (i != CS_NO_MORE_ITEMS) {
-			if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {
-				link->conf.ConfigIndex = cf->index;
-				link->io.BasePort1 = cf->io.win[0].base;
-				link->io.BasePort2 = cf->io.win[1].base;
-				link->io.IOAddrLines =
-				    cf->io.flags & CISTPL_IO_LINES_MASK;
-				i = pcmcia_request_io(link, &link->io);
-				base2 = link->io.BasePort2;
-				if (i == CS_SUCCESS)
-					break;
-			}
-			i = next_tuple(link, tuple, parse);
+		if (pcmcia_loop_config(link, multi_config_check_notpicky,
+				       &base2)) {
+			printk(KERN_NOTICE "serial_cs: no usable port range"
+			       "found, giving up\n");
+			return -ENODEV;
 		}
 	}
 
-	if (i != CS_SUCCESS) {
-		cs_error(link, RequestIO, i);
-		rc = -1;
-		goto free_cfg_mem;
-	}
-
 	i = pcmcia_request_irq(link, &link->irq);
-	if (i != CS_SUCCESS) {
+	if (i != 0) {
+		/* FIXME: comment does not fit, error handling does not fit */
 		printk(KERN_NOTICE
 		       "serial_cs: no usable port range found, giving up\n");
 		cs_error(link, RequestIRQ, i);
@@ -664,10 +624,9 @@
 		info->quirk->config(link);
 
 	i = pcmcia_request_configuration(link, &link->conf);
-	if (i != CS_SUCCESS) {
+	if (i != 0) {
 		cs_error(link, RequestConfiguration, i);
-		rc = -1;
-		goto free_cfg_mem;
+		return -ENODEV;
 	}
 
 	/* The Oxford Semiconductor OXCF950 cards are in fact single-port:
@@ -678,7 +637,8 @@
 				info->prodid == PRODID_POSSIO_GCC)) {
 		int err;
 
-		if (cf->index == 1 || cf->index == 3) {
+		if (link->conf.ConfigIndex == 1 ||
+		    link->conf.ConfigIndex == 3) {
 			err = setup_serial(link, info, base2,
 					link->irq.AssignedIRQ);
 			base2 = link->io.BasePort1;
@@ -695,18 +655,14 @@
 		if (info->quirk && info->quirk->wakeup)
 			info->quirk->wakeup(link);
 
-		rc = 0;
-		goto free_cfg_mem;
+		return 0;
 	}
 
 	setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
 	for (i = 0; i < info->multi - 1; i++)
 		setup_serial(link, info, base2 + (8 * i),
 				link->irq.AssignedIRQ);
-	rc = 0;
-free_cfg_mem:
-	kfree(cfg_mem);
-	return rc;
+	return 0;
 }
 
 /*======================================================================
@@ -746,7 +702,7 @@
 	/* Is this a compliant multifunction card? */
 	tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
 	tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
-	info->multi = (first_tuple(link, tuple, parse) == CS_SUCCESS);
+	info->multi = (first_tuple(link, tuple, parse) == 0);
 
 	/* Is this a multiport card? */
 	tuple->DesiredTuple = CISTPL_MANFID;
@@ -770,7 +726,7 @@
 	    ((link->func_id == CISTPL_FUNCID_MULTI) ||
 	     (link->func_id == CISTPL_FUNCID_SERIAL))) {
 		tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
-		if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
+		if (first_tuple(link, tuple, parse) == 0) {
 			if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
 				info->multi = cf->io.win[0].len >> 3;
 			if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index 24c2a46..fbfadba 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -80,7 +80,7 @@
 	reg.Action = CS_WRITE;
 	reg.Value = value;
 	res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
-	if (unlikely(res != CS_SUCCESS))
+	if (unlikely(res != 0))
 		return -EBUSY;
 
 	return 0;
@@ -96,7 +96,7 @@
 	reg.Offset = offset;
 	reg.Action = CS_READ;
 	res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
-	if (unlikely(res != CS_SUCCESS))
+	if (unlikely(res != 0))
 		return -EBUSY;
 	*value = reg.Value;
 
@@ -638,17 +638,17 @@
 	tuple.TupleData = buf;
 	tuple.TupleDataMax = sizeof(buf);
 	res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
-	GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl");
+	GOTO_ERROR_ON(res != 0, "MAC first tpl");
 	res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
-	GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl data");
+	GOTO_ERROR_ON(res != 0, "MAC first tpl data");
 	while (1) {
 		GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
 		if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
 			break;
 		res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
-		GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl");
+		GOTO_ERROR_ON(res != 0, "MAC next tpl");
 		res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
-		GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl data");
+		GOTO_ERROR_ON(res != 0, "MAC next tpl data");
 	}
 	GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
 	memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
@@ -659,9 +659,9 @@
 	tuple.TupleData = buf;
 	tuple.TupleDataMax = sizeof(buf);
 	res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
-	GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl");
+	GOTO_ERROR_ON(res != 0, "VEN first tpl");
 	res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
-	GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl data");
+	GOTO_ERROR_ON(res != 0, "VEN first tpl data");
 	while (1) {
 		GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
 		switch (tuple.TupleData[0]) {
@@ -733,11 +733,11 @@
 			break;
 		}
 		res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
-		if (res == CS_NO_MORE_ITEMS)
+		if (res == -ENOSPC)
 			break;
-		GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl");
+		GOTO_ERROR_ON(res != 0, "VEN next tpl");
 		res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
-		GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl data");
+		GOTO_ERROR_ON(res != 0, "VEN next tpl data");
 	}
 
 	return 0;
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index ff9a29b..347c3ed 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -124,65 +124,53 @@
 	return;
 }
 
+static int ixj_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->io.nwin > 0) || (dflt->io.nwin > 0)) {
+		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+		p_dev->io.BasePort1 = io->win[0].base;
+		p_dev->io.NumPorts1 = io->win[0].len;
+		if (io->nwin == 2) {
+			p_dev->io.BasePort2 = io->win[1].base;
+			p_dev->io.NumPorts2 = io->win[1].len;
+		}
+		if (!pcmcia_request_io(p_dev, &p_dev->io))
+			return 0;
+	}
+	return -ENODEV;
+}
+
 static int ixj_config(struct pcmcia_device * link)
 {
 	IXJ *j;
 	ixj_info_t *info;
-	tuple_t tuple;
-	u_short buf[128];
-	cisparse_t parse;
-	cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
-	cistpl_cftable_entry_t dflt =
-	{
-		0
-	};
-	int last_ret, last_fn;
+	cistpl_cftable_entry_t dflt = { 0 };
+
 	info = link->priv;
 	DEBUG(0, "ixj_config(0x%p)\n", link);
-	tuple.TupleData = (cisdata_t *) buf;
-	tuple.TupleOffset = 0;
-	tuple.TupleDataMax = 255;
-	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 ||
-				pcmcia_parse_tuple(link, &tuple, &parse) != 0)
-			goto next_entry;
-		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-			link->conf.ConfigIndex = cfg->index;
-			link->io.BasePort1 = io->win[0].base;
-			link->io.NumPorts1 = io->win[0].len;
-			if (io->nwin == 2) {
-				link->io.BasePort2 = io->win[1].base;
-				link->io.NumPorts2 = io->win[1].len;
-			}
-			if (pcmcia_request_io(link, &link->io) != 0)
-				goto next_entry;
-			/* If we've got this far, we're done */
-			break;
-		}
-	      next_entry:
-		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-			dflt = *cfg;
-		CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
-	}
 
-	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+	if (pcmcia_loop_config(link, ixj_config_check, &dflt))
+		goto cs_failed;
+
+	if (pcmcia_request_configuration(link, &link->conf))
+		goto cs_failed;
 
 	/*
  	 *	Register the card with the core.
- 	 */	
-	j=ixj_pcmcia_probe(link->io.BasePort1,link->io.BasePort1 + 0x10);
+	 */
+	j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10);
 
 	info->ndev = 1;
 	info->node.major = PHONE_MAJOR;
 	link->dev_node = &info->node;
 	ixj_get_serial(link, j);
 	return 0;
+
       cs_failed:
-	cs_error(link, last_fn, last_ret);
 	ixj_cs_release(link);
 	return -ENODEV;
 }
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 5da63f5..516848d 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -112,7 +112,8 @@
 	.num_resources		= ARRAY_SIZE(resources),
 };
 
-static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq)
+static int sl811_hc_init(struct device *parent, resource_size_t base_addr,
+			 int irq)
 {
 	if (platform_dev.dev.parent)
 		return -EBUSY;
@@ -155,97 +156,72 @@
 	platform_device_unregister(&platform_dev);
 }
 
+static int sl811_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)
+		return -ENODEV;
+
+	/* 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 (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc)
+			return -ENODEV;
+	} else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
+		if (dflt->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc)
+			return -ENODEV;
+		}
+
+	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;
+
+	/* we need 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_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;
+
+		return pcmcia_request_io(p_dev, &p_dev->io);
+	}
+	pcmcia_disable_device(p_dev);
+	return -ENODEV;
+}
+
+
 static int sl811_cs_config(struct pcmcia_device *link)
 {
 	struct device		*parent = &handle_to_dev(link);
 	local_info_t		*dev = link->priv;
-	tuple_t			tuple;
-	cisparse_t		parse;
 	int			last_fn, last_ret;
-	u_char			buf[64];
-	config_info_t		conf;
-	cistpl_cftable_entry_t	dflt = { 0 };
 
 	DBG(0, "sl811_cs_config(0x%p)\n", link);
 
-	/* Look up the current Vcc */
-	CS_CHECK(GetConfigurationInfo,
-			pcmcia_get_configuration_info(link, &conf));
-
-	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);
-
-		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 (cfg->vcc.param[CISTPL_POWER_VNOM]/10000
-					!= conf.Vcc)
-				goto next_entry;
-		} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
-			if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000
-					!= conf.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;
-
-		/* we need 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_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 (pcmcia_request_io(link, &link->io) != 0)
-				goto next_entry;
-		}
-		break;
-
-next_entry:
-		pcmcia_disable_device(link);
-		last_ret = pcmcia_get_next_tuple(link, &tuple);
-	}
+	if (pcmcia_loop_config(link, sl811_cs_config_check, NULL))
+		goto failed;
 
 	/* require an IRQ and two registers */
 	if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
-		goto cs_failed;
+		goto failed;
 	if (link->conf.Attributes & CONF_ENABLE_IRQ)
 		CS_CHECK(RequestIRQ,
 			pcmcia_request_irq(link, &link->irq));
 	else
-		goto cs_failed;
+		goto failed;
 
 	CS_CHECK(RequestConfiguration,
 		pcmcia_request_configuration(link, &link->conf));
@@ -266,8 +242,9 @@
 	if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
 			< 0) {
 cs_failed:
-		printk("sl811_cs_config failed\n");
 		cs_error(link, last_fn, last_ret);
+failed:
+		printk(KERN_WARNING "sl811_cs_config failed\n");
 		sl811_cs_release(link);
 		return  -ENODEV;
 	}
diff --git a/include/pcmcia/ciscode.h b/include/pcmcia/ciscode.h
index ad6e278..b417985 100644
--- a/include/pcmcia/ciscode.h
+++ b/include/pcmcia/ciscode.h
@@ -119,7 +119,7 @@
 
 #define MANFID_TOSHIBA			0x0098
 
-#define MANFID_UNGERMANN 0x02c0
+#define MANFID_UNGERMANN		0x02c0
 
 #define MANFID_XIRCOM			0x0105
 
diff --git a/include/pcmcia/cistpl.h b/include/pcmcia/cistpl.h
index e2e10c1..cfdd5af 100644
--- a/include/pcmcia/cistpl.h
+++ b/include/pcmcia/cistpl.h
@@ -573,44 +573,6 @@
 #define TUPLE_RETURN_LINK	0x01
 #define TUPLE_RETURN_COMMON	0x02
 
-/* For ValidateCIS */
-typedef struct cisinfo_t {
-    u_int	Chains;
-} cisinfo_t;
-
 #define CISTPL_MAX_CIS_SIZE	0x200
 
-/* For ReplaceCIS */
-typedef struct cisdump_t {
-    u_int	Length;
-    cisdata_t	Data[CISTPL_MAX_CIS_SIZE];
-} cisdump_t;
-
-
-int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis);
-
-/* don't use outside of PCMCIA core yet */
-int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple);
-int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple);
-int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
-int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse);
-
-int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *count);
-
-/* ... but use these wrappers instead */
-#define pcmcia_get_first_tuple(p_dev, tuple) \
-		pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple)
-
-#define pcmcia_get_next_tuple(p_dev, tuple) \
-		pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple)
-
-#define pcmcia_get_tuple_data(p_dev, tuple) \
-		pccard_get_tuple_data(p_dev->socket, tuple)
-
-#define pcmcia_parse_tuple(p_dev, tuple, parse) \
-		pccard_parse_tuple(tuple, parse)
-
-#define pcmcia_validate_cis(p_dev, info) \
-		pccard_validate_cis(p_dev->socket, p_dev->func, info)
-
 #endif /* LINUX_CISTPL_H */
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h
index 45d84b2..904468a 100644
--- a/include/pcmcia/cs.h
+++ b/include/pcmcia/cs.h
@@ -28,72 +28,16 @@
 #define CS_WRITE	2
 
 /* for AdjustResourceInfo */
-typedef struct adjust_t {
-    u_int	Action;
-    u_int	Resource;
-    u_int	Attributes;
-    union {
-	struct memory {
-	    u_long	Base;
-	    u_long	Size;
-	} memory;
-	struct io {
-	    ioaddr_t	BasePort;
-	    ioaddr_t	NumPorts;
-	    u_int	IOAddrLines;
-	} io;
-	struct irq {
-	    u_int	IRQ;
-	} irq;
-    } resource;
-} adjust_t;
-
 /* Action field */
 #define REMOVE_MANAGED_RESOURCE		1
 #define ADD_MANAGED_RESOURCE		2
-#define GET_FIRST_MANAGED_RESOURCE	3
-#define GET_NEXT_MANAGED_RESOURCE	4
-/* Resource field */
-#define RES_MEMORY_RANGE		1
-#define RES_IO_RANGE			2
-#define RES_IRQ				3
-/* Attribute field */
-#define RES_IRQ_TYPE			0x03
-#define RES_IRQ_TYPE_EXCLUSIVE		0
-#define RES_IRQ_TYPE_TIME		1
-#define RES_IRQ_TYPE_DYNAMIC		2
-#define RES_IRQ_CSC			0x04
-#define RES_SHARED			0x08
-#define RES_RESERVED			0x10
-#define RES_ALLOCATED			0x20
-#define RES_REMOVED			0x40
+
 
 typedef struct event_callback_args_t {
 	struct pcmcia_device	*client_handle;
 	void			*client_data;
 } event_callback_args_t;
 
-/* for GetConfigurationInfo */
-typedef struct config_info_t {
-    u_char	Function;
-    u_int	Attributes;
-    u_int	Vcc, Vpp1, Vpp2;
-    u_int	IntType;
-    u_int	ConfigBase;
-    u_char	Status, Pin, Copy, Option, ExtStatus;
-    u_int	Present;
-    u_int	CardValues;
-    u_int	AssignedIRQ;
-    u_int	IRQAttributes;
-    ioaddr_t	BasePort1;
-    ioaddr_t	NumPorts1;
-    u_int	Attributes1;
-    ioaddr_t	BasePort2;
-    ioaddr_t	NumPorts2;
-    u_int	Attributes2;
-    u_int	IOAddrLines;
-} config_info_t;
-
 /* For CardValues field */
 #define CV_OPTION_VALUE		0x01
 #define CV_STATUS_VALUE		0x02
@@ -257,22 +201,6 @@
 #define WIN_BAR_MASK		0xe000
 #define WIN_BAR_SHIFT		13
 
-/* Attributes for RegisterClient -- UNUSED -- */
-#define INFO_MASTER_CLIENT	0x01
-#define INFO_IO_CLIENT		0x02
-#define INFO_MTD_CLIENT		0x04
-#define INFO_MEM_CLIENT		0x08
-#define MAX_NUM_CLIENTS		3
-
-#define INFO_CARD_SHARE		0x10
-#define INFO_CARD_EXCL		0x20
-
-typedef struct cs_status_t {
-    u_char	Function;
-    event_t 	CardState;
-    event_t	SocketState;
-} cs_status_t;
-
 typedef struct error_info_t {
     int		func;
     int		retcode;
@@ -308,95 +236,4 @@
 #define CS_EVENT_3VCARD			0x200000
 #define CS_EVENT_XVCARD			0x400000
 
-/* Return codes */
-#define CS_SUCCESS		0x00
-#define CS_BAD_ADAPTER		0x01
-#define CS_BAD_ATTRIBUTE	0x02
-#define CS_BAD_BASE		0x03
-#define CS_BAD_EDC		0x04
-#define CS_BAD_IRQ		0x06
-#define CS_BAD_OFFSET		0x07
-#define CS_BAD_PAGE		0x08
-#define CS_READ_FAILURE		0x09
-#define CS_BAD_SIZE		0x0a
-#define CS_BAD_SOCKET		0x0b
-#define CS_BAD_TYPE		0x0d
-#define CS_BAD_VCC		0x0e
-#define CS_BAD_VPP		0x0f
-#define CS_BAD_WINDOW		0x11
-#define CS_WRITE_FAILURE	0x12
-#define CS_NO_CARD		0x14
-#define CS_UNSUPPORTED_FUNCTION	0x15
-#define CS_UNSUPPORTED_MODE	0x16
-#define CS_BAD_SPEED		0x17
-#define CS_BUSY			0x18
-#define CS_GENERAL_FAILURE	0x19
-#define CS_WRITE_PROTECTED	0x1a
-#define CS_BAD_ARG_LENGTH	0x1b
-#define CS_BAD_ARGS		0x1c
-#define CS_CONFIGURATION_LOCKED	0x1d
-#define CS_IN_USE		0x1e
-#define CS_NO_MORE_ITEMS	0x1f
-#define CS_OUT_OF_RESOURCE	0x20
-#define CS_BAD_HANDLE		0x21
-
-#define CS_BAD_TUPLE		0x40
-
-#ifdef __KERNEL__
-
-/*
- *  The main Card Services entry point
- */
-
-enum service {
-    AccessConfigurationRegister, AddSocketServices,
-    AdjustResourceInfo, CheckEraseQueue, CloseMemory, CopyMemory,
-    DeregisterClient, DeregisterEraseQueue, GetCardServicesInfo,
-    GetClientInfo, GetConfigurationInfo, GetEventMask,
-    GetFirstClient, GetFirstPartion, GetFirstRegion, GetFirstTuple,
-    GetNextClient, GetNextPartition, GetNextRegion, GetNextTuple,
-    GetStatus, GetTupleData, MapLogSocket, MapLogWindow, MapMemPage,
-    MapPhySocket, MapPhyWindow, ModifyConfiguration, ModifyWindow,
-    OpenMemory, ParseTuple, ReadMemory, RegisterClient,
-    RegisterEraseQueue, RegisterMTD, RegisterTimer,
-    ReleaseConfiguration, ReleaseExclusive, ReleaseIO, ReleaseIRQ,
-    ReleaseSocketMask, ReleaseWindow, ReplaceSocketServices,
-    RequestConfiguration, RequestExclusive, RequestIO, RequestIRQ,
-    RequestSocketMask, RequestWindow, ResetCard, ReturnSSEntry,
-    SetEventMask, SetRegion, ValidateCIS, VendorSpecific,
-    WriteMemory, BindDevice, BindMTD, ReportError,
-    SuspendCard, ResumeCard, EjectCard, InsertCard, ReplaceCIS,
-    GetFirstWindow, GetNextWindow, GetMemPage
-};
-
-struct pcmcia_socket;
-
-int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg);
-int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config);
-int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);
-int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
-int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
-int pcmcia_release_window(window_handle_t win);
-int pcmcia_request_configuration(struct pcmcia_device *p_dev, config_req_t *req);
-int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req);
-int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req);
-int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh);
-int pcmcia_suspend_card(struct pcmcia_socket *skt);
-int pcmcia_resume_card(struct pcmcia_socket *skt);
-int pcmcia_eject_card(struct pcmcia_socket *skt);
-int pcmcia_insert_card(struct pcmcia_socket *skt);
-int pccard_reset_card(struct pcmcia_socket *skt);
-
-struct pcmcia_device * pcmcia_dev_present(struct pcmcia_device *p_dev);
-void pcmcia_disable_device(struct pcmcia_device *p_dev);
-
-struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt);
-void pcmcia_put_socket(struct pcmcia_socket *skt);
-
-/* compatibility functions */
-#define pcmcia_reset_card(p_dev, req) \
-		pccard_reset_card(p_dev->socket)
-
-#endif /* __KERNEL__ */
-
 #endif /* _LINUX_CS_H */
diff --git a/include/pcmcia/cs_types.h b/include/pcmcia/cs_types.h
index f402a0f..315965a 100644
--- a/include/pcmcia/cs_types.h
+++ b/include/pcmcia/cs_types.h
@@ -21,14 +21,6 @@
 #include <sys/types.h>
 #endif
 
-#if defined(__arm__) || defined(__mips__) || defined(__avr32__) || \
-	defined(__bfin__)
-/* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */
-typedef u_int   ioaddr_t;
-#else
-typedef u_short	ioaddr_t;
-#endif
-
 typedef u_short	socket_t;
 typedef u_int	event_t;
 typedef u_char	cisdata_t;
diff --git a/include/pcmcia/device_id.h b/include/pcmcia/device_id.h
index e04e0b0..c33ea08 100644
--- a/include/pcmcia/device_id.h
+++ b/include/pcmcia/device_id.h
@@ -1,10 +1,19 @@
 /*
- * Copyright (2003-2004) 	Dominik Brodowski <linux@brodo.de>
- *				David Woodhouse
+ * device_id.h -- PCMCIA driver matching helpers
  *
- * License: GPL v2
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (C) 2003 - 2004	David Woodhouse
+ * (C) 2003 - 2004	Dominik Brodowski
  */
 
+#ifndef _LINUX_PCMCIA_DEVICE_ID_H
+#define _LINUX_PCMCIA_DEVICE_ID_H
+
+#ifdef __KERNEL__
+
 #define PCMCIA_DEVICE_MANF_CARD(manf, card) { \
 	.match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \
 			PCMCIA_DEV_ID_MATCH_CARD_ID, \
@@ -256,3 +265,6 @@
 
 
 #define PCMCIA_DEVICE_NULL { .match_flags = 0, }
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_PCMCIA_DEVICE_ID_H */
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index b316027..a2be80b 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -10,7 +10,7 @@
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * (C) 1999		David A. Hinds
- * (C) 2003 - 2004	Dominik Brodowski
+ * (C) 2003 - 2008	Dominik Brodowski
  */
 
 #ifndef _LINUX_DS_H
@@ -23,108 +23,21 @@
 #include <pcmcia/cs_types.h>
 #include <pcmcia/device_id.h>
 
-typedef struct tuple_parse_t {
-    tuple_t		tuple;
-    cisdata_t		data[255];
-    cisparse_t		parse;
-} tuple_parse_t;
-
-typedef struct win_info_t {
-    window_handle_t	handle;
-    win_req_t		window;
-    memreq_t		map;
-} win_info_t;
-    
-typedef struct bind_info_t {
-    dev_info_t		dev_info;
-    u_char		function;
-    struct pcmcia_device *instance;
-    char		name[DEV_NAME_LEN];
-    u_short		major, minor;
-    void		*next;
-} bind_info_t;
-
-typedef struct mtd_info_t {
-    dev_info_t		dev_info;
-    u_int		Attributes;
-    u_int		CardOffset;
-} mtd_info_t;
-
-typedef struct region_info_t {
-    u_int		Attributes;
-    u_int		CardOffset;
-    u_int		RegionSize;
-    u_int		AccessSpeed;
-    u_int		BlockSize;
-    u_int		PartMultiple;
-    u_char		JedecMfr, JedecInfo;
-    memory_handle_t	next;
-} region_info_t;
-#define REGION_TYPE		0x0001
-#define REGION_TYPE_CM		0x0000
-#define REGION_TYPE_AM		0x0001
-#define REGION_PREFETCH		0x0008
-#define REGION_CACHEABLE	0x0010
-#define REGION_BAR_MASK		0xe000
-#define REGION_BAR_SHIFT	13
-
-typedef union ds_ioctl_arg_t {
-    adjust_t		adjust;
-    config_info_t	config;
-    tuple_t		tuple;
-    tuple_parse_t	tuple_parse;
-    client_req_t	client_req;
-    cs_status_t		status;
-    conf_reg_t		conf_reg;
-    cisinfo_t		cisinfo;
-    region_info_t	region;
-    bind_info_t		bind_info;
-    mtd_info_t		mtd_info;
-    win_info_t		win_info;
-    cisdump_t		cisdump;
-} ds_ioctl_arg_t;
-
-#define DS_ADJUST_RESOURCE_INFO		_IOWR('d', 2, adjust_t)
-#define DS_GET_CONFIGURATION_INFO	_IOWR('d', 3, config_info_t)
-#define DS_GET_FIRST_TUPLE		_IOWR('d', 4, tuple_t)
-#define DS_GET_NEXT_TUPLE		_IOWR('d', 5, tuple_t)
-#define DS_GET_TUPLE_DATA		_IOWR('d', 6, tuple_parse_t)
-#define DS_PARSE_TUPLE			_IOWR('d', 7, tuple_parse_t)
-#define DS_RESET_CARD			_IO  ('d', 8)
-#define DS_GET_STATUS			_IOWR('d', 9, cs_status_t)
-#define DS_ACCESS_CONFIGURATION_REGISTER _IOWR('d', 10, conf_reg_t)
-#define DS_VALIDATE_CIS			_IOR ('d', 11, cisinfo_t)
-#define DS_SUSPEND_CARD			_IO  ('d', 12)
-#define DS_RESUME_CARD			_IO  ('d', 13)
-#define DS_EJECT_CARD			_IO  ('d', 14)
-#define DS_INSERT_CARD			_IO  ('d', 15)
-#define DS_GET_FIRST_REGION		_IOWR('d', 16, region_info_t)
-#define DS_GET_NEXT_REGION		_IOWR('d', 17, region_info_t)
-#define DS_REPLACE_CIS			_IOWR('d', 18, cisdump_t)
-#define DS_GET_FIRST_WINDOW		_IOR ('d', 19, win_info_t)
-#define DS_GET_NEXT_WINDOW		_IOWR('d', 20, win_info_t)
-#define DS_GET_MEM_PAGE			_IOWR('d', 21, win_info_t)
-
-#define DS_BIND_REQUEST			_IOWR('d', 60, bind_info_t)
-#define DS_GET_DEVICE_INFO		_IOWR('d', 61, bind_info_t) 
-#define DS_GET_NEXT_DEVICE		_IOWR('d', 62, bind_info_t) 
-#define DS_UNBIND_REQUEST		_IOW ('d', 63, bind_info_t)
-#define DS_BIND_MTD			_IOWR('d', 64, mtd_info_t)
-
 #ifdef __KERNEL__
 #include <linux/device.h>
 #include <pcmcia/ss.h>
 
-typedef struct dev_node_t {
-    char		dev_name[DEV_NAME_LEN];
-    u_short		major, minor;
-    struct dev_node_t	*next;
-} dev_node_t;
-
-
+/*
+ * PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus
+ * a.k.a. PCI drivers
+ */
 struct pcmcia_socket;
+struct pcmcia_device;
 struct config_t;
 
+/* dynamic device IDs for PCMCIA device drivers. See
+ * Documentation/pcmcia/driver.txt for details.
+*/
 struct pcmcia_dynids {
 	spinlock_t		lock;
 	struct list_head	list;
@@ -147,6 +60,14 @@
 int pcmcia_register_driver(struct pcmcia_driver *driver);
 void pcmcia_unregister_driver(struct pcmcia_driver *driver);
 
+/* Some drivers use dev_node_t to store char or block device information.
+ * Don't use this in new drivers, though.
+ */
+typedef struct dev_node_t {
+	char			dev_name[DEV_NAME_LEN];
+	u_short			major, minor;
+	struct dev_node_t	*next;
+} dev_node_t;
 
 struct pcmcia_device {
 	/* the socket and the device_no [for multifunction devices]
@@ -216,10 +137,304 @@
 #define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev)
 #define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv)
 
+/* deprecated -- don't use! */
 #define handle_to_dev(handle) (handle->dev)
 
-/* error reporting */
-void cs_error(struct pcmcia_device *handle, int func, int ret);
+
+/* (deprecated) error reporting by PCMCIA devices. Use dev_printk()
+ * or dev_dbg() directly in the driver, without referring to pcmcia_error_func()
+ * and/or pcmcia_error_ret() for those functions will go away soon.
+ */
+enum service {
+    AccessConfigurationRegister, AddSocketServices,
+    AdjustResourceInfo, CheckEraseQueue, CloseMemory, CopyMemory,
+    DeregisterClient, DeregisterEraseQueue, GetCardServicesInfo,
+    GetClientInfo, GetConfigurationInfo, GetEventMask,
+    GetFirstClient, GetFirstPartion, GetFirstRegion, GetFirstTuple,
+    GetNextClient, GetNextPartition, GetNextRegion, GetNextTuple,
+    GetStatus, GetTupleData, MapLogSocket, MapLogWindow, MapMemPage,
+    MapPhySocket, MapPhyWindow, ModifyConfiguration, ModifyWindow,
+    OpenMemory, ParseTuple, ReadMemory, RegisterClient,
+    RegisterEraseQueue, RegisterMTD, RegisterTimer,
+    ReleaseConfiguration, ReleaseExclusive, ReleaseIO, ReleaseIRQ,
+    ReleaseSocketMask, ReleaseWindow, ReplaceSocketServices,
+    RequestConfiguration, RequestExclusive, RequestIO, RequestIRQ,
+    RequestSocketMask, RequestWindow, ResetCard, ReturnSSEntry,
+    SetEventMask, SetRegion, ValidateCIS, VendorSpecific,
+    WriteMemory, BindDevice, BindMTD, ReportError,
+    SuspendCard, ResumeCard, EjectCard, InsertCard, ReplaceCIS,
+    GetFirstWindow, GetNextWindow, GetMemPage
+};
+const char *pcmcia_error_func(int func);
+const char *pcmcia_error_ret(int ret);
+
+#define cs_error(p_dev, func, ret)			\
+	{						\
+		dev_printk(KERN_NOTICE, &p_dev->dev,	\
+			   "%s : %s\n",			\
+			   pcmcia_error_func(func),	\
+			   pcmcia_error_ret(ret));	\
+	}
+
+/* CIS access.
+ * Use the pcmcia_* versions in PCMCIA drivers
+ */
+int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse);
+
+int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
+			   tuple_t *tuple);
+#define pcmcia_get_first_tuple(p_dev, tuple) \
+		pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple)
+
+int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
+			  tuple_t *tuple);
+#define pcmcia_get_next_tuple(p_dev, tuple) \
+		pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple)
+
+int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
+#define pcmcia_get_tuple_data(p_dev, tuple) \
+		pccard_get_tuple_data(p_dev->socket, tuple)
+
+
+/* loop CIS entries for valid configuration */
+int pcmcia_loop_config(struct pcmcia_device *p_dev,
+		       int	(*conf_check)	(struct pcmcia_device *p_dev,
+						 cistpl_cftable_entry_t *cf,
+						 cistpl_cftable_entry_t *dflt,
+						 unsigned int vcc,
+						 void *priv_data),
+		       void *priv_data);
+
+/* is the device still there? */
+struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *p_dev);
+
+/* low-level interface reset */
+int pcmcia_reset_card(struct pcmcia_socket *skt);
+
+/* CIS config */
+int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
+					 conf_reg_t *reg);
+
+/* device configuration */
+int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req);
+int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req);
+int pcmcia_request_configuration(struct pcmcia_device *p_dev,
+				 config_req_t *req);
+
+int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req,
+			  window_handle_t *wh);
+int pcmcia_release_window(window_handle_t win);
+
+int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);
+int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
+
+int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
+void pcmcia_disable_device(struct pcmcia_device *p_dev);
 
 #endif /* __KERNEL__ */
+
+
+
+/* Below, there are only definitions which are used by
+ * - the PCMCIA ioctl
+ * - deprecated PCMCIA userspace tools only
+ *
+ * here be dragons ... here be dragons ... here be dragons ... here be drag
+ */
+
+#if defined(CONFIG_PCMCIA_IOCTL) || !defined(__KERNEL__)
+
+#if defined(__arm__) || defined(__mips__) || defined(__avr32__) || \
+	defined(__bfin__)
+/* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */
+typedef u_int   ioaddr_t;
+#else
+typedef u_short	ioaddr_t;
+#endif
+
+/* for AdjustResourceInfo */
+typedef struct adjust_t {
+	u_int			Action;
+	u_int			Resource;
+	u_int			Attributes;
+	union {
+		struct memory {
+			u_long		Base;
+			u_long		Size;
+		} memory;
+		struct io {
+			ioaddr_t	BasePort;
+			ioaddr_t	NumPorts;
+			u_int		IOAddrLines;
+		} io;
+		struct irq {
+			u_int		IRQ;
+		} irq;
+	} resource;
+} adjust_t;
+
+/* Action field */
+#define REMOVE_MANAGED_RESOURCE		1
+#define ADD_MANAGED_RESOURCE		2
+#define GET_FIRST_MANAGED_RESOURCE	3
+#define GET_NEXT_MANAGED_RESOURCE	4
+/* Resource field */
+#define RES_MEMORY_RANGE		1
+#define RES_IO_RANGE			2
+#define RES_IRQ				3
+/* Attribute field */
+#define RES_IRQ_TYPE			0x03
+#define RES_IRQ_TYPE_EXCLUSIVE		0
+#define RES_IRQ_TYPE_TIME		1
+#define RES_IRQ_TYPE_DYNAMIC		2
+#define RES_IRQ_CSC			0x04
+#define RES_SHARED			0x08
+#define RES_RESERVED			0x10
+#define RES_ALLOCATED			0x20
+#define RES_REMOVED			0x40
+
+
+typedef struct tuple_parse_t {
+	tuple_t			tuple;
+	cisdata_t		data[255];
+	cisparse_t		parse;
+} tuple_parse_t;
+
+typedef struct win_info_t {
+	window_handle_t		handle;
+	win_req_t		window;
+	memreq_t		map;
+} win_info_t;
+
+typedef struct bind_info_t {
+	dev_info_t		dev_info;
+	u_char			function;
+	struct pcmcia_device	*instance;
+	char			name[DEV_NAME_LEN];
+	u_short			major, minor;
+	void			*next;
+} bind_info_t;
+
+typedef struct mtd_info_t {
+	dev_info_t     		dev_info;
+	u_int			Attributes;
+	u_int			CardOffset;
+} mtd_info_t;
+
+typedef struct region_info_t {
+	u_int			Attributes;
+	u_int			CardOffset;
+	u_int			RegionSize;
+	u_int			AccessSpeed;
+	u_int			BlockSize;
+	u_int			PartMultiple;
+	u_char			JedecMfr, JedecInfo;
+	memory_handle_t		next;
+} region_info_t;
+
+#define REGION_TYPE		0x0001
+#define REGION_TYPE_CM		0x0000
+#define REGION_TYPE_AM		0x0001
+#define REGION_PREFETCH		0x0008
+#define REGION_CACHEABLE	0x0010
+#define REGION_BAR_MASK		0xe000
+#define REGION_BAR_SHIFT	13
+
+/* For ReplaceCIS */
+typedef struct cisdump_t {
+	u_int			Length;
+	cisdata_t		Data[CISTPL_MAX_CIS_SIZE];
+} cisdump_t;
+
+/* for GetConfigurationInfo */
+typedef struct config_info_t {
+	u_char			Function;
+	u_int			Attributes;
+	u_int			Vcc, Vpp1, Vpp2;
+	u_int			IntType;
+	u_int			ConfigBase;
+	u_char			Status, Pin, Copy, Option, ExtStatus;
+	u_int			Present;
+	u_int			CardValues;
+	u_int			AssignedIRQ;
+	u_int			IRQAttributes;
+	ioaddr_t		BasePort1;
+	ioaddr_t		NumPorts1;
+	u_int			Attributes1;
+	ioaddr_t		BasePort2;
+	ioaddr_t		NumPorts2;
+	u_int			Attributes2;
+	u_int			IOAddrLines;
+} config_info_t;
+
+/* For ValidateCIS */
+typedef struct cisinfo_t {
+	u_int			Chains;
+} cisinfo_t;
+
+typedef struct cs_status_t {
+	u_char			Function;
+	event_t 		CardState;
+	event_t			SocketState;
+} cs_status_t;
+
+typedef union ds_ioctl_arg_t {
+	adjust_t		adjust;
+	config_info_t		config;
+	tuple_t			tuple;
+	tuple_parse_t		tuple_parse;
+	client_req_t		client_req;
+	cs_status_t		status;
+	conf_reg_t		conf_reg;
+	cisinfo_t		cisinfo;
+	region_info_t		region;
+	bind_info_t		bind_info;
+	mtd_info_t		mtd_info;
+	win_info_t		win_info;
+	cisdump_t		cisdump;
+} ds_ioctl_arg_t;
+
+#define DS_ADJUST_RESOURCE_INFO			_IOWR('d',  2, adjust_t)
+#define DS_GET_CONFIGURATION_INFO		_IOWR('d',  3, config_info_t)
+#define DS_GET_FIRST_TUPLE			_IOWR('d',  4, tuple_t)
+#define DS_GET_NEXT_TUPLE			_IOWR('d',  5, tuple_t)
+#define DS_GET_TUPLE_DATA			_IOWR('d',  6, tuple_parse_t)
+#define DS_PARSE_TUPLE				_IOWR('d',  7, tuple_parse_t)
+#define DS_RESET_CARD				_IO  ('d',  8)
+#define DS_GET_STATUS				_IOWR('d',  9, cs_status_t)
+#define DS_ACCESS_CONFIGURATION_REGISTER	_IOWR('d', 10, conf_reg_t)
+#define DS_VALIDATE_CIS				_IOR ('d', 11, cisinfo_t)
+#define DS_SUSPEND_CARD				_IO  ('d', 12)
+#define DS_RESUME_CARD				_IO  ('d', 13)
+#define DS_EJECT_CARD				_IO  ('d', 14)
+#define DS_INSERT_CARD				_IO  ('d', 15)
+#define DS_GET_FIRST_REGION			_IOWR('d', 16, region_info_t)
+#define DS_GET_NEXT_REGION			_IOWR('d', 17, region_info_t)
+#define DS_REPLACE_CIS				_IOWR('d', 18, cisdump_t)
+#define DS_GET_FIRST_WINDOW			_IOR ('d', 19, win_info_t)
+#define DS_GET_NEXT_WINDOW			_IOWR('d', 20, win_info_t)
+#define DS_GET_MEM_PAGE				_IOWR('d', 21, win_info_t)
+
+#define DS_BIND_REQUEST				_IOWR('d', 60, bind_info_t)
+#define DS_GET_DEVICE_INFO			_IOWR('d', 61, bind_info_t)
+#define DS_GET_NEXT_DEVICE			_IOWR('d', 62, bind_info_t)
+#define DS_UNBIND_REQUEST			_IOW ('d', 63, bind_info_t)
+#define DS_BIND_MTD				_IOWR('d', 64, mtd_info_t)
+
+
+/* used in userspace only */
+#define CS_IN_USE			0x1e
+
+#define INFO_MASTER_CLIENT	0x01
+#define INFO_IO_CLIENT		0x02
+#define INFO_MTD_CLIENT		0x04
+#define INFO_MEM_CLIENT		0x08
+#define MAX_NUM_CLIENTS		3
+
+#define INFO_CARD_SHARE		0x10
+#define INFO_CARD_EXCL		0x20
+
+
+#endif /* !defined(__KERNEL__) || defined(CONFIG_PCMCIA_IOCTL) */
+
 #endif /* _LINUX_DS_H */
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index ed919dd..9b4ac93 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -53,10 +53,10 @@
 
 /* for GetSocket, SetSocket */
 typedef struct socket_state_t {
-    u_int	flags;
-    u_int	csc_mask;
-    u_char	Vcc, Vpp;
-    u_char	io_irq;
+	u_int	flags;
+	u_int	csc_mask;
+	u_char	Vcc, Vpp;
+	u_char	io_irq;
 } socket_state_t;
 
 extern socket_state_t dead_socket;
@@ -86,79 +86,22 @@
 #define HOOK_POWER_PRE	0x01
 #define HOOK_POWER_POST	0x02
 
-
 typedef struct pccard_io_map {
-    u_char	map;
-    u_char	flags;
-    u_short	speed;
-    u_int	start, stop;
+	u_char	map;
+	u_char	flags;
+	u_short	speed;
+	u_int	start, stop;
 } pccard_io_map;
 
 typedef struct pccard_mem_map {
-    u_char	map;
-    u_char	flags;
-    u_short	speed;
-    u_long	static_start;
-    u_int	card_start;
-    struct resource *res;
+	u_char		map;
+	u_char		flags;
+	u_short		speed;
+	u_long		static_start;
+	u_int		card_start;
+	struct resource	*res;
 } pccard_mem_map;
 
-typedef struct cb_bridge_map {
-    u_char	map;
-    u_char	flags;
-    u_int	start, stop;
-} cb_bridge_map;
-
-/*
- * Socket operations.
- */
-struct pcmcia_socket;
-
-struct pccard_operations {
-	int (*init)(struct pcmcia_socket *sock);
-	int (*suspend)(struct pcmcia_socket *sock);
-	int (*get_status)(struct pcmcia_socket *sock, u_int *value);
-	int (*set_socket)(struct pcmcia_socket *sock, socket_state_t *state);
-	int (*set_io_map)(struct pcmcia_socket *sock, struct pccard_io_map *io);
-	int (*set_mem_map)(struct pcmcia_socket *sock, struct pccard_mem_map *mem);
-};
-
-struct pccard_resource_ops {
-	int	(*validate_mem)		(struct pcmcia_socket *s);
-	int	(*adjust_io_region)	(struct resource *res,
-					 unsigned long r_start,
-					 unsigned long r_end,
-					 struct pcmcia_socket *s);
-	struct resource* (*find_io)	(unsigned long base, int num,
-					 unsigned long align,
-					 struct pcmcia_socket *s);
-	struct resource* (*find_mem)	(unsigned long base, unsigned long num,
-					 unsigned long align, int low,
-					 struct pcmcia_socket *s);
-	int	(*add_io)		(struct pcmcia_socket *s,
-					 unsigned int action,
-					 unsigned long r_start,
-					 unsigned long r_end);
-	int	(*add_mem)		(struct pcmcia_socket *s,
-					 unsigned int action,
-					 unsigned long r_start,
-					 unsigned long r_end);
-	int	(*init)			(struct pcmcia_socket *s);
-	void	(*exit)			(struct pcmcia_socket *s);
-};
-/* SS_CAP_STATIC_MAP */
-extern struct pccard_resource_ops pccard_static_ops;
-/* !SS_CAP_STATIC_MAP */
-extern struct pccard_resource_ops pccard_nonstatic_ops;
-
-/* static mem, dynamic IO sockets */
-extern struct pccard_resource_ops pccard_iodyn_ops;
-
-/*
- *  Calls to set up low-level "Socket Services" drivers
- */
-struct pcmcia_socket;
-
 typedef struct io_window_t {
 	u_int			InUse, Config;
 	struct resource		*res;
@@ -179,10 +122,25 @@
 /* Maximum number of memory windows per socket */
 #define MAX_WIN 4
 
+
+/*
+ * Socket operations.
+ */
+struct pcmcia_socket;
+struct pccard_resource_ops;
 struct config_t;
 struct pcmcia_callback;
 struct user_info_t;
 
+struct pccard_operations {
+	int (*init)(struct pcmcia_socket *s);
+	int (*suspend)(struct pcmcia_socket *s);
+	int (*get_status)(struct pcmcia_socket *s, u_int *value);
+	int (*set_socket)(struct pcmcia_socket *s, socket_state_t *state);
+	int (*set_io_map)(struct pcmcia_socket *s, struct pccard_io_map *io);
+	int (*set_mem_map)(struct pcmcia_socket *s, struct pccard_mem_map *mem);
+};
+
 struct pcmcia_socket {
 	struct module			*owner;
 	spinlock_t			lock;
@@ -199,8 +157,8 @@
 	io_window_t			io[MAX_IO_WIN];
 	window_t			win[MAX_WIN];
 	struct list_head		cis_cache;
-	u_int				fake_cis_len;
-	char				*fake_cis;
+	size_t				fake_cis_len;
+	u8				*fake_cis;
 
 	struct list_head		socket_list;
 	struct completion		socket_released;
@@ -218,12 +176,12 @@
 	struct pci_dev *		cb_dev;
 
 
-	/* socket setup is done so resources should be able to be allocated. Only
-	 * if set to 1, calls to find_{io,mem}_region are handled, and insertion
-	 * events are actually managed by the PCMCIA layer.*/
+	/* socket setup is done so resources should be able to be allocated.
+	 * Only if set to 1, calls to find_{io,mem}_region are handled, and
+	 * insertio events are actually managed by the PCMCIA layer.*/
 	u8				resource_setup_done:1;
 
-	/* is set to one if resource setup is done using adjust_resource_info() */
+	/* It's old if resource setup is done using adjust_resource_info() */
 	u8				resource_setup_old:1;
 	u8				resource_setup_new:1;
 
@@ -236,75 +194,101 @@
 
 	/* Zoom video behaviour is so chip specific its not worth adding
 	   this to _ops */
-	void 				(*zoom_video)(struct pcmcia_socket *, int);
+	void 				(*zoom_video)(struct pcmcia_socket *,
+						      int);
 
 	/* so is power hook */
 	int (*power_hook)(struct pcmcia_socket *sock, int operation);
-#ifdef CONFIG_CARDBUS
+
 	/* allows tuning the CB bridge before loading driver for the CB card */
+#ifdef CONFIG_CARDBUS
 	void (*tune_bridge)(struct pcmcia_socket *sock, struct pci_bus *bus);
 #endif
 
 	/* state thread */
-	struct mutex			skt_mutex;	/* protects socket h/w state */
-
 	struct task_struct		*thread;
 	struct completion		thread_done;
-	spinlock_t			thread_lock;	/* protects thread_events */
 	unsigned int			thread_events;
+	/* protects socket h/w state */
+	struct mutex			skt_mutex;
+	/* protects thread_events */
+	spinlock_t			thread_lock;
 
 	/* pcmcia (16-bit) */
 	struct pcmcia_callback		*callback;
 
 #if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
-	struct list_head		devices_list;	/*  PCMCIA devices */
-	u8				device_count;	/* the number of devices, used
-							 * only internally and subject
-							 * to incorrectness and change */
+	/* The following elements refer to 16-bit PCMCIA devices inserted
+	 * into the socket */
+	struct list_head		devices_list;
 
+	/* the number of devices, used only internally and subject to
+	 * incorrectness and change */
+	u8				device_count;
+
+	/* 16-bit state: */
 	struct {
-		u8			present:1,	/* PCMCIA card is present in socket */
-					busy:1,		/* "master" ioctl is used */
-					dead:1,		/* pcmcia module is being unloaded */
-					device_add_pending:1, /* a multifunction-device
-							       * add event is pending */
-					mfc_pfc:1,	/* the pending event adds a mfc (1) or pfc (0) */
-					reserved:3;
-	} 				pcmcia_state;
+		/* PCMCIA card is present in socket */
+		u8			present:1;
+		/* "master" ioctl is used */
+		u8			busy:1;
+		/* pcmcia module is being unloaded */
+		u8			dead:1;
+		/* a multifunction-device add event is pending */
+		u8			device_add_pending:1;
+		/* the pending event adds a mfc (1) or pfc (0) */
+		u8			mfc_pfc:1;
 
-	struct work_struct		device_add;	/* for adding further pseudo-multifunction
-							 * devices */
+		u8			reserved:3;
+	} pcmcia_state;
+
+
+	/* for adding further pseudo-multifunction devices */
+	struct work_struct		device_add;
 
 #ifdef CONFIG_PCMCIA_IOCTL
 	struct user_info_t		*user;
 	wait_queue_head_t		queue;
-#endif
-#endif
+#endif /* CONFIG_PCMCIA_IOCTL */
+#endif /* CONFIG_PCMCIA */
 
 	/* cardbus (32-bit) */
 #ifdef CONFIG_CARDBUS
 	struct resource *		cb_cis_res;
 	void __iomem			*cb_cis_virt;
-#endif
+#endif /* CONFIG_CARDBUS */
 
 	/* socket device */
 	struct device			dev;
-	void				*driver_data;	/* data internal to the socket driver */
-
+	/* data internal to the socket driver */
+	void				*driver_data;
 };
 
-struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr);
 
-
-
-extern void pcmcia_parse_events(struct pcmcia_socket *socket, unsigned int events);
-extern int pcmcia_register_socket(struct pcmcia_socket *socket);
-extern void pcmcia_unregister_socket(struct pcmcia_socket *socket);
-
-extern struct class pcmcia_socket_class;
+/* socket drivers must define the resource operations type they use. There
+ * are three options:
+ * - pccard_static_ops		iomem and ioport areas are assigned statically
+ * - pccard_iodyn_ops		iomem areas is assigned statically, ioport
+ *				areas dynamically
+ * - pccard_nonstatic_ops	iomem and ioport areas are assigned dynamically.
+ *				If this option is selected, use
+ *				"select PCCARD_NONSTATIC" in Kconfig.
+ */
+extern struct pccard_resource_ops pccard_static_ops;
+extern struct pccard_resource_ops pccard_iodyn_ops;
+extern struct pccard_resource_ops pccard_nonstatic_ops;
 
 /* socket drivers are expected to use these callbacks in their .drv struct */
 extern int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state);
 extern int pcmcia_socket_dev_resume(struct device *dev);
 
+/* socket drivers use this callback in their IRQ handler */
+extern void pcmcia_parse_events(struct pcmcia_socket *socket,
+				unsigned int events);
+
+/* to register and unregister a socket */
+extern int pcmcia_register_socket(struct pcmcia_socket *socket);
+extern void pcmcia_unregister_socket(struct pcmcia_socket *socket);
+
+
 #endif /* _LINUX_SS_H */