aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/airo_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/airo_cs.c')
-rw-r--r--drivers/net/wireless/airo_cs.c222
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) \
207do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 207do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
208 208
209static 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
209static int airo_config(struct pcmcia_device *link) 289static 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