diff options
Diffstat (limited to 'drivers/net/wireless/airo_cs.c')
-rw-r--r-- | drivers/net/wireless/airo_cs.c | 222 |
1 files changed, 111 insertions, 111 deletions
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index f12355398fe..fac1526e49a 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c | |||
@@ -206,126 +206,123 @@ static void airo_detach(struct pcmcia_device *link) | |||
206 | #define CS_CHECK(fn, ret) \ | 206 | #define CS_CHECK(fn, ret) \ |
207 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 207 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
208 | 208 | ||
209 | static int airo_cs_config_check(struct pcmcia_device *p_dev, | ||
210 | cistpl_cftable_entry_t *cfg, | ||
211 | cistpl_cftable_entry_t *dflt, | ||
212 | unsigned int vcc, | ||
213 | void *priv_data) | ||
214 | { | ||
215 | win_req_t *req = priv_data; | ||
216 | |||
217 | if (cfg->index == 0) | ||
218 | return -ENODEV; | ||
219 | |||
220 | /* Does this card need audio output? */ | ||
221 | if (cfg->flags & CISTPL_CFTABLE_AUDIO) { | ||
222 | p_dev->conf.Attributes |= CONF_ENABLE_SPKR; | ||
223 | p_dev->conf.Status = CCSR_AUDIO_ENA; | ||
224 | } | ||
225 | |||
226 | /* Use power settings for Vcc and Vpp if present */ | ||
227 | /* Note that the CIS values need to be rescaled */ | ||
228 | if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
229 | p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
230 | else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
231 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
232 | |||
233 | /* Do we need to allocate an interrupt? */ | ||
234 | if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) | ||
235 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
236 | |||
237 | /* IO window settings */ | ||
238 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | ||
239 | if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { | ||
240 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; | ||
241 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
242 | if (!(io->flags & CISTPL_IO_8BIT)) | ||
243 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
244 | if (!(io->flags & CISTPL_IO_16BIT)) | ||
245 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
246 | p_dev->io.BasePort1 = io->win[0].base; | ||
247 | p_dev->io.NumPorts1 = io->win[0].len; | ||
248 | if (io->nwin > 1) { | ||
249 | p_dev->io.Attributes2 = p_dev->io.Attributes1; | ||
250 | p_dev->io.BasePort2 = io->win[1].base; | ||
251 | p_dev->io.NumPorts2 = io->win[1].len; | ||
252 | } | ||
253 | } | ||
254 | |||
255 | /* This reserves IO space but doesn't actually enable it */ | ||
256 | if (pcmcia_request_io(p_dev, &p_dev->io) != 0) | ||
257 | return -ENODEV; | ||
258 | |||
259 | /* | ||
260 | Now set up a common memory window, if needed. There is room | ||
261 | in the struct pcmcia_device structure for one memory window handle, | ||
262 | but if the base addresses need to be saved, or if multiple | ||
263 | windows are needed, the info should go in the private data | ||
264 | structure for this device. | ||
265 | |||
266 | Note that the memory window base is a physical address, and | ||
267 | needs to be mapped to virtual space with ioremap() before it | ||
268 | is used. | ||
269 | */ | ||
270 | if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) { | ||
271 | cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem; | ||
272 | memreq_t map; | ||
273 | req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; | ||
274 | req->Base = mem->win[0].host_addr; | ||
275 | req->Size = mem->win[0].len; | ||
276 | req->AccessSpeed = 0; | ||
277 | if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0) | ||
278 | return -ENODEV; | ||
279 | map.Page = 0; | ||
280 | map.CardOffset = mem->win[0].card_addr; | ||
281 | if (pcmcia_map_mem_page(p_dev->win, &map) != 0) | ||
282 | return -ENODEV; | ||
283 | } | ||
284 | /* If we got this far, we're cool! */ | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | |||
209 | static int airo_config(struct pcmcia_device *link) | 289 | static int airo_config(struct pcmcia_device *link) |
210 | { | 290 | { |
211 | tuple_t tuple; | ||
212 | cisparse_t parse; | ||
213 | local_info_t *dev; | 291 | local_info_t *dev; |
292 | win_req_t *req; | ||
214 | int last_fn, last_ret; | 293 | int last_fn, last_ret; |
215 | u_char buf[64]; | ||
216 | win_req_t req; | ||
217 | memreq_t map; | ||
218 | 294 | ||
219 | dev = link->priv; | 295 | dev = link->priv; |
220 | 296 | ||
221 | DEBUG(0, "airo_config(0x%p)\n", link); | 297 | DEBUG(0, "airo_config(0x%p)\n", link); |
222 | 298 | ||
299 | req = kzalloc(sizeof(win_req_t), GFP_KERNEL); | ||
300 | if (!req) | ||
301 | return -ENOMEM; | ||
302 | |||
303 | /* | ||
304 | * In this loop, we scan the CIS for configuration table | ||
305 | * entries, each of which describes a valid card | ||
306 | * configuration, including voltage, IO window, memory window, | ||
307 | * and interrupt settings. | ||
308 | * | ||
309 | * We make no assumptions about the card to be configured: we | ||
310 | * use just the information available in the CIS. In an ideal | ||
311 | * world, this would work for any PCMCIA card, but it requires | ||
312 | * a complete and accurate CIS. In practice, a driver usually | ||
313 | * "knows" most of these things without consulting the CIS, | ||
314 | * and most client drivers will only use the CIS to fill in | ||
315 | * implementation-defined details. | ||
316 | */ | ||
317 | last_ret = pcmcia_loop_config(link, airo_cs_config_check, req); | ||
318 | if (last_ret) | ||
319 | goto failed; | ||
320 | |||
223 | /* | 321 | /* |
224 | In this loop, we scan the CIS for configuration table entries, | 322 | Allocate an interrupt line. Note that this does not assign a |
225 | each of which describes a valid card configuration, including | 323 | handler to the interrupt, unless the 'Handler' member of the |
226 | voltage, IO window, memory window, and interrupt settings. | 324 | irq structure is initialized. |
227 | |||
228 | We make no assumptions about the card to be configured: we use | ||
229 | just the information available in the CIS. In an ideal world, | ||
230 | this would work for any PCMCIA card, but it requires a complete | ||
231 | and accurate CIS. In practice, a driver usually "knows" most of | ||
232 | these things without consulting the CIS, and most client drivers | ||
233 | will only use the CIS to fill in implementation-defined details. | ||
234 | */ | 325 | */ |
235 | tuple.Attributes = 0; | ||
236 | tuple.TupleData = buf; | ||
237 | tuple.TupleDataMax = sizeof(buf); | ||
238 | tuple.TupleOffset = 0; | ||
239 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
240 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
241 | while (1) { | ||
242 | cistpl_cftable_entry_t dflt = { 0 }; | ||
243 | cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); | ||
244 | if (pcmcia_get_tuple_data(link, &tuple) != 0 || | ||
245 | pcmcia_parse_tuple(link, &tuple, &parse) != 0) | ||
246 | goto next_entry; | ||
247 | |||
248 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; | ||
249 | if (cfg->index == 0) goto next_entry; | ||
250 | link->conf.ConfigIndex = cfg->index; | ||
251 | |||
252 | /* Does this card need audio output? */ | ||
253 | if (cfg->flags & CISTPL_CFTABLE_AUDIO) { | ||
254 | link->conf.Attributes |= CONF_ENABLE_SPKR; | ||
255 | link->conf.Status = CCSR_AUDIO_ENA; | ||
256 | } | ||
257 | |||
258 | /* Use power settings for Vcc and Vpp if present */ | ||
259 | /* Note that the CIS values need to be rescaled */ | ||
260 | if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
261 | link->conf.Vpp = | ||
262 | cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
263 | else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
264 | link->conf.Vpp = | ||
265 | dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
266 | |||
267 | /* Do we need to allocate an interrupt? */ | ||
268 | if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) | ||
269 | link->conf.Attributes |= CONF_ENABLE_IRQ; | ||
270 | |||
271 | /* IO window settings */ | ||
272 | link->io.NumPorts1 = link->io.NumPorts2 = 0; | ||
273 | if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { | ||
274 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; | ||
275 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
276 | if (!(io->flags & CISTPL_IO_8BIT)) | ||
277 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
278 | if (!(io->flags & CISTPL_IO_16BIT)) | ||
279 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
280 | link->io.BasePort1 = io->win[0].base; | ||
281 | link->io.NumPorts1 = io->win[0].len; | ||
282 | if (io->nwin > 1) { | ||
283 | link->io.Attributes2 = link->io.Attributes1; | ||
284 | link->io.BasePort2 = io->win[1].base; | ||
285 | link->io.NumPorts2 = io->win[1].len; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | /* This reserves IO space but doesn't actually enable it */ | ||
290 | if (pcmcia_request_io(link, &link->io) != 0) | ||
291 | goto next_entry; | ||
292 | |||
293 | /* | ||
294 | Now set up a common memory window, if needed. There is room | ||
295 | in the struct pcmcia_device structure for one memory window handle, | ||
296 | but if the base addresses need to be saved, or if multiple | ||
297 | windows are needed, the info should go in the private data | ||
298 | structure for this device. | ||
299 | |||
300 | Note that the memory window base is a physical address, and | ||
301 | needs to be mapped to virtual space with ioremap() before it | ||
302 | is used. | ||
303 | */ | ||
304 | if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { | ||
305 | cistpl_mem_t *mem = | ||
306 | (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; | ||
307 | req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; | ||
308 | req.Base = mem->win[0].host_addr; | ||
309 | req.Size = mem->win[0].len; | ||
310 | req.AccessSpeed = 0; | ||
311 | if (pcmcia_request_window(&link, &req, &link->win) != 0) | ||
312 | goto next_entry; | ||
313 | map.Page = 0; map.CardOffset = mem->win[0].card_addr; | ||
314 | if (pcmcia_map_mem_page(link->win, &map) != 0) | ||
315 | goto next_entry; | ||
316 | } | ||
317 | /* If we got this far, we're cool! */ | ||
318 | break; | ||
319 | |||
320 | next_entry: | ||
321 | CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); | ||
322 | } | ||
323 | |||
324 | /* | ||
325 | Allocate an interrupt line. Note that this does not assign a | ||
326 | handler to the interrupt, unless the 'Handler' member of the | ||
327 | irq structure is initialized. | ||
328 | */ | ||
329 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | 326 | if (link->conf.Attributes & CONF_ENABLE_IRQ) |
330 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); | 327 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); |
331 | 328 | ||
@@ -362,14 +359,17 @@ static int airo_config(struct pcmcia_device *link) | |||
362 | printk(" & 0x%04x-0x%04x", link->io.BasePort2, | 359 | printk(" & 0x%04x-0x%04x", link->io.BasePort2, |
363 | link->io.BasePort2+link->io.NumPorts2-1); | 360 | link->io.BasePort2+link->io.NumPorts2-1); |
364 | if (link->win) | 361 | if (link->win) |
365 | printk(", mem 0x%06lx-0x%06lx", req.Base, | 362 | printk(", mem 0x%06lx-0x%06lx", req->Base, |
366 | req.Base+req.Size-1); | 363 | req->Base+req->Size-1); |
367 | printk("\n"); | 364 | printk("\n"); |
365 | kfree(req); | ||
368 | return 0; | 366 | return 0; |
369 | 367 | ||
370 | cs_failed: | 368 | cs_failed: |
371 | cs_error(link, last_fn, last_ret); | 369 | cs_error(link, last_fn, last_ret); |
370 | failed: | ||
372 | airo_release(link); | 371 | airo_release(link); |
372 | kfree(req); | ||
373 | return -ENODEV; | 373 | return -ENODEV; |
374 | } /* airo_config */ | 374 | } /* airo_config */ |
375 | 375 | ||