aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/pcmcia/driver-changes.txt12
-rw-r--r--drivers/ata/pata_pcmcia.c81
-rw-r--r--drivers/bluetooth/bt3c_cs.c53
-rw-r--r--drivers/bluetooth/btuart_cs.c51
-rw-r--r--drivers/bluetooth/dtl1_cs.c18
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c15
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c22
-rw-r--r--drivers/char/pcmcia/ipwireless/main.c26
-rw-r--r--drivers/char/pcmcia/synclink_cs.c16
-rw-r--r--drivers/ide/ide-cs.c82
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c19
-rw-r--r--drivers/isdn/hisax/avma1_cs.c22
-rw-r--r--drivers/isdn/hisax/elsa_cs.c23
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c36
-rw-r--r--drivers/isdn/hisax/teles_cs.c16
-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
-rw-r--r--drivers/net/wireless/airo_cs.c34
-rw-r--r--drivers/net/wireless/atmel_cs.c28
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c43
-rw-r--r--drivers/net/wireless/libertas/if_cs.c16
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c41
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c45
-rw-r--r--drivers/parport/parport_cs.c34
-rw-r--r--drivers/pcmcia/pcmcia_cis.c78
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c34
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c13
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c47
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c13
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c13
-rw-r--r--drivers/serial/serial_cs.c132
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c31
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c33
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c32
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c32
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c32
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c14
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c32
-rw-r--r--drivers/telephony/ixj_pcmcia.c32
-rw-r--r--drivers/usb/host/sl811_cs.c26
-rw-r--r--include/pcmcia/ds.h30
44 files changed, 515 insertions, 1025 deletions
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index 62a029f24f46..dd04361dd361 100644
--- a/Documentation/pcmcia/driver-changes.txt
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -1,4 +1,16 @@
1This file details changes in 2.6 which affect PCMCIA card driver authors: 1This file details changes in 2.6 which affect PCMCIA card driver authors:
2* pcmcia_loop_config() and autoconfiguration (as of 2.6.36)
3 If struct pcmcia_device *p_dev->config_flags is set accordingly,
4 pcmcia_loop_config() now sets up certain configuration values
5 automatically, though the driver may still override the settings
6 in the callback function. The following autoconfiguration options
7 are provided at the moment:
8 CONF_AUTO_CHECK_VCC : check for matching Vcc
9 CONF_AUTO_SET_VPP : set Vpp
10 CONF_AUTO_AUDIO : auto-enable audio line, if required
11 CONF_AUTO_SET_IO : set ioport resources (->resource[0,1])
12 CONF_AUTO_SET_IOMEM : set first iomem resource (->resource[2])
13
2* pcmcia_request_configuration -> pcmcia_enable_device (as of 2.6.36) 14* pcmcia_request_configuration -> pcmcia_enable_device (as of 2.6.36)
3 pcmcia_request_configuration() got renamed to pcmcia_enable_device(), 15 pcmcia_request_configuration() got renamed to pcmcia_enable_device(),
4 as it mirrors pcmcia_disable_device(). Configuration settings are now 16 as it mirrors pcmcia_disable_device(). Configuration settings are now
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 954f43c512f1..88cb03c36963 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -167,45 +167,26 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
167}; 167};
168 168
169 169
170struct pcmcia_config_check { 170static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
171 unsigned long ctl_base;
172 int is_kme;
173};
174
175static int pcmcia_check_one_config(struct pcmcia_device *pdev,
176 cistpl_cftable_entry_t *cfg,
177 cistpl_cftable_entry_t *dflt,
178 void *priv_data)
179{ 171{
180 struct pcmcia_config_check *stk = priv_data; 172 int *is_kme = priv_data;
181 173
182 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { 174 if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) {
183 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; 175 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
184 pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK; 176 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
185 pdev->resource[0]->start = io->win[0].base; 177 }
186 if (!(io->flags & CISTPL_IO_16BIT)) { 178 pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
187 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; 179 pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
188 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 180
189 } 181 if (pdev->resource[1]->end) {
190 if (io->nwin == 2) { 182 pdev->resource[0]->end = 8;
191 pdev->resource[0]->end = 8; 183 pdev->resource[1]->end = (*is_kme) ? 2 : 1;
192 pdev->resource[1]->start = io->win[1].base; 184 } else {
193 pdev->resource[1]->end = (stk->is_kme) ? 2 : 1; 185 if (pdev->resource[0]->end < 16)
194 if (pcmcia_request_io(pdev) != 0)
195 return -ENODEV;
196 stk->ctl_base = pdev->resource[1]->start;
197 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
198 pdev->resource[0]->end = io->win[0].len;
199 pdev->resource[1]->end = 0;
200 if (pcmcia_request_io(pdev) != 0)
201 return -ENODEV;
202 stk->ctl_base = pdev->resource[0]->start + 0x0e;
203 } else
204 return -ENODEV; 186 return -ENODEV;
205 /* If we've got this far, we're done */
206 return 0;
207 } 187 }
208 return -ENODEV; 188
189 return pcmcia_request_io(pdev);
209} 190}
210 191
211/** 192/**
@@ -220,7 +201,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
220{ 201{
221 struct ata_host *host; 202 struct ata_host *host;
222 struct ata_port *ap; 203 struct ata_port *ap;
223 struct pcmcia_config_check *stk = NULL;
224 int is_kme = 0, ret = -ENOMEM, p; 204 int is_kme = 0, ret = -ENOMEM, p;
225 unsigned long io_base, ctl_base; 205 unsigned long io_base, ctl_base;
226 void __iomem *io_addr, *ctl_addr; 206 void __iomem *io_addr, *ctl_addr;
@@ -228,10 +208,8 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
228 struct ata_port_operations *ops = &pcmcia_port_ops; 208 struct ata_port_operations *ops = &pcmcia_port_ops;
229 209
230 /* Set up attributes in order to probe card and get resources */ 210 /* Set up attributes in order to probe card and get resources */
231 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; 211 pdev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
232 pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; 212 CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
233 pdev->config_flags |= CONF_ENABLE_IRQ;
234 pdev->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
235 213
236 /* See if we have a manufacturer identifier. Use it to set is_kme for 214 /* See if we have a manufacturer identifier. Use it to set is_kme for
237 vendor quirks */ 215 vendor quirks */
@@ -239,21 +217,17 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
239 ((pdev->card_id == PRODID_KME_KXLC005_A) || 217 ((pdev->card_id == PRODID_KME_KXLC005_A) ||
240 (pdev->card_id == PRODID_KME_KXLC005_B))); 218 (pdev->card_id == PRODID_KME_KXLC005_B)));
241 219
242 /* Allocate resoure probing structures */ 220 if (pcmcia_loop_config(pdev, pcmcia_check_one_config, &is_kme)) {
243
244 stk = kzalloc(sizeof(*stk), GFP_KERNEL);
245 if (!stk)
246 goto out1;
247 stk->is_kme = is_kme;
248 io_base = ctl_base = 0;
249
250 if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) {
251 pdev->config_flags &= ~CONF_AUTO_CHECK_VCC; 221 pdev->config_flags &= ~CONF_AUTO_CHECK_VCC;
252 if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) 222 if (pcmcia_loop_config(pdev, pcmcia_check_one_config, &is_kme))
253 goto failed; /* No suitable config found */ 223 goto failed; /* No suitable config found */
254 } 224 }
255 io_base = pdev->resource[0]->start; 225 io_base = pdev->resource[0]->start;
256 ctl_base = stk->ctl_base; 226 if (pdev->resource[1]->end)
227 ctl_base = pdev->resource[1]->start;
228 else
229 ctl_base = pdev->resource[0]->start + 0x0e;
230
257 if (!pdev->irq) 231 if (!pdev->irq)
258 goto failed; 232 goto failed;
259 233
@@ -310,13 +284,10 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
310 goto failed; 284 goto failed;
311 285
312 pdev->priv = host; 286 pdev->priv = host;
313 kfree(stk);
314 return 0; 287 return 0;
315 288
316failed: 289failed:
317 kfree(stk);
318 pcmcia_disable_device(pdev); 290 pcmcia_disable_device(pdev);
319out1:
320 return ret; 291 return ret;
321} 292}
322 293
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 97338a3aae1a..8b8be35fe312 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -656,10 +656,8 @@ static int bt3c_probe(struct pcmcia_device *link)
656 info->p_dev = link; 656 info->p_dev = link;
657 link->priv = info; 657 link->priv = info;
658 658
659 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 659 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
660 link->resource[0]->end = 8; 660 CONF_AUTO_SET_IO;
661
662 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP;
663 661
664 return bt3c_config(link); 662 return bt3c_config(link);
665} 663}
@@ -673,38 +671,41 @@ static void bt3c_detach(struct pcmcia_device *link)
673 kfree(info); 671 kfree(info);
674} 672}
675 673
676static int bt3c_check_config(struct pcmcia_device *p_dev, 674static int bt3c_check_config(struct pcmcia_device *p_dev, void *priv_data)
677 cistpl_cftable_entry_t *cf,
678 cistpl_cftable_entry_t *dflt,
679 void *priv_data)
680{ 675{
681 unsigned long try = (unsigned long) priv_data; 676 int *try = priv_data;
682 p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
683 677
684 if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && 678 if (try == 0)
685 (cf->io.win[0].base != 0)) { 679 p_dev->io_lines = 16;
686 p_dev->resource[0]->start = cf->io.win[0].base; 680
687 if (!pcmcia_request_io(p_dev)) 681 if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0))
688 return 0; 682 return -EINVAL;
689 } 683
690 return -ENODEV; 684 p_dev->resource[0]->end = 8;
685 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
686 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
687
688 return pcmcia_request_io(p_dev);
691} 689}
692 690
693static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev, 691static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
694 cistpl_cftable_entry_t *cf,
695 cistpl_cftable_entry_t *dflt,
696 void *priv_data) 692 void *priv_data)
697{ 693{
698 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; 694 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
699 int j; 695 int j;
700 696
701 if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { 697 if (p_dev->io_lines > 3)
702 for (j = 0; j < 5; j++) { 698 return -ENODEV;
703 p_dev->resource[0]->start = base[j]; 699
704 p_dev->io_lines = base[j] ? 16 : 3; 700 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
705 if (!pcmcia_request_io(p_dev)) 701 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
706 return 0; 702 p_dev->resource[0]->end = 8;
707 } 703
704 for (j = 0; j < 5; j++) {
705 p_dev->resource[0]->start = base[j];
706 p_dev->io_lines = base[j] ? 16 : 3;
707 if (!pcmcia_request_io(p_dev))
708 return 0;
708 } 709 }
709 return -ENODEV; 710 return -ENODEV;
710} 711}
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 8a6864fc8c38..9f9bb69dc0a2 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -585,10 +585,8 @@ static int btuart_probe(struct pcmcia_device *link)
585 info->p_dev = link; 585 info->p_dev = link;
586 link->priv = info; 586 link->priv = info;
587 587
588 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 588 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
589 link->resource[0]->end = 8; 589 CONF_AUTO_SET_IO;
590
591 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP;
592 590
593 return btuart_config(link); 591 return btuart_config(link);
594} 592}
@@ -602,38 +600,41 @@ static void btuart_detach(struct pcmcia_device *link)
602 kfree(info); 600 kfree(info);
603} 601}
604 602
605static int btuart_check_config(struct pcmcia_device *p_dev, 603static int btuart_check_config(struct pcmcia_device *p_dev, void *priv_data)
606 cistpl_cftable_entry_t *cf,
607 cistpl_cftable_entry_t *dflt,
608 void *priv_data)
609{ 604{
610 int *try = priv_data; 605 int *try = priv_data;
611 p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
612 606
613 if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && 607 if (try == 0)
614 (cf->io.win[0].base != 0)) { 608 p_dev->io_lines = 16;
615 p_dev->resource[0]->start = cf->io.win[0].base; 609
616 if (!pcmcia_request_io(p_dev)) 610 if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0))
617 return 0; 611 return -EINVAL;
618 } 612
619 return -ENODEV; 613 p_dev->resource[0]->end = 8;
614 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
615 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
616
617 return pcmcia_request_io(p_dev);
620} 618}
621 619
622static int btuart_check_config_notpicky(struct pcmcia_device *p_dev, 620static int btuart_check_config_notpicky(struct pcmcia_device *p_dev,
623 cistpl_cftable_entry_t *cf,
624 cistpl_cftable_entry_t *dflt,
625 void *priv_data) 621 void *priv_data)
626{ 622{
627 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; 623 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
628 int j; 624 int j;
629 625
630 if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { 626 if (p_dev->io_lines > 3)
631 for (j = 0; j < 5; j++) { 627 return -ENODEV;
632 p_dev->resource[0]->start = base[j]; 628
633 p_dev->io_lines = base[j] ? 16 : 3; 629 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
634 if (!pcmcia_request_io(p_dev)) 630 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
635 return 0; 631 p_dev->resource[0]->end = 8;
636 } 632
633 for (j = 0; j < 5; j++) {
634 p_dev->resource[0]->start = base[j];
635 p_dev->io_lines = base[j] ? 16 : 3;
636 if (!pcmcia_request_io(p_dev))
637 return 0;
637 } 638 }
638 return -ENODEV; 639 return -ENODEV;
639} 640}
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 4620cc398676..12cd177132fc 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -571,10 +571,7 @@ static int dtl1_probe(struct pcmcia_device *link)
571 info->p_dev = link; 571 info->p_dev = link;
572 link->priv = info; 572 link->priv = info;
573 573
574 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 574 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
575 link->resource[0]->end = 8;
576
577 link->config_flags |= CONF_ENABLE_IRQ;
578 575
579 return dtl1_config(link); 576 return dtl1_config(link);
580} 577}
@@ -589,17 +586,14 @@ static void dtl1_detach(struct pcmcia_device *link)
589 kfree(info); 586 kfree(info);
590} 587}
591 588
592static int dtl1_confcheck(struct pcmcia_device *p_dev, 589static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data)
593 cistpl_cftable_entry_t *cf,
594 cistpl_cftable_entry_t *dflt,
595 void *priv_data)
596{ 590{
597 if ((cf->io.nwin != 1) || (cf->io.win[0].len <= 8)) 591 if ((p_dev->resource[1]->end) || (p_dev->resource[1]->end < 8))
598 return -ENODEV; 592 return -ENODEV;
599 593
600 p_dev->resource[0]->start = cf->io.win[0].base; 594 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
601 p_dev->resource[0]->end = cf->io.win[0].len; /*yo */ 595 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
602 p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; 596
603 return pcmcia_request_io(p_dev); 597 return pcmcia_request_io(p_dev);
604} 598}
605 599
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 0b2f3b9d261a..79de9ccb8caf 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1741,19 +1741,8 @@ static void cmm_cm4000_release(struct pcmcia_device * link)
1741 1741
1742/*==== Interface to PCMCIA Layer =======================================*/ 1742/*==== Interface to PCMCIA Layer =======================================*/
1743 1743
1744static int cm4000_config_check(struct pcmcia_device *p_dev, 1744static int cm4000_config_check(struct pcmcia_device *p_dev, void *priv_data)
1745 cistpl_cftable_entry_t *cfg,
1746 cistpl_cftable_entry_t *dflt,
1747 void *priv_data)
1748{ 1745{
1749 if (!cfg->io.nwin)
1750 return -ENODEV;
1751
1752 p_dev->resource[0]->start = cfg->io.win[0].base;
1753 p_dev->resource[0]->end = cfg->io.win[0].len;
1754 p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags);
1755 p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK;
1756
1757 return pcmcia_request_io(p_dev); 1746 return pcmcia_request_io(p_dev);
1758} 1747}
1759 1748
@@ -1761,6 +1750,8 @@ static int cm4000_config(struct pcmcia_device * link, int devno)
1761{ 1750{
1762 struct cm4000_dev *dev; 1751 struct cm4000_dev *dev;
1763 1752
1753 link->config_flags |= CONF_AUTO_SET_IO;
1754
1764 /* read the config-tuples */ 1755 /* read the config-tuples */
1765 if (pcmcia_loop_config(link, cm4000_config_check, NULL)) 1756 if (pcmcia_loop_config(link, cm4000_config_check, NULL))
1766 goto cs_release; 1757 goto cs_release;
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index acf88d5c72b2..bf012d228a9e 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -515,25 +515,9 @@ static void cm4040_reader_release(struct pcmcia_device *link)
515 return; 515 return;
516} 516}
517 517
518static int cm4040_config_check(struct pcmcia_device *p_dev, 518static int cm4040_config_check(struct pcmcia_device *p_dev, void *priv_data)
519 cistpl_cftable_entry_t *cfg,
520 cistpl_cftable_entry_t *dflt,
521 void *priv_data)
522{ 519{
523 int rc; 520 return pcmcia_request_io(p_dev);
524 if (!cfg->io.nwin)
525 return -ENODEV;
526
527 /* Get the IOaddr */
528 p_dev->resource[0]->start = cfg->io.win[0].base;
529 p_dev->resource[0]->end = cfg->io.win[0].len;
530 p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags);
531 p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK;
532 rc = pcmcia_request_io(p_dev);
533
534 dev_printk(KERN_INFO, &p_dev->dev,
535 "pcmcia_request_io returned 0x%x\n", rc);
536 return rc;
537} 521}
538 522
539 523
@@ -542,6 +526,8 @@ static int reader_config(struct pcmcia_device *link, int devno)
542 struct reader_dev *dev; 526 struct reader_dev *dev;
543 int fail_rc; 527 int fail_rc;
544 528
529 link->config_flags |= CONF_AUTO_SET_IO;
530
545 if (pcmcia_loop_config(link, cm4040_config_check, NULL)) 531 if (pcmcia_loop_config(link, cm4040_config_check, NULL))
546 goto cs_release; 532 goto cs_release;
547 533
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c
index 1b7f0920737b..594c23be69f5 100644
--- a/drivers/char/pcmcia/ipwireless/main.c
+++ b/drivers/char/pcmcia/ipwireless/main.c
@@ -75,22 +75,18 @@ static void signalled_reboot_callback(void *callback_data)
75 schedule_work(&ipw->work_reboot); 75 schedule_work(&ipw->work_reboot);
76} 76}
77 77
78static int ipwireless_probe(struct pcmcia_device *p_dev, 78static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data)
79 cistpl_cftable_entry_t *cfg,
80 cistpl_cftable_entry_t *dflt,
81 void *priv_data)
82{ 79{
83 struct ipw_dev *ipw = priv_data; 80 struct ipw_dev *ipw = priv_data;
84 struct resource *io_resource; 81 struct resource *io_resource;
85 int ret; 82 int ret;
86 83
84 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
87 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; 85 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
88 p_dev->resource[0]->start = cfg->io.win[0].base;
89 p_dev->resource[0]->end = cfg->io.win[0].len;
90 86
91 /* 0x40 causes it to generate level mode interrupts. */ 87 /* 0x40 causes it to generate level mode interrupts. */
92 /* 0x04 enables IREQ pin. */ 88 /* 0x04 enables IREQ pin. */
93 p_dev->config_index = cfg->index | 0x44; 89 p_dev->config_index |= 0x44;
94 p_dev->io_lines = 16; 90 p_dev->io_lines = 16;
95 ret = pcmcia_request_io(p_dev); 91 ret = pcmcia_request_io(p_dev);
96 if (ret) 92 if (ret)
@@ -100,26 +96,18 @@ static int ipwireless_probe(struct pcmcia_device *p_dev,
100 resource_size(p_dev->resource[0]), 96 resource_size(p_dev->resource[0]),
101 IPWIRELESS_PCCARD_NAME); 97 IPWIRELESS_PCCARD_NAME);
102 98
103 if (cfg->mem.nwin == 0)
104 return 0;
105
106 p_dev->resource[2]->flags |= 99 p_dev->resource[2]->flags |=
107 WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; 100 WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
108 p_dev->resource[2]->start = cfg->mem.win[0].host_addr;
109 p_dev->resource[2]->end = cfg->mem.win[0].len;
110 if (p_dev->resource[2]->end < 0x1000)
111 p_dev->resource[2]->end = 0x1000;
112 101
113 ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0); 102 ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0);
114 if (ret != 0) 103 if (ret != 0)
115 goto exit1; 104 goto exit1;
116 105
117 ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], 106 ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], p_dev->card_addr);
118 cfg->mem.win[0].card_addr);
119 if (ret != 0) 107 if (ret != 0)
120 goto exit2; 108 goto exit2;
121 109
122 ipw->is_v2_card = cfg->mem.win[0].len == 0x100; 110 ipw->is_v2_card = resource_size(p_dev->resource[2]) == 0x100;
123 111
124 ipw->attr_memory = ioremap(p_dev->resource[2]->start, 112 ipw->attr_memory = ioremap(p_dev->resource[2]->start,
125 resource_size(p_dev->resource[2])); 113 resource_size(p_dev->resource[2]));
@@ -165,13 +153,13 @@ static int config_ipwireless(struct ipw_dev *ipw)
165 int ret = 0; 153 int ret = 0;
166 154
167 ipw->is_v2_card = 0; 155 ipw->is_v2_card = 0;
156 link->config_flags |= CONF_AUTO_SET_IO | CONF_AUTO_SET_IOMEM |
157 CONF_ENABLE_IRQ;
168 158
169 ret = pcmcia_loop_config(link, ipwireless_probe, ipw); 159 ret = pcmcia_loop_config(link, ipwireless_probe, ipw);
170 if (ret != 0) 160 if (ret != 0)
171 return ret; 161 return ret;
172 162
173 link->config_flags |= CONF_ENABLE_IRQ;
174
175 INIT_WORK(&ipw->work_reboot, signalled_reboot_work); 163 INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
176 164
177 ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start, 165 ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start,
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index c701434f76b7..a343b8f817e4 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -561,19 +561,8 @@ static int mgslpc_probe(struct pcmcia_device *link)
561/* Card has been inserted. 561/* Card has been inserted.
562 */ 562 */
563 563
564static int mgslpc_ioprobe(struct pcmcia_device *p_dev, 564static int mgslpc_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
565 cistpl_cftable_entry_t *cfg,
566 cistpl_cftable_entry_t *dflt,
567 void *priv_data)
568{ 565{
569 if (!cfg->io.nwin)
570 return -ENODEV;
571
572 p_dev->resource[0]->start = cfg->io.win[0].base;
573 p_dev->resource[0]->end = cfg->io.win[0].len;
574 p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags);
575 p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK;
576
577 return pcmcia_request_io(p_dev); 566 return pcmcia_request_io(p_dev);
578} 567}
579 568
@@ -585,11 +574,12 @@ static int mgslpc_config(struct pcmcia_device *link)
585 if (debug_level >= DEBUG_LEVEL_INFO) 574 if (debug_level >= DEBUG_LEVEL_INFO)
586 printk("mgslpc_config(0x%p)\n", link); 575 printk("mgslpc_config(0x%p)\n", link);
587 576
577 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
578
588 ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL); 579 ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
589 if (ret != 0) 580 if (ret != 0)
590 goto failed; 581 goto failed;
591 582
592 link->config_flags |= CONF_ENABLE_IRQ;
593 link->config_index = 8; 583 link->config_index = 8;
594 link->config_regs = PRESENT_OPTION; 584 link->config_regs = PRESENT_OPTION;
595 585
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
index 25b8a105a98d..c389d9a28881 100644
--- a/drivers/ide/ide-cs.c
+++ b/drivers/ide/ide-cs.c
@@ -96,10 +96,8 @@ static int ide_probe(struct pcmcia_device *link)
96 info->p_dev = link; 96 info->p_dev = link;
97 link->priv = info; 97 link->priv = info;
98 98
99 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; 99 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
100 link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; 100 CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
101 link->config_flags |= CONF_ENABLE_IRQ;
102 link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
103 101
104 return ide_config(link); 102 return ide_config(link);
105} /* ide_attach */ 103} /* ide_attach */
@@ -194,52 +192,31 @@ out_release:
194 192
195======================================================================*/ 193======================================================================*/
196 194
197struct pcmcia_config_check { 195static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
198 unsigned long ctl_base;
199 int is_kme;
200};
201
202static int pcmcia_check_one_config(struct pcmcia_device *pdev,
203 cistpl_cftable_entry_t *cfg,
204 cistpl_cftable_entry_t *dflt,
205 void *priv_data)
206{ 196{
207 struct pcmcia_config_check *stk = priv_data; 197 int *is_kme = priv_data;
208 198
209 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { 199 if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) {
210 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; 200 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
211 pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK; 201 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
212 pdev->config_index = cfg->index; 202 }
213 pdev->resource[0]->start = io->win[0].base; 203 pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
214 if (!(io->flags & CISTPL_IO_16BIT)) { 204 pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
215 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; 205
216 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 206 if (pdev->resource[1]->end) {
217 } 207 pdev->resource[0]->end = 8;
218 if (io->nwin == 2) { 208 pdev->resource[1]->end = (*is_kme) ? 2 : 1;
219 pdev->resource[0]->end = 8; 209 } else {
220 pdev->resource[1]->start = io->win[1].base; 210 if (pdev->resource[0]->end < 16)
221 pdev->resource[1]->end = (stk->is_kme) ? 2 : 1;
222 if (pcmcia_request_io(pdev) != 0)
223 return -ENODEV;
224 stk->ctl_base = pdev->resource[1]->start;
225 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
226 pdev->resource[0]->end = io->win[0].len;
227 pdev->resource[1]->end = 0;
228 if (pcmcia_request_io(pdev) != 0)
229 return -ENODEV;
230 stk->ctl_base = pdev->resource[0]->start + 0x0e;
231 } else
232 return -ENODEV; 211 return -ENODEV;
233 /* If we've got this far, we're done */
234 return 0;
235 } 212 }
236 return -ENODEV; 213
214 return pcmcia_request_io(pdev);
237} 215}
238 216
239static int ide_config(struct pcmcia_device *link) 217static int ide_config(struct pcmcia_device *link)
240{ 218{
241 ide_info_t *info = link->priv; 219 ide_info_t *info = link->priv;
242 struct pcmcia_config_check *stk = NULL;
243 int ret = 0, is_kme = 0; 220 int ret = 0, is_kme = 0;
244 unsigned long io_base, ctl_base; 221 unsigned long io_base, ctl_base;
245 struct ide_host *host; 222 struct ide_host *host;
@@ -250,19 +227,16 @@ static int ide_config(struct pcmcia_device *link)
250 ((link->card_id == PRODID_KME_KXLC005_A) || 227 ((link->card_id == PRODID_KME_KXLC005_A) ||
251 (link->card_id == PRODID_KME_KXLC005_B))); 228 (link->card_id == PRODID_KME_KXLC005_B)));
252 229
253 stk = kzalloc(sizeof(*stk), GFP_KERNEL); 230 if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme)) {
254 if (!stk)
255 goto err_mem;
256 stk->is_kme = is_kme;
257 io_base = ctl_base = 0;
258
259 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) {
260 link->config_flags &= ~CONF_AUTO_CHECK_VCC; 231 link->config_flags &= ~CONF_AUTO_CHECK_VCC;
261 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) 232 if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme))
262 goto failed; /* No suitable config found */ 233 goto failed; /* No suitable config found */
263 } 234 }
264 io_base = link->resource[0]->start; 235 io_base = link->resource[0]->start;
265 ctl_base = stk->ctl_base; 236 if (link->resource[1]->end)
237 ctl_base = link->resource[1]->start;
238 else
239 ctl_base = link->resource[0]->start + 0x0e;
266 240
267 if (!link->irq) 241 if (!link->irq)
268 goto failed; 242 goto failed;
@@ -294,15 +268,9 @@ static int ide_config(struct pcmcia_device *link)
294 'a' + host->ports[0]->index * 2, 268 'a' + host->ports[0]->index * 2,
295 link->vpp / 10, link->vpp % 10); 269 link->vpp / 10, link->vpp % 10);
296 270
297 kfree(stk);
298 return 0; 271 return 0;
299 272
300err_mem:
301 printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
302 goto failed;
303
304failed: 273failed:
305 kfree(stk);
306 ide_release(link); 274 ide_release(link);
307 return -ENODEV; 275 return -ENODEV;
308} /* ide_config */ 276} /* ide_config */
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index 9dbab9c99bea..403a995bec95 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -72,13 +72,8 @@ static void avmcs_detach(struct pcmcia_device *p_dev);
72 72
73static int avmcs_probe(struct pcmcia_device *p_dev) 73static int avmcs_probe(struct pcmcia_device *p_dev)
74{ 74{
75
76 /* The io structure describes IO port mapping */
77 p_dev->resource[0]->end = 16;
78 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
79
80 /* General socket configuration */ 75 /* General socket configuration */
81 p_dev->config_flags |= CONF_ENABLE_IRQ; 76 p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
82 p_dev->config_index = 1; 77 p_dev->config_index = 1;
83 p_dev->config_regs = PRESENT_OPTION; 78 p_dev->config_regs = PRESENT_OPTION;
84 79
@@ -107,16 +102,12 @@ static void avmcs_detach(struct pcmcia_device *link)
107 102
108======================================================================*/ 103======================================================================*/
109 104
110static int avmcs_configcheck(struct pcmcia_device *p_dev, 105static int avmcs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
111 cistpl_cftable_entry_t *cf,
112 cistpl_cftable_entry_t *dflt,
113 void *priv_data)
114{ 106{
115 if (cf->io.nwin <= 0) 107 p_dev->resource[0]->end = 16;
116 return -ENODEV; 108 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
109 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
117 110
118 p_dev->resource[0]->start = cf->io.win[0].base;
119 p_dev->resource[0]->end = cf->io.win[0].len;
120 return pcmcia_request_io(p_dev); 111 return pcmcia_request_io(p_dev);
121} 112}
122 113
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 2f2b0005f07b..cb09f0cacd12 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -76,14 +76,8 @@ static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
76{ 76{
77 dev_dbg(&p_dev->dev, "avma1cs_attach()\n"); 77 dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
78 78
79 /* The io structure describes IO port mapping */
80 p_dev->resource[0]->end = 16;
81 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
82 p_dev->resource[1]->end = 16;
83 p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
84
85 /* General socket configuration */ 79 /* General socket configuration */
86 p_dev->config_flags |= CONF_ENABLE_IRQ; 80 p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
87 p_dev->config_index = 1; 81 p_dev->config_index = 1;
88 p_dev->config_regs = PRESENT_OPTION; 82 p_dev->config_regs = PRESENT_OPTION;
89 83
@@ -114,17 +108,13 @@ static void __devexit avma1cs_detach(struct pcmcia_device *link)
114 108
115======================================================================*/ 109======================================================================*/
116 110
117static int avma1cs_configcheck(struct pcmcia_device *p_dev, 111static int avma1cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
118 cistpl_cftable_entry_t *cf,
119 cistpl_cftable_entry_t *dflt,
120 void *priv_data)
121{ 112{
122 if (cf->io.nwin <= 0) 113 p_dev->resource[0]->end = 16;
123 return -ENODEV; 114 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
124 115 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
125 p_dev->resource[0]->start = cf->io.win[0].base;
126 p_dev->resource[0]->end = cf->io.win[0].len;
127 p_dev->io_lines = 5; 116 p_dev->io_lines = 5;
117
128 return pcmcia_request_io(p_dev); 118 return pcmcia_request_io(p_dev);
129} 119}
130 120
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 0a65280be8d5..f203a52aab2a 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -118,16 +118,6 @@ static int __devinit elsa_cs_probe(struct pcmcia_device *link)
118 118
119 local->cardnr = -1; 119 local->cardnr = -1;
120 120
121 /*
122 General socket configuration defaults can go here. In this
123 client, we assume very little, and rely on the CIS for almost
124 everything. In most clients, many details (i.e., number, sizes,
125 and attributes of IO windows) are fixed by the nature of the
126 device, and can be hard-wired here.
127 */
128 link->resource[0]->end = 8;
129 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
130
131 return elsa_cs_config(link); 121 return elsa_cs_config(link);
132} /* elsa_cs_attach */ 122} /* elsa_cs_attach */
133 123
@@ -160,18 +150,17 @@ static void __devexit elsa_cs_detach(struct pcmcia_device *link)
160 150
161======================================================================*/ 151======================================================================*/
162 152
163static int elsa_cs_configcheck(struct pcmcia_device *p_dev, 153static int elsa_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
164 cistpl_cftable_entry_t *cf,
165 cistpl_cftable_entry_t *dflt,
166 void *priv_data)
167{ 154{
168 int j; 155 int j;
169 156
170 p_dev->io_lines = 3; 157 p_dev->io_lines = 3;
158 p_dev->resource[0]->end = 8;
159 p_dev->resource[0]->flags &= IO_DATA_PATH_WIDTH;
160 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
171 161
172 if ((cf->io.nwin > 0) && cf->io.win[0].base) { 162 if ((p_dev->resource[0]->end) && p_dev->resource[0]->start) {
173 printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); 163 printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
174 p_dev->resource[0]->start = cf->io.win[0].base;
175 if (!pcmcia_request_io(p_dev)) 164 if (!pcmcia_request_io(p_dev))
176 return 0; 165 return 0;
177 } else { 166 } else {
@@ -194,6 +183,8 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link)
194 dev_dbg(&link->dev, "elsa_config(0x%p)\n", link); 183 dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
195 dev = link->priv; 184 dev = link->priv;
196 185
186 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
187
197 i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL); 188 i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
198 if (i != 0) 189 if (i != 0)
199 goto failed; 190 goto failed;
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index b69eccfdbb05..a88c88f6cdeb 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -128,8 +128,6 @@ static int __devinit sedlbauer_probe(struct pcmcia_device *link)
128 /* from old sedl_cs 128 /* from old sedl_cs
129 */ 129 */
130 /* The io structure describes IO port mapping */ 130 /* The io structure describes IO port mapping */
131 link->resource[0]->end = 8;
132 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
133 131
134 return sedlbauer_config(link); 132 return sedlbauer_config(link);
135} /* sedlbauer_attach */ 133} /* sedlbauer_attach */
@@ -161,35 +159,13 @@ static void __devexit sedlbauer_detach(struct pcmcia_device *link)
161 device available to the system. 159 device available to the system.
162 160
163======================================================================*/ 161======================================================================*/
164static int sedlbauer_config_check(struct pcmcia_device *p_dev, 162static int sedlbauer_config_check(struct pcmcia_device *p_dev, void *priv_data)
165 cistpl_cftable_entry_t *cfg,
166 cistpl_cftable_entry_t *dflt,
167 void *priv_data)
168{ 163{
169 if (cfg->index == 0) 164 if (p_dev->config_index == 0)
170 return -ENODEV; 165 return -EINVAL;
171
172 /* IO window settings */
173 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
174 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
175 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
176 p_dev->resource[0]->start = io->win[0].base;
177 p_dev->resource[0]->end = io->win[0].len;
178 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
179 p_dev->resource[0]->flags |=
180 pcmcia_io_cfg_data_width(io->flags);
181 if (io->nwin > 1) {
182 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
183 p_dev->resource[1]->start = io->win[1].base;
184 p_dev->resource[1]->end = io->win[1].len;
185 }
186 /* This reserves IO space but doesn't actually enable it */
187 p_dev->io_lines = 3;
188 if (pcmcia_request_io(p_dev) != 0)
189 return -ENODEV;
190 }
191 166
192 return 0; 167 p_dev->io_lines = 3;
168 return pcmcia_request_io(p_dev);
193} 169}
194 170
195 171
@@ -202,7 +178,7 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link)
202 dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link); 178 dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
203 179
204 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC | 180 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
205 CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO; 181 CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
206 182
207 /* 183 /*
208 In this loop, we scan the CIS for configuration table entries, 184 In this loop, we scan the CIS for configuration table entries,
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 6605480aa37f..05a5631963bb 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -105,10 +105,7 @@ static int __devinit teles_probe(struct pcmcia_device *link)
105 and attributes of IO windows) are fixed by the nature of the 105 and attributes of IO windows) are fixed by the nature of the
106 device, and can be hard-wired here. 106 device, and can be hard-wired here.
107 */ 107 */
108 link->resource[0]->end = 96; 108 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
109 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
110
111 link->config_flags |= CONF_ENABLE_IRQ;
112 109
113 return teles_cs_config(link); 110 return teles_cs_config(link);
114} /* teles_attach */ 111} /* teles_attach */
@@ -142,18 +139,17 @@ static void __devexit teles_detach(struct pcmcia_device *link)
142 139
143======================================================================*/ 140======================================================================*/
144 141
145static int teles_cs_configcheck(struct pcmcia_device *p_dev, 142static int teles_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
146 cistpl_cftable_entry_t *cf,
147 cistpl_cftable_entry_t *dflt,
148 void *priv_data)
149{ 143{
150 int j; 144 int j;
151 145
152 p_dev->io_lines = 5; 146 p_dev->io_lines = 5;
147 p_dev->resource[0]->end = 96;
148 p_dev->resource[0]->flags &= IO_DATA_PATH_WIDTH;
149 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
153 150
154 if ((cf->io.nwin > 0) && cf->io.win[0].base) { 151 if ((p_dev->resource[0]->end) && p_dev->resource[0]->start) {
155 printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); 152 printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
156 p_dev->resource[0]->start = cf->io.win[0].base;
157 if (!pcmcia_request_io(p_dev)) 153 if (!pcmcia_request_io(p_dev))
158 return 0; 154 return 0;
159 } else { 155 } else {
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)))
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 63bf662e9c7f..77682f27772b 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -137,36 +137,12 @@ static void airo_detach(struct pcmcia_device *link)
137 137
138 ======================================================================*/ 138 ======================================================================*/
139 139
140static int airo_cs_config_check(struct pcmcia_device *p_dev, 140static int airo_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
141 cistpl_cftable_entry_t *cfg,
142 cistpl_cftable_entry_t *dflt,
143 void *priv_data)
144{ 141{
145 if (cfg->index == 0) 142 if (p_dev->config_index == 0)
146 return -ENODEV; 143 return -EINVAL;
147
148 /* IO window settings */
149 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
150 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
151 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
152 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
153 p_dev->resource[0]->flags |=
154 pcmcia_io_cfg_data_width(io->flags);
155 p_dev->resource[0]->start = io->win[0].base;
156 p_dev->resource[0]->end = io->win[0].len;
157 if (io->nwin > 1) {
158 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
159 p_dev->resource[1]->start = io->win[1].base;
160 p_dev->resource[1]->end = io->win[1].len;
161 }
162 }
163
164 /* This reserves IO space but doesn't actually enable it */
165 if (pcmcia_request_io(p_dev) != 0)
166 return -ENODEV;
167 144
168 /* If we got this far, we're cool! */ 145 return pcmcia_request_io(p_dev);
169 return 0;
170} 146}
171 147
172 148
@@ -180,7 +156,7 @@ static int airo_config(struct pcmcia_device *link)
180 dev_dbg(&link->dev, "airo_config\n"); 156 dev_dbg(&link->dev, "airo_config\n");
181 157
182 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP | 158 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
183 CONF_AUTO_AUDIO; 159 CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
184 160
185 /* 161 /*
186 * In this loop, we scan the CIS for configuration table 162 * In this loop, we scan the CIS for configuration table
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 812decd3fbe9..202938022112 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -154,31 +154,11 @@ static int card_present(void *arg)
154 return 0; 154 return 0;
155} 155}
156 156
157static int atmel_config_check(struct pcmcia_device *p_dev, 157static int atmel_config_check(struct pcmcia_device *p_dev, void *priv_data)
158 cistpl_cftable_entry_t *cfg,
159 cistpl_cftable_entry_t *dflt,
160 void *priv_data)
161{ 158{
162 if (cfg->index == 0) 159 if (p_dev->config_index == 0)
163 return -ENODEV; 160 return -EINVAL;
164
165 /* IO window settings */
166 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
167 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
168 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
169 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
170 p_dev->resource[0]->flags |=
171 pcmcia_io_cfg_data_width(io->flags);
172 p_dev->resource[0]->start = io->win[0].base;
173 p_dev->resource[0]->end = io->win[0].len;
174 if (io->nwin > 1) {
175 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
176 p_dev->resource[1]->start = io->win[1].base;
177 p_dev->resource[1]->end = io->win[1].len;
178 }
179 }
180 161
181 /* This reserves IO space but doesn't actually enable it */
182 return pcmcia_request_io(p_dev); 162 return pcmcia_request_io(p_dev);
183} 163}
184 164
@@ -194,7 +174,7 @@ static int atmel_config(struct pcmcia_device *link)
194 dev_dbg(&link->dev, "atmel_config\n"); 174 dev_dbg(&link->dev, "atmel_config\n");
195 175
196 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP | 176 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
197 CONF_AUTO_AUDIO; 177 CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
198 178
199 /* 179 /*
200 In this loop, we scan the CIS for configuration table entries, 180 In this loop, we scan the CIS for configuration table entries,
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index d4f19af1757f..e57b20134d39 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -469,46 +469,11 @@ static void prism2_detach(struct pcmcia_device *link)
469/* run after a CARD_INSERTION event is received to configure the PCMCIA 469/* run after a CARD_INSERTION event is received to configure the PCMCIA
470 * socket and make the device available to the system */ 470 * socket and make the device available to the system */
471 471
472static int prism2_config_check(struct pcmcia_device *p_dev, 472static int prism2_config_check(struct pcmcia_device *p_dev, void *priv_data)
473 cistpl_cftable_entry_t *cfg,
474 cistpl_cftable_entry_t *dflt,
475 void *priv_data)
476{ 473{
477 if (cfg->index == 0) 474 if (p_dev->config_index == 0)
478 return -ENODEV; 475 return -EINVAL;
479
480 PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
481 "(default 0x%02X)\n", cfg->index, dflt->index);
482
483 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
484 p_dev->vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
485 else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
486 p_dev->vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
487
488 /* Do we need to allocate an interrupt? */
489 p_dev->config_flags |= CONF_ENABLE_IRQ;
490
491 /* IO window settings */
492 PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
493 "dflt->io.nwin=%d\n",
494 cfg->io.nwin, dflt->io.nwin);
495 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
496 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
497 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
498 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
499 p_dev->resource[0]->flags |=
500 pcmcia_io_cfg_data_width(io->flags);
501 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
502 p_dev->resource[0]->start = io->win[0].base;
503 p_dev->resource[0]->end = io->win[0].len;
504 if (io->nwin > 1) {
505 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
506 p_dev->resource[1]->start = io->win[1].base;
507 p_dev->resource[1]->end = io->win[1].len;
508 }
509 }
510 476
511 /* This reserves IO space but doesn't actually enable it */
512 return pcmcia_request_io(p_dev); 477 return pcmcia_request_io(p_dev);
513} 478}
514 479
@@ -531,7 +496,7 @@ static int prism2_config(struct pcmcia_device *link)
531 496
532 /* Look for an appropriate configuration table entry in the CIS */ 497 /* Look for an appropriate configuration table entry in the CIS */
533 link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | 498 link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO |
534 CONF_AUTO_CHECK_VCC; 499 CONF_AUTO_CHECK_VCC | CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
535 if (ignore_cis_vcc) 500 if (ignore_cis_vcc)
536 link->config_flags &= ~CONF_AUTO_CHECK_VCC; 501 link->config_flags &= ~CONF_AUTO_CHECK_VCC;
537 ret = pcmcia_loop_config(link, prism2_config_check, NULL); 502 ret = pcmcia_loop_config(link, prism2_config_check, NULL);
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 031f3e6da3c9..2c6f28ac5197 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -794,20 +794,12 @@ static void if_cs_release(struct pcmcia_device *p_dev)
794 * insertion event. 794 * insertion event.
795 */ 795 */
796 796
797static int if_cs_ioprobe(struct pcmcia_device *p_dev, 797static int if_cs_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
798 cistpl_cftable_entry_t *cfg,
799 cistpl_cftable_entry_t *dflt,
800 void *priv_data)
801{ 798{
799 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
802 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; 800 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
803 p_dev->resource[0]->start = cfg->io.win[0].base;
804 p_dev->resource[0]->end = cfg->io.win[0].len;
805 801
806 /* Do we need to allocate an interrupt? */ 802 if (p_dev->resource[1]->end) {
807 p_dev->config_flags |= CONF_ENABLE_IRQ;
808
809 /* IO window settings */
810 if (cfg->io.nwin != 1) {
811 lbs_pr_err("wrong CIS (check number of IO windows)\n"); 803 lbs_pr_err("wrong CIS (check number of IO windows)\n");
812 return -ENODEV; 804 return -ENODEV;
813 } 805 }
@@ -833,6 +825,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
833 card->p_dev = p_dev; 825 card->p_dev = p_dev;
834 p_dev->priv = card; 826 p_dev->priv = card;
835 827
828 p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
829
836 if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) { 830 if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
837 lbs_pr_err("error in pcmcia_loop_config\n"); 831 lbs_pr_err("error in pcmcia_loop_config\n");
838 goto out1; 832 goto out1;
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index b92173827b55..263dfe9e0e30 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -142,42 +142,12 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
142 * device available to the system. 142 * device available to the system.
143 */ 143 */
144 144
145static int orinoco_cs_config_check(struct pcmcia_device *p_dev, 145static int orinoco_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
146 cistpl_cftable_entry_t *cfg,
147 cistpl_cftable_entry_t *dflt,
148 void *priv_data)
149{ 146{
150 if (cfg->index == 0) 147 if (p_dev->config_index == 0)
151 goto next_entry; 148 return -EINVAL;
152
153 /* Do we need to allocate an interrupt? */
154 p_dev->config_flags |= CONF_ENABLE_IRQ;
155
156 /* IO window settings */
157 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
158 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
159 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
160 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
161 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
162 p_dev->resource[0]->flags |=
163 pcmcia_io_cfg_data_width(io->flags);
164 p_dev->resource[0]->start = io->win[0].base;
165 p_dev->resource[0]->end = io->win[0].len;
166 if (io->nwin > 1) {
167 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
168 p_dev->resource[1]->start = io->win[1].base;
169 p_dev->resource[1]->end = io->win[1].len;
170 }
171
172 /* This reserves IO space but doesn't actually enable it */
173 if (pcmcia_request_io(p_dev) != 0)
174 goto next_entry;
175 }
176 return 0;
177 149
178next_entry: 150 return pcmcia_request_io(p_dev);
179 pcmcia_disable_device(p_dev);
180 return -ENODEV;
181}; 151};
182 152
183static int 153static int
@@ -202,7 +172,8 @@ orinoco_cs_config(struct pcmcia_device *link)
202 * and most client drivers will only use the CIS to fill in 172 * and most client drivers will only use the CIS to fill in
203 * implementation-defined details. 173 * implementation-defined details.
204 */ 174 */
205 link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC; 175 link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC |
176 CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
206 if (ignore_cis_vcc) 177 if (ignore_cis_vcc)
207 link->config_flags &= ~CONF_AUTO_CHECK_VCC; 178 link->config_flags &= ~CONF_AUTO_CHECK_VCC;
208 ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL); 179 ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index f462c78856e9..78446507873f 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -205,48 +205,12 @@ static void spectrum_cs_detach(struct pcmcia_device *link)
205 */ 205 */
206 206
207static int spectrum_cs_config_check(struct pcmcia_device *p_dev, 207static int spectrum_cs_config_check(struct pcmcia_device *p_dev,
208 cistpl_cftable_entry_t *cfg,
209 cistpl_cftable_entry_t *dflt,
210 void *priv_data) 208 void *priv_data)
211{ 209{
212 if (cfg->index == 0) 210 if (p_dev->config_index == 0)
213 goto next_entry; 211 return -EINVAL;
214
215 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
216 p_dev->vpp =
217 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
218 else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
219 p_dev->vpp =
220 dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
221
222 /* Do we need to allocate an interrupt? */
223 p_dev->config_flags |= CONF_ENABLE_IRQ;
224
225 /* IO window settings */
226 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
227 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
228 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
229 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
230 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
231 p_dev->resource[0]->flags |=
232 pcmcia_io_cfg_data_width(io->flags);
233 p_dev->resource[0]->start = io->win[0].base;
234 p_dev->resource[0]->end = io->win[0].len;
235 if (io->nwin > 1) {
236 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
237 p_dev->resource[1]->start = io->win[1].base;
238 p_dev->resource[1]->end = io->win[1].len;
239 }
240
241 /* This reserves IO space but doesn't actually enable it */
242 if (pcmcia_request_io(p_dev) != 0)
243 goto next_entry;
244 }
245 return 0;
246 212
247next_entry: 213 return pcmcia_request_io(p_dev);
248 pcmcia_disable_device(p_dev);
249 return -ENODEV;
250}; 214};
251 215
252static int 216static int
@@ -271,7 +235,8 @@ spectrum_cs_config(struct pcmcia_device *link)
271 * and most client drivers will only use the CIS to fill in 235 * and most client drivers will only use the CIS to fill in
272 * implementation-defined details. 236 * implementation-defined details.
273 */ 237 */
274 link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC; 238 link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC |
239 CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
275 if (ignore_cis_vcc) 240 if (ignore_cis_vcc)
276 link->config_flags &= ~CONF_AUTO_CHECK_VCC; 241 link->config_flags &= ~CONF_AUTO_CHECK_VCC;
277 ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL); 242 ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 8c2a4733bc19..3730184a04a3 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -100,9 +100,7 @@ static int parport_probe(struct pcmcia_device *link)
100 link->priv = info; 100 link->priv = info;
101 info->p_dev = link; 101 info->p_dev = link;
102 102
103 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 103 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
104 link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
105 link->config_flags |= CONF_ENABLE_IRQ;
106 104
107 return parport_config(link); 105 return parport_config(link);
108} /* parport_attach */ 106} /* parport_attach */
@@ -133,27 +131,14 @@ static void parport_detach(struct pcmcia_device *link)
133 131
134======================================================================*/ 132======================================================================*/
135 133
136static int parport_config_check(struct pcmcia_device *p_dev, 134static int parport_config_check(struct pcmcia_device *p_dev, void *priv_data)
137 cistpl_cftable_entry_t *cfg,
138 cistpl_cftable_entry_t *dflt,
139 void *priv_data)
140{ 135{
141 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { 136 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
142 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; 137 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
143 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; 138 p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
144 if (epp_mode) 139 p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
145 p_dev->config_index |= FORCE_EPP_MODE; 140
146 p_dev->resource[0]->start = io->win[0].base; 141 return pcmcia_request_io(p_dev);
147 p_dev->resource[0]->end = io->win[0].len;
148 if (io->nwin == 2) {
149 p_dev->resource[1]->start = io->win[1].base;
150 p_dev->resource[1]->end = io->win[1].len;
151 }
152 if (pcmcia_request_io(p_dev) != 0)
153 return -ENODEV;
154 return 0;
155 }
156 return -ENODEV;
157} 142}
158 143
159static int parport_config(struct pcmcia_device *link) 144static int parport_config(struct pcmcia_device *link)
@@ -164,6 +149,9 @@ static int parport_config(struct pcmcia_device *link)
164 149
165 dev_dbg(&link->dev, "parport_config\n"); 150 dev_dbg(&link->dev, "parport_config\n");
166 151
152 if (epp_mode)
153 link->config_index |= FORCE_EPP_MODE;
154
167 ret = pcmcia_loop_config(link, parport_config_check, NULL); 155 ret = pcmcia_loop_config(link, parport_config_check, NULL);
168 if (ret) 156 if (ret)
169 goto failed; 157 goto failed;
diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c
index 160da0697335..e2c92415b892 100644
--- a/drivers/pcmcia/pcmcia_cis.c
+++ b/drivers/pcmcia/pcmcia_cis.c
@@ -6,7 +6,7 @@
6 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 6 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
7 * 7 *
8 * Copyright (C) 1999 David A. Hinds 8 * Copyright (C) 1999 David A. Hinds
9 * Copyright (C) 2004-2009 Dominik Brodowski 9 * Copyright (C) 2004-2010 Dominik Brodowski
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -125,13 +125,24 @@ next_entry:
125 return ret; 125 return ret;
126} 126}
127 127
128
129/**
130 * pcmcia_io_cfg_data_width() - convert cfgtable to data path width parameter
131 */
132static int pcmcia_io_cfg_data_width(unsigned int flags)
133{
134 if (!(flags & CISTPL_IO_8BIT))
135 return IO_DATA_PATH_WIDTH_16;
136 if (!(flags & CISTPL_IO_16BIT))
137 return IO_DATA_PATH_WIDTH_8;
138 return IO_DATA_PATH_WIDTH_AUTO;
139}
140
141
128struct pcmcia_cfg_mem { 142struct pcmcia_cfg_mem {
129 struct pcmcia_device *p_dev; 143 struct pcmcia_device *p_dev;
144 int (*conf_check) (struct pcmcia_device *p_dev, void *priv_data);
130 void *priv_data; 145 void *priv_data;
131 int (*conf_check) (struct pcmcia_device *p_dev,
132 cistpl_cftable_entry_t *cfg,
133 cistpl_cftable_entry_t *dflt,
134 void *priv_data);
135 cisparse_t parse; 146 cisparse_t parse;
136 cistpl_cftable_entry_t dflt; 147 cistpl_cftable_entry_t dflt;
137}; 148};
@@ -184,16 +195,63 @@ static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
184 if ((flags & CONF_AUTO_AUDIO) && (cfg->flags & CISTPL_CFTABLE_AUDIO)) 195 if ((flags & CONF_AUTO_AUDIO) && (cfg->flags & CISTPL_CFTABLE_AUDIO))
185 p_dev->config_flags |= CONF_ENABLE_SPKR; 196 p_dev->config_flags |= CONF_ENABLE_SPKR;
186 197
187 return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt, 198
188 cfg_mem->priv_data); 199 /* IO window settings? */
200 if (flags & CONF_AUTO_SET_IO) {
201 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
202 int i = 0;
203
204 p_dev->resource[0]->start = p_dev->resource[0]->end = 0;
205 p_dev->resource[1]->start = p_dev->resource[1]->end = 0;
206 if (io->nwin == 0)
207 return -ENODEV;
208
209 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
210 p_dev->resource[0]->flags |=
211 pcmcia_io_cfg_data_width(io->flags);
212 if (io->nwin > 1) {
213 /* For multifunction cards, by convention, we
214 * configure the network function with window 0,
215 * and serial with window 1 */
216 i = (io->win[1].len > io->win[0].len);
217 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
218 p_dev->resource[1]->start = io->win[1-i].base;
219 p_dev->resource[1]->end = io->win[1-i].len;
220 }
221 p_dev->resource[0]->start = io->win[i].base;
222 p_dev->resource[0]->end = io->win[i].len;
223 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
224 }
225
226 /* MEM window settings? */
227 if (flags & CONF_AUTO_SET_IOMEM) {
228 /* so far, we only set one memory window */
229 cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
230
231 p_dev->resource[2]->start = p_dev->resource[2]->end = 0;
232 if (mem->nwin == 0)
233 return -ENODEV;
234
235 p_dev->resource[2]->start = mem->win[0].host_addr;
236 p_dev->resource[2]->end = mem->win[0].len;
237 if (p_dev->resource[2]->end < 0x1000)
238 p_dev->resource[2]->end = 0x1000;
239 p_dev->card_addr = mem->win[0].card_addr;
240 }
241
242 dev_dbg(&p_dev->dev,
243 "checking configuration %x: %pr %pr %pr (%d lines)\n",
244 p_dev->config_index, p_dev->resource[0], p_dev->resource[1],
245 p_dev->resource[2], p_dev->io_lines);
246
247 return cfg_mem->conf_check(p_dev, cfg_mem->priv_data);
189} 248}
190 249
191/** 250/**
192 * pcmcia_loop_config() - loop over configuration options 251 * pcmcia_loop_config() - loop over configuration options
193 * @p_dev: the struct pcmcia_device which we need to loop for. 252 * @p_dev: the struct pcmcia_device which we need to loop for.
194 * @conf_check: function to call for each configuration option. 253 * @conf_check: function to call for each configuration option.
195 * It gets passed the struct pcmcia_device, the CIS data 254 * It gets passed the struct pcmcia_device and private data
196 * describing the configuration option, and private data
197 * being passed to pcmcia_loop_config() 255 * being passed to pcmcia_loop_config()
198 * @priv_data: private data to be passed to the conf_check function. 256 * @priv_data: private data to be passed to the conf_check function.
199 * 257 *
@@ -203,8 +261,6 @@ static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
203 */ 261 */
204int pcmcia_loop_config(struct pcmcia_device *p_dev, 262int pcmcia_loop_config(struct pcmcia_device *p_dev,
205 int (*conf_check) (struct pcmcia_device *p_dev, 263 int (*conf_check) (struct pcmcia_device *p_dev,
206 cistpl_cftable_entry_t *cfg,
207 cistpl_cftable_entry_t *dflt,
208 void *priv_data), 264 void *priv_data),
209 void *priv_data) 265 void *priv_data)
210{ 266{
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 0b5fc2fa0589..bd9ce09b7ff8 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -99,9 +99,7 @@ static int aha152x_probe(struct pcmcia_device *link)
99 info->p_dev = link; 99 info->p_dev = link;
100 link->priv = info; 100 link->priv = info;
101 101
102 link->resource[0]->end = 0x20; 102 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
103 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
104 link->config_flags |= CONF_ENABLE_IRQ;
105 link->config_regs = PRESENT_OPTION; 103 link->config_regs = PRESENT_OPTION;
106 104
107 return aha152x_config_cs(link); 105 return aha152x_config_cs(link);
@@ -121,24 +119,24 @@ static void aha152x_detach(struct pcmcia_device *link)
121 119
122/*====================================================================*/ 120/*====================================================================*/
123 121
124static int aha152x_config_check(struct pcmcia_device *p_dev, 122static int aha152x_config_check(struct pcmcia_device *p_dev, void *priv_data)
125 cistpl_cftable_entry_t *cfg,
126 cistpl_cftable_entry_t *dflt,
127 void *priv_data)
128{ 123{
129 p_dev->io_lines = 10; 124 p_dev->io_lines = 10;
125
130 /* For New Media T&J, look for a SCSI window */ 126 /* For New Media T&J, look for a SCSI window */
131 if (cfg->io.win[0].len >= 0x20) 127 if ((p_dev->resource[0]->end < 0x20) &&
132 p_dev->resource[0]->start = cfg->io.win[0].base; 128 (p_dev->resource[1]->end >= 0x20))
133 else if ((cfg->io.nwin > 1) && 129 p_dev->resource[0]->start = p_dev->resource[1]->start;
134 (cfg->io.win[1].len >= 0x20)) 130
135 p_dev->resource[0]->start = cfg->io.win[1].base; 131 if (p_dev->resource[0]->start >= 0xffff)
136 if ((cfg->io.nwin > 0) && 132 return -EINVAL;
137 (p_dev->resource[0]->start < 0xffff)) { 133
138 if (!pcmcia_request_io(p_dev)) 134 p_dev->resource[1]->start = p_dev->resource[1]->end = 0;
139 return 0; 135 p_dev->resource[0]->end = 0x20;
140 } 136 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
141 return -EINVAL; 137 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
138
139 return pcmcia_request_io(p_dev);
142} 140}
143 141
144static int aha152x_config_cs(struct pcmcia_device *link) 142static int aha152x_config_cs(struct pcmcia_device *link)
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index 3b9f311cb035..f2dc627e9da2 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -82,9 +82,7 @@ static int fdomain_probe(struct pcmcia_device *link)
82 82
83 info->p_dev = link; 83 info->p_dev = link;
84 link->priv = info; 84 link->priv = info;
85 link->resource[0]->end = 0x10; 85 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
86 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
87 link->config_flags |= CONF_ENABLE_IRQ;
88 link->config_regs = PRESENT_OPTION; 86 link->config_regs = PRESENT_OPTION;
89 87
90 return fdomain_config(link); 88 return fdomain_config(link);
@@ -103,13 +101,12 @@ static void fdomain_detach(struct pcmcia_device *link)
103 101
104/*====================================================================*/ 102/*====================================================================*/
105 103
106static int fdomain_config_check(struct pcmcia_device *p_dev, 104static int fdomain_config_check(struct pcmcia_device *p_dev, void *priv_data)
107 cistpl_cftable_entry_t *cfg,
108 cistpl_cftable_entry_t *dflt,
109 void *priv_data)
110{ 105{
111 p_dev->io_lines = 10; 106 p_dev->io_lines = 10;
112 p_dev->resource[0]->start = cfg->io.win[0].base; 107 p_dev->resource[0]->end = 0x10;
108 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
109 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
113 return pcmcia_request_io(p_dev); 110 return pcmcia_request_io(p_dev);
114} 111}
115 112
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 344d49900b4c..3b90ad9d1956 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1556,13 +1556,6 @@ static int nsp_cs_probe(struct pcmcia_device *link)
1556 1556
1557 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info); 1557 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1558 1558
1559 /* The io structure describes IO port mapping */
1560 link->resource[0]->end = 0x10;
1561 link->resource[0]->flags = IO_DATA_PATH_WIDTH_AUTO;
1562
1563 /* General socket configuration */
1564 link->config_flags |= CONF_ENABLE_IRQ;
1565
1566 ret = nsp_cs_config(link); 1559 ret = nsp_cs_config(link);
1567 1560
1568 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); 1561 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
@@ -1594,50 +1587,27 @@ static void nsp_cs_detach(struct pcmcia_device *link)
1594 ethernet device available to the system. 1587 ethernet device available to the system.
1595======================================================================*/ 1588======================================================================*/
1596 1589
1597static int nsp_cs_config_check(struct pcmcia_device *p_dev, 1590static int nsp_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
1598 cistpl_cftable_entry_t *cfg,
1599 cistpl_cftable_entry_t *dflt,
1600 void *priv_data)
1601{ 1591{
1602 nsp_hw_data *data = priv_data; 1592 nsp_hw_data *data = priv_data;
1603 1593
1604 if (cfg->index == 0) 1594 if (p_dev->config_index == 0)
1605 return -ENODEV; 1595 return -ENODEV;
1606 1596
1607 /* IO window settings */ 1597 /* This reserves IO space but doesn't actually enable it */
1608 p_dev->resource[0]->end = p_dev->resource[1]->end = 0; 1598 if (pcmcia_request_io(p_dev) != 0)
1609 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { 1599 goto next_entry;
1610 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
1611 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
1612 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
1613 p_dev->resource[0]->flags |=
1614 pcmcia_io_cfg_data_width(io->flags);
1615 p_dev->resource[0]->start = io->win[0].base;
1616 p_dev->resource[0]->end = io->win[0].len;
1617 if (io->nwin > 1) {
1618 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
1619 p_dev->resource[1]->start = io->win[1].base;
1620 p_dev->resource[1]->end = io->win[1].len;
1621 }
1622 /* This reserves IO space but doesn't actually enable it */
1623 if (pcmcia_request_io(p_dev) != 0)
1624 goto next_entry;
1625 }
1626 1600
1627 if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) { 1601 if (resource_size(p_dev->resource[2])) {
1628 cistpl_mem_t *mem =
1629 (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
1630 p_dev->resource[2]->flags |= (WIN_DATA_WIDTH_16 | 1602 p_dev->resource[2]->flags |= (WIN_DATA_WIDTH_16 |
1631 WIN_MEMORY_TYPE_CM | 1603 WIN_MEMORY_TYPE_CM |
1632 WIN_ENABLE); 1604 WIN_ENABLE);
1633 p_dev->resource[2]->start = mem->win[0].host_addr;
1634 p_dev->resource[2]->end = mem->win[0].len;
1635 if (p_dev->resource[2]->end < 0x1000) 1605 if (p_dev->resource[2]->end < 0x1000)
1636 p_dev->resource[2]->end = 0x1000; 1606 p_dev->resource[2]->end = 0x1000;
1637 if (pcmcia_request_window(p_dev, p_dev->resource[2], 0) != 0) 1607 if (pcmcia_request_window(p_dev, p_dev->resource[2], 0) != 0)
1638 goto next_entry; 1608 goto next_entry;
1639 if (pcmcia_map_mem_page(p_dev, p_dev->resource[2], 1609 if (pcmcia_map_mem_page(p_dev, p_dev->resource[2],
1640 mem->win[0].card_addr) != 0) 1610 p_dev->card_addr) != 0)
1641 goto next_entry; 1611 goto next_entry;
1642 1612
1643 data->MmioAddress = (unsigned long) 1613 data->MmioAddress = (unsigned long)
@@ -1664,7 +1634,8 @@ static int nsp_cs_config(struct pcmcia_device *link)
1664 nsp_dbg(NSP_DEBUG_INIT, "in"); 1634 nsp_dbg(NSP_DEBUG_INIT, "in");
1665 1635
1666 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC | 1636 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
1667 CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO; 1637 CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IOMEM |
1638 CONF_AUTO_SET_IO;
1668 1639
1669 ret = pcmcia_loop_config(link, nsp_cs_config_check, data); 1640 ret = pcmcia_loop_config(link, nsp_cs_config_check, data);
1670 if (ret) 1641 if (ret)
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 468fd12fe98d..e8a06e3a384c 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -155,9 +155,7 @@ static int qlogic_probe(struct pcmcia_device *link)
155 return -ENOMEM; 155 return -ENOMEM;
156 info->p_dev = link; 156 info->p_dev = link;
157 link->priv = info; 157 link->priv = info;
158 link->resource[0]->end = 16; 158 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
159 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
160 link->config_flags |= CONF_ENABLE_IRQ;
161 link->config_regs = PRESENT_OPTION; 159 link->config_regs = PRESENT_OPTION;
162 160
163 return qlogic_config(link); 161 return qlogic_config(link);
@@ -176,14 +174,11 @@ static void qlogic_detach(struct pcmcia_device *link)
176 174
177/*====================================================================*/ 175/*====================================================================*/
178 176
179static int qlogic_config_check(struct pcmcia_device *p_dev, 177static int qlogic_config_check(struct pcmcia_device *p_dev, void *priv_data)
180 cistpl_cftable_entry_t *cfg,
181 cistpl_cftable_entry_t *dflt,
182 void *priv_data)
183{ 178{
184 p_dev->io_lines = 10; 179 p_dev->io_lines = 10;
185 p_dev->resource[0]->start = cfg->io.win[0].base; 180 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
186 p_dev->resource[0]->end = cfg->io.win[0].len; 181 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
187 182
188 if (p_dev->resource[0]->start == 0) 183 if (p_dev->resource[0]->start == 0)
189 return -ENODEV; 184 return -ENODEV;
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 7a0bb9aea042..6ceb57c355fa 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -683,14 +683,11 @@ static struct scsi_host_template sym53c500_driver_template = {
683 .shost_attrs = SYM53C500_shost_attrs 683 .shost_attrs = SYM53C500_shost_attrs
684}; 684};
685 685
686static int SYM53C500_config_check(struct pcmcia_device *p_dev, 686static int SYM53C500_config_check(struct pcmcia_device *p_dev, void *priv_data)
687 cistpl_cftable_entry_t *cfg,
688 cistpl_cftable_entry_t *dflt,
689 void *priv_data)
690{ 687{
691 p_dev->io_lines = 10; 688 p_dev->io_lines = 10;
692 p_dev->resource[0]->start = cfg->io.win[0].base; 689 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
693 p_dev->resource[0]->end = cfg->io.win[0].len; 690 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
694 691
695 if (p_dev->resource[0]->start == 0) 692 if (p_dev->resource[0]->start == 0)
696 return -ENODEV; 693 return -ENODEV;
@@ -857,9 +854,7 @@ SYM53C500_probe(struct pcmcia_device *link)
857 return -ENOMEM; 854 return -ENOMEM;
858 info->p_dev = link; 855 info->p_dev = link;
859 link->priv = info; 856 link->priv = info;
860 link->resource[0]->end = 16; 857 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
861 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
862 link->config_flags |= CONF_ENABLE_IRQ;
863 858
864 return SYM53C500_config(link); 859 return SYM53C500_config(link);
865} /* SYM53C500_attach */ 860} /* SYM53C500_attach */
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index a796a93fe39c..422520342936 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -424,41 +424,45 @@ static int pfc_config(struct pcmcia_device *p_dev)
424 return -ENODEV; 424 return -ENODEV;
425} 425}
426 426
427static int simple_config_check(struct pcmcia_device *p_dev, 427static int simple_config_check(struct pcmcia_device *p_dev, void *priv_data)
428 cistpl_cftable_entry_t *cf,
429 cistpl_cftable_entry_t *dflt,
430 void *priv_data)
431{ 428{
432 static const int size_table[2] = { 8, 16 }; 429 static const int size_table[2] = { 8, 16 };
433 int *try = priv_data; 430 int *try = priv_data;
434 431
435 p_dev->io_lines = ((*try & 0x1) == 0) ? 432 if (p_dev->resource[0]->start == 0)
436 16 : cf->io.flags & CISTPL_IO_LINES_MASK; 433 return -ENODEV;
437 434
438 if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)]) 435 if ((*try & 0x1) == 0)
439 && (cf->io.win[0].base != 0)) { 436 p_dev->io_lines = 16;
440 p_dev->resource[0]->start = cf->io.win[0].base; 437
441 if (!pcmcia_request_io(p_dev)) 438 if (p_dev->resource[0]->end != size_table[(*try >> 1)])
442 return 0; 439 return -ENODEV;
443 } 440
444 return -EINVAL; 441 p_dev->resource[0]->end = 8;
442 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
443 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
444
445 return pcmcia_request_io(p_dev);
445} 446}
446 447
447static int simple_config_check_notpicky(struct pcmcia_device *p_dev, 448static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
448 cistpl_cftable_entry_t *cf,
449 cistpl_cftable_entry_t *dflt,
450 void *priv_data) 449 void *priv_data)
451{ 450{
452 static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; 451 static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
453 int j; 452 int j;
454 453
455 if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { 454 if (p_dev->io_lines > 3)
456 for (j = 0; j < 5; j++) { 455 return -ENODEV;
457 p_dev->resource[0]->start = base[j]; 456
458 p_dev->io_lines = base[j] ? 16 : 3; 457 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
459 if (!pcmcia_request_io(p_dev)) 458 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
460 return 0; 459 p_dev->resource[0]->end = 8;
461 } 460
461 for (j = 0; j < 5; j++) {
462 p_dev->resource[0]->start = base[j];
463 p_dev->io_lines = base[j] ? 16 : 3;
464 if (!pcmcia_request_io(p_dev))
465 return 0;
462 } 466 }
463 return -ENODEV; 467 return -ENODEV;
464} 468}
@@ -468,12 +472,9 @@ static int simple_config(struct pcmcia_device *link)
468 struct serial_info *info = link->priv; 472 struct serial_info *info = link->priv;
469 int i = -ENODEV, try; 473 int i = -ENODEV, try;
470 474
471 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
472 link->resource[0]->end = 8;
473
474 /* First pass: look for a config entry that looks normal. 475 /* First pass: look for a config entry that looks normal.
475 * Two tries: without IO aliases, then with aliases */ 476 * Two tries: without IO aliases, then with aliases */
476 link->config_flags |= CONF_AUTO_SET_VPP; 477 link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_SET_IO;
477 for (try = 0; try < 4; try++) 478 for (try = 0; try < 4; try++)
478 if (!pcmcia_loop_config(link, simple_config_check, &try)) 479 if (!pcmcia_loop_config(link, simple_config_check, &try))
479 goto found_port; 480 goto found_port;
@@ -503,43 +504,44 @@ found_port:
503 return setup_serial(link, info, link->resource[0]->start, link->irq); 504 return setup_serial(link, info, link->resource[0]->start, link->irq);
504} 505}
505 506
506static int multi_config_check(struct pcmcia_device *p_dev, 507static int multi_config_check(struct pcmcia_device *p_dev, void *priv_data)
507 cistpl_cftable_entry_t *cf,
508 cistpl_cftable_entry_t *dflt,
509 void *priv_data)
510{ 508{
511 int *base2 = priv_data; 509 int *multi = priv_data;
510
511 if (p_dev->resource[1]->end)
512 return -EINVAL;
512 513
513 /* The quad port cards have bad CIS's, so just look for a 514 /* The quad port cards have bad CIS's, so just look for a
514 window larger than 8 ports and assume it will be right */ 515 window larger than 8 ports and assume it will be right */
515 if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { 516 if (p_dev->resource[0]->end <= 8)
516 p_dev->resource[0]->start = cf->io.win[0].base; 517 return -EINVAL;
517 p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; 518
518 if (!pcmcia_request_io(p_dev)) { 519 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
519 *base2 = p_dev->resource[0]->start + 8; 520 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
520 return 0; 521 p_dev->resource[0]->end = *multi * 8;
521 } 522
522 } 523 if (pcmcia_request_io(p_dev))
523 return -ENODEV; 524 return -ENODEV;
525 return 0;
524} 526}
525 527
526static int multi_config_check_notpicky(struct pcmcia_device *p_dev, 528static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
527 cistpl_cftable_entry_t *cf,
528 cistpl_cftable_entry_t *dflt,
529 void *priv_data) 529 void *priv_data)
530{ 530{
531 int *base2 = priv_data; 531 int *base2 = priv_data;
532 532
533 if (cf->io.nwin == 2) { 533 if (!p_dev->resource[0]->end || !p_dev->resource[1]->end)
534 p_dev->resource[0]->start = cf->io.win[0].base; 534 return -ENODEV;
535 p_dev->resource[1]->start = cf->io.win[1].base; 535
536 p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; 536 p_dev->resource[0]->end = p_dev->resource[1]->end = 8;
537 if (!pcmcia_request_io(p_dev)) { 537 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
538 *base2 = p_dev->resource[1]->start; 538 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
539 return 0; 539
540 } 540 if (pcmcia_request_io(p_dev))
541 } 541 return -ENODEV;
542 return -ENODEV; 542
543 *base2 = p_dev->resource[0]->start + 8;
544 return 0;
543} 545}
544 546
545static int multi_config(struct pcmcia_device *link) 547static int multi_config(struct pcmcia_device *link)
@@ -547,12 +549,12 @@ static int multi_config(struct pcmcia_device *link)
547 struct serial_info *info = link->priv; 549 struct serial_info *info = link->priv;
548 int i, base2 = 0; 550 int i, base2 = 0;
549 551
552 link->config_flags |= CONF_AUTO_SET_IO;
550 /* First, look for a generic full-sized window */ 553 /* First, look for a generic full-sized window */
551 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 554 if (!pcmcia_loop_config(link, multi_config_check, &info->multi))
552 link->resource[0]->end = info->multi * 8; 555 base2 = link->resource[0]->start + 8;
553 if (pcmcia_loop_config(link, multi_config_check, &base2)) { 556 else {
554 /* If that didn't work, look for two windows */ 557 /* If that didn't work, look for two windows */
555 link->resource[0]->end = link->resource[1]->end = 8;
556 info->multi = 2; 558 info->multi = 2;
557 if (pcmcia_loop_config(link, multi_config_check_notpicky, 559 if (pcmcia_loop_config(link, multi_config_check_notpicky,
558 &base2)) { 560 &base2)) {
@@ -587,7 +589,7 @@ static int multi_config(struct pcmcia_device *link)
587 link->config_index == 3) { 589 link->config_index == 3) {
588 err = setup_serial(link, info, base2, 590 err = setup_serial(link, info, base2,
589 link->irq); 591 link->irq);
590 base2 = link->resource[0]->start;; 592 base2 = link->resource[0]->start;
591 } else { 593 } else {
592 err = setup_serial(link, info, link->resource[0]->start, 594 err = setup_serial(link, info, link->resource[0]->start,
593 link->irq); 595 link->irq);
@@ -611,18 +613,18 @@ static int multi_config(struct pcmcia_device *link)
611 return 0; 613 return 0;
612} 614}
613 615
614static int serial_check_for_multi(struct pcmcia_device *p_dev, 616static int serial_check_for_multi(struct pcmcia_device *p_dev, void *priv_data)
615 cistpl_cftable_entry_t *cf,
616 cistpl_cftable_entry_t *dflt,
617 void *priv_data)
618{ 617{
619 struct serial_info *info = p_dev->priv; 618 struct serial_info *info = p_dev->priv;
620 619
621 if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) 620 if (!p_dev->resource[0]->end)
622 info->multi = cf->io.win[0].len >> 3; 621 return -EINVAL;
622
623 if ((!p_dev->resource[1]->end) && (p_dev->resource[0]->end % 8 == 0))
624 info->multi = p_dev->resource[0]->end >> 3;
623 625
624 if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && 626 if ((p_dev->resource[1]->end) && (p_dev->resource[0]->end == 8)
625 (cf->io.win[1].len == 8)) 627 && (p_dev->resource[1]->end == 8))
626 info->multi = 2; 628 info->multi = 2;
627 629
628 return 0; /* break */ 630 return 0; /* break */
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index 678fbf67d7a8..c43c68922c74 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -710,36 +710,12 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link)
710 710
711 711
712static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, 712static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
713 cistpl_cftable_entry_t *cfg,
714 cistpl_cftable_entry_t *dflt,
715 void *priv_data) 713 void *priv_data)
716{ 714{
717 if (cfg->index == 0) 715 if (p_dev->config_index == 0)
718 return -EINVAL; 716 return -EINVAL;
719 717
720 /* Do we need to allocate an interrupt? */ 718 return pcmcia_request_io(p_dev);
721 p_dev->config_flags |= CONF_ENABLE_IRQ;
722
723 /* IO window settings */
724 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
725 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
726 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
727 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
728 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
729 p_dev->resource[0]->flags |=
730 pcmcia_io_cfg_data_width(io->flags);
731 p_dev->resource[0]->start = io->win[0].base;
732 p_dev->resource[0]->end = io->win[0].len;
733 if (io->nwin > 1) {
734 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
735 p_dev->resource[1]->start = io->win[1].base;
736 p_dev->resource[1]->end = io->win[1].len;
737 }
738 /* This reserves IO space but doesn't actually enable it */
739 return pcmcia_request_io(p_dev);
740 }
741
742 return 0;
743} 719}
744 720
745static void das16cs_pcmcia_config(struct pcmcia_device *link) 721static void das16cs_pcmcia_config(struct pcmcia_device *link)
@@ -748,6 +724,9 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
748 724
749 dev_dbg(&link->dev, "das16cs_pcmcia_config\n"); 725 dev_dbg(&link->dev, "das16cs_pcmcia_config\n");
750 726
727 /* Do we need to allocate an interrupt? */
728 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
729
751 ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL); 730 ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL);
752 if (ret) { 731 if (ret) {
753 dev_warn(&link->dev, "no configuration found\n"); 732 dev_warn(&link->dev, "no configuration found\n");
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index 12a96b7a43ad..d3959093381b 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -192,35 +192,12 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
192 192
193 193
194static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, 194static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
195 cistpl_cftable_entry_t *cfg,
196 cistpl_cftable_entry_t *dflt,
197 void *priv_data) 195 void *priv_data)
198{ 196{
199 if (cfg->index == 0) 197 if (p_dev->config_index == 0)
200 return -ENODEV; 198 return -EINVAL;
201 199
202 /* Do we need to allocate an interrupt? */ 200 return pcmcia_request_io(p_dev);
203 p_dev->config_flags |= CONF_ENABLE_IRQ;
204
205 /* IO window settings */
206 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
207 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
208 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
209 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
210 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
211 p_dev->resource[0]->flags |=
212 pcmcia_io_cfg_data_width(io->flags);
213 p_dev->resource[0]->start = io->win[0].base;
214 p_dev->resource[0]->end = io->win[0].len;
215 if (io->nwin > 1) {
216 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
217 p_dev->resource[1]->start = io->win[1].base;
218 p_dev->resource[1]->end = io->win[1].len;
219 }
220 /* This reserves IO space but doesn't actually enable it */
221 return pcmcia_request_io(p_dev);
222 }
223 return 0;
224} 201}
225 202
226 203
@@ -238,6 +215,8 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
238 215
239 dev_dbg(&link->dev, "das08_pcmcia_config\n"); 216 dev_dbg(&link->dev, "das08_pcmcia_config\n");
240 217
218 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
219
241 ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL); 220 ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL);
242 if (ret) { 221 if (ret) {
243 dev_warn(&link->dev, "no configuration found\n"); 222 dev_warn(&link->dev, "no configuration found\n");
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index f22dc0f2a8d6..7129b0ca4c8b 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -530,35 +530,12 @@ static void dio700_cs_detach(struct pcmcia_device *link)
530======================================================================*/ 530======================================================================*/
531 531
532static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, 532static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
533 cistpl_cftable_entry_t *cfg,
534 cistpl_cftable_entry_t *dflt,
535 void *priv_data) 533 void *priv_data)
536{ 534{
537 if (cfg->index == 0) 535 if (p_dev->config_index == 0)
538 return -ENODEV; 536 return -EINVAL;
539
540 /* IO window settings */
541 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
542 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
543 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
544 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
545 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
546 p_dev->resource[0]->flags |=
547 pcmcia_io_cfg_data_width(io->flags);
548 p_dev->resource[0]->start = io->win[0].base;
549 p_dev->resource[0]->end = io->win[0].len;
550 if (io->nwin > 1) {
551 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
552 p_dev->resource[1]->start = io->win[1].base;
553 p_dev->resource[1]->end = io->win[1].len;
554 }
555 /* This reserves IO space but doesn't actually enable it */
556 if (pcmcia_request_io(p_dev) != 0)
557 return -ENODEV;
558 }
559 537
560 /* If we got this far, we're cool! */ 538 return pcmcia_request_io(p_dev);
561 return 0;
562} 539}
563 540
564static void dio700_config(struct pcmcia_device *link) 541static void dio700_config(struct pcmcia_device *link)
@@ -570,7 +547,8 @@ static void dio700_config(struct pcmcia_device *link)
570 547
571 dev_dbg(&link->dev, "dio700_config\n"); 548 dev_dbg(&link->dev, "dio700_config\n");
572 549
573 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO; 550 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO |
551 CONF_AUTO_SET_IO;
574 552
575 ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, NULL); 553 ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, NULL);
576 if (ret) { 554 if (ret) {
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
index 6dc2b06064cd..4defdda2bfaf 100644
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -282,35 +282,12 @@ static void dio24_cs_detach(struct pcmcia_device *link)
282======================================================================*/ 282======================================================================*/
283 283
284static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev, 284static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
285 cistpl_cftable_entry_t *cfg,
286 cistpl_cftable_entry_t *dflt,
287 void *priv_data) 285 void *priv_data)
288{ 286{
289 if (cfg->index == 0) 287 if (p_dev->config_index == 0)
290 return -ENODEV; 288 return -EINVAL;
291
292 /* IO window settings */
293 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
294 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
295 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
296 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
297 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
298 p_dev->resource[0]->flags |=
299 pcmcia_io_cfg_data_width(io->flags);
300 p_dev->resource[0]->start = io->win[0].base;
301 p_dev->resource[0]->end = io->win[0].len;
302 if (io->nwin > 1) {
303 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
304 p_dev->resource[1]->start = io->win[1].base;
305 p_dev->resource[1]->end = io->win[1].len;
306 }
307 /* This reserves IO space but doesn't actually enable it */
308 if (pcmcia_request_io(p_dev) != 0)
309 return -ENODEV;
310 }
311 289
312 /* If we got this far, we're cool! */ 290 return pcmcia_request_io(p_dev);
313 return 0;
314} 291}
315 292
316static void dio24_config(struct pcmcia_device *link) 293static void dio24_config(struct pcmcia_device *link)
@@ -321,7 +298,8 @@ static void dio24_config(struct pcmcia_device *link)
321 298
322 dev_dbg(&link->dev, "dio24_config\n"); 299 dev_dbg(&link->dev, "dio24_config\n");
323 300
324 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO; 301 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO |
302 CONF_AUTO_SET_IO;
325 303
326 ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, NULL); 304 ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, NULL);
327 if (ret) { 305 if (ret) {
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
index 6eacbd70e2e9..5123b3131c51 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -261,35 +261,12 @@ static void labpc_cs_detach(struct pcmcia_device *link)
261======================================================================*/ 261======================================================================*/
262 262
263static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev, 263static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
264 cistpl_cftable_entry_t *cfg,
265 cistpl_cftable_entry_t *dflt,
266 void *priv_data) 264 void *priv_data)
267{ 265{
268 if (cfg->index == 0) 266 if (p_dev->config_index == 0)
269 return -ENODEV; 267 return -EINVAL;
270
271 /* IO window settings */
272 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
273 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
274 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
275 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
276 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
277 p_dev->resource[0]->flags |=
278 pcmcia_io_cfg_data_width(io->flags);
279 p_dev->resource[0]->start = io->win[0].base;
280 p_dev->resource[0]->end = io->win[0].len;
281 if (io->nwin > 1) {
282 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
283 p_dev->resource[1]->start = io->win[1].base;
284 p_dev->resource[1]->end = io->win[1].len;
285 }
286 /* This reserves IO space but doesn't actually enable it */
287 if (pcmcia_request_io(p_dev) != 0)
288 return -ENODEV;
289 }
290 268
291 /* If we got this far, we're cool! */ 269 return pcmcia_request_io(p_dev);
292 return 0;
293} 270}
294 271
295 272
@@ -300,7 +277,7 @@ static void labpc_config(struct pcmcia_device *link)
300 dev_dbg(&link->dev, "labpc_config\n"); 277 dev_dbg(&link->dev, "labpc_config\n");
301 278
302 link->config_flags |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ | 279 link->config_flags |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ |
303 CONF_AUTO_AUDIO; 280 CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
304 281
305 ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, NULL); 282 ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, NULL);
306 if (ret) { 283 if (ret) {
@@ -316,7 +293,6 @@ static void labpc_config(struct pcmcia_device *link)
316 the I/O windows and the interrupt mapping, and putting the 293 the I/O windows and the interrupt mapping, and putting the
317 card and host interface into "Memory and IO" mode. 294 card and host interface into "Memory and IO" mode.
318 */ 295 */
319 p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
320 ret = pcmcia_enable_device(link); 296 ret = pcmcia_enable_device(link);
321 if (ret) 297 if (ret)
322 goto failed; 298 goto failed;
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
index da4e2a21b19a..f1e31d3e12bc 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -262,10 +262,6 @@ static struct pcmcia_device *cur_dev = NULL;
262 262
263static int cs_attach(struct pcmcia_device *link) 263static int cs_attach(struct pcmcia_device *link)
264{ 264{
265 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
266 link->resource[0]->end = 16;
267 link->config_flags |= CONF_ENABLE_IRQ;
268
269 cur_dev = link; 265 cur_dev = link;
270 266
271 mio_cs_config(link); 267 mio_cs_config(link);
@@ -299,15 +295,12 @@ static int mio_cs_resume(struct pcmcia_device *link)
299} 295}
300 296
301 297
302static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev, 298static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data)
303 cistpl_cftable_entry_t *cfg,
304 cistpl_cftable_entry_t *dflt,
305 void *priv_data)
306{ 299{
307 int base, ret; 300 int base, ret;
308 301
309 p_dev->resource[0]->end = cfg->io.win[0].len; 302 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
310 p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK; 303 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
311 304
312 for (base = 0x000; base < 0x400; base += 0x20) { 305 for (base = 0x000; base < 0x400; base += 0x20) {
313 p_dev->resource[0]->start = base; 306 p_dev->resource[0]->start = base;
@@ -324,6 +317,7 @@ static void mio_cs_config(struct pcmcia_device *link)
324 int ret; 317 int ret;
325 318
326 DPRINTK("mio_cs_config(link=%p)\n", link); 319 DPRINTK("mio_cs_config(link=%p)\n", link);
320 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
327 321
328 ret = pcmcia_loop_config(link, mio_pcmcia_config_loop, NULL); 322 ret = pcmcia_loop_config(link, mio_pcmcia_config_loop, NULL);
329 if (ret) { 323 if (ret) {
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index 03a72d7ac676..afd283d0e711 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -1068,35 +1068,11 @@ static void daqp_cs_detach(struct pcmcia_device *link)
1068======================================================================*/ 1068======================================================================*/
1069 1069
1070 1070
1071static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, 1071static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data)
1072 cistpl_cftable_entry_t *cfg,
1073 cistpl_cftable_entry_t *dflt,
1074 void *priv_data)
1075{ 1072{
1076 if (cfg->index == 0) 1073 if (p_dev->config_index == 0)
1077 return -ENODEV; 1074 return -EINVAL;
1078 1075
1079 /* Do we need to allocate an interrupt? */
1080 p_dev->config_flags |= CONF_ENABLE_IRQ;
1081
1082 /* IO window settings */
1083 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
1084 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
1085 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
1086 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
1087 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
1088 p_dev->resource[0]->flags |=
1089 pcmcia_io_cfg_data_width(io->flags);
1090 p_dev->resource[0]->start = io->win[0].base;
1091 p_dev->resource[0]->end = io->win[0].len;
1092 if (io->nwin > 1) {
1093 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
1094 p_dev->resource[1]->start = io->win[1].base;
1095 p_dev->resource[1]->end = io->win[1].len;
1096 }
1097 }
1098
1099 /* This reserves IO space but doesn't actually enable it */
1100 return pcmcia_request_io(p_dev); 1076 return pcmcia_request_io(p_dev);
1101} 1077}
1102 1078
@@ -1106,6 +1082,8 @@ static void daqp_cs_config(struct pcmcia_device *link)
1106 1082
1107 dev_dbg(&link->dev, "daqp_cs_config\n"); 1083 dev_dbg(&link->dev, "daqp_cs_config\n");
1108 1084
1085 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
1086
1109 ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL); 1087 ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL);
1110 if (ret) { 1088 if (ret) {
1111 dev_warn(&link->dev, "no configuration found\n"); 1089 dev_warn(&link->dev, "no configuration found\n");
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index 670a76bf5164..76edd39525de 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -31,8 +31,6 @@ static int ixj_probe(struct pcmcia_device *p_dev)
31{ 31{
32 dev_dbg(&p_dev->dev, "ixj_attach()\n"); 32 dev_dbg(&p_dev->dev, "ixj_attach()\n");
33 /* Create new ixj device */ 33 /* Create new ixj device */
34 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
35 p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
36 p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL); 34 p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
37 if (!p_dev->priv) { 35 if (!p_dev->priv) {
38 return -ENOMEM; 36 return -ENOMEM;
@@ -109,36 +107,28 @@ failed:
109 return; 107 return;
110} 108}
111 109
112static int ixj_config_check(struct pcmcia_device *p_dev, 110static int ixj_config_check(struct pcmcia_device *p_dev, void *priv_data)
113 cistpl_cftable_entry_t *cfg,
114 cistpl_cftable_entry_t *dflt,
115 void *priv_data)
116{ 111{
117 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { 112 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
118 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; 113 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
119 p_dev->resource[0]->start = io->win[0].base; 114 p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
120 p_dev->resource[0]->end = io->win[0].len; 115 p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
121 p_dev->io_lines = 3; 116 p_dev->io_lines = 3;
122 if (io->nwin == 2) { 117
123 p_dev->resource[1]->start = io->win[1].base; 118 return pcmcia_request_io(p_dev);
124 p_dev->resource[1]->end = io->win[1].len;
125 }
126 if (!pcmcia_request_io(p_dev))
127 return 0;
128 }
129 return -ENODEV;
130} 119}
131 120
132static int ixj_config(struct pcmcia_device * link) 121static int ixj_config(struct pcmcia_device * link)
133{ 122{
134 IXJ *j; 123 IXJ *j;
135 ixj_info_t *info; 124 ixj_info_t *info;
136 cistpl_cftable_entry_t dflt = { 0 };
137 125
138 info = link->priv; 126 info = link->priv;
139 dev_dbg(&link->dev, "ixj_config\n"); 127 dev_dbg(&link->dev, "ixj_config\n");
140 128
141 if (pcmcia_loop_config(link, ixj_config_check, &dflt)) 129 link->config_flags = CONF_AUTO_SET_IO;
130
131 if (pcmcia_loop_config(link, ixj_config_check, NULL))
142 goto failed; 132 goto failed;
143 133
144 if (pcmcia_enable_device(link)) 134 if (pcmcia_enable_device(link))
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index d9606293c1af..81d7eeacdf6a 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -131,28 +131,12 @@ static void sl811_cs_release(struct pcmcia_device * link)
131 platform_device_unregister(&platform_dev); 131 platform_device_unregister(&platform_dev);
132} 132}
133 133
134static int sl811_cs_config_check(struct pcmcia_device *p_dev, 134static int sl811_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
135 cistpl_cftable_entry_t *cfg,
136 cistpl_cftable_entry_t *dflt,
137 void *priv_data)
138{ 135{
139 if (cfg->index == 0) 136 if (p_dev->config_index == 0)
140 return -ENODEV; 137 return -EINVAL;
141 138
142 /* IO window settings */ 139 return pcmcia_request_io(p_dev);
143 p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
144 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
145 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
146 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
147
148 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
149 p_dev->resource[0]->start = io->win[0].base;
150 p_dev->resource[0]->end = io->win[0].len;
151
152 return pcmcia_request_io(p_dev);
153 }
154 pcmcia_disable_device(p_dev);
155 return -ENODEV;
156} 140}
157 141
158 142
@@ -164,7 +148,7 @@ static int sl811_cs_config(struct pcmcia_device *link)
164 dev_dbg(&link->dev, "sl811_cs_config\n"); 148 dev_dbg(&link->dev, "sl811_cs_config\n");
165 149
166 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP | 150 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
167 CONF_AUTO_CHECK_VCC; 151 CONF_AUTO_CHECK_VCC | CONF_AUTO_SET_IO;
168 152
169 if (pcmcia_loop_config(link, sl811_cs_config_check, NULL)) 153 if (pcmcia_loop_config(link, sl811_cs_config_check, NULL))
170 goto failed; 154 goto failed;
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index 0577e5f10304..0b8c8d45df47 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -93,6 +93,7 @@ struct pcmcia_device {
93 /* device setup */ 93 /* device setup */
94 unsigned int irq; 94 unsigned int irq;
95 struct resource *resource[PCMCIA_NUM_RESOURCES]; 95 struct resource *resource[PCMCIA_NUM_RESOURCES];
96 resource_size_t card_addr; /* for the 1st IOMEM resource */
96 unsigned int vpp; 97 unsigned int vpp;
97 98
98 unsigned int config_flags; /* CONF_ENABLE_ flags below */ 99 unsigned int config_flags; /* CONF_ENABLE_ flags below */
@@ -175,8 +176,6 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse);
175/* loop CIS entries for valid configuration */ 176/* loop CIS entries for valid configuration */
176int pcmcia_loop_config(struct pcmcia_device *p_dev, 177int pcmcia_loop_config(struct pcmcia_device *p_dev,
177 int (*conf_check) (struct pcmcia_device *p_dev, 178 int (*conf_check) (struct pcmcia_device *p_dev,
178 cistpl_cftable_entry_t *cf,
179 cistpl_cftable_entry_t *dflt,
180 void *priv_data), 179 void *priv_data),
181 void *priv_data); 180 void *priv_data);
182 181
@@ -225,16 +224,6 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev);
225#define IO_DATA_PATH_WIDTH_16 0x08 224#define IO_DATA_PATH_WIDTH_16 0x08
226#define IO_DATA_PATH_WIDTH_AUTO 0x10 225#define IO_DATA_PATH_WIDTH_AUTO 0x10
227 226
228/* convert flag found in cfgtable to data path width parameter */
229static inline int pcmcia_io_cfg_data_width(unsigned int flags)
230{
231 if (!(flags & CISTPL_IO_8BIT))
232 return IO_DATA_PATH_WIDTH_16;
233 if (!(flags & CISTPL_IO_16BIT))
234 return IO_DATA_PATH_WIDTH_8;
235 return IO_DATA_PATH_WIDTH_AUTO;
236}
237
238/* IO memory */ 227/* IO memory */
239#define WIN_MEMORY_TYPE_CM 0x00 /* default */ 228#define WIN_MEMORY_TYPE_CM 0x00 /* default */
240#define WIN_MEMORY_TYPE_AM 0x20 /* MAP_ATTRIB */ 229#define WIN_MEMORY_TYPE_AM 0x20 /* MAP_ATTRIB */
@@ -264,16 +253,17 @@ static inline int pcmcia_io_cfg_data_width(unsigned int flags)
264#define PRESENT_IOSIZE 0x200 253#define PRESENT_IOSIZE 0x200
265 254
266/* flags to be passed to pcmcia_enable_device() */ 255/* flags to be passed to pcmcia_enable_device() */
267#define CONF_ENABLE_IRQ 0x01 256#define CONF_ENABLE_IRQ 0x0001
268#define CONF_ENABLE_SPKR 0x02 257#define CONF_ENABLE_SPKR 0x0002
269#define CONF_ENABLE_PULSE_IRQ 0x04 258#define CONF_ENABLE_PULSE_IRQ 0x0004
270#define CONF_ENABLE_ESR 0x08 259#define CONF_ENABLE_ESR 0x0008
271 260
272/* flags used by pcmcia_loop_config() autoconfiguration */ 261/* flags used by pcmcia_loop_config() autoconfiguration */
273#define CONF_AUTO_CHECK_VCC 0x10 /* check for matching Vcc? */ 262#define CONF_AUTO_CHECK_VCC 0x0100 /* check for matching Vcc? */
274#define CONF_AUTO_SET_VPP 0x20 /* set Vpp? */ 263#define CONF_AUTO_SET_VPP 0x0200 /* set Vpp? */
275#define CONF_AUTO_AUDIO 0x40 /* enable audio line? */ 264#define CONF_AUTO_AUDIO 0x0400 /* enable audio line? */
276 265#define CONF_AUTO_SET_IO 0x0800 /* set ->resource[0,1] */
266#define CONF_AUTO_SET_IOMEM 0x1000 /* set ->resource[2] */
277 267
278#endif /* __KERNEL__ */ 268#endif /* __KERNEL__ */
279 269