aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-07-30 07:13:46 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2010-09-29 11:20:24 -0400
commit00990e7ce0b0e596fe41d9c64d6933ea70084003 (patch)
tree189e0dd92860feba84231c66955749574cac5d6d /drivers/net/pcmcia
parent440eed43e2a95bb842488755683716814da10f2b (diff)
pcmcia: use autoconfiguration feature for ioports and iomem
When CONF_AUTO_SET_IO or CONF_AUTO_SET_IOMEM are set, the corresponding fields in struct pcmcia_device *p_dev->resource[0,1,2] are set accordinly. Drivers wishing to override certain settings may do so in the callback function, but they no longer need to parse the CIS entries stored in cistpl_cftable_entry_t themselves. CC: netdev@vger.kernel.org CC: linux-wireless@vger.kernel.org CC: linux-ide@vger.kernel.org CC: linux-usb@vger.kernel.org CC: laforge@gnumonks.org CC: linux-mtd@lists.infradead.org CC: linux-bluetooth@vger.kernel.org CC: alsa-devel@alsa-project.org CC: linux-serial@vger.kernel.org CC: Jiri Kosina <jkosina@suse.cz> CC: linux-scsi@vger.kernel.org Tested-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/net/pcmcia')
-rw-r--r--drivers/net/pcmcia/axnet_cs.c32
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c5
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c38
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c39
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c69
5 files changed, 74 insertions, 109 deletions
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 17f1040e255e..9d9d997f2e59 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -284,34 +284,16 @@ static int try_io_port(struct pcmcia_device *link)
284 } 284 }
285} 285}
286 286
287static int axnet_configcheck(struct pcmcia_device *p_dev, 287static int axnet_configcheck(struct pcmcia_device *p_dev, void *priv_data)
288 cistpl_cftable_entry_t *cfg,
289 cistpl_cftable_entry_t *dflt,
290 void *priv_data)
291{ 288{
292 int i; 289 if (p_dev->config_index == 0)
293 cistpl_io_t *io = &cfg->io; 290 return -EINVAL;
294
295 if (cfg->index == 0 || cfg->io.nwin == 0)
296 return -ENODEV;
297 291
298 p_dev->config_index = 0x05; 292 p_dev->config_index = 0x05;
299 /* For multifunction cards, by convention, we configure the 293 if (p_dev->resource[0]->end + p_dev->resource[1]->end < 32)
300 network function with window 0, and serial with window 1 */ 294 return -ENODEV;
301 if (io->nwin > 1) {
302 i = (io->win[1].len > io->win[0].len);
303 p_dev->resource[1]->start = io->win[1-i].base;
304 p_dev->resource[1]->end = io->win[1-i].len;
305 } else {
306 i = p_dev->resource[1]->end = 0;
307 }
308 p_dev->resource[0]->start = io->win[i].base;
309 p_dev->resource[0]->end = io->win[i].len;
310 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
311 if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32)
312 return try_io_port(p_dev);
313 295
314 return -ENODEV; 296 return try_io_port(p_dev);
315} 297}
316 298
317static int axnet_config(struct pcmcia_device *link) 299static int axnet_config(struct pcmcia_device *link)
@@ -324,6 +306,7 @@ static int axnet_config(struct pcmcia_device *link)
324 306
325 /* don't trust the CIS on this; Linksys got it wrong */ 307 /* don't trust the CIS on this; Linksys got it wrong */
326 link->config_regs = 0x63; 308 link->config_regs = 0x63;
309 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
327 ret = pcmcia_loop_config(link, axnet_configcheck, NULL); 310 ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
328 if (ret != 0) 311 if (ret != 0)
329 goto failed; 312 goto failed;
@@ -331,7 +314,6 @@ static int axnet_config(struct pcmcia_device *link)
331 if (!link->irq) 314 if (!link->irq)
332 goto failed; 315 goto failed;
333 316
334 link->config_flags |= CONF_ENABLE_IRQ;
335 if (resource_size(link->resource[1]) == 8) 317 if (resource_size(link->resource[1]) == 8)
336 link->config_flags |= CONF_ENABLE_SPKR; 318 link->config_flags |= CONF_ENABLE_SPKR;
337 319
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index c1479e3bfab4..792ab38d979c 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -319,10 +319,7 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
319 return ret; /* RequestIO failed */ 319 return ret; /* RequestIO failed */
320} 320}
321 321
322static int fmvj18x_ioprobe(struct pcmcia_device *p_dev, 322static int fmvj18x_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
323 cistpl_cftable_entry_t *cfg,
324 cistpl_cftable_entry_t *dflt,
325 void *priv_data)
326{ 323{
327 return 0; /* strange, but that's what the code did already before... */ 324 return 0; /* strange, but that's what the code did already before... */
328} 325}
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 12b028c6abc9..ffe2587b9145 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -259,7 +259,7 @@ static int pcnet_probe(struct pcmcia_device *link)
259 info->p_dev = link; 259 info->p_dev = link;
260 link->priv = dev; 260 link->priv = dev;
261 261
262 link->config_flags |= CONF_ENABLE_IRQ; 262 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
263 263
264 dev->netdev_ops = &pcnet_netdev_ops; 264 dev->netdev_ops = &pcnet_netdev_ops;
265 265
@@ -500,42 +500,22 @@ static int try_io_port(struct pcmcia_device *link)
500 } 500 }
501} 501}
502 502
503static int pcnet_confcheck(struct pcmcia_device *p_dev, 503static int pcnet_confcheck(struct pcmcia_device *p_dev, void *priv_data)
504 cistpl_cftable_entry_t *cfg,
505 cistpl_cftable_entry_t *dflt,
506 void *priv_data)
507{ 504{
508 int *priv = priv_data; 505 int *priv = priv_data;
509 int try = (*priv & 0x1); 506 int try = (*priv & 0x1);
510 int i;
511 cistpl_io_t *io = &cfg->io;
512 507
513 if (cfg->index == 0 || cfg->io.nwin == 0) 508 *priv &= (p_dev->resource[2]->end >= 0x4000) ? 0x10 : ~0x10;
514 return -EINVAL;
515 509
516 /* For multifunction cards, by convention, we configure the 510 if (p_dev->config_index == 0)
517 network function with window 0, and serial with window 1 */ 511 return -EINVAL;
518 if (io->nwin > 1) {
519 i = (io->win[1].len > io->win[0].len);
520 p_dev->resource[1]->start = io->win[1-i].base;
521 p_dev->resource[1]->end = io->win[1-i].len;
522 } else {
523 i = p_dev->resource[1]->end = 0;
524 }
525 512
526 *priv &= ((cfg->mem.nwin == 1) && 513 if (p_dev->resource[0]->end + p_dev->resource[1]->end < 32)
527 (cfg->mem.win[0].len >= 0x4000)) ? 0x10 : ~0x10; 514 return -EINVAL;
528 515
529 p_dev->resource[0]->start = io->win[i].base; 516 if (try)
530 p_dev->resource[0]->end = io->win[i].len;
531 if (!try)
532 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
533 else
534 p_dev->io_lines = 16; 517 p_dev->io_lines = 16;
535 if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32) 518 return try_io_port(p_dev);
536 return try_io_port(p_dev);
537
538 return -EINVAL;
539} 519}
540 520
541static hw_info_t *pcnet_try_config(struct pcmcia_device *link, 521static hw_info_t *pcnet_try_config(struct pcmcia_device *link,
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index e127d2b546dd..a8cef28507de 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -323,9 +323,6 @@ static int smc91c92_probe(struct pcmcia_device *link)
323 link->priv = dev; 323 link->priv = dev;
324 324
325 spin_lock_init(&smc->lock); 325 spin_lock_init(&smc->lock);
326 link->resource[0]->end = 16;
327 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
328 link->config_flags |= CONF_ENABLE_IRQ;
329 326
330 /* The SMC91c92-specific entries in the device structure. */ 327 /* The SMC91c92-specific entries in the device structure. */
331 dev->netdev_ops = &smc_netdev_ops; 328 dev->netdev_ops = &smc_netdev_ops;
@@ -417,18 +414,21 @@ static int mhz_3288_power(struct pcmcia_device *link)
417 return 0; 414 return 0;
418} 415}
419 416
420static int mhz_mfc_config_check(struct pcmcia_device *p_dev, 417static int mhz_mfc_config_check(struct pcmcia_device *p_dev, void *priv_data)
421 cistpl_cftable_entry_t *cf,
422 cistpl_cftable_entry_t *dflt,
423 void *priv_data)
424{ 418{
425 int k; 419 int k;
426 p_dev->resource[1]->start = cf->io.win[0].base; 420 p_dev->io_lines = 16;
421 p_dev->resource[1]->start = p_dev->resource[0]->start;
422 p_dev->resource[1]->end = 8;
423 p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
424 p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
425 p_dev->resource[0]->end = 16;
426 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
427 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
427 for (k = 0; k < 0x400; k += 0x10) { 428 for (k = 0; k < 0x400; k += 0x10) {
428 if (k & 0x80) 429 if (k & 0x80)
429 continue; 430 continue;
430 p_dev->resource[0]->start = k ^ 0x300; 431 p_dev->resource[0]->start = k ^ 0x300;
431 p_dev->io_lines = 16;
432 if (!pcmcia_request_io(p_dev)) 432 if (!pcmcia_request_io(p_dev))
433 return 0; 433 return 0;
434 } 434 }
@@ -442,9 +442,8 @@ static int mhz_mfc_config(struct pcmcia_device *link)
442 unsigned int offset; 442 unsigned int offset;
443 int i; 443 int i;
444 444
445 link->config_flags |= CONF_ENABLE_SPKR; 445 link->config_flags |= CONF_ENABLE_SPKR | CONF_ENABLE_IRQ |
446 link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; 446 CONF_AUTO_SET_IO;
447 link->resource[1]->end = 8;
448 447
449 /* The Megahertz combo cards have modem-like CIS entries, so 448 /* The Megahertz combo cards have modem-like CIS entries, so
450 we have to explicitly try a bunch of port combinations. */ 449 we have to explicitly try a bunch of port combinations. */
@@ -586,13 +585,12 @@ static int mot_setup(struct pcmcia_device *link)
586 585
587/*====================================================================*/ 586/*====================================================================*/
588 587
589static int smc_configcheck(struct pcmcia_device *p_dev, 588static int smc_configcheck(struct pcmcia_device *p_dev, void *priv_data)
590 cistpl_cftable_entry_t *cf,
591 cistpl_cftable_entry_t *dflt,
592 void *priv_data)
593{ 589{
594 p_dev->resource[0]->start = cf->io.win[0].base; 590 p_dev->resource[0]->end = 16;
595 p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; 591 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
592 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
593
596 return pcmcia_request_io(p_dev); 594 return pcmcia_request_io(p_dev);
597} 595}
598 596
@@ -601,7 +599,8 @@ static int smc_config(struct pcmcia_device *link)
601 struct net_device *dev = link->priv; 599 struct net_device *dev = link->priv;
602 int i; 600 int i;
603 601
604 link->resource[0]->end = 16; 602 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
603
605 i = pcmcia_loop_config(link, smc_configcheck, NULL); 604 i = pcmcia_loop_config(link, smc_configcheck, NULL);
606 if (!i) 605 if (!i)
607 dev->base_addr = link->resource[0]->start; 606 dev->base_addr = link->resource[0]->start;
@@ -634,7 +633,7 @@ static int osi_config(struct pcmcia_device *link)
634 static const unsigned int com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; 633 static const unsigned int com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
635 int i, j; 634 int i, j;
636 635
637 link->config_flags |= CONF_ENABLE_SPKR; 636 link->config_flags |= CONF_ENABLE_SPKR | CONF_ENABLE_IRQ;
638 link->resource[0]->end = 64; 637 link->resource[0]->end = 64;
639 link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; 638 link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
640 link->resource[1]->end = 8; 639 link->resource[1]->end = 8;
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 2bc2eb89c4cd..cecc07454e9e 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -528,7 +528,6 @@ xirc2ps_probe(struct pcmcia_device *link)
528 link->priv = dev; 528 link->priv = dev;
529 529
530 /* General socket configuration */ 530 /* General socket configuration */
531 link->config_flags |= CONF_ENABLE_IRQ;
532 link->config_index = 1; 531 link->config_index = 1;
533 532
534 /* Fill in card specific entries */ 533 /* Fill in card specific entries */
@@ -665,42 +664,53 @@ has_ce2_string(struct pcmcia_device * p_dev)
665} 664}
666 665
667static int 666static int
668xirc2ps_config_modem(struct pcmcia_device *p_dev, 667xirc2ps_config_modem(struct pcmcia_device *p_dev, void *priv_data)
669 cistpl_cftable_entry_t *cf,
670 cistpl_cftable_entry_t *dflt,
671 void *priv_data)
672{ 668{
673 unsigned int ioaddr; 669 unsigned int ioaddr;
674 670
675 if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { 671 if ((p_dev->resource[0]->start & 0xf) == 8)
676 for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { 672 return -ENODEV;
677 p_dev->resource[1]->start = cf->io.win[0].base; 673
678 p_dev->resource[0]->start = ioaddr; 674 p_dev->resource[0]->end = 16;
679 if (!pcmcia_request_io(p_dev)) 675 p_dev->resource[1]->end = 8;
680 return 0; 676 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
681 } 677 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
678 p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
679 p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
680 p_dev->io_lines = 10;
681
682 p_dev->resource[1]->start = p_dev->resource[0]->start;
683 for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
684 p_dev->resource[0]->start = ioaddr;
685 if (!pcmcia_request_io(p_dev))
686 return 0;
682 } 687 }
683 return -ENODEV; 688 return -ENODEV;
684} 689}
685 690
686static int 691static int
687xirc2ps_config_check(struct pcmcia_device *p_dev, 692xirc2ps_config_check(struct pcmcia_device *p_dev, void *priv_data)
688 cistpl_cftable_entry_t *cf,
689 cistpl_cftable_entry_t *dflt,
690 void *priv_data)
691{ 693{
692 int *pass = priv_data; 694 int *pass = priv_data;
695 resource_size_t tmp = p_dev->resource[1]->start;
693 696
694 if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { 697 tmp += (*pass ? (p_dev->config_index & 0x20 ? -24 : 8)
695 p_dev->resource[1]->start = cf->io.win[0].base; 698 : (p_dev->config_index & 0x20 ? 8 : -24));
696 p_dev->resource[0]->start = p_dev->resource[1]->start 699
697 + (*pass ? (cf->index & 0x20 ? -24:8) 700 if ((p_dev->resource[0]->start & 0xf) == 8)
698 : (cf->index & 0x20 ? 8:-24)); 701 return -ENODEV;
699 if (!pcmcia_request_io(p_dev)) 702
700 return 0; 703 p_dev->resource[0]->end = 18;
701 } 704 p_dev->resource[1]->end = 8;
702 return -ENODEV; 705 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
706 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
707 p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
708 p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
709 p_dev->io_lines = 10;
703 710
711 p_dev->resource[1]->start = p_dev->resource[0]->start;
712 p_dev->resource[0]->start = tmp;
713 return pcmcia_request_io(p_dev);
704} 714}
705 715
706 716
@@ -803,21 +813,16 @@ xirc2ps_config(struct pcmcia_device * link)
803 goto failure; 813 goto failure;
804 } 814 }
805 815
806 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
807 link->io_lines = 10;
808 if (local->modem) { 816 if (local->modem) {
809 int pass; 817 int pass;
818 link->config_flags |= CONF_AUTO_SET_IO;
810 819
811 link->resource[1]->end = 8;
812 link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
813 if (local->dingo) { 820 if (local->dingo) {
814 /* Take the Modem IO port from the CIS and scan for a free 821 /* Take the Modem IO port from the CIS and scan for a free
815 * Ethernet port */ 822 * Ethernet port */
816 link->resource[0]->end = 16; /* no Mako stuff anymore */
817 if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL)) 823 if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
818 goto port_found; 824 goto port_found;
819 } else { 825 } else {
820 link->resource[0]->end = 18;
821 /* We do 2 passes here: The first one uses the regular mapping and 826 /* We do 2 passes here: The first one uses the regular mapping and
822 * the second tries again, thereby considering that the 32 ports are 827 * the second tries again, thereby considering that the 32 ports are
823 * mirrored every 32 bytes. Actually we use a mirrored port for 828 * mirrored every 32 bytes. Actually we use a mirrored port for
@@ -833,7 +838,9 @@ xirc2ps_config(struct pcmcia_device * link)
833 } 838 }
834 printk(KNOT_XIRC "no ports available\n"); 839 printk(KNOT_XIRC "no ports available\n");
835 } else { 840 } else {
841 link->io_lines = 10;
836 link->resource[0]->end = 16; 842 link->resource[0]->end = 16;
843 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
837 for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { 844 for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
838 link->resource[0]->start = ioaddr; 845 link->resource[0]->start = ioaddr;
839 if (!(err = pcmcia_request_io(link))) 846 if (!(err = pcmcia_request_io(link)))