Example #1
0
static int sl811_cs_config(struct pcmcia_device *link)
{
	struct device		*parent = &link->dev;
	int			ret;

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

	link->config_flags |= CONF_ENABLE_IRQ |	CONF_AUTO_SET_VPP |
		CONF_AUTO_CHECK_VCC | CONF_AUTO_SET_IO;

	if (pcmcia_loop_config(link, sl811_cs_config_check, NULL))
		goto failed;

	/* require an IRQ and two registers */
	if (resource_size(link->resource[0]) < 2)
		goto failed;

	if (!link->irq)
		goto failed;

	ret = pcmcia_enable_device(link);
	if (ret)
		goto failed;

	if (sl811_hc_init(parent, link->resource[0]->start, link->irq)
			< 0) {
failed:
		printk(KERN_WARNING "sl811_cs_config failed\n");
		sl811_cs_release(link);
		return  -ENODEV;
	}
	return 0;
}
static int sl811_cs_config(struct pcmcia_device *link)
{
	struct device		*parent = &link->dev;
	local_info_t		*dev = link->priv;
	int			ret;

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

	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 failed;
	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
		ret = pcmcia_request_irq(link, &link->irq);
		if (ret)
			goto failed;
	} else
		goto failed;

	ret = pcmcia_request_configuration(link, &link->conf);
	if (ret)
		goto failed;

	sprintf(dev->node.dev_name, driver_name);
	dev->node.major = dev->node.minor = 0;
	link->dev_node = &dev->node;

	printk(KERN_INFO "%s: index 0x%02x: ",
	       dev->node.dev_name, link->conf.ConfigIndex);
	if (link->conf.Vpp)
		printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
	printk(", irq %d", link->irq.AssignedIRQ);
	printk(", io 0x%04x-0x%04x", link->io.BasePort1,
	       link->io.BasePort1+link->io.NumPorts1-1);
	printk("\n");

	if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
			< 0) {
failed:
		printk(KERN_WARNING "sl811_cs_config failed\n");
		sl811_cs_release(link);
		return  -ENODEV;
	}
	return 0;
}
Example #3
0
static void sl811_cs_config(dev_link_t *link)
{
	client_handle_t		handle = link->handle;
	struct device		*parent = &handle_to_dev(handle);
	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);

	tuple.DesiredTuple = CISTPL_CONFIG;
	tuple.Attributes = 0;
	tuple.TupleData = buf;
	tuple.TupleDataMax = sizeof(buf);
	tuple.TupleOffset = 0;
	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
	CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
	link->conf.ConfigBase = parse.config.base;
	link->conf.Present = parse.config.rmask[0];

	/* Configure card */
	link->state |= DEV_CONFIG;

	/* Look up the current Vcc */
	CS_CHECK(GetConfigurationInfo,
			pcmcia_get_configuration_info(handle, &conf));
	link->conf.Vcc = conf.Vcc;

	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
	while (1) {
		cistpl_cftable_entry_t	*cfg = &(parse.cftable_entry);

		if (pcmcia_get_tuple_data(handle, &tuple) != 0
				|| pcmcia_parse_tuple(handle, &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.Vpp1 = link->conf.Vpp2 =
				cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
		else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
			link->conf.Vpp1 = link->conf.Vpp2 =
				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->handle, &link->io) != 0)
				goto next_entry;
		}
		break;

next_entry:
		if (link->io.NumPorts1)
			pcmcia_release_io(link->handle, &link->io);
		last_ret = pcmcia_get_next_tuple(handle, &tuple);
	}

	/* require an IRQ and two registers */
	if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
		goto cs_failed;
	if (link->conf.Attributes & CONF_ENABLE_IRQ)
		CS_CHECK(RequestIRQ,
			pcmcia_request_irq(link->handle, &link->irq));
	else
		goto cs_failed;

	CS_CHECK(RequestConfiguration,
		pcmcia_request_configuration(link->handle, &link->conf));

	sprintf(dev->node.dev_name, driver_name);
	dev->node.major = dev->node.minor = 0;
	link->dev = &dev->node;

	printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
	       dev->node.dev_name, link->conf.ConfigIndex,
	       link->conf.Vcc/10, link->conf.Vcc%10);
	if (link->conf.Vpp1)
		printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
	printk(", irq %d", link->irq.AssignedIRQ);
	printk(", io 0x%04x-0x%04x", link->io.BasePort1,
	       link->io.BasePort1+link->io.NumPorts1-1);
	printk("\n");

	link->state &= ~DEV_CONFIG_PENDING;

	if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
			< 0) {
cs_failed:
		printk("sl811_cs_config failed\n");
		cs_error(link->handle, last_fn, last_ret);
		sl811_cs_release(link);
		link->state &= ~DEV_CONFIG_PENDING;
	}
}