aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hisax/sedlbauer_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/hisax/sedlbauer_cs.c')
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c208
1 files changed, 102 insertions, 106 deletions
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 439cb530def8..0f80b5667ea1 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -217,101 +217,68 @@ static void sedlbauer_detach(struct pcmcia_device *link)
217#define CS_CHECK(fn, ret) \ 217#define CS_CHECK(fn, ret) \
218do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 218do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
219 219
220static int sedlbauer_config(struct pcmcia_device *link) 220struct sedlbauer_config_data {
221{ 221 cistpl_cftable_entry_t dflt;
222 local_info_t *dev = link->priv; 222 config_info_t conf;
223 tuple_t tuple; 223 win_req_t req;
224 cisparse_t parse; 224};
225 int last_fn, last_ret;
226 u8 buf[64];
227 config_info_t conf;
228 win_req_t req;
229 memreq_t map;
230 IsdnCard_t icard;
231
232 DEBUG(0, "sedlbauer_config(0x%p)\n", link);
233
234 tuple.Attributes = 0;
235 tuple.TupleData = buf;
236 tuple.TupleDataMax = sizeof(buf);
237 tuple.TupleOffset = 0;
238 225
239 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); 226static int sedlbauer_config_check(struct pcmcia_device *p_dev,
227 cistpl_cftable_entry_t *cfg,
228 void *priv_data)
229{
230 struct sedlbauer_config_data *cfg_mem = priv_data;
240 231
241 /* 232 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
242 In this loop, we scan the CIS for configuration table entries, 233 cfg_mem->dflt = *cfg;
243 each of which describes a valid card configuration, including 234 if (cfg->index == 0)
244 voltage, IO window, memory window, and interrupt settings. 235 return -ENODEV;
236 p_dev->conf.ConfigIndex = cfg->index;
245 237
246 We make no assumptions about the card to be configured: we use
247 just the information available in the CIS. In an ideal world,
248 this would work for any PCMCIA card, but it requires a complete
249 and accurate CIS. In practice, a driver usually "knows" most of
250 these things without consulting the CIS, and most client drivers
251 will only use the CIS to fill in implementation-defined details.
252 */
253 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
254 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
255 while (1) {
256 cistpl_cftable_entry_t dflt = { 0 };
257 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
258 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
259 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
260 goto next_entry;
261
262 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
263 if (cfg->index == 0) goto next_entry;
264 link->conf.ConfigIndex = cfg->index;
265
266 /* Does this card need audio output? */ 238 /* Does this card need audio output? */
267 if (cfg->flags & CISTPL_CFTABLE_AUDIO) { 239 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
268 link->conf.Attributes |= CONF_ENABLE_SPKR; 240 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
269 link->conf.Status = CCSR_AUDIO_ENA; 241 p_dev->conf.Status = CCSR_AUDIO_ENA;
270 } 242 }
271 243
272 /* Use power settings for Vcc and Vpp if present */ 244 /* Use power settings for Vcc and Vpp if present */
273 /* Note that the CIS values need to be rescaled */ 245 /* Note that the CIS values need to be rescaled */
274 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { 246 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
275 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) 247 if (cfg_mem->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
276 goto next_entry; 248 return -ENODEV;
277 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { 249 } else if (cfg_mem->dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
278 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) 250 if (cfg_mem->conf.Vcc != cfg_mem->dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
279 goto next_entry; 251 return -ENODEV;
280 } 252 }
281 253
282 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) 254 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
283 link->conf.Vpp = 255 p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
284 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; 256 else if (cfg_mem->dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
285 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) 257 p_dev->conf.Vpp = cfg_mem->dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
286 link->conf.Vpp = 258
287 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
288
289 /* Do we need to allocate an interrupt? */ 259 /* Do we need to allocate an interrupt? */
290 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) 260 if (cfg->irq.IRQInfo1 || cfg_mem->dflt.irq.IRQInfo1)
291 link->conf.Attributes |= CONF_ENABLE_IRQ; 261 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
292 262
293 /* IO window settings */ 263 /* IO window settings */
294 link->io.NumPorts1 = link->io.NumPorts2 = 0; 264 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
295 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 265 if ((cfg->io.nwin > 0) || (cfg_mem->dflt.io.nwin > 0)) {
296 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; 266 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &cfg_mem->dflt.io;
297 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 267 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
298 if (!(io->flags & CISTPL_IO_8BIT)) 268 if (!(io->flags & CISTPL_IO_8BIT))
299 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; 269 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
300 if (!(io->flags & CISTPL_IO_16BIT)) 270 if (!(io->flags & CISTPL_IO_16BIT))
301 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 271 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
302/* new in dummy.cs 2001/01/28 MN 272 p_dev->io.BasePort1 = io->win[0].base;
303 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; 273 p_dev->io.NumPorts1 = io->win[0].len;
304*/ 274 if (io->nwin > 1) {
305 link->io.BasePort1 = io->win[0].base; 275 p_dev->io.Attributes2 = p_dev->io.Attributes1;
306 link->io.NumPorts1 = io->win[0].len; 276 p_dev->io.BasePort2 = io->win[1].base;
307 if (io->nwin > 1) { 277 p_dev->io.NumPorts2 = io->win[1].len;
308 link->io.Attributes2 = link->io.Attributes1; 278 }
309 link->io.BasePort2 = io->win[1].base; 279 /* This reserves IO space but doesn't actually enable it */
310 link->io.NumPorts2 = io->win[1].len; 280 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
311 } 281 return -ENODEV;
312 /* This reserves IO space but doesn't actually enable it */
313 if (pcmcia_request_io(link, &link->io) != 0)
314 goto next_entry;
315 } 282 }
316 283
317 /* 284 /*
@@ -325,30 +292,58 @@ static int sedlbauer_config(struct pcmcia_device *link)
325 needs to be mapped to virtual space with ioremap() before it 292 needs to be mapped to virtual space with ioremap() before it
326 is used. 293 is used.
327 */ 294 */
328 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { 295 if ((cfg->mem.nwin > 0) || (cfg_mem->dflt.mem.nwin > 0)) {
329 cistpl_mem_t *mem = 296 cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &cfg_mem->dflt.mem;
330 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; 297 memreq_t map;
331 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; 298 cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
332 req.Attributes |= WIN_ENABLE; 299 cfg_mem->req.Attributes |= WIN_ENABLE;
333 req.Base = mem->win[0].host_addr; 300 cfg_mem->req.Base = mem->win[0].host_addr;
334 req.Size = mem->win[0].len; 301 cfg_mem->req.Size = mem->win[0].len;
335/* new in dummy.cs 2001/01/28 MN 302 cfg_mem->req.AccessSpeed = 0;
336 if (req.Size < 0x1000) 303 if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0)
337 req.Size = 0x1000; 304 return -ENODEV;
338*/ 305 map.Page = 0;
339 req.AccessSpeed = 0; 306 map.CardOffset = mem->win[0].card_addr;
340 if (pcmcia_request_window(&link, &req, &link->win) != 0) 307 if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
341 goto next_entry; 308 return -ENODEV;
342 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
343 if (pcmcia_map_mem_page(link->win, &map) != 0)
344 goto next_entry;
345 } 309 }
346 /* If we got this far, we're cool! */ 310 return 0;
347 break; 311}
348 312
349 next_entry: 313
350 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); 314
351 } 315static int sedlbauer_config(struct pcmcia_device *link)
316{
317 local_info_t *dev = link->priv;
318 struct sedlbauer_config_data *cfg_mem;
319 int last_fn, last_ret;
320 IsdnCard_t icard;
321
322 DEBUG(0, "sedlbauer_config(0x%p)\n", link);
323
324 cfg_mem = kzalloc(sizeof(struct sedlbauer_config_data), GFP_KERNEL);
325 if (!cfg_mem)
326 return -ENOMEM;
327
328 /* Look up the current Vcc */
329 CS_CHECK(GetConfigurationInfo,
330 pcmcia_get_configuration_info(link, &cfg_mem->conf));
331
332 /*
333 In this loop, we scan the CIS for configuration table entries,
334 each of which describes a valid card configuration, including
335 voltage, IO window, memory window, and interrupt settings.
336
337 We make no assumptions about the card to be configured: we use
338 just the information available in the CIS. In an ideal world,
339 this would work for any PCMCIA card, but it requires a complete
340 and accurate CIS. In practice, a driver usually "knows" most of
341 these things without consulting the CIS, and most client drivers
342 will only use the CIS to fill in implementation-defined details.
343 */
344 last_ret = pcmcia_loop_config(link, sedlbauer_config_check, cfg_mem);
345 if (last_ret)
346 goto failed;
352 347
353 /* 348 /*
354 Allocate an interrupt line. Note that this does not assign a 349 Allocate an interrupt line. Note that this does not assign a
@@ -387,8 +382,8 @@ static int sedlbauer_config(struct pcmcia_device *link)
387 printk(" & 0x%04x-0x%04x", link->io.BasePort2, 382 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
388 link->io.BasePort2+link->io.NumPorts2-1); 383 link->io.BasePort2+link->io.NumPorts2-1);
389 if (link->win) 384 if (link->win)
390 printk(", mem 0x%06lx-0x%06lx", req.Base, 385 printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base,
391 req.Base+req.Size-1); 386 cfg_mem->req.Base+cfg_mem->req.Size-1);
392 printk("\n"); 387 printk("\n");
393 388
394 icard.para[0] = link->irq.AssignedIRQ; 389 icard.para[0] = link->irq.AssignedIRQ;
@@ -409,6 +404,7 @@ static int sedlbauer_config(struct pcmcia_device *link)
409 404
410cs_failed: 405cs_failed:
411 cs_error(link, last_fn, last_ret); 406 cs_error(link, last_fn, last_ret);
407failed:
412 sedlbauer_release(link); 408 sedlbauer_release(link);
413 return -ENODEV; 409 return -ENODEV;
414 410