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 12617cd0b78e..263c36f7ee22 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) | |||
224 | return 0; | 224 | return 0; |
225 | } | 225 | } |
226 | 226 | ||
227 | static int atmel_config_check(struct pcmcia_device *p_dev, | ||
228 | cistpl_cftable_entry_t *cfg, | ||
229 | void *priv_data) | ||
230 | { | ||
231 | cistpl_cftable_entry_t *dflt = priv_data; | ||
232 | |||
233 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) | ||
234 | *dflt = *cfg; | ||
235 | if (cfg->index == 0) | ||
236 | return -ENODEV; | ||
237 | p_dev->conf.ConfigIndex = cfg->index; | ||
238 | |||
239 | /* Does this card need audio output? */ | ||
240 | if (cfg->flags & CISTPL_CFTABLE_AUDIO) { | ||
241 | p_dev->conf.Attributes |= CONF_ENABLE_SPKR; | ||
242 | p_dev->conf.Status = CCSR_AUDIO_ENA; | ||
243 | } | ||
244 | |||
245 | /* Use power settings for Vcc and Vpp if present */ | ||
246 | /* Note that the CIS values need to be rescaled */ | ||
247 | if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
248 | p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
249 | else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
250 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
251 | |||
252 | /* Do we need to allocate an interrupt? */ | ||
253 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | ||
254 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
255 | |||
256 | /* IO window settings */ | ||
257 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | ||
258 | if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { | ||
259 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; | ||
260 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
261 | if (!(io->flags & CISTPL_IO_8BIT)) | ||
262 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
263 | if (!(io->flags & CISTPL_IO_16BIT)) | ||
264 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
265 | p_dev->io.BasePort1 = io->win[0].base; | ||
266 | p_dev->io.NumPorts1 = io->win[0].len; | ||
267 | if (io->nwin > 1) { | ||
268 | p_dev->io.Attributes2 = p_dev->io.Attributes1; | ||
269 | p_dev->io.BasePort2 = io->win[1].base; | ||
270 | p_dev->io.NumPorts2 = io->win[1].len; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | /* This reserves IO space but doesn't actually enable it */ | ||
275 | return pcmcia_request_io(p_dev, &p_dev->io); | ||
276 | } | ||
277 | |||
227 | static int atmel_config(struct pcmcia_device *link) | 278 | static int atmel_config(struct pcmcia_device *link) |
228 | { | 279 | { |
229 | tuple_t tuple; | ||
230 | cisparse_t parse; | ||
231 | local_info_t *dev; | 280 | local_info_t *dev; |
232 | int last_fn, last_ret; | 281 | int last_fn, last_ret; |
233 | u_char buf[64]; | ||
234 | struct pcmcia_device_id *did; | 282 | struct pcmcia_device_id *did; |
283 | cistpl_cftable_entry_t dflt = { 0 }; | ||
235 | 284 | ||
236 | dev = link->priv; | 285 | dev = link->priv; |
237 | did = handle_to_dev(link).driver_data; | 286 | did = handle_to_dev(link).driver_data; |
238 | 287 | ||
239 | DEBUG(0, "atmel_config(0x%p)\n", link); | 288 | DEBUG(0, "atmel_config(0x%p)\n", link); |
240 | 289 | ||
241 | tuple.Attributes = 0; | ||
242 | tuple.TupleData = buf; | ||
243 | tuple.TupleDataMax = sizeof(buf); | ||
244 | tuple.TupleOffset = 0; | ||
245 | |||
246 | /* | 290 | /* |
247 | In this loop, we scan the CIS for configuration table entries, | 291 | In this loop, we scan the CIS for configuration table entries, |
248 | each of which describes a valid card configuration, including | 292 | each of which describes a valid card configuration, including |
@@ -255,66 +299,8 @@ static int atmel_config(struct pcmcia_device *link) | |||
255 | these things without consulting the CIS, and most client drivers | 299 | these things without consulting the CIS, and most client drivers |
256 | will only use the CIS to fill in implementation-defined details. | 300 | will only use the CIS to fill in implementation-defined details. |
257 | */ | 301 | */ |
258 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 302 | if (pcmcia_loop_config(link, atmel_config_check, &dflt)) |
259 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 303 | goto failed; |
260 | while (1) { | ||
261 | cistpl_cftable_entry_t dflt = { 0 }; | ||
262 | cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); | ||
263 | if (pcmcia_get_tuple_data(link, &tuple) != 0 || | ||
264 | pcmcia_parse_tuple(link, &tuple, &parse) != 0) | ||
265 | goto next_entry; | ||
266 | |||
267 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; | ||
268 | if (cfg->index == 0) goto next_entry; | ||
269 | link->conf.ConfigIndex = cfg->index; | ||
270 | |||
271 | /* Does this card need audio output? */ | ||
272 | if (cfg->flags & CISTPL_CFTABLE_AUDIO) { | ||
273 | link->conf.Attributes |= CONF_ENABLE_SPKR; | ||
274 | link->conf.Status = CCSR_AUDIO_ENA; | ||
275 | } | ||
276 | |||
277 | /* Use power settings for Vcc and Vpp if present */ | ||
278 | /* Note that the CIS values need to be rescaled */ | ||
279 | if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
280 | link->conf.Vpp = | ||
281 | cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
282 | else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
283 | link->conf.Vpp = | ||
284 | dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
285 | |||
286 | /* Do we need to allocate an interrupt? */ | ||
287 | if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) | ||
288 | link->conf.Attributes |= CONF_ENABLE_IRQ; | ||
289 | |||
290 | /* IO window settings */ | ||
291 | link->io.NumPorts1 = link->io.NumPorts2 = 0; | ||
292 | if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { | ||
293 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; | ||
294 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
295 | if (!(io->flags & CISTPL_IO_8BIT)) | ||
296 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
297 | if (!(io->flags & CISTPL_IO_16BIT)) | ||
298 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
299 | link->io.BasePort1 = io->win[0].base; | ||
300 | link->io.NumPorts1 = io->win[0].len; | ||
301 | if (io->nwin > 1) { | ||
302 | link->io.Attributes2 = link->io.Attributes1; | ||
303 | link->io.BasePort2 = io->win[1].base; | ||
304 | link->io.NumPorts2 = io->win[1].len; | ||
305 | } | ||
306 | } | ||
307 | |||
308 | /* This reserves IO space but doesn't actually enable it */ | ||
309 | if (pcmcia_request_io(link, &link->io) != 0) | ||
310 | goto next_entry; | ||
311 | |||
312 | /* If we got this far, we're cool! */ | ||
313 | break; | ||
314 | |||
315 | next_entry: | ||
316 | CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); | ||
317 | } | ||
318 | 304 | ||
319 | /* | 305 | /* |
320 | Allocate an interrupt line. Note that this does not assign a | 306 | Allocate an interrupt line. Note that this does not assign a |
@@ -360,6 +346,7 @@ static int atmel_config(struct pcmcia_device *link) | |||
360 | 346 | ||
361 | cs_failed: | 347 | cs_failed: |
362 | cs_error(link, last_fn, last_ret); | 348 | cs_error(link, last_fn, last_ret); |
349 | failed: | ||
363 | atmel_release(link); | 350 | atmel_release(link); |
364 | return -ENODEV; | 351 | return -ENODEV; |
365 | } | 352 | } |