aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/pcmcia/driver-changes.txt6
-rw-r--r--drivers/ata/pata_pcmcia.c168
-rw-r--r--drivers/bluetooth/bt3c_cs.c121
-rw-r--r--drivers/bluetooth/btuart_cs.c122
-rw-r--r--drivers/bluetooth/dtl1_cs.c63
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c73
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c76
-rw-r--r--drivers/ide/legacy/ide-cs.c158
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c81
-rw-r--r--drivers/isdn/hisax/avma1_cs.c77
-rw-r--r--drivers/isdn/hisax/elsa_cs.c73
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c197
-rw-r--r--drivers/isdn/hisax/teles_cs.c73
-rw-r--r--drivers/net/pcmcia/axnet_cs.c73
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c79
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c98
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c75
-rw-r--r--drivers/net/wireless/airo_cs.c222
-rw-r--r--drivers/net/wireless/atmel_cs.c119
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c213
-rw-r--r--drivers/net/wireless/orinoco_cs.c163
-rw-r--r--drivers/net/wireless/spectrum_cs.c162
-rw-r--r--drivers/parport/parport_cs.c70
-rw-r--r--drivers/pcmcia/cistpl.c18
-rw-r--r--drivers/pcmcia/ds.c12
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c2
-rw-r--r--drivers/pcmcia/pcmcia_resource.c76
-rw-r--r--drivers/pcmcia/socket_sysfs.c13
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c58
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c37
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c194
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c47
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c46
-rw-r--r--drivers/serial/serial_cs.c266
-rw-r--r--drivers/telephony/ixj_pcmcia.c72
-rw-r--r--drivers/usb/host/sl811_cs.c130
-rw-r--r--include/pcmcia/cistpl.h18
-rw-r--r--include/pcmcia/ds.h6
-rw-r--r--include/pcmcia/ss.h4
39 files changed, 1559 insertions, 2002 deletions
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index 96f155e6875..059934363ca 100644
--- a/Documentation/pcmcia/driver-changes.txt
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -1,5 +1,11 @@
1This file details changes in 2.6 which affect PCMCIA card driver authors: 1This file details changes in 2.6 which affect PCMCIA card driver authors:
2 2
3* New configuration loop helper (as of 2.6.28)
4 By calling pcmcia_loop_config(), a driver can iterate over all available
5 configuration options. During a driver's probe() phase, one doesn't need
6 to use pcmcia_get_{first,next}_tuple, pcmcia_get_tuple_data and
7 pcmcia_parse_tuple directly in most if not all cases.
8
3* New release helper (as of 2.6.17) 9* New release helper (as of 2.6.17)
4 Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's 10 Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's
5 necessary now is calling pcmcia_disable_device. As there is no valid 11 necessary now is calling pcmcia_disable_device. As there is no valid
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 41b4361bbf6..02b596b9cf6 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -148,6 +148,64 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
148#define CS_CHECK(fn, ret) \ 148#define CS_CHECK(fn, ret) \
149do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 149do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
150 150
151
152struct pcmcia_config_check {
153 unsigned long ctl_base;
154 int skip_vcc;
155 int is_kme;
156};
157
158static int pcmcia_check_one_config(struct pcmcia_device *pdev,
159 cistpl_cftable_entry_t *cfg,
160 cistpl_cftable_entry_t *dflt,
161 unsigned int vcc,
162 void *priv_data)
163{
164 struct pcmcia_config_check *stk = priv_data;
165
166 /* Check for matching Vcc, unless we're desperate */
167 if (!stk->skip_vcc) {
168 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
169 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
170 return -ENODEV;
171 } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
172 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
173 return -ENODEV;
174 }
175 }
176
177 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
178 pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
179 else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
180 pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
181
182 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
183 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
184 pdev->io.BasePort1 = io->win[0].base;
185 pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
186 if (!(io->flags & CISTPL_IO_16BIT))
187 pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
188 if (io->nwin == 2) {
189 pdev->io.NumPorts1 = 8;
190 pdev->io.BasePort2 = io->win[1].base;
191 pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
192 if (pcmcia_request_io(pdev, &pdev->io) != 0)
193 return -ENODEV;
194 stk->ctl_base = pdev->io.BasePort2;
195 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
196 pdev->io.NumPorts1 = io->win[0].len;
197 pdev->io.NumPorts2 = 0;
198 if (pcmcia_request_io(pdev, &pdev->io) != 0)
199 return -ENODEV;
200 stk->ctl_base = pdev->io.BasePort1 + 0x0e;
201 } else
202 return -ENODEV;
203 /* If we've got this far, we're done */
204 return 0;
205 }
206 return -ENODEV;
207}
208
151/** 209/**
152 * pcmcia_init_one - attach a PCMCIA interface 210 * pcmcia_init_one - attach a PCMCIA interface
153 * @pdev: pcmcia device 211 * @pdev: pcmcia device
@@ -161,19 +219,11 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
161 struct ata_host *host; 219 struct ata_host *host;
162 struct ata_port *ap; 220 struct ata_port *ap;
163 struct ata_pcmcia_info *info; 221 struct ata_pcmcia_info *info;
164 tuple_t tuple; 222 struct pcmcia_config_check *stk = NULL;
165 struct { 223 int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
166 unsigned short buf[128];
167 cisparse_t parse;
168 config_info_t conf;
169 cistpl_cftable_entry_t dflt;
170 } *stk = NULL;
171 cistpl_cftable_entry_t *cfg;
172 int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
173 unsigned long io_base, ctl_base; 224 unsigned long io_base, ctl_base;
174 void __iomem *io_addr, *ctl_addr; 225 void __iomem *io_addr, *ctl_addr;
175 int n_ports = 1; 226 int n_ports = 1;
176
177 struct ata_port_operations *ops = &pcmcia_port_ops; 227 struct ata_port_operations *ops = &pcmcia_port_ops;
178 228
179 info = kzalloc(sizeof(*info), GFP_KERNEL); 229 info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -193,96 +243,27 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
193 pdev->conf.Attributes = CONF_ENABLE_IRQ; 243 pdev->conf.Attributes = CONF_ENABLE_IRQ;
194 pdev->conf.IntType = INT_MEMORY_AND_IO; 244 pdev->conf.IntType = INT_MEMORY_AND_IO;
195 245
196 /* Allocate resoure probing structures */
197
198 stk = kzalloc(sizeof(*stk), GFP_KERNEL);
199 if (!stk)
200 goto out1;
201
202 cfg = &stk->parse.cftable_entry;
203
204 /* Tuples we are walking */
205 tuple.TupleData = (cisdata_t *)&stk->buf;
206 tuple.TupleOffset = 0;
207 tuple.TupleDataMax = 255;
208 tuple.Attributes = 0;
209
210 /* See if we have a manufacturer identifier. Use it to set is_kme for 246 /* See if we have a manufacturer identifier. Use it to set is_kme for
211 vendor quirks */ 247 vendor quirks */
212 is_kme = ((pdev->manf_id == MANFID_KME) && 248 is_kme = ((pdev->manf_id == MANFID_KME) &&
213 ((pdev->card_id == PRODID_KME_KXLC005_A) || 249 ((pdev->card_id == PRODID_KME_KXLC005_A) ||
214 (pdev->card_id == PRODID_KME_KXLC005_B))); 250 (pdev->card_id == PRODID_KME_KXLC005_B)));
215 251
216 /* Not sure if this is right... look up the current Vcc */ 252 /* Allocate resoure probing structures */
217 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf));
218/* link->conf.Vcc = stk->conf.Vcc; */
219
220 pass = io_base = ctl_base = 0;
221 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
222 tuple.Attributes = 0;
223 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
224
225 /* Now munch the resources looking for a suitable set */
226 while (1) {
227 if (pcmcia_get_tuple_data(pdev, &tuple) != 0)
228 goto next_entry;
229 if (pcmcia_parse_tuple(pdev, &tuple, &stk->parse) != 0)
230 goto next_entry;
231 /* Check for matching Vcc, unless we're desperate */
232 if (!pass) {
233 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
234 if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
235 goto next_entry;
236 } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
237 if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
238 goto next_entry;
239 }
240 }
241 253
242 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) 254 stk = kzalloc(sizeof(*stk), GFP_KERNEL);
243 pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; 255 if (!stk)
244 else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) 256 goto out1;
245 pdev->conf.Vpp = stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; 257 stk->is_kme = is_kme;
246 258 stk->skip_vcc = io_base = ctl_base = 0;
247 if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
248 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
249 pdev->conf.ConfigIndex = cfg->index;
250 pdev->io.BasePort1 = io->win[0].base;
251 pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
252 if (!(io->flags & CISTPL_IO_16BIT))
253 pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
254 if (io->nwin == 2) {
255 pdev->io.NumPorts1 = 8;
256 pdev->io.BasePort2 = io->win[1].base;
257 pdev->io.NumPorts2 = (is_kme) ? 2 : 1;
258 if (pcmcia_request_io(pdev, &pdev->io) != 0)
259 goto next_entry;
260 io_base = pdev->io.BasePort1;
261 ctl_base = pdev->io.BasePort2;
262 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
263 pdev->io.NumPorts1 = io->win[0].len;
264 pdev->io.NumPorts2 = 0;
265 if (pcmcia_request_io(pdev, &pdev->io) != 0)
266 goto next_entry;
267 io_base = pdev->io.BasePort1;
268 ctl_base = pdev->io.BasePort1 + 0x0e;
269 } else
270 goto next_entry;
271 /* If we've got this far, we're done */
272 break;
273 }
274next_entry:
275 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
276 memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
277 if (pass) {
278 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(pdev, &tuple));
279 } else if (pcmcia_get_next_tuple(pdev, &tuple) != 0) {
280 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
281 memset(&stk->dflt, 0, sizeof(stk->dflt));
282 pass++;
283 }
284 }
285 259
260 if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) {
261 stk->skip_vcc = 1;
262 if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk))
263 goto failed; /* No suitable config found */
264 }
265 io_base = pdev->io.BasePort1;
266 ctl_base = stk->ctl_base;
286 CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq)); 267 CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
287 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf)); 268 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
288 269
@@ -384,6 +365,7 @@ static struct pcmcia_device_id pcmcia_devices[] = {
384 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), 365 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
385 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904), 366 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904),
386 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ 367 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */
368 PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */
387 PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */ 369 PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */
388 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ 370 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
389 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), 371 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
@@ -404,9 +386,9 @@ static struct pcmcia_device_id pcmcia_devices[] = {
404 PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), 386 PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591),
405 PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), 387 PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
406 PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), 388 PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
407 PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
408 PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae), 389 PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
409 PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178), 390 PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
391 PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
410 PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178), 392 PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
411 PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753), 393 PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
412 PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e), 394 PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 593b7c59503..3fd8022a635 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -678,93 +678,70 @@ static void bt3c_detach(struct pcmcia_device *link)
678 kfree(info); 678 kfree(info);
679} 679}
680 680
681static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) 681static int bt3c_check_config(struct pcmcia_device *p_dev,
682 cistpl_cftable_entry_t *cf,
683 cistpl_cftable_entry_t *dflt,
684 unsigned int vcc,
685 void *priv_data)
682{ 686{
683 int i; 687 unsigned long try = (unsigned long) priv_data;
684 688
685 i = pcmcia_get_tuple_data(handle, tuple); 689 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
686 if (i != CS_SUCCESS) 690 p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
687 return i; 691 if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
688 692 (cf->io.win[0].base != 0)) {
689 return pcmcia_parse_tuple(handle, tuple, parse); 693 p_dev->io.BasePort1 = cf->io.win[0].base;
690} 694 p_dev->io.IOAddrLines = (try == 0) ? 16 :
691 695 cf->io.flags & CISTPL_IO_LINES_MASK;
692static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) 696 if (!pcmcia_request_io(p_dev, &p_dev->io))
693{ 697 return 0;
694 if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) 698 }
695 return CS_NO_MORE_ITEMS; 699 return -ENODEV;
696 return get_tuple(handle, tuple, parse);
697} 700}
698 701
699static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) 702static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
703 cistpl_cftable_entry_t *cf,
704 cistpl_cftable_entry_t *dflt,
705 unsigned int vcc,
706 void *priv_data)
700{ 707{
701 if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) 708 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
702 return CS_NO_MORE_ITEMS; 709 int j;
703 return get_tuple(handle, tuple, parse); 710
711 if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
712 for (j = 0; j < 5; j++) {
713 p_dev->io.BasePort1 = base[j];
714 p_dev->io.IOAddrLines = base[j] ? 16 : 3;
715 if (!pcmcia_request_io(p_dev, &p_dev->io))
716 return 0;
717 }
718 }
719 return -ENODEV;
704} 720}
705 721
706static int bt3c_config(struct pcmcia_device *link) 722static int bt3c_config(struct pcmcia_device *link)
707{ 723{
708 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
709 bt3c_info_t *info = link->priv; 724 bt3c_info_t *info = link->priv;
710 tuple_t tuple; 725 int i;
711 u_short buf[256]; 726 unsigned long try;
712 cisparse_t parse; 727
713 cistpl_cftable_entry_t *cf = &parse.cftable_entry; 728 /* First pass: look for a config entry that looks normal.
714 int i, j, try; 729 Two tries: without IO aliases, then with aliases */
715 730 for (try = 0; try < 2; try++)
716 /* First pass: look for a config entry that looks normal. */ 731 if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
717 tuple.TupleData = (cisdata_t *)buf; 732 goto found_port;
718 tuple.TupleOffset = 0;
719 tuple.TupleDataMax = 255;
720 tuple.Attributes = 0;
721 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
722 /* Two tries: without IO aliases, then with aliases */
723 for (try = 0; try < 2; try++) {
724 i = first_tuple(link, &tuple, &parse);
725 while (i != CS_NO_MORE_ITEMS) {
726 if (i != CS_SUCCESS)
727 goto next_entry;
728 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
729 link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
730 if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
731 link->conf.ConfigIndex = cf->index;
732 link->io.BasePort1 = cf->io.win[0].base;
733 link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
734 i = pcmcia_request_io(link, &link->io);
735 if (i == CS_SUCCESS)
736 goto found_port;
737 }
738next_entry:
739 i = next_tuple(link, &tuple, &parse);
740 }
741 }
742 733
743 /* Second pass: try to find an entry that isn't picky about 734 /* Second pass: try to find an entry that isn't picky about
744 its base address, then try to grab any standard serial port 735 its base address, then try to grab any standard serial port
745 address, and finally try to get any free port. */ 736 address, and finally try to get any free port. */
746 i = first_tuple(link, &tuple, &parse); 737 if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
747 while (i != CS_NO_MORE_ITEMS) { 738 goto found_port;
748 if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
749 link->conf.ConfigIndex = cf->index;
750 for (j = 0; j < 5; j++) {
751 link->io.BasePort1 = base[j];
752 link->io.IOAddrLines = base[j] ? 16 : 3;
753 i = pcmcia_request_io(link, &link->io);
754 if (i == CS_SUCCESS)
755 goto found_port;
756 }
757 }
758 i = next_tuple(link, &tuple, &parse);
759 }
760 739
761found_port: 740 BT_ERR("No usable port range found");
762 if (i != CS_SUCCESS) { 741 cs_error(link, RequestIO, -ENODEV);
763 BT_ERR("No usable port range found"); 742 goto failed;
764 cs_error(link, RequestIO, i);
765 goto failed;
766 }
767 743
744found_port:
768 i = pcmcia_request_irq(link, &link->irq); 745 i = pcmcia_request_irq(link, &link->irq);
769 if (i != CS_SUCCESS) { 746 if (i != CS_SUCCESS) {
770 cs_error(link, RequestIRQ, i); 747 cs_error(link, RequestIRQ, i);
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 68d1d258e6a..17183125434 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -607,94 +607,70 @@ static void btuart_detach(struct pcmcia_device *link)
607 kfree(info); 607 kfree(info);
608} 608}
609 609
610static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) 610static int btuart_check_config(struct pcmcia_device *p_dev,
611 cistpl_cftable_entry_t *cf,
612 cistpl_cftable_entry_t *dflt,
613 unsigned int vcc,
614 void *priv_data)
611{ 615{
612 int i; 616 int *try = priv_data;
613 617
614 i = pcmcia_get_tuple_data(handle, tuple); 618 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
615 if (i != CS_SUCCESS) 619 p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
616 return i; 620 if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
617 621 (cf->io.win[0].base != 0)) {
618 return pcmcia_parse_tuple(handle, tuple, parse); 622 p_dev->io.BasePort1 = cf->io.win[0].base;
619} 623 p_dev->io.IOAddrLines = (*try == 0) ? 16 :
620 624 cf->io.flags & CISTPL_IO_LINES_MASK;
621static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) 625 if (!pcmcia_request_io(p_dev, &p_dev->io))
622{ 626 return 0;
623 if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) 627 }
624 return CS_NO_MORE_ITEMS; 628 return -ENODEV;
625 return get_tuple(handle, tuple, parse);
626} 629}
627 630
628static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) 631static int btuart_check_config_notpicky(struct pcmcia_device *p_dev,
632 cistpl_cftable_entry_t *cf,
633 cistpl_cftable_entry_t *dflt,
634 unsigned int vcc,
635 void *priv_data)
629{ 636{
630 if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) 637 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
631 return CS_NO_MORE_ITEMS; 638 int j;
632 return get_tuple(handle, tuple, parse); 639
640 if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
641 for (j = 0; j < 5; j++) {
642 p_dev->io.BasePort1 = base[j];
643 p_dev->io.IOAddrLines = base[j] ? 16 : 3;
644 if (!pcmcia_request_io(p_dev, &p_dev->io))
645 return 0;
646 }
647 }
648 return -ENODEV;
633} 649}
634 650
635static int btuart_config(struct pcmcia_device *link) 651static int btuart_config(struct pcmcia_device *link)
636{ 652{
637 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
638 btuart_info_t *info = link->priv; 653 btuart_info_t *info = link->priv;
639 tuple_t tuple; 654 int i;
640 u_short buf[256]; 655 int try;
641 cisparse_t parse; 656
642 cistpl_cftable_entry_t *cf = &parse.cftable_entry; 657 /* First pass: look for a config entry that looks normal.
643 int i, j, try; 658 Two tries: without IO aliases, then with aliases */
644 659 for (try = 0; try < 2; try++)
645 /* First pass: look for a config entry that looks normal. */ 660 if (!pcmcia_loop_config(link, btuart_check_config, &try))
646 tuple.TupleData = (cisdata_t *) buf; 661 goto found_port;
647 tuple.TupleOffset = 0;
648 tuple.TupleDataMax = 255;
649 tuple.Attributes = 0;
650 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
651 /* Two tries: without IO aliases, then with aliases */
652 for (try = 0; try < 2; try++) {
653 i = first_tuple(link, &tuple, &parse);
654 while (i != CS_NO_MORE_ITEMS) {
655 if (i != CS_SUCCESS)
656 goto next_entry;
657 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
658 link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
659 if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
660 link->conf.ConfigIndex = cf->index;
661 link->io.BasePort1 = cf->io.win[0].base;
662 link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
663 i = pcmcia_request_io(link, &link->io);
664 if (i == CS_SUCCESS)
665 goto found_port;
666 }
667next_entry:
668 i = next_tuple(link, &tuple, &parse);
669 }
670 }
671 662
672 /* Second pass: try to find an entry that isn't picky about 663 /* Second pass: try to find an entry that isn't picky about
673 its base address, then try to grab any standard serial port 664 its base address, then try to grab any standard serial port
674 address, and finally try to get any free port. */ 665 address, and finally try to get any free port. */
675 i = first_tuple(link, &tuple, &parse); 666 if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL))
676 while (i != CS_NO_MORE_ITEMS) { 667 goto found_port;
677 if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
678 && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
679 link->conf.ConfigIndex = cf->index;
680 for (j = 0; j < 5; j++) {
681 link->io.BasePort1 = base[j];
682 link->io.IOAddrLines = base[j] ? 16 : 3;
683 i = pcmcia_request_io(link, &link->io);
684 if (i == CS_SUCCESS)
685 goto found_port;
686 }
687 }
688 i = next_tuple(link, &tuple, &parse);
689 }
690 668
691found_port: 669 BT_ERR("No usable port range found");
692 if (i != CS_SUCCESS) { 670 cs_error(link, RequestIO, -ENODEV);
693 BT_ERR("No usable port range found"); 671 goto failed;
694 cs_error(link, RequestIO, i);
695 goto failed;
696 }
697 672
673found_port:
698 i = pcmcia_request_irq(link, &link->irq); 674 i = pcmcia_request_irq(link, &link->irq);
699 if (i != CS_SUCCESS) { 675 if (i != CS_SUCCESS) {
700 cs_error(link, RequestIRQ, i); 676 cs_error(link, RequestIRQ, i);
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index dae45cdf02b..ec12560e034 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -590,66 +590,31 @@ static void dtl1_detach(struct pcmcia_device *link)
590 kfree(info); 590 kfree(info);
591} 591}
592 592
593static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) 593static int dtl1_confcheck(struct pcmcia_device *p_dev,
594 cistpl_cftable_entry_t *cf,
595 cistpl_cftable_entry_t *dflt,
596 unsigned int vcc,
597 void *priv_data)
594{ 598{
595 int i; 599 if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
596 600 p_dev->io.BasePort1 = cf->io.win[0].base;
597 i = pcmcia_get_tuple_data(handle, tuple); 601 p_dev->io.NumPorts1 = cf->io.win[0].len; /*yo */
598 if (i != CS_SUCCESS) 602 p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
599 return i; 603 if (!pcmcia_request_io(p_dev, &p_dev->io))
600 604 return 0;
601 return pcmcia_parse_tuple(handle, tuple, parse); 605 }
602} 606 return -ENODEV;
603
604static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
605{
606 if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
607 return CS_NO_MORE_ITEMS;
608 return get_tuple(handle, tuple, parse);
609}
610
611static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
612{
613 if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
614 return CS_NO_MORE_ITEMS;
615 return get_tuple(handle, tuple, parse);
616} 607}
617 608
618static int dtl1_config(struct pcmcia_device *link) 609static int dtl1_config(struct pcmcia_device *link)
619{ 610{
620 dtl1_info_t *info = link->priv; 611 dtl1_info_t *info = link->priv;
621 tuple_t tuple;
622 u_short buf[256];
623 cisparse_t parse;
624 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
625 int i; 612 int i;
626 613
627 tuple.TupleData = (cisdata_t *)buf;
628 tuple.TupleOffset = 0;
629 tuple.TupleDataMax = 255;
630 tuple.Attributes = 0;
631 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
632
633 /* Look for a generic full-sized window */ 614 /* Look for a generic full-sized window */
634 link->io.NumPorts1 = 8; 615 link->io.NumPorts1 = 8;
635 i = first_tuple(link, &tuple, &parse); 616 if (!pcmcia_loop_config(link, dtl1_confcheck, NULL))
636 while (i != CS_NO_MORE_ITEMS) {
637 if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
638 link->conf.ConfigIndex = cf->index;
639 link->io.BasePort1 = cf->io.win[0].base;
640 link->io.NumPorts1 = cf->io.win[0].len; /*yo */
641 link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
642 i = pcmcia_request_io(link, &link->io);
643 if (i == CS_SUCCESS)
644 break;
645 }
646 i = next_tuple(link, &tuple, &parse);
647 }
648
649 if (i != CS_SUCCESS) {
650 cs_error(link, RequestIO, i);
651 goto failed; 617 goto failed;
652 }
653 618
654 i = pcmcia_request_irq(link, &link->irq); 619 i = pcmcia_request_irq(link, &link->irq);
655 if (i != CS_SUCCESS) { 620 if (i != CS_SUCCESS) {
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index f070ae7bd91..1c5bf99895e 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1759,65 +1759,40 @@ static void cmm_cm4000_release(struct pcmcia_device * link)
1759 1759
1760/*==== Interface to PCMCIA Layer =======================================*/ 1760/*==== Interface to PCMCIA Layer =======================================*/
1761 1761
1762static int cm4000_config_check(struct pcmcia_device *p_dev,
1763 cistpl_cftable_entry_t *cfg,
1764 cistpl_cftable_entry_t *dflt,
1765 unsigned int vcc,
1766 void *priv_data)
1767{
1768 if (!cfg->io.nwin)
1769 return -ENODEV;
1770
1771 /* Get the IOaddr */
1772 p_dev->io.BasePort1 = cfg->io.win[0].base;
1773 p_dev->io.NumPorts1 = cfg->io.win[0].len;
1774 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1775 if (!(cfg->io.flags & CISTPL_IO_8BIT))
1776 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1777 if (!(cfg->io.flags & CISTPL_IO_16BIT))
1778 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1779 p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
1780
1781 return pcmcia_request_io(p_dev, &p_dev->io);
1782}
1783
1762static int cm4000_config(struct pcmcia_device * link, int devno) 1784static int cm4000_config(struct pcmcia_device * link, int devno)
1763{ 1785{
1764 struct cm4000_dev *dev; 1786 struct cm4000_dev *dev;
1765 tuple_t tuple;
1766 cisparse_t parse;
1767 u_char buf[64];
1768 int fail_fn, fail_rc;
1769 int rc;
1770 1787
1771 /* read the config-tuples */ 1788 /* read the config-tuples */
1772 tuple.Attributes = 0; 1789 if (pcmcia_loop_config(link, cm4000_config_check, NULL))
1773 tuple.TupleData = buf;
1774 tuple.TupleDataMax = sizeof(buf);
1775 tuple.TupleOffset = 0;
1776
1777 link->io.BasePort2 = 0;
1778 link->io.NumPorts2 = 0;
1779 link->io.Attributes2 = 0;
1780 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1781 for (rc = pcmcia_get_first_tuple(link, &tuple);
1782 rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(link, &tuple)) {
1783
1784 rc = pcmcia_get_tuple_data(link, &tuple);
1785 if (rc != CS_SUCCESS)
1786 continue;
1787 rc = pcmcia_parse_tuple(link, &tuple, &parse);
1788 if (rc != CS_SUCCESS)
1789 continue;
1790
1791 link->conf.ConfigIndex = parse.cftable_entry.index;
1792
1793 if (!parse.cftable_entry.io.nwin)
1794 continue;
1795
1796 /* Get the IOaddr */
1797 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
1798 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
1799 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1800 if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
1801 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1802 if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
1803 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1804 link->io.IOAddrLines = parse.cftable_entry.io.flags
1805 & CISTPL_IO_LINES_MASK;
1806
1807 rc = pcmcia_request_io(link, &link->io);
1808 if (rc == CS_SUCCESS)
1809 break; /* we are done */
1810 }
1811 if (rc != CS_SUCCESS)
1812 goto cs_release; 1790 goto cs_release;
1813 1791
1814 link->conf.IntType = 00000002; 1792 link->conf.IntType = 00000002;
1815 1793
1816 if ((fail_rc = 1794 if (pcmcia_request_configuration(link, &link->conf))
1817 pcmcia_request_configuration(link, &link->conf)) != CS_SUCCESS) {
1818 fail_fn = RequestConfiguration;
1819 goto cs_release; 1795 goto cs_release;
1820 }
1821 1796
1822 dev = link->priv; 1797 dev = link->priv;
1823 sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); 1798 sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 0b5934bef7a..e047bac56f0 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -526,65 +526,49 @@ static void cm4040_reader_release(struct pcmcia_device *link)
526 return; 526 return;
527} 527}
528 528
529static int reader_config(struct pcmcia_device *link, int devno) 529static int cm4040_config_check(struct pcmcia_device *p_dev,
530 cistpl_cftable_entry_t *cfg,
531 cistpl_cftable_entry_t *dflt,
532 unsigned int vcc,
533 void *priv_data)
530{ 534{
531 struct reader_dev *dev;
532 tuple_t tuple;
533 cisparse_t parse;
534 u_char buf[64];
535 int fail_fn, fail_rc;
536 int rc; 535 int rc;
536 if (!cfg->io.nwin)
537 return -ENODEV;
538
539 /* Get the IOaddr */
540 p_dev->io.BasePort1 = cfg->io.win[0].base;
541 p_dev->io.NumPorts1 = cfg->io.win[0].len;
542 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
543 if (!(cfg->io.flags & CISTPL_IO_8BIT))
544 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
545 if (!(cfg->io.flags & CISTPL_IO_16BIT))
546 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
547 p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
548
549 rc = pcmcia_request_io(p_dev, &p_dev->io);
550 dev_printk(KERN_INFO, &handle_to_dev(p_dev),
551 "pcmcia_request_io returned 0x%x\n", rc);
552 return rc;
553}
554
537 555
538 tuple.Attributes = 0; 556static int reader_config(struct pcmcia_device *link, int devno)
539 tuple.TupleData = buf; 557{
540 tuple.TupleDataMax = sizeof(buf); 558 struct reader_dev *dev;
541 tuple.TupleOffset = 0; 559 int fail_rc;
542 560
543 link->io.BasePort2 = 0; 561 link->io.BasePort2 = 0;
544 link->io.NumPorts2 = 0; 562 link->io.NumPorts2 = 0;
545 link->io.Attributes2 = 0; 563 link->io.Attributes2 = 0;
546 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 564
547 for (rc = pcmcia_get_first_tuple(link, &tuple); 565 if (pcmcia_loop_config(link, cm4040_config_check, NULL))
548 rc == CS_SUCCESS;
549 rc = pcmcia_get_next_tuple(link, &tuple)) {
550 rc = pcmcia_get_tuple_data(link, &tuple);
551 if (rc != CS_SUCCESS)
552 continue;
553 rc = pcmcia_parse_tuple(link, &tuple, &parse);
554 if (rc != CS_SUCCESS)
555 continue;
556
557 link->conf.ConfigIndex = parse.cftable_entry.index;
558
559 if (!parse.cftable_entry.io.nwin)
560 continue;
561
562 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
563 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
564 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
565 if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
566 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
567 if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
568 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
569 link->io.IOAddrLines = parse.cftable_entry.io.flags
570 & CISTPL_IO_LINES_MASK;
571 rc = pcmcia_request_io(link, &link->io);
572
573 dev_printk(KERN_INFO, &handle_to_dev(link), "foo");
574 if (rc == CS_SUCCESS)
575 break;
576 else
577 dev_printk(KERN_INFO, &handle_to_dev(link),
578 "pcmcia_request_io failed 0x%x\n", rc);
579 }
580 if (rc != CS_SUCCESS)
581 goto cs_release; 566 goto cs_release;
582 567
583 link->conf.IntType = 00000002; 568 link->conf.IntType = 00000002;
584 569
585 if ((fail_rc = pcmcia_request_configuration(link,&link->conf)) 570 if ((fail_rc = pcmcia_request_configuration(link,&link->conf))
586 !=CS_SUCCESS) { 571 !=CS_SUCCESS) {
587 fail_fn = RequestConfiguration;
588 dev_printk(KERN_INFO, &handle_to_dev(link), 572 dev_printk(KERN_INFO, &handle_to_dev(link),
589 "pcmcia_request_configuration failed 0x%x\n", 573 "pcmcia_request_configuration failed 0x%x\n",
590 fail_rc); 574 fail_rc);
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 21bfac13784..fe20cdbd56f 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -220,103 +220,91 @@ out_release:
220#define CS_CHECK(fn, ret) \ 220#define CS_CHECK(fn, ret) \
221do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 221do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
222 222
223struct pcmcia_config_check {
224 unsigned long ctl_base;
225 int skip_vcc;
226 int is_kme;
227};
228
229static int pcmcia_check_one_config(struct pcmcia_device *pdev,
230 cistpl_cftable_entry_t *cfg,
231 cistpl_cftable_entry_t *dflt,
232 unsigned int vcc,
233 void *priv_data)
234{
235 struct pcmcia_config_check *stk = priv_data;
236
237 /* Check for matching Vcc, unless we're desperate */
238 if (!stk->skip_vcc) {
239 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
240 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
241 return -ENODEV;
242 } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
243 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
244 return -ENODEV;
245 }
246 }
247
248 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
249 pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
250 else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
251 pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
252
253 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
254 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
255 pdev->conf.ConfigIndex = cfg->index;
256 pdev->io.BasePort1 = io->win[0].base;
257 pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
258 if (!(io->flags & CISTPL_IO_16BIT))
259 pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
260 if (io->nwin == 2) {
261 pdev->io.NumPorts1 = 8;
262 pdev->io.BasePort2 = io->win[1].base;
263 pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
264 if (pcmcia_request_io(pdev, &pdev->io) != 0)
265 return -ENODEV;
266 stk->ctl_base = pdev->io.BasePort2;
267 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
268 pdev->io.NumPorts1 = io->win[0].len;
269 pdev->io.NumPorts2 = 0;
270 if (pcmcia_request_io(pdev, &pdev->io) != 0)
271 return -ENODEV;
272 stk->ctl_base = pdev->io.BasePort1 + 0x0e;
273 } else
274 return -ENODEV;
275 /* If we've got this far, we're done */
276 return 0;
277 }
278 return -ENODEV;
279}
280
223static int ide_config(struct pcmcia_device *link) 281static int ide_config(struct pcmcia_device *link)
224{ 282{
225 ide_info_t *info = link->priv; 283 ide_info_t *info = link->priv;
226 tuple_t tuple; 284 struct pcmcia_config_check *stk = NULL;
227 struct { 285 int last_ret = 0, last_fn = 0, is_kme = 0;
228 u_short buf[128];
229 cisparse_t parse;
230 config_info_t conf;
231 cistpl_cftable_entry_t dflt;
232 } *stk = NULL;
233 cistpl_cftable_entry_t *cfg;
234 int pass, last_ret = 0, last_fn = 0, is_kme = 0;
235 unsigned long io_base, ctl_base; 286 unsigned long io_base, ctl_base;
236 struct ide_host *host; 287 struct ide_host *host;
237 288
238 DEBUG(0, "ide_config(0x%p)\n", link); 289 DEBUG(0, "ide_config(0x%p)\n", link);
239 290
240 stk = kzalloc(sizeof(*stk), GFP_KERNEL);
241 if (!stk) goto err_mem;
242 cfg = &stk->parse.cftable_entry;
243
244 tuple.TupleData = (cisdata_t *)&stk->buf;
245 tuple.TupleOffset = 0;
246 tuple.TupleDataMax = 255;
247 tuple.Attributes = 0;
248
249 is_kme = ((link->manf_id == MANFID_KME) && 291 is_kme = ((link->manf_id == MANFID_KME) &&
250 ((link->card_id == PRODID_KME_KXLC005_A) || 292 ((link->card_id == PRODID_KME_KXLC005_A) ||
251 (link->card_id == PRODID_KME_KXLC005_B))); 293 (link->card_id == PRODID_KME_KXLC005_B)));
252 294
253 /* Not sure if this is right... look up the current Vcc */ 295 stk = kzalloc(sizeof(*stk), GFP_KERNEL);
254 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); 296 if (!stk)
255 297 goto err_mem;
256 pass = io_base = ctl_base = 0; 298 stk->is_kme = is_kme;
257 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 299 stk->skip_vcc = io_base = ctl_base = 0;
258 tuple.Attributes = 0; 300
259 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 301 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) {
260 while (1) { 302 stk->skip_vcc = 1;
261 if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry; 303 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk))
262 if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry; 304 goto failed; /* No suitable config found */
263
264 /* Check for matching Vcc, unless we're desperate */
265 if (!pass) {
266 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
267 if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
268 goto next_entry;
269 } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
270 if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
271 goto next_entry;
272 }
273 }
274
275 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
276 link->conf.Vpp =
277 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
278 else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
279 link->conf.Vpp =
280 stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
281
282 if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
283 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
284 link->conf.ConfigIndex = cfg->index;
285 link->io.BasePort1 = io->win[0].base;
286 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
287 if (!(io->flags & CISTPL_IO_16BIT))
288 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
289 if (io->nwin == 2) {
290 link->io.NumPorts1 = 8;
291 link->io.BasePort2 = io->win[1].base;
292 link->io.NumPorts2 = (is_kme) ? 2 : 1;
293 if (pcmcia_request_io(link, &link->io) != 0)
294 goto next_entry;
295 io_base = link->io.BasePort1;
296 ctl_base = link->io.BasePort2;
297 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
298 link->io.NumPorts1 = io->win[0].len;
299 link->io.NumPorts2 = 0;
300 if (pcmcia_request_io(link, &link->io) != 0)
301 goto next_entry;
302 io_base = link->io.BasePort1;
303 ctl_base = link->io.BasePort1 + 0x0e;
304 } else goto next_entry;
305 /* If we've got this far, we're done */
306 break;
307 }
308
309 next_entry:
310 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
311 memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
312 if (pass) {
313 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
314 } else if (pcmcia_get_next_tuple(link, &tuple) != 0) {
315 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
316 memset(&stk->dflt, 0, sizeof(stk->dflt));
317 pass++;
318 }
319 } 305 }
306 io_base = link->io.BasePort1;
307 ctl_base = stk->ctl_base;
320 308
321 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 309 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
322 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 310 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
@@ -404,8 +392,10 @@ static struct pcmcia_device_id ide_ids[] = {
404 PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */ 392 PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */
405 PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */ 393 PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */
406 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), 394 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
395 PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904),
407 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ 396 PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */
408 PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */ 397 PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */
398 PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */
409 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ 399 PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
410 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), 400 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
411 PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ 401 PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index a5b941c327f..38804653970 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -154,78 +154,45 @@ static void avmcs_detach(struct pcmcia_device *link)
154 154
155======================================================================*/ 155======================================================================*/
156 156
157static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, 157static int avmcs_configcheck(struct pcmcia_device *p_dev,
158 cisparse_t *parse) 158 cistpl_cftable_entry_t *cf,
159 cistpl_cftable_entry_t *dflt,
160 unsigned int vcc,
161 void *priv_data)
159{ 162{
160 int i = pcmcia_get_tuple_data(handle, tuple); 163 if (cf->io.nwin <= 0)
161 if (i != CS_SUCCESS) return i; 164 return -ENODEV;
162 return pcmcia_parse_tuple(handle, tuple, parse); 165
163} 166 p_dev->io.BasePort1 = cf->io.win[0].base;
164 167 p_dev->io.NumPorts1 = cf->io.win[0].len;
165static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, 168 p_dev->io.NumPorts2 = 0;
166 cisparse_t *parse) 169 printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
167{ 170 p_dev->io.BasePort1,
168 int i = pcmcia_get_first_tuple(handle, tuple); 171 p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
169 if (i != CS_SUCCESS) return i; 172 return pcmcia_request_io(p_dev, &p_dev->io);
170 return get_tuple(handle, tuple, parse);
171}
172
173static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
174 cisparse_t *parse)
175{
176 int i = pcmcia_get_next_tuple(handle, tuple);
177 if (i != CS_SUCCESS) return i;
178 return get_tuple(handle, tuple, parse);
179} 173}
180 174
181static int avmcs_config(struct pcmcia_device *link) 175static int avmcs_config(struct pcmcia_device *link)
182{ 176{
183 tuple_t tuple;
184 cisparse_t parse;
185 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
186 local_info_t *dev; 177 local_info_t *dev;
187 int i; 178 int i;
188 u_char buf[64];
189 char devname[128]; 179 char devname[128];
190 int cardtype; 180 int cardtype;
191 int (*addcard)(unsigned int port, unsigned irq); 181 int (*addcard)(unsigned int port, unsigned irq);
192 182
193 dev = link->priv; 183 dev = link->priv;
194 184
195 do { 185 devname[0] = 0;
196 devname[0] = 0; 186 if (link->prod_id[1])
197 if (link->prod_id[1]) 187 strlcpy(devname, link->prod_id[1], sizeof(devname));
198 strlcpy(devname, link->prod_id[1], sizeof(devname));
199
200 /*
201 * find IO port
202 */
203 tuple.TupleData = (cisdata_t *)buf;
204 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
205 tuple.Attributes = 0;
206 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
207 i = first_tuple(link, &tuple, &parse);
208 while (i == CS_SUCCESS) {
209 if (cf->io.nwin > 0) {
210 link->conf.ConfigIndex = cf->index;
211 link->io.BasePort1 = cf->io.win[0].base;
212 link->io.NumPorts1 = cf->io.win[0].len;
213 link->io.NumPorts2 = 0;
214 printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
215 link->io.BasePort1,
216 link->io.BasePort1+link->io.NumPorts1-1);
217 i = pcmcia_request_io(link, &link->io);
218 if (i == CS_SUCCESS) goto found_port;
219 }
220 i = next_tuple(link, &tuple, &parse);
221 }
222 188
223found_port: 189 /*
224 if (i != CS_SUCCESS) { 190 * find IO port
225 cs_error(link, RequestIO, i); 191 */
226 break; 192 if (pcmcia_loop_config(link, avmcs_configcheck, NULL))
227 } 193 return -ENODEV;
228 194
195 do {
229 /* 196 /*
230 * allocate an interrupt line 197 * allocate an interrupt line
231 */ 198 */
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index fc6cc2c065b..8fd3ca0fb93 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -174,38 +174,29 @@ static void avma1cs_detach(struct pcmcia_device *link)
174 174
175======================================================================*/ 175======================================================================*/
176 176
177static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, 177static int avma1cs_configcheck(struct pcmcia_device *p_dev,
178 cisparse_t *parse) 178 cistpl_cftable_entry_t *cf,
179 cistpl_cftable_entry_t *dflt,
180 unsigned int vcc,
181 void *priv_data)
179{ 182{
180 int i = pcmcia_get_tuple_data(handle, tuple); 183 if (cf->io.nwin <= 0)
181 if (i != CS_SUCCESS) return i; 184 return -ENODEV;
182 return pcmcia_parse_tuple(handle, tuple, parse); 185
186 p_dev->io.BasePort1 = cf->io.win[0].base;
187 p_dev->io.NumPorts1 = cf->io.win[0].len;
188 p_dev->io.NumPorts2 = 0;
189 printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
190 p_dev->io.BasePort1,
191 p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
192 return pcmcia_request_io(p_dev, &p_dev->io);
183} 193}
184 194
185static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
186 cisparse_t *parse)
187{
188 int i = pcmcia_get_first_tuple(handle, tuple);
189 if (i != CS_SUCCESS) return i;
190 return get_tuple(handle, tuple, parse);
191}
192
193static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
194 cisparse_t *parse)
195{
196 int i = pcmcia_get_next_tuple(handle, tuple);
197 if (i != CS_SUCCESS) return i;
198 return get_tuple(handle, tuple, parse);
199}
200 195
201static int avma1cs_config(struct pcmcia_device *link) 196static int avma1cs_config(struct pcmcia_device *link)
202{ 197{
203 tuple_t tuple;
204 cisparse_t parse;
205 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
206 local_info_t *dev; 198 local_info_t *dev;
207 int i; 199 int i;
208 u_char buf[64];
209 char devname[128]; 200 char devname[128];
210 IsdnCard_t icard; 201 IsdnCard_t icard;
211 int busy = 0; 202 int busy = 0;
@@ -214,40 +205,14 @@ static int avma1cs_config(struct pcmcia_device *link)
214 205
215 DEBUG(0, "avma1cs_config(0x%p)\n", link); 206 DEBUG(0, "avma1cs_config(0x%p)\n", link);
216 207
217 do { 208 devname[0] = 0;
218 devname[0] = 0; 209 if (link->prod_id[1])
219 if (link->prod_id[1]) 210 strlcpy(devname, link->prod_id[1], sizeof(devname));
220 strlcpy(devname, link->prod_id[1], sizeof(devname));
221 211
222 /* 212 if (pcmcia_loop_config(link, avma1cs_configcheck, NULL))
223 * find IO port 213 return -ENODEV;
224 */
225 tuple.TupleData = (cisdata_t *)buf;
226 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
227 tuple.Attributes = 0;
228 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
229 i = first_tuple(link, &tuple, &parse);
230 while (i == CS_SUCCESS) {
231 if (cf->io.nwin > 0) {
232 link->conf.ConfigIndex = cf->index;
233 link->io.BasePort1 = cf->io.win[0].base;
234 link->io.NumPorts1 = cf->io.win[0].len;
235 link->io.NumPorts2 = 0;
236 printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
237 link->io.BasePort1,
238 link->io.BasePort1+link->io.NumPorts1 - 1);
239 i = pcmcia_request_io(link, &link->io);
240 if (i == CS_SUCCESS) goto found_port;
241 }
242 i = next_tuple(link, &tuple, &parse);
243 }
244 214
245found_port: 215 do {
246 if (i != CS_SUCCESS) {
247 cs_error(link, RequestIO, i);
248 break;
249 }
250
251 /* 216 /*
252 * allocate an interrupt line 217 * allocate an interrupt line
253 */ 218 */
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index db7e64424af..2bf0016dea5 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -203,68 +203,41 @@ static void elsa_cs_detach(struct pcmcia_device *link)
203 device available to the system. 203 device available to the system.
204 204
205======================================================================*/ 205======================================================================*/
206static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
207 cisparse_t *parse)
208{
209 int i = pcmcia_get_tuple_data(handle, tuple);
210 if (i != CS_SUCCESS) return i;
211 return pcmcia_parse_tuple(handle, tuple, parse);
212}
213
214static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
215 cisparse_t *parse)
216{
217 int i = pcmcia_get_first_tuple(handle, tuple);
218 if (i != CS_SUCCESS) return i;
219 return get_tuple(handle, tuple, parse);
220}
221 206
222static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, 207static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
223 cisparse_t *parse) 208 cistpl_cftable_entry_t *cf,
209 cistpl_cftable_entry_t *dflt,
210 unsigned int vcc,
211 void *priv_data)
224{ 212{
225 int i = pcmcia_get_next_tuple(handle, tuple); 213 int j;
226 if (i != CS_SUCCESS) return i; 214
227 return get_tuple(handle, tuple, parse); 215 if ((cf->io.nwin > 0) && cf->io.win[0].base) {
216 printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
217 p_dev->io.BasePort1 = cf->io.win[0].base;
218 if (!pcmcia_request_io(p_dev, &p_dev->io))
219 return 0;
220 } else {
221 printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
222 for (j = 0x2f0; j > 0x100; j -= 0x10) {
223 p_dev->io.BasePort1 = j;
224 if (!pcmcia_request_io(p_dev, &p_dev->io))
225 return 0;
226 }
227 }
228 return -ENODEV;
228} 229}
229 230
230static int elsa_cs_config(struct pcmcia_device *link) 231static int elsa_cs_config(struct pcmcia_device *link)
231{ 232{
232 tuple_t tuple;
233 cisparse_t parse;
234 local_info_t *dev; 233 local_info_t *dev;
235 int i, j, last_fn; 234 int i, last_fn;
236 u_short buf[128];
237 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
238 IsdnCard_t icard; 235 IsdnCard_t icard;
239 236
240 DEBUG(0, "elsa_config(0x%p)\n", link); 237 DEBUG(0, "elsa_config(0x%p)\n", link);
241 dev = link->priv; 238 dev = link->priv;
242 239
243 tuple.TupleData = (cisdata_t *)buf; 240 i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
244 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
245 tuple.Attributes = 0;
246 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
247 i = first_tuple(link, &tuple, &parse);
248 while (i == CS_SUCCESS) {
249 if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
250 printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
251 link->conf.ConfigIndex = cf->index;
252 link->io.BasePort1 = cf->io.win[0].base;
253 i = pcmcia_request_io(link, &link->io);
254 if (i == CS_SUCCESS) break;
255 } else {
256 printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
257 link->conf.ConfigIndex = cf->index;
258 for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
259 link->io.BasePort1 = j;
260 i = pcmcia_request_io(link, &link->io);
261 if (i == CS_SUCCESS) break;
262 }
263 break;
264 }
265 i = next_tuple(link, &tuple, &parse);
266 }
267
268 if (i != CS_SUCCESS) { 241 if (i != CS_SUCCESS) {
269 last_fn = RequestIO; 242 last_fn = RequestIO;
270 goto cs_failed; 243 goto cs_failed;
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 439cb530def..9a3c9f5e4fe 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -217,101 +217,61 @@ static void sedlbauer_detach(struct pcmcia_device *link)
217#define CS_CHECK(fn, ret) \ 217#define CS_CHECK(fn, ret) \
218do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 218do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
219 219
220static int sedlbauer_config(struct pcmcia_device *link) 220static int sedlbauer_config_check(struct pcmcia_device *p_dev,
221 cistpl_cftable_entry_t *cfg,
222 cistpl_cftable_entry_t *dflt,
223 unsigned int vcc,
224 void *priv_data)
221{ 225{
222 local_info_t *dev = link->priv; 226 win_req_t *req = priv_data;
223 tuple_t tuple;
224 cisparse_t parse;
225 int last_fn, last_ret;
226 u8 buf[64];
227 config_info_t conf;
228 win_req_t req;
229 memreq_t map;
230 IsdnCard_t icard;
231
232 DEBUG(0, "sedlbauer_config(0x%p)\n", link);
233
234 tuple.Attributes = 0;
235 tuple.TupleData = buf;
236 tuple.TupleDataMax = sizeof(buf);
237 tuple.TupleOffset = 0;
238 227
239 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); 228 if (cfg->index == 0)
229 return -ENODEV;
240 230
241 /*
242 In this loop, we scan the CIS for configuration table entries,
243 each of which describes a valid card configuration, including
244 voltage, IO window, memory window, and interrupt settings.
245
246 We make no assumptions about the card to be configured: we use
247 just the information available in the CIS. In an ideal world,
248 this would work for any PCMCIA card, but it requires a complete
249 and accurate CIS. In practice, a driver usually "knows" most of
250 these things without consulting the CIS, and most client drivers
251 will only use the CIS to fill in implementation-defined details.
252 */
253 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
254 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
255 while (1) {
256 cistpl_cftable_entry_t dflt = { 0 };
257 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
258 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
259 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
260 goto next_entry;
261
262 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
263 if (cfg->index == 0) goto next_entry;
264 link->conf.ConfigIndex = cfg->index;
265
266 /* Does this card need audio output? */ 231 /* Does this card need audio output? */
267 if (cfg->flags & CISTPL_CFTABLE_AUDIO) { 232 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
268 link->conf.Attributes |= CONF_ENABLE_SPKR; 233 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
269 link->conf.Status = CCSR_AUDIO_ENA; 234 p_dev->conf.Status = CCSR_AUDIO_ENA;
270 } 235 }
271 236
272 /* Use power settings for Vcc and Vpp if present */ 237 /* Use power settings for Vcc and Vpp if present */
273 /* Note that the CIS values need to be rescaled */ 238 /* Note that the CIS values need to be rescaled */
274 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { 239 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
275 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) 240 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
276 goto next_entry; 241 return -ENODEV;
277 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { 242 } else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
278 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) 243 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000)
279 goto next_entry; 244 return -ENODEV;
280 } 245 }
281 246
282 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) 247 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
283 link->conf.Vpp = 248 p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
284 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; 249 else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
285 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) 250 p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
286 link->conf.Vpp = 251
287 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
288
289 /* Do we need to allocate an interrupt? */ 252 /* Do we need to allocate an interrupt? */
290 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) 253 if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
291 link->conf.Attributes |= CONF_ENABLE_IRQ; 254 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
292 255
293 /* IO window settings */ 256 /* IO window settings */
294 link->io.NumPorts1 = link->io.NumPorts2 = 0; 257 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
295 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 258 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
296 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; 259 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
297 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 260 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
298 if (!(io->flags & CISTPL_IO_8BIT)) 261 if (!(io->flags & CISTPL_IO_8BIT))
299 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; 262 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
300 if (!(io->flags & CISTPL_IO_16BIT)) 263 if (!(io->flags & CISTPL_IO_16BIT))
301 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 264 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
302/* new in dummy.cs 2001/01/28 MN 265 p_dev->io.BasePort1 = io->win[0].base;
303 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; 266 p_dev->io.NumPorts1 = io->win[0].len;
304*/ 267 if (io->nwin > 1) {
305 link->io.BasePort1 = io->win[0].base; 268 p_dev->io.Attributes2 = p_dev->io.Attributes1;
306 link->io.NumPorts1 = io->win[0].len; 269 p_dev->io.BasePort2 = io->win[1].base;
307 if (io->nwin > 1) { 270 p_dev->io.NumPorts2 = io->win[1].len;
308 link->io.Attributes2 = link->io.Attributes1; 271 }
309 link->io.BasePort2 = io->win[1].base; 272 /* This reserves IO space but doesn't actually enable it */
310 link->io.NumPorts2 = io->win[1].len; 273 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
311 } 274 return -ENODEV;
312 /* This reserves IO space but doesn't actually enable it */
313 if (pcmcia_request_io(link, &link->io) != 0)
314 goto next_entry;
315 } 275 }
316 276
317 /* 277 /*
@@ -325,30 +285,54 @@ static int sedlbauer_config(struct pcmcia_device *link)
325 needs to be mapped to virtual space with ioremap() before it 285 needs to be mapped to virtual space with ioremap() before it
326 is used. 286 is used.
327 */ 287 */
328 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { 288 if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
329 cistpl_mem_t *mem = 289 cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
330 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; 290 memreq_t map;
331 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; 291 req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
332 req.Attributes |= WIN_ENABLE; 292 req->Attributes |= WIN_ENABLE;
333 req.Base = mem->win[0].host_addr; 293 req->Base = mem->win[0].host_addr;
334 req.Size = mem->win[0].len; 294 req->Size = mem->win[0].len;
335/* new in dummy.cs 2001/01/28 MN 295 req->AccessSpeed = 0;
336 if (req.Size < 0x1000) 296 if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
337 req.Size = 0x1000; 297 return -ENODEV;
338*/ 298 map.Page = 0;
339 req.AccessSpeed = 0; 299 map.CardOffset = mem->win[0].card_addr;
340 if (pcmcia_request_window(&link, &req, &link->win) != 0) 300 if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
341 goto next_entry; 301 return -ENODEV;
342 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
343 if (pcmcia_map_mem_page(link->win, &map) != 0)
344 goto next_entry;
345 } 302 }
346 /* If we got this far, we're cool! */ 303 return 0;
347 break; 304}
348 305
349 next_entry: 306
350 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); 307
351 } 308static int sedlbauer_config(struct pcmcia_device *link)
309{
310 local_info_t *dev = link->priv;
311 win_req_t *req;
312 int last_fn, last_ret;
313 IsdnCard_t icard;
314
315 DEBUG(0, "sedlbauer_config(0x%p)\n", link);
316
317 req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
318 if (!req)
319 return -ENOMEM;
320
321 /*
322 In this loop, we scan the CIS for configuration table entries,
323 each of which describes a valid card configuration, including
324 voltage, IO window, memory window, and interrupt settings.
325
326 We make no assumptions about the card to be configured: we use
327 just the information available in the CIS. In an ideal world,
328 this would work for any PCMCIA card, but it requires a complete
329 and accurate CIS. In practice, a driver usually "knows" most of
330 these things without consulting the CIS, and most client drivers
331 will only use the CIS to fill in implementation-defined details.
332 */
333 last_ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
334 if (last_ret)
335 goto failed;
352 336
353 /* 337 /*
354 Allocate an interrupt line. Note that this does not assign a 338 Allocate an interrupt line. Note that this does not assign a
@@ -387,8 +371,8 @@ static int sedlbauer_config(struct pcmcia_device *link)
387 printk(" & 0x%04x-0x%04x", link->io.BasePort2, 371 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
388 link->io.BasePort2+link->io.NumPorts2-1); 372 link->io.BasePort2+link->io.NumPorts2-1);
389 if (link->win) 373 if (link->win)
390 printk(", mem 0x%06lx-0x%06lx", req.Base, 374 printk(", mem 0x%06lx-0x%06lx", req->Base,
391 req.Base+req.Size-1); 375 req->Base+req->Size-1);
392 printk("\n"); 376 printk("\n");
393 377
394 icard.para[0] = link->irq.AssignedIRQ; 378 icard.para[0] = link->irq.AssignedIRQ;
@@ -409,6 +393,7 @@ static int sedlbauer_config(struct pcmcia_device *link)
409 393
410cs_failed: 394cs_failed:
411 cs_error(link, last_fn, last_ret); 395 cs_error(link, last_fn, last_ret);
396failed:
412 sedlbauer_release(link); 397 sedlbauer_release(link);
413 return -ENODEV; 398 return -ENODEV;
414 399
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index ab4bd455450..21cabd0aadb 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -193,68 +193,41 @@ static void teles_detach(struct pcmcia_device *link)
193 device available to the system. 193 device available to the system.
194 194
195======================================================================*/ 195======================================================================*/
196static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
197 cisparse_t *parse)
198{
199 int i = pcmcia_get_tuple_data(handle, tuple);
200 if (i != CS_SUCCESS) return i;
201 return pcmcia_parse_tuple(handle, tuple, parse);
202}
203
204static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
205 cisparse_t *parse)
206{
207 int i = pcmcia_get_first_tuple(handle, tuple);
208 if (i != CS_SUCCESS) return i;
209 return get_tuple(handle, tuple, parse);
210}
211 196
212static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, 197static int teles_cs_configcheck(struct pcmcia_device *p_dev,
213 cisparse_t *parse) 198 cistpl_cftable_entry_t *cf,
199 cistpl_cftable_entry_t *dflt,
200 unsigned int vcc,
201 void *priv_data)
214{ 202{
215 int i = pcmcia_get_next_tuple(handle, tuple); 203 int j;
216 if (i != CS_SUCCESS) return i; 204
217 return get_tuple(handle, tuple, parse); 205 if ((cf->io.nwin > 0) && cf->io.win[0].base) {
206 printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
207 p_dev->io.BasePort1 = cf->io.win[0].base;
208 if (!pcmcia_request_io(p_dev, &p_dev->io))
209 return 0;
210 } else {
211 printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
212 for (j = 0x2f0; j > 0x100; j -= 0x10) {
213 p_dev->io.BasePort1 = j;
214 if (!pcmcia_request_io(p_dev, &p_dev->io))
215 return 0;
216 }
217 }
218 return -ENODEV;
218} 219}
219 220
220static int teles_cs_config(struct pcmcia_device *link) 221static int teles_cs_config(struct pcmcia_device *link)
221{ 222{
222 tuple_t tuple;
223 cisparse_t parse;
224 local_info_t *dev; 223 local_info_t *dev;
225 int i, j, last_fn; 224 int i, last_fn;
226 u_short buf[128];
227 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
228 IsdnCard_t icard; 225 IsdnCard_t icard;
229 226
230 DEBUG(0, "teles_config(0x%p)\n", link); 227 DEBUG(0, "teles_config(0x%p)\n", link);
231 dev = link->priv; 228 dev = link->priv;
232 229
233 tuple.TupleData = (cisdata_t *)buf; 230 i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
234 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
235 tuple.Attributes = 0;
236 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
237 i = first_tuple(link, &tuple, &parse);
238 while (i == CS_SUCCESS) {
239 if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
240 printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
241 link->conf.ConfigIndex = cf->index;
242 link->io.BasePort1 = cf->io.win[0].base;
243 i = pcmcia_request_io(link, &link->io);
244 if (i == CS_SUCCESS) break;
245 } else {
246 printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
247 link->conf.ConfigIndex = cf->index;
248 for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
249 link->io.BasePort1 = j;
250 i = pcmcia_request_io(link, &link->io);
251 if (i == CS_SUCCESS) break;
252 }
253 break;
254 }
255 i = next_tuple(link, &tuple, &parse);
256 }
257
258 if (i != CS_SUCCESS) { 231 if (i != CS_SUCCESS) {
259 last_fn = RequestIO; 232 last_fn = RequestIO;
260 goto cs_failed; 233 goto cs_failed;
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 3f682d49a4e..061d889794c 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -284,58 +284,49 @@ static int try_io_port(struct pcmcia_device *link)
284 } 284 }
285} 285}
286 286
287static int axnet_configcheck(struct pcmcia_device *p_dev,
288 cistpl_cftable_entry_t *cfg,
289 cistpl_cftable_entry_t *dflt,
290 unsigned int vcc,
291 void *priv_data)
292{
293 int i;
294 cistpl_io_t *io = &cfg->io;
295
296 if (cfg->index == 0 || cfg->io.nwin == 0)
297 return -ENODEV;
298
299 p_dev->conf.ConfigIndex = 0x05;
300 /* For multifunction cards, by convention, we configure the
301 network function with window 0, and serial with window 1 */
302 if (io->nwin > 1) {
303 i = (io->win[1].len > io->win[0].len);
304 p_dev->io.BasePort2 = io->win[1-i].base;
305 p_dev->io.NumPorts2 = io->win[1-i].len;
306 } else {
307 i = p_dev->io.NumPorts2 = 0;
308 }
309 p_dev->io.BasePort1 = io->win[i].base;
310 p_dev->io.NumPorts1 = io->win[i].len;
311 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
312 if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
313 return try_io_port(p_dev);
314
315 return -ENODEV;
316}
317
287static int axnet_config(struct pcmcia_device *link) 318static int axnet_config(struct pcmcia_device *link)
288{ 319{
289 struct net_device *dev = link->priv; 320 struct net_device *dev = link->priv;
290 axnet_dev_t *info = PRIV(dev); 321 axnet_dev_t *info = PRIV(dev);
291 tuple_t tuple;
292 cisparse_t parse;
293 int i, j, last_ret, last_fn; 322 int i, j, last_ret, last_fn;
294 u_short buf[64];
295 DECLARE_MAC_BUF(mac); 323 DECLARE_MAC_BUF(mac);
296 324
297 DEBUG(0, "axnet_config(0x%p)\n", link); 325 DEBUG(0, "axnet_config(0x%p)\n", link);
298 326
299 tuple.Attributes = 0;
300 tuple.TupleData = (cisdata_t *)buf;
301 tuple.TupleDataMax = sizeof(buf);
302 tuple.TupleOffset = 0;
303
304 /* don't trust the CIS on this; Linksys got it wrong */ 327 /* don't trust the CIS on this; Linksys got it wrong */
305 link->conf.Present = 0x63; 328 link->conf.Present = 0x63;
306 329 last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
307 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
308 tuple.Attributes = 0;
309 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
310 while (last_ret == CS_SUCCESS) {
311 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
312 cistpl_io_t *io = &(parse.cftable_entry.io);
313
314 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
315 pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
316 cfg->index == 0 || cfg->io.nwin == 0)
317 goto next_entry;
318
319 link->conf.ConfigIndex = 0x05;
320 /* For multifunction cards, by convention, we configure the
321 network function with window 0, and serial with window 1 */
322 if (io->nwin > 1) {
323 i = (io->win[1].len > io->win[0].len);
324 link->io.BasePort2 = io->win[1-i].base;
325 link->io.NumPorts2 = io->win[1-i].len;
326 } else {
327 i = link->io.NumPorts2 = 0;
328 }
329 link->io.BasePort1 = io->win[i].base;
330 link->io.NumPorts1 = io->win[i].len;
331 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
332 if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
333 last_ret = try_io_port(link);
334 if (last_ret == CS_SUCCESS) break;
335 }
336 next_entry:
337 last_ret = pcmcia_get_next_tuple(link, &tuple);
338 }
339 if (last_ret != CS_SUCCESS) { 330 if (last_ret != CS_SUCCESS) {
340 cs_error(link, RequestIO, last_ret); 331 cs_error(link, RequestIO, last_ret);
341 goto failed; 332 goto failed;
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 2d4c4ad89b8..aa17434faa0 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -512,58 +512,53 @@ static int try_io_port(struct pcmcia_device *link)
512 } 512 }
513} 513}
514 514
515static int pcnet_confcheck(struct pcmcia_device *p_dev,
516 cistpl_cftable_entry_t *cfg,
517 cistpl_cftable_entry_t *dflt,
518 unsigned int vcc,
519 void *priv_data)
520{
521 int *has_shmem = priv_data;
522 int i;
523 cistpl_io_t *io = &cfg->io;
524
525 if (cfg->index == 0 || cfg->io.nwin == 0)
526 return -EINVAL;
527
528 /* For multifunction cards, by convention, we configure the
529 network function with window 0, and serial with window 1 */
530 if (io->nwin > 1) {
531 i = (io->win[1].len > io->win[0].len);
532 p_dev->io.BasePort2 = io->win[1-i].base;
533 p_dev->io.NumPorts2 = io->win[1-i].len;
534 } else {
535 i = p_dev->io.NumPorts2 = 0;
536 }
537
538 *has_shmem = ((cfg->mem.nwin == 1) &&
539 (cfg->mem.win[0].len >= 0x4000));
540 p_dev->io.BasePort1 = io->win[i].base;
541 p_dev->io.NumPorts1 = io->win[i].len;
542 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
543 if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
544 return try_io_port(p_dev);
545
546 return 0;
547}
548
515static int pcnet_config(struct pcmcia_device *link) 549static int pcnet_config(struct pcmcia_device *link)
516{ 550{
517 struct net_device *dev = link->priv; 551 struct net_device *dev = link->priv;
518 pcnet_dev_t *info = PRIV(dev); 552 pcnet_dev_t *info = PRIV(dev);
519 tuple_t tuple; 553 int last_ret, last_fn, start_pg, stop_pg, cm_offset;
520 cisparse_t parse;
521 int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
522 int has_shmem = 0; 554 int has_shmem = 0;
523 u_short buf[64];
524 hw_info_t *local_hw_info; 555 hw_info_t *local_hw_info;
525 DECLARE_MAC_BUF(mac); 556 DECLARE_MAC_BUF(mac);
526 557
527 DEBUG(0, "pcnet_config(0x%p)\n", link); 558 DEBUG(0, "pcnet_config(0x%p)\n", link);
528 559
529 tuple.TupleData = (cisdata_t *)buf; 560 last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
530 tuple.TupleDataMax = sizeof(buf); 561 if (last_ret) {
531 tuple.TupleOffset = 0;
532 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
533 tuple.Attributes = 0;
534 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
535 while (last_ret == CS_SUCCESS) {
536 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
537 cistpl_io_t *io = &(parse.cftable_entry.io);
538
539 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
540 pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
541 cfg->index == 0 || cfg->io.nwin == 0)
542 goto next_entry;
543
544 link->conf.ConfigIndex = cfg->index;
545 /* For multifunction cards, by convention, we configure the
546 network function with window 0, and serial with window 1 */
547 if (io->nwin > 1) {
548 i = (io->win[1].len > io->win[0].len);
549 link->io.BasePort2 = io->win[1-i].base;
550 link->io.NumPorts2 = io->win[1-i].len;
551 } else {
552 i = link->io.NumPorts2 = 0;
553 }
554 has_shmem = ((cfg->mem.nwin == 1) &&
555 (cfg->mem.win[0].len >= 0x4000));
556 link->io.BasePort1 = io->win[i].base;
557 link->io.NumPorts1 = io->win[i].len;
558 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
559 if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
560 last_ret = try_io_port(link);
561 if (last_ret == CS_SUCCESS) break;
562 }
563 next_entry:
564 last_ret = pcmcia_get_next_tuple(link, &tuple);
565 }
566 if (last_ret != CS_SUCCESS) {
567 cs_error(link, RequestIO, last_ret); 562 cs_error(link, RequestIO, last_ret);
568 goto failed; 563 goto failed;
569 } 564 }
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 250eb1954c3..b3f2085ddca 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -459,28 +459,37 @@ static int mhz_3288_power(struct pcmcia_device *link)
459 return 0; 459 return 0;
460} 460}
461 461
462static int mhz_mfc_config_check(struct pcmcia_device *p_dev,
463 cistpl_cftable_entry_t *cf,
464 cistpl_cftable_entry_t *dflt,
465 unsigned int vcc,
466 void *priv_data)
467{
468 int k;
469 p_dev->io.BasePort2 = cf->io.win[0].base;
470 for (k = 0; k < 0x400; k += 0x10) {
471 if (k & 0x80)
472 continue;
473 p_dev->io.BasePort1 = k ^ 0x300;
474 if (!pcmcia_request_io(p_dev, &p_dev->io))
475 return 0;
476 }
477 return -ENODEV;
478}
479
462static int mhz_mfc_config(struct pcmcia_device *link) 480static int mhz_mfc_config(struct pcmcia_device *link)
463{ 481{
464 struct net_device *dev = link->priv; 482 struct net_device *dev = link->priv;
465 struct smc_private *smc = netdev_priv(dev); 483 struct smc_private *smc = netdev_priv(dev);
466 struct smc_cfg_mem *cfg_mem; 484 struct smc_cfg_mem *cfg_mem;
467 tuple_t *tuple;
468 cisparse_t *parse;
469 cistpl_cftable_entry_t *cf;
470 u_char *buf;
471 win_req_t req; 485 win_req_t req;
472 memreq_t mem; 486 memreq_t mem;
473 int i, k; 487 int i;
474 488
475 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); 489 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
476 if (!cfg_mem) 490 if (!cfg_mem)
477 return CS_OUT_OF_RESOURCE; 491 return CS_OUT_OF_RESOURCE;
478 492
479 tuple = &cfg_mem->tuple;
480 parse = &cfg_mem->parse;
481 cf = &parse->cftable_entry;
482 buf = cfg_mem->buf;
483
484 link->conf.Attributes |= CONF_ENABLE_SPKR; 493 link->conf.Attributes |= CONF_ENABLE_SPKR;
485 link->conf.Status = CCSR_AUDIO_ENA; 494 link->conf.Status = CCSR_AUDIO_ENA;
486 link->irq.Attributes = 495 link->irq.Attributes =
@@ -489,27 +498,9 @@ static int mhz_mfc_config(struct pcmcia_device *link)
489 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; 498 link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
490 link->io.NumPorts2 = 8; 499 link->io.NumPorts2 = 8;
491 500
492 tuple->Attributes = tuple->TupleOffset = 0;
493 tuple->TupleData = (cisdata_t *)buf;
494 tuple->TupleDataMax = 255;
495 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
496
497 i = first_tuple(link, tuple, parse);
498 /* The Megahertz combo cards have modem-like CIS entries, so 501 /* The Megahertz combo cards have modem-like CIS entries, so
499 we have to explicitly try a bunch of port combinations. */ 502 we have to explicitly try a bunch of port combinations. */
500 while (i == CS_SUCCESS) { 503 if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
501 link->conf.ConfigIndex = cf->index;
502 link->io.BasePort2 = cf->io.win[0].base;
503 for (k = 0; k < 0x400; k += 0x10) {
504 if (k & 0x80) continue;
505 link->io.BasePort1 = k ^ 0x300;
506 i = pcmcia_request_io(link, &link->io);
507 if (i == CS_SUCCESS) break;
508 }
509 if (i == CS_SUCCESS) break;
510 i = next_tuple(link, tuple, parse);
511 }
512 if (i != CS_SUCCESS)
513 goto free_cfg_mem; 504 goto free_cfg_mem;
514 dev->base_addr = link->io.BasePort1; 505 dev->base_addr = link->io.BasePort1;
515 506
@@ -533,7 +524,7 @@ static int mhz_mfc_config(struct pcmcia_device *link)
533 524
534free_cfg_mem: 525free_cfg_mem:
535 kfree(cfg_mem); 526 kfree(cfg_mem);
536 return i; 527 return -ENODEV;
537} 528}
538 529
539static int mhz_setup(struct pcmcia_device *link) 530static int mhz_setup(struct pcmcia_device *link)
@@ -660,46 +651,27 @@ static int mot_setup(struct pcmcia_device *link)
660 651
661/*====================================================================*/ 652/*====================================================================*/
662 653
654static int smc_configcheck(struct pcmcia_device *p_dev,
655 cistpl_cftable_entry_t *cf,
656 cistpl_cftable_entry_t *dflt,
657 unsigned int vcc,
658 void *priv_data)
659{
660 p_dev->io.BasePort1 = cf->io.win[0].base;
661 p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
662 return pcmcia_request_io(p_dev, &p_dev->io);
663}
664
663static int smc_config(struct pcmcia_device *link) 665static int smc_config(struct pcmcia_device *link)
664{ 666{
665 struct net_device *dev = link->priv; 667 struct net_device *dev = link->priv;
666 struct smc_cfg_mem *cfg_mem;
667 tuple_t *tuple;
668 cisparse_t *parse;
669 cistpl_cftable_entry_t *cf;
670 u_char *buf;
671 int i; 668 int i;
672 669
673 cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
674 if (!cfg_mem)
675 return CS_OUT_OF_RESOURCE;
676
677 tuple = &cfg_mem->tuple;
678 parse = &cfg_mem->parse;
679 cf = &parse->cftable_entry;
680 buf = cfg_mem->buf;
681
682 tuple->Attributes = tuple->TupleOffset = 0;
683 tuple->TupleData = (cisdata_t *)buf;
684 tuple->TupleDataMax = 255;
685 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
686
687 link->io.NumPorts1 = 16; 670 link->io.NumPorts1 = 16;
688 i = first_tuple(link, tuple, parse); 671 i = pcmcia_loop_config(link, smc_configcheck, NULL);
689 while (i != CS_NO_MORE_ITEMS) { 672 if (!i)
690 if (i == CS_SUCCESS) { 673 dev->base_addr = link->io.BasePort1;
691 link->conf.ConfigIndex = cf->index;
692 link->io.BasePort1 = cf->io.win[0].base;
693 link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
694 i = pcmcia_request_io(link, &link->io);
695 if (i == CS_SUCCESS) break;
696 }
697 i = next_tuple(link, tuple, parse);
698 }
699 if (i == CS_SUCCESS)
700 dev->base_addr = link->io.BasePort1;
701 674
702 kfree(cfg_mem);
703 return i; 675 return i;
704} 676}
705 677
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index f6c4698ce73..d97e6e917c3 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -715,6 +715,47 @@ has_ce2_string(struct pcmcia_device * p_dev)
715 return 0; 715 return 0;
716} 716}
717 717
718static int
719xirc2ps_config_modem(struct pcmcia_device *p_dev,
720 cistpl_cftable_entry_t *cf,
721 cistpl_cftable_entry_t *dflt,
722 unsigned int vcc,
723 void *priv_data)
724{
725 unsigned int ioaddr;
726
727 if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
728 for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
729 p_dev->io.BasePort2 = cf->io.win[0].base;
730 p_dev->io.BasePort1 = ioaddr;
731 if (!pcmcia_request_io(p_dev, &p_dev->io))
732 return 0;
733 }
734 }
735 return -ENODEV;
736}
737
738static int
739xirc2ps_config_check(struct pcmcia_device *p_dev,
740 cistpl_cftable_entry_t *cf,
741 cistpl_cftable_entry_t *dflt,
742 unsigned int vcc,
743 void *priv_data)
744{
745 int *pass = priv_data;
746
747 if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
748 p_dev->io.BasePort2 = cf->io.win[0].base;
749 p_dev->io.BasePort1 = p_dev->io.BasePort2
750 + (*pass ? (cf->index & 0x20 ? -24:8)
751 : (cf->index & 0x20 ? 8:-24));
752 if (!pcmcia_request_io(p_dev, &p_dev->io))
753 return 0;
754 }
755 return -ENODEV;
756
757}
758
718/**************** 759/****************
719 * xirc2ps_config() is scheduled to run after a CARD_INSERTION event 760 * xirc2ps_config() is scheduled to run after a CARD_INSERTION event
720 * is received, to configure the PCMCIA socket, and to make the 761 * is received, to configure the PCMCIA socket, and to make the
@@ -725,13 +766,12 @@ xirc2ps_config(struct pcmcia_device * link)
725{ 766{
726 struct net_device *dev = link->priv; 767 struct net_device *dev = link->priv;
727 local_info_t *local = netdev_priv(dev); 768 local_info_t *local = netdev_priv(dev);
769 unsigned int ioaddr;
728 tuple_t tuple; 770 tuple_t tuple;
729 cisparse_t parse; 771 cisparse_t parse;
730 unsigned int ioaddr;
731 int err, i; 772 int err, i;
732 u_char buf[64]; 773 u_char buf[64];
733 cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data; 774 cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
734 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
735 DECLARE_MAC_BUF(mac); 775 DECLARE_MAC_BUF(mac);
736 776
737 local->dingo_ccr = NULL; 777 local->dingo_ccr = NULL;
@@ -846,19 +886,8 @@ xirc2ps_config(struct pcmcia_device * link)
846 /* Take the Modem IO port from the CIS and scan for a free 886 /* Take the Modem IO port from the CIS and scan for a free
847 * Ethernet port */ 887 * Ethernet port */
848 link->io.NumPorts1 = 16; /* no Mako stuff anymore */ 888 link->io.NumPorts1 = 16; /* no Mako stuff anymore */
849 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 889 if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
850 for (err = first_tuple(link, &tuple, &parse); !err; 890 goto port_found;
851 err = next_tuple(link, &tuple, &parse)) {
852 if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
853 for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
854 link->conf.ConfigIndex = cf->index ;
855 link->io.BasePort2 = cf->io.win[0].base;
856 link->io.BasePort1 = ioaddr;
857 if (!(err=pcmcia_request_io(link, &link->io)))
858 goto port_found;
859 }
860 }
861 }
862 } else { 891 } else {
863 link->io.NumPorts1 = 18; 892 link->io.NumPorts1 = 18;
864 /* We do 2 passes here: The first one uses the regular mapping and 893 /* We do 2 passes here: The first one uses the regular mapping and
@@ -866,21 +895,9 @@ xirc2ps_config(struct pcmcia_device * link)
866 * mirrored every 32 bytes. Actually we use a mirrored port for 895 * mirrored every 32 bytes. Actually we use a mirrored port for
867 * the Mako if (on the first pass) the COR bit 5 is set. 896 * the Mako if (on the first pass) the COR bit 5 is set.
868 */ 897 */
869 for (pass=0; pass < 2; pass++) { 898 for (pass=0; pass < 2; pass++)
870 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 899 if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass))
871 for (err = first_tuple(link, &tuple, &parse); !err;
872 err = next_tuple(link, &tuple, &parse)){
873 if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){
874 link->conf.ConfigIndex = cf->index ;
875 link->io.BasePort2 = cf->io.win[0].base;
876 link->io.BasePort1 = link->io.BasePort2
877 + (pass ? (cf->index & 0x20 ? -24:8)
878 : (cf->index & 0x20 ? 8:-24));
879 if (!(err=pcmcia_request_io(link, &link->io)))
880 goto port_found; 900 goto port_found;
881 }
882 }
883 }
884 /* if special option: 901 /* if special option:
885 * try to configure as Ethernet only. 902 * try to configure as Ethernet only.
886 * .... */ 903 * .... */
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index f12355398fe..fac1526e49a 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -206,126 +206,123 @@ static void airo_detach(struct pcmcia_device *link)
206#define CS_CHECK(fn, ret) \ 206#define CS_CHECK(fn, ret) \
207do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 207do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
208 208
209static int airo_cs_config_check(struct pcmcia_device *p_dev,
210 cistpl_cftable_entry_t *cfg,
211 cistpl_cftable_entry_t *dflt,
212 unsigned int vcc,
213 void *priv_data)
214{
215 win_req_t *req = priv_data;
216
217 if (cfg->index == 0)
218 return -ENODEV;
219
220 /* Does this card need audio output? */
221 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
222 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
223 p_dev->conf.Status = CCSR_AUDIO_ENA;
224 }
225
226 /* Use power settings for Vcc and Vpp if present */
227 /* Note that the CIS values need to be rescaled */
228 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
229 p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
230 else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
231 p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
232
233 /* Do we need to allocate an interrupt? */
234 if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
235 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
236
237 /* IO window settings */
238 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
239 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
240 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
241 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
242 if (!(io->flags & CISTPL_IO_8BIT))
243 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
244 if (!(io->flags & CISTPL_IO_16BIT))
245 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
246 p_dev->io.BasePort1 = io->win[0].base;
247 p_dev->io.NumPorts1 = io->win[0].len;
248 if (io->nwin > 1) {
249 p_dev->io.Attributes2 = p_dev->io.Attributes1;
250 p_dev->io.BasePort2 = io->win[1].base;
251 p_dev->io.NumPorts2 = io->win[1].len;
252 }
253 }
254
255 /* This reserves IO space but doesn't actually enable it */
256 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
257 return -ENODEV;
258
259 /*
260 Now set up a common memory window, if needed. There is room
261 in the struct pcmcia_device structure for one memory window handle,
262 but if the base addresses need to be saved, or if multiple
263 windows are needed, the info should go in the private data
264 structure for this device.
265
266 Note that the memory window base is a physical address, and
267 needs to be mapped to virtual space with ioremap() before it
268 is used.
269 */
270 if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
271 cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
272 memreq_t map;
273 req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
274 req->Base = mem->win[0].host_addr;
275 req->Size = mem->win[0].len;
276 req->AccessSpeed = 0;
277 if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
278 return -ENODEV;
279 map.Page = 0;
280 map.CardOffset = mem->win[0].card_addr;
281 if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
282 return -ENODEV;
283 }
284 /* If we got this far, we're cool! */
285 return 0;
286}
287
288
209static int airo_config(struct pcmcia_device *link) 289static int airo_config(struct pcmcia_device *link)
210{ 290{
211 tuple_t tuple;
212 cisparse_t parse;
213 local_info_t *dev; 291 local_info_t *dev;
292 win_req_t *req;
214 int last_fn, last_ret; 293 int last_fn, last_ret;
215 u_char buf[64];
216 win_req_t req;
217 memreq_t map;
218 294
219 dev = link->priv; 295 dev = link->priv;
220 296
221 DEBUG(0, "airo_config(0x%p)\n", link); 297 DEBUG(0, "airo_config(0x%p)\n", link);
222 298
299 req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
300 if (!req)
301 return -ENOMEM;
302
303 /*
304 * In this loop, we scan the CIS for configuration table
305 * entries, each of which describes a valid card
306 * configuration, including voltage, IO window, memory window,
307 * and interrupt settings.
308 *
309 * We make no assumptions about the card to be configured: we
310 * use just the information available in the CIS. In an ideal
311 * world, this would work for any PCMCIA card, but it requires
312 * a complete and accurate CIS. In practice, a driver usually
313 * "knows" most of these things without consulting the CIS,
314 * and most client drivers will only use the CIS to fill in
315 * implementation-defined details.
316 */
317 last_ret = pcmcia_loop_config(link, airo_cs_config_check, req);
318 if (last_ret)
319 goto failed;
320
223 /* 321 /*
224 In this loop, we scan the CIS for configuration table entries, 322 Allocate an interrupt line. Note that this does not assign a
225 each of which describes a valid card configuration, including 323 handler to the interrupt, unless the 'Handler' member of the
226 voltage, IO window, memory window, and interrupt settings. 324 irq structure is initialized.
227
228 We make no assumptions about the card to be configured: we use
229 just the information available in the CIS. In an ideal world,
230 this would work for any PCMCIA card, but it requires a complete
231 and accurate CIS. In practice, a driver usually "knows" most of
232 these things without consulting the CIS, and most client drivers
233 will only use the CIS to fill in implementation-defined details.
234 */ 325 */
235 tuple.Attributes = 0;
236 tuple.TupleData = buf;
237 tuple.TupleDataMax = sizeof(buf);
238 tuple.TupleOffset = 0;
239 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
240 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
241 while (1) {
242 cistpl_cftable_entry_t dflt = { 0 };
243 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
244 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
245 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
246 goto next_entry;
247
248 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
249 if (cfg->index == 0) goto next_entry;
250 link->conf.ConfigIndex = cfg->index;
251
252 /* Does this card need audio output? */
253 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
254 link->conf.Attributes |= CONF_ENABLE_SPKR;
255 link->conf.Status = CCSR_AUDIO_ENA;
256 }
257
258 /* Use power settings for Vcc and Vpp if present */
259 /* Note that the CIS values need to be rescaled */
260 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
261 link->conf.Vpp =
262 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
263 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
264 link->conf.Vpp =
265 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
266
267 /* Do we need to allocate an interrupt? */
268 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
269 link->conf.Attributes |= CONF_ENABLE_IRQ;
270
271 /* IO window settings */
272 link->io.NumPorts1 = link->io.NumPorts2 = 0;
273 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
274 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
275 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
276 if (!(io->flags & CISTPL_IO_8BIT))
277 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
278 if (!(io->flags & CISTPL_IO_16BIT))
279 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
280 link->io.BasePort1 = io->win[0].base;
281 link->io.NumPorts1 = io->win[0].len;
282 if (io->nwin > 1) {
283 link->io.Attributes2 = link->io.Attributes1;
284 link->io.BasePort2 = io->win[1].base;
285 link->io.NumPorts2 = io->win[1].len;
286 }
287 }
288
289 /* This reserves IO space but doesn't actually enable it */
290 if (pcmcia_request_io(link, &link->io) != 0)
291 goto next_entry;
292
293 /*
294 Now set up a common memory window, if needed. There is room
295 in the struct pcmcia_device structure for one memory window handle,
296 but if the base addresses need to be saved, or if multiple
297 windows are needed, the info should go in the private data
298 structure for this device.
299
300 Note that the memory window base is a physical address, and
301 needs to be mapped to virtual space with ioremap() before it
302 is used.
303 */
304 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
305 cistpl_mem_t *mem =
306 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
307 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
308 req.Base = mem->win[0].host_addr;
309 req.Size = mem->win[0].len;
310 req.AccessSpeed = 0;
311 if (pcmcia_request_window(&link, &req, &link->win) != 0)
312 goto next_entry;
313 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
314 if (pcmcia_map_mem_page(link->win, &map) != 0)
315 goto next_entry;
316 }
317 /* If we got this far, we're cool! */
318 break;
319
320 next_entry:
321 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
322 }
323
324 /*
325 Allocate an interrupt line. Note that this does not assign a
326 handler to the interrupt, unless the 'Handler' member of the
327 irq structure is initialized.
328 */
329 if (link->conf.Attributes & CONF_ENABLE_IRQ) 326 if (link->conf.Attributes & CONF_ENABLE_IRQ)
330 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 327 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
331 328
@@ -362,14 +359,17 @@ static int airo_config(struct pcmcia_device *link)
362 printk(" & 0x%04x-0x%04x", link->io.BasePort2, 359 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
363 link->io.BasePort2+link->io.NumPorts2-1); 360 link->io.BasePort2+link->io.NumPorts2-1);
364 if (link->win) 361 if (link->win)
365 printk(", mem 0x%06lx-0x%06lx", req.Base, 362 printk(", mem 0x%06lx-0x%06lx", req->Base,
366 req.Base+req.Size-1); 363 req->Base+req->Size-1);
367 printk("\n"); 364 printk("\n");
365 kfree(req);
368 return 0; 366 return 0;
369 367
370 cs_failed: 368 cs_failed:
371 cs_error(link, last_fn, last_ret); 369 cs_error(link, last_fn, last_ret);
370 failed:
372 airo_release(link); 371 airo_release(link);
372 kfree(req);
373 return -ENODEV; 373 return -ENODEV;
374} /* airo_config */ 374} /* airo_config */
375 375
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 12617cd0b78..4830d51900a 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -224,13 +224,58 @@ static int card_present(void *arg)
224 return 0; 224 return 0;
225} 225}
226 226
227static int atmel_config_check(struct pcmcia_device *p_dev,
228 cistpl_cftable_entry_t *cfg,
229 cistpl_cftable_entry_t *dflt,
230 unsigned int vcc,
231 void *priv_data)
232{
233 if (cfg->index == 0)
234 return -ENODEV;
235
236 /* Does this card need audio output? */
237 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
238 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
239 p_dev->conf.Status = CCSR_AUDIO_ENA;
240 }
241
242 /* Use power settings for Vcc and Vpp if present */
243 /* Note that the CIS values need to be rescaled */
244 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
245 p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
246 else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
247 p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
248
249 /* Do we need to allocate an interrupt? */
250 if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
251 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
252
253 /* IO window settings */
254 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
255 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
256 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
257 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
258 if (!(io->flags & CISTPL_IO_8BIT))
259 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
260 if (!(io->flags & CISTPL_IO_16BIT))
261 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
262 p_dev->io.BasePort1 = io->win[0].base;
263 p_dev->io.NumPorts1 = io->win[0].len;
264 if (io->nwin > 1) {
265 p_dev->io.Attributes2 = p_dev->io.Attributes1;
266 p_dev->io.BasePort2 = io->win[1].base;
267 p_dev->io.NumPorts2 = io->win[1].len;
268 }
269 }
270
271 /* This reserves IO space but doesn't actually enable it */
272 return pcmcia_request_io(p_dev, &p_dev->io);
273}
274
227static int atmel_config(struct pcmcia_device *link) 275static int atmel_config(struct pcmcia_device *link)
228{ 276{
229 tuple_t tuple;
230 cisparse_t parse;
231 local_info_t *dev; 277 local_info_t *dev;
232 int last_fn, last_ret; 278 int last_fn, last_ret;
233 u_char buf[64];
234 struct pcmcia_device_id *did; 279 struct pcmcia_device_id *did;
235 280
236 dev = link->priv; 281 dev = link->priv;
@@ -238,11 +283,6 @@ static int atmel_config(struct pcmcia_device *link)
238 283
239 DEBUG(0, "atmel_config(0x%p)\n", link); 284 DEBUG(0, "atmel_config(0x%p)\n", link);
240 285
241 tuple.Attributes = 0;
242 tuple.TupleData = buf;
243 tuple.TupleDataMax = sizeof(buf);
244 tuple.TupleOffset = 0;
245
246 /* 286 /*
247 In this loop, we scan the CIS for configuration table entries, 287 In this loop, we scan the CIS for configuration table entries,
248 each of which describes a valid card configuration, including 288 each of which describes a valid card configuration, including
@@ -255,66 +295,8 @@ static int atmel_config(struct pcmcia_device *link)
255 these things without consulting the CIS, and most client drivers 295 these things without consulting the CIS, and most client drivers
256 will only use the CIS to fill in implementation-defined details. 296 will only use the CIS to fill in implementation-defined details.
257 */ 297 */
258 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 298 if (pcmcia_loop_config(link, atmel_config_check, NULL))
259 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 299 goto failed;
260 while (1) {
261 cistpl_cftable_entry_t dflt = { 0 };
262 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
263 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
264 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
265 goto next_entry;
266
267 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
268 if (cfg->index == 0) goto next_entry;
269 link->conf.ConfigIndex = cfg->index;
270
271 /* Does this card need audio output? */
272 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
273 link->conf.Attributes |= CONF_ENABLE_SPKR;
274 link->conf.Status = CCSR_AUDIO_ENA;
275 }
276
277 /* Use power settings for Vcc and Vpp if present */
278 /* Note that the CIS values need to be rescaled */
279 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
280 link->conf.Vpp =
281 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
282 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
283 link->conf.Vpp =
284 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
285
286 /* Do we need to allocate an interrupt? */
287 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
288 link->conf.Attributes |= CONF_ENABLE_IRQ;
289
290 /* IO window settings */
291 link->io.NumPorts1 = link->io.NumPorts2 = 0;
292 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
293 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
294 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
295 if (!(io->flags & CISTPL_IO_8BIT))
296 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
297 if (!(io->flags & CISTPL_IO_16BIT))
298 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
299 link->io.BasePort1 = io->win[0].base;
300 link->io.NumPorts1 = io->win[0].len;
301 if (io->nwin > 1) {
302 link->io.Attributes2 = link->io.Attributes1;
303 link->io.BasePort2 = io->win[1].base;
304 link->io.NumPorts2 = io->win[1].len;
305 }
306 }
307
308 /* This reserves IO space but doesn't actually enable it */
309 if (pcmcia_request_io(link, &link->io) != 0)
310 goto next_entry;
311
312 /* If we got this far, we're cool! */
313 break;
314
315 next_entry:
316 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
317 }
318 300
319 /* 301 /*
320 Allocate an interrupt line. Note that this does not assign a 302 Allocate an interrupt line. Note that this does not assign a
@@ -360,6 +342,7 @@ static int atmel_config(struct pcmcia_device *link)
360 342
361 cs_failed: 343 cs_failed:
362 cs_error(link, last_fn, last_ret); 344 cs_error(link, last_fn, last_ret);
345 failed:
363 atmel_release(link); 346 atmel_release(link);
364 return -ENODEV; 347 return -ENODEV;
365} 348}
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 3b4e55cf33c..c768d42d517 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -532,145 +532,118 @@ static void prism2_detach(struct pcmcia_device *link)
532#define CS_CHECK(fn, ret) \ 532#define CS_CHECK(fn, ret) \
533do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 533do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
534 534
535#define CFG_CHECK2(fn, retf) \
536do { int _ret = (retf); \
537if (_ret != 0) { \
538 PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \
539 cs_error(link, fn, _ret); \
540 goto next_entry; \
541} \
542} while (0)
543
544 535
545/* run after a CARD_INSERTION event is received to configure the PCMCIA 536/* run after a CARD_INSERTION event is received to configure the PCMCIA
546 * socket and make the device available to the system */ 537 * socket and make the device available to the system */
538
539static int prism2_config_check(struct pcmcia_device *p_dev,
540 cistpl_cftable_entry_t *cfg,
541 cistpl_cftable_entry_t *dflt,
542 unsigned int vcc,
543 void *priv_data)
544{
545 if (cfg->index == 0)
546 return -ENODEV;
547
548 PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
549 "(default 0x%02X)\n", cfg->index, dflt->index);
550
551 /* Does this card need audio output? */
552 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
553 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
554 p_dev->conf.Status = CCSR_AUDIO_ENA;
555 }
556
557 /* Use power settings for Vcc and Vpp if present */
558 /* Note that the CIS values need to be rescaled */
559 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
560 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
561 10000 && !ignore_cis_vcc) {
562 PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping"
563 " this entry\n");
564 return -ENODEV;
565 }
566 } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
567 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] /
568 10000 && !ignore_cis_vcc) {
569 PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch "
570 "- skipping this entry\n");
571 return -ENODEV;
572 }
573 }
574
575 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
576 p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
577 else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
578 p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
579
580 /* Do we need to allocate an interrupt? */
581 if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
582 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
583 else if (!(p_dev->conf.Attributes & CONF_ENABLE_IRQ)) {
584 /* At least Compaq WL200 does not have IRQInfo1 set,
585 * but it does not work without interrupts.. */
586 printk(KERN_WARNING "Config has no IRQ info, but trying to "
587 "enable IRQ anyway..\n");
588 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
589 }
590
591 /* IO window settings */
592 PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
593 "dflt->io.nwin=%d\n",
594 cfg->io.nwin, dflt->io.nwin);
595 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
596 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
597 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
598 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
599 PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
600 "io.base=0x%04x, len=%d\n", io->flags,
601 io->win[0].base, io->win[0].len);
602 if (!(io->flags & CISTPL_IO_8BIT))
603 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
604 if (!(io->flags & CISTPL_IO_16BIT))
605 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
606 p_dev->io.IOAddrLines = io->flags &
607 CISTPL_IO_LINES_MASK;
608 p_dev->io.BasePort1 = io->win[0].base;
609 p_dev->io.NumPorts1 = io->win[0].len;
610 if (io->nwin > 1) {
611 p_dev->io.Attributes2 = p_dev->io.Attributes1;
612 p_dev->io.BasePort2 = io->win[1].base;
613 p_dev->io.NumPorts2 = io->win[1].len;
614 }
615 }
616
617 /* This reserves IO space but doesn't actually enable it */
618 return pcmcia_request_io(p_dev, &p_dev->io);
619}
620
547static int prism2_config(struct pcmcia_device *link) 621static int prism2_config(struct pcmcia_device *link)
548{ 622{
549 struct net_device *dev; 623 struct net_device *dev;
550 struct hostap_interface *iface; 624 struct hostap_interface *iface;
551 local_info_t *local; 625 local_info_t *local;
552 int ret = 1; 626 int ret = 1;
553 tuple_t tuple;
554 cisparse_t *parse;
555 int last_fn, last_ret; 627 int last_fn, last_ret;
556 u_char buf[64];
557 config_info_t conf;
558 cistpl_cftable_entry_t dflt = { 0 };
559 struct hostap_cs_priv *hw_priv; 628 struct hostap_cs_priv *hw_priv;
560 629
561 PDEBUG(DEBUG_FLOW, "prism2_config()\n"); 630 PDEBUG(DEBUG_FLOW, "prism2_config()\n");
562 631
563 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
564 hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL); 632 hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
565 if (parse == NULL || hw_priv == NULL) { 633 if (hw_priv == NULL) {
566 ret = -ENOMEM; 634 ret = -ENOMEM;
567 goto failed; 635 goto failed;
568 } 636 }
569 637
570 tuple.Attributes = 0;
571 tuple.TupleData = buf;
572 tuple.TupleDataMax = sizeof(buf);
573 tuple.TupleOffset = 0;
574
575 CS_CHECK(GetConfigurationInfo,
576 pcmcia_get_configuration_info(link, &conf));
577
578 /* Look for an appropriate configuration table entry in the CIS */ 638 /* Look for an appropriate configuration table entry in the CIS */
579 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 639 last_ret = pcmcia_loop_config(link, prism2_config_check, NULL);
580 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 640 if (last_ret) {
581 for (;;) { 641 if (!ignore_cis_vcc)
582 cistpl_cftable_entry_t *cfg = &(parse->cftable_entry); 642 printk(KERN_ERR "GetNextTuple(): No matching "
583 CFG_CHECK2(GetTupleData, 643 "CIS configuration. Maybe you need the "
584 pcmcia_get_tuple_data(link, &tuple)); 644 "ignore_cis_vcc=1 parameter.\n");
585 CFG_CHECK2(ParseTuple, 645 cs_error(link, RequestIO, last_ret);
586 pcmcia_parse_tuple(link, &tuple, parse)); 646 goto failed;
587
588 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
589 dflt = *cfg;
590 if (cfg->index == 0)
591 goto next_entry;
592 link->conf.ConfigIndex = cfg->index;
593 PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
594 "(default 0x%02X)\n", cfg->index, dflt.index);
595
596 /* Does this card need audio output? */
597 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
598 link->conf.Attributes |= CONF_ENABLE_SPKR;
599 link->conf.Status = CCSR_AUDIO_ENA;
600 }
601
602 /* Use power settings for Vcc and Vpp if present */
603 /* Note that the CIS values need to be rescaled */
604 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
605 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
606 10000 && !ignore_cis_vcc) {
607 PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping"
608 " this entry\n");
609 goto next_entry;
610 }
611 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
612 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] /
613 10000 && !ignore_cis_vcc) {
614 PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch "
615 "- skipping this entry\n");
616 goto next_entry;
617 }
618 }
619
620 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
621 link->conf.Vpp =
622 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
623 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
624 link->conf.Vpp =
625 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
626
627 /* Do we need to allocate an interrupt? */
628 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
629 link->conf.Attributes |= CONF_ENABLE_IRQ;
630 else if (!(link->conf.Attributes & CONF_ENABLE_IRQ)) {
631 /* At least Compaq WL200 does not have IRQInfo1 set,
632 * but it does not work without interrupts.. */
633 printk("Config has no IRQ info, but trying to enable "
634 "IRQ anyway..\n");
635 link->conf.Attributes |= CONF_ENABLE_IRQ;
636 }
637
638 /* IO window settings */
639 PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
640 "dflt.io.nwin=%d\n",
641 cfg->io.nwin, dflt.io.nwin);
642 link->io.NumPorts1 = link->io.NumPorts2 = 0;
643 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
644 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
645 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
646 PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
647 "io.base=0x%04x, len=%d\n", io->flags,
648 io->win[0].base, io->win[0].len);
649 if (!(io->flags & CISTPL_IO_8BIT))
650 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
651 if (!(io->flags & CISTPL_IO_16BIT))
652 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
653 link->io.IOAddrLines = io->flags &
654 CISTPL_IO_LINES_MASK;
655 link->io.BasePort1 = io->win[0].base;
656 link->io.NumPorts1 = io->win[0].len;
657 if (io->nwin > 1) {
658 link->io.Attributes2 = link->io.Attributes1;
659 link->io.BasePort2 = io->win[1].base;
660 link->io.NumPorts2 = io->win[1].len;
661 }
662 }
663
664 /* This reserves IO space but doesn't actually enable it */
665 CFG_CHECK2(RequestIO,
666 pcmcia_request_io(link, &link->io));
667
668 /* This configuration table entry is OK */
669 break;
670
671 next_entry:
672 CS_CHECK(GetNextTuple,
673 pcmcia_get_next_tuple(link, &tuple));
674 } 647 }
675 648
676 /* Need to allocate net_device before requesting IRQ handler */ 649 /* Need to allocate net_device before requesting IRQ handler */
@@ -738,14 +711,12 @@ static int prism2_config(struct pcmcia_device *link)
738 if (ret == 0 && local->ddev) 711 if (ret == 0 && local->ddev)
739 strcpy(hw_priv->node.dev_name, local->ddev->name); 712 strcpy(hw_priv->node.dev_name, local->ddev->name);
740 } 713 }
741 kfree(parse);
742 return ret; 714 return ret;
743 715
744 cs_failed: 716 cs_failed:
745 cs_error(link, last_fn, last_ret); 717 cs_error(link, last_fn, last_ret);
746 718
747 failed: 719 failed:
748 kfree(parse);
749 kfree(hw_priv); 720 kfree(hw_priv);
750 prism2_release((u_long)link); 721 prism2_release((u_long)link);
751 return ret; 722 return ret;
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index 1c216e015f6..c7b57d9d499 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -164,6 +164,70 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
164 last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \ 164 last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
165 } while (0) 165 } while (0)
166 166
167static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
168 cistpl_cftable_entry_t *cfg,
169 cistpl_cftable_entry_t *dflt,
170 unsigned int vcc,
171 void *priv_data)
172{
173 if (cfg->index == 0)
174 goto next_entry;
175
176 /* Use power settings for Vcc and Vpp if present */
177 /* Note that the CIS values need to be rescaled */
178 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
179 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
180 DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
181 if (!ignore_cis_vcc)
182 goto next_entry;
183 }
184 } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
185 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
186 DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
187 if (!ignore_cis_vcc)
188 goto next_entry;
189 }
190 }
191
192 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
193 p_dev->conf.Vpp =
194 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
195 else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
196 p_dev->conf.Vpp =
197 dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
198
199 /* Do we need to allocate an interrupt? */
200 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
201
202 /* IO window settings */
203 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
204 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
205 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
206 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
207 if (!(io->flags & CISTPL_IO_8BIT))
208 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
209 if (!(io->flags & CISTPL_IO_16BIT))
210 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
211 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
212 p_dev->io.BasePort1 = io->win[0].base;
213 p_dev->io.NumPorts1 = io->win[0].len;
214 if (io->nwin > 1) {
215 p_dev->io.Attributes2 = p_dev->io.Attributes1;
216 p_dev->io.BasePort2 = io->win[1].base;
217 p_dev->io.NumPorts2 = io->win[1].len;
218 }
219
220 /* This reserves IO space but doesn't actually enable it */
221 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
222 goto next_entry;
223 }
224 return 0;
225
226next_entry:
227 pcmcia_disable_device(p_dev);
228 return -ENODEV;
229};
230
167static int 231static int
168orinoco_cs_config(struct pcmcia_device *link) 232orinoco_cs_config(struct pcmcia_device *link)
169{ 233{
@@ -172,16 +236,8 @@ orinoco_cs_config(struct pcmcia_device *link)
172 struct orinoco_pccard *card = priv->card; 236 struct orinoco_pccard *card = priv->card;
173 hermes_t *hw = &priv->hw; 237 hermes_t *hw = &priv->hw;
174 int last_fn, last_ret; 238 int last_fn, last_ret;
175 u_char buf[64];
176 config_info_t conf;
177 tuple_t tuple;
178 cisparse_t parse;
179 void __iomem *mem; 239 void __iomem *mem;
180 240
181 /* Look up the current Vcc */
182 CS_CHECK(GetConfigurationInfo,
183 pcmcia_get_configuration_info(link, &conf));
184
185 /* 241 /*
186 * In this loop, we scan the CIS for configuration table 242 * In this loop, we scan the CIS for configuration table
187 * entries, each of which describes a valid card 243 * entries, each of which describes a valid card
@@ -196,94 +252,14 @@ orinoco_cs_config(struct pcmcia_device *link)
196 * and most client drivers will only use the CIS to fill in 252 * and most client drivers will only use the CIS to fill in
197 * implementation-defined details. 253 * implementation-defined details.
198 */ 254 */
199 tuple.Attributes = 0; 255 last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
200 tuple.TupleData = buf; 256 if (last_ret) {
201 tuple.TupleDataMax = sizeof(buf); 257 if (!ignore_cis_vcc)
202 tuple.TupleOffset = 0;
203 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
204 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
205 while (1) {
206 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
207 cistpl_cftable_entry_t dflt = { .index = 0 };
208
209 if ( (pcmcia_get_tuple_data(link, &tuple) != 0)
210 || (pcmcia_parse_tuple(link, &tuple, &parse) != 0))
211 goto next_entry;
212
213 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
214 dflt = *cfg;
215 if (cfg->index == 0)
216 goto next_entry;
217 link->conf.ConfigIndex = cfg->index;
218
219 /* Use power settings for Vcc and Vpp if present */
220 /* Note that the CIS values need to be rescaled */
221 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
222 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
223 DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, cfg CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
224 if (!ignore_cis_vcc)
225 goto next_entry;
226 }
227 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
228 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
229 DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, dflt CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
230 if(!ignore_cis_vcc)
231 goto next_entry;
232 }
233 }
234
235 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
236 link->conf.Vpp =
237 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
238 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
239 link->conf.Vpp =
240 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
241
242 /* Do we need to allocate an interrupt? */
243 link->conf.Attributes |= CONF_ENABLE_IRQ;
244
245 /* IO window settings */
246 link->io.NumPorts1 = link->io.NumPorts2 = 0;
247 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
248 cistpl_io_t *io =
249 (cfg->io.nwin) ? &cfg->io : &dflt.io;
250 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
251 if (!(io->flags & CISTPL_IO_8BIT))
252 link->io.Attributes1 =
253 IO_DATA_PATH_WIDTH_16;
254 if (!(io->flags & CISTPL_IO_16BIT))
255 link->io.Attributes1 =
256 IO_DATA_PATH_WIDTH_8;
257 link->io.IOAddrLines =
258 io->flags & CISTPL_IO_LINES_MASK;
259 link->io.BasePort1 = io->win[0].base;
260 link->io.NumPorts1 = io->win[0].len;
261 if (io->nwin > 1) {
262 link->io.Attributes2 =
263 link->io.Attributes1;
264 link->io.BasePort2 = io->win[1].base;
265 link->io.NumPorts2 = io->win[1].len;
266 }
267
268 /* This reserves IO space but doesn't actually enable it */
269 if (pcmcia_request_io(link, &link->io) != 0)
270 goto next_entry;
271 }
272
273
274 /* If we got this far, we're cool! */
275
276 break;
277
278 next_entry:
279 pcmcia_disable_device(link);
280 last_ret = pcmcia_get_next_tuple(link, &tuple);
281 if (last_ret == CS_NO_MORE_ITEMS) {
282 printk(KERN_ERR PFX "GetNextTuple(): No matching " 258 printk(KERN_ERR PFX "GetNextTuple(): No matching "
283 "CIS configuration. Maybe you need the " 259 "CIS configuration. Maybe you need the "
284 "ignore_cis_vcc=1 parameter.\n"); 260 "ignore_cis_vcc=1 parameter.\n");
285 goto cs_failed; 261 cs_error(link, RequestIO, last_ret);
286 } 262 goto failed;
287 } 263 }
288 264
289 /* 265 /*
@@ -334,7 +310,6 @@ orinoco_cs_config(struct pcmcia_device *link)
334 "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id, 310 "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id,
335 link->irq.AssignedIRQ, link->io.BasePort1, 311 link->irq.AssignedIRQ, link->io.BasePort1,
336 link->io.BasePort1 + link->io.NumPorts1 - 1); 312 link->io.BasePort1 + link->io.NumPorts1 - 1);
337
338 return 0; 313 return 0;
339 314
340 cs_failed: 315 cs_failed:
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 98df9bc7836..d7e9d9c3042 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -633,6 +633,70 @@ static void spectrum_cs_detach(struct pcmcia_device *link)
633 * device available to the system. 633 * device available to the system.
634 */ 634 */
635 635
636static int spectrum_cs_config_check(struct pcmcia_device *p_dev,
637 cistpl_cftable_entry_t *cfg,
638 cistpl_cftable_entry_t *dflt,
639 unsigned int vcc,
640 void *priv_data)
641{
642 if (cfg->index == 0)
643 goto next_entry;
644
645 /* Use power settings for Vcc and Vpp if present */
646 /* Note that the CIS values need to be rescaled */
647 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
648 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
649 DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
650 if (!ignore_cis_vcc)
651 goto next_entry;
652 }
653 } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
654 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
655 DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
656 if (!ignore_cis_vcc)
657 goto next_entry;
658 }
659 }
660
661 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
662 p_dev->conf.Vpp =
663 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
664 else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
665 p_dev->conf.Vpp =
666 dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
667
668 /* Do we need to allocate an interrupt? */
669 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
670
671 /* IO window settings */
672 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
673 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
674 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
675 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
676 if (!(io->flags & CISTPL_IO_8BIT))
677 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
678 if (!(io->flags & CISTPL_IO_16BIT))
679 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
680 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
681 p_dev->io.BasePort1 = io->win[0].base;
682 p_dev->io.NumPorts1 = io->win[0].len;
683 if (io->nwin > 1) {
684 p_dev->io.Attributes2 = p_dev->io.Attributes1;
685 p_dev->io.BasePort2 = io->win[1].base;
686 p_dev->io.NumPorts2 = io->win[1].len;
687 }
688
689 /* This reserves IO space but doesn't actually enable it */
690 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
691 goto next_entry;
692 }
693 return 0;
694
695next_entry:
696 pcmcia_disable_device(p_dev);
697 return -ENODEV;
698};
699
636static int 700static int
637spectrum_cs_config(struct pcmcia_device *link) 701spectrum_cs_config(struct pcmcia_device *link)
638{ 702{
@@ -641,16 +705,8 @@ spectrum_cs_config(struct pcmcia_device *link)
641 struct orinoco_pccard *card = priv->card; 705 struct orinoco_pccard *card = priv->card;
642 hermes_t *hw = &priv->hw; 706 hermes_t *hw = &priv->hw;
643 int last_fn, last_ret; 707 int last_fn, last_ret;
644 u_char buf[64];
645 config_info_t conf;
646 tuple_t tuple;
647 cisparse_t parse;
648 void __iomem *mem; 708 void __iomem *mem;
649 709
650 /* Look up the current Vcc */
651 CS_CHECK(GetConfigurationInfo,
652 pcmcia_get_configuration_info(link, &conf));
653
654 /* 710 /*
655 * In this loop, we scan the CIS for configuration table 711 * In this loop, we scan the CIS for configuration table
656 * entries, each of which describes a valid card 712 * entries, each of which describes a valid card
@@ -665,94 +721,14 @@ spectrum_cs_config(struct pcmcia_device *link)
665 * and most client drivers will only use the CIS to fill in 721 * and most client drivers will only use the CIS to fill in
666 * implementation-defined details. 722 * implementation-defined details.
667 */ 723 */
668 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 724 last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
669 tuple.Attributes = 0; 725 if (last_ret) {
670 tuple.TupleData = buf; 726 if (!ignore_cis_vcc)
671 tuple.TupleDataMax = sizeof(buf);
672 tuple.TupleOffset = 0;
673 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
674 while (1) {
675 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
676 cistpl_cftable_entry_t dflt = { .index = 0 };
677
678 if ( (pcmcia_get_tuple_data(link, &tuple) != 0)
679 || (pcmcia_parse_tuple(link, &tuple, &parse) != 0))
680 goto next_entry;
681
682 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
683 dflt = *cfg;
684 if (cfg->index == 0)
685 goto next_entry;
686 link->conf.ConfigIndex = cfg->index;
687
688 /* Use power settings for Vcc and Vpp if present */
689 /* Note that the CIS values need to be rescaled */
690 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
691 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
692 DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
693 if (!ignore_cis_vcc)
694 goto next_entry;
695 }
696 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
697 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
698 DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
699 if(!ignore_cis_vcc)
700 goto next_entry;
701 }
702 }
703
704 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
705 link->conf.Vpp =
706 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
707 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
708 link->conf.Vpp =
709 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
710
711 /* Do we need to allocate an interrupt? */
712 link->conf.Attributes |= CONF_ENABLE_IRQ;
713
714 /* IO window settings */
715 link->io.NumPorts1 = link->io.NumPorts2 = 0;
716 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
717 cistpl_io_t *io =
718 (cfg->io.nwin) ? &cfg->io : &dflt.io;
719 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
720 if (!(io->flags & CISTPL_IO_8BIT))
721 link->io.Attributes1 =
722 IO_DATA_PATH_WIDTH_16;
723 if (!(io->flags & CISTPL_IO_16BIT))
724 link->io.Attributes1 =
725 IO_DATA_PATH_WIDTH_8;
726 link->io.IOAddrLines =
727 io->flags & CISTPL_IO_LINES_MASK;
728 link->io.BasePort1 = io->win[0].base;
729 link->io.NumPorts1 = io->win[0].len;
730 if (io->nwin > 1) {
731 link->io.Attributes2 =
732 link->io.Attributes1;
733 link->io.BasePort2 = io->win[1].base;
734 link->io.NumPorts2 = io->win[1].len;
735 }
736
737 /* This reserves IO space but doesn't actually enable it */
738 if (pcmcia_request_io(link, &link->io) != 0)
739 goto next_entry;
740 }
741
742
743 /* If we got this far, we're cool! */
744
745 break;
746
747 next_entry:
748 pcmcia_disable_device(link);
749 last_ret = pcmcia_get_next_tuple(link, &tuple);
750 if (last_ret == CS_NO_MORE_ITEMS) {
751 printk(KERN_ERR PFX "GetNextTuple(): No matching " 727 printk(KERN_ERR PFX "GetNextTuple(): No matching "
752 "CIS configuration. Maybe you need the " 728 "CIS configuration. Maybe you need the "
753 "ignore_cis_vcc=1 parameter.\n"); 729 "ignore_cis_vcc=1 parameter.\n");
754 goto cs_failed; 730 cs_error(link, RequestIO, last_ret);
755 } 731 goto failed;
756 } 732 }
757 733
758 /* 734 /*
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 00e1d9620f7..b1899e9c1f6 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -149,52 +149,44 @@ static void parport_detach(struct pcmcia_device *link)
149#define CS_CHECK(fn, ret) \ 149#define CS_CHECK(fn, ret) \
150do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 150do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
151 151
152static int parport_config_check(struct pcmcia_device *p_dev,
153 cistpl_cftable_entry_t *cfg,
154 cistpl_cftable_entry_t *dflt,
155 unsigned int vcc,
156 void *priv_data)
157{
158 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
159 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
160 if (epp_mode)
161 p_dev->conf.ConfigIndex |= FORCE_EPP_MODE;
162 p_dev->io.BasePort1 = io->win[0].base;
163 p_dev->io.NumPorts1 = io->win[0].len;
164 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
165 if (io->nwin == 2) {
166 p_dev->io.BasePort2 = io->win[1].base;
167 p_dev->io.NumPorts2 = io->win[1].len;
168 }
169 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
170 return -ENODEV;
171 return 0;
172 }
173 return -ENODEV;
174}
175
152static int parport_config(struct pcmcia_device *link) 176static int parport_config(struct pcmcia_device *link)
153{ 177{
154 parport_info_t *info = link->priv; 178 parport_info_t *info = link->priv;
155 tuple_t tuple;
156 u_short buf[128];
157 cisparse_t parse;
158 cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
159 cistpl_cftable_entry_t dflt = { 0 };
160 struct parport *p; 179 struct parport *p;
161 int last_ret, last_fn; 180 int last_ret, last_fn;
162 181
163 DEBUG(0, "parport_config(0x%p)\n", link); 182 DEBUG(0, "parport_config(0x%p)\n", link);
164 183
165 tuple.TupleData = (cisdata_t *)buf; 184 last_ret = pcmcia_loop_config(link, parport_config_check, NULL);
166 tuple.TupleOffset = 0; tuple.TupleDataMax = 255; 185 if (last_ret) {
167 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 186 cs_error(link, RequestIO, last_ret);
168 tuple.Attributes = 0; 187 goto failed;
169 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
170 while (1) {
171 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
172 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
173 goto next_entry;
174
175 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
176 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
177 link->conf.ConfigIndex = cfg->index;
178 if (epp_mode)
179 link->conf.ConfigIndex |= FORCE_EPP_MODE;
180 link->io.BasePort1 = io->win[0].base;
181 link->io.NumPorts1 = io->win[0].len;
182 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
183 if (io->nwin == 2) {
184 link->io.BasePort2 = io->win[1].base;
185 link->io.NumPorts2 = io->win[1].len;
186 }
187 if (pcmcia_request_io(link, &link->io) != 0)
188 goto next_entry;
189 /* If we've got this far, we're done */
190 break;
191 }
192
193 next_entry:
194 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
195 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
196 } 188 }
197 189
198 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 190 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
199 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 191 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
200 192
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index f804b45de24..fe789e0e7ad 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -266,13 +266,13 @@ EXPORT_SYMBOL(pcmcia_write_cis_mem);
266======================================================================*/ 266======================================================================*/
267 267
268static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, 268static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
269 u_int len, void *ptr) 269 size_t len, void *ptr)
270{ 270{
271 struct cis_cache_entry *cis; 271 struct cis_cache_entry *cis;
272 int ret; 272 int ret;
273 273
274 if (s->fake_cis) { 274 if (s->fake_cis) {
275 if (s->fake_cis_len > addr+len) 275 if (s->fake_cis_len >= addr+len)
276 memcpy(ptr, s->fake_cis+addr, len); 276 memcpy(ptr, s->fake_cis+addr, len);
277 else 277 else
278 memset(ptr, 0xff, len); 278 memset(ptr, 0xff, len);
@@ -381,17 +381,17 @@ int verify_cis_cache(struct pcmcia_socket *s)
381 381
382======================================================================*/ 382======================================================================*/
383 383
384int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis) 384int pcmcia_replace_cis(struct pcmcia_socket *s,
385 const u8 *data, const size_t len)
385{ 386{
386 kfree(s->fake_cis); 387 if (len > CISTPL_MAX_CIS_SIZE)
387 s->fake_cis = NULL;
388 if (cis->Length > CISTPL_MAX_CIS_SIZE)
389 return CS_BAD_SIZE; 388 return CS_BAD_SIZE;
390 s->fake_cis = kmalloc(cis->Length, GFP_KERNEL); 389 kfree(s->fake_cis);
390 s->fake_cis = kmalloc(len, GFP_KERNEL);
391 if (s->fake_cis == NULL) 391 if (s->fake_cis == NULL)
392 return CS_OUT_OF_RESOURCE; 392 return CS_OUT_OF_RESOURCE;
393 s->fake_cis_len = cis->Length; 393 s->fake_cis_len = len;
394 memcpy(s->fake_cis, cis->Data, cis->Length); 394 memcpy(s->fake_cis, data, len);
395 return CS_SUCCESS; 395 return CS_SUCCESS;
396} 396}
397EXPORT_SYMBOL(pcmcia_replace_cis); 397EXPORT_SYMBOL(pcmcia_replace_cis);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 6501a968a64..a393501554a 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -864,7 +864,6 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
864 int ret = -ENOMEM; 864 int ret = -ENOMEM;
865 int no_funcs; 865 int no_funcs;
866 int old_funcs; 866 int old_funcs;
867 cisdump_t *cis;
868 cistpl_longlink_mfc_t mfc; 867 cistpl_longlink_mfc_t mfc;
869 868
870 if (!filename) 869 if (!filename)
@@ -889,16 +888,7 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
889 goto release; 888 goto release;
890 } 889 }
891 890
892 cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); 891 if (!pcmcia_replace_cis(s, fw->data, fw->size))
893 if (!cis) {
894 ret = -ENOMEM;
895 goto release;
896 }
897
898 cis->Length = fw->size + 1;
899 memcpy(cis->Data, fw->data, fw->size);
900
901 if (!pcmcia_replace_cis(s, cis))
902 ret = 0; 892 ret = 0;
903 else { 893 else {
904 dev_printk(KERN_ERR, &dev->dev, 894 dev_printk(KERN_ERR, &dev->dev,
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 0492d2df01a..f555a505214 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -867,7 +867,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
867 &buf->win_info.map); 867 &buf->win_info.map);
868 break; 868 break;
869 case DS_REPLACE_CIS: 869 case DS_REPLACE_CIS:
870 ret = pcmcia_replace_cis(s, &buf->cisdump); 870 ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length);
871 break; 871 break;
872 case DS_BIND_REQUEST: 872 case DS_BIND_REQUEST:
873 if (!capable(CAP_SYS_ADMIN)) { 873 if (!capable(CAP_SYS_ADMIN)) {
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 2c636058f49..9afe420c41f 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -912,3 +912,79 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) {
912 pcmcia_release_window(p_dev->win); 912 pcmcia_release_window(p_dev->win);
913} 913}
914EXPORT_SYMBOL(pcmcia_disable_device); 914EXPORT_SYMBOL(pcmcia_disable_device);
915
916
917struct pcmcia_cfg_mem {
918 tuple_t tuple;
919 cisparse_t parse;
920 u8 buf[256];
921 cistpl_cftable_entry_t dflt;
922};
923
924/**
925 * pcmcia_loop_config() - loop over configuration options
926 * @p_dev: the struct pcmcia_device which we need to loop for.
927 * @conf_check: function to call for each configuration option.
928 * It gets passed the struct pcmcia_device, the CIS data
929 * describing the configuration option, and private data
930 * being passed to pcmcia_loop_config()
931 * @priv_data: private data to be passed to the conf_check function.
932 *
933 * pcmcia_loop_config() loops over all configuration options, and calls
934 * the driver-specific conf_check() for each one, checking whether
935 * it is a valid one.
936 */
937int pcmcia_loop_config(struct pcmcia_device *p_dev,
938 int (*conf_check) (struct pcmcia_device *p_dev,
939 cistpl_cftable_entry_t *cfg,
940 cistpl_cftable_entry_t *dflt,
941 unsigned int vcc,
942 void *priv_data),
943 void *priv_data)
944{
945 struct pcmcia_cfg_mem *cfg_mem;
946
947 tuple_t *tuple;
948 int ret = -ENODEV;
949 unsigned int vcc;
950
951 cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
952 if (cfg_mem == NULL)
953 return -ENOMEM;
954
955 /* get the current Vcc setting */
956 vcc = p_dev->socket->socket.Vcc;
957
958 tuple = &cfg_mem->tuple;
959 tuple->TupleData = cfg_mem->buf;
960 tuple->TupleDataMax = 255;
961 tuple->TupleOffset = 0;
962 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
963 tuple->Attributes = 0;
964
965 ret = pcmcia_get_first_tuple(p_dev, tuple);
966 while (!ret) {
967 cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry;
968
969 if (pcmcia_get_tuple_data(p_dev, tuple))
970 goto next_entry;
971
972 if (pcmcia_parse_tuple(p_dev, tuple, &cfg_mem->parse))
973 goto next_entry;
974
975 /* default values */
976 p_dev->conf.ConfigIndex = cfg->index;
977 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
978 cfg_mem->dflt = *cfg;
979
980 ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data);
981 if (!ret)
982 break;
983
984next_entry:
985 ret = pcmcia_get_next_tuple(p_dev, tuple);
986 }
987
988 return ret;
989}
990EXPORT_SYMBOL(pcmcia_loop_config);
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 006a29e91d8..ff9a3bb3c88 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -316,27 +316,18 @@ static ssize_t pccard_store_cis(struct kobject *kobj,
316 char *buf, loff_t off, size_t count) 316 char *buf, loff_t off, size_t count)
317{ 317{
318 struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj)); 318 struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
319 cisdump_t *cis;
320 int error; 319 int error;
321 320
322 if (off) 321 if (off)
323 return -EINVAL; 322 return -EINVAL;
324 323
325 if (count >= 0x200) 324 if (count >= CISTPL_MAX_CIS_SIZE)
326 return -EINVAL; 325 return -EINVAL;
327 326
328 if (!(s->state & SOCKET_PRESENT)) 327 if (!(s->state & SOCKET_PRESENT))
329 return -ENODEV; 328 return -ENODEV;
330 329
331 cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); 330 error = pcmcia_replace_cis(s, buf, count);
332 if (!cis)
333 return -ENOMEM;
334
335 cis->Length = count + 1;
336 memcpy(cis->Data, buf, count);
337
338 error = pcmcia_replace_cis(s, cis);
339 kfree(cis);
340 if (error) 331 if (error)
341 return -EIO; 332 return -EIO;
342 333
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 2dd0dc9a9ae..165ff884f48 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -140,44 +140,41 @@ static void aha152x_detach(struct pcmcia_device *link)
140#define CS_CHECK(fn, ret) \ 140#define CS_CHECK(fn, ret) \
141do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 141do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
142 142
143static int aha152x_config_check(struct pcmcia_device *p_dev,
144 cistpl_cftable_entry_t *cfg,
145 cistpl_cftable_entry_t *dflt,
146 unsigned int vcc,
147 void *priv_data)
148{
149 /* For New Media T&J, look for a SCSI window */
150 if (cfg->io.win[0].len >= 0x20)
151 p_dev->io.BasePort1 = cfg->io.win[0].base;
152 else if ((cfg->io.nwin > 1) &&
153 (cfg->io.win[1].len >= 0x20))
154 p_dev->io.BasePort1 = cfg->io.win[1].base;
155 if ((cfg->io.nwin > 0) &&
156 (p_dev->io.BasePort1 < 0xffff)) {
157 if (!pcmcia_request_io(p_dev, &p_dev->io))
158 return 0;
159 }
160 return -EINVAL;
161}
162
143static int aha152x_config_cs(struct pcmcia_device *link) 163static int aha152x_config_cs(struct pcmcia_device *link)
144{ 164{
145 scsi_info_t *info = link->priv; 165 scsi_info_t *info = link->priv;
146 struct aha152x_setup s; 166 struct aha152x_setup s;
147 tuple_t tuple; 167 int last_ret, last_fn;
148 cisparse_t parse;
149 int i, last_ret, last_fn;
150 u_char tuple_data[64];
151 struct Scsi_Host *host; 168 struct Scsi_Host *host;
152 169
153 DEBUG(0, "aha152x_config(0x%p)\n", link); 170 DEBUG(0, "aha152x_config(0x%p)\n", link);
154 171
155 tuple.TupleData = tuple_data; 172 last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
156 tuple.TupleDataMax = 64; 173 if (last_ret) {
157 tuple.TupleOffset = 0; 174 cs_error(link, RequestIO, last_ret);
158 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 175 goto failed;
159 tuple.Attributes = 0;
160 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
161 while (1) {
162 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
163 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
164 goto next_entry;
165 /* For New Media T&J, look for a SCSI window */
166 if (parse.cftable_entry.io.win[0].len >= 0x20)
167 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
168 else if ((parse.cftable_entry.io.nwin > 1) &&
169 (parse.cftable_entry.io.win[1].len >= 0x20))
170 link->io.BasePort1 = parse.cftable_entry.io.win[1].base;
171 if ((parse.cftable_entry.io.nwin > 0) &&
172 (link->io.BasePort1 < 0xffff)) {
173 link->conf.ConfigIndex = parse.cftable_entry.index;
174 i = pcmcia_request_io(link, &link->io);
175 if (i == CS_SUCCESS) break;
176 }
177 next_entry:
178 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
179 } 176 }
180 177
181 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 178 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
182 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 179 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
183 180
@@ -208,6 +205,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
208 205
209cs_failed: 206cs_failed:
210 cs_error(link, last_fn, last_ret); 207 cs_error(link, last_fn, last_ret);
208failed:
211 aha152x_release_cs(link); 209 aha152x_release_cs(link);
212 return -ENODEV; 210 return -ENODEV;
213} 211}
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index d8b99351b05..06254f46a0d 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -123,34 +123,30 @@ static void fdomain_detach(struct pcmcia_device *link)
123#define CS_CHECK(fn, ret) \ 123#define CS_CHECK(fn, ret) \
124do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 124do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
125 125
126static int fdomain_config_check(struct pcmcia_device *p_dev,
127 cistpl_cftable_entry_t *cfg,
128 cistpl_cftable_entry_t *dflt,
129 unsigned int vcc,
130 void *priv_data)
131{
132 p_dev->io.BasePort1 = cfg->io.win[0].base;
133 return pcmcia_request_io(p_dev, &p_dev->io);
134}
135
136
126static int fdomain_config(struct pcmcia_device *link) 137static int fdomain_config(struct pcmcia_device *link)
127{ 138{
128 scsi_info_t *info = link->priv; 139 scsi_info_t *info = link->priv;
129 tuple_t tuple; 140 int last_ret, last_fn;
130 cisparse_t parse;
131 int i, last_ret, last_fn;
132 u_char tuple_data[64];
133 char str[22]; 141 char str[22];
134 struct Scsi_Host *host; 142 struct Scsi_Host *host;
135 143
136 DEBUG(0, "fdomain_config(0x%p)\n", link); 144 DEBUG(0, "fdomain_config(0x%p)\n", link);
137 145
138 tuple.TupleData = tuple_data; 146 last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
139 tuple.TupleDataMax = 64; 147 if (last_ret) {
140 tuple.TupleOffset = 0; 148 cs_error(link, RequestIO, last_ret);
141 149 goto failed;
142 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
143 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
144 while (1) {
145 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
146 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
147 goto next_entry;
148 link->conf.ConfigIndex = parse.cftable_entry.index;
149 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
150 i = pcmcia_request_io(link, &link->io);
151 if (i == CS_SUCCESS) break;
152 next_entry:
153 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
154 } 150 }
155 151
156 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 152 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@@ -181,6 +177,7 @@ static int fdomain_config(struct pcmcia_device *link)
181 177
182cs_failed: 178cs_failed:
183 cs_error(link, last_fn, last_ret); 179 cs_error(link, last_fn, last_ret);
180failed:
184 fdomain_release(link); 181 fdomain_release(link);
185 return -ENODEV; 182 return -ENODEV;
186} /* fdomain_config */ 183} /* fdomain_config */
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index a221b6ef9fa..7c19bf26487 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1607,133 +1607,129 @@ static void nsp_cs_detach(struct pcmcia_device *link)
1607 is received, to configure the PCMCIA socket, and to make the 1607 is received, to configure the PCMCIA socket, and to make the
1608 ethernet device available to the system. 1608 ethernet device available to the system.
1609======================================================================*/ 1609======================================================================*/
1610#define CS_CHECK(fn, ret) \
1611do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1612/*====================================================================*/
1613static int nsp_cs_config(struct pcmcia_device *link)
1614{
1615 int ret;
1616 scsi_info_t *info = link->priv;
1617 tuple_t tuple;
1618 cisparse_t parse;
1619 int last_ret, last_fn;
1620 unsigned char tuple_data[64];
1621 config_info_t conf;
1622 win_req_t req;
1623 memreq_t map;
1624 cistpl_cftable_entry_t dflt = { 0 };
1625 struct Scsi_Host *host;
1626 nsp_hw_data *data = &nsp_data_base;
1627
1628 nsp_dbg(NSP_DEBUG_INIT, "in");
1629
1630 tuple.Attributes = 0;
1631 tuple.TupleData = tuple_data;
1632 tuple.TupleDataMax = sizeof(tuple_data);
1633 tuple.TupleOffset = 0;
1634
1635 /* Look up the current Vcc */
1636 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
1637 1610
1638 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 1611struct nsp_cs_configdata {
1639 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 1612 nsp_hw_data *data;
1640 while (1) { 1613 win_req_t req;
1641 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 1614};
1642 1615
1643 if (pcmcia_get_tuple_data(link, &tuple) != 0 || 1616static int nsp_cs_config_check(struct pcmcia_device *p_dev,
1644 pcmcia_parse_tuple(link, &tuple, &parse) != 0) 1617 cistpl_cftable_entry_t *cfg,
1645 goto next_entry; 1618 cistpl_cftable_entry_t *dflt,
1619 unsigned int vcc,
1620 void *priv_data)
1621{
1622 struct nsp_cs_configdata *cfg_mem = priv_data;
1646 1623
1647 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } 1624 if (cfg->index == 0)
1648 if (cfg->index == 0) { goto next_entry; } 1625 return -ENODEV;
1649 link->conf.ConfigIndex = cfg->index;
1650 1626
1651 /* Does this card need audio output? */ 1627 /* Does this card need audio output? */
1652 if (cfg->flags & CISTPL_CFTABLE_AUDIO) { 1628 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1653 link->conf.Attributes |= CONF_ENABLE_SPKR; 1629 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
1654 link->conf.Status = CCSR_AUDIO_ENA; 1630 p_dev->conf.Status = CCSR_AUDIO_ENA;
1655 } 1631 }
1656 1632
1657 /* Use power settings for Vcc and Vpp if present */ 1633 /* Use power settings for Vcc and Vpp if present */
1658 /* Note that the CIS values need to be rescaled */ 1634 /* Note that the CIS values need to be rescaled */
1659 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { 1635 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1660 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) { 1636 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
1661 goto next_entry; 1637 return -ENODEV;
1662 } 1638 else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1663 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { 1639 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000)
1664 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) { 1640 return -ENODEV;
1665 goto next_entry;
1666 }
1667 } 1641 }
1668 1642
1669 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) { 1643 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1670 link->conf.Vpp = 1644 p_dev->conf.Vpp =
1671 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; 1645 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1672 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { 1646 } else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1673 link->conf.Vpp = 1647 p_dev->conf.Vpp =
1674 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; 1648 dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1675 } 1649 }
1676 1650
1677 /* Do we need to allocate an interrupt? */ 1651 /* Do we need to allocate an interrupt? */
1678 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) { 1652 if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
1679 link->conf.Attributes |= CONF_ENABLE_IRQ; 1653 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
1680 }
1681 1654
1682 /* IO window settings */ 1655 /* IO window settings */
1683 link->io.NumPorts1 = link->io.NumPorts2 = 0; 1656 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
1684 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 1657 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
1685 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; 1658 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
1686 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 1659 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1687 if (!(io->flags & CISTPL_IO_8BIT)) 1660 if (!(io->flags & CISTPL_IO_8BIT))
1688 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; 1661 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1689 if (!(io->flags & CISTPL_IO_16BIT)) 1662 if (!(io->flags & CISTPL_IO_16BIT))
1690 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 1663 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1691 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; 1664 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1692 link->io.BasePort1 = io->win[0].base; 1665 p_dev->io.BasePort1 = io->win[0].base;
1693 link->io.NumPorts1 = io->win[0].len; 1666 p_dev->io.NumPorts1 = io->win[0].len;
1694 if (io->nwin > 1) { 1667 if (io->nwin > 1) {
1695 link->io.Attributes2 = link->io.Attributes1; 1668 p_dev->io.Attributes2 = p_dev->io.Attributes1;
1696 link->io.BasePort2 = io->win[1].base; 1669 p_dev->io.BasePort2 = io->win[1].base;
1697 link->io.NumPorts2 = io->win[1].len; 1670 p_dev->io.NumPorts2 = io->win[1].len;
1698 } 1671 }
1699 /* This reserves IO space but doesn't actually enable it */ 1672 /* This reserves IO space but doesn't actually enable it */
1700 if (pcmcia_request_io(link, &link->io) != 0) 1673 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
1701 goto next_entry; 1674 goto next_entry;
1702 } 1675 }
1703 1676
1704 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { 1677 if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
1705 cistpl_mem_t *mem = 1678 memreq_t map;
1706 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; 1679 cistpl_mem_t *mem =
1707 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; 1680 (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
1708 req.Attributes |= WIN_ENABLE; 1681 cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
1709 req.Base = mem->win[0].host_addr; 1682 cfg_mem->req.Attributes |= WIN_ENABLE;
1710 req.Size = mem->win[0].len; 1683 cfg_mem->req.Base = mem->win[0].host_addr;
1711 if (req.Size < 0x1000) { 1684 cfg_mem->req.Size = mem->win[0].len;
1712 req.Size = 0x1000; 1685 if (cfg_mem->req.Size < 0x1000)
1713 } 1686 cfg_mem->req.Size = 0x1000;
1714 req.AccessSpeed = 0; 1687 cfg_mem->req.AccessSpeed = 0;
1715 if (pcmcia_request_window(&link, &req, &link->win) != 0) 1688 if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0)
1716 goto next_entry; 1689 goto next_entry;
1717 map.Page = 0; map.CardOffset = mem->win[0].card_addr; 1690 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1718 if (pcmcia_map_mem_page(link->win, &map) != 0) 1691 if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
1719 goto next_entry; 1692 goto next_entry;
1720 1693
1721 data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size); 1694 cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size);
1722 data->MmioLength = req.Size; 1695 cfg_mem->data->MmioLength = cfg_mem->req.Size;
1723 } 1696 }
1724 /* If we got this far, we're cool! */ 1697 /* If we got this far, we're cool! */
1725 break; 1698 return 0;
1726
1727 next_entry:
1728 nsp_dbg(NSP_DEBUG_INIT, "next");
1729 pcmcia_disable_device(link);
1730 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
1731 } 1699 }
1732 1700
1701next_entry:
1702 nsp_dbg(NSP_DEBUG_INIT, "next");
1703 pcmcia_disable_device(p_dev);
1704 return -ENODEV;
1705}
1706
1707static int nsp_cs_config(struct pcmcia_device *link)
1708{
1709 int ret;
1710 scsi_info_t *info = link->priv;
1711 struct nsp_cs_configdata *cfg_mem;
1712 struct Scsi_Host *host;
1713 nsp_hw_data *data = &nsp_data_base;
1714
1715 nsp_dbg(NSP_DEBUG_INIT, "in");
1716
1717 cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL);
1718 if (!cfg_mem)
1719 return -ENOMEM;
1720 cfg_mem->data = data;
1721
1722 ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem);
1723 goto cs_failed;
1724
1733 if (link->conf.Attributes & CONF_ENABLE_IRQ) { 1725 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1734 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 1726 if (pcmcia_request_irq(link, &link->irq))
1727 goto cs_failed;
1735 } 1728 }
1736 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 1729
1730 ret = pcmcia_request_configuration(link, &link->conf);
1731 if (ret)
1732 goto cs_failed;
1737 1733
1738 if (free_ports) { 1734 if (free_ports) {
1739 if (link->io.BasePort1) { 1735 if (link->io.BasePort1) {
@@ -1791,20 +1787,20 @@ static int nsp_cs_config(struct pcmcia_device *link)
1791 printk(" & 0x%04x-0x%04x", link->io.BasePort2, 1787 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1792 link->io.BasePort2+link->io.NumPorts2-1); 1788 link->io.BasePort2+link->io.NumPorts2-1);
1793 if (link->win) 1789 if (link->win)
1794 printk(", mem 0x%06lx-0x%06lx", req.Base, 1790 printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base,
1795 req.Base+req.Size-1); 1791 cfg_mem->req.Base+cfg_mem->req.Size-1);
1796 printk("\n"); 1792 printk("\n");
1797 1793
1794 kfree(cfg_mem);
1798 return 0; 1795 return 0;
1799 1796
1800 cs_failed: 1797 cs_failed:
1801 nsp_dbg(NSP_DEBUG_INIT, "config fail"); 1798 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1802 cs_error(link, last_fn, last_ret);
1803 nsp_cs_release(link); 1799 nsp_cs_release(link);
1800 kfree(cfg_mem);
1804 1801
1805 return -ENODEV; 1802 return -ENODEV;
1806} /* nsp_cs_config */ 1803} /* nsp_cs_config */
1807#undef CS_CHECK
1808 1804
1809 1805
1810/*====================================================================== 1806/*======================================================================
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 67c5a58d17d..20c3e5e6d88 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -195,39 +195,33 @@ static void qlogic_detach(struct pcmcia_device *link)
195#define CS_CHECK(fn, ret) \ 195#define CS_CHECK(fn, ret) \
196do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 196do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
197 197
198static int qlogic_config_check(struct pcmcia_device *p_dev,
199 cistpl_cftable_entry_t *cfg,
200 cistpl_cftable_entry_t *dflt,
201 unsigned int vcc,
202 void *priv_data)
203{
204 p_dev->io.BasePort1 = cfg->io.win[0].base;
205 p_dev->io.NumPorts1 = cfg->io.win[0].len;
206
207 if (p_dev->io.BasePort1 == 0)
208 return -ENODEV;
209
210 return pcmcia_request_io(p_dev, &p_dev->io);
211}
212
198static int qlogic_config(struct pcmcia_device * link) 213static int qlogic_config(struct pcmcia_device * link)
199{ 214{
200 scsi_info_t *info = link->priv; 215 scsi_info_t *info = link->priv;
201 tuple_t tuple; 216 int last_ret, last_fn;
202 cisparse_t parse;
203 int i, last_ret, last_fn;
204 unsigned short tuple_data[32];
205 struct Scsi_Host *host; 217 struct Scsi_Host *host;
206 218
207 DEBUG(0, "qlogic_config(0x%p)\n", link); 219 DEBUG(0, "qlogic_config(0x%p)\n", link);
208 220
209 info->manf_id = link->manf_id; 221 last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
210 222 if (last_ret) {
211 tuple.TupleData = (cisdata_t *) tuple_data; 223 cs_error(link, RequestIO, last_ret);
212 tuple.TupleDataMax = 64; 224 goto failed;
213 tuple.TupleOffset = 0;
214
215 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
216 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
217 while (1) {
218 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
219 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
220 goto next_entry;
221 link->conf.ConfigIndex = parse.cftable_entry.index;
222 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
223 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
224 if (link->io.BasePort1 != 0) {
225 i = pcmcia_request_io(link, &link->io);
226 if (i == CS_SUCCESS)
227 break;
228 }
229 next_entry:
230 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
231 } 225 }
232 226
233 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 227 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@@ -262,6 +256,7 @@ static int qlogic_config(struct pcmcia_device * link)
262cs_failed: 256cs_failed:
263 cs_error(link, last_fn, last_ret); 257 cs_error(link, last_fn, last_ret);
264 pcmcia_disable_device(link); 258 pcmcia_disable_device(link);
259failed:
265 return -ENODEV; 260 return -ENODEV;
266 261
267} /* qlogic_config */ 262} /* qlogic_config */
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 0be232b58ff..b330c11a175 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -700,15 +700,27 @@ static struct scsi_host_template sym53c500_driver_template = {
700#define CS_CHECK(fn, ret) \ 700#define CS_CHECK(fn, ret) \
701do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 701do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
702 702
703static int SYM53C500_config_check(struct pcmcia_device *p_dev,
704 cistpl_cftable_entry_t *cfg,
705 cistpl_cftable_entry_t *dflt,
706 unsigned int vcc,
707 void *priv_data)
708{
709 p_dev->io.BasePort1 = cfg->io.win[0].base;
710 p_dev->io.NumPorts1 = cfg->io.win[0].len;
711
712 if (p_dev->io.BasePort1 == 0)
713 return -ENODEV;
714
715 return pcmcia_request_io(p_dev, &p_dev->io);
716}
717
703static int 718static int
704SYM53C500_config(struct pcmcia_device *link) 719SYM53C500_config(struct pcmcia_device *link)
705{ 720{
706 struct scsi_info_t *info = link->priv; 721 struct scsi_info_t *info = link->priv;
707 tuple_t tuple; 722 int last_ret, last_fn;
708 cisparse_t parse;
709 int i, last_ret, last_fn;
710 int irq_level, port_base; 723 int irq_level, port_base;
711 unsigned short tuple_data[32];
712 struct Scsi_Host *host; 724 struct Scsi_Host *host;
713 struct scsi_host_template *tpnt = &sym53c500_driver_template; 725 struct scsi_host_template *tpnt = &sym53c500_driver_template;
714 struct sym53c500_data *data; 726 struct sym53c500_data *data;
@@ -717,27 +729,10 @@ SYM53C500_config(struct pcmcia_device *link)
717 729
718 info->manf_id = link->manf_id; 730 info->manf_id = link->manf_id;
719 731
720 tuple.TupleData = (cisdata_t *)tuple_data; 732 last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
721 tuple.TupleDataMax = 64; 733 if (last_ret) {
722 tuple.TupleOffset = 0; 734 cs_error(link, RequestIO, last_ret);
723 735 goto failed;
724 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
725 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
726 while (1) {
727 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
728 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
729 goto next_entry;
730 link->conf.ConfigIndex = parse.cftable_entry.index;
731 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
732 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
733
734 if (link->io.BasePort1 != 0) {
735 i = pcmcia_request_io(link, &link->io);
736 if (i == CS_SUCCESS)
737 break;
738 }
739next_entry:
740 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
741 } 736 }
742 737
743 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 738 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@@ -831,6 +826,7 @@ err_release:
831 826
832cs_failed: 827cs_failed:
833 cs_error(link, last_fn, last_ret); 828 cs_error(link, last_fn, last_ret);
829failed:
834 SYM53C500_release(link); 830 SYM53C500_release(link);
835 return -ENODEV; 831 return -ENODEV;
836} /* SYM53C500_config */ 832} /* SYM53C500_config */
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 164d2a42eb5..7e00e672bfe 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -439,43 +439,57 @@ first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
439 return pcmcia_parse_tuple(handle, tuple, parse); 439 return pcmcia_parse_tuple(handle, tuple, parse);
440} 440}
441 441
442static int 442/*====================================================================*/
443next_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) 443
444static int simple_config_check(struct pcmcia_device *p_dev,
445 cistpl_cftable_entry_t *cf,
446 cistpl_cftable_entry_t *dflt,
447 unsigned int vcc,
448 void *priv_data)
444{ 449{
445 int i; 450 static const int size_table[2] = { 8, 16 };
446 i = pcmcia_get_next_tuple(handle, tuple); 451 int *try = priv_data;
447 if (i != CS_SUCCESS) 452
448 return CS_NO_MORE_ITEMS; 453 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
449 i = pcmcia_get_tuple_data(handle, tuple); 454 p_dev->conf.Vpp =
450 if (i != CS_SUCCESS) 455 cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
451 return i; 456
452 return pcmcia_parse_tuple(handle, tuple, parse); 457 if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)])
458 && (cf->io.win[0].base != 0)) {
459 p_dev->io.BasePort1 = cf->io.win[0].base;
460 p_dev->io.IOAddrLines = ((*try & 0x1) == 0) ?
461 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
462 if (!pcmcia_request_io(p_dev, &p_dev->io))
463 return 0;
464 }
465 return -EINVAL;
453} 466}
454 467
455/*====================================================================*/ 468static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
469 cistpl_cftable_entry_t *cf,
470 cistpl_cftable_entry_t *dflt,
471 unsigned int vcc,
472 void *priv_data)
473{
474 static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
475 int j;
476
477 if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
478 for (j = 0; j < 5; j++) {
479 p_dev->io.BasePort1 = base[j];
480 p_dev->io.IOAddrLines = base[j] ? 16 : 3;
481 if (!pcmcia_request_io(p_dev, &p_dev->io))
482 return 0;
483 }
484 }
485 return -ENODEV;
486}
456 487
457static int simple_config(struct pcmcia_device *link) 488static int simple_config(struct pcmcia_device *link)
458{ 489{
459 static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
460 static const int size_table[2] = { 8, 16 };
461 struct serial_info *info = link->priv; 490 struct serial_info *info = link->priv;
462 struct serial_cfg_mem *cfg_mem;
463 tuple_t *tuple;
464 u_char *buf;
465 cisparse_t *parse;
466 cistpl_cftable_entry_t *cf;
467 config_info_t config; 491 config_info_t config;
468 int i, j, try; 492 int i, try;
469 int s;
470
471 cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
472 if (!cfg_mem)
473 return -1;
474
475 tuple = &cfg_mem->tuple;
476 parse = &cfg_mem->parse;
477 cf = &parse->cftable_entry;
478 buf = cfg_mem->buf;
479 493
480 /* If the card is already configured, look up the port and irq */ 494 /* If the card is already configured, look up the port and irq */
481 i = pcmcia_get_configuration_info(link, &config); 495 i = pcmcia_get_configuration_info(link, &config);
@@ -490,70 +504,28 @@ static int simple_config(struct pcmcia_device *link)
490 info->slave = 1; 504 info->slave = 1;
491 } 505 }
492 if (info->slave) { 506 if (info->slave) {
493 kfree(cfg_mem);
494 return setup_serial(link, info, port, config.AssignedIRQ); 507 return setup_serial(link, info, port, config.AssignedIRQ);
495 } 508 }
496 } 509 }
497 510
498 /* First pass: look for a config entry that looks normal. */ 511 /* First pass: look for a config entry that looks normal.
499 tuple->TupleData = (cisdata_t *) buf; 512 * Two tries: without IO aliases, then with aliases */
500 tuple->TupleOffset = 0; 513 for (try = 0; try < 4; try++)
501 tuple->TupleDataMax = 255; 514 if (!pcmcia_loop_config(link, simple_config_check, &try))
502 tuple->Attributes = 0; 515 goto found_port;
503 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; 516
504 /* Two tries: without IO aliases, then with aliases */
505 for (s = 0; s < 2; s++) {
506 for (try = 0; try < 2; try++) {
507 i = first_tuple(link, tuple, parse);
508 while (i != CS_NO_MORE_ITEMS) {
509 if (i != CS_SUCCESS)
510 goto next_entry;
511 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
512 link->conf.Vpp =
513 cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
514 if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) &&
515 (cf->io.win[0].base != 0)) {
516 link->conf.ConfigIndex = cf->index;
517 link->io.BasePort1 = cf->io.win[0].base;
518 link->io.IOAddrLines = (try == 0) ?
519 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
520 i = pcmcia_request_io(link, &link->io);
521 if (i == CS_SUCCESS)
522 goto found_port;
523 }
524next_entry:
525 i = next_tuple(link, tuple, parse);
526 }
527 }
528 }
529 /* Second pass: try to find an entry that isn't picky about 517 /* Second pass: try to find an entry that isn't picky about
530 its base address, then try to grab any standard serial port 518 its base address, then try to grab any standard serial port
531 address, and finally try to get any free port. */ 519 address, and finally try to get any free port. */
532 i = first_tuple(link, tuple, parse); 520 if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
533 while (i != CS_NO_MORE_ITEMS) { 521 goto found_port;
534 if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&
535 ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
536 link->conf.ConfigIndex = cf->index;
537 for (j = 0; j < 5; j++) {
538 link->io.BasePort1 = base[j];
539 link->io.IOAddrLines = base[j] ? 16 : 3;
540 i = pcmcia_request_io(link, &link->io);
541 if (i == CS_SUCCESS)
542 goto found_port;
543 }
544 }
545 i = next_tuple(link, tuple, parse);
546 }
547 522
548 found_port: 523 printk(KERN_NOTICE
549 if (i != CS_SUCCESS) { 524 "serial_cs: no usable port range found, giving up\n");
550 printk(KERN_NOTICE 525 cs_error(link, RequestIO, i);
551 "serial_cs: no usable port range found, giving up\n"); 526 return -1;
552 cs_error(link, RequestIO, i);
553 kfree(cfg_mem);
554 return -1;
555 }
556 527
528found_port:
557 i = pcmcia_request_irq(link, &link->irq); 529 i = pcmcia_request_irq(link, &link->irq);
558 if (i != CS_SUCCESS) { 530 if (i != CS_SUCCESS) {
559 cs_error(link, RequestIRQ, i); 531 cs_error(link, RequestIRQ, i);
@@ -571,86 +543,74 @@ next_entry:
571 i = pcmcia_request_configuration(link, &link->conf); 543 i = pcmcia_request_configuration(link, &link->conf);
572 if (i != CS_SUCCESS) { 544 if (i != CS_SUCCESS) {
573 cs_error(link, RequestConfiguration, i); 545 cs_error(link, RequestConfiguration, i);
574 kfree(cfg_mem);
575 return -1; 546 return -1;
576 } 547 }
577 kfree(cfg_mem);
578 return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); 548 return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
579} 549}
580 550
581static int multi_config(struct pcmcia_device * link) 551static int multi_config_check(struct pcmcia_device *p_dev,
552 cistpl_cftable_entry_t *cf,
553 cistpl_cftable_entry_t *dflt,
554 unsigned int vcc,
555 void *priv_data)
582{ 556{
583 struct serial_info *info = link->priv; 557 int *base2 = priv_data;
584 struct serial_cfg_mem *cfg_mem; 558
585 tuple_t *tuple; 559 /* The quad port cards have bad CIS's, so just look for a
586 u_char *buf; 560 window larger than 8 ports and assume it will be right */
587 cisparse_t *parse; 561 if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
588 cistpl_cftable_entry_t *cf; 562 p_dev->io.BasePort1 = cf->io.win[0].base;
589 int i, rc, base2 = 0; 563 p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
564 if (!pcmcia_request_io(p_dev, &p_dev->io)) {
565 *base2 = p_dev->io.BasePort1 + 8;
566 return 0;
567 }
568 }
569 return -ENODEV;
570}
590 571
591 cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); 572static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
592 if (!cfg_mem) 573 cistpl_cftable_entry_t *cf,
593 return -1; 574 cistpl_cftable_entry_t *dflt,
594 tuple = &cfg_mem->tuple; 575 unsigned int vcc,
595 parse = &cfg_mem->parse; 576 void *priv_data)
596 cf = &parse->cftable_entry; 577{
597 buf = cfg_mem->buf; 578 int *base2 = priv_data;
579
580 if (cf->io.nwin == 2) {
581 p_dev->io.BasePort1 = cf->io.win[0].base;
582 p_dev->io.BasePort2 = cf->io.win[1].base;
583 p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
584 if (!pcmcia_request_io(p_dev, &p_dev->io)) {
585 *base2 = p_dev->io.BasePort2;
586 return 0;
587 }
588 }
589 return -ENODEV;
590}
598 591
599 tuple->TupleData = (cisdata_t *) buf; 592static int multi_config(struct pcmcia_device *link)
600 tuple->TupleOffset = 0; 593{
601 tuple->TupleDataMax = 255; 594 struct serial_info *info = link->priv;
602 tuple->Attributes = 0; 595 int i, base2 = 0;
603 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
604 596
605 /* First, look for a generic full-sized window */ 597 /* First, look for a generic full-sized window */
606 link->io.NumPorts1 = info->multi * 8; 598 link->io.NumPorts1 = info->multi * 8;
607 i = first_tuple(link, tuple, parse); 599 if (pcmcia_loop_config(link, multi_config_check, &base2)) {
608 while (i != CS_NO_MORE_ITEMS) { 600 /* If that didn't work, look for two windows */
609 /* The quad port cards have bad CIS's, so just look for a
610 window larger than 8 ports and assume it will be right */
611 if ((i == CS_SUCCESS) && (cf->io.nwin == 1) &&
612 (cf->io.win[0].len > 8)) {
613 link->conf.ConfigIndex = cf->index;
614 link->io.BasePort1 = cf->io.win[0].base;
615 link->io.IOAddrLines =
616 cf->io.flags & CISTPL_IO_LINES_MASK;
617 i = pcmcia_request_io(link, &link->io);
618 base2 = link->io.BasePort1 + 8;
619 if (i == CS_SUCCESS)
620 break;
621 }
622 i = next_tuple(link, tuple, parse);
623 }
624
625 /* If that didn't work, look for two windows */
626 if (i != CS_SUCCESS) {
627 link->io.NumPorts1 = link->io.NumPorts2 = 8; 601 link->io.NumPorts1 = link->io.NumPorts2 = 8;
628 info->multi = 2; 602 info->multi = 2;
629 i = first_tuple(link, tuple, parse); 603 if (pcmcia_loop_config(link, multi_config_check_notpicky,
630 while (i != CS_NO_MORE_ITEMS) { 604 &base2)) {
631 if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { 605 printk(KERN_NOTICE "serial_cs: no usable port range"
632 link->conf.ConfigIndex = cf->index; 606 "found, giving up\n");
633 link->io.BasePort1 = cf->io.win[0].base; 607 return -ENODEV;
634 link->io.BasePort2 = cf->io.win[1].base;
635 link->io.IOAddrLines =
636 cf->io.flags & CISTPL_IO_LINES_MASK;
637 i = pcmcia_request_io(link, &link->io);
638 base2 = link->io.BasePort2;
639 if (i == CS_SUCCESS)
640 break;
641 }
642 i = next_tuple(link, tuple, parse);
643 } 608 }
644 } 609 }
645 610
646 if (i != CS_SUCCESS) {
647 cs_error(link, RequestIO, i);
648 rc = -1;
649 goto free_cfg_mem;
650 }
651
652 i = pcmcia_request_irq(link, &link->irq); 611 i = pcmcia_request_irq(link, &link->irq);
653 if (i != CS_SUCCESS) { 612 if (i != CS_SUCCESS) {
613 /* FIXME: comment does not fit, error handling does not fit */
654 printk(KERN_NOTICE 614 printk(KERN_NOTICE
655 "serial_cs: no usable port range found, giving up\n"); 615 "serial_cs: no usable port range found, giving up\n");
656 cs_error(link, RequestIRQ, i); 616 cs_error(link, RequestIRQ, i);
@@ -666,8 +626,7 @@ static int multi_config(struct pcmcia_device * link)
666 i = pcmcia_request_configuration(link, &link->conf); 626 i = pcmcia_request_configuration(link, &link->conf);
667 if (i != CS_SUCCESS) { 627 if (i != CS_SUCCESS) {
668 cs_error(link, RequestConfiguration, i); 628 cs_error(link, RequestConfiguration, i);
669 rc = -1; 629 return -ENODEV;
670 goto free_cfg_mem;
671 } 630 }
672 631
673 /* The Oxford Semiconductor OXCF950 cards are in fact single-port: 632 /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
@@ -678,7 +637,8 @@ static int multi_config(struct pcmcia_device * link)
678 info->prodid == PRODID_POSSIO_GCC)) { 637 info->prodid == PRODID_POSSIO_GCC)) {
679 int err; 638 int err;
680 639
681 if (cf->index == 1 || cf->index == 3) { 640 if (link->conf.ConfigIndex == 1 ||
641 link->conf.ConfigIndex == 3) {
682 err = setup_serial(link, info, base2, 642 err = setup_serial(link, info, base2,
683 link->irq.AssignedIRQ); 643 link->irq.AssignedIRQ);
684 base2 = link->io.BasePort1; 644 base2 = link->io.BasePort1;
@@ -695,18 +655,14 @@ static int multi_config(struct pcmcia_device * link)
695 if (info->quirk && info->quirk->wakeup) 655 if (info->quirk && info->quirk->wakeup)
696 info->quirk->wakeup(link); 656 info->quirk->wakeup(link);
697 657
698 rc = 0; 658 return 0;
699 goto free_cfg_mem;
700 } 659 }
701 660
702 setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); 661 setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
703 for (i = 0; i < info->multi - 1; i++) 662 for (i = 0; i < info->multi - 1; i++)
704 setup_serial(link, info, base2 + (8 * i), 663 setup_serial(link, info, base2 + (8 * i),
705 link->irq.AssignedIRQ); 664 link->irq.AssignedIRQ);
706 rc = 0; 665 return 0;
707free_cfg_mem:
708 kfree(cfg_mem);
709 return rc;
710} 666}
711 667
712/*====================================================================== 668/*======================================================================
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index ff9a29b7633..347c3ed1d9f 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -124,65 +124,53 @@ static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
124 return; 124 return;
125} 125}
126 126
127static int ixj_config_check(struct pcmcia_device *p_dev,
128 cistpl_cftable_entry_t *cfg,
129 cistpl_cftable_entry_t *dflt,
130 unsigned int vcc,
131 void *priv_data)
132{
133 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
134 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
135 p_dev->io.BasePort1 = io->win[0].base;
136 p_dev->io.NumPorts1 = io->win[0].len;
137 if (io->nwin == 2) {
138 p_dev->io.BasePort2 = io->win[1].base;
139 p_dev->io.NumPorts2 = io->win[1].len;
140 }
141 if (!pcmcia_request_io(p_dev, &p_dev->io))
142 return 0;
143 }
144 return -ENODEV;
145}
146
127static int ixj_config(struct pcmcia_device * link) 147static int ixj_config(struct pcmcia_device * link)
128{ 148{
129 IXJ *j; 149 IXJ *j;
130 ixj_info_t *info; 150 ixj_info_t *info;
131 tuple_t tuple; 151 cistpl_cftable_entry_t dflt = { 0 };
132 u_short buf[128]; 152
133 cisparse_t parse;
134 cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
135 cistpl_cftable_entry_t dflt =
136 {
137 0
138 };
139 int last_ret, last_fn;
140 info = link->priv; 153 info = link->priv;
141 DEBUG(0, "ixj_config(0x%p)\n", link); 154 DEBUG(0, "ixj_config(0x%p)\n", link);
142 tuple.TupleData = (cisdata_t *) buf;
143 tuple.TupleOffset = 0;
144 tuple.TupleDataMax = 255;
145 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
146 tuple.Attributes = 0;
147 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
148 while (1) {
149 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
150 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
151 goto next_entry;
152 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
153 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
154 link->conf.ConfigIndex = cfg->index;
155 link->io.BasePort1 = io->win[0].base;
156 link->io.NumPorts1 = io->win[0].len;
157 if (io->nwin == 2) {
158 link->io.BasePort2 = io->win[1].base;
159 link->io.NumPorts2 = io->win[1].len;
160 }
161 if (pcmcia_request_io(link, &link->io) != 0)
162 goto next_entry;
163 /* If we've got this far, we're done */
164 break;
165 }
166 next_entry:
167 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
168 dflt = *cfg;
169 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
170 }
171 155
172 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 156 if (pcmcia_loop_config(link, ixj_config_check, &dflt))
157 goto cs_failed;
158
159 if (pcmcia_request_configuration(link, &link->conf))
160 goto cs_failed;
173 161
174 /* 162 /*
175 * Register the card with the core. 163 * Register the card with the core.
176 */ 164 */
177 j=ixj_pcmcia_probe(link->io.BasePort1,link->io.BasePort1 + 0x10); 165 j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10);
178 166
179 info->ndev = 1; 167 info->ndev = 1;
180 info->node.major = PHONE_MAJOR; 168 info->node.major = PHONE_MAJOR;
181 link->dev_node = &info->node; 169 link->dev_node = &info->node;
182 ixj_get_serial(link, j); 170 ixj_get_serial(link, j);
183 return 0; 171 return 0;
172
184 cs_failed: 173 cs_failed:
185 cs_error(link, last_fn, last_ret);
186 ixj_cs_release(link); 174 ixj_cs_release(link);
187 return -ENODEV; 175 return -ENODEV;
188} 176}
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 5da63f53500..ca733b7caea 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -155,97 +155,72 @@ static void sl811_cs_release(struct pcmcia_device * link)
155 platform_device_unregister(&platform_dev); 155 platform_device_unregister(&platform_dev);
156} 156}
157 157
158static int sl811_cs_config_check(struct pcmcia_device *p_dev,
159 cistpl_cftable_entry_t *cfg,
160 cistpl_cftable_entry_t *dflt,
161 unsigned int vcc,
162 void *priv_data)
163{
164 if (cfg->index == 0)
165 return -ENODEV;
166
167 /* Use power settings for Vcc and Vpp if present */
168 /* Note that the CIS values need to be rescaled */
169 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
170 if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc)
171 return -ENODEV;
172 } else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
173 if (dflt->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc)
174 return -ENODEV;
175 }
176
177 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
178 p_dev->conf.Vpp =
179 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
180 else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
181 p_dev->conf.Vpp =
182 dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
183
184 /* we need an interrupt */
185 if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
186 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
187
188 /* IO window settings */
189 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
190 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
191 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
192
193 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
194 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
195 p_dev->io.BasePort1 = io->win[0].base;
196 p_dev->io.NumPorts1 = io->win[0].len;
197
198 return pcmcia_request_io(p_dev, &p_dev->io);
199 }
200 pcmcia_disable_device(p_dev);
201 return -ENODEV;
202}
203
204
158static int sl811_cs_config(struct pcmcia_device *link) 205static int sl811_cs_config(struct pcmcia_device *link)
159{ 206{
160 struct device *parent = &handle_to_dev(link); 207 struct device *parent = &handle_to_dev(link);
161 local_info_t *dev = link->priv; 208 local_info_t *dev = link->priv;
162 tuple_t tuple;
163 cisparse_t parse;
164 int last_fn, last_ret; 209 int last_fn, last_ret;
165 u_char buf[64];
166 config_info_t conf;
167 cistpl_cftable_entry_t dflt = { 0 };
168 210
169 DBG(0, "sl811_cs_config(0x%p)\n", link); 211 DBG(0, "sl811_cs_config(0x%p)\n", link);
170 212
171 /* Look up the current Vcc */ 213 if (pcmcia_loop_config(link, sl811_cs_config_check, NULL))
172 CS_CHECK(GetConfigurationInfo, 214 goto failed;
173 pcmcia_get_configuration_info(link, &conf));
174
175 tuple.Attributes = 0;
176 tuple.TupleData = buf;
177 tuple.TupleDataMax = sizeof(buf);
178 tuple.TupleOffset = 0;
179 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
180 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
181 while (1) {
182 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
183
184 if (pcmcia_get_tuple_data(link, &tuple) != 0
185 || pcmcia_parse_tuple(link, &tuple, &parse)
186 != 0)
187 goto next_entry;
188
189 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) {
190 dflt = *cfg;
191 }
192
193 if (cfg->index == 0)
194 goto next_entry;
195
196 link->conf.ConfigIndex = cfg->index;
197
198 /* Use power settings for Vcc and Vpp if present */
199 /* Note that the CIS values need to be rescaled */
200 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
201 if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000
202 != conf.Vcc)
203 goto next_entry;
204 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
205 if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000
206 != conf.Vcc)
207 goto next_entry;
208 }
209
210 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
211 link->conf.Vpp =
212 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
213 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
214 link->conf.Vpp =
215 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
216
217 /* we need an interrupt */
218 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
219 link->conf.Attributes |= CONF_ENABLE_IRQ;
220
221 /* IO window settings */
222 link->io.NumPorts1 = link->io.NumPorts2 = 0;
223 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
224 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
225
226 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
227 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
228 link->io.BasePort1 = io->win[0].base;
229 link->io.NumPorts1 = io->win[0].len;
230
231 if (pcmcia_request_io(link, &link->io) != 0)
232 goto next_entry;
233 }
234 break;
235
236next_entry:
237 pcmcia_disable_device(link);
238 last_ret = pcmcia_get_next_tuple(link, &tuple);
239 }
240 215
241 /* require an IRQ and two registers */ 216 /* require an IRQ and two registers */
242 if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) 217 if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
243 goto cs_failed; 218 goto failed;
244 if (link->conf.Attributes & CONF_ENABLE_IRQ) 219 if (link->conf.Attributes & CONF_ENABLE_IRQ)
245 CS_CHECK(RequestIRQ, 220 CS_CHECK(RequestIRQ,
246 pcmcia_request_irq(link, &link->irq)); 221 pcmcia_request_irq(link, &link->irq));
247 else 222 else
248 goto cs_failed; 223 goto failed;
249 224
250 CS_CHECK(RequestConfiguration, 225 CS_CHECK(RequestConfiguration,
251 pcmcia_request_configuration(link, &link->conf)); 226 pcmcia_request_configuration(link, &link->conf));
@@ -266,8 +241,9 @@ next_entry:
266 if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) 241 if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
267 < 0) { 242 < 0) {
268cs_failed: 243cs_failed:
269 printk("sl811_cs_config failed\n");
270 cs_error(link, last_fn, last_ret); 244 cs_error(link, last_fn, last_ret);
245failed:
246 printk(KERN_WARNING "sl811_cs_config failed\n");
271 sl811_cs_release(link); 247 sl811_cs_release(link);
272 return -ENODEV; 248 return -ENODEV;
273 } 249 }
diff --git a/include/pcmcia/cistpl.h b/include/pcmcia/cistpl.h
index e2e10c1e9a0..75a9d34c634 100644
--- a/include/pcmcia/cistpl.h
+++ b/include/pcmcia/cistpl.h
@@ -580,14 +580,8 @@ typedef struct cisinfo_t {
580 580
581#define CISTPL_MAX_CIS_SIZE 0x200 581#define CISTPL_MAX_CIS_SIZE 0x200
582 582
583/* For ReplaceCIS */ 583int pcmcia_replace_cis(struct pcmcia_socket *s,
584typedef struct cisdump_t { 584 const u8 *data, const size_t len);
585 u_int Length;
586 cisdata_t Data[CISTPL_MAX_CIS_SIZE];
587} cisdump_t;
588
589
590int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis);
591 585
592/* don't use outside of PCMCIA core yet */ 586/* don't use outside of PCMCIA core yet */
593int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple); 587int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple);
@@ -613,4 +607,12 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
613#define pcmcia_validate_cis(p_dev, info) \ 607#define pcmcia_validate_cis(p_dev, info) \
614 pccard_validate_cis(p_dev->socket, p_dev->func, info) 608 pccard_validate_cis(p_dev->socket, p_dev->func, info)
615 609
610int pcmcia_loop_config(struct pcmcia_device *p_dev,
611 int (*conf_check) (struct pcmcia_device *p_dev,
612 cistpl_cftable_entry_t *cf,
613 cistpl_cftable_entry_t *dflt,
614 unsigned int vcc,
615 void *priv_data),
616 void *priv_data);
617
616#endif /* LINUX_CISTPL_H */ 618#endif /* LINUX_CISTPL_H */
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index b316027c853..2d36a4f80e5 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -68,6 +68,12 @@ typedef struct region_info_t {
68#define REGION_BAR_MASK 0xe000 68#define REGION_BAR_MASK 0xe000
69#define REGION_BAR_SHIFT 13 69#define REGION_BAR_SHIFT 13
70 70
71/* For ReplaceCIS */
72typedef struct cisdump_t {
73 u_int Length;
74 cisdata_t Data[CISTPL_MAX_CIS_SIZE];
75} cisdump_t;
76
71typedef union ds_ioctl_arg_t { 77typedef union ds_ioctl_arg_t {
72 adjust_t adjust; 78 adjust_t adjust;
73 config_info_t config; 79 config_info_t config;
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index ed919dd9bb5..e34bef0fc74 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -199,8 +199,8 @@ struct pcmcia_socket {
199 io_window_t io[MAX_IO_WIN]; 199 io_window_t io[MAX_IO_WIN];
200 window_t win[MAX_WIN]; 200 window_t win[MAX_WIN];
201 struct list_head cis_cache; 201 struct list_head cis_cache;
202 u_int fake_cis_len; 202 size_t fake_cis_len;
203 char *fake_cis; 203 u8 *fake_cis;
204 204
205 struct list_head socket_list; 205 struct list_head socket_list;
206 struct completion socket_released; 206 struct completion socket_released;