aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/bt3c_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/bt3c_cs.c')
-rw-r--r--drivers/bluetooth/bt3c_cs.c125
1 files changed, 51 insertions, 74 deletions
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 27058477cc8b..2cbe70b66470 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -678,101 +678,78 @@ 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 != 0) {
770 cs_error(link, RequestIRQ, i); 747 cs_error(link, RequestIRQ, i);
771 link->irq.AssignedIRQ = 0; 748 link->irq.AssignedIRQ = 0;
772 } 749 }
773 750
774 i = pcmcia_request_configuration(link, &link->conf); 751 i = pcmcia_request_configuration(link, &link->conf);
775 if (i != CS_SUCCESS) { 752 if (i != 0) {
776 cs_error(link, RequestConfiguration, i); 753 cs_error(link, RequestConfiguration, i);
777 goto failed; 754 goto failed;
778 } 755 }