diff options
Diffstat (limited to 'drivers/bluetooth/btuart_cs.c')
-rw-r--r-- | drivers/bluetooth/btuart_cs.c | 130 |
1 files changed, 40 insertions, 90 deletions
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 7b4bff4cfa2d..9ce4c93467e5 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c | |||
@@ -68,7 +68,7 @@ MODULE_LICENSE("GPL"); | |||
68 | 68 | ||
69 | 69 | ||
70 | typedef struct btuart_info_t { | 70 | typedef struct btuart_info_t { |
71 | dev_link_t link; | 71 | struct pcmcia_device *p_dev; |
72 | dev_node_t node; | 72 | dev_node_t node; |
73 | 73 | ||
74 | struct hci_dev *hdev; | 74 | struct hci_dev *hdev; |
@@ -84,8 +84,8 @@ typedef struct btuart_info_t { | |||
84 | } btuart_info_t; | 84 | } btuart_info_t; |
85 | 85 | ||
86 | 86 | ||
87 | static void btuart_config(dev_link_t *link); | 87 | static int btuart_config(struct pcmcia_device *link); |
88 | static void btuart_release(dev_link_t *link); | 88 | static void btuart_release(struct pcmcia_device *link); |
89 | 89 | ||
90 | static void btuart_detach(struct pcmcia_device *p_dev); | 90 | static void btuart_detach(struct pcmcia_device *p_dev); |
91 | 91 | ||
@@ -146,13 +146,13 @@ static void btuart_write_wakeup(btuart_info_t *info) | |||
146 | } | 146 | } |
147 | 147 | ||
148 | do { | 148 | do { |
149 | register unsigned int iobase = info->link.io.BasePort1; | 149 | register unsigned int iobase = info->p_dev->io.BasePort1; |
150 | register struct sk_buff *skb; | 150 | register struct sk_buff *skb; |
151 | register int len; | 151 | register int len; |
152 | 152 | ||
153 | clear_bit(XMIT_WAKEUP, &(info->tx_state)); | 153 | clear_bit(XMIT_WAKEUP, &(info->tx_state)); |
154 | 154 | ||
155 | if (!(info->link.state & DEV_PRESENT)) | 155 | if (!pcmcia_dev_present(info->p_dev)) |
156 | return; | 156 | return; |
157 | 157 | ||
158 | if (!(skb = skb_dequeue(&(info->txq)))) | 158 | if (!(skb = skb_dequeue(&(info->txq)))) |
@@ -187,7 +187,7 @@ static void btuart_receive(btuart_info_t *info) | |||
187 | return; | 187 | return; |
188 | } | 188 | } |
189 | 189 | ||
190 | iobase = info->link.io.BasePort1; | 190 | iobase = info->p_dev->io.BasePort1; |
191 | 191 | ||
192 | do { | 192 | do { |
193 | info->hdev->stat.byte_rx++; | 193 | info->hdev->stat.byte_rx++; |
@@ -301,7 +301,7 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst, struct pt_regs *reg | |||
301 | return IRQ_NONE; | 301 | return IRQ_NONE; |
302 | } | 302 | } |
303 | 303 | ||
304 | iobase = info->link.io.BasePort1; | 304 | iobase = info->p_dev->io.BasePort1; |
305 | 305 | ||
306 | spin_lock(&(info->lock)); | 306 | spin_lock(&(info->lock)); |
307 | 307 | ||
@@ -357,7 +357,7 @@ static void btuart_change_speed(btuart_info_t *info, unsigned int speed) | |||
357 | return; | 357 | return; |
358 | } | 358 | } |
359 | 359 | ||
360 | iobase = info->link.io.BasePort1; | 360 | iobase = info->p_dev->io.BasePort1; |
361 | 361 | ||
362 | spin_lock_irqsave(&(info->lock), flags); | 362 | spin_lock_irqsave(&(info->lock), flags); |
363 | 363 | ||
@@ -481,7 +481,7 @@ static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned lon | |||
481 | static int btuart_open(btuart_info_t *info) | 481 | static int btuart_open(btuart_info_t *info) |
482 | { | 482 | { |
483 | unsigned long flags; | 483 | unsigned long flags; |
484 | unsigned int iobase = info->link.io.BasePort1; | 484 | unsigned int iobase = info->p_dev->io.BasePort1; |
485 | struct hci_dev *hdev; | 485 | struct hci_dev *hdev; |
486 | 486 | ||
487 | spin_lock_init(&(info->lock)); | 487 | spin_lock_init(&(info->lock)); |
@@ -550,7 +550,7 @@ static int btuart_open(btuart_info_t *info) | |||
550 | static int btuart_close(btuart_info_t *info) | 550 | static int btuart_close(btuart_info_t *info) |
551 | { | 551 | { |
552 | unsigned long flags; | 552 | unsigned long flags; |
553 | unsigned int iobase = info->link.io.BasePort1; | 553 | unsigned int iobase = info->p_dev->io.BasePort1; |
554 | struct hci_dev *hdev = info->hdev; | 554 | struct hci_dev *hdev = info->hdev; |
555 | 555 | ||
556 | if (!hdev) | 556 | if (!hdev) |
@@ -576,17 +576,16 @@ static int btuart_close(btuart_info_t *info) | |||
576 | return 0; | 576 | return 0; |
577 | } | 577 | } |
578 | 578 | ||
579 | static int btuart_attach(struct pcmcia_device *p_dev) | 579 | static int btuart_probe(struct pcmcia_device *link) |
580 | { | 580 | { |
581 | btuart_info_t *info; | 581 | btuart_info_t *info; |
582 | dev_link_t *link; | ||
583 | 582 | ||
584 | /* Create new info device */ | 583 | /* Create new info device */ |
585 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 584 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
586 | if (!info) | 585 | if (!info) |
587 | return -ENOMEM; | 586 | return -ENOMEM; |
588 | 587 | ||
589 | link = &info->link; | 588 | info->p_dev = link; |
590 | link->priv = info; | 589 | link->priv = info; |
591 | 590 | ||
592 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 591 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
@@ -598,31 +597,21 @@ static int btuart_attach(struct pcmcia_device *p_dev) | |||
598 | link->irq.Instance = info; | 597 | link->irq.Instance = info; |
599 | 598 | ||
600 | link->conf.Attributes = CONF_ENABLE_IRQ; | 599 | link->conf.Attributes = CONF_ENABLE_IRQ; |
601 | link->conf.Vcc = 50; | ||
602 | link->conf.IntType = INT_MEMORY_AND_IO; | 600 | link->conf.IntType = INT_MEMORY_AND_IO; |
603 | 601 | ||
604 | link->handle = p_dev; | 602 | return btuart_config(link); |
605 | p_dev->instance = link; | ||
606 | |||
607 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
608 | btuart_config(link); | ||
609 | |||
610 | return 0; | ||
611 | } | 603 | } |
612 | 604 | ||
613 | 605 | ||
614 | static void btuart_detach(struct pcmcia_device *p_dev) | 606 | static void btuart_detach(struct pcmcia_device *link) |
615 | { | 607 | { |
616 | dev_link_t *link = dev_to_instance(p_dev); | ||
617 | btuart_info_t *info = link->priv; | 608 | btuart_info_t *info = link->priv; |
618 | 609 | ||
619 | if (link->state & DEV_CONFIG) | 610 | btuart_release(link); |
620 | btuart_release(link); | ||
621 | |||
622 | kfree(info); | 611 | kfree(info); |
623 | } | 612 | } |
624 | 613 | ||
625 | static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | 614 | static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) |
626 | { | 615 | { |
627 | int i; | 616 | int i; |
628 | 617 | ||
@@ -633,30 +622,28 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | |||
633 | return pcmcia_parse_tuple(handle, tuple, parse); | 622 | return pcmcia_parse_tuple(handle, tuple, parse); |
634 | } | 623 | } |
635 | 624 | ||
636 | static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | 625 | static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) |
637 | { | 626 | { |
638 | if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) | 627 | if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) |
639 | return CS_NO_MORE_ITEMS; | 628 | return CS_NO_MORE_ITEMS; |
640 | return get_tuple(handle, tuple, parse); | 629 | return get_tuple(handle, tuple, parse); |
641 | } | 630 | } |
642 | 631 | ||
643 | static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | 632 | static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) |
644 | { | 633 | { |
645 | if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) | 634 | if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) |
646 | return CS_NO_MORE_ITEMS; | 635 | return CS_NO_MORE_ITEMS; |
647 | return get_tuple(handle, tuple, parse); | 636 | return get_tuple(handle, tuple, parse); |
648 | } | 637 | } |
649 | 638 | ||
650 | static void btuart_config(dev_link_t *link) | 639 | static int btuart_config(struct pcmcia_device *link) |
651 | { | 640 | { |
652 | static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; | 641 | static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; |
653 | client_handle_t handle = link->handle; | ||
654 | btuart_info_t *info = link->priv; | 642 | btuart_info_t *info = link->priv; |
655 | tuple_t tuple; | 643 | tuple_t tuple; |
656 | u_short buf[256]; | 644 | u_short buf[256]; |
657 | cisparse_t parse; | 645 | cisparse_t parse; |
658 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 646 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; |
659 | config_info_t config; | ||
660 | int i, j, try, last_ret, last_fn; | 647 | int i, j, try, last_ret, last_fn; |
661 | 648 | ||
662 | tuple.TupleData = (cisdata_t *)buf; | 649 | tuple.TupleData = (cisdata_t *)buf; |
@@ -666,7 +653,7 @@ static void btuart_config(dev_link_t *link) | |||
666 | 653 | ||
667 | /* Get configuration register information */ | 654 | /* Get configuration register information */ |
668 | tuple.DesiredTuple = CISTPL_CONFIG; | 655 | tuple.DesiredTuple = CISTPL_CONFIG; |
669 | last_ret = first_tuple(handle, &tuple, &parse); | 656 | last_ret = first_tuple(link, &tuple, &parse); |
670 | if (last_ret != CS_SUCCESS) { | 657 | if (last_ret != CS_SUCCESS) { |
671 | last_fn = ParseTuple; | 658 | last_fn = ParseTuple; |
672 | goto cs_failed; | 659 | goto cs_failed; |
@@ -674,11 +661,6 @@ static void btuart_config(dev_link_t *link) | |||
674 | link->conf.ConfigBase = parse.config.base; | 661 | link->conf.ConfigBase = parse.config.base; |
675 | link->conf.Present = parse.config.rmask[0]; | 662 | link->conf.Present = parse.config.rmask[0]; |
676 | 663 | ||
677 | /* Configure card */ | ||
678 | link->state |= DEV_CONFIG; | ||
679 | i = pcmcia_get_configuration_info(handle, &config); | ||
680 | link->conf.Vcc = config.Vcc; | ||
681 | |||
682 | /* First pass: look for a config entry that looks normal. */ | 664 | /* First pass: look for a config entry that looks normal. */ |
683 | tuple.TupleData = (cisdata_t *) buf; | 665 | tuple.TupleData = (cisdata_t *) buf; |
684 | tuple.TupleOffset = 0; | 666 | tuple.TupleOffset = 0; |
@@ -687,29 +669,29 @@ static void btuart_config(dev_link_t *link) | |||
687 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 669 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
688 | /* Two tries: without IO aliases, then with aliases */ | 670 | /* Two tries: without IO aliases, then with aliases */ |
689 | for (try = 0; try < 2; try++) { | 671 | for (try = 0; try < 2; try++) { |
690 | i = first_tuple(handle, &tuple, &parse); | 672 | i = first_tuple(link, &tuple, &parse); |
691 | while (i != CS_NO_MORE_ITEMS) { | 673 | while (i != CS_NO_MORE_ITEMS) { |
692 | if (i != CS_SUCCESS) | 674 | if (i != CS_SUCCESS) |
693 | goto next_entry; | 675 | goto next_entry; |
694 | if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) | 676 | if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) |
695 | link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; | 677 | link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; |
696 | if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { | 678 | if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { |
697 | link->conf.ConfigIndex = cf->index; | 679 | link->conf.ConfigIndex = cf->index; |
698 | link->io.BasePort1 = cf->io.win[0].base; | 680 | link->io.BasePort1 = cf->io.win[0].base; |
699 | link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; | 681 | link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; |
700 | i = pcmcia_request_io(link->handle, &link->io); | 682 | i = pcmcia_request_io(link, &link->io); |
701 | if (i == CS_SUCCESS) | 683 | if (i == CS_SUCCESS) |
702 | goto found_port; | 684 | goto found_port; |
703 | } | 685 | } |
704 | next_entry: | 686 | next_entry: |
705 | i = next_tuple(handle, &tuple, &parse); | 687 | i = next_tuple(link, &tuple, &parse); |
706 | } | 688 | } |
707 | } | 689 | } |
708 | 690 | ||
709 | /* Second pass: try to find an entry that isn't picky about | 691 | /* Second pass: try to find an entry that isn't picky about |
710 | its base address, then try to grab any standard serial port | 692 | its base address, then try to grab any standard serial port |
711 | address, and finally try to get any free port. */ | 693 | address, and finally try to get any free port. */ |
712 | i = first_tuple(handle, &tuple, &parse); | 694 | i = first_tuple(link, &tuple, &parse); |
713 | while (i != CS_NO_MORE_ITEMS) { | 695 | while (i != CS_NO_MORE_ITEMS) { |
714 | if ((i == CS_SUCCESS) && (cf->io.nwin > 0) | 696 | if ((i == CS_SUCCESS) && (cf->io.nwin > 0) |
715 | && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { | 697 | && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { |
@@ -717,30 +699,30 @@ next_entry: | |||
717 | for (j = 0; j < 5; j++) { | 699 | for (j = 0; j < 5; j++) { |
718 | link->io.BasePort1 = base[j]; | 700 | link->io.BasePort1 = base[j]; |
719 | link->io.IOAddrLines = base[j] ? 16 : 3; | 701 | link->io.IOAddrLines = base[j] ? 16 : 3; |
720 | i = pcmcia_request_io(link->handle, &link->io); | 702 | i = pcmcia_request_io(link, &link->io); |
721 | if (i == CS_SUCCESS) | 703 | if (i == CS_SUCCESS) |
722 | goto found_port; | 704 | goto found_port; |
723 | } | 705 | } |
724 | } | 706 | } |
725 | i = next_tuple(handle, &tuple, &parse); | 707 | i = next_tuple(link, &tuple, &parse); |
726 | } | 708 | } |
727 | 709 | ||
728 | found_port: | 710 | found_port: |
729 | if (i != CS_SUCCESS) { | 711 | if (i != CS_SUCCESS) { |
730 | BT_ERR("No usable port range found"); | 712 | BT_ERR("No usable port range found"); |
731 | cs_error(link->handle, RequestIO, i); | 713 | cs_error(link, RequestIO, i); |
732 | goto failed; | 714 | goto failed; |
733 | } | 715 | } |
734 | 716 | ||
735 | i = pcmcia_request_irq(link->handle, &link->irq); | 717 | i = pcmcia_request_irq(link, &link->irq); |
736 | if (i != CS_SUCCESS) { | 718 | if (i != CS_SUCCESS) { |
737 | cs_error(link->handle, RequestIRQ, i); | 719 | cs_error(link, RequestIRQ, i); |
738 | link->irq.AssignedIRQ = 0; | 720 | link->irq.AssignedIRQ = 0; |
739 | } | 721 | } |
740 | 722 | ||
741 | i = pcmcia_request_configuration(link->handle, &link->conf); | 723 | i = pcmcia_request_configuration(link, &link->conf); |
742 | if (i != CS_SUCCESS) { | 724 | if (i != CS_SUCCESS) { |
743 | cs_error(link->handle, RequestConfiguration, i); | 725 | cs_error(link, RequestConfiguration, i); |
744 | goto failed; | 726 | goto failed; |
745 | } | 727 | } |
746 | 728 | ||
@@ -748,58 +730,28 @@ found_port: | |||
748 | goto failed; | 730 | goto failed; |
749 | 731 | ||
750 | strcpy(info->node.dev_name, info->hdev->name); | 732 | strcpy(info->node.dev_name, info->hdev->name); |
751 | link->dev = &info->node; | 733 | link->dev_node = &info->node; |
752 | link->state &= ~DEV_CONFIG_PENDING; | ||
753 | 734 | ||
754 | return; | 735 | return 0; |
755 | 736 | ||
756 | cs_failed: | 737 | cs_failed: |
757 | cs_error(link->handle, last_fn, last_ret); | 738 | cs_error(link, last_fn, last_ret); |
758 | 739 | ||
759 | failed: | 740 | failed: |
760 | btuart_release(link); | 741 | btuart_release(link); |
742 | return -ENODEV; | ||
761 | } | 743 | } |
762 | 744 | ||
763 | 745 | ||
764 | static void btuart_release(dev_link_t *link) | 746 | static void btuart_release(struct pcmcia_device *link) |
765 | { | 747 | { |
766 | btuart_info_t *info = link->priv; | 748 | btuart_info_t *info = link->priv; |
767 | 749 | ||
768 | if (link->state & DEV_PRESENT) | 750 | btuart_close(info); |
769 | btuart_close(info); | ||
770 | |||
771 | link->dev = NULL; | ||
772 | |||
773 | pcmcia_release_configuration(link->handle); | ||
774 | pcmcia_release_io(link->handle, &link->io); | ||
775 | pcmcia_release_irq(link->handle, &link->irq); | ||
776 | |||
777 | link->state &= ~DEV_CONFIG; | ||
778 | } | ||
779 | |||
780 | static int btuart_suspend(struct pcmcia_device *dev) | ||
781 | { | ||
782 | dev_link_t *link = dev_to_instance(dev); | ||
783 | |||
784 | link->state |= DEV_SUSPEND; | ||
785 | if (link->state & DEV_CONFIG) | ||
786 | pcmcia_release_configuration(link->handle); | ||
787 | 751 | ||
788 | return 0; | 752 | pcmcia_disable_device(link); |
789 | } | 753 | } |
790 | 754 | ||
791 | static int btuart_resume(struct pcmcia_device *dev) | ||
792 | { | ||
793 | dev_link_t *link = dev_to_instance(dev); | ||
794 | |||
795 | link->state &= ~DEV_SUSPEND; | ||
796 | if (DEV_OK(link)) | ||
797 | pcmcia_request_configuration(link->handle, &link->conf); | ||
798 | |||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | |||
803 | static struct pcmcia_device_id btuart_ids[] = { | 755 | static struct pcmcia_device_id btuart_ids[] = { |
804 | /* don't use this driver. Use serial_cs + hci_uart instead */ | 756 | /* don't use this driver. Use serial_cs + hci_uart instead */ |
805 | PCMCIA_DEVICE_NULL | 757 | PCMCIA_DEVICE_NULL |
@@ -811,11 +763,9 @@ static struct pcmcia_driver btuart_driver = { | |||
811 | .drv = { | 763 | .drv = { |
812 | .name = "btuart_cs", | 764 | .name = "btuart_cs", |
813 | }, | 765 | }, |
814 | .probe = btuart_attach, | 766 | .probe = btuart_probe, |
815 | .remove = btuart_detach, | 767 | .remove = btuart_detach, |
816 | .id_table = btuart_ids, | 768 | .id_table = btuart_ids, |
817 | .suspend = btuart_suspend, | ||
818 | .resume = btuart_resume, | ||
819 | }; | 769 | }; |
820 | 770 | ||
821 | static int __init init_btuart_cs(void) | 771 | static int __init init_btuart_cs(void) |