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.c119
1 files changed, 47 insertions, 72 deletions
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 593b7c595038..6ec366f1cf74 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -678,93 +678,68 @@ 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 void *priv_data)
682{ 684{
683 int i; 685 unsigned long try = (unsigned long) priv_data;
684 686
685 i = pcmcia_get_tuple_data(handle, tuple); 687 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
686 if (i != CS_SUCCESS) 688 p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
687 return i; 689 if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
688 690 (cf->io.win[0].base != 0)) {
689 return pcmcia_parse_tuple(handle, tuple, parse); 691 p_dev->conf.ConfigIndex = cf->index;
690} 692 p_dev->io.BasePort1 = cf->io.win[0].base;
691 693 p_dev->io.IOAddrLines = (try == 0) ? 16 :
692static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) 694 cf->io.flags & CISTPL_IO_LINES_MASK;
693{ 695 if (!pcmcia_request_io(p_dev, &p_dev->io))
694 if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) 696 return 0;
695 return CS_NO_MORE_ITEMS; 697 }
696 return get_tuple(handle, tuple, parse); 698 return -ENODEV;
697} 699}
698 700
699static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) 701static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
702 cistpl_cftable_entry_t *cf,
703 void *priv_data)
700{ 704{
701 if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) 705 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
702 return CS_NO_MORE_ITEMS; 706 int j;
703 return get_tuple(handle, tuple, parse); 707
708 if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
709 p_dev->conf.ConfigIndex = cf->index;
710 for (j = 0; j < 5; j++) {
711 p_dev->io.BasePort1 = base[j];
712 p_dev->io.IOAddrLines = base[j] ? 16 : 3;
713 if (!pcmcia_request_io(p_dev, &p_dev->io))
714 return 0;
715 }
716 }
717 return -ENODEV;
704} 718}
705 719
706static int bt3c_config(struct pcmcia_device *link) 720static int bt3c_config(struct pcmcia_device *link)
707{ 721{
708 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
709 bt3c_info_t *info = link->priv; 722 bt3c_info_t *info = link->priv;
710 tuple_t tuple; 723 int i;
711 u_short buf[256]; 724 unsigned long try;
712 cisparse_t parse; 725
713 cistpl_cftable_entry_t *cf = &parse.cftable_entry; 726 /* First pass: look for a config entry that looks normal.
714 int i, j, try; 727 Two tries: without IO aliases, then with aliases */
715 728 for (try = 0; try < 2; try++)
716 /* First pass: look for a config entry that looks normal. */ 729 if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
717 tuple.TupleData = (cisdata_t *)buf; 730 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 731
743 /* Second pass: try to find an entry that isn't picky about 732 /* Second pass: try to find an entry that isn't picky about
744 its base address, then try to grab any standard serial port 733 its base address, then try to grab any standard serial port
745 address, and finally try to get any free port. */ 734 address, and finally try to get any free port. */
746 i = first_tuple(link, &tuple, &parse); 735 if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
747 while (i != CS_NO_MORE_ITEMS) { 736 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 737
761found_port: 738 BT_ERR("No usable port range found");
762 if (i != CS_SUCCESS) { 739 cs_error(link, RequestIO, -ENODEV);
763 BT_ERR("No usable port range found"); 740 goto failed;
764 cs_error(link, RequestIO, i);
765 goto failed;
766 }
767 741
742found_port:
768 i = pcmcia_request_irq(link, &link->irq); 743 i = pcmcia_request_irq(link, &link->irq);
769 if (i != CS_SUCCESS) { 744 if (i != CS_SUCCESS) {
770 cs_error(link, RequestIRQ, i); 745 cs_error(link, RequestIRQ, i);