aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2008-07-29 02:38:55 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2008-08-22 19:21:29 -0400
commit84e2d34004dcd0c90d1af43a143511b334f11a4d (patch)
tree1872000f78edc7368d34ebf1211fd8c56d395143
parentb54bf94bf91e4ca2a489eb02bca0424ddb55242a (diff)
pcmcia: use pcmcia_loop_config in misc pcmcia drivers
Use the config loop helper in misc pcmcia drivers. CC: Harald Welte <laforge@gnumonks.org> CC: <linux-parport@lists.infradead.org> CC: Russell King <rmk+kernel@arm.linux.org.uk> CC: Ed Okerson <eokerson@quicknet.net> CC: linux-serial@vger.kernel.org CC: boti@rocketmail.com CC: linux-usb@vger.kernel.org Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c73
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c76
-rw-r--r--drivers/parport/parport_cs.c73
-rw-r--r--drivers/serial/serial_cs.c262
-rw-r--r--drivers/telephony/ixj_pcmcia.c76
-rw-r--r--drivers/usb/host/sl811_cs.c140
6 files changed, 299 insertions, 401 deletions
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index f070ae7bd91a..47adec480bd1 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 void *priv_data)
1765{
1766 p_dev->conf.ConfigIndex = cfg->index;
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 0b5934bef7a4..e0f5d8c9b266 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 void *priv_data)
530{ 532{
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; 533 int rc;
534 p_dev->conf.ConfigIndex = cfg->index;
535
536 if (!cfg->io.nwin)
537 return -ENODEV;
537 538
538 tuple.Attributes = 0; 539 /* Get the IOaddr */
539 tuple.TupleData = buf; 540 p_dev->io.BasePort1 = cfg->io.win[0].base;
540 tuple.TupleDataMax = sizeof(buf); 541 p_dev->io.NumPorts1 = cfg->io.win[0].len;
541 tuple.TupleOffset = 0; 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
555
556static int reader_config(struct pcmcia_device *link, int devno)
557{
558 struct reader_dev *dev;
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/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 00e1d9620f7c..636231739f4b 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -149,52 +149,49 @@ 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 void *priv_data)
155{
156 cistpl_cftable_entry_t *dflt = priv_data;
157 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
158 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
159 p_dev->conf.ConfigIndex = cfg->index;
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 goto next_entry;
171 return 0;
172 }
173
174next_entry:
175 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
176 *dflt = *cfg;
177 return -ENODEV;
178}
179
152static int parport_config(struct pcmcia_device *link) 180static int parport_config(struct pcmcia_device *link)
153{ 181{
154 parport_info_t *info = link->priv; 182 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 }; 183 cistpl_cftable_entry_t dflt = { 0 };
160 struct parport *p; 184 struct parport *p;
161 int last_ret, last_fn; 185 int last_ret, last_fn;
162 186
163 DEBUG(0, "parport_config(0x%p)\n", link); 187 DEBUG(0, "parport_config(0x%p)\n", link);
164 188
165 tuple.TupleData = (cisdata_t *)buf; 189 last_ret = pcmcia_loop_config(link, parport_config_check, &dflt);
166 tuple.TupleOffset = 0; tuple.TupleDataMax = 255; 190 if (last_ret) {
167 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 191 cs_error(link, RequestIO, last_ret);
168 tuple.Attributes = 0; 192 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 } 193 }
197 194
198 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 195 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
199 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 196 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
200 197
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 164d2a42eb59..ac60cd288418 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -439,43 +439,55 @@ 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 void *priv_data)
444{ 447{
445 int i; 448 static const int size_table[2] = { 8, 16 };
446 i = pcmcia_get_next_tuple(handle, tuple); 449 int *try = priv_data;
447 if (i != CS_SUCCESS) 450
448 return CS_NO_MORE_ITEMS; 451 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
449 i = pcmcia_get_tuple_data(handle, tuple); 452 p_dev->conf.Vpp =
450 if (i != CS_SUCCESS) 453 cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
451 return i; 454
452 return pcmcia_parse_tuple(handle, tuple, parse); 455 if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)])
456 && (cf->io.win[0].base != 0)) {
457 p_dev->conf.ConfigIndex = cf->index;
458 p_dev->io.BasePort1 = cf->io.win[0].base;
459 p_dev->io.IOAddrLines = ((*try & 0x1) == 0) ?
460 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
461 if (!pcmcia_request_io(p_dev, &p_dev->io))
462 return 0;
463 }
464 return -EINVAL;
453} 465}
454 466
455/*====================================================================*/ 467static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
468 cistpl_cftable_entry_t *cf,
469 void *priv_data)
470{
471 static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
472 int j;
473
474 if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
475 p_dev->conf.ConfigIndex = cf->index;
476 for (j = 0; j < 5; j++) {
477 p_dev->io.BasePort1 = base[j];
478 p_dev->io.IOAddrLines = base[j] ? 16 : 3;
479 if (!pcmcia_request_io(p_dev, &p_dev->io))
480 return 0;
481 }
482 }
483 return -ENODEV;
484}
456 485
457static int simple_config(struct pcmcia_device *link) 486static int simple_config(struct pcmcia_device *link)
458{ 487{
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; 488 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; 489 config_info_t config;
468 int i, j, try; 490 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 491
480 /* If the card is already configured, look up the port and irq */ 492 /* If the card is already configured, look up the port and irq */
481 i = pcmcia_get_configuration_info(link, &config); 493 i = pcmcia_get_configuration_info(link, &config);
@@ -490,70 +502,28 @@ static int simple_config(struct pcmcia_device *link)
490 info->slave = 1; 502 info->slave = 1;
491 } 503 }
492 if (info->slave) { 504 if (info->slave) {
493 kfree(cfg_mem);
494 return setup_serial(link, info, port, config.AssignedIRQ); 505 return setup_serial(link, info, port, config.AssignedIRQ);
495 } 506 }
496 } 507 }
497 508
498 /* First pass: look for a config entry that looks normal. */ 509 /* First pass: look for a config entry that looks normal.
499 tuple->TupleData = (cisdata_t *) buf; 510 * Two tries: without IO aliases, then with aliases */
500 tuple->TupleOffset = 0; 511 for (try = 0; try < 4; try++)
501 tuple->TupleDataMax = 255; 512 if (!pcmcia_loop_config(link, simple_config_check, &try))
502 tuple->Attributes = 0; 513 goto found_port;
503 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; 514
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 515 /* Second pass: try to find an entry that isn't picky about
530 its base address, then try to grab any standard serial port 516 its base address, then try to grab any standard serial port
531 address, and finally try to get any free port. */ 517 address, and finally try to get any free port. */
532 i = first_tuple(link, tuple, parse); 518 if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
533 while (i != CS_NO_MORE_ITEMS) { 519 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 520
548 found_port: 521 printk(KERN_NOTICE
549 if (i != CS_SUCCESS) { 522 "serial_cs: no usable port range found, giving up\n");
550 printk(KERN_NOTICE 523 cs_error(link, RequestIO, i);
551 "serial_cs: no usable port range found, giving up\n"); 524 return -1;
552 cs_error(link, RequestIO, i);
553 kfree(cfg_mem);
554 return -1;
555 }
556 525
526found_port:
557 i = pcmcia_request_irq(link, &link->irq); 527 i = pcmcia_request_irq(link, &link->irq);
558 if (i != CS_SUCCESS) { 528 if (i != CS_SUCCESS) {
559 cs_error(link, RequestIRQ, i); 529 cs_error(link, RequestIRQ, i);
@@ -571,86 +541,72 @@ next_entry:
571 i = pcmcia_request_configuration(link, &link->conf); 541 i = pcmcia_request_configuration(link, &link->conf);
572 if (i != CS_SUCCESS) { 542 if (i != CS_SUCCESS) {
573 cs_error(link, RequestConfiguration, i); 543 cs_error(link, RequestConfiguration, i);
574 kfree(cfg_mem);
575 return -1; 544 return -1;
576 } 545 }
577 kfree(cfg_mem);
578 return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); 546 return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
579} 547}
580 548
581static int multi_config(struct pcmcia_device * link) 549static int multi_config_check(struct pcmcia_device *p_dev,
550 cistpl_cftable_entry_t *cf,
551 void *priv_data)
582{ 552{
583 struct serial_info *info = link->priv; 553 int *base2 = priv_data;
584 struct serial_cfg_mem *cfg_mem; 554
585 tuple_t *tuple; 555 /* The quad port cards have bad CIS's, so just look for a
586 u_char *buf; 556 window larger than 8 ports and assume it will be right */
587 cisparse_t *parse; 557 if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
588 cistpl_cftable_entry_t *cf; 558 p_dev->conf.ConfigIndex = cf->index;
589 int i, rc, base2 = 0; 559 p_dev->io.BasePort1 = cf->io.win[0].base;
560 p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
561 if (!pcmcia_request_io(p_dev, &p_dev->io)) {
562 *base2 = p_dev->io.BasePort1 + 8;
563 return 0;
564 }
565 }
566 return -ENODEV;
567}
590 568
591 cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); 569static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
592 if (!cfg_mem) 570 cistpl_cftable_entry_t *cf,
593 return -1; 571 void *priv_data)
594 tuple = &cfg_mem->tuple; 572{
595 parse = &cfg_mem->parse; 573 int *base2 = priv_data;
596 cf = &parse->cftable_entry; 574
597 buf = cfg_mem->buf; 575 if (cf->io.nwin == 2) {
576 p_dev->conf.ConfigIndex = cf->index;
577 p_dev->io.BasePort1 = cf->io.win[0].base;
578 p_dev->io.BasePort2 = cf->io.win[1].base;
579 p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
580 if (!pcmcia_request_io(p_dev, &p_dev->io)) {
581 *base2 = p_dev->io.BasePort2;
582 return 0;
583 }
584 }
585 return -ENODEV;
586}
598 587
599 tuple->TupleData = (cisdata_t *) buf; 588static int multi_config(struct pcmcia_device *link)
600 tuple->TupleOffset = 0; 589{
601 tuple->TupleDataMax = 255; 590 struct serial_info *info = link->priv;
602 tuple->Attributes = 0; 591 int i, base2 = 0;
603 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
604 592
605 /* First, look for a generic full-sized window */ 593 /* First, look for a generic full-sized window */
606 link->io.NumPorts1 = info->multi * 8; 594 link->io.NumPorts1 = info->multi * 8;
607 i = first_tuple(link, tuple, parse); 595 if (pcmcia_loop_config(link, multi_config_check, &base2)) {
608 while (i != CS_NO_MORE_ITEMS) { 596 /* 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; 597 link->io.NumPorts1 = link->io.NumPorts2 = 8;
628 info->multi = 2; 598 info->multi = 2;
629 i = first_tuple(link, tuple, parse); 599 if (pcmcia_loop_config(link, multi_config_check_notpicky,
630 while (i != CS_NO_MORE_ITEMS) { 600 &base2)) {
631 if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { 601 printk(KERN_NOTICE "serial_cs: no usable port range"
632 link->conf.ConfigIndex = cf->index; 602 "found, giving up\n");
633 link->io.BasePort1 = cf->io.win[0].base; 603 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 } 604 }
644 } 605 }
645 606
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); 607 i = pcmcia_request_irq(link, &link->irq);
653 if (i != CS_SUCCESS) { 608 if (i != CS_SUCCESS) {
609 /* FIXME: comment does not fit, error handling does not fit */
654 printk(KERN_NOTICE 610 printk(KERN_NOTICE
655 "serial_cs: no usable port range found, giving up\n"); 611 "serial_cs: no usable port range found, giving up\n");
656 cs_error(link, RequestIRQ, i); 612 cs_error(link, RequestIRQ, i);
@@ -666,8 +622,7 @@ static int multi_config(struct pcmcia_device * link)
666 i = pcmcia_request_configuration(link, &link->conf); 622 i = pcmcia_request_configuration(link, &link->conf);
667 if (i != CS_SUCCESS) { 623 if (i != CS_SUCCESS) {
668 cs_error(link, RequestConfiguration, i); 624 cs_error(link, RequestConfiguration, i);
669 rc = -1; 625 return -ENODEV;
670 goto free_cfg_mem;
671 } 626 }
672 627
673 /* The Oxford Semiconductor OXCF950 cards are in fact single-port: 628 /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
@@ -678,7 +633,8 @@ static int multi_config(struct pcmcia_device * link)
678 info->prodid == PRODID_POSSIO_GCC)) { 633 info->prodid == PRODID_POSSIO_GCC)) {
679 int err; 634 int err;
680 635
681 if (cf->index == 1 || cf->index == 3) { 636 if (link->conf.ConfigIndex == 1 ||
637 link->conf.ConfigIndex == 3) {
682 err = setup_serial(link, info, base2, 638 err = setup_serial(link, info, base2,
683 link->irq.AssignedIRQ); 639 link->irq.AssignedIRQ);
684 base2 = link->io.BasePort1; 640 base2 = link->io.BasePort1;
@@ -695,18 +651,14 @@ static int multi_config(struct pcmcia_device * link)
695 if (info->quirk && info->quirk->wakeup) 651 if (info->quirk && info->quirk->wakeup)
696 info->quirk->wakeup(link); 652 info->quirk->wakeup(link);
697 653
698 rc = 0; 654 return 0;
699 goto free_cfg_mem;
700 } 655 }
701 656
702 setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); 657 setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
703 for (i = 0; i < info->multi - 1; i++) 658 for (i = 0; i < info->multi - 1; i++)
704 setup_serial(link, info, base2 + (8 * i), 659 setup_serial(link, info, base2 + (8 * i),
705 link->irq.AssignedIRQ); 660 link->irq.AssignedIRQ);
706 rc = 0; 661 return 0;
707free_cfg_mem:
708 kfree(cfg_mem);
709 return rc;
710} 662}
711 663
712/*====================================================================== 664/*======================================================================
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index ff9a29b76336..89c5e40ce3a0 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -124,65 +124,57 @@ 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 void *priv_data)
130{
131 cistpl_cftable_entry_t *dflt = 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->conf.ConfigIndex = cfg->index;
136 p_dev->io.BasePort1 = io->win[0].base;
137 p_dev->io.NumPorts1 = io->win[0].len;
138 if (io->nwin == 2) {
139 p_dev->io.BasePort2 = io->win[1].base;
140 p_dev->io.NumPorts2 = io->win[1].len;
141 }
142 if (pcmcia_request_io(p_dev, &p_dev->io)) {
143 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
144 *dflt = *cfg;
145 } else
146 return 0;
147 }
148 return -ENODEV;
149}
150
127static int ixj_config(struct pcmcia_device * link) 151static int ixj_config(struct pcmcia_device * link)
128{ 152{
129 IXJ *j; 153 IXJ *j;
130 ixj_info_t *info; 154 ixj_info_t *info;
131 tuple_t tuple; 155 cistpl_cftable_entry_t dflt = { 0 };
132 u_short buf[128]; 156
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; 157 info = link->priv;
141 DEBUG(0, "ixj_config(0x%p)\n", link); 158 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 159
172 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 160 if (pcmcia_loop_config(link, ixj_config_check, &dflt))
161 goto cs_failed;
162
163 if (pcmcia_request_configuration(link, &link->conf))
164 goto cs_failed;
173 165
174 /* 166 /*
175 * Register the card with the core. 167 * Register the card with the core.
176 */ 168 */
177 j=ixj_pcmcia_probe(link->io.BasePort1,link->io.BasePort1 + 0x10); 169 j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10);
178 170
179 info->ndev = 1; 171 info->ndev = 1;
180 info->node.major = PHONE_MAJOR; 172 info->node.major = PHONE_MAJOR;
181 link->dev_node = &info->node; 173 link->dev_node = &info->node;
182 ixj_get_serial(link, j); 174 ixj_get_serial(link, j);
183 return 0; 175 return 0;
176
184 cs_failed: 177 cs_failed:
185 cs_error(link, last_fn, last_ret);
186 ixj_cs_release(link); 178 ixj_cs_release(link);
187 return -ENODEV; 179 return -ENODEV;
188} 180}
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 5da63f535005..9773601bf0bb 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -155,88 +155,84 @@ 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
158struct sl811_css_cfg {
159 cistpl_cftable_entry_t dflt;
160 config_info_t conf;
161};
162
163static int sl811_cs_config_check(struct pcmcia_device *p_dev,
164 cistpl_cftable_entry_t *cfg,
165 void *priv_data)
166{
167 struct sl811_css_cfg *cfg_mem = priv_data;
168
169 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
170 memcpy(&cfg_mem->dflt, cfg, sizeof(cistpl_cftable_entry_t));
171
172 if (cfg->index == 0)
173 return -ENODEV;
174
175 p_dev->conf.ConfigIndex = cfg->index;
176
177 /* Use power settings for Vcc and Vpp if present */
178 /* Note that the CIS values need to be rescaled */
179 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
180 if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 !=
181 cfg_mem->conf.Vcc)
182 return -ENODEV;
183 } else if (cfg_mem->dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
184 if (cfg_mem->dflt.vcc.param[CISTPL_POWER_VNOM]/10000
185 != cfg_mem->conf.Vcc)
186 return -ENODEV;
187 }
188
189 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
190 p_dev->conf.Vpp =
191 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
192 else if (cfg_mem->dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
193 p_dev->conf.Vpp =
194 cfg_mem->dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
195
196 /* we need an interrupt */
197 if (cfg->irq.IRQInfo1 || cfg_mem->dflt.irq.IRQInfo1)
198 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
199
200 /* IO window settings */
201 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
202 if ((cfg->io.nwin > 0) || (cfg_mem->dflt.io.nwin > 0)) {
203 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &cfg_mem->dflt.io;
204
205 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
206 p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
207 p_dev->io.BasePort1 = io->win[0].base;
208 p_dev->io.NumPorts1 = io->win[0].len;
209
210 return pcmcia_request_io(p_dev, &p_dev->io);
211 }
212 pcmcia_disable_device(p_dev);
213 return -ENODEV;
214}
215
216
158static int sl811_cs_config(struct pcmcia_device *link) 217static int sl811_cs_config(struct pcmcia_device *link)
159{ 218{
160 struct device *parent = &handle_to_dev(link); 219 struct device *parent = &handle_to_dev(link);
161 local_info_t *dev = link->priv; 220 local_info_t *dev = link->priv;
162 tuple_t tuple;
163 cisparse_t parse;
164 int last_fn, last_ret; 221 int last_fn, last_ret;
165 u_char buf[64]; 222 struct sl811_css_cfg *cfg_mem;
166 config_info_t conf;
167 cistpl_cftable_entry_t dflt = { 0 };
168 223
169 DBG(0, "sl811_cs_config(0x%p)\n", link); 224 DBG(0, "sl811_cs_config(0x%p)\n", link);
170 225
226 cfg_mem = kzalloc(sizeof(struct sl811_css_cfg), GFP_KERNEL);
227 if (!cfg_mem)
228 return -ENOMEM;
229
171 /* Look up the current Vcc */ 230 /* Look up the current Vcc */
172 CS_CHECK(GetConfigurationInfo, 231 CS_CHECK(GetConfigurationInfo,
173 pcmcia_get_configuration_info(link, &conf)); 232 pcmcia_get_configuration_info(link, &cfg_mem->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 233
193 if (cfg->index == 0) 234 if (pcmcia_loop_config(link, sl811_cs_config_check, cfg_mem))
194 goto next_entry; 235 return -ENODEV;
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 236
241 /* require an IRQ and two registers */ 237 /* require an IRQ and two registers */
242 if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) 238 if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
@@ -269,8 +265,10 @@ cs_failed:
269 printk("sl811_cs_config failed\n"); 265 printk("sl811_cs_config failed\n");
270 cs_error(link, last_fn, last_ret); 266 cs_error(link, last_fn, last_ret);
271 sl811_cs_release(link); 267 sl811_cs_release(link);
268 kfree(cfg_mem);
272 return -ENODEV; 269 return -ENODEV;
273 } 270 }
271 kfree(cfg_mem);
274 return 0; 272 return 0;
275} 273}
276 274