diff options
Diffstat (limited to 'drivers/net/pcmcia/axnet_cs.c')
-rw-r--r-- | drivers/net/pcmcia/axnet_cs.c | 80 |
1 files changed, 36 insertions, 44 deletions
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 52bf11b73c6e..b37a498939ae 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
@@ -262,7 +262,7 @@ static int try_io_port(struct pcmcia_device *link) | |||
262 | if (link->io.NumPorts2 > 0) { | 262 | if (link->io.NumPorts2 > 0) { |
263 | /* for master/slave multifunction cards */ | 263 | /* for master/slave multifunction cards */ |
264 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 264 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
265 | link->irq.Attributes = | 265 | link->irq.Attributes = |
266 | IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; | 266 | IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; |
267 | } | 267 | } |
268 | } else { | 268 | } else { |
@@ -276,7 +276,8 @@ static int try_io_port(struct pcmcia_device *link) | |||
276 | link->io.BasePort1 = j ^ 0x300; | 276 | link->io.BasePort1 = j ^ 0x300; |
277 | link->io.BasePort2 = (j ^ 0x300) + 0x10; | 277 | link->io.BasePort2 = (j ^ 0x300) + 0x10; |
278 | ret = pcmcia_request_io(link, &link->io); | 278 | ret = pcmcia_request_io(link, &link->io); |
279 | if (ret == CS_SUCCESS) return ret; | 279 | if (ret == 0) |
280 | return ret; | ||
280 | } | 281 | } |
281 | return ret; | 282 | return ret; |
282 | } else { | 283 | } else { |
@@ -284,59 +285,50 @@ static int try_io_port(struct pcmcia_device *link) | |||
284 | } | 285 | } |
285 | } | 286 | } |
286 | 287 | ||
288 | static int axnet_configcheck(struct pcmcia_device *p_dev, | ||
289 | cistpl_cftable_entry_t *cfg, | ||
290 | cistpl_cftable_entry_t *dflt, | ||
291 | unsigned int vcc, | ||
292 | void *priv_data) | ||
293 | { | ||
294 | int i; | ||
295 | cistpl_io_t *io = &cfg->io; | ||
296 | |||
297 | if (cfg->index == 0 || cfg->io.nwin == 0) | ||
298 | return -ENODEV; | ||
299 | |||
300 | p_dev->conf.ConfigIndex = 0x05; | ||
301 | /* For multifunction cards, by convention, we configure the | ||
302 | network function with window 0, and serial with window 1 */ | ||
303 | if (io->nwin > 1) { | ||
304 | i = (io->win[1].len > io->win[0].len); | ||
305 | p_dev->io.BasePort2 = io->win[1-i].base; | ||
306 | p_dev->io.NumPorts2 = io->win[1-i].len; | ||
307 | } else { | ||
308 | i = p_dev->io.NumPorts2 = 0; | ||
309 | } | ||
310 | p_dev->io.BasePort1 = io->win[i].base; | ||
311 | p_dev->io.NumPorts1 = io->win[i].len; | ||
312 | p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | ||
313 | if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) | ||
314 | return try_io_port(p_dev); | ||
315 | |||
316 | return -ENODEV; | ||
317 | } | ||
318 | |||
287 | static int axnet_config(struct pcmcia_device *link) | 319 | static int axnet_config(struct pcmcia_device *link) |
288 | { | 320 | { |
289 | struct net_device *dev = link->priv; | 321 | struct net_device *dev = link->priv; |
290 | axnet_dev_t *info = PRIV(dev); | 322 | axnet_dev_t *info = PRIV(dev); |
291 | tuple_t tuple; | ||
292 | cisparse_t parse; | ||
293 | int i, j, last_ret, last_fn; | 323 | int i, j, last_ret, last_fn; |
294 | u_short buf[64]; | ||
295 | DECLARE_MAC_BUF(mac); | 324 | DECLARE_MAC_BUF(mac); |
296 | 325 | ||
297 | DEBUG(0, "axnet_config(0x%p)\n", link); | 326 | DEBUG(0, "axnet_config(0x%p)\n", link); |
298 | 327 | ||
299 | tuple.Attributes = 0; | ||
300 | tuple.TupleData = (cisdata_t *)buf; | ||
301 | tuple.TupleDataMax = sizeof(buf); | ||
302 | tuple.TupleOffset = 0; | ||
303 | |||
304 | /* don't trust the CIS on this; Linksys got it wrong */ | 328 | /* don't trust the CIS on this; Linksys got it wrong */ |
305 | link->conf.Present = 0x63; | 329 | link->conf.Present = 0x63; |
306 | 330 | last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL); | |
307 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 331 | if (last_ret != 0) { |
308 | tuple.Attributes = 0; | ||
309 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
310 | while (last_ret == CS_SUCCESS) { | ||
311 | cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); | ||
312 | cistpl_io_t *io = &(parse.cftable_entry.io); | ||
313 | |||
314 | if (pcmcia_get_tuple_data(link, &tuple) != 0 || | ||
315 | pcmcia_parse_tuple(link, &tuple, &parse) != 0 || | ||
316 | cfg->index == 0 || cfg->io.nwin == 0) | ||
317 | goto next_entry; | ||
318 | |||
319 | link->conf.ConfigIndex = 0x05; | ||
320 | /* For multifunction cards, by convention, we configure the | ||
321 | network function with window 0, and serial with window 1 */ | ||
322 | if (io->nwin > 1) { | ||
323 | i = (io->win[1].len > io->win[0].len); | ||
324 | link->io.BasePort2 = io->win[1-i].base; | ||
325 | link->io.NumPorts2 = io->win[1-i].len; | ||
326 | } else { | ||
327 | i = link->io.NumPorts2 = 0; | ||
328 | } | ||
329 | link->io.BasePort1 = io->win[i].base; | ||
330 | link->io.NumPorts1 = io->win[i].len; | ||
331 | link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | ||
332 | if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { | ||
333 | last_ret = try_io_port(link); | ||
334 | if (last_ret == CS_SUCCESS) break; | ||
335 | } | ||
336 | next_entry: | ||
337 | last_ret = pcmcia_get_next_tuple(link, &tuple); | ||
338 | } | ||
339 | if (last_ret != CS_SUCCESS) { | ||
340 | cs_error(link, RequestIO, last_ret); | 332 | cs_error(link, RequestIO, last_ret); |
341 | goto failed; | 333 | goto failed; |
342 | } | 334 | } |