diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-07-30 07:13:46 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-09-29 11:20:24 -0400 |
commit | 00990e7ce0b0e596fe41d9c64d6933ea70084003 (patch) | |
tree | 189e0dd92860feba84231c66955749574cac5d6d /drivers | |
parent | 440eed43e2a95bb842488755683716814da10f2b (diff) |
pcmcia: use autoconfiguration feature for ioports and iomem
When CONF_AUTO_SET_IO or CONF_AUTO_SET_IOMEM are set, the corresponding
fields in struct pcmcia_device *p_dev->resource[0,1,2] are set
accordinly. Drivers wishing to override certain settings may do so in
the callback function, but they no longer need to parse the CIS entries
stored in cistpl_cftable_entry_t themselves.
CC: netdev@vger.kernel.org
CC: linux-wireless@vger.kernel.org
CC: linux-ide@vger.kernel.org
CC: linux-usb@vger.kernel.org
CC: laforge@gnumonks.org
CC: linux-mtd@lists.infradead.org
CC: linux-bluetooth@vger.kernel.org
CC: alsa-devel@alsa-project.org
CC: linux-serial@vger.kernel.org
CC: Jiri Kosina <jkosina@suse.cz>
CC: linux-scsi@vger.kernel.org
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers')
42 files changed, 493 insertions, 1005 deletions
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 | ||
170 | struct pcmcia_config_check { | 170 | static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data) |
171 | unsigned long ctl_base; | ||
172 | int is_kme; | ||
173 | }; | ||
174 | |||
175 | static 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 | ||
316 | failed: | 289 | failed: |
317 | kfree(stk); | ||
318 | pcmcia_disable_device(pdev); | 290 | pcmcia_disable_device(pdev); |
319 | out1: | ||
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 | ||
676 | static int bt3c_check_config(struct pcmcia_device *p_dev, | 674 | static 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 | ||
693 | static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev, | 691 | static 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 | ||
605 | static int btuart_check_config(struct pcmcia_device *p_dev, | 603 | static 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 | ||
622 | static int btuart_check_config_notpicky(struct pcmcia_device *p_dev, | 620 | static 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 | ||
592 | static int dtl1_confcheck(struct pcmcia_device *p_dev, | 589 | static 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 | ||
1744 | static int cm4000_config_check(struct pcmcia_device *p_dev, | 1744 | static 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 | ||
518 | static int cm4040_config_check(struct pcmcia_device *p_dev, | 518 | static 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 | ||
78 | static int ipwireless_probe(struct pcmcia_device *p_dev, | 78 | static 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 | ||
564 | static int mgslpc_ioprobe(struct pcmcia_device *p_dev, | 564 | static 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 | ||
197 | struct pcmcia_config_check { | 195 | static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data) |
198 | unsigned long ctl_base; | ||
199 | int is_kme; | ||
200 | }; | ||
201 | |||
202 | static 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 | ||
239 | static int ide_config(struct pcmcia_device *link) | 217 | static 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 | ||
300 | err_mem: | ||
301 | printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n"); | ||
302 | goto failed; | ||
303 | |||
304 | failed: | 273 | failed: |
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 | ||
73 | static int avmcs_probe(struct pcmcia_device *p_dev) | 73 | static 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 | ||
110 | static int avmcs_configcheck(struct pcmcia_device *p_dev, | 105 | static 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 | ||
117 | static int avma1cs_configcheck(struct pcmcia_device *p_dev, | 111 | static 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 | ||
163 | static int elsa_cs_configcheck(struct pcmcia_device *p_dev, | 153 | static 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 | ======================================================================*/ |
164 | static int sedlbauer_config_check(struct pcmcia_device *p_dev, | 162 | static 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 | ||
145 | static int teles_cs_configcheck(struct pcmcia_device *p_dev, | 142 | static 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 | ||
287 | static int axnet_configcheck(struct pcmcia_device *p_dev, | 287 | static 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 | ||
317 | static int axnet_config(struct pcmcia_device *link) | 299 | static 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 | ||
322 | static int fmvj18x_ioprobe(struct pcmcia_device *p_dev, | 322 | static 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 | ||
503 | static int pcnet_confcheck(struct pcmcia_device *p_dev, | 503 | static 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 | ||
541 | static hw_info_t *pcnet_try_config(struct pcmcia_device *link, | 521 | static 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 | ||
420 | static int mhz_mfc_config_check(struct pcmcia_device *p_dev, | 417 | static 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 | ||
589 | static int smc_configcheck(struct pcmcia_device *p_dev, | 588 | static 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 | ||
667 | static int | 666 | static int |
668 | xirc2ps_config_modem(struct pcmcia_device *p_dev, | 667 | xirc2ps_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 | ||
686 | static int | 691 | static int |
687 | xirc2ps_config_check(struct pcmcia_device *p_dev, | 692 | xirc2ps_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 | ||
140 | static int airo_cs_config_check(struct pcmcia_device *p_dev, | 140 | static 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 | ||
157 | static int atmel_config_check(struct pcmcia_device *p_dev, | 157 | static 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 | ||
472 | static int prism2_config_check(struct pcmcia_device *p_dev, | 472 | static 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 | ||
797 | static int if_cs_ioprobe(struct pcmcia_device *p_dev, | 797 | static 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 | ||
145 | static int orinoco_cs_config_check(struct pcmcia_device *p_dev, | 145 | static 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 | ||
178 | next_entry: | 150 | return pcmcia_request_io(p_dev); |
179 | pcmcia_disable_device(p_dev); | ||
180 | return -ENODEV; | ||
181 | }; | 151 | }; |
182 | 152 | ||
183 | static int | 153 | static 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 | ||
207 | static int spectrum_cs_config_check(struct pcmcia_device *p_dev, | 207 | static 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 | ||
247 | next_entry: | 213 | return pcmcia_request_io(p_dev); |
248 | pcmcia_disable_device(p_dev); | ||
249 | return -ENODEV; | ||
250 | }; | 214 | }; |
251 | 215 | ||
252 | static int | 216 | static 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 | ||
136 | static int parport_config_check(struct pcmcia_device *p_dev, | 134 | static 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 | ||
159 | static int parport_config(struct pcmcia_device *link) | 144 | static 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 | */ | ||
132 | static 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 | |||
128 | struct pcmcia_cfg_mem { | 142 | struct 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 | */ |
204 | int pcmcia_loop_config(struct pcmcia_device *p_dev, | 262 | int 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 | ||
124 | static int aha152x_config_check(struct pcmcia_device *p_dev, | 122 | static 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 | ||
144 | static int aha152x_config_cs(struct pcmcia_device *link) | 142 | static 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 | ||
106 | static int fdomain_config_check(struct pcmcia_device *p_dev, | 104 | static 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 | ||
1597 | static int nsp_cs_config_check(struct pcmcia_device *p_dev, | 1590 | static 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 | ||
179 | static int qlogic_config_check(struct pcmcia_device *p_dev, | 177 | static 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 | ||
686 | static int SYM53C500_config_check(struct pcmcia_device *p_dev, | 686 | static 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 | ||
427 | static int simple_config_check(struct pcmcia_device *p_dev, | 427 | static 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 | ||
447 | static int simple_config_check_notpicky(struct pcmcia_device *p_dev, | 448 | static 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 | ||
506 | static int multi_config_check(struct pcmcia_device *p_dev, | 507 | static 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 | ||
526 | static int multi_config_check_notpicky(struct pcmcia_device *p_dev, | 528 | static 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 | ||
545 | static int multi_config(struct pcmcia_device *link) | 547 | static 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 | ||
614 | static int serial_check_for_multi(struct pcmcia_device *p_dev, | 616 | static 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 | ||
712 | static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, | 712 | static 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 | ||
745 | static void das16cs_pcmcia_config(struct pcmcia_device *link) | 721 | static 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 | ||
194 | static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, | 194 | static 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 | ||
532 | static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, | 532 | static 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 | ||
564 | static void dio700_config(struct pcmcia_device *link) | 541 | static 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 | ||
284 | static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev, | 284 | static 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 | ||
316 | static void dio24_config(struct pcmcia_device *link) | 293 | static 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 | ||
263 | static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev, | 263 | static 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 | ||
263 | static int cs_attach(struct pcmcia_device *link) | 263 | static 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 | ||
302 | static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev, | 298 | static 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 | ||
1071 | static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, | 1071 | static 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 | ||
112 | static int ixj_config_check(struct pcmcia_device *p_dev, | 110 | static 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 | ||
132 | static int ixj_config(struct pcmcia_device * link) | 121 | static 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 | ||
134 | static int sl811_cs_config_check(struct pcmcia_device *p_dev, | 134 | static 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; |