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