aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2009-10-18 17:54:24 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2009-11-08 12:23:05 -0500
commitdddfbd824b96a25da0b2f1cf35c0be33ef2422fe (patch)
tree0f48f2883bd00ec5f15d8d32a3c826a3184f47ba /drivers/net/pcmcia
parent91284224da5b15ec6c2b45e10fa5eccd1c92a204 (diff)
pcmcia: convert net pcmcia drivers to use new CIS helpers
Use the new CIS helpers in net pcmcia drivers, which allows for a few code cleanups. This revision does not remove the phys_addr assignment in 3c589_cs.c -- a bug noted by Komuro <komurojun-mbn@nifty.com> CC: David S. Miller <davem@davemloft.net> CC: netdev@vger.kernel.org Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/net/pcmcia')
-rw-r--r--drivers/net/pcmcia/3c574_cs.c18
-rw-r--r--drivers/net/pcmcia/3c589_cs.c21
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c50
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c19
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c238
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c147
6 files changed, 171 insertions, 322 deletions
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index b58965a2b3ae..6449290c62ff 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -344,13 +344,13 @@ static int tc574_config(struct pcmcia_device *link)
344{ 344{
345 struct net_device *dev = link->priv; 345 struct net_device *dev = link->priv;
346 struct el3_private *lp = netdev_priv(dev); 346 struct el3_private *lp = netdev_priv(dev);
347 tuple_t tuple;
348 __le16 buf[32];
349 int last_fn, last_ret, i, j; 347 int last_fn, last_ret, i, j;
350 unsigned int ioaddr; 348 unsigned int ioaddr;
351 __be16 *phys_addr; 349 __be16 *phys_addr;
352 char *cardname; 350 char *cardname;
353 __u32 config; 351 __u32 config;
352 u8 *buf;
353 size_t len;
354 354
355 phys_addr = (__be16 *)dev->dev_addr; 355 phys_addr = (__be16 *)dev->dev_addr;
356 356
@@ -378,16 +378,14 @@ static int tc574_config(struct pcmcia_device *link)
378 /* The 3c574 normally uses an EEPROM for configuration info, including 378 /* The 3c574 normally uses an EEPROM for configuration info, including
379 the hardware address. The future products may include a modem chip 379 the hardware address. The future products may include a modem chip
380 and put the address in the CIS. */ 380 and put the address in the CIS. */
381 tuple.Attributes = 0; 381
382 tuple.TupleData = (cisdata_t *)buf; 382 len = pcmcia_get_tuple(link, 0x88, &buf);
383 tuple.TupleDataMax = 64; 383 if (buf && len >= 6) {
384 tuple.TupleOffset = 0;
385 tuple.DesiredTuple = 0x88;
386 if (pcmcia_get_first_tuple(link, &tuple) == 0) {
387 pcmcia_get_tuple_data(link, &tuple);
388 for (i = 0; i < 3; i++) 384 for (i = 0; i < 3; i++)
389 phys_addr[i] = htons(le16_to_cpu(buf[i])); 385 phys_addr[i] = htons(le16_to_cpu(buf[i * 2]));
386 kfree(buf);
390 } else { 387 } else {
388 kfree(buf); /* 0 < len < 6 */
391 EL3WINDOW(0); 389 EL3WINDOW(0);
392 for (i = 0; i < 3; i++) 390 for (i = 0; i < 3; i++)
393 phys_addr[i] = htons(read_eeprom(ioaddr, i + 10)); 391 phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 569fb06793cf..fc6123ea6fa7 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -256,22 +256,16 @@ static int tc589_config(struct pcmcia_device *link)
256{ 256{
257 struct net_device *dev = link->priv; 257 struct net_device *dev = link->priv;
258 struct el3_private *lp = netdev_priv(dev); 258 struct el3_private *lp = netdev_priv(dev);
259 tuple_t tuple;
260 __le16 buf[32];
261 __be16 *phys_addr; 259 __be16 *phys_addr;
262 int last_fn, last_ret, i, j, multi = 0, fifo; 260 int last_fn, last_ret, i, j, multi = 0, fifo;
263 unsigned int ioaddr; 261 unsigned int ioaddr;
264 char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; 262 char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
263 u8 *buf;
264 size_t len;
265 265
266 DEBUG(0, "3c589_config(0x%p)\n", link); 266 DEBUG(0, "3c589_config(0x%p)\n", link);
267 267
268 phys_addr = (__be16 *)dev->dev_addr; 268 phys_addr = (__be16 *)dev->dev_addr;
269 tuple.Attributes = 0;
270 tuple.TupleData = (cisdata_t *)buf;
271 tuple.TupleDataMax = sizeof(buf);
272 tuple.TupleOffset = 0;
273 tuple.Attributes = TUPLE_RETURN_COMMON;
274
275 /* Is this a 3c562? */ 269 /* Is this a 3c562? */
276 if (link->manf_id != MANFID_3COM) 270 if (link->manf_id != MANFID_3COM)
277 printk(KERN_INFO "3c589_cs: hmmm, is this really a " 271 printk(KERN_INFO "3c589_cs: hmmm, is this really a "
@@ -301,12 +295,13 @@ static int tc589_config(struct pcmcia_device *link)
301 295
302 /* The 3c589 has an extra EEPROM for configuration info, including 296 /* The 3c589 has an extra EEPROM for configuration info, including
303 the hardware address. The 3c562 puts the address in the CIS. */ 297 the hardware address. The 3c562 puts the address in the CIS. */
304 tuple.DesiredTuple = 0x88; 298 len = pcmcia_get_tuple(link, 0x88, &buf);
305 if (pcmcia_get_first_tuple(link, &tuple) == 0) { 299 if (buf && len >= 6) {
306 pcmcia_get_tuple_data(link, &tuple); 300 for (i = 0; i < 3; i++)
307 for (i = 0; i < 3; i++) 301 phys_addr[i] = htons(le16_to_cpu(buf[i*2]));
308 phys_addr[i] = htons(le16_to_cpu(buf[i])); 302 kfree(buf);
309 } else { 303 } else {
304 kfree(buf); /* 0 < len < 6 */
310 for (i = 0; i < 3; i++) 305 for (i = 0; i < 3; i++)
311 phys_addr[i] = htons(read_eeprom(ioaddr, i)); 306 phys_addr[i] = htons(read_eeprom(ioaddr, i));
312 if (phys_addr[0] == htons(0x6060)) { 307 if (phys_addr[0] == htons(0x6060)) {
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index c7a2bbfaf821..5b73b11411c8 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -350,32 +350,29 @@ static int fmvj18x_ioprobe(struct pcmcia_device *p_dev,
350 return 0; /* strange, but that's what the code did already before... */ 350 return 0; /* strange, but that's what the code did already before... */
351} 351}
352 352
353
354static int fmvj18x_config(struct pcmcia_device *link) 353static int fmvj18x_config(struct pcmcia_device *link)
355{ 354{
356 struct net_device *dev = link->priv; 355 struct net_device *dev = link->priv;
357 local_info_t *lp = netdev_priv(dev); 356 local_info_t *lp = netdev_priv(dev);
358 tuple_t tuple;
359 u_short buf[32];
360 int i, last_fn = RequestIO, last_ret = 0, ret; 357 int i, last_fn = RequestIO, last_ret = 0, ret;
361 unsigned int ioaddr; 358 unsigned int ioaddr;
362 cardtype_t cardtype; 359 cardtype_t cardtype;
363 char *card_name = "unknown"; 360 char *card_name = "unknown";
364 u_char *node_id; 361 u8 *buf;
362 size_t len;
363 u_char buggybuf[32];
365 364
366 DEBUG(0, "fmvj18x_config(0x%p)\n", link); 365 DEBUG(0, "fmvj18x_config(0x%p)\n", link);
367 366
368 tuple.TupleData = (u_char *)buf; 367 len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
369 tuple.TupleDataMax = 64; 368 kfree(buf);
370 tuple.TupleOffset = 0; 369
371 tuple.DesiredTuple = CISTPL_FUNCE; 370 if (len) {
372 tuple.TupleOffset = 0; 371 /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
373 if (pcmcia_get_first_tuple(link, &tuple) == 0) {
374 last_ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL); 372 last_ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL);
375 if (last_ret != 0) 373 if (last_ret != 0)
376 goto cs_failed; 374 goto cs_failed;
377 375
378 /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
379 switch (link->manf_id) { 376 switch (link->manf_id) {
380 case MANFID_TDK: 377 case MANFID_TDK:
381 cardtype = TDK; 378 cardtype = TDK;
@@ -482,21 +479,21 @@ static int fmvj18x_config(struct pcmcia_device *link)
482 case CONTEC: 479 case CONTEC:
483 case NEC: 480 case NEC:
484 case KME: 481 case KME:
485 tuple.DesiredTuple = CISTPL_FUNCE;
486 tuple.TupleOffset = 0;
487 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
488 tuple.TupleOffset = 0;
489 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
490 if (cardtype == MBH10304) { 482 if (cardtype == MBH10304) {
491 /* MBH10304's CIS_FUNCE is corrupted */
492 node_id = &(tuple.TupleData[5]);
493 card_name = "FMV-J182"; 483 card_name = "FMV-J182";
494 } else { 484
495 while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) { 485 len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
496 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); 486 if (len < 11) {
497 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); 487 kfree(buf);
488 goto failed;
498 } 489 }
499 node_id = &(tuple.TupleData[2]); 490 /* Read MACID from CIS */
491 for (i = 5; i < 11; i++)
492 dev->dev_addr[i] = buf[i];
493 kfree(buf);
494 } else {
495 if (pcmcia_get_mac_from_cis(link, dev))
496 goto failed;
500 if( cardtype == TDK ) { 497 if( cardtype == TDK ) {
501 card_name = "TDK LAK-CD021"; 498 card_name = "TDK LAK-CD021";
502 } else if( cardtype == LA501 ) { 499 } else if( cardtype == LA501 ) {
@@ -509,9 +506,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
509 card_name = "C-NET(PC)C"; 506 card_name = "C-NET(PC)C";
510 } 507 }
511 } 508 }
512 /* Read MACID from CIS */
513 for (i = 0; i < 6; i++)
514 dev->dev_addr[i] = node_id[i];
515 break; 509 break;
516 case UNGERMANN: 510 case UNGERMANN:
517 /* Read MACID from register */ 511 /* Read MACID from register */
@@ -521,12 +515,12 @@ static int fmvj18x_config(struct pcmcia_device *link)
521 break; 515 break;
522 case XXX10304: 516 case XXX10304:
523 /* Read MACID from Buggy CIS */ 517 /* Read MACID from Buggy CIS */
524 if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) { 518 if (fmvj18x_get_hwinfo(link, buggybuf) == -1) {
525 printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n"); 519 printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
526 goto failed; 520 goto failed;
527 } 521 }
528 for (i = 0 ; i < 6; i++) { 522 for (i = 0 ; i < 6; i++) {
529 dev->dev_addr[i] = tuple.TupleData[i]; 523 dev->dev_addr[i] = buggybuf[i];
530 } 524 }
531 card_name = "FMV-J182"; 525 card_name = "FMV-J182";
532 break; 526 break;
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 5ed6339c52bc..4b96b356d979 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -661,8 +661,8 @@ static int nmclan_config(struct pcmcia_device *link)
661{ 661{
662 struct net_device *dev = link->priv; 662 struct net_device *dev = link->priv;
663 mace_private *lp = netdev_priv(dev); 663 mace_private *lp = netdev_priv(dev);
664 tuple_t tuple; 664 u8 *buf;
665 u_char buf[64]; 665 size_t len;
666 int i, last_ret, last_fn; 666 int i, last_ret, last_fn;
667 unsigned int ioaddr; 667 unsigned int ioaddr;
668 668
@@ -677,14 +677,13 @@ static int nmclan_config(struct pcmcia_device *link)
677 ioaddr = dev->base_addr; 677 ioaddr = dev->base_addr;
678 678
679 /* Read the ethernet address from the CIS. */ 679 /* Read the ethernet address from the CIS. */
680 tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */; 680 len = pcmcia_get_tuple(link, 0x80, &buf);
681 tuple.TupleData = buf; 681 if (!buf || len < ETHER_ADDR_LEN) {
682 tuple.TupleDataMax = 64; 682 kfree(buf);
683 tuple.TupleOffset = 0; 683 goto failed;
684 tuple.Attributes = 0; 684 }
685 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 685 memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN);
686 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); 686 kfree(buf);
687 memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
688 687
689 /* Verify configuration by reading the MACE ID. */ 688 /* Verify configuration by reading the MACE ID. */
690 { 689 {
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index af03759d186d..df92bcde9bcf 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -126,12 +126,6 @@ struct smc_private {
126 int rx_ovrn; 126 int rx_ovrn;
127}; 127};
128 128
129struct smc_cfg_mem {
130 tuple_t tuple;
131 cisparse_t parse;
132 u_char buf[255];
133};
134
135/* Special definitions for Megahertz multifunction cards */ 129/* Special definitions for Megahertz multifunction cards */
136#define MEGAHERTZ_ISR 0x0380 130#define MEGAHERTZ_ISR 0x0380
137 131
@@ -408,34 +402,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s)
408 return 0; 402 return 0;
409} 403}
410 404
411/*====================================================================*/ 405/*====================================================================
412
413static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
414 cisparse_t *parse)
415{
416 int i;
417
418 i = pcmcia_get_first_tuple(handle, tuple);
419 if (i != 0)
420 return i;
421 i = pcmcia_get_tuple_data(handle, tuple);
422 if (i != 0)
423 return i;
424 return pcmcia_parse_tuple(tuple, parse);
425}
426
427static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
428 cisparse_t *parse)
429{
430 int i;
431
432 if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
433 (i = pcmcia_get_tuple_data(handle, tuple)) != 0)
434 return i;
435 return pcmcia_parse_tuple(tuple, parse);
436}
437
438/*======================================================================
439 406
440 Configuration stuff for Megahertz cards 407 Configuration stuff for Megahertz cards
441 408
@@ -490,15 +457,10 @@ static int mhz_mfc_config(struct pcmcia_device *link)
490{ 457{
491 struct net_device *dev = link->priv; 458 struct net_device *dev = link->priv;
492 struct smc_private *smc = netdev_priv(dev); 459 struct smc_private *smc = netdev_priv(dev);
493 struct smc_cfg_mem *cfg_mem;
494 win_req_t req; 460 win_req_t req;
495 memreq_t mem; 461 memreq_t mem;
496 int i; 462 int i;
497 463
498 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
499 if (!cfg_mem)
500 return -ENOMEM;
501
502 link->conf.Attributes |= CONF_ENABLE_SPKR; 464 link->conf.Attributes |= CONF_ENABLE_SPKR;
503 link->conf.Status = CCSR_AUDIO_ENA; 465 link->conf.Status = CCSR_AUDIO_ENA;
504 link->irq.Attributes = 466 link->irq.Attributes =
@@ -510,7 +472,8 @@ static int mhz_mfc_config(struct pcmcia_device *link)
510 /* The Megahertz combo cards have modem-like CIS entries, so 472 /* The Megahertz combo cards have modem-like CIS entries, so
511 we have to explicitly try a bunch of port combinations. */ 473 we have to explicitly try a bunch of port combinations. */
512 if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL)) 474 if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
513 goto free_cfg_mem; 475 return -ENODEV;
476
514 dev->base_addr = link->io.BasePort1; 477 dev->base_addr = link->io.BasePort1;
515 478
516 /* Allocate a memory window, for accessing the ISR */ 479 /* Allocate a memory window, for accessing the ISR */
@@ -519,7 +482,8 @@ static int mhz_mfc_config(struct pcmcia_device *link)
519 req.AccessSpeed = 0; 482 req.AccessSpeed = 0;
520 i = pcmcia_request_window(&link, &req, &link->win); 483 i = pcmcia_request_window(&link, &req, &link->win);
521 if (i != 0) 484 if (i != 0)
522 goto free_cfg_mem; 485 return -ENODEV;
486
523 smc->base = ioremap(req.Base, req.Size); 487 smc->base = ioremap(req.Base, req.Size);
524 mem.CardOffset = mem.Page = 0; 488 mem.CardOffset = mem.Page = 0;
525 if (smc->manfid == MANFID_MOTOROLA) 489 if (smc->manfid == MANFID_MOTOROLA)
@@ -531,18 +495,32 @@ static int mhz_mfc_config(struct pcmcia_device *link)
531 && (smc->cardid == PRODID_MEGAHERTZ_EM3288)) 495 && (smc->cardid == PRODID_MEGAHERTZ_EM3288))
532 mhz_3288_power(link); 496 mhz_3288_power(link);
533 497
534free_cfg_mem: 498 return 0;
535 kfree(cfg_mem);
536 return -ENODEV;
537} 499}
538 500
501static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
502 tuple_t *tuple,
503 void *priv)
504{
505 struct net_device *dev = priv;
506 cisparse_t parse;
507
508 if (pcmcia_parse_tuple(tuple, &parse))
509 return -EINVAL;
510
511 if ((parse.version_1.ns > 3) &&
512 (cvt_ascii_address(dev,
513 (parse.version_1.str + parse.version_1.ofs[3]))))
514 return 0;
515
516 return -EINVAL;
517};
518
539static int mhz_setup(struct pcmcia_device *link) 519static int mhz_setup(struct pcmcia_device *link)
540{ 520{
541 struct net_device *dev = link->priv; 521 struct net_device *dev = link->priv;
542 struct smc_cfg_mem *cfg_mem; 522 size_t len;
543 tuple_t *tuple; 523 u8 *buf;
544 cisparse_t *parse;
545 u_char *buf, *station_addr;
546 int rc; 524 int rc;
547 525
548 /* Read the station address from the CIS. It is stored as the last 526 /* Read the station address from the CIS. It is stored as the last
@@ -552,56 +530,22 @@ static int mhz_setup(struct pcmcia_device *link)
552 return 0; 530 return 0;
553 531
554 /* Workarounds for broken cards start here. */ 532 /* Workarounds for broken cards start here. */
555
556 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
557 if (!cfg_mem)
558 return -1;
559
560 tuple = &cfg_mem->tuple;
561 parse = &cfg_mem->parse;
562 buf = cfg_mem->buf;
563
564 tuple->Attributes = tuple->TupleOffset = 0;
565 tuple->TupleData = (cisdata_t *)buf;
566 tuple->TupleDataMax = 255;
567
568 /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ 533 /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
569 tuple->DesiredTuple = CISTPL_VERS_1; 534 if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev))
570 if (first_tuple(link, tuple, parse) != 0) { 535 return 0;
571 rc = -1;
572 goto free_cfg_mem;
573 }
574 /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
575 if (next_tuple(link, tuple, parse) != 0)
576 first_tuple(link, tuple, parse);
577 if (parse->version_1.ns > 3) {
578 station_addr = parse->version_1.str + parse->version_1.ofs[3];
579 if (cvt_ascii_address(dev, station_addr) == 0) {
580 rc = 0;
581 goto free_cfg_mem;
582 }
583 }
584 536
585 /* Another possibility: for the EM3288, in a special tuple */ 537 /* Another possibility: for the EM3288, in a special tuple */
586 tuple->DesiredTuple = 0x81;
587 if (pcmcia_get_first_tuple(link, tuple) != 0) {
588 rc = -1;
589 goto free_cfg_mem;
590 }
591 if (pcmcia_get_tuple_data(link, tuple) != 0) {
592 rc = -1;
593 goto free_cfg_mem;
594 }
595 buf[12] = '\0';
596 if (cvt_ascii_address(dev, buf) == 0) {
597 rc = 0;
598 goto free_cfg_mem;
599 }
600 rc = -1; 538 rc = -1;
601free_cfg_mem: 539 len = pcmcia_get_tuple(link, 0x81, &buf);
602 kfree(cfg_mem); 540 if (buf && len >= 13) {
603 return rc; 541 buf[12] = '\0';
604} 542 if (cvt_ascii_address(dev, buf))
543 rc = 0;
544 }
545 kfree(buf);
546
547 return rc;
548};
605 549
606/*====================================================================== 550/*======================================================================
607 551
@@ -691,58 +635,21 @@ static int smc_config(struct pcmcia_device *link)
691 return i; 635 return i;
692} 636}
693 637
638
694static int smc_setup(struct pcmcia_device *link) 639static int smc_setup(struct pcmcia_device *link)
695{ 640{
696 struct net_device *dev = link->priv; 641 struct net_device *dev = link->priv;
697 struct smc_cfg_mem *cfg_mem;
698 tuple_t *tuple;
699 cisparse_t *parse;
700 cistpl_lan_node_id_t *node_id;
701 u_char *buf, *station_addr;
702 int i, rc;
703
704 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
705 if (!cfg_mem)
706 return -ENOMEM;
707
708 tuple = &cfg_mem->tuple;
709 parse = &cfg_mem->parse;
710 buf = cfg_mem->buf;
711
712 tuple->Attributes = tuple->TupleOffset = 0;
713 tuple->TupleData = (cisdata_t *)buf;
714 tuple->TupleDataMax = 255;
715 642
716 /* Check for a LAN function extension tuple */ 643 /* Check for a LAN function extension tuple */
717 tuple->DesiredTuple = CISTPL_FUNCE; 644 if (!pcmcia_get_mac_from_cis(link, dev))
718 i = first_tuple(link, tuple, parse); 645 return 0;
719 while (i == 0) { 646
720 if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
721 break;
722 i = next_tuple(link, tuple, parse);
723 }
724 if (i == 0) {
725 node_id = (cistpl_lan_node_id_t *)parse->funce.data;
726 if (node_id->nb == 6) {
727 for (i = 0; i < 6; i++)
728 dev->dev_addr[i] = node_id->id[i];
729 rc = 0;
730 goto free_cfg_mem;
731 }
732 }
733 /* Try the third string in the Version 1 Version/ID tuple. */ 647 /* Try the third string in the Version 1 Version/ID tuple. */
734 if (link->prod_id[2]) { 648 if (link->prod_id[2]) {
735 station_addr = link->prod_id[2]; 649 if (cvt_ascii_address(dev, link->prod_id[2]) == 0)
736 if (cvt_ascii_address(dev, station_addr) == 0) { 650 return 0;
737 rc = 0;
738 goto free_cfg_mem;
739 }
740 } 651 }
741 652 return -1;
742 rc = -1;
743free_cfg_mem:
744 kfree(cfg_mem);
745 return rc;
746} 653}
747 654
748/*====================================================================*/ 655/*====================================================================*/
@@ -801,41 +708,31 @@ static int osi_load_firmware(struct pcmcia_device *link)
801 return err; 708 return err;
802} 709}
803 710
804static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) 711static int pcmcia_osi_mac(struct pcmcia_device *p_dev,
712 tuple_t *tuple,
713 void *priv)
805{ 714{
806 struct net_device *dev = link->priv; 715 struct net_device *dev = priv;
807 struct smc_cfg_mem *cfg_mem; 716 int i;
808 tuple_t *tuple;
809 u_char *buf;
810 int i, rc;
811 717
812 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); 718 if (tuple->TupleDataLen < 8)
813 if (!cfg_mem) 719 return -EINVAL;
814 return -1; 720 if (tuple->TupleData[0] != 0x04)
721 return -EINVAL;
722 for (i = 0; i < 6; i++)
723 dev->dev_addr[i] = tuple->TupleData[i+2];
724 return 0;
725};
815 726
816 tuple = &cfg_mem->tuple;
817 buf = cfg_mem->buf;
818 727
819 tuple->Attributes = TUPLE_RETURN_COMMON; 728static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
820 tuple->TupleData = (cisdata_t *)buf; 729{
821 tuple->TupleDataMax = 255; 730 struct net_device *dev = link->priv;
822 tuple->TupleOffset = 0; 731 int rc;
823 732
824 /* Read the station address from tuple 0x90, subtuple 0x04 */ 733 /* Read the station address from tuple 0x90, subtuple 0x04 */
825 tuple->DesiredTuple = 0x90; 734 if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev))
826 i = pcmcia_get_first_tuple(link, tuple); 735 return -1;
827 while (i == 0) {
828 i = pcmcia_get_tuple_data(link, tuple);
829 if ((i != 0) || (buf[0] == 0x04))
830 break;
831 i = pcmcia_get_next_tuple(link, tuple);
832 }
833 if (i != 0) {
834 rc = -1;
835 goto free_cfg_mem;
836 }
837 for (i = 0; i < 6; i++)
838 dev->dev_addr[i] = buf[i+2];
839 736
840 if (((manfid == MANFID_OSITECH) && 737 if (((manfid == MANFID_OSITECH) &&
841 (cardid == PRODID_OSITECH_SEVEN)) || 738 (cardid == PRODID_OSITECH_SEVEN)) ||
@@ -843,7 +740,7 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
843 (cardid == PRODID_PSION_NET100))) { 740 (cardid == PRODID_PSION_NET100))) {
844 rc = osi_load_firmware(link); 741 rc = osi_load_firmware(link);
845 if (rc) 742 if (rc)
846 goto free_cfg_mem; 743 return rc;
847 } else if (manfid == MANFID_OSITECH) { 744 } else if (manfid == MANFID_OSITECH) {
848 /* Make sure both functions are powered up */ 745 /* Make sure both functions are powered up */
849 set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR); 746 set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
@@ -853,10 +750,7 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
853 inw(link->io.BasePort1 + OSITECH_AUI_PWR), 750 inw(link->io.BasePort1 + OSITECH_AUI_PWR),
854 inw(link->io.BasePort1 + OSITECH_RESET_ISR)); 751 inw(link->io.BasePort1 + OSITECH_RESET_ISR));
855 } 752 }
856 rc = 0; 753 return 0;
857free_cfg_mem:
858 kfree(cfg_mem);
859 return rc;
860} 754}
861 755
862static int smc91c92_suspend(struct pcmcia_device *link) 756static int smc91c92_suspend(struct pcmcia_device *link)
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 5e203230144f..925e85096629 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -359,7 +359,7 @@ static void xirc_tx_timeout(struct net_device *dev);
359static void xirc2ps_tx_timeout_task(struct work_struct *work); 359static void xirc2ps_tx_timeout_task(struct work_struct *work);
360static void set_addresses(struct net_device *dev); 360static void set_addresses(struct net_device *dev);
361static void set_multicast_list(struct net_device *dev); 361static void set_multicast_list(struct net_device *dev);
362static int set_card_type(struct pcmcia_device *link, const void *s); 362static int set_card_type(struct pcmcia_device *link);
363static int do_config(struct net_device *dev, struct ifmap *map); 363static int do_config(struct net_device *dev, struct ifmap *map);
364static int do_open(struct net_device *dev); 364static int do_open(struct net_device *dev);
365static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 365static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -371,28 +371,6 @@ static void do_powerdown(struct net_device *dev);
371static int do_stop(struct net_device *dev); 371static int do_stop(struct net_device *dev);
372 372
373/*=============== Helper functions =========================*/ 373/*=============== Helper functions =========================*/
374static int
375first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
376{
377 int err;
378
379 if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
380 (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
381 err = pcmcia_parse_tuple(tuple, parse);
382 return err;
383}
384
385static int
386next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
387{
388 int err;
389
390 if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
391 (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
392 err = pcmcia_parse_tuple(tuple, parse);
393 return err;
394}
395
396#define SelectPage(pgnr) outb((pgnr), ioaddr + XIRCREG_PR) 374#define SelectPage(pgnr) outb((pgnr), ioaddr + XIRCREG_PR)
397#define GetByte(reg) ((unsigned)inb(ioaddr + (reg))) 375#define GetByte(reg) ((unsigned)inb(ioaddr + (reg)))
398#define GetWord(reg) ((unsigned)inw(ioaddr + (reg))) 376#define GetWord(reg) ((unsigned)inw(ioaddr + (reg)))
@@ -644,15 +622,23 @@ xirc2ps_detach(struct pcmcia_device *link)
644 * 622 *
645 */ 623 */
646static int 624static int
647set_card_type(struct pcmcia_device *link, const void *s) 625set_card_type(struct pcmcia_device *link)
648{ 626{
649 struct net_device *dev = link->priv; 627 struct net_device *dev = link->priv;
650 local_info_t *local = netdev_priv(dev); 628 local_info_t *local = netdev_priv(dev);
651 #ifdef PCMCIA_DEBUG 629 u8 *buf;
652 unsigned cisrev = ((const unsigned char *)s)[2]; 630 unsigned int cisrev, mediaid, prodid;
653 #endif 631 size_t len;
654 unsigned mediaid= ((const unsigned char *)s)[3]; 632
655 unsigned prodid = ((const unsigned char *)s)[4]; 633 len = pcmcia_get_tuple(link, CISTPL_MANFID, &buf);
634 if (len < 5) {
635 dev_err(&link->dev, "invalid CIS -- sorry\n");
636 return 0;
637 }
638
639 cisrev = buf[2];
640 mediaid = buf[3];
641 prodid = buf[4];
656 642
657 DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n", 643 DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n",
658 cisrev, mediaid, prodid); 644 cisrev, mediaid, prodid);
@@ -761,6 +747,26 @@ xirc2ps_config_check(struct pcmcia_device *p_dev,
761 747
762} 748}
763 749
750
751static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev,
752 tuple_t *tuple,
753 void *priv)
754{
755 struct net_device *dev = priv;
756 int i;
757
758 if (tuple->TupleDataLen != 13)
759 return -EINVAL;
760 if ((tuple->TupleData[0] != 2) || (tuple->TupleData[1] != 1) ||
761 (tuple->TupleData[2] != 6))
762 return -EINVAL;
763 /* another try (James Lehmer's CE2 version 4.1)*/
764 for (i = 2; i < 6; i++)
765 dev->dev_addr[i] = tuple->TupleData[i+2];
766 return 0;
767};
768
769
764/**************** 770/****************
765 * xirc2ps_config() is scheduled to run after a CARD_INSERTION event 771 * xirc2ps_config() is scheduled to run after a CARD_INSERTION event
766 * is received, to configure the PCMCIA socket, and to make the 772 * is received, to configure the PCMCIA socket, and to make the
@@ -772,25 +778,14 @@ xirc2ps_config(struct pcmcia_device * link)
772 struct net_device *dev = link->priv; 778 struct net_device *dev = link->priv;
773 local_info_t *local = netdev_priv(dev); 779 local_info_t *local = netdev_priv(dev);
774 unsigned int ioaddr; 780 unsigned int ioaddr;
775 tuple_t tuple; 781 int err;
776 cisparse_t parse; 782 u8 *buf;
777 int err, i; 783 size_t len;
778 u_char buf[64];
779 cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
780 784
781 local->dingo_ccr = NULL; 785 local->dingo_ccr = NULL;
782 786
783 DEBUG(0, "config(0x%p)\n", link); 787 DEBUG(0, "config(0x%p)\n", link);
784 788
785 /*
786 * This reads the card's CONFIG tuple to find its configuration
787 * registers.
788 */
789 tuple.Attributes = 0;
790 tuple.TupleData = buf;
791 tuple.TupleDataMax = 64;
792 tuple.TupleOffset = 0;
793
794 /* Is this a valid card */ 789 /* Is this a valid card */
795 if (link->has_manf_id == 0) { 790 if (link->has_manf_id == 0) {
796 printk(KNOT_XIRC "manfid not found in CIS\n"); 791 printk(KNOT_XIRC "manfid not found in CIS\n");
@@ -816,67 +811,41 @@ xirc2ps_config(struct pcmcia_device * link)
816 break; 811 break;
817 default: 812 default:
818 printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n", 813 printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",
819 (unsigned)parse.manfid.manf); 814 (unsigned)link->manf_id);
820 goto failure; 815 goto failure;
821 } 816 }
822 DEBUG(0, "found %s card\n", local->manf_str); 817 DEBUG(0, "found %s card\n", local->manf_str);
823 818
824 /* needed for the additional fields to be parsed by set_card_type() */ 819 if (!set_card_type(link)) {
825 tuple.DesiredTuple = CISTPL_MANFID;
826 err = first_tuple(link, &tuple, &parse)
827 if (err) {
828 printk(KNOT_XIRC "manfid not found in CIS\n");
829 goto failure;
830 }
831 if (!set_card_type(link, buf)) {
832 printk(KNOT_XIRC "this card is not supported\n"); 820 printk(KNOT_XIRC "this card is not supported\n");
833 goto failure; 821 goto failure;
834 } 822 }
835 823
836 /* get the ethernet address from the CIS */ 824 /* get the ethernet address from the CIS */
837 tuple.DesiredTuple = CISTPL_FUNCE; 825 err = pcmcia_get_mac_from_cis(link, dev);
838 for (err = first_tuple(link, &tuple, &parse); !err; 826
839 err = next_tuple(link, &tuple, &parse)) { 827 /* not found: try to get the node-id from tuple 0x89 */
840 /* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries: 828 if (err) {
841 * the first one with a length of zero the second correct - 829 len = pcmcia_get_tuple(link, 0x89, &buf);
842 * so I skip all entries with length 0 */ 830 /* data layout looks like tuple 0x22 */
843 if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID 831 if (buf && len == 8) {
844 && ((cistpl_lan_node_id_t *)parse.funce.data)->nb) 832 if (*buf == CISTPL_FUNCE_LAN_NODE_ID) {
845 break; 833 int i;
846 } 834 for (i = 2; i < 6; i++)
847 if (err) { /* not found: try to get the node-id from tuple 0x89 */ 835 dev->dev_addr[i] = buf[i+2];
848 tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */ 836 } else
849 if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 && 837 err = -1;
850 (err = pcmcia_get_tuple_data(link, &tuple)) == 0) {
851 if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)
852 memcpy(&parse, buf, 8);
853 else
854 err = -1;
855 }
856 }
857 if (err) { /* another try (James Lehmer's CE2 version 4.1)*/
858 tuple.DesiredTuple = CISTPL_FUNCE;
859 for (err = first_tuple(link, &tuple, &parse); !err;
860 err = next_tuple(link, &tuple, &parse)) {
861 if (parse.funce.type == 0x02 && parse.funce.data[0] == 1
862 && parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {
863 buf[1] = 4;
864 memcpy(&parse, buf+1, 8);
865 break;
866 } 838 }
867 } 839 kfree(buf);
868 } 840 }
841
842 if (err)
843 err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);
844
869 if (err) { 845 if (err) {
870 printk(KNOT_XIRC "node-id not found in CIS\n"); 846 printk(KNOT_XIRC "node-id not found in CIS\n");
871 goto failure; 847 goto failure;
872 } 848 }
873 node_id = (cistpl_lan_node_id_t *)parse.funce.data;
874 if (node_id->nb != 6) {
875 printk(KNOT_XIRC "malformed node-id in CIS\n");
876 goto failure;
877 }
878 for (i=0; i < 6; i++)
879 dev->dev_addr[i] = node_id->id[i];
880 849
881 link->io.IOAddrLines =10; 850 link->io.IOAddrLines =10;
882 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; 851 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;