aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2008-08-02 08:28:43 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2008-08-22 19:21:28 -0400
commitb54bf94bf91e4ca2a489eb02bca0424ddb55242a (patch)
tree4a5383d29173e24dd1fe71ce3ee4d010e60f391c
parent5fcd4da0090828bd34a1956cb322a483c6bf163c (diff)
pcmcia: use pcmcia_loop_config in net pcmcia drivers
Use the config loop helper in (some) net pcmcia drivers. CC: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r--drivers/net/pcmcia/axnet_cs.c71
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c79
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c96
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c73
-rw-r--r--drivers/net/wireless/airo_cs.c230
-rw-r--r--drivers/net/wireless/atmel_cs.c123
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c227
-rw-r--r--drivers/net/wireless/orinoco_cs.c176
-rw-r--r--drivers/net/wireless/spectrum_cs.c175
9 files changed, 596 insertions, 654 deletions
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 3f682d49a4e6..04ece0b77d1d 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -284,58 +284,47 @@ static int try_io_port(struct pcmcia_device *link)
284 } 284 }
285} 285}
286 286
287static int axnet_configcheck(struct pcmcia_device *p_dev,
288 cistpl_cftable_entry_t *cfg,
289 void *priv_data)
290{
291 int i;
292 cistpl_io_t *io = &cfg->io;
293
294 if (cfg->index == 0 || cfg->io.nwin == 0)
295 return -ENODEV;
296
297 p_dev->conf.ConfigIndex = 0x05;
298 /* For multifunction cards, by convention, we configure the
299 network function with window 0, and serial with window 1 */
300 if (io->nwin > 1) {
301 i = (io->win[1].len > io->win[0].len);
302 p_dev->io.BasePort2 = io->win[1-i].base;
303 p_dev->io.NumPorts2 = io->win[1-i].len;
304 } else {
305 i = p_dev->io.NumPorts2 = 0;
306 }
307 p_dev->io.BasePort1 = io->win[i].base;
308 p_dev->io.NumPorts1 = io->win[i].len;
309 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
310 if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
311 return try_io_port(p_dev);
312
313 return -ENODEV;
314}
315
287static int axnet_config(struct pcmcia_device *link) 316static int axnet_config(struct pcmcia_device *link)
288{ 317{
289 struct net_device *dev = link->priv; 318 struct net_device *dev = link->priv;
290 axnet_dev_t *info = PRIV(dev); 319 axnet_dev_t *info = PRIV(dev);
291 tuple_t tuple;
292 cisparse_t parse;
293 int i, j, last_ret, last_fn; 320 int i, j, last_ret, last_fn;
294 u_short buf[64];
295 DECLARE_MAC_BUF(mac); 321 DECLARE_MAC_BUF(mac);
296 322
297 DEBUG(0, "axnet_config(0x%p)\n", link); 323 DEBUG(0, "axnet_config(0x%p)\n", link);
298 324
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 */ 325 /* don't trust the CIS on this; Linksys got it wrong */
305 link->conf.Present = 0x63; 326 link->conf.Present = 0x63;
306 327 last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
307 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
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) { 328 if (last_ret != CS_SUCCESS) {
340 cs_error(link, RequestIO, last_ret); 329 cs_error(link, RequestIO, last_ret);
341 goto failed; 330 goto failed;
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 2d4c4ad89b8d..7a9eeca6adc2 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -512,58 +512,53 @@ static int try_io_port(struct pcmcia_device *link)
512 } 512 }
513} 513}
514 514
515static int pcnet_confcheck(struct pcmcia_device *p_dev,
516 cistpl_cftable_entry_t *cfg,
517 void *priv_data)
518{
519 int *has_shmem = priv_data;
520 int i;
521 cistpl_io_t *io = &cfg->io;
522
523 if (cfg->index == 0 || cfg->io.nwin == 0)
524 return -EINVAL;
525
526 p_dev->conf.ConfigIndex = cfg->index;
527
528 /* For multifunction cards, by convention, we configure the
529 network function with window 0, and serial with window 1 */
530 if (io->nwin > 1) {
531 i = (io->win[1].len > io->win[0].len);
532 p_dev->io.BasePort2 = io->win[1-i].base;
533 p_dev->io.NumPorts2 = io->win[1-i].len;
534 } else {
535 i = p_dev->io.NumPorts2 = 0;
536 }
537
538 *has_shmem = ((cfg->mem.nwin == 1) &&
539 (cfg->mem.win[0].len >= 0x4000));
540 p_dev->io.BasePort1 = io->win[i].base;
541 p_dev->io.NumPorts1 = io->win[i].len;
542 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
543 if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
544 return try_io_port(p_dev);
545
546 return 0;
547}
548
515static int pcnet_config(struct pcmcia_device *link) 549static int pcnet_config(struct pcmcia_device *link)
516{ 550{
517 struct net_device *dev = link->priv; 551 struct net_device *dev = link->priv;
518 pcnet_dev_t *info = PRIV(dev); 552 pcnet_dev_t *info = PRIV(dev);
519 tuple_t tuple; 553 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; 554 int has_shmem = 0;
523 u_short buf[64];
524 hw_info_t *local_hw_info; 555 hw_info_t *local_hw_info;
525 DECLARE_MAC_BUF(mac); 556 DECLARE_MAC_BUF(mac);
526 557
527 DEBUG(0, "pcnet_config(0x%p)\n", link); 558 DEBUG(0, "pcnet_config(0x%p)\n", link);
528 559
529 tuple.TupleData = (cisdata_t *)buf; 560 last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
530 tuple.TupleDataMax = sizeof(buf); 561 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); 562 cs_error(link, RequestIO, last_ret);
568 goto failed; 563 goto failed;
569 } 564 }
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 250eb1954c34..c012e3400736 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -459,28 +459,36 @@ static int mhz_3288_power(struct pcmcia_device *link)
459 return 0; 459 return 0;
460} 460}
461 461
462static int mhz_mfc_config_check(struct pcmcia_device *p_dev,
463 cistpl_cftable_entry_t *cf,
464 void *priv_data)
465{
466 int k;
467 p_dev->conf.ConfigIndex = cf->index;
468 p_dev->io.BasePort2 = cf->io.win[0].base;
469 for (k = 0; k < 0x400; k += 0x10) {
470 if (k & 0x80)
471 continue;
472 p_dev->io.BasePort1 = k ^ 0x300;
473 if (!pcmcia_request_io(p_dev, &p_dev->io))
474 return 0;
475 }
476 return -ENODEV;
477}
478
462static int mhz_mfc_config(struct pcmcia_device *link) 479static int mhz_mfc_config(struct pcmcia_device *link)
463{ 480{
464 struct net_device *dev = link->priv; 481 struct net_device *dev = link->priv;
465 struct smc_private *smc = netdev_priv(dev); 482 struct smc_private *smc = netdev_priv(dev);
466 struct smc_cfg_mem *cfg_mem; 483 struct smc_cfg_mem *cfg_mem;
467 tuple_t *tuple;
468 cisparse_t *parse;
469 cistpl_cftable_entry_t *cf;
470 u_char *buf;
471 win_req_t req; 484 win_req_t req;
472 memreq_t mem; 485 memreq_t mem;
473 int i, k; 486 int i;
474 487
475 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); 488 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
476 if (!cfg_mem) 489 if (!cfg_mem)
477 return CS_OUT_OF_RESOURCE; 490 return CS_OUT_OF_RESOURCE;
478 491
479 tuple = &cfg_mem->tuple;
480 parse = &cfg_mem->parse;
481 cf = &parse->cftable_entry;
482 buf = cfg_mem->buf;
483
484 link->conf.Attributes |= CONF_ENABLE_SPKR; 492 link->conf.Attributes |= CONF_ENABLE_SPKR;
485 link->conf.Status = CCSR_AUDIO_ENA; 493 link->conf.Status = CCSR_AUDIO_ENA;
486 link->irq.Attributes = 494 link->irq.Attributes =
@@ -489,27 +497,9 @@ static int mhz_mfc_config(struct pcmcia_device *link)
489 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; 497 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
490 link->io.NumPorts2 = 8; 498 link->io.NumPorts2 = 8;
491 499
492 tuple->Attributes = tuple->TupleOffset = 0;
493 tuple->TupleData = (cisdata_t *)buf;
494 tuple->TupleDataMax = 255;
495 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
496
497 i = first_tuple(link, tuple, parse);
498 /* The Megahertz combo cards have modem-like CIS entries, so 500 /* The Megahertz combo cards have modem-like CIS entries, so
499 we have to explicitly try a bunch of port combinations. */ 501 we have to explicitly try a bunch of port combinations. */
500 while (i == CS_SUCCESS) { 502 if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
501 link->conf.ConfigIndex = cf->index;
502 link->io.BasePort2 = cf->io.win[0].base;
503 for (k = 0; k < 0x400; k += 0x10) {
504 if (k & 0x80) continue;
505 link->io.BasePort1 = k ^ 0x300;
506 i = pcmcia_request_io(link, &link->io);
507 if (i == CS_SUCCESS) break;
508 }
509 if (i == CS_SUCCESS) break;
510 i = next_tuple(link, tuple, parse);
511 }
512 if (i != CS_SUCCESS)
513 goto free_cfg_mem; 503 goto free_cfg_mem;
514 dev->base_addr = link->io.BasePort1; 504 dev->base_addr = link->io.BasePort1;
515 505
@@ -533,7 +523,7 @@ static int mhz_mfc_config(struct pcmcia_device *link)
533 523
534free_cfg_mem: 524free_cfg_mem:
535 kfree(cfg_mem); 525 kfree(cfg_mem);
536 return i; 526 return -ENODEV;
537} 527}
538 528
539static int mhz_setup(struct pcmcia_device *link) 529static int mhz_setup(struct pcmcia_device *link)
@@ -660,46 +650,26 @@ static int mot_setup(struct pcmcia_device *link)
660 650
661/*====================================================================*/ 651/*====================================================================*/
662 652
653static int smc_configcheck(struct pcmcia_device *p_dev,
654 cistpl_cftable_entry_t *cf,
655 void *priv_data)
656{
657 p_dev->conf.ConfigIndex = cf->index;
658 p_dev->io.BasePort1 = cf->io.win[0].base;
659 p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
660 return pcmcia_request_io(p_dev, &p_dev->io);
661}
662
663static int smc_config(struct pcmcia_device *link) 663static int smc_config(struct pcmcia_device *link)
664{ 664{
665 struct net_device *dev = link->priv; 665 struct net_device *dev = link->priv;
666 struct smc_cfg_mem *cfg_mem;
667 tuple_t *tuple;
668 cisparse_t *parse;
669 cistpl_cftable_entry_t *cf;
670 u_char *buf;
671 int i; 666 int i;
672 667
673 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
674 if (!cfg_mem)
675 return CS_OUT_OF_RESOURCE;
676
677 tuple = &cfg_mem->tuple;
678 parse = &cfg_mem->parse;
679 cf = &parse->cftable_entry;
680 buf = cfg_mem->buf;
681
682 tuple->Attributes = tuple->TupleOffset = 0;
683 tuple->TupleData = (cisdata_t *)buf;
684 tuple->TupleDataMax = 255;
685 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
686
687 link->io.NumPorts1 = 16; 668 link->io.NumPorts1 = 16;
688 i = first_tuple(link, tuple, parse); 669 i = pcmcia_loop_config(link, smc_configcheck, NULL);
689 while (i != CS_NO_MORE_ITEMS) { 670 if (!i)
690 if (i == CS_SUCCESS) { 671 dev->base_addr = link->io.BasePort1;
691 link->conf.ConfigIndex = cf->index;
692 link->io.BasePort1 = cf->io.win[0].base;
693 link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
694 i = pcmcia_request_io(link, &link->io);
695 if (i == CS_SUCCESS) break;
696 }
697 i = next_tuple(link, tuple, parse);
698 }
699 if (i == CS_SUCCESS)
700 dev->base_addr = link->io.BasePort1;
701 672
702 kfree(cfg_mem);
703 return i; 673 return i;
704} 674}
705 675
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index f6c4698ce738..b57f022952b4 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -715,6 +715,45 @@ has_ce2_string(struct pcmcia_device * p_dev)
715 return 0; 715 return 0;
716} 716}
717 717
718static int
719xirc2ps_config_modem(struct pcmcia_device *p_dev,
720 cistpl_cftable_entry_t *cf,
721 void *priv_data)
722{
723 unsigned int ioaddr;
724
725 if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
726 for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
727 p_dev->conf.ConfigIndex = cf->index ;
728 p_dev->io.BasePort2 = cf->io.win[0].base;
729 p_dev->io.BasePort1 = ioaddr;
730 if (!pcmcia_request_io(p_dev, &p_dev->io))
731 return 0;
732 }
733 }
734 return -ENODEV;
735}
736
737static int
738xirc2ps_config_check(struct pcmcia_device *p_dev,
739 cistpl_cftable_entry_t *cf,
740 void *priv_data)
741{
742 int *pass = priv_data;
743
744 if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
745 p_dev->conf.ConfigIndex = cf->index ;
746 p_dev->io.BasePort2 = cf->io.win[0].base;
747 p_dev->io.BasePort1 = p_dev->io.BasePort2
748 + (*pass ? (cf->index & 0x20 ? -24:8)
749 : (cf->index & 0x20 ? 8:-24));
750 if (!pcmcia_request_io(p_dev, &p_dev->io))
751 return 0;
752 }
753 return -ENODEV;
754
755}
756
718/**************** 757/****************
719 * xirc2ps_config() is scheduled to run after a CARD_INSERTION event 758 * xirc2ps_config() is scheduled to run after a CARD_INSERTION event
720 * is received, to configure the PCMCIA socket, and to make the 759 * is received, to configure the PCMCIA socket, and to make the
@@ -725,13 +764,12 @@ xirc2ps_config(struct pcmcia_device * link)
725{ 764{
726 struct net_device *dev = link->priv; 765 struct net_device *dev = link->priv;
727 local_info_t *local = netdev_priv(dev); 766 local_info_t *local = netdev_priv(dev);
767 unsigned int ioaddr;
728 tuple_t tuple; 768 tuple_t tuple;
729 cisparse_t parse; 769 cisparse_t parse;
730 unsigned int ioaddr;
731 int err, i; 770 int err, i;
732 u_char buf[64]; 771 u_char buf[64];
733 cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data; 772 cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
734 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
735 DECLARE_MAC_BUF(mac); 773 DECLARE_MAC_BUF(mac);
736 774
737 local->dingo_ccr = NULL; 775 local->dingo_ccr = NULL;
@@ -846,19 +884,8 @@ xirc2ps_config(struct pcmcia_device * link)
846 /* Take the Modem IO port from the CIS and scan for a free 884 /* Take the Modem IO port from the CIS and scan for a free
847 * Ethernet port */ 885 * Ethernet port */
848 link->io.NumPorts1 = 16; /* no Mako stuff anymore */ 886 link->io.NumPorts1 = 16; /* no Mako stuff anymore */
849 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 887 if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
850 for (err = first_tuple(link, &tuple, &parse); !err; 888 goto port_found;
851 err = next_tuple(link, &tuple, &parse)) {
852 if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
853 for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
854 link->conf.ConfigIndex = cf->index ;
855 link->io.BasePort2 = cf->io.win[0].base;
856 link->io.BasePort1 = ioaddr;
857 if (!(err=pcmcia_request_io(link, &link->io)))
858 goto port_found;
859 }
860 }
861 }
862 } else { 889 } else {
863 link->io.NumPorts1 = 18; 890 link->io.NumPorts1 = 18;
864 /* We do 2 passes here: The first one uses the regular mapping and 891 /* We do 2 passes here: The first one uses the regular mapping and
@@ -866,21 +893,9 @@ xirc2ps_config(struct pcmcia_device * link)
866 * mirrored every 32 bytes. Actually we use a mirrored port for 893 * mirrored every 32 bytes. Actually we use a mirrored port for
867 * the Mako if (on the first pass) the COR bit 5 is set. 894 * the Mako if (on the first pass) the COR bit 5 is set.
868 */ 895 */
869 for (pass=0; pass < 2; pass++) { 896 for (pass=0; pass < 2; pass++)
870 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 897 if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass))
871 for (err = first_tuple(link, &tuple, &parse); !err;
872 err = next_tuple(link, &tuple, &parse)){
873 if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){
874 link->conf.ConfigIndex = cf->index ;
875 link->io.BasePort2 = cf->io.win[0].base;
876 link->io.BasePort1 = link->io.BasePort2
877 + (pass ? (cf->index & 0x20 ? -24:8)
878 : (cf->index & 0x20 ? 8:-24));
879 if (!(err=pcmcia_request_io(link, &link->io)))
880 goto port_found; 898 goto port_found;
881 }
882 }
883 }
884 /* if special option: 899 /* if special option:
885 * try to configure as Ethernet only. 900 * try to configure as Ethernet only.
886 * .... */ 901 * .... */
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index f12355398fe7..4fbe811bebfc 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -206,126 +206,131 @@ static void airo_detach(struct pcmcia_device *link)
206#define CS_CHECK(fn, ret) \ 206#define CS_CHECK(fn, ret) \
207do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 207do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
208 208
209struct airo_cs_config_data {
210 cistpl_cftable_entry_t dflt;
211 win_req_t req;
212};
213
214static int airo_cs_config_check(struct pcmcia_device *p_dev,
215 cistpl_cftable_entry_t *cfg,
216 void *priv_data)
217{
218 struct airo_cs_config_data *cfg_mem = priv_data;
219
220 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
221 cfg_mem->dflt = *cfg;
222
223 if (cfg->index == 0)
224 return -ENODEV;
225
226 p_dev->conf.ConfigIndex = cfg->index;
227
228 /* Does this card need audio output? */
229 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
230 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
231 p_dev->conf.Status = CCSR_AUDIO_ENA;
232 }
233
234 /* Use power settings for Vcc and Vpp if present */
235 /* Note that the CIS values need to be rescaled */
236 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
237 p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
238 else if (cfg_mem->dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
239 p_dev->conf.Vpp = cfg_mem->dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
240
241 /* Do we need to allocate an interrupt? */
242 if (cfg->irq.IRQInfo1 || cfg_mem->dflt.irq.IRQInfo1)
243 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
244
245 /* IO window settings */
246 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
247 if ((cfg->io.nwin > 0) || (cfg_mem->dflt.io.nwin > 0)) {
248 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &cfg_mem->dflt.io;
249 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
250 if (!(io->flags & CISTPL_IO_8BIT))
251 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
252 if (!(io->flags & CISTPL_IO_16BIT))
253 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
254 p_dev->io.BasePort1 = io->win[0].base;
255 p_dev->io.NumPorts1 = io->win[0].len;
256 if (io->nwin > 1) {
257 p_dev->io.Attributes2 = p_dev->io.Attributes1;
258 p_dev->io.BasePort2 = io->win[1].base;
259 p_dev->io.NumPorts2 = io->win[1].len;
260 }
261 }
262
263 /* This reserves IO space but doesn't actually enable it */
264 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
265 return -ENODEV;
266
267 /*
268 Now set up a common memory window, if needed. There is room
269 in the struct pcmcia_device structure for one memory window handle,
270 but if the base addresses need to be saved, or if multiple
271 windows are needed, the info should go in the private data
272 structure for this device.
273
274 Note that the memory window base is a physical address, and
275 needs to be mapped to virtual space with ioremap() before it
276 is used.
277 */
278 if ((cfg->mem.nwin > 0) || (cfg_mem->dflt.mem.nwin > 0)) {
279 cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &cfg_mem->dflt.mem;
280 memreq_t map;
281 cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
282 cfg_mem->req.Base = mem->win[0].host_addr;
283 cfg_mem->req.Size = mem->win[0].len;
284 cfg_mem->req.AccessSpeed = 0;
285 if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0)
286 return -ENODEV;
287 map.Page = 0;
288 map.CardOffset = mem->win[0].card_addr;
289 if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
290 return -ENODEV;
291 }
292 /* If we got this far, we're cool! */
293 return 0;
294}
295
296
209static int airo_config(struct pcmcia_device *link) 297static int airo_config(struct pcmcia_device *link)
210{ 298{
211 tuple_t tuple;
212 cisparse_t parse;
213 local_info_t *dev; 299 local_info_t *dev;
300 struct airo_cs_config_data *cfg_mem;
214 int last_fn, last_ret; 301 int last_fn, last_ret;
215 u_char buf[64];
216 win_req_t req;
217 memreq_t map;
218 302
219 dev = link->priv; 303 dev = link->priv;
220 304
221 DEBUG(0, "airo_config(0x%p)\n", link); 305 DEBUG(0, "airo_config(0x%p)\n", link);
222 306
307 cfg_mem = kzalloc(sizeof(struct airo_cs_config_data), GFP_KERNEL);
308 if (!cfg_mem)
309 return -ENOMEM;
310
223 /* 311 /*
224 In this loop, we scan the CIS for configuration table entries, 312 * In this loop, we scan the CIS for configuration table
225 each of which describes a valid card configuration, including 313 * entries, each of which describes a valid card
226 voltage, IO window, memory window, and interrupt settings. 314 * configuration, including voltage, IO window, memory window,
227 315 * and interrupt settings.
228 We make no assumptions about the card to be configured: we use 316 *
229 just the information available in the CIS. In an ideal world, 317 * We make no assumptions about the card to be configured: we
230 this would work for any PCMCIA card, but it requires a complete 318 * use just the information available in the CIS. In an ideal
231 and accurate CIS. In practice, a driver usually "knows" most of 319 * world, this would work for any PCMCIA card, but it requires
232 these things without consulting the CIS, and most client drivers 320 * a complete and accurate CIS. In practice, a driver usually
233 will only use the CIS to fill in implementation-defined details. 321 * "knows" most of these things without consulting the CIS,
322 * and most client drivers will only use the CIS to fill in
323 * implementation-defined details.
324 */
325 last_ret = pcmcia_loop_config(link, airo_cs_config_check, cfg_mem);
326 if (last_ret)
327 goto failed;
328
329 /*
330 Allocate an interrupt line. Note that this does not assign a
331 handler to the interrupt, unless the 'Handler' member of the
332 irq structure is initialized.
234 */ 333 */
235 tuple.Attributes = 0;
236 tuple.TupleData = buf;
237 tuple.TupleDataMax = sizeof(buf);
238 tuple.TupleOffset = 0;
239 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
240 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
241 while (1) {
242 cistpl_cftable_entry_t dflt = { 0 };
243 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
244 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
245 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
246 goto next_entry;
247
248 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
249 if (cfg->index == 0) goto next_entry;
250 link->conf.ConfigIndex = cfg->index;
251
252 /* Does this card need audio output? */
253 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
254 link->conf.Attributes |= CONF_ENABLE_SPKR;
255 link->conf.Status = CCSR_AUDIO_ENA;
256 }
257
258 /* Use power settings for Vcc and Vpp if present */
259 /* Note that the CIS values need to be rescaled */
260 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
261 link->conf.Vpp =
262 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
263 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
264 link->conf.Vpp =
265 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
266
267 /* Do we need to allocate an interrupt? */
268 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
269 link->conf.Attributes |= CONF_ENABLE_IRQ;
270
271 /* IO window settings */
272 link->io.NumPorts1 = link->io.NumPorts2 = 0;
273 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
274 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
275 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
276 if (!(io->flags & CISTPL_IO_8BIT))
277 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
278 if (!(io->flags & CISTPL_IO_16BIT))
279 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
280 link->io.BasePort1 = io->win[0].base;
281 link->io.NumPorts1 = io->win[0].len;
282 if (io->nwin > 1) {
283 link->io.Attributes2 = link->io.Attributes1;
284 link->io.BasePort2 = io->win[1].base;
285 link->io.NumPorts2 = io->win[1].len;
286 }
287 }
288
289 /* This reserves IO space but doesn't actually enable it */
290 if (pcmcia_request_io(link, &link->io) != 0)
291 goto next_entry;
292
293 /*
294 Now set up a common memory window, if needed. There is room
295 in the struct pcmcia_device structure for one memory window handle,
296 but if the base addresses need to be saved, or if multiple
297 windows are needed, the info should go in the private data
298 structure for this device.
299
300 Note that the memory window base is a physical address, and
301 needs to be mapped to virtual space with ioremap() before it
302 is used.
303 */
304 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
305 cistpl_mem_t *mem =
306 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
307 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
308 req.Base = mem->win[0].host_addr;
309 req.Size = mem->win[0].len;
310 req.AccessSpeed = 0;
311 if (pcmcia_request_window(&link, &req, &link->win) != 0)
312 goto next_entry;
313 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
314 if (pcmcia_map_mem_page(link->win, &map) != 0)
315 goto next_entry;
316 }
317 /* If we got this far, we're cool! */
318 break;
319
320 next_entry:
321 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
322 }
323
324 /*
325 Allocate an interrupt line. Note that this does not assign a
326 handler to the interrupt, unless the 'Handler' member of the
327 irq structure is initialized.
328 */
329 if (link->conf.Attributes & CONF_ENABLE_IRQ) 334 if (link->conf.Attributes & CONF_ENABLE_IRQ)
330 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 335 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
331 336
@@ -362,14 +367,17 @@ static int airo_config(struct pcmcia_device *link)
362 printk(" & 0x%04x-0x%04x", link->io.BasePort2, 367 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
363 link->io.BasePort2+link->io.NumPorts2-1); 368 link->io.BasePort2+link->io.NumPorts2-1);
364 if (link->win) 369 if (link->win)
365 printk(", mem 0x%06lx-0x%06lx", req.Base, 370 printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base,
366 req.Base+req.Size-1); 371 cfg_mem->req.Base+cfg_mem->req.Size-1);
367 printk("\n"); 372 printk("\n");
373 kfree(cfg_mem);
368 return 0; 374 return 0;
369 375
370 cs_failed: 376 cs_failed:
371 cs_error(link, last_fn, last_ret); 377 cs_error(link, last_fn, last_ret);
378 failed:
372 airo_release(link); 379 airo_release(link);
380 kfree(cfg_mem);
373 return -ENODEV; 381 return -ENODEV;
374} /* airo_config */ 382} /* airo_config */
375 383
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 12617cd0b78e..263c36f7ee22 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -224,25 +224,69 @@ static int card_present(void *arg)
224 return 0; 224 return 0;
225} 225}
226 226
227static int atmel_config_check(struct pcmcia_device *p_dev,
228 cistpl_cftable_entry_t *cfg,
229 void *priv_data)
230{
231 cistpl_cftable_entry_t *dflt = priv_data;
232
233 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
234 *dflt = *cfg;
235 if (cfg->index == 0)
236 return -ENODEV;
237 p_dev->conf.ConfigIndex = cfg->index;
238
239 /* Does this card need audio output? */
240 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
241 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
242 p_dev->conf.Status = CCSR_AUDIO_ENA;
243 }
244
245 /* Use power settings for Vcc and Vpp if present */
246 /* Note that the CIS values need to be rescaled */
247 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
248 p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
249 else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
250 p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
251
252 /* Do we need to allocate an interrupt? */
253 if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
254 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
255
256 /* IO window settings */
257 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
258 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
259 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
260 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
261 if (!(io->flags & CISTPL_IO_8BIT))
262 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
263 if (!(io->flags & CISTPL_IO_16BIT))
264 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
265 p_dev->io.BasePort1 = io->win[0].base;
266 p_dev->io.NumPorts1 = io->win[0].len;
267 if (io->nwin > 1) {
268 p_dev->io.Attributes2 = p_dev->io.Attributes1;
269 p_dev->io.BasePort2 = io->win[1].base;
270 p_dev->io.NumPorts2 = io->win[1].len;
271 }
272 }
273
274 /* This reserves IO space but doesn't actually enable it */
275 return pcmcia_request_io(p_dev, &p_dev->io);
276}
277
227static int atmel_config(struct pcmcia_device *link) 278static int atmel_config(struct pcmcia_device *link)
228{ 279{
229 tuple_t tuple;
230 cisparse_t parse;
231 local_info_t *dev; 280 local_info_t *dev;
232 int last_fn, last_ret; 281 int last_fn, last_ret;
233 u_char buf[64];
234 struct pcmcia_device_id *did; 282 struct pcmcia_device_id *did;
283 cistpl_cftable_entry_t dflt = { 0 };
235 284
236 dev = link->priv; 285 dev = link->priv;
237 did = handle_to_dev(link).driver_data; 286 did = handle_to_dev(link).driver_data;
238 287
239 DEBUG(0, "atmel_config(0x%p)\n", link); 288 DEBUG(0, "atmel_config(0x%p)\n", link);
240 289
241 tuple.Attributes = 0;
242 tuple.TupleData = buf;
243 tuple.TupleDataMax = sizeof(buf);
244 tuple.TupleOffset = 0;
245
246 /* 290 /*
247 In this loop, we scan the CIS for configuration table entries, 291 In this loop, we scan the CIS for configuration table entries,
248 each of which describes a valid card configuration, including 292 each of which describes a valid card configuration, including
@@ -255,66 +299,8 @@ static int atmel_config(struct pcmcia_device *link)
255 these things without consulting the CIS, and most client drivers 299 these things without consulting the CIS, and most client drivers
256 will only use the CIS to fill in implementation-defined details. 300 will only use the CIS to fill in implementation-defined details.
257 */ 301 */
258 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 302 if (pcmcia_loop_config(link, atmel_config_check, &dflt))
259 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 303 goto failed;
260 while (1) {
261 cistpl_cftable_entry_t dflt = { 0 };
262 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
263 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
264 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
265 goto next_entry;
266
267 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
268 if (cfg->index == 0) goto next_entry;
269 link->conf.ConfigIndex = cfg->index;
270
271 /* Does this card need audio output? */
272 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
273 link->conf.Attributes |= CONF_ENABLE_SPKR;
274 link->conf.Status = CCSR_AUDIO_ENA;
275 }
276
277 /* Use power settings for Vcc and Vpp if present */
278 /* Note that the CIS values need to be rescaled */
279 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
280 link->conf.Vpp =
281 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
282 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
283 link->conf.Vpp =
284 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
285
286 /* Do we need to allocate an interrupt? */
287 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
288 link->conf.Attributes |= CONF_ENABLE_IRQ;
289
290 /* IO window settings */
291 link->io.NumPorts1 = link->io.NumPorts2 = 0;
292 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
293 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
294 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
295 if (!(io->flags & CISTPL_IO_8BIT))
296 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
297 if (!(io->flags & CISTPL_IO_16BIT))
298 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
299 link->io.BasePort1 = io->win[0].base;
300 link->io.NumPorts1 = io->win[0].len;
301 if (io->nwin > 1) {
302 link->io.Attributes2 = link->io.Attributes1;
303 link->io.BasePort2 = io->win[1].base;
304 link->io.NumPorts2 = io->win[1].len;
305 }
306 }
307
308 /* This reserves IO space but doesn't actually enable it */
309 if (pcmcia_request_io(link, &link->io) != 0)
310 goto next_entry;
311
312 /* If we got this far, we're cool! */
313 break;
314
315 next_entry:
316 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
317 }
318 304
319 /* 305 /*
320 Allocate an interrupt line. Note that this does not assign a 306 Allocate an interrupt line. Note that this does not assign a
@@ -360,6 +346,7 @@ static int atmel_config(struct pcmcia_device *link)
360 346
361 cs_failed: 347 cs_failed:
362 cs_error(link, last_fn, last_ret); 348 cs_error(link, last_fn, last_ret);
349 failed:
363 atmel_release(link); 350 atmel_release(link);
364 return -ENODEV; 351 return -ENODEV;
365} 352}
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 3b4e55cf33cd..3d914dde5de0 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -532,145 +532,134 @@ static void prism2_detach(struct pcmcia_device *link)
532#define CS_CHECK(fn, ret) \ 532#define CS_CHECK(fn, ret) \
533do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 533do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
534 534
535#define CFG_CHECK2(fn, retf) \
536do { int _ret = (retf); \
537if (_ret != 0) { \
538 PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \
539 cs_error(link, fn, _ret); \
540 goto next_entry; \
541} \
542} while (0)
543
544 535
545/* run after a CARD_INSERTION event is received to configure the PCMCIA 536/* run after a CARD_INSERTION event is received to configure the PCMCIA
546 * socket and make the device available to the system */ 537 * socket and make the device available to the system */
538
539struct prism2_config_data {
540 cistpl_cftable_entry_t dflt;
541 config_info_t conf;
542};
543
544static int prism2_config_check(struct pcmcia_device *p_dev,
545 cistpl_cftable_entry_t *cfg,
546 void *priv_data)
547{
548 struct prism2_config_data *cfg_mem = priv_data;
549
550 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
551 cfg_mem->dflt = *cfg;
552 if (cfg->index == 0)
553 return -ENODEV;
554
555 p_dev->conf.ConfigIndex = cfg->index;
556 PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
557 "(default 0x%02X)\n", cfg->index, cfg_mem->dflt.index);
558
559 /* Does this card need audio output? */
560 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
561 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
562 p_dev->conf.Status = CCSR_AUDIO_ENA;
563 }
564
565 /* Use power settings for Vcc and Vpp if present */
566 /* Note that the CIS values need to be rescaled */
567 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
568 if (cfg_mem->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
569 10000 && !ignore_cis_vcc) {
570 PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping"
571 " this entry\n");
572 return -ENODEV;
573 }
574 } else if (cfg_mem->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
575 if (cfg_mem->conf.Vcc != cfg_mem->dflt.vcc.param[CISTPL_POWER_VNOM] /
576 10000 && !ignore_cis_vcc) {
577 PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch "
578 "- skipping this entry\n");
579 return -ENODEV;
580 }
581 }
582
583 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
584 p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
585 else if (cfg_mem->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
586 p_dev->conf.Vpp = cfg_mem->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
587
588 /* Do we need to allocate an interrupt? */
589 if (cfg->irq.IRQInfo1 || cfg_mem->dflt.irq.IRQInfo1)
590 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
591 else if (!(p_dev->conf.Attributes & CONF_ENABLE_IRQ)) {
592 /* At least Compaq WL200 does not have IRQInfo1 set,
593 * but it does not work without interrupts.. */
594 printk(KERN_WARNING "Config has no IRQ info, but trying to "
595 "enable IRQ anyway..\n");
596 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
597 }
598
599 /* IO window settings */
600 PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
601 "cfg_mem->dflt.io.nwin=%d\n",
602 cfg->io.nwin, cfg_mem->dflt.io.nwin);
603 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
604 if ((cfg->io.nwin > 0) || (cfg_mem->dflt.io.nwin > 0)) {
605 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &cfg_mem->dflt.io;
606 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
607 PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
608 "io.base=0x%04x, len=%d\n", io->flags,
609 io->win[0].base, io->win[0].len);
610 if (!(io->flags & CISTPL_IO_8BIT))
611 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
612 if (!(io->flags & CISTPL_IO_16BIT))
613 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
614 p_dev->io.IOAddrLines = io->flags &
615 CISTPL_IO_LINES_MASK;
616 p_dev->io.BasePort1 = io->win[0].base;
617 p_dev->io.NumPorts1 = io->win[0].len;
618 if (io->nwin > 1) {
619 p_dev->io.Attributes2 = p_dev->io.Attributes1;
620 p_dev->io.BasePort2 = io->win[1].base;
621 p_dev->io.NumPorts2 = io->win[1].len;
622 }
623 }
624
625 /* This reserves IO space but doesn't actually enable it */
626 return pcmcia_request_io(p_dev, &p_dev->io);
627}
628
547static int prism2_config(struct pcmcia_device *link) 629static int prism2_config(struct pcmcia_device *link)
548{ 630{
549 struct net_device *dev; 631 struct net_device *dev;
550 struct hostap_interface *iface; 632 struct hostap_interface *iface;
633 struct prism2_config_data *cfg_mem;
551 local_info_t *local; 634 local_info_t *local;
552 int ret = 1; 635 int ret = 1;
553 tuple_t tuple;
554 cisparse_t *parse;
555 int last_fn, last_ret; 636 int last_fn, last_ret;
556 u_char buf[64];
557 config_info_t conf;
558 cistpl_cftable_entry_t dflt = { 0 };
559 struct hostap_cs_priv *hw_priv; 637 struct hostap_cs_priv *hw_priv;
560 638
561 PDEBUG(DEBUG_FLOW, "prism2_config()\n"); 639 PDEBUG(DEBUG_FLOW, "prism2_config()\n");
562 640
563 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL); 641 cfg_mem = kzalloc(sizeof(struct prism2_config_data), GFP_KERNEL);
642 if (!cfg_mem)
643 return -ENOMEM;
644
564 hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL); 645 hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
565 if (parse == NULL || hw_priv == NULL) { 646 if (hw_priv == NULL) {
566 ret = -ENOMEM; 647 ret = -ENOMEM;
567 goto failed; 648 goto failed;
568 } 649 }
569 650
570 tuple.Attributes = 0;
571 tuple.TupleData = buf;
572 tuple.TupleDataMax = sizeof(buf);
573 tuple.TupleOffset = 0;
574
575 CS_CHECK(GetConfigurationInfo, 651 CS_CHECK(GetConfigurationInfo,
576 pcmcia_get_configuration_info(link, &conf)); 652 pcmcia_get_configuration_info(link, &cfg_mem->conf));
577 653
578 /* Look for an appropriate configuration table entry in the CIS */ 654 /* Look for an appropriate configuration table entry in the CIS */
579 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 655 last_ret = pcmcia_loop_config(link, prism2_config_check, cfg_mem);
580 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 656 if (last_ret) {
581 for (;;) { 657 if (!ignore_cis_vcc)
582 cistpl_cftable_entry_t *cfg = &(parse->cftable_entry); 658 printk(KERN_ERR "GetNextTuple(): No matching "
583 CFG_CHECK2(GetTupleData, 659 "CIS configuration. Maybe you need the "
584 pcmcia_get_tuple_data(link, &tuple)); 660 "ignore_cis_vcc=1 parameter.\n");
585 CFG_CHECK2(ParseTuple, 661 cs_error(link, RequestIO, last_ret);
586 pcmcia_parse_tuple(link, &tuple, parse)); 662 goto failed;
587
588 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
589 dflt = *cfg;
590 if (cfg->index == 0)
591 goto next_entry;
592 link->conf.ConfigIndex = cfg->index;
593 PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
594 "(default 0x%02X)\n", cfg->index, dflt.index);
595
596 /* Does this card need audio output? */
597 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
598 link->conf.Attributes |= CONF_ENABLE_SPKR;
599 link->conf.Status = CCSR_AUDIO_ENA;
600 }
601
602 /* Use power settings for Vcc and Vpp if present */
603 /* Note that the CIS values need to be rescaled */
604 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
605 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
606 10000 && !ignore_cis_vcc) {
607 PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping"
608 " this entry\n");
609 goto next_entry;
610 }
611 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
612 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] /
613 10000 && !ignore_cis_vcc) {
614 PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch "
615 "- skipping this entry\n");
616 goto next_entry;
617 }
618 }
619
620 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
621 link->conf.Vpp =
622 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
623 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
624 link->conf.Vpp =
625 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
626
627 /* Do we need to allocate an interrupt? */
628 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
629 link->conf.Attributes |= CONF_ENABLE_IRQ;
630 else if (!(link->conf.Attributes & CONF_ENABLE_IRQ)) {
631 /* At least Compaq WL200 does not have IRQInfo1 set,
632 * but it does not work without interrupts.. */
633 printk("Config has no IRQ info, but trying to enable "
634 "IRQ anyway..\n");
635 link->conf.Attributes |= CONF_ENABLE_IRQ;
636 }
637
638 /* IO window settings */
639 PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
640 "dflt.io.nwin=%d\n",
641 cfg->io.nwin, dflt.io.nwin);
642 link->io.NumPorts1 = link->io.NumPorts2 = 0;
643 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
644 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
645 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
646 PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
647 "io.base=0x%04x, len=%d\n", io->flags,
648 io->win[0].base, io->win[0].len);
649 if (!(io->flags & CISTPL_IO_8BIT))
650 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
651 if (!(io->flags & CISTPL_IO_16BIT))
652 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
653 link->io.IOAddrLines = io->flags &
654 CISTPL_IO_LINES_MASK;
655 link->io.BasePort1 = io->win[0].base;
656 link->io.NumPorts1 = io->win[0].len;
657 if (io->nwin > 1) {
658 link->io.Attributes2 = link->io.Attributes1;
659 link->io.BasePort2 = io->win[1].base;
660 link->io.NumPorts2 = io->win[1].len;
661 }
662 }
663
664 /* This reserves IO space but doesn't actually enable it */
665 CFG_CHECK2(RequestIO,
666 pcmcia_request_io(link, &link->io));
667
668 /* This configuration table entry is OK */
669 break;
670
671 next_entry:
672 CS_CHECK(GetNextTuple,
673 pcmcia_get_next_tuple(link, &tuple));
674 } 663 }
675 664
676 /* Need to allocate net_device before requesting IRQ handler */ 665 /* Need to allocate net_device before requesting IRQ handler */
@@ -738,15 +727,15 @@ static int prism2_config(struct pcmcia_device *link)
738 if (ret == 0 && local->ddev) 727 if (ret == 0 && local->ddev)
739 strcpy(hw_priv->node.dev_name, local->ddev->name); 728 strcpy(hw_priv->node.dev_name, local->ddev->name);
740 } 729 }
741 kfree(parse); 730 kfree(cfg_mem);
742 return ret; 731 return ret;
743 732
744 cs_failed: 733 cs_failed:
745 cs_error(link, last_fn, last_ret); 734 cs_error(link, last_fn, last_ret);
746 735
747 failed: 736 failed:
748 kfree(parse);
749 kfree(hw_priv); 737 kfree(hw_priv);
738 kfree(cfg_mem);
750 prism2_release((u_long)link); 739 prism2_release((u_long)link);
751 return ret; 740 return ret;
752} 741}
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index 1c216e015f64..473370c9e0d6 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -164,23 +164,96 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
164 last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \ 164 last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
165 } while (0) 165 } while (0)
166 166
167struct orinoco_cs_config_data {
168 cistpl_cftable_entry_t dflt;
169 config_info_t conf;
170};
171
172static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
173 cistpl_cftable_entry_t *cfg,
174 void *priv_data)
175{
176 struct orinoco_cs_config_data *cfg_mem = priv_data;
177
178 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
179 cfg_mem->dflt = *cfg;
180 if (cfg->index == 0)
181 goto next_entry;
182 p_dev->conf.ConfigIndex = cfg->index;
183
184 /* Use power settings for Vcc and Vpp if present */
185 /* Note that the CIS values need to be rescaled */
186 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
187 if (cfg_mem->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
188 DEBUG(2, "spectrum_cs_config: Vcc mismatch (cfg_mem->conf.Vcc = %d, CIS = %d)\n", cfg_mem->conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
189 if (!ignore_cis_vcc)
190 goto next_entry;
191 }
192 } else if (cfg_mem->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
193 if (cfg_mem->conf.Vcc != cfg_mem->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
194 DEBUG(2, "spectrum_cs_config: Vcc mismatch (cfg_mem->conf.Vcc = %d, CIS = %d)\n", cfg_mem->conf.Vcc, cfg_mem->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
195 if (!ignore_cis_vcc)
196 goto next_entry;
197 }
198 }
199
200 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
201 p_dev->conf.Vpp =
202 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
203 else if (cfg_mem->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
204 p_dev->conf.Vpp =
205 cfg_mem->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
206
207 /* Do we need to allocate an interrupt? */
208 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
209
210 /* IO window settings */
211 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
212 if ((cfg->io.nwin > 0) || (cfg_mem->dflt.io.nwin > 0)) {
213 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &cfg_mem->dflt.io;
214 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
215 if (!(io->flags & CISTPL_IO_8BIT))
216 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
217 if (!(io->flags & CISTPL_IO_16BIT))
218 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
219 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
220 p_dev->io.BasePort1 = io->win[0].base;
221 p_dev->io.NumPorts1 = io->win[0].len;
222 if (io->nwin > 1) {
223 p_dev->io.Attributes2 = p_dev->io.Attributes1;
224 p_dev->io.BasePort2 = io->win[1].base;
225 p_dev->io.NumPorts2 = io->win[1].len;
226 }
227
228 /* This reserves IO space but doesn't actually enable it */
229 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
230 goto next_entry;
231 }
232 return 0;
233
234next_entry:
235 pcmcia_disable_device(p_dev);
236 return -ENODEV;
237};
238
167static int 239static int
168orinoco_cs_config(struct pcmcia_device *link) 240orinoco_cs_config(struct pcmcia_device *link)
169{ 241{
242 struct orinoco_cs_config_data *cfg_mem;
170 struct net_device *dev = link->priv; 243 struct net_device *dev = link->priv;
171 struct orinoco_private *priv = netdev_priv(dev); 244 struct orinoco_private *priv = netdev_priv(dev);
172 struct orinoco_pccard *card = priv->card; 245 struct orinoco_pccard *card = priv->card;
173 hermes_t *hw = &priv->hw; 246 hermes_t *hw = &priv->hw;
174 int last_fn, last_ret; 247 int last_fn, last_ret;
175 u_char buf[64];
176 config_info_t conf;
177 tuple_t tuple;
178 cisparse_t parse;
179 void __iomem *mem; 248 void __iomem *mem;
180 249
250 cfg_mem = kzalloc(sizeof(struct orinoco_cs_config_data), GFP_KERNEL);
251 if (!cfg_mem)
252 return -ENOMEM;
253
181 /* Look up the current Vcc */ 254 /* Look up the current Vcc */
182 CS_CHECK(GetConfigurationInfo, 255 CS_CHECK(GetConfigurationInfo,
183 pcmcia_get_configuration_info(link, &conf)); 256 pcmcia_get_configuration_info(link, &cfg_mem->conf));
184 257
185 /* 258 /*
186 * In this loop, we scan the CIS for configuration table 259 * In this loop, we scan the CIS for configuration table
@@ -196,94 +269,14 @@ orinoco_cs_config(struct pcmcia_device *link)
196 * and most client drivers will only use the CIS to fill in 269 * and most client drivers will only use the CIS to fill in
197 * implementation-defined details. 270 * implementation-defined details.
198 */ 271 */
199 tuple.Attributes = 0; 272 last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, cfg_mem);
200 tuple.TupleData = buf; 273 if (last_ret) {
201 tuple.TupleDataMax = sizeof(buf); 274 if (!ignore_cis_vcc)
202 tuple.TupleOffset = 0;
203 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
204 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
205 while (1) {
206 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
207 cistpl_cftable_entry_t dflt = { .index = 0 };
208
209 if ( (pcmcia_get_tuple_data(link, &tuple) != 0)
210 || (pcmcia_parse_tuple(link, &tuple, &parse) != 0))
211 goto next_entry;
212
213 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
214 dflt = *cfg;
215 if (cfg->index == 0)
216 goto next_entry;
217 link->conf.ConfigIndex = cfg->index;
218
219 /* Use power settings for Vcc and Vpp if present */
220 /* Note that the CIS values need to be rescaled */
221 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
222 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
223 DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, cfg CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
224 if (!ignore_cis_vcc)
225 goto next_entry;
226 }
227 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
228 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
229 DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, dflt CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
230 if(!ignore_cis_vcc)
231 goto next_entry;
232 }
233 }
234
235 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
236 link->conf.Vpp =
237 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
238 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
239 link->conf.Vpp =
240 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
241
242 /* Do we need to allocate an interrupt? */
243 link->conf.Attributes |= CONF_ENABLE_IRQ;
244
245 /* IO window settings */
246 link->io.NumPorts1 = link->io.NumPorts2 = 0;
247 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
248 cistpl_io_t *io =
249 (cfg->io.nwin) ? &cfg->io : &dflt.io;
250 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
251 if (!(io->flags & CISTPL_IO_8BIT))
252 link->io.Attributes1 =
253 IO_DATA_PATH_WIDTH_16;
254 if (!(io->flags & CISTPL_IO_16BIT))
255 link->io.Attributes1 =
256 IO_DATA_PATH_WIDTH_8;
257 link->io.IOAddrLines =
258 io->flags & CISTPL_IO_LINES_MASK;
259 link->io.BasePort1 = io->win[0].base;
260 link->io.NumPorts1 = io->win[0].len;
261 if (io->nwin > 1) {
262 link->io.Attributes2 =
263 link->io.Attributes1;
264 link->io.BasePort2 = io->win[1].base;
265 link->io.NumPorts2 = io->win[1].len;
266 }
267
268 /* This reserves IO space but doesn't actually enable it */
269 if (pcmcia_request_io(link, &link->io) != 0)
270 goto next_entry;
271 }
272
273
274 /* If we got this far, we're cool! */
275
276 break;
277
278 next_entry:
279 pcmcia_disable_device(link);
280 last_ret = pcmcia_get_next_tuple(link, &tuple);
281 if (last_ret == CS_NO_MORE_ITEMS) {
282 printk(KERN_ERR PFX "GetNextTuple(): No matching " 275 printk(KERN_ERR PFX "GetNextTuple(): No matching "
283 "CIS configuration. Maybe you need the " 276 "CIS configuration. Maybe you need the "
284 "ignore_cis_vcc=1 parameter.\n"); 277 "ignore_cis_vcc=1 parameter.\n");
285 goto cs_failed; 278 cs_error(link, RequestIO, last_ret);
286 } 279 goto failed;
287 } 280 }
288 281
289 /* 282 /*
@@ -334,7 +327,7 @@ orinoco_cs_config(struct pcmcia_device *link)
334 "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id, 327 "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id,
335 link->irq.AssignedIRQ, link->io.BasePort1, 328 link->irq.AssignedIRQ, link->io.BasePort1,
336 link->io.BasePort1 + link->io.NumPorts1 - 1); 329 link->io.BasePort1 + link->io.NumPorts1 - 1);
337 330 kfree(cfg_mem);
338 return 0; 331 return 0;
339 332
340 cs_failed: 333 cs_failed:
@@ -342,6 +335,7 @@ orinoco_cs_config(struct pcmcia_device *link)
342 335
343 failed: 336 failed:
344 orinoco_cs_release(link); 337 orinoco_cs_release(link);
338 kfree(cfg_mem);
345 return -ENODEV; 339 return -ENODEV;
346} /* orinoco_cs_config */ 340} /* orinoco_cs_config */
347 341
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 98df9bc7836a..8e1951cfc152 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -633,23 +633,96 @@ static void spectrum_cs_detach(struct pcmcia_device *link)
633 * device available to the system. 633 * device available to the system.
634 */ 634 */
635 635
636struct spectrum_cs_config_data {
637 cistpl_cftable_entry_t dflt;
638 config_info_t conf;
639};
640
641static int spectrum_cs_config_check(struct pcmcia_device *p_dev,
642 cistpl_cftable_entry_t *cfg,
643 void *priv_data)
644{
645 struct spectrum_cs_config_data *cfg_mem = priv_data;
646
647 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
648 cfg_mem->dflt = *cfg;
649 if (cfg->index == 0)
650 goto next_entry;
651 p_dev->conf.ConfigIndex = cfg->index;
652
653 /* Use power settings for Vcc and Vpp if present */
654 /* Note that the CIS values need to be rescaled */
655 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
656 if (cfg_mem->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
657 DEBUG(2, "spectrum_cs_config: Vcc mismatch (cfg_mem->conf.Vcc = %d, CIS = %d)\n", cfg_mem->conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
658 if (!ignore_cis_vcc)
659 goto next_entry;
660 }
661 } else if (cfg_mem->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
662 if (cfg_mem->conf.Vcc != cfg_mem->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
663 DEBUG(2, "spectrum_cs_config: Vcc mismatch (cfg_mem->conf.Vcc = %d, CIS = %d)\n", cfg_mem->conf.Vcc, cfg_mem->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
664 if (!ignore_cis_vcc)
665 goto next_entry;
666 }
667 }
668
669 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
670 p_dev->conf.Vpp =
671 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
672 else if (cfg_mem->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
673 p_dev->conf.Vpp =
674 cfg_mem->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
675
676 /* Do we need to allocate an interrupt? */
677 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
678
679 /* IO window settings */
680 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
681 if ((cfg->io.nwin > 0) || (cfg_mem->dflt.io.nwin > 0)) {
682 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &cfg_mem->dflt.io;
683 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
684 if (!(io->flags & CISTPL_IO_8BIT))
685 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
686 if (!(io->flags & CISTPL_IO_16BIT))
687 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
688 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
689 p_dev->io.BasePort1 = io->win[0].base;
690 p_dev->io.NumPorts1 = io->win[0].len;
691 if (io->nwin > 1) {
692 p_dev->io.Attributes2 = p_dev->io.Attributes1;
693 p_dev->io.BasePort2 = io->win[1].base;
694 p_dev->io.NumPorts2 = io->win[1].len;
695 }
696
697 /* This reserves IO space but doesn't actually enable it */
698 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
699 goto next_entry;
700 }
701 return 0;
702
703next_entry:
704 pcmcia_disable_device(p_dev);
705 return -ENODEV;
706};
707
636static int 708static int
637spectrum_cs_config(struct pcmcia_device *link) 709spectrum_cs_config(struct pcmcia_device *link)
638{ 710{
711 struct spectrum_cs_config_data *cfg_mem;
639 struct net_device *dev = link->priv; 712 struct net_device *dev = link->priv;
640 struct orinoco_private *priv = netdev_priv(dev); 713 struct orinoco_private *priv = netdev_priv(dev);
641 struct orinoco_pccard *card = priv->card; 714 struct orinoco_pccard *card = priv->card;
642 hermes_t *hw = &priv->hw; 715 hermes_t *hw = &priv->hw;
643 int last_fn, last_ret; 716 int last_fn, last_ret;
644 u_char buf[64];
645 config_info_t conf;
646 tuple_t tuple;
647 cisparse_t parse;
648 void __iomem *mem; 717 void __iomem *mem;
649 718
719 cfg_mem = kzalloc(sizeof(struct spectrum_cs_config_data), GFP_KERNEL);
720 if (!cfg_mem)
721 return -ENOMEM;
722
650 /* Look up the current Vcc */ 723 /* Look up the current Vcc */
651 CS_CHECK(GetConfigurationInfo, 724 CS_CHECK(GetConfigurationInfo,
652 pcmcia_get_configuration_info(link, &conf)); 725 pcmcia_get_configuration_info(link, &cfg_mem->conf));
653 726
654 /* 727 /*
655 * In this loop, we scan the CIS for configuration table 728 * In this loop, we scan the CIS for configuration table
@@ -665,94 +738,14 @@ spectrum_cs_config(struct pcmcia_device *link)
665 * and most client drivers will only use the CIS to fill in 738 * and most client drivers will only use the CIS to fill in
666 * implementation-defined details. 739 * implementation-defined details.
667 */ 740 */
668 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 741 last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, cfg_mem);
669 tuple.Attributes = 0; 742 if (last_ret) {
670 tuple.TupleData = buf; 743 if (!ignore_cis_vcc)
671 tuple.TupleDataMax = sizeof(buf);
672 tuple.TupleOffset = 0;
673 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
674 while (1) {
675 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
676 cistpl_cftable_entry_t dflt = { .index = 0 };
677
678 if ( (pcmcia_get_tuple_data(link, &tuple) != 0)
679 || (pcmcia_parse_tuple(link, &tuple, &parse) != 0))
680 goto next_entry;
681
682 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
683 dflt = *cfg;
684 if (cfg->index == 0)
685 goto next_entry;
686 link->conf.ConfigIndex = cfg->index;
687
688 /* Use power settings for Vcc and Vpp if present */
689 /* Note that the CIS values need to be rescaled */
690 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
691 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
692 DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
693 if (!ignore_cis_vcc)
694 goto next_entry;
695 }
696 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
697 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
698 DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
699 if(!ignore_cis_vcc)
700 goto next_entry;
701 }
702 }
703
704 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
705 link->conf.Vpp =
706 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
707 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
708 link->conf.Vpp =
709 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
710
711 /* Do we need to allocate an interrupt? */
712 link->conf.Attributes |= CONF_ENABLE_IRQ;
713
714 /* IO window settings */
715 link->io.NumPorts1 = link->io.NumPorts2 = 0;
716 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
717 cistpl_io_t *io =
718 (cfg->io.nwin) ? &cfg->io : &dflt.io;
719 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
720 if (!(io->flags & CISTPL_IO_8BIT))
721 link->io.Attributes1 =
722 IO_DATA_PATH_WIDTH_16;
723 if (!(io->flags & CISTPL_IO_16BIT))
724 link->io.Attributes1 =
725 IO_DATA_PATH_WIDTH_8;
726 link->io.IOAddrLines =
727 io->flags & CISTPL_IO_LINES_MASK;
728 link->io.BasePort1 = io->win[0].base;
729 link->io.NumPorts1 = io->win[0].len;
730 if (io->nwin > 1) {
731 link->io.Attributes2 =
732 link->io.Attributes1;
733 link->io.BasePort2 = io->win[1].base;
734 link->io.NumPorts2 = io->win[1].len;
735 }
736
737 /* This reserves IO space but doesn't actually enable it */
738 if (pcmcia_request_io(link, &link->io) != 0)
739 goto next_entry;
740 }
741
742
743 /* If we got this far, we're cool! */
744
745 break;
746
747 next_entry:
748 pcmcia_disable_device(link);
749 last_ret = pcmcia_get_next_tuple(link, &tuple);
750 if (last_ret == CS_NO_MORE_ITEMS) {
751 printk(KERN_ERR PFX "GetNextTuple(): No matching " 744 printk(KERN_ERR PFX "GetNextTuple(): No matching "
752 "CIS configuration. Maybe you need the " 745 "CIS configuration. Maybe you need the "
753 "ignore_cis_vcc=1 parameter.\n"); 746 "ignore_cis_vcc=1 parameter.\n");
754 goto cs_failed; 747 cs_error(link, RequestIO, last_ret);
755 } 748 goto failed;
756 } 749 }
757 750
758 /* 751 /*
@@ -809,6 +802,7 @@ spectrum_cs_config(struct pcmcia_device *link)
809 link->irq.AssignedIRQ, link->io.BasePort1, 802 link->irq.AssignedIRQ, link->io.BasePort1,
810 link->io.BasePort1 + link->io.NumPorts1 - 1); 803 link->io.BasePort1 + link->io.NumPorts1 - 1);
811 804
805 kfree(cfg_mem);
812 return 0; 806 return 0;
813 807
814 cs_failed: 808 cs_failed:
@@ -816,6 +810,7 @@ spectrum_cs_config(struct pcmcia_device *link)
816 810
817 failed: 811 failed:
818 spectrum_cs_release(link); 812 spectrum_cs_release(link);
813 kfree(cfg_mem);
819 return -ENODEV; 814 return -ENODEV;
820} /* spectrum_cs_config */ 815} /* spectrum_cs_config */
821 816