diff options
Diffstat (limited to 'drivers/bluetooth/dtl1_cs.c')
-rw-r--r-- | drivers/bluetooth/dtl1_cs.c | 120 |
1 files changed, 36 insertions, 84 deletions
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 0449bc45ae5e..a71a240611e0 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c | |||
@@ -68,7 +68,7 @@ MODULE_LICENSE("GPL"); | |||
68 | 68 | ||
69 | 69 | ||
70 | typedef struct dtl1_info_t { | 70 | typedef struct dtl1_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; |
@@ -87,8 +87,8 @@ typedef struct dtl1_info_t { | |||
87 | } dtl1_info_t; | 87 | } dtl1_info_t; |
88 | 88 | ||
89 | 89 | ||
90 | static void dtl1_config(dev_link_t *link); | 90 | static int dtl1_config(struct pcmcia_device *link); |
91 | static void dtl1_release(dev_link_t *link); | 91 | static void dtl1_release(struct pcmcia_device *link); |
92 | 92 | ||
93 | static void dtl1_detach(struct pcmcia_device *p_dev); | 93 | static void dtl1_detach(struct pcmcia_device *p_dev); |
94 | 94 | ||
@@ -153,13 +153,13 @@ static void dtl1_write_wakeup(dtl1_info_t *info) | |||
153 | } | 153 | } |
154 | 154 | ||
155 | do { | 155 | do { |
156 | register unsigned int iobase = info->link.io.BasePort1; | 156 | register unsigned int iobase = info->p_dev->io.BasePort1; |
157 | register struct sk_buff *skb; | 157 | register struct sk_buff *skb; |
158 | register int len; | 158 | register int len; |
159 | 159 | ||
160 | clear_bit(XMIT_WAKEUP, &(info->tx_state)); | 160 | clear_bit(XMIT_WAKEUP, &(info->tx_state)); |
161 | 161 | ||
162 | if (!(info->link.state & DEV_PRESENT)) | 162 | if (!pcmcia_dev_present(info->p_dev)) |
163 | return; | 163 | return; |
164 | 164 | ||
165 | if (!(skb = skb_dequeue(&(info->txq)))) | 165 | if (!(skb = skb_dequeue(&(info->txq)))) |
@@ -218,7 +218,7 @@ static void dtl1_receive(dtl1_info_t *info) | |||
218 | return; | 218 | return; |
219 | } | 219 | } |
220 | 220 | ||
221 | iobase = info->link.io.BasePort1; | 221 | iobase = info->p_dev->io.BasePort1; |
222 | 222 | ||
223 | do { | 223 | do { |
224 | info->hdev->stat.byte_rx++; | 224 | info->hdev->stat.byte_rx++; |
@@ -305,7 +305,7 @@ static irqreturn_t dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs) | |||
305 | return IRQ_NONE; | 305 | return IRQ_NONE; |
306 | } | 306 | } |
307 | 307 | ||
308 | iobase = info->link.io.BasePort1; | 308 | iobase = info->p_dev->io.BasePort1; |
309 | 309 | ||
310 | spin_lock(&(info->lock)); | 310 | spin_lock(&(info->lock)); |
311 | 311 | ||
@@ -458,7 +458,7 @@ static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long | |||
458 | static int dtl1_open(dtl1_info_t *info) | 458 | static int dtl1_open(dtl1_info_t *info) |
459 | { | 459 | { |
460 | unsigned long flags; | 460 | unsigned long flags; |
461 | unsigned int iobase = info->link.io.BasePort1; | 461 | unsigned int iobase = info->p_dev->io.BasePort1; |
462 | struct hci_dev *hdev; | 462 | struct hci_dev *hdev; |
463 | 463 | ||
464 | spin_lock_init(&(info->lock)); | 464 | spin_lock_init(&(info->lock)); |
@@ -504,7 +504,7 @@ static int dtl1_open(dtl1_info_t *info) | |||
504 | outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */ | 504 | outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */ |
505 | outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR); | 505 | outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR); |
506 | 506 | ||
507 | info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI; | 507 | info->ri_latch = inb(info->p_dev->io.BasePort1 + UART_MSR) & UART_MSR_RI; |
508 | 508 | ||
509 | /* Turn on interrupts */ | 509 | /* Turn on interrupts */ |
510 | outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER); | 510 | outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER); |
@@ -529,7 +529,7 @@ static int dtl1_open(dtl1_info_t *info) | |||
529 | static int dtl1_close(dtl1_info_t *info) | 529 | static int dtl1_close(dtl1_info_t *info) |
530 | { | 530 | { |
531 | unsigned long flags; | 531 | unsigned long flags; |
532 | unsigned int iobase = info->link.io.BasePort1; | 532 | unsigned int iobase = info->p_dev->io.BasePort1; |
533 | struct hci_dev *hdev = info->hdev; | 533 | struct hci_dev *hdev = info->hdev; |
534 | 534 | ||
535 | if (!hdev) | 535 | if (!hdev) |
@@ -555,17 +555,16 @@ static int dtl1_close(dtl1_info_t *info) | |||
555 | return 0; | 555 | return 0; |
556 | } | 556 | } |
557 | 557 | ||
558 | static int dtl1_attach(struct pcmcia_device *p_dev) | 558 | static int dtl1_probe(struct pcmcia_device *link) |
559 | { | 559 | { |
560 | dtl1_info_t *info; | 560 | dtl1_info_t *info; |
561 | dev_link_t *link; | ||
562 | 561 | ||
563 | /* Create new info device */ | 562 | /* Create new info device */ |
564 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 563 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
565 | if (!info) | 564 | if (!info) |
566 | return -ENOMEM; | 565 | return -ENOMEM; |
567 | 566 | ||
568 | link = &info->link; | 567 | info->p_dev = link; |
569 | link->priv = info; | 568 | link->priv = info; |
570 | 569 | ||
571 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 570 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
@@ -577,31 +576,22 @@ static int dtl1_attach(struct pcmcia_device *p_dev) | |||
577 | link->irq.Instance = info; | 576 | link->irq.Instance = info; |
578 | 577 | ||
579 | link->conf.Attributes = CONF_ENABLE_IRQ; | 578 | link->conf.Attributes = CONF_ENABLE_IRQ; |
580 | link->conf.Vcc = 50; | ||
581 | link->conf.IntType = INT_MEMORY_AND_IO; | 579 | link->conf.IntType = INT_MEMORY_AND_IO; |
582 | 580 | ||
583 | link->handle = p_dev; | 581 | return dtl1_config(link); |
584 | p_dev->instance = link; | ||
585 | |||
586 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
587 | dtl1_config(link); | ||
588 | |||
589 | return 0; | ||
590 | } | 582 | } |
591 | 583 | ||
592 | 584 | ||
593 | static void dtl1_detach(struct pcmcia_device *p_dev) | 585 | static void dtl1_detach(struct pcmcia_device *link) |
594 | { | 586 | { |
595 | dev_link_t *link = dev_to_instance(p_dev); | ||
596 | dtl1_info_t *info = link->priv; | 587 | dtl1_info_t *info = link->priv; |
597 | 588 | ||
598 | if (link->state & DEV_CONFIG) | 589 | dtl1_release(link); |
599 | dtl1_release(link); | ||
600 | 590 | ||
601 | kfree(info); | 591 | kfree(info); |
602 | } | 592 | } |
603 | 593 | ||
604 | static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | 594 | static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) |
605 | { | 595 | { |
606 | int i; | 596 | int i; |
607 | 597 | ||
@@ -612,29 +602,27 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | |||
612 | return pcmcia_parse_tuple(handle, tuple, parse); | 602 | return pcmcia_parse_tuple(handle, tuple, parse); |
613 | } | 603 | } |
614 | 604 | ||
615 | static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | 605 | static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) |
616 | { | 606 | { |
617 | if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) | 607 | if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) |
618 | return CS_NO_MORE_ITEMS; | 608 | return CS_NO_MORE_ITEMS; |
619 | return get_tuple(handle, tuple, parse); | 609 | return get_tuple(handle, tuple, parse); |
620 | } | 610 | } |
621 | 611 | ||
622 | static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) | 612 | static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) |
623 | { | 613 | { |
624 | if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) | 614 | if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) |
625 | return CS_NO_MORE_ITEMS; | 615 | return CS_NO_MORE_ITEMS; |
626 | return get_tuple(handle, tuple, parse); | 616 | return get_tuple(handle, tuple, parse); |
627 | } | 617 | } |
628 | 618 | ||
629 | static void dtl1_config(dev_link_t *link) | 619 | static int dtl1_config(struct pcmcia_device *link) |
630 | { | 620 | { |
631 | client_handle_t handle = link->handle; | ||
632 | dtl1_info_t *info = link->priv; | 621 | dtl1_info_t *info = link->priv; |
633 | tuple_t tuple; | 622 | tuple_t tuple; |
634 | u_short buf[256]; | 623 | u_short buf[256]; |
635 | cisparse_t parse; | 624 | cisparse_t parse; |
636 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 625 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; |
637 | config_info_t config; | ||
638 | int i, last_ret, last_fn; | 626 | int i, last_ret, last_fn; |
639 | 627 | ||
640 | tuple.TupleData = (cisdata_t *)buf; | 628 | tuple.TupleData = (cisdata_t *)buf; |
@@ -644,7 +632,7 @@ static void dtl1_config(dev_link_t *link) | |||
644 | 632 | ||
645 | /* Get configuration register information */ | 633 | /* Get configuration register information */ |
646 | tuple.DesiredTuple = CISTPL_CONFIG; | 634 | tuple.DesiredTuple = CISTPL_CONFIG; |
647 | last_ret = first_tuple(handle, &tuple, &parse); | 635 | last_ret = first_tuple(link, &tuple, &parse); |
648 | if (last_ret != CS_SUCCESS) { | 636 | if (last_ret != CS_SUCCESS) { |
649 | last_fn = ParseTuple; | 637 | last_fn = ParseTuple; |
650 | goto cs_failed; | 638 | goto cs_failed; |
@@ -652,11 +640,6 @@ static void dtl1_config(dev_link_t *link) | |||
652 | link->conf.ConfigBase = parse.config.base; | 640 | link->conf.ConfigBase = parse.config.base; |
653 | link->conf.Present = parse.config.rmask[0]; | 641 | link->conf.Present = parse.config.rmask[0]; |
654 | 642 | ||
655 | /* Configure card */ | ||
656 | link->state |= DEV_CONFIG; | ||
657 | i = pcmcia_get_configuration_info(handle, &config); | ||
658 | link->conf.Vcc = config.Vcc; | ||
659 | |||
660 | tuple.TupleData = (cisdata_t *)buf; | 643 | tuple.TupleData = (cisdata_t *)buf; |
661 | tuple.TupleOffset = 0; | 644 | tuple.TupleOffset = 0; |
662 | tuple.TupleDataMax = 255; | 645 | tuple.TupleDataMax = 255; |
@@ -665,34 +648,34 @@ static void dtl1_config(dev_link_t *link) | |||
665 | 648 | ||
666 | /* Look for a generic full-sized window */ | 649 | /* Look for a generic full-sized window */ |
667 | link->io.NumPorts1 = 8; | 650 | link->io.NumPorts1 = 8; |
668 | i = first_tuple(handle, &tuple, &parse); | 651 | i = first_tuple(link, &tuple, &parse); |
669 | while (i != CS_NO_MORE_ITEMS) { | 652 | while (i != CS_NO_MORE_ITEMS) { |
670 | if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { | 653 | if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { |
671 | link->conf.ConfigIndex = cf->index; | 654 | link->conf.ConfigIndex = cf->index; |
672 | link->io.BasePort1 = cf->io.win[0].base; | 655 | link->io.BasePort1 = cf->io.win[0].base; |
673 | link->io.NumPorts1 = cf->io.win[0].len; /*yo */ | 656 | link->io.NumPorts1 = cf->io.win[0].len; /*yo */ |
674 | link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; | 657 | link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; |
675 | i = pcmcia_request_io(link->handle, &link->io); | 658 | i = pcmcia_request_io(link, &link->io); |
676 | if (i == CS_SUCCESS) | 659 | if (i == CS_SUCCESS) |
677 | break; | 660 | break; |
678 | } | 661 | } |
679 | i = next_tuple(handle, &tuple, &parse); | 662 | i = next_tuple(link, &tuple, &parse); |
680 | } | 663 | } |
681 | 664 | ||
682 | if (i != CS_SUCCESS) { | 665 | if (i != CS_SUCCESS) { |
683 | cs_error(link->handle, RequestIO, i); | 666 | cs_error(link, RequestIO, i); |
684 | goto failed; | 667 | goto failed; |
685 | } | 668 | } |
686 | 669 | ||
687 | i = pcmcia_request_irq(link->handle, &link->irq); | 670 | i = pcmcia_request_irq(link, &link->irq); |
688 | if (i != CS_SUCCESS) { | 671 | if (i != CS_SUCCESS) { |
689 | cs_error(link->handle, RequestIRQ, i); | 672 | cs_error(link, RequestIRQ, i); |
690 | link->irq.AssignedIRQ = 0; | 673 | link->irq.AssignedIRQ = 0; |
691 | } | 674 | } |
692 | 675 | ||
693 | i = pcmcia_request_configuration(link->handle, &link->conf); | 676 | i = pcmcia_request_configuration(link, &link->conf); |
694 | if (i != CS_SUCCESS) { | 677 | if (i != CS_SUCCESS) { |
695 | cs_error(link->handle, RequestConfiguration, i); | 678 | cs_error(link, RequestConfiguration, i); |
696 | goto failed; | 679 | goto failed; |
697 | } | 680 | } |
698 | 681 | ||
@@ -700,55 +683,26 @@ static void dtl1_config(dev_link_t *link) | |||
700 | goto failed; | 683 | goto failed; |
701 | 684 | ||
702 | strcpy(info->node.dev_name, info->hdev->name); | 685 | strcpy(info->node.dev_name, info->hdev->name); |
703 | link->dev = &info->node; | 686 | link->dev_node = &info->node; |
704 | link->state &= ~DEV_CONFIG_PENDING; | ||
705 | 687 | ||
706 | return; | 688 | return 0; |
707 | 689 | ||
708 | cs_failed: | 690 | cs_failed: |
709 | cs_error(link->handle, last_fn, last_ret); | 691 | cs_error(link, last_fn, last_ret); |
710 | 692 | ||
711 | failed: | 693 | failed: |
712 | dtl1_release(link); | 694 | dtl1_release(link); |
695 | return -ENODEV; | ||
713 | } | 696 | } |
714 | 697 | ||
715 | 698 | ||
716 | static void dtl1_release(dev_link_t *link) | 699 | static void dtl1_release(struct pcmcia_device *link) |
717 | { | 700 | { |
718 | dtl1_info_t *info = link->priv; | 701 | dtl1_info_t *info = link->priv; |
719 | 702 | ||
720 | if (link->state & DEV_PRESENT) | 703 | dtl1_close(info); |
721 | dtl1_close(info); | ||
722 | |||
723 | link->dev = NULL; | ||
724 | |||
725 | pcmcia_release_configuration(link->handle); | ||
726 | pcmcia_release_io(link->handle, &link->io); | ||
727 | pcmcia_release_irq(link->handle, &link->irq); | ||
728 | |||
729 | link->state &= ~DEV_CONFIG; | ||
730 | } | ||
731 | |||
732 | static int dtl1_suspend(struct pcmcia_device *dev) | ||
733 | { | ||
734 | dev_link_t *link = dev_to_instance(dev); | ||
735 | |||
736 | link->state |= DEV_SUSPEND; | ||
737 | if (link->state & DEV_CONFIG) | ||
738 | pcmcia_release_configuration(link->handle); | ||
739 | |||
740 | return 0; | ||
741 | } | ||
742 | |||
743 | static int dtl1_resume(struct pcmcia_device *dev) | ||
744 | { | ||
745 | dev_link_t *link = dev_to_instance(dev); | ||
746 | 704 | ||
747 | link->state &= ~DEV_SUSPEND; | 705 | pcmcia_disable_device(link); |
748 | if (DEV_OK(link)) | ||
749 | pcmcia_request_configuration(link->handle, &link->conf); | ||
750 | |||
751 | return 0; | ||
752 | } | 706 | } |
753 | 707 | ||
754 | 708 | ||
@@ -765,11 +719,9 @@ static struct pcmcia_driver dtl1_driver = { | |||
765 | .drv = { | 719 | .drv = { |
766 | .name = "dtl1_cs", | 720 | .name = "dtl1_cs", |
767 | }, | 721 | }, |
768 | .probe = dtl1_attach, | 722 | .probe = dtl1_probe, |
769 | .remove = dtl1_detach, | 723 | .remove = dtl1_detach, |
770 | .id_table = dtl1_ids, | 724 | .id_table = dtl1_ids, |
771 | .suspend = dtl1_suspend, | ||
772 | .resume = dtl1_resume, | ||
773 | }; | 725 | }; |
774 | 726 | ||
775 | static int __init init_dtl1_cs(void) | 727 | static int __init init_dtl1_cs(void) |