aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hisax
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2008-07-29 02:38:55 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2008-08-22 19:21:27 -0400
commit5fcd4da0090828bd34a1956cb322a483c6bf163c (patch)
treeb26a14ab9ea94bfdc7815d62aa59aad77a6a1817 /drivers/isdn/hisax
parent0e6f9d2708409cd8e864cdb94edbe599872a19d1 (diff)
pcmcia: use pcmcia_loop_config in ISDN pcmcia drivers
Use the config loop helper in ISDN pcmcia drivers. CC: Karsten Keil <kkeil@suse.de> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/isdn/hisax')
-rw-r--r--drivers/isdn/hisax/avma1_cs.c76
-rw-r--r--drivers/isdn/hisax/elsa_cs.c73
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c208
-rw-r--r--drivers/isdn/hisax/teles_cs.c73
4 files changed, 168 insertions, 262 deletions
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index fc6cc2c065b8..8142d9fc8147 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -174,38 +174,28 @@ static void avma1cs_detach(struct pcmcia_device *link)
174 174
175======================================================================*/ 175======================================================================*/
176 176
177static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, 177static int avma1cs_configcheck(struct pcmcia_device *p_dev,
178 cisparse_t *parse) 178 cistpl_cftable_entry_t *cf,
179 void *priv_data)
179{ 180{
180 int i = pcmcia_get_tuple_data(handle, tuple); 181 if (cf->io.nwin <= 0)
181 if (i != CS_SUCCESS) return i; 182 return -ENODEV;
182 return pcmcia_parse_tuple(handle, tuple, parse); 183
184 p_dev->conf.ConfigIndex = cf->index;
185 p_dev->io.BasePort1 = cf->io.win[0].base;
186 p_dev->io.NumPorts1 = cf->io.win[0].len;
187 p_dev->io.NumPorts2 = 0;
188 printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
189 p_dev->io.BasePort1,
190 p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
191 return pcmcia_request_io(p_dev, &p_dev->io);
183} 192}
184 193
185static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
186 cisparse_t *parse)
187{
188 int i = pcmcia_get_first_tuple(handle, tuple);
189 if (i != CS_SUCCESS) return i;
190 return get_tuple(handle, tuple, parse);
191}
192
193static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
194 cisparse_t *parse)
195{
196 int i = pcmcia_get_next_tuple(handle, tuple);
197 if (i != CS_SUCCESS) return i;
198 return get_tuple(handle, tuple, parse);
199}
200 194
201static int avma1cs_config(struct pcmcia_device *link) 195static int avma1cs_config(struct pcmcia_device *link)
202{ 196{
203 tuple_t tuple;
204 cisparse_t parse;
205 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
206 local_info_t *dev; 197 local_info_t *dev;
207 int i; 198 int i;
208 u_char buf[64];
209 char devname[128]; 199 char devname[128];
210 IsdnCard_t icard; 200 IsdnCard_t icard;
211 int busy = 0; 201 int busy = 0;
@@ -214,40 +204,14 @@ static int avma1cs_config(struct pcmcia_device *link)
214 204
215 DEBUG(0, "avma1cs_config(0x%p)\n", link); 205 DEBUG(0, "avma1cs_config(0x%p)\n", link);
216 206
217 do { 207 devname[0] = 0;
218 devname[0] = 0; 208 if (link->prod_id[1])
219 if (link->prod_id[1]) 209 strlcpy(devname, link->prod_id[1], sizeof(devname));
220 strlcpy(devname, link->prod_id[1], sizeof(devname));
221 210
222 /* 211 if (pcmcia_loop_config(link, avma1cs_configcheck, NULL))
223 * find IO port 212 return -ENODEV;
224 */
225 tuple.TupleData = (cisdata_t *)buf;
226 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
227 tuple.Attributes = 0;
228 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
229 i = first_tuple(link, &tuple, &parse);
230 while (i == CS_SUCCESS) {
231 if (cf->io.nwin > 0) {
232 link->conf.ConfigIndex = cf->index;
233 link->io.BasePort1 = cf->io.win[0].base;
234 link->io.NumPorts1 = cf->io.win[0].len;
235 link->io.NumPorts2 = 0;
236 printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
237 link->io.BasePort1,
238 link->io.BasePort1+link->io.NumPorts1 - 1);
239 i = pcmcia_request_io(link, &link->io);
240 if (i == CS_SUCCESS) goto found_port;
241 }
242 i = next_tuple(link, &tuple, &parse);
243 }
244 213
245found_port: 214 do {
246 if (i != CS_SUCCESS) {
247 cs_error(link, RequestIO, i);
248 break;
249 }
250
251 /* 215 /*
252 * allocate an interrupt line 216 * allocate an interrupt line
253 */ 217 */
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index db7e64424afe..449800898dcf 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -203,68 +203,41 @@ static void elsa_cs_detach(struct pcmcia_device *link)
203 device available to the system. 203 device available to the system.
204 204
205======================================================================*/ 205======================================================================*/
206static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
207 cisparse_t *parse)
208{
209 int i = pcmcia_get_tuple_data(handle, tuple);
210 if (i != CS_SUCCESS) return i;
211 return pcmcia_parse_tuple(handle, tuple, parse);
212}
213
214static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
215 cisparse_t *parse)
216{
217 int i = pcmcia_get_first_tuple(handle, tuple);
218 if (i != CS_SUCCESS) return i;
219 return get_tuple(handle, tuple, parse);
220}
221 206
222static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, 207static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
223 cisparse_t *parse) 208 cistpl_cftable_entry_t *cf,
209 void *priv_data)
224{ 210{
225 int i = pcmcia_get_next_tuple(handle, tuple); 211 int j;
226 if (i != CS_SUCCESS) return i; 212
227 return get_tuple(handle, tuple, parse); 213 if ((cf->io.nwin > 0) && cf->io.win[0].base) {
214 printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
215 p_dev->conf.ConfigIndex = cf->index;
216 p_dev->io.BasePort1 = cf->io.win[0].base;
217 if (!pcmcia_request_io(p_dev, &p_dev->io))
218 return 0;
219 } else {
220 printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
221 p_dev->conf.ConfigIndex = cf->index;
222 for (j = 0x2f0; j > 0x100; j -= 0x10) {
223 p_dev->io.BasePort1 = j;
224 if (!pcmcia_request_io(p_dev, &p_dev->io))
225 return 0;
226 }
227 }
228 return -ENODEV;
228} 229}
229 230
230static int elsa_cs_config(struct pcmcia_device *link) 231static int elsa_cs_config(struct pcmcia_device *link)
231{ 232{
232 tuple_t tuple;
233 cisparse_t parse;
234 local_info_t *dev; 233 local_info_t *dev;
235 int i, j, last_fn; 234 int i, last_fn;
236 u_short buf[128];
237 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
238 IsdnCard_t icard; 235 IsdnCard_t icard;
239 236
240 DEBUG(0, "elsa_config(0x%p)\n", link); 237 DEBUG(0, "elsa_config(0x%p)\n", link);
241 dev = link->priv; 238 dev = link->priv;
242 239
243 tuple.TupleData = (cisdata_t *)buf; 240 i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
244 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
245 tuple.Attributes = 0;
246 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
247 i = first_tuple(link, &tuple, &parse);
248 while (i == CS_SUCCESS) {
249 if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
250 printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
251 link->conf.ConfigIndex = cf->index;
252 link->io.BasePort1 = cf->io.win[0].base;
253 i = pcmcia_request_io(link, &link->io);
254 if (i == CS_SUCCESS) break;
255 } else {
256 printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
257 link->conf.ConfigIndex = cf->index;
258 for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
259 link->io.BasePort1 = j;
260 i = pcmcia_request_io(link, &link->io);
261 if (i == CS_SUCCESS) break;
262 }
263 break;
264 }
265 i = next_tuple(link, &tuple, &parse);
266 }
267
268 if (i != CS_SUCCESS) { 241 if (i != CS_SUCCESS) {
269 last_fn = RequestIO; 242 last_fn = RequestIO;
270 goto cs_failed; 243 goto cs_failed;
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
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index ab4bd455450e..2b063a2916f4 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -193,68 +193,41 @@ static void teles_detach(struct pcmcia_device *link)
193 device available to the system. 193 device available to the system.
194 194
195======================================================================*/ 195======================================================================*/
196static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
197 cisparse_t *parse)
198{
199 int i = pcmcia_get_tuple_data(handle, tuple);
200 if (i != CS_SUCCESS) return i;
201 return pcmcia_parse_tuple(handle, tuple, parse);
202}
203
204static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
205 cisparse_t *parse)
206{
207 int i = pcmcia_get_first_tuple(handle, tuple);
208 if (i != CS_SUCCESS) return i;
209 return get_tuple(handle, tuple, parse);
210}
211 196
212static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, 197static int teles_cs_configcheck(struct pcmcia_device *p_dev,
213 cisparse_t *parse) 198 cistpl_cftable_entry_t *cf,
199 void *priv_data)
214{ 200{
215 int i = pcmcia_get_next_tuple(handle, tuple); 201 int j;
216 if (i != CS_SUCCESS) return i; 202
217 return get_tuple(handle, tuple, parse); 203 if ((cf->io.nwin > 0) && cf->io.win[0].base) {
204 printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
205 p_dev->conf.ConfigIndex = cf->index;
206 p_dev->io.BasePort1 = cf->io.win[0].base;
207 if (!pcmcia_request_io(p_dev, &p_dev->io))
208 return 0;
209 } else {
210 printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
211 p_dev->conf.ConfigIndex = cf->index;
212 for (j = 0x2f0; j > 0x100; j -= 0x10) {
213 p_dev->io.BasePort1 = j;
214 if (!pcmcia_request_io(p_dev, &p_dev->io))
215 return 0;
216 }
217 }
218 return -ENODEV;
218} 219}
219 220
220static int teles_cs_config(struct pcmcia_device *link) 221static int teles_cs_config(struct pcmcia_device *link)
221{ 222{
222 tuple_t tuple;
223 cisparse_t parse;
224 local_info_t *dev; 223 local_info_t *dev;
225 int i, j, last_fn; 224 int i, last_fn;
226 u_short buf[128];
227 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
228 IsdnCard_t icard; 225 IsdnCard_t icard;
229 226
230 DEBUG(0, "teles_config(0x%p)\n", link); 227 DEBUG(0, "teles_config(0x%p)\n", link);
231 dev = link->priv; 228 dev = link->priv;
232 229
233 tuple.TupleData = (cisdata_t *)buf; 230 i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
234 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
235 tuple.Attributes = 0;
236 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
237 i = first_tuple(link, &tuple, &parse);
238 while (i == CS_SUCCESS) {
239 if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
240 printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
241 link->conf.ConfigIndex = cf->index;
242 link->io.BasePort1 = cf->io.win[0].base;
243 i = pcmcia_request_io(link, &link->io);
244 if (i == CS_SUCCESS) break;
245 } else {
246 printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
247 link->conf.ConfigIndex = cf->index;
248 for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
249 link->io.BasePort1 = j;
250 i = pcmcia_request_io(link, &link->io);
251 if (i == CS_SUCCESS) break;
252 }
253 break;
254 }
255 i = next_tuple(link, &tuple, &parse);
256 }
257
258 if (i != CS_SUCCESS) { 231 if (i != CS_SUCCESS) {
259 last_fn = RequestIO; 232 last_fn = RequestIO;
260 goto cs_failed; 233 goto cs_failed;