diff options
Diffstat (limited to 'drivers/usb/host/sl811_cs.c')
| -rw-r--r-- | drivers/usb/host/sl811_cs.c | 125 | 
1 files changed, 51 insertions, 74 deletions
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 5da63f53500..516848dd9b4 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -112,7 +112,8 @@ static struct platform_device platform_dev = {  	.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 @@ static void sl811_cs_release(struct pcmcia_device * link)  	platform_device_unregister(&platform_dev);  } -static int sl811_cs_config(struct pcmcia_device *link) +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)  { -	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 (cfg->index == 0) +		return -ENODEV; -		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; +	/* 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->index == 0) -			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; -		link->conf.ConfigIndex = cfg->index; +	/* we need an interrupt */ +	if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) +		p_dev->conf.Attributes |= CONF_ENABLE_IRQ; -		/* 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; -		} +	/* 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; -		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->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; -		/* we need an interrupt */ -		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) -			link->conf.Attributes |= CONF_ENABLE_IRQ; +		return pcmcia_request_io(p_dev, &p_dev->io); +	} +	pcmcia_disable_device(p_dev); +	return -ENODEV; +} -		/* 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; +static int sl811_cs_config(struct pcmcia_device *link) +{ +	struct device		*parent = &handle_to_dev(link); +	local_info_t		*dev = link->priv; +	int			last_fn, last_ret; -			if (pcmcia_request_io(link, &link->io) != 0) -				goto next_entry; -		} -		break; +	DBG(0, "sl811_cs_config(0x%p)\n", link); -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 @@ next_entry:  	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;  	}  |