diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2008-07-29 02:38:55 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2008-08-22 19:21:27 -0400 |
commit | 5fcd4da0090828bd34a1956cb322a483c6bf163c (patch) | |
tree | b26a14ab9ea94bfdc7815d62aa59aad77a6a1817 /drivers/isdn/hisax | |
parent | 0e6f9d2708409cd8e864cdb94edbe599872a19d1 (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.c | 76 | ||||
-rw-r--r-- | drivers/isdn/hisax/elsa_cs.c | 73 | ||||
-rw-r--r-- | drivers/isdn/hisax/sedlbauer_cs.c | 208 | ||||
-rw-r--r-- | drivers/isdn/hisax/teles_cs.c | 73 |
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 | ||
177 | static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, | 177 | static 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 | ||
185 | static 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 | |||
193 | static 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 | ||
201 | static int avma1cs_config(struct pcmcia_device *link) | 195 | static 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 | ||
245 | found_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 | ======================================================================*/ |
206 | static 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 | |||
214 | static 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 | ||
222 | static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, | 207 | static 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 | ||
230 | static int elsa_cs_config(struct pcmcia_device *link) | 231 | static 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) \ |
218 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 218 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
219 | 219 | ||
220 | static int sedlbauer_config(struct pcmcia_device *link) | 220 | struct 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)); | 226 | static 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 | } | 315 | static 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 | ||
410 | cs_failed: | 405 | cs_failed: |
411 | cs_error(link, last_fn, last_ret); | 406 | cs_error(link, last_fn, last_ret); |
407 | failed: | ||
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 | ======================================================================*/ |
196 | static 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 | |||
204 | static 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 | ||
212 | static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, | 197 | static 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 | ||
220 | static int teles_cs_config(struct pcmcia_device *link) | 221 | static 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; |