aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/pcnet_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcmcia/pcnet_cs.c')
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c86
1 files changed, 41 insertions, 45 deletions
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index ebc1ae6bcbe5..e40d6301aa7a 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -310,7 +310,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
310 req.Base = 0; req.Size = 0; 310 req.Base = 0; req.Size = 0;
311 req.AccessSpeed = 0; 311 req.AccessSpeed = 0;
312 i = pcmcia_request_window(&link, &req, &link->win); 312 i = pcmcia_request_window(&link, &req, &link->win);
313 if (i != CS_SUCCESS) { 313 if (i != 0) {
314 cs_error(link, RequestWindow, i); 314 cs_error(link, RequestWindow, i);
315 return NULL; 315 return NULL;
316 } 316 }
@@ -333,7 +333,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
333 333
334 iounmap(virt); 334 iounmap(virt);
335 j = pcmcia_release_window(link->win); 335 j = pcmcia_release_window(link->win);
336 if (j != CS_SUCCESS) 336 if (j != 0)
337 cs_error(link, ReleaseWindow, j); 337 cs_error(link, ReleaseWindow, j);
338 return (i < NR_INFO) ? hw_info+i : NULL; 338 return (i < NR_INFO) ? hw_info+i : NULL;
339} /* get_hwinfo */ 339} /* get_hwinfo */
@@ -504,7 +504,8 @@ static int try_io_port(struct pcmcia_device *link)
504 link->io.BasePort1 = j ^ 0x300; 504 link->io.BasePort1 = j ^ 0x300;
505 link->io.BasePort2 = (j ^ 0x300) + 0x10; 505 link->io.BasePort2 = (j ^ 0x300) + 0x10;
506 ret = pcmcia_request_io(link, &link->io); 506 ret = pcmcia_request_io(link, &link->io);
507 if (ret == CS_SUCCESS) return ret; 507 if (ret == 0)
508 return ret;
508 } 509 }
509 return ret; 510 return ret;
510 } else { 511 } else {
@@ -512,58 +513,53 @@ static int try_io_port(struct pcmcia_device *link)
512 } 513 }
513} 514}
514 515
516static int pcnet_confcheck(struct pcmcia_device *p_dev,
517 cistpl_cftable_entry_t *cfg,
518 cistpl_cftable_entry_t *dflt,
519 unsigned int vcc,
520 void *priv_data)
521{
522 int *has_shmem = priv_data;
523 int i;
524 cistpl_io_t *io = &cfg->io;
525
526 if (cfg->index == 0 || cfg->io.nwin == 0)
527 return -EINVAL;
528
529 /* For multifunction cards, by convention, we configure the
530 network function with window 0, and serial with window 1 */
531 if (io->nwin > 1) {
532 i = (io->win[1].len > io->win[0].len);
533 p_dev->io.BasePort2 = io->win[1-i].base;
534 p_dev->io.NumPorts2 = io->win[1-i].len;
535 } else {
536 i = p_dev->io.NumPorts2 = 0;
537 }
538
539 *has_shmem = ((cfg->mem.nwin == 1) &&
540 (cfg->mem.win[0].len >= 0x4000));
541 p_dev->io.BasePort1 = io->win[i].base;
542 p_dev->io.NumPorts1 = io->win[i].len;
543 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
544 if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
545 return try_io_port(p_dev);
546
547 return 0;
548}
549
515static int pcnet_config(struct pcmcia_device *link) 550static int pcnet_config(struct pcmcia_device *link)
516{ 551{
517 struct net_device *dev = link->priv; 552 struct net_device *dev = link->priv;
518 pcnet_dev_t *info = PRIV(dev); 553 pcnet_dev_t *info = PRIV(dev);
519 tuple_t tuple; 554 int last_ret, last_fn, start_pg, stop_pg, cm_offset;
520 cisparse_t parse;
521 int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
522 int has_shmem = 0; 555 int has_shmem = 0;
523 u_short buf[64];
524 hw_info_t *local_hw_info; 556 hw_info_t *local_hw_info;
525 DECLARE_MAC_BUF(mac); 557 DECLARE_MAC_BUF(mac);
526 558
527 DEBUG(0, "pcnet_config(0x%p)\n", link); 559 DEBUG(0, "pcnet_config(0x%p)\n", link);
528 560
529 tuple.TupleData = (cisdata_t *)buf; 561 last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
530 tuple.TupleDataMax = sizeof(buf); 562 if (last_ret) {
531 tuple.TupleOffset = 0;
532 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
533 tuple.Attributes = 0;
534 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
535 while (last_ret == CS_SUCCESS) {
536 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
537 cistpl_io_t *io = &(parse.cftable_entry.io);
538
539 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
540 pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
541 cfg->index == 0 || cfg->io.nwin == 0)
542 goto next_entry;
543
544 link->conf.ConfigIndex = cfg->index;
545 /* For multifunction cards, by convention, we configure the
546 network function with window 0, and serial with window 1 */
547 if (io->nwin > 1) {
548 i = (io->win[1].len > io->win[0].len);
549 link->io.BasePort2 = io->win[1-i].base;
550 link->io.NumPorts2 = io->win[1-i].len;
551 } else {
552 i = link->io.NumPorts2 = 0;
553 }
554 has_shmem = ((cfg->mem.nwin == 1) &&
555 (cfg->mem.win[0].len >= 0x4000));
556 link->io.BasePort1 = io->win[i].base;
557 link->io.NumPorts1 = io->win[i].len;
558 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
559 if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
560 last_ret = try_io_port(link);
561 if (last_ret == CS_SUCCESS) break;
562 }
563 next_entry:
564 last_ret = pcmcia_get_next_tuple(link, &tuple);
565 }
566 if (last_ret != CS_SUCCESS) {
567 cs_error(link, RequestIO, last_ret); 563 cs_error(link, RequestIO, last_ret);
568 goto failed; 564 goto failed;
569 } 565 }