diff options
Diffstat (limited to 'drivers/net/wireless/atmel_cs.c')
| -rw-r--r-- | drivers/net/wireless/atmel_cs.c | 123 | 
1 files changed, 55 insertions, 68 deletions
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 12617cd0b78..263c36f7ee2 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -224,25 +224,69 @@ static int card_present(void *arg)  	return 0;  } +static int atmel_config_check(struct pcmcia_device *p_dev, +			      cistpl_cftable_entry_t *cfg, +			      void *priv_data) +{ +	cistpl_cftable_entry_t *dflt = priv_data; + +	if (cfg->flags & CISTPL_CFTABLE_DEFAULT) +		*dflt = *cfg; +	if (cfg->index == 0) +		return -ENODEV; +	p_dev->conf.ConfigIndex = cfg->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->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; +	cistpl_cftable_entry_t dflt = { 0 };  	dev = link->priv;  	did = handle_to_dev(link).driver_data;  	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 +299,8 @@ static int atmel_config(struct pcmcia_device *link)  	  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, &dflt)) +		goto failed;  	/*  	  Allocate an interrupt line.  Note that this does not assign a @@ -360,6 +346,7 @@ static int atmel_config(struct pcmcia_device *link)   cs_failed:  	cs_error(link, last_fn, last_ret); + failed:  	atmel_release(link);  	return -ENODEV;  }  |