diff options
Diffstat (limited to 'drivers/net/wireless/atmel_cs.c')
-rw-r--r-- | drivers/net/wireless/atmel_cs.c | 119 |
1 files changed, 51 insertions, 68 deletions
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index d2388e8d179a..77406245dc7b 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c | |||
@@ -224,13 +224,58 @@ 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 | cistpl_cftable_entry_t *dflt, | ||
230 | unsigned int vcc, | ||
231 | void *priv_data) | ||
232 | { | ||
233 | if (cfg->index == 0) | ||
234 | return -ENODEV; | ||
235 | |||
236 | /* Does this card need audio output? */ | ||
237 | if (cfg->flags & CISTPL_CFTABLE_AUDIO) { | ||
238 | p_dev->conf.Attributes |= CONF_ENABLE_SPKR; | ||
239 | p_dev->conf.Status = CCSR_AUDIO_ENA; | ||
240 | } | ||
241 | |||
242 | /* Use power settings for Vcc and Vpp if present */ | ||
243 | /* Note that the CIS values need to be rescaled */ | ||
244 | if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
245 | p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
246 | else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
247 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
248 | |||
249 | /* Do we need to allocate an interrupt? */ | ||
250 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | ||
251 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
252 | |||
253 | /* IO window settings */ | ||
254 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | ||
255 | if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { | ||
256 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; | ||
257 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
258 | if (!(io->flags & CISTPL_IO_8BIT)) | ||
259 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
260 | if (!(io->flags & CISTPL_IO_16BIT)) | ||
261 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
262 | p_dev->io.BasePort1 = io->win[0].base; | ||
263 | p_dev->io.NumPorts1 = io->win[0].len; | ||
264 | if (io->nwin > 1) { | ||
265 | p_dev->io.Attributes2 = p_dev->io.Attributes1; | ||
266 | p_dev->io.BasePort2 = io->win[1].base; | ||
267 | p_dev->io.NumPorts2 = io->win[1].len; | ||
268 | } | ||
269 | } | ||
270 | |||
271 | /* This reserves IO space but doesn't actually enable it */ | ||
272 | return pcmcia_request_io(p_dev, &p_dev->io); | ||
273 | } | ||
274 | |||
227 | static int atmel_config(struct pcmcia_device *link) | 275 | static int atmel_config(struct pcmcia_device *link) |
228 | { | 276 | { |
229 | tuple_t tuple; | ||
230 | cisparse_t parse; | ||
231 | local_info_t *dev; | 277 | local_info_t *dev; |
232 | int last_fn, last_ret; | 278 | int last_fn, last_ret; |
233 | u_char buf[64]; | ||
234 | struct pcmcia_device_id *did; | 279 | struct pcmcia_device_id *did; |
235 | 280 | ||
236 | dev = link->priv; | 281 | dev = link->priv; |
@@ -238,11 +283,6 @@ static int atmel_config(struct pcmcia_device *link) | |||
238 | 283 | ||
239 | DEBUG(0, "atmel_config(0x%p)\n", link); | 284 | DEBUG(0, "atmel_config(0x%p)\n", link); |
240 | 285 | ||
241 | tuple.Attributes = 0; | ||
242 | tuple.TupleData = buf; | ||
243 | tuple.TupleDataMax = sizeof(buf); | ||
244 | tuple.TupleOffset = 0; | ||
245 | |||
246 | /* | 286 | /* |
247 | In this loop, we scan the CIS for configuration table entries, | 287 | In this loop, we scan the CIS for configuration table entries, |
248 | each of which describes a valid card configuration, including | 288 | each of which describes a valid card configuration, including |
@@ -255,66 +295,8 @@ static int atmel_config(struct pcmcia_device *link) | |||
255 | these things without consulting the CIS, and most client drivers | 295 | these things without consulting the CIS, and most client drivers |
256 | will only use the CIS to fill in implementation-defined details. | 296 | will only use the CIS to fill in implementation-defined details. |
257 | */ | 297 | */ |
258 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 298 | if (pcmcia_loop_config(link, atmel_config_check, NULL)) |
259 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 299 | 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 | 300 | ||
319 | /* | 301 | /* |
320 | Allocate an interrupt line. Note that this does not assign a | 302 | Allocate an interrupt line. Note that this does not assign a |
@@ -360,6 +342,7 @@ static int atmel_config(struct pcmcia_device *link) | |||
360 | 342 | ||
361 | cs_failed: | 343 | cs_failed: |
362 | cs_error(link, last_fn, last_ret); | 344 | cs_error(link, last_fn, last_ret); |
345 | failed: | ||
363 | atmel_release(link); | 346 | atmel_release(link); |
364 | return -ENODEV; | 347 | return -ENODEV; |
365 | } | 348 | } |