linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC] [PATCH 1/7] pcmcia: add pcmcia_loop_config() helper
@ 2008-07-29  7:15 Dominik Brodowski
  2008-07-29  7:17 ` [RFC] [PATCH 2/7] pcmcia: use pcmcia_loop_config in pata and ide drivers Dominik Brodowski
  2008-07-29 21:16 ` [RFC] [PATCH 1/7] pcmcia: add pcmcia_loop_config() helper Randy Dunlap
  0 siblings, 2 replies; 4+ messages in thread
From: Dominik Brodowski @ 2008-07-29  7:15 UTC (permalink / raw)
  To: linux-pcmcia
  Cc: Tejun Heo, Alan Cox, linux-ide, Marcel Holtmann, linux-bluetooth,
	James E.J. Bottomley, linux-scsi, Karsten Keil, isdn4linux,
	Jeff Garzik, netdev, Harald Welte, linux-parport, Russell King,
	Ed Okerson, linux-serial

By calling pcmcia_loop_config(), a pcmcia 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.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
 Documentation/pcmcia/driver-changes.txt |    6 +++
 drivers/pcmcia/pcmcia_resource.c        |   57 +++++++++++++++++++++++++++++++
 include/pcmcia/cistpl.h                 |    6 +++
 3 files changed, 69 insertions(+), 0 deletions(-)

By calling pcmcia_loop_config(), a pcmcia 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.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
 Documentation/pcmcia/driver-changes.txt |    6 +++
 drivers/pcmcia/pcmcia_resource.c        |   63 +++++++++++++++++++++++++++++++
 include/pcmcia/cistpl.h                 |    6 +++
 3 files changed, 75 insertions(+), 0 deletions(-)

diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index 96f155e..44085c1 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/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 4884a18..0fa48aa 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -909,3 +909,66 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) {
 		pcmcia_release_window(p_dev->win);
 }
 EXPORT_SYMBOL(pcmcia_disable_device);
+
+
+/**
+ * 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.
+ */
+
+struct pcmcia_cfg_mem {
+	tuple_t tuple;
+	cisparse_t parse;
+	u8 buf[256];
+};
+
+int pcmcia_loop_config(struct pcmcia_device *p_dev,
+		       int	(*conf_check)	(struct pcmcia_device *p_dev,
+						 cistpl_cftable_entry_t *cfg,
+						 void *priv_data),
+		       void *priv_data)
+{
+	struct pcmcia_cfg_mem *cfg_mem;
+	tuple_t *tuple;
+	int ret = -ENODEV;
+
+	cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
+	if (cfg_mem == NULL)
+		return -ENOMEM;
+
+	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) {
+		if (pcmcia_get_tuple_data(p_dev, tuple))
+			goto next_entry;
+
+		if (pcmcia_parse_tuple(p_dev, tuple, &cfg_mem->parse))
+			goto next_entry;
+
+		ret = conf_check(p_dev, &cfg_mem->parse.cftable_entry,
+				 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/include/pcmcia/cistpl.h b/include/pcmcia/cistpl.h
index 552a332..9830b34 100644
--- a/include/pcmcia/cistpl.h
+++ b/include/pcmcia/cistpl.h
@@ -607,4 +607,10 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
 #define pcmcia_validate_cis(p_dev, info) \
 		pccard_validate_cis(p_dev->socket, p_dev->func, info)
 
+int pcmcia_loop_config(struct pcmcia_device *p_dev,
+		       int	(*conf_check)	(struct pcmcia_device *p_dev,
+						 cistpl_cftable_entry_t *cf,
+						 void *priv_data),
+		       void *priv_data);
+
 #endif /* LINUX_CISTPL_H */
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [RFC] [PATCH 2/7] pcmcia: use pcmcia_loop_config in pata and ide drivers
  2008-07-29  7:15 [RFC] [PATCH 1/7] pcmcia: add pcmcia_loop_config() helper Dominik Brodowski
@ 2008-07-29  7:17 ` Dominik Brodowski
  2008-07-29 20:19   ` Larry Finger
  2008-07-29 21:16 ` [RFC] [PATCH 1/7] pcmcia: add pcmcia_loop_config() helper Randy Dunlap
  1 sibling, 1 reply; 4+ messages in thread
From: Dominik Brodowski @ 2008-07-29  7:17 UTC (permalink / raw)
  To: linux-pcmcia; +Cc: Tejun Heo, Alan Cox, linux-ide

Use the config loop helper in pata_pcmcia and ide_cs

CC: Tejun Heo <htejun@gmail.com>
CC: Alan Cox <alan@lxorguk.ukuu.org.uk>
CC: linux-ide@vger.kernel.org
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
 drivers/ata/pata_pcmcia.c   |  171 ++++++++++++++++++++-----------------------
 drivers/ide/legacy/ide-cs.c |  156 +++++++++++++++++++--------------------
 2 files changed, 155 insertions(+), 172 deletions(-)

diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 41b4361..8cccd1b 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -148,6 +148,69 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
+
+struct pcmcia_config_check {
+	config_info_t conf;
+	cistpl_cftable_entry_t dflt;
+	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,
+				   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 (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 = (stk->is_kme) ? 2 : 1;
+			if (pcmcia_request_io(pdev, &pdev->io) != 0)
+				goto next_entry;
+			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)
+				goto next_entry;
+			stk->ctl_base = pdev->io.BasePort1 + 0x0e;
+		} else
+			goto next_entry;
+		/* If we've got this far, we're done */
+		return 0;
+	}
+next_entry:
+	if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+		memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
+
+	return -ENODEV;
+}
+
 /**
  *	pcmcia_init_one		-	attach a PCMCIA interface
  *	@pdev: pcmcia device
@@ -161,19 +224,11 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
 	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 +248,30 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
 	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; */
-
-	pass = io_base = ctl_base = 0;
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	tuple.Attributes = 0;
-	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
+	/* Allocate resoure probing structures */
 
-	/* 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;
-			}
-		}
+	stk = kzalloc(sizeof(*stk), GFP_KERNEL);
+	if (!stk)
+		goto out1;
+	stk->is_kme = is_kme;
 
-		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++;
-		}
+	/* Not sure if this is right... look up the current Vcc */
+	CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf));
+	stk->skip_vcc = io_base = ctl_base = 0;
+	if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) {
+		memset(&stk->dflt, 0, sizeof(stk->dflt));
+		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));
 
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 27b1e0b..50624b6 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -226,103 +226,97 @@ out_release:
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
+struct pcmcia_config_check {
+	config_info_t conf;
+	cistpl_cftable_entry_t dflt;
+	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,
+				   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 (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 = (stk->is_kme) ? 2 : 1;
+			if (pcmcia_request_io(pdev, &pdev->io) != 0)
+				goto next_entry;
+			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)
+				goto next_entry;
+			stk->ctl_base = pdev->io.BasePort1 + 0x0e;
+		} else
+			goto next_entry;
+		/* If we've got this far, we're done */
+		return 0;
+	}
+next_entry:
+	if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+		memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
+
+	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;
     ide_hwif_t *hwif;
 
     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)));
 
+    stk = kzalloc(sizeof(*stk), GFP_KERNEL);
+    if (!stk) goto err_mem;
+    stk->is_kme = is_kme;
+
     /* Not sure if this is right... look up the current Vcc */
     CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
-
-    pass = io_base = ctl_base = 0;
-    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-    tuple.Attributes = 0;
-    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-    while (1) {
-    	if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry;
-	if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry;
-
-	/* Check for matching Vcc, unless we're desperate */
-	if (!pass) {
-	    if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
-		if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
-		    goto next_entry;
-	    } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
-		if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
-		    goto next_entry;
-	    }
-	}
-
-	if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
-	    link->conf.Vpp =
-		cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-	else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
-	    link->conf.Vpp =
-		stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
-
-	if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
-	    cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
-	    link->conf.ConfigIndex = cfg->index;
-	    link->io.BasePort1 = io->win[0].base;
-	    link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-	    if (!(io->flags & CISTPL_IO_16BIT))
-		link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-	    if (io->nwin == 2) {
-		link->io.NumPorts1 = 8;
-		link->io.BasePort2 = io->win[1].base;
-		link->io.NumPorts2 = (is_kme) ? 2 : 1;
-		if (pcmcia_request_io(link, &link->io) != 0)
-			goto next_entry;
-		io_base = link->io.BasePort1;
-		ctl_base = link->io.BasePort2;
-	    } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
-		link->io.NumPorts1 = io->win[0].len;
-		link->io.NumPorts2 = 0;
-		if (pcmcia_request_io(link, &link->io) != 0)
-			goto next_entry;
-		io_base = link->io.BasePort1;
-		ctl_base = link->io.BasePort1 + 0x0e;
-	    } else goto next_entry;
-	    /* If we've got this far, we're done */
-	    break;
-	}
-
-    next_entry:
-	if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-	    memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
-	if (pass) {
-	    CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
-	} else if (pcmcia_get_next_tuple(link, &tuple) != 0) {
-	    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
+    stk->skip_vcc = io_base = ctl_base = 0;
+    if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) {
 	    memset(&stk->dflt, 0, sizeof(stk->dflt));
-	    pass++;
-	}
+	    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));
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC] [PATCH 2/7] pcmcia: use pcmcia_loop_config in pata and ide drivers
  2008-07-29  7:17 ` [RFC] [PATCH 2/7] pcmcia: use pcmcia_loop_config in pata and ide drivers Dominik Brodowski
@ 2008-07-29 20:19   ` Larry Finger
  0 siblings, 0 replies; 4+ messages in thread
From: Larry Finger @ 2008-07-29 20:19 UTC (permalink / raw)
  To: Dominik Brodowski; +Cc: linux-ide, Tejun Heo, linux-pcmcia, Alan Cox

Dominik Brodowski wrote:
> Use the config loop helper in pata_pcmcia and ide_cs
> 
> CC: Tejun Heo <htejun@gmail.com>
> CC: Alan Cox <alan@lxorguk.ukuu.org.uk>
> CC: linux-ide@vger.kernel.org
> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
> ---
>  drivers/ata/pata_pcmcia.c   |  171 ++++++++++++++++++++-----------------------
>  drivers/ide/legacy/ide-cs.c |  156 +++++++++++++++++++--------------------
>  2 files changed, 155 insertions(+), 172 deletions(-)

ACKed by Larry Finger <Larry.Finger@lwfinger.net> for ide-cs

There was one patch rejection when installing onto 2.6.27-rc1:

>  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;
>      ide_hwif_t *hwif;

The last line should be

 >      struct ide_host *host;



Larry

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC] [PATCH 1/7] pcmcia: add pcmcia_loop_config() helper
  2008-07-29  7:15 [RFC] [PATCH 1/7] pcmcia: add pcmcia_loop_config() helper Dominik Brodowski
  2008-07-29  7:17 ` [RFC] [PATCH 2/7] pcmcia: use pcmcia_loop_config in pata and ide drivers Dominik Brodowski
@ 2008-07-29 21:16 ` Randy Dunlap
  1 sibling, 0 replies; 4+ messages in thread
From: Randy Dunlap @ 2008-07-29 21:16 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: linux-pcmcia, Tejun Heo, Alan Cox, linux-ide, Marcel Holtmann,
	linux-bluetooth, James E.J. Bottomley, linux-scsi, Karsten Keil,
	isdn4linux, Jeff Garzik, netdev, Harald Welte, linux-parport,
	Russell King, Ed Okerson, linux-serial

On Tue, 29 Jul 2008 09:15:39 +0200 Dominik Brodowski wrote:

> By calling pcmcia_loop_config(), a pcmcia 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.
> 
> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
> ---
>  Documentation/pcmcia/driver-changes.txt |    6 +++
>  drivers/pcmcia/pcmcia_resource.c        |   57 +++++++++++++++++++++++++++++++
>  include/pcmcia/cistpl.h                 |    6 +++
>  3 files changed, 69 insertions(+), 0 deletions(-)
> 
> By calling pcmcia_loop_config(), a pcmcia 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.
> 
> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
> ---
>  Documentation/pcmcia/driver-changes.txt |    6 +++
>  drivers/pcmcia/pcmcia_resource.c        |   63 +++++++++++++++++++++++++++++++
>  include/pcmcia/cistpl.h                 |    6 +++
>  3 files changed, 75 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
> index 4884a18..0fa48aa 100644
> --- a/drivers/pcmcia/pcmcia_resource.c
> +++ b/drivers/pcmcia/pcmcia_resource.c
> @@ -909,3 +909,66 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) {
>  		pcmcia_release_window(p_dev->win);
>  }
>  EXPORT_SYMBOL(pcmcia_disable_device);
> +
> +

Hi,

One more comment here (sorry I missed it earlier):

The kernel-doc comment needs to immediately precede the function, so that
struct pcmcia_cfg_mem needs to be moved to before the kernel-doc block...


> +/**
> + * 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.
> + */
> +
> +struct pcmcia_cfg_mem {
> +	tuple_t tuple;
> +	cisparse_t parse;
> +	u8 buf[256];
> +};
> +
> +int pcmcia_loop_config(struct pcmcia_device *p_dev,
> +		       int	(*conf_check)	(struct pcmcia_device *p_dev,
> +						 cistpl_cftable_entry_t *cfg,
> +						 void *priv_data),
> +		       void *priv_data)
> +{
...
> +}
> +EXPORT_SYMBOL(pcmcia_loop_config);


---
~Randy
Linux Plumbers Conference, 17-19 September 2008, Portland, Oregon USA
http://linuxplumbersconf.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-07-29 21:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-29  7:15 [RFC] [PATCH 1/7] pcmcia: add pcmcia_loop_config() helper Dominik Brodowski
2008-07-29  7:17 ` [RFC] [PATCH 2/7] pcmcia: use pcmcia_loop_config in pata and ide drivers Dominik Brodowski
2008-07-29 20:19   ` Larry Finger
2008-07-29 21:16 ` [RFC] [PATCH 1/7] pcmcia: add pcmcia_loop_config() helper Randy Dunlap

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).