aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/pcmcia/cm4040_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/pcmcia/cm4040_cs.c')
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c151
1 files changed, 44 insertions, 107 deletions
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 4c698d908ffa..46eb371bf17e 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -65,7 +65,6 @@ static char *version =
65#define POLL_PERIOD msecs_to_jiffies(10) 65#define POLL_PERIOD msecs_to_jiffies(10)
66 66
67static void reader_release(dev_link_t *link); 67static void reader_release(dev_link_t *link);
68static void reader_detach(dev_link_t *link);
69 68
70static int major; 69static int major;
71 70
@@ -86,7 +85,6 @@ struct reader_dev {
86 struct timer_list poll_timer; 85 struct timer_list poll_timer;
87}; 86};
88 87
89static dev_info_t dev_info = MODULE_NAME;
90static dev_link_t *dev_table[CM_MAX_DEV]; 88static dev_link_t *dev_table[CM_MAX_DEV];
91 89
92#ifndef PCMCIA_DEBUG 90#ifndef PCMCIA_DEBUG
@@ -629,65 +627,26 @@ cs_release:
629 link->state &= ~DEV_CONFIG_PENDING; 627 link->state &= ~DEV_CONFIG_PENDING;
630} 628}
631 629
632static int reader_event(event_t event, int priority, 630static int reader_suspend(struct pcmcia_device *p_dev)
633 event_callback_args_t *args)
634{ 631{
635 dev_link_t *link; 632 dev_link_t *link = dev_to_instance(p_dev);
636 struct reader_dev *dev;
637 int devno;
638 633
639 link = args->client_data; 634 link->state |= DEV_SUSPEND;
640 dev = link->priv; 635 if (link->state & DEV_CONFIG)
641 DEBUGP(3, dev, "-> reader_event\n"); 636 pcmcia_release_configuration(link->handle);
642 for (devno = 0; devno < CM_MAX_DEV; devno++) {
643 if (dev_table[devno] == link)
644 break;
645 }
646 if (devno == CM_MAX_DEV)
647 return CS_BAD_ADAPTER;
648 637
649 switch (event) { 638 return 0;
650 case CS_EVENT_CARD_INSERTION: 639}
651 DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n"); 640
652 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 641static int reader_resume(struct pcmcia_device *p_dev)
653 reader_config(link, devno); 642{
654 break; 643 dev_link_t *link = dev_to_instance(p_dev);
655 case CS_EVENT_CARD_REMOVAL: 644
656 DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); 645 link->state &= ~DEV_SUSPEND;
657 link->state &= ~DEV_PRESENT; 646 if (link->state & DEV_CONFIG)
658 break; 647 pcmcia_request_configuration(link->handle, &link->conf);
659 case CS_EVENT_PM_SUSPEND: 648
660 DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND " 649 return 0;
661 "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
662 link->state |= DEV_SUSPEND;
663
664 case CS_EVENT_RESET_PHYSICAL:
665 DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
666 if (link->state & DEV_CONFIG) {
667 DEBUGP(5, dev, "ReleaseConfiguration\n");
668 pcmcia_release_configuration(link->handle);
669 }
670 break;
671 case CS_EVENT_PM_RESUME:
672 DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
673 "(fall-through to CS_EVENT_CARD_RESET)\n");
674 link->state &= ~DEV_SUSPEND;
675
676 case CS_EVENT_CARD_RESET:
677 DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
678 if ((link->state & DEV_CONFIG)) {
679 DEBUGP(5, dev, "RequestConfiguration\n");
680 pcmcia_request_configuration(link->handle,
681 &link->conf);
682 }
683 break;
684 default:
685 DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
686 event);
687 break;
688 }
689 DEBUGP(3, dev, "<- reader_event\n");
690 return CS_SUCCESS;
691} 650}
692 651
693static void reader_release(dev_link_t *link) 652static void reader_release(dev_link_t *link)
@@ -697,11 +656,10 @@ static void reader_release(dev_link_t *link)
697 pcmcia_release_io(link->handle, &link->io); 656 pcmcia_release_io(link->handle, &link->io);
698} 657}
699 658
700static dev_link_t *reader_attach(void) 659static int reader_attach(struct pcmcia_device *p_dev)
701{ 660{
702 struct reader_dev *dev; 661 struct reader_dev *dev;
703 dev_link_t *link; 662 dev_link_t *link;
704 client_reg_t client_reg;
705 int i; 663 int i;
706 664
707 for (i = 0; i < CM_MAX_DEV; i++) { 665 for (i = 0; i < CM_MAX_DEV; i++) {
@@ -710,11 +668,11 @@ static dev_link_t *reader_attach(void)
710 } 668 }
711 669
712 if (i == CM_MAX_DEV) 670 if (i == CM_MAX_DEV)
713 return NULL; 671 return -ENODEV;
714 672
715 dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL); 673 dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL);
716 if (dev == NULL) 674 if (dev == NULL)
717 return NULL; 675 return -ENOMEM;
718 676
719 dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT; 677 dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
720 dev->buffer_status = 0; 678 dev->buffer_status = 0;
@@ -725,20 +683,6 @@ static dev_link_t *reader_attach(void)
725 link->conf.IntType = INT_MEMORY_AND_IO; 683 link->conf.IntType = INT_MEMORY_AND_IO;
726 dev_table[i] = link; 684 dev_table[i] = link;
727 685
728 client_reg.dev_info = &dev_info;
729 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
730 client_reg.EventMask=
731 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
732 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
733 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
734 client_reg.Version = 0x0210;
735 client_reg.event_callback_args.client_data = link;
736 i = pcmcia_register_client(&link->handle, &client_reg);
737 if (i) {
738 cs_error(link->handle, RegisterClient, i);
739 reader_detach(link);
740 return NULL;
741 }
742 init_waitqueue_head(&dev->devq); 686 init_waitqueue_head(&dev->devq);
743 init_waitqueue_head(&dev->poll_wait); 687 init_waitqueue_head(&dev->poll_wait);
744 init_waitqueue_head(&dev->read_wait); 688 init_waitqueue_head(&dev->read_wait);
@@ -746,39 +690,37 @@ static dev_link_t *reader_attach(void)
746 init_timer(&dev->poll_timer); 690 init_timer(&dev->poll_timer);
747 dev->poll_timer.function = &cm4040_do_poll; 691 dev->poll_timer.function = &cm4040_do_poll;
748 692
749 return link; 693 link->handle = p_dev;
750} 694 p_dev->instance = link;
751
752static void reader_detach_by_devno(int devno, dev_link_t *link)
753{
754 struct reader_dev *dev = link->priv;
755 695
756 if (link->state & DEV_CONFIG) { 696 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
757 DEBUGP(5, dev, "device still configured (try to release it)\n"); 697 reader_config(link, i);
758 reader_release(link);
759 }
760 698
761 pcmcia_deregister_client(link->handle); 699 return 0;
762 dev_table[devno] = NULL;
763 DEBUGP(5, dev, "freeing dev=%p\n", dev);
764 cm4040_stop_poll(dev);
765 kfree(dev);
766 return;
767} 700}
768 701
769static void reader_detach(dev_link_t *link) 702static void reader_detach(struct pcmcia_device *p_dev)
770{ 703{
771 int i; 704 dev_link_t *link = dev_to_instance(p_dev);
705 struct reader_dev *dev = link->priv;
706 int devno;
772 707
773 /* find device */ 708 /* find device */
774 for (i = 0; i < CM_MAX_DEV; i++) { 709 for (devno = 0; devno < CM_MAX_DEV; devno++) {
775 if (dev_table[i] == link) 710 if (dev_table[devno] == link)
776 break; 711 break;
777 } 712 }
778 if (i == CM_MAX_DEV) 713 if (devno == CM_MAX_DEV)
779 return; 714 return;
780 715
781 reader_detach_by_devno(i, link); 716 link->state &= ~DEV_PRESENT;
717
718 if (link->state & DEV_CONFIG)
719 reader_release(link);
720
721 dev_table[devno] = NULL;
722 kfree(dev);
723
782 return; 724 return;
783} 725}
784 726
@@ -804,9 +746,10 @@ static struct pcmcia_driver reader_driver = {
804 .drv = { 746 .drv = {
805 .name = "cm4040_cs", 747 .name = "cm4040_cs",
806 }, 748 },
807 .attach = reader_attach, 749 .probe = reader_attach,
808 .detach = reader_detach, 750 .remove = reader_detach,
809 .event = reader_event, 751 .suspend = reader_suspend,
752 .resume = reader_resume,
810 .id_table = cm4040_ids, 753 .id_table = cm4040_ids,
811}; 754};
812 755
@@ -825,14 +768,8 @@ static int __init cm4040_init(void)
825 768
826static void __exit cm4040_exit(void) 769static void __exit cm4040_exit(void)
827{ 770{
828 int i;
829
830 printk(KERN_INFO MODULE_NAME ": unloading\n"); 771 printk(KERN_INFO MODULE_NAME ": unloading\n");
831 pcmcia_unregister_driver(&reader_driver); 772 pcmcia_unregister_driver(&reader_driver);
832 for (i = 0; i < CM_MAX_DEV; i++) {
833 if (dev_table[i])
834 reader_detach_by_devno(i, dev_table[i]);
835 }
836 unregister_chrdev(major, DEVICE_NAME); 773 unregister_chrdev(major, DEVICE_NAME);
837} 774}
838 775