Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55a19b39 authored by Dominik Brodowski's avatar Dominik Brodowski
Browse files

pcmcia/staging: update comedi drivers



Update comedi PCMCIA drivers to work with recent PCMCIA changes documented
in Documentation/pcmcia/driver-changes.txt:

- use pcmcia_config_loop()
- don't use PCMCIA_DEBUG, but use dev_dbg()
- don't use cs_error()
- re-use prod_id and card_id values already stored

Acked-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent 66024db5
Loading
Loading
Loading
Loading
+55 −165
Original line number Diff line number Diff line
@@ -141,38 +141,15 @@ static int das16cs_timer_insn_config(struct comedi_device *dev,
				     struct comedi_insn *insn,
				     unsigned int *data);

static int get_prodid(struct comedi_device *dev, struct pcmcia_device *link)
{
	tuple_t tuple;
	u_short buf[128];
	int prodid = 0;

	tuple.TupleData = (cisdata_t *) buf;
	tuple.TupleOffset = 0;
	tuple.TupleDataMax = 255;
	tuple.DesiredTuple = CISTPL_MANFID;
	tuple.Attributes = TUPLE_RETURN_COMMON;
	if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
	    (pcmcia_get_tuple_data(link, &tuple) == 0)) {
		prodid = le16_to_cpu(buf[1]);
	}

	return prodid;
}

static const struct das16cs_board *das16cs_probe(struct comedi_device *dev,
						 struct pcmcia_device *link)
{
	int id;
	int i;

	id = get_prodid(dev, link);

	for (i = 0; i < n_boards; i++) {
		if (das16cs_boards[i].device_id == id) {
		if (das16cs_boards[i].device_id == link->card_id)
			return das16cs_boards + i;
	}
	}

	printk("unknown board!\n");

@@ -660,27 +637,8 @@ static int das16cs_timer_insn_config(struct comedi_device *dev,

======================================================================*/

/*
   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
   you do not define PCMCIA_DEBUG at all, all the debug code will be
   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
   be present but disabled -- but it can then be enabled for specific
   modules at load time with a 'pc_debug=#' option to insmod.
*/
#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)

#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0644);
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
static char *version =
    "cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
#else
#define DEBUG(n, args...)
#endif

/*====================================================================*/

static void das16cs_pcmcia_config(struct pcmcia_device *link);
static void das16cs_pcmcia_release(struct pcmcia_device *link);
static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev);
@@ -733,7 +691,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
{
	struct local_info_t *local;

	DEBUG(0, "das16cs_pcmcia_attach()\n");
	dev_dbg(&link->dev, "das16cs_pcmcia_attach()\n");

	/* Allocate space for private device-specific data */
	local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -760,7 +718,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)

static void das16cs_pcmcia_detach(struct pcmcia_device *link)
{
	DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link);
	dev_dbg(&link->dev, "das16cs_pcmcia_detach\n");

	if (link->dev_node) {
		((struct local_info_t *)link->priv)->stop = 1;
@@ -771,118 +729,55 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link)
		kfree(link->priv);
}				/* das16cs_pcmcia_detach */

static void das16cs_pcmcia_config(struct pcmcia_device *link)
{
	struct local_info_t *dev = link->priv;
	tuple_t tuple;
	cisparse_t parse;
	int last_fn, last_ret;
	u_char buf[64];
	cistpl_cftable_entry_t dflt = { 0 };

	DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link);

	/*
	   This reads the card's CONFIG tuple to find its configuration
	   registers.
	 */
	tuple.DesiredTuple = CISTPL_CONFIG;
	tuple.Attributes = 0;
	tuple.TupleData = buf;
	tuple.TupleDataMax = sizeof(buf);
	tuple.TupleOffset = 0;

	last_fn = GetFirstTuple;
	last_ret = pcmcia_get_first_tuple(link, &tuple);
	if (last_ret != 0)
		goto cs_failed;

	last_fn = GetTupleData;
	last_ret = pcmcia_get_tuple_data(link, &tuple);
	if (last_ret != 0)
		goto cs_failed;

	last_fn = ParseTuple;
	last_ret = pcmcia_parse_tuple(&tuple, &parse);
	if (last_ret != 0)
		goto cs_failed;

	link->conf.ConfigBase = parse.config.base;
	link->conf.Present = parse.config.rmask[0];

	/*
	   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;
	last_fn = GetFirstTuple;

	last_ret = pcmcia_get_first_tuple(link, &tuple);
	if (last_ret)
		goto cs_failed;

	while (1) {
		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
		if (pcmcia_get_tuple_data(link, &tuple))
			goto next_entry;
		if (pcmcia_parse_tuple(&tuple, &parse))
			goto next_entry;

		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
			dflt = *cfg;
static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
				cistpl_cftable_entry_t *cfg,
				cistpl_cftable_entry_t *dflt,
				unsigned int vcc,
				void *priv_data)
{
	if (cfg->index == 0)
			goto next_entry;
		link->conf.ConfigIndex = cfg->index;
		return -EINVAL;

		/* Does this card need audio output? */
/*	if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
		link->conf.Attributes |= CONF_ENABLE_SPKR;
		link->conf.Status = CCSR_AUDIO_ENA;
	}
*/
	/* Do we need to allocate an interrupt? */
		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
			link->conf.Attributes |= CONF_ENABLE_IRQ;
	if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
		p_dev->conf.Attributes |= CONF_ENABLE_IRQ;

	/* IO window settings */
		link->io.NumPorts1 = link->io.NumPorts2 = 0;
		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
	if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
		p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
		if (!(io->flags & CISTPL_IO_8BIT))
				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
		if (!(io->flags & CISTPL_IO_16BIT))
				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
			link->io.BasePort1 = io->win[0].base;
			link->io.NumPorts1 = io->win[0].len;
			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
		p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
		p_dev->io.BasePort1 = io->win[0].base;
		p_dev->io.NumPorts1 = io->win[0].len;
		if (io->nwin > 1) {
				link->io.Attributes2 = link->io.Attributes1;
				link->io.BasePort2 = io->win[1].base;
				link->io.NumPorts2 = io->win[1].len;
			p_dev->io.Attributes2 = p_dev->io.Attributes1;
			p_dev->io.BasePort2 = io->win[1].base;
			p_dev->io.NumPorts2 = io->win[1].len;
		}
		/* This reserves IO space but doesn't actually enable it */
			if (pcmcia_request_io(link, &link->io))
				goto next_entry;
		return pcmcia_request_io(p_dev, &p_dev->io);
	}

		/* If we got this far, we're cool! */
		break;
	return 0;
}

next_entry:
		last_fn = GetNextTuple;
static void das16cs_pcmcia_config(struct pcmcia_device *link)
{
	struct local_info_t *dev = link->priv;
	int ret;

		last_ret = pcmcia_get_next_tuple(link, &tuple);
		if (last_ret)
			goto cs_failed;
	dev_dbg(&link->dev, "das16cs_pcmcia_config\n");

	ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL);
	if (ret) {
		dev_warn(&link->dev, "no configuration found\n");
		goto failed;
	}

	/*
@@ -891,21 +786,18 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
	   irq structure is initialized.
	 */
	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
		last_fn = RequestIRQ;

		last_ret = pcmcia_request_irq(link, &link->irq);
		if (last_ret)
			goto cs_failed;
		ret = pcmcia_request_irq(link, &link->irq);
		if (ret)
			goto failed;
	}
	/*
	   This actually configures the PCMCIA socket -- setting up
	   the I/O windows and the interrupt mapping, and putting the
	   card and host interface into "Memory and IO" mode.
	 */
	last_fn = RequestConfiguration;
	last_ret = pcmcia_request_configuration(link, &link->conf);
	if (last_ret)
		goto cs_failed;
	ret = pcmcia_request_configuration(link, &link->conf);
	if (ret)
		goto failed;

	/*
	   At this point, the dev_node_t structure(s) need to be
@@ -930,14 +822,13 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)

	return;

cs_failed:
	cs_error(link, last_fn, last_ret);
failed:
	das16cs_pcmcia_release(link);
}				/* das16cs_pcmcia_config */

static void das16cs_pcmcia_release(struct pcmcia_device *link)
{
	DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link);
	dev_dbg(&link->dev, "das16cs_pcmcia_release\n");
	pcmcia_disable_device(link);
}				/* das16cs_pcmcia_release */

@@ -983,14 +874,13 @@ struct pcmcia_driver das16cs_driver = {

static int __init init_das16cs_pcmcia_cs(void)
{
	DEBUG(0, "%s\n", version);
	pcmcia_register_driver(&das16cs_driver);
	return 0;
}

static void __exit exit_das16cs_pcmcia_cs(void)
{
	DEBUG(0, "das16cs_pcmcia_cs: unloading\n");
	pr_debug("das16cs_pcmcia_cs: unloading\n");
	pcmcia_unregister_driver(&das16cs_driver);
}

+55 −147
Original line number Diff line number Diff line
@@ -110,25 +110,6 @@ static int das08_cs_attach(struct comedi_device *dev,

======================================================================*/

/*
   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
   you do not define PCMCIA_DEBUG at all, all the debug code will be
   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
   be present but disabled -- but it can then be enabled for specific
   modules at load time with a 'pc_debug=#' option to insmod.
*/

#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0644);
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
static const char *version =
    "das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
#else
#define DEBUG(n, args...)
#endif

/*====================================================================*/
static void das08_pcmcia_config(struct pcmcia_device *link);
static void das08_pcmcia_release(struct pcmcia_device *link);
static int das08_pcmcia_suspend(struct pcmcia_device *p_dev);
@@ -181,7 +162,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
{
	struct local_info_t *local;

	DEBUG(0, "das08_pcmcia_attach()\n");
	dev_dbg(&link->dev, "das08_pcmcia_attach()\n");

	/* Allocate space for private device-specific data */
	local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -224,7 +205,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
static void das08_pcmcia_detach(struct pcmcia_device *link)
{

	DEBUG(0, "das08_pcmcia_detach(0x%p)\n", link);
	dev_dbg(&link->dev, "das08_pcmcia_detach\n");

	if (link->dev_node) {
		((struct local_info_t *)link->priv)->stop = 1;
@@ -237,139 +218,69 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)

}				/* das08_pcmcia_detach */

/*======================================================================

    das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event
    is received, to configure the PCMCIA socket, and to make the
    device available to the system.

======================================================================*/

static void das08_pcmcia_config(struct pcmcia_device *link)
static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
				cistpl_cftable_entry_t *cfg,
				cistpl_cftable_entry_t *dflt,
				unsigned int vcc,
				void *priv_data)
{
	struct local_info_t *dev = link->priv;
	tuple_t tuple;
	cisparse_t parse;
	int last_fn, last_ret;
	u_char buf[64];
	cistpl_cftable_entry_t dflt = { 0 };

	DEBUG(0, "das08_pcmcia_config(0x%p)\n", link);

	/*
	   This reads the card's CONFIG tuple to find its configuration
	   registers.
	 */
	tuple.DesiredTuple = CISTPL_CONFIG;
	tuple.Attributes = 0;
	tuple.TupleData = buf;
	tuple.TupleDataMax = sizeof(buf);
	tuple.TupleOffset = 0;
	last_fn = GetFirstTuple;

	last_ret = pcmcia_get_first_tuple(link, &tuple);
	if (last_ret)
		goto cs_failed;

	last_fn = GetTupleData;

	last_ret = pcmcia_get_tuple_data(link, &tuple);
	if (last_ret)
		goto cs_failed;

	last_fn = ParseTuple;

	last_ret = pcmcia_parse_tuple(&tuple, &parse);
	if (last_ret)
		goto cs_failed;

	link->conf.ConfigBase = parse.config.base;
	link->conf.Present = parse.config.rmask[0];

	/*
	   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;
	last_fn = GetFirstTuple;

	last_ret = pcmcia_get_first_tuple(link, &tuple);
	if (last_ret)
		goto cs_failed;

	while (1) {
		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);

		last_ret = pcmcia_get_tuple_data(link, &tuple);
		if (last_ret)
			goto next_entry;

		last_ret = pcmcia_parse_tuple(&tuple, &parse);
		if (last_ret)
			goto next_entry;

		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
			dflt = *cfg;
	if (cfg->index == 0)
			goto next_entry;
		link->conf.ConfigIndex = cfg->index;
		return -ENODEV;

		/* Does this card need audio output? */
/*	if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
		link->conf.Attributes |= CONF_ENABLE_SPKR;
		link->conf.Status = CCSR_AUDIO_ENA;
	}
*/
	/* Do we need to allocate an interrupt? */
		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
			link->conf.Attributes |= CONF_ENABLE_IRQ;
	if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
		p_dev->conf.Attributes |= CONF_ENABLE_IRQ;

	/* IO window settings */
		link->io.NumPorts1 = link->io.NumPorts2 = 0;
		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
	if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
		p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
		if (!(io->flags & CISTPL_IO_8BIT))
				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
		if (!(io->flags & CISTPL_IO_16BIT))
				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
			link->io.BasePort1 = io->win[0].base;
			link->io.NumPorts1 = io->win[0].len;
			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
		p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
		p_dev->io.BasePort1 = io->win[0].base;
		p_dev->io.NumPorts1 = io->win[0].len;
		if (io->nwin > 1) {
				link->io.Attributes2 = link->io.Attributes1;
				link->io.BasePort2 = io->win[1].base;
				link->io.NumPorts2 = io->win[1].len;
			p_dev->io.Attributes2 = p_dev->io.Attributes1;
			p_dev->io.BasePort2 = io->win[1].base;
			p_dev->io.NumPorts2 = io->win[1].len;
		}
		/* This reserves IO space but doesn't actually enable it */
			if (pcmcia_request_io(link, &link->io) != 0)
				goto next_entry;
		return pcmcia_request_io(p_dev, &p_dev->io);
	}
	return 0;
}


		/* If we got this far, we're cool! */
		break;
/*======================================================================

    das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event
    is received, to configure the PCMCIA socket, and to make the
    device available to the system.

======================================================================*/

static void das08_pcmcia_config(struct pcmcia_device *link)
{
	struct local_info_t *dev = link->priv;
	int ret;

next_entry:
		last_fn = GetNextTuple;
	dev_dbg(&link->dev, "das08_pcmcia_config\n");

		last_ret = pcmcia_get_next_tuple(link, &tuple);
		if (last_ret)
			goto cs_failed;
	ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL);
	if (ret) {
		dev_warn(&link->dev, "no configuration found\n");
		goto failed;
	}

	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
		last_fn = RequestIRQ;
		last_ret = pcmcia_request_irq(link, &link->irq);
		if (last_ret)
			goto cs_failed;
		ret = pcmcia_request_irq(link, &link->irq);
		if (ret)
			goto failed;
	}

	/*
@@ -377,10 +288,9 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
	   the I/O windows and the interrupt mapping, and putting the
	   card and host interface into "Memory and IO" mode.
	 */
	last_fn = RequestConfiguration;
	last_ret = pcmcia_request_configuration(link, &link->conf);
	if (last_ret)
		goto cs_failed;
	ret = pcmcia_request_configuration(link, &link->conf);
	if (ret)
		goto failed;

	/*
	   At this point, the dev_node_t structure(s) need to be
@@ -405,8 +315,7 @@ static void das08_pcmcia_config(struct pcmcia_device *link)

	return;

cs_failed:
	cs_error(link, last_fn, last_ret);
failed:
	das08_pcmcia_release(link);

}				/* das08_pcmcia_config */
@@ -421,7 +330,7 @@ static void das08_pcmcia_config(struct pcmcia_device *link)

static void das08_pcmcia_release(struct pcmcia_device *link)
{
	DEBUG(0, "das08_pcmcia_release(0x%p)\n", link);
	dev_dbg(&link->dev, "das08_pcmcia_release\n");
	pcmcia_disable_device(link);
}				/* das08_pcmcia_release */

@@ -477,14 +386,13 @@ struct pcmcia_driver das08_cs_driver = {

static int __init init_das08_pcmcia_cs(void)
{
	DEBUG(0, "%s\n", version);
	pcmcia_register_driver(&das08_cs_driver);
	return 0;
}

static void __exit exit_das08_pcmcia_cs(void)
{
	DEBUG(0, "das08_pcmcia_cs: unloading\n");
	pr_debug("das08_pcmcia_cs: unloading\n");
	pcmcia_unregister_driver(&das08_cs_driver);
}

+78 −158

File changed.

Preview size limit exceeded, changes collapsed.

+77 −158
Original line number Diff line number Diff line
@@ -187,25 +187,7 @@ static int dio24_detach(struct comedi_device *dev)
	return 0;
};

/* PCMCIA crap */

/*
   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
   you do not define PCMCIA_DEBUG at all, all the debug code will be
   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
   be present but disabled -- but it can then be enabled for specific
   modules at load time with a 'pc_debug=#' option to insmod.
*/
#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0644);
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
static char *version = "ni_daq_dio24.c, based on dummy_cs.c";
#else
#define DEBUG(n, args...)
#endif

/*====================================================================*/
/* PCMCIA crap -- watch your words! */

static void dio24_config(struct pcmcia_device *link);
static void dio24_release(struct pcmcia_device *link);
@@ -261,7 +243,7 @@ static int dio24_cs_attach(struct pcmcia_device *link)

	printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");

	DEBUG(0, "dio24_cs_attach()\n");
	dev_dbg(&link->dev, "dio24_cs_attach()\n");

	/* Allocate space for private device-specific data */
	local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -306,7 +288,7 @@ static void dio24_cs_detach(struct pcmcia_device *link)

	printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");

	DEBUG(0, "dio24_cs_detach(0x%p)\n", link);
	dev_dbg(&link->dev, "dio24_cs_detach\n");

	if (link->dev_node) {
		((struct local_info_t *)link->priv)->stop = 1;
@@ -327,142 +309,85 @@ static void dio24_cs_detach(struct pcmcia_device *link)

======================================================================*/

static void dio24_config(struct pcmcia_device *link)
static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
				cistpl_cftable_entry_t *cfg,
				cistpl_cftable_entry_t *dflt,
				unsigned int vcc,
				void *priv_data)
{
	struct local_info_t *dev = link->priv;
	tuple_t tuple;
	cisparse_t parse;
	int last_ret;
	u_char buf[64];
	win_req_t req;
	win_req_t *req = priv_data;
	memreq_t map;
	cistpl_cftable_entry_t dflt = { 0 };

	printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");

	DEBUG(0, "dio24_config(0x%p)\n", link);

	/*
	   This reads the card's CONFIG tuple to find its configuration
	   registers.
	 */
	tuple.DesiredTuple = CISTPL_CONFIG;
	tuple.Attributes = 0;
	tuple.TupleData = buf;
	tuple.TupleDataMax = sizeof(buf);
	tuple.TupleOffset = 0;

	last_ret = pcmcia_get_first_tuple(link, &tuple);
	if (last_ret) {
		cs_error(link, GetFirstTuple, last_ret);
		goto cs_failed;
	}

	last_ret = pcmcia_get_tuple_data(link, &tuple);
	if (last_ret) {
		cs_error(link, GetTupleData, last_ret);
		goto cs_failed;
	}

	last_ret = pcmcia_parse_tuple(&tuple, &parse);
	if (last_ret) {
		cs_error(link, ParseTuple, last_ret);
		goto cs_failed;
	}
	link->conf.ConfigBase = parse.config.base;
	link->conf.Present = parse.config.rmask[0];

	/*
	   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;

	last_ret = pcmcia_get_first_tuple(link, &tuple);
	if (last_ret) {
		cs_error(link, GetFirstTuple, last_ret);
		goto cs_failed;
	}
	while (1) {
		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
		if (pcmcia_get_tuple_data(link, &tuple) != 0)
			goto next_entry;
		if (pcmcia_parse_tuple(&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;
		return -ENODEV;

	/* Does this card need audio output? */
	if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
			link->conf.Attributes |= CONF_ENABLE_SPKR;
			link->conf.Status = CCSR_AUDIO_ENA;
		p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
		p_dev->conf.Status = CCSR_AUDIO_ENA;
	}

	/* Do we need to allocate an interrupt? */
		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
			link->conf.Attributes |= CONF_ENABLE_IRQ;
	if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
		p_dev->conf.Attributes |= CONF_ENABLE_IRQ;

	/* IO window settings */
		link->io.NumPorts1 = link->io.NumPorts2 = 0;
		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
	if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
		p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
		if (!(io->flags & CISTPL_IO_8BIT))
				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
		if (!(io->flags & CISTPL_IO_16BIT))
				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
			link->io.BasePort1 = io->win[0].base;
			link->io.NumPorts1 = io->win[0].len;
			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
		p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
		p_dev->io.BasePort1 = io->win[0].base;
		p_dev->io.NumPorts1 = io->win[0].len;
		if (io->nwin > 1) {
				link->io.Attributes2 = link->io.Attributes1;
				link->io.BasePort2 = io->win[1].base;
				link->io.NumPorts2 = io->win[1].len;
			p_dev->io.Attributes2 = p_dev->io.Attributes1;
			p_dev->io.BasePort2 = io->win[1].base;
			p_dev->io.NumPorts2 = io->win[1].len;
		}
		/* This reserves IO space but doesn't actually enable it */
			if (pcmcia_request_io(link, &link->io) != 0)
				goto next_entry;
		if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
			return -ENODEV;
	}

		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
	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))
				goto next_entry;
			(cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
		req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
		req->Attributes |= WIN_ENABLE;
		req->Base = mem->win[0].host_addr;
		req->Size = mem->win[0].len;
		if (req->Size < 0x1000)
			req->Size = 0x1000;
		req->AccessSpeed = 0;
		if (pcmcia_request_window(&p_dev, req, &p_dev->win))
			return -ENODEV;
		map.Page = 0;
		map.CardOffset = mem->win[0].card_addr;
			if (pcmcia_map_mem_page(link->win, &map))
				goto next_entry;
		if (pcmcia_map_mem_page(p_dev->win, &map))
			return -ENODEV;
	}
	/* If we got this far, we're cool! */
		break;
	return 0;
}

next_entry:
static void dio24_config(struct pcmcia_device *link)
{
	struct local_info_t *dev = link->priv;
	int ret;
	win_req_t req;

		last_ret = pcmcia_get_next_tuple(link, &tuple);
		if (last_ret) {
			cs_error(link, GetNextTuple, last_ret);
			goto cs_failed;
		}
	printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");

	dev_dbg(&link->dev, "dio24_config\n");

	ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, &req);
	if (ret) {
		dev_warn(&link->dev, "no configuration found\n");
		goto failed;
	}

	/*
@@ -471,11 +396,9 @@ static void dio24_config(struct pcmcia_device *link)
	   irq structure is initialized.
	 */
	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
		last_ret = pcmcia_request_irq(link, &link->irq);
		if (last_ret) {
			cs_error(link, RequestIRQ, last_ret);
			goto cs_failed;
		}
		ret = pcmcia_request_irq(link, &link->irq);
		if (ret)
			goto failed;
	}

	/*
@@ -483,11 +406,9 @@ static void dio24_config(struct pcmcia_device *link)
	   the I/O windows and the interrupt mapping, and putting the
	   card and host interface into "Memory and IO" mode.
	 */
	last_ret = pcmcia_request_configuration(link, &link->conf);
	if (last_ret) {
		cs_error(link, RequestConfiguration, last_ret);
		goto cs_failed;
	}
	ret = pcmcia_request_configuration(link, &link->conf);
	if (ret)
		goto failed;

	/*
	   At this point, the dev_node_t structure(s) need to be
@@ -515,7 +436,7 @@ static void dio24_config(struct pcmcia_device *link)

	return;

cs_failed:
failed:
	printk(KERN_INFO "Fallo");
	dio24_release(link);

@@ -523,7 +444,7 @@ static void dio24_config(struct pcmcia_device *link)

static void dio24_release(struct pcmcia_device *link)
{
	DEBUG(0, "dio24_release(0x%p)\n", link);
	dev_dbg(&link->dev, "dio24_release\n");

	pcmcia_disable_device(link);
}				/* dio24_release */
@@ -582,14 +503,12 @@ struct pcmcia_driver dio24_cs_driver = {
static int __init init_dio24_cs(void)
{
	printk("ni_daq_dio24: HOLA SOY YO!\n");
	DEBUG(0, "%s\n", version);
	pcmcia_register_driver(&dio24_cs_driver);
	return 0;
}

static void __exit exit_dio24_cs(void)
{
	DEBUG(0, "ni_dio24: unloading\n");
	pcmcia_unregister_driver(&dio24_cs_driver);
}

+75 −149

File changed.

Preview size limit exceeded, changes collapsed.

Loading