diff options
47 files changed, 373 insertions, 896 deletions
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt index 5c822f54d46c..45c25c7a3445 100644 --- a/Documentation/pcmcia/driver-changes.txt +++ b/Documentation/pcmcia/driver-changes.txt | |||
@@ -1,5 +1,8 @@ | |||
1 | This file details changes in 2.6 which affect PCMCIA card driver authors: | 1 | This file details changes in 2.6 which affect PCMCIA card driver authors: |
2 | 2 | ||
3 | * Unify detach and REMOVAL event code (as of 2.6.16) | ||
4 | void (*remove) (struct pcmcia_device *dev); | ||
5 | |||
3 | * Move suspend, resume and reset out of event handler (as of 2.6.16) | 6 | * Move suspend, resume and reset out of event handler (as of 2.6.16) |
4 | int (*suspend) (struct pcmcia_device *dev); | 7 | int (*suspend) (struct pcmcia_device *dev); |
5 | int (*resume) (struct pcmcia_device *dev); | 8 | int (*resume) (struct pcmcia_device *dev); |
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 5b24131e5430..f5088cb3812b 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -92,7 +92,7 @@ static int bluecard_event(event_t event, int priority, event_callback_args_t *ar | |||
92 | static dev_info_t dev_info = "bluecard_cs"; | 92 | static dev_info_t dev_info = "bluecard_cs"; |
93 | 93 | ||
94 | static dev_link_t *bluecard_attach(void); | 94 | static dev_link_t *bluecard_attach(void); |
95 | static void bluecard_detach(dev_link_t *); | 95 | static void bluecard_detach(struct pcmcia_device *p_dev); |
96 | 96 | ||
97 | static dev_link_t *dev_list = NULL; | 97 | static dev_link_t *dev_list = NULL; |
98 | 98 | ||
@@ -899,7 +899,7 @@ static dev_link_t *bluecard_attach(void) | |||
899 | ret = pcmcia_register_client(&link->handle, &client_reg); | 899 | ret = pcmcia_register_client(&link->handle, &client_reg); |
900 | if (ret != CS_SUCCESS) { | 900 | if (ret != CS_SUCCESS) { |
901 | cs_error(link->handle, RegisterClient, ret); | 901 | cs_error(link->handle, RegisterClient, ret); |
902 | bluecard_detach(link); | 902 | bluecard_detach(link->handle); |
903 | return NULL; | 903 | return NULL; |
904 | } | 904 | } |
905 | 905 | ||
@@ -907,11 +907,11 @@ static dev_link_t *bluecard_attach(void) | |||
907 | } | 907 | } |
908 | 908 | ||
909 | 909 | ||
910 | static void bluecard_detach(dev_link_t *link) | 910 | static void bluecard_detach(struct pcmcia_device *p_dev) |
911 | { | 911 | { |
912 | dev_link_t *link = dev_to_instance(p_dev); | ||
912 | bluecard_info_t *info = link->priv; | 913 | bluecard_info_t *info = link->priv; |
913 | dev_link_t **linkp; | 914 | dev_link_t **linkp; |
914 | int ret; | ||
915 | 915 | ||
916 | /* Locate device structure */ | 916 | /* Locate device structure */ |
917 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | 917 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) |
@@ -924,12 +924,6 @@ static void bluecard_detach(dev_link_t *link) | |||
924 | if (link->state & DEV_CONFIG) | 924 | if (link->state & DEV_CONFIG) |
925 | bluecard_release(link); | 925 | bluecard_release(link); |
926 | 926 | ||
927 | if (link->handle) { | ||
928 | ret = pcmcia_deregister_client(link->handle); | ||
929 | if (ret != CS_SUCCESS) | ||
930 | cs_error(link->handle, DeregisterClient, ret); | ||
931 | } | ||
932 | |||
933 | /* Unlink device structure, free bits */ | 927 | /* Unlink device structure, free bits */ |
934 | *linkp = link->next; | 928 | *linkp = link->next; |
935 | 929 | ||
@@ -1070,16 +1064,8 @@ static int bluecard_resume(struct pcmcia_device *dev) | |||
1070 | static int bluecard_event(event_t event, int priority, event_callback_args_t *args) | 1064 | static int bluecard_event(event_t event, int priority, event_callback_args_t *args) |
1071 | { | 1065 | { |
1072 | dev_link_t *link = args->client_data; | 1066 | dev_link_t *link = args->client_data; |
1073 | bluecard_info_t *info = link->priv; | ||
1074 | 1067 | ||
1075 | switch (event) { | 1068 | switch (event) { |
1076 | case CS_EVENT_CARD_REMOVAL: | ||
1077 | link->state &= ~DEV_PRESENT; | ||
1078 | if (link->state & DEV_CONFIG) { | ||
1079 | bluecard_close(info); | ||
1080 | bluecard_release(link); | ||
1081 | } | ||
1082 | break; | ||
1083 | case CS_EVENT_CARD_INSERTION: | 1069 | case CS_EVENT_CARD_INSERTION: |
1084 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 1070 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
1085 | bluecard_config(link); | 1071 | bluecard_config(link); |
@@ -1104,7 +1090,7 @@ static struct pcmcia_driver bluecard_driver = { | |||
1104 | }, | 1090 | }, |
1105 | .attach = bluecard_attach, | 1091 | .attach = bluecard_attach, |
1106 | .event = bluecard_event, | 1092 | .event = bluecard_event, |
1107 | .detach = bluecard_detach, | 1093 | .remove = bluecard_detach, |
1108 | .id_table = bluecard_ids, | 1094 | .id_table = bluecard_ids, |
1109 | .suspend = bluecard_suspend, | 1095 | .suspend = bluecard_suspend, |
1110 | .resume = bluecard_resume, | 1096 | .resume = bluecard_resume, |
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 1d524baa24a0..02ce38e33d32 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
@@ -95,7 +95,7 @@ static int bt3c_event(event_t event, int priority, event_callback_args_t *args); | |||
95 | static dev_info_t dev_info = "bt3c_cs"; | 95 | static dev_info_t dev_info = "bt3c_cs"; |
96 | 96 | ||
97 | static dev_link_t *bt3c_attach(void); | 97 | static dev_link_t *bt3c_attach(void); |
98 | static void bt3c_detach(dev_link_t *); | 98 | static void bt3c_detach(struct pcmcia_device *p_dev); |
99 | 99 | ||
100 | static dev_link_t *dev_list = NULL; | 100 | static dev_link_t *dev_list = NULL; |
101 | 101 | ||
@@ -700,7 +700,7 @@ static dev_link_t *bt3c_attach(void) | |||
700 | ret = pcmcia_register_client(&link->handle, &client_reg); | 700 | ret = pcmcia_register_client(&link->handle, &client_reg); |
701 | if (ret != CS_SUCCESS) { | 701 | if (ret != CS_SUCCESS) { |
702 | cs_error(link->handle, RegisterClient, ret); | 702 | cs_error(link->handle, RegisterClient, ret); |
703 | bt3c_detach(link); | 703 | bt3c_detach(link->handle); |
704 | return NULL; | 704 | return NULL; |
705 | } | 705 | } |
706 | 706 | ||
@@ -708,11 +708,11 @@ static dev_link_t *bt3c_attach(void) | |||
708 | } | 708 | } |
709 | 709 | ||
710 | 710 | ||
711 | static void bt3c_detach(dev_link_t *link) | 711 | static void bt3c_detach(struct pcmcia_device *p_dev) |
712 | { | 712 | { |
713 | dev_link_t *link = dev_to_instance(p_dev); | ||
713 | bt3c_info_t *info = link->priv; | 714 | bt3c_info_t *info = link->priv; |
714 | dev_link_t **linkp; | 715 | dev_link_t **linkp; |
715 | int ret; | ||
716 | 716 | ||
717 | /* Locate device structure */ | 717 | /* Locate device structure */ |
718 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | 718 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) |
@@ -725,12 +725,6 @@ static void bt3c_detach(dev_link_t *link) | |||
725 | if (link->state & DEV_CONFIG) | 725 | if (link->state & DEV_CONFIG) |
726 | bt3c_release(link); | 726 | bt3c_release(link); |
727 | 727 | ||
728 | if (link->handle) { | ||
729 | ret = pcmcia_deregister_client(link->handle); | ||
730 | if (ret != CS_SUCCESS) | ||
731 | cs_error(link->handle, DeregisterClient, ret); | ||
732 | } | ||
733 | |||
734 | /* Unlink device structure, free bits */ | 728 | /* Unlink device structure, free bits */ |
735 | *linkp = link->next; | 729 | *linkp = link->next; |
736 | 730 | ||
@@ -916,16 +910,8 @@ static int bt3c_resume(struct pcmcia_device *dev) | |||
916 | static int bt3c_event(event_t event, int priority, event_callback_args_t *args) | 910 | static int bt3c_event(event_t event, int priority, event_callback_args_t *args) |
917 | { | 911 | { |
918 | dev_link_t *link = args->client_data; | 912 | dev_link_t *link = args->client_data; |
919 | bt3c_info_t *info = link->priv; | ||
920 | 913 | ||
921 | switch (event) { | 914 | switch (event) { |
922 | case CS_EVENT_CARD_REMOVAL: | ||
923 | link->state &= ~DEV_PRESENT; | ||
924 | if (link->state & DEV_CONFIG) { | ||
925 | bt3c_close(info); | ||
926 | bt3c_release(link); | ||
927 | } | ||
928 | break; | ||
929 | case CS_EVENT_CARD_INSERTION: | 915 | case CS_EVENT_CARD_INSERTION: |
930 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 916 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
931 | bt3c_config(link); | 917 | bt3c_config(link); |
@@ -948,7 +934,7 @@ static struct pcmcia_driver bt3c_driver = { | |||
948 | }, | 934 | }, |
949 | .attach = bt3c_attach, | 935 | .attach = bt3c_attach, |
950 | .event = bt3c_event, | 936 | .event = bt3c_event, |
951 | .detach = bt3c_detach, | 937 | .remove = bt3c_detach, |
952 | .id_table = bt3c_ids, | 938 | .id_table = bt3c_ids, |
953 | .suspend = bt3c_suspend, | 939 | .suspend = bt3c_suspend, |
954 | .resume = bt3c_resume, | 940 | .resume = bt3c_resume, |
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 1828ba6ca25e..63221d383fda 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c | |||
@@ -91,7 +91,7 @@ static int btuart_event(event_t event, int priority, event_callback_args_t *args | |||
91 | static dev_info_t dev_info = "btuart_cs"; | 91 | static dev_info_t dev_info = "btuart_cs"; |
92 | 92 | ||
93 | static dev_link_t *btuart_attach(void); | 93 | static dev_link_t *btuart_attach(void); |
94 | static void btuart_detach(dev_link_t *); | 94 | static void btuart_detach(struct pcmcia_device *p_dev); |
95 | 95 | ||
96 | static dev_link_t *dev_list = NULL; | 96 | static dev_link_t *dev_list = NULL; |
97 | 97 | ||
@@ -619,7 +619,7 @@ static dev_link_t *btuart_attach(void) | |||
619 | ret = pcmcia_register_client(&link->handle, &client_reg); | 619 | ret = pcmcia_register_client(&link->handle, &client_reg); |
620 | if (ret != CS_SUCCESS) { | 620 | if (ret != CS_SUCCESS) { |
621 | cs_error(link->handle, RegisterClient, ret); | 621 | cs_error(link->handle, RegisterClient, ret); |
622 | btuart_detach(link); | 622 | btuart_detach(link->handle); |
623 | return NULL; | 623 | return NULL; |
624 | } | 624 | } |
625 | 625 | ||
@@ -627,11 +627,11 @@ static dev_link_t *btuart_attach(void) | |||
627 | } | 627 | } |
628 | 628 | ||
629 | 629 | ||
630 | static void btuart_detach(dev_link_t *link) | 630 | static void btuart_detach(struct pcmcia_device *p_dev) |
631 | { | 631 | { |
632 | dev_link_t *link = dev_to_instance(p_dev); | ||
632 | btuart_info_t *info = link->priv; | 633 | btuart_info_t *info = link->priv; |
633 | dev_link_t **linkp; | 634 | dev_link_t **linkp; |
634 | int ret; | ||
635 | 635 | ||
636 | /* Locate device structure */ | 636 | /* Locate device structure */ |
637 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | 637 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) |
@@ -644,12 +644,6 @@ static void btuart_detach(dev_link_t *link) | |||
644 | if (link->state & DEV_CONFIG) | 644 | if (link->state & DEV_CONFIG) |
645 | btuart_release(link); | 645 | btuart_release(link); |
646 | 646 | ||
647 | if (link->handle) { | ||
648 | ret = pcmcia_deregister_client(link->handle); | ||
649 | if (ret != CS_SUCCESS) | ||
650 | cs_error(link->handle, DeregisterClient, ret); | ||
651 | } | ||
652 | |||
653 | /* Unlink device structure, free bits */ | 647 | /* Unlink device structure, free bits */ |
654 | *linkp = link->next; | 648 | *linkp = link->next; |
655 | 649 | ||
@@ -837,16 +831,8 @@ static int btuart_resume(struct pcmcia_device *dev) | |||
837 | static int btuart_event(event_t event, int priority, event_callback_args_t *args) | 831 | static int btuart_event(event_t event, int priority, event_callback_args_t *args) |
838 | { | 832 | { |
839 | dev_link_t *link = args->client_data; | 833 | dev_link_t *link = args->client_data; |
840 | btuart_info_t *info = link->priv; | ||
841 | 834 | ||
842 | switch (event) { | 835 | switch (event) { |
843 | case CS_EVENT_CARD_REMOVAL: | ||
844 | link->state &= ~DEV_PRESENT; | ||
845 | if (link->state & DEV_CONFIG) { | ||
846 | btuart_close(info); | ||
847 | btuart_release(link); | ||
848 | } | ||
849 | break; | ||
850 | case CS_EVENT_CARD_INSERTION: | 836 | case CS_EVENT_CARD_INSERTION: |
851 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 837 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
852 | btuart_config(link); | 838 | btuart_config(link); |
@@ -869,7 +855,7 @@ static struct pcmcia_driver btuart_driver = { | |||
869 | }, | 855 | }, |
870 | .attach = btuart_attach, | 856 | .attach = btuart_attach, |
871 | .event = btuart_event, | 857 | .event = btuart_event, |
872 | .detach = btuart_detach, | 858 | .remove = btuart_detach, |
873 | .id_table = btuart_ids, | 859 | .id_table = btuart_ids, |
874 | .suspend = btuart_suspend, | 860 | .suspend = btuart_suspend, |
875 | .resume = btuart_resume, | 861 | .resume = btuart_resume, |
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 9f9d3f91f455..2874d8722be9 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c | |||
@@ -94,7 +94,7 @@ static int dtl1_event(event_t event, int priority, event_callback_args_t *args); | |||
94 | static dev_info_t dev_info = "dtl1_cs"; | 94 | static dev_info_t dev_info = "dtl1_cs"; |
95 | 95 | ||
96 | static dev_link_t *dtl1_attach(void); | 96 | static dev_link_t *dtl1_attach(void); |
97 | static void dtl1_detach(dev_link_t *); | 97 | static void dtl1_detach(struct pcmcia_device *p_dev); |
98 | 98 | ||
99 | static dev_link_t *dev_list = NULL; | 99 | static dev_link_t *dev_list = NULL; |
100 | 100 | ||
@@ -598,7 +598,7 @@ static dev_link_t *dtl1_attach(void) | |||
598 | ret = pcmcia_register_client(&link->handle, &client_reg); | 598 | ret = pcmcia_register_client(&link->handle, &client_reg); |
599 | if (ret != CS_SUCCESS) { | 599 | if (ret != CS_SUCCESS) { |
600 | cs_error(link->handle, RegisterClient, ret); | 600 | cs_error(link->handle, RegisterClient, ret); |
601 | dtl1_detach(link); | 601 | dtl1_detach(link->handle); |
602 | return NULL; | 602 | return NULL; |
603 | } | 603 | } |
604 | 604 | ||
@@ -606,11 +606,11 @@ static dev_link_t *dtl1_attach(void) | |||
606 | } | 606 | } |
607 | 607 | ||
608 | 608 | ||
609 | static void dtl1_detach(dev_link_t *link) | 609 | static void dtl1_detach(struct pcmcia_device *p_dev) |
610 | { | 610 | { |
611 | dev_link_t *link = dev_to_instance(p_dev); | ||
611 | dtl1_info_t *info = link->priv; | 612 | dtl1_info_t *info = link->priv; |
612 | dev_link_t **linkp; | 613 | dev_link_t **linkp; |
613 | int ret; | ||
614 | 614 | ||
615 | /* Locate device structure */ | 615 | /* Locate device structure */ |
616 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | 616 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) |
@@ -623,12 +623,6 @@ static void dtl1_detach(dev_link_t *link) | |||
623 | if (link->state & DEV_CONFIG) | 623 | if (link->state & DEV_CONFIG) |
624 | dtl1_release(link); | 624 | dtl1_release(link); |
625 | 625 | ||
626 | if (link->handle) { | ||
627 | ret = pcmcia_deregister_client(link->handle); | ||
628 | if (ret != CS_SUCCESS) | ||
629 | cs_error(link->handle, DeregisterClient, ret); | ||
630 | } | ||
631 | |||
632 | /* Unlink device structure, free bits */ | 626 | /* Unlink device structure, free bits */ |
633 | *linkp = link->next; | 627 | *linkp = link->next; |
634 | 628 | ||
@@ -788,16 +782,8 @@ static int dtl1_resume(struct pcmcia_device *dev) | |||
788 | static int dtl1_event(event_t event, int priority, event_callback_args_t *args) | 782 | static int dtl1_event(event_t event, int priority, event_callback_args_t *args) |
789 | { | 783 | { |
790 | dev_link_t *link = args->client_data; | 784 | dev_link_t *link = args->client_data; |
791 | dtl1_info_t *info = link->priv; | ||
792 | 785 | ||
793 | switch (event) { | 786 | switch (event) { |
794 | case CS_EVENT_CARD_REMOVAL: | ||
795 | link->state &= ~DEV_PRESENT; | ||
796 | if (link->state & DEV_CONFIG) { | ||
797 | dtl1_close(info); | ||
798 | dtl1_release(link); | ||
799 | } | ||
800 | break; | ||
801 | case CS_EVENT_CARD_INSERTION: | 787 | case CS_EVENT_CARD_INSERTION: |
802 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 788 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
803 | dtl1_config(link); | 789 | dtl1_config(link); |
@@ -821,7 +807,7 @@ static struct pcmcia_driver dtl1_driver = { | |||
821 | }, | 807 | }, |
822 | .attach = dtl1_attach, | 808 | .attach = dtl1_attach, |
823 | .event = dtl1_event, | 809 | .event = dtl1_event, |
824 | .detach = dtl1_detach, | 810 | .remove = dtl1_detach, |
825 | .id_table = dtl1_ids, | 811 | .id_table = dtl1_ids, |
826 | .suspend = dtl1_suspend, | 812 | .suspend = dtl1_suspend, |
827 | .resume = dtl1_resume, | 813 | .resume = dtl1_resume, |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 05e93054c98c..8a064f2f005d 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -66,7 +66,7 @@ static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte"; | |||
66 | #define T_100MSEC msecs_to_jiffies(100) | 66 | #define T_100MSEC msecs_to_jiffies(100) |
67 | #define T_500MSEC msecs_to_jiffies(500) | 67 | #define T_500MSEC msecs_to_jiffies(500) |
68 | 68 | ||
69 | static void cm4000_detach(dev_link_t *link); | 69 | static void cm4000_detach(struct pcmcia_device *p_dev); |
70 | static void cm4000_release(dev_link_t *link); | 70 | static void cm4000_release(dev_link_t *link); |
71 | 71 | ||
72 | static int major; /* major number we get from the kernel */ | 72 | static int major; /* major number we get from the kernel */ |
@@ -1888,11 +1888,6 @@ static int cm4000_event(event_t event, int priority, | |||
1888 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 1888 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
1889 | cm4000_config(link, devno); | 1889 | cm4000_config(link, devno); |
1890 | break; | 1890 | break; |
1891 | case CS_EVENT_CARD_REMOVAL: | ||
1892 | DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); | ||
1893 | link->state &= ~DEV_PRESENT; | ||
1894 | stop_monitor(dev); | ||
1895 | break; | ||
1896 | default: | 1891 | default: |
1897 | DEBUGP(5, dev, "unknown event %.2x\n", event); | 1892 | DEBUGP(5, dev, "unknown event %.2x\n", event); |
1898 | break; | 1893 | break; |
@@ -1978,7 +1973,7 @@ static dev_link_t *cm4000_attach(void) | |||
1978 | i = pcmcia_register_client(&link->handle, &client_reg); | 1973 | i = pcmcia_register_client(&link->handle, &client_reg); |
1979 | if (i) { | 1974 | if (i) { |
1980 | cs_error(link->handle, RegisterClient, i); | 1975 | cs_error(link->handle, RegisterClient, i); |
1981 | cm4000_detach(link); | 1976 | cm4000_detach(link->handle); |
1982 | return NULL; | 1977 | return NULL; |
1983 | } | 1978 | } |
1984 | 1979 | ||
@@ -1990,39 +1985,28 @@ static dev_link_t *cm4000_attach(void) | |||
1990 | return link; | 1985 | return link; |
1991 | } | 1986 | } |
1992 | 1987 | ||
1993 | static void cm4000_detach_by_devno(int devno, dev_link_t * link) | 1988 | static void cm4000_detach(struct pcmcia_device *p_dev) |
1994 | { | 1989 | { |
1990 | dev_link_t *link = dev_to_instance(p_dev); | ||
1995 | struct cm4000_dev *dev = link->priv; | 1991 | struct cm4000_dev *dev = link->priv; |
1992 | int devno; | ||
1996 | 1993 | ||
1997 | DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno); | 1994 | /* find device */ |
1995 | for (devno = 0; devno < CM4000_MAX_DEV; devno++) | ||
1996 | if (dev_table[devno] == link) | ||
1997 | break; | ||
1998 | if (devno == CM4000_MAX_DEV) | ||
1999 | return; | ||
1998 | 2000 | ||
1999 | if (link->state & DEV_CONFIG) { | 2001 | link->state &= ~DEV_PRESENT; |
2000 | DEBUGP(5, dev, "device still configured (try to release it)\n"); | 2002 | stop_monitor(dev); |
2001 | cm4000_release(link); | ||
2002 | } | ||
2003 | 2003 | ||
2004 | if (link->handle) { | 2004 | if (link->state & DEV_CONFIG) |
2005 | pcmcia_deregister_client(link->handle); | 2005 | cm4000_release(link); |
2006 | } | ||
2007 | 2006 | ||
2008 | dev_table[devno] = NULL; | 2007 | dev_table[devno] = NULL; |
2009 | kfree(dev); | 2008 | kfree(dev); |
2010 | return; | ||
2011 | } | ||
2012 | |||
2013 | static void cm4000_detach(dev_link_t * link) | ||
2014 | { | ||
2015 | int i; | ||
2016 | 2009 | ||
2017 | /* find device */ | ||
2018 | for (i = 0; i < CM4000_MAX_DEV; i++) | ||
2019 | if (dev_table[i] == link) | ||
2020 | break; | ||
2021 | |||
2022 | if (i == CM4000_MAX_DEV) | ||
2023 | return; | ||
2024 | |||
2025 | cm4000_detach_by_devno(i, link); | ||
2026 | return; | 2010 | return; |
2027 | } | 2011 | } |
2028 | 2012 | ||
@@ -2048,7 +2032,7 @@ static struct pcmcia_driver cm4000_driver = { | |||
2048 | .name = "cm4000_cs", | 2032 | .name = "cm4000_cs", |
2049 | }, | 2033 | }, |
2050 | .attach = cm4000_attach, | 2034 | .attach = cm4000_attach, |
2051 | .detach = cm4000_detach, | 2035 | .remove = cm4000_detach, |
2052 | .suspend = cm4000_suspend, | 2036 | .suspend = cm4000_suspend, |
2053 | .resume = cm4000_resume, | 2037 | .resume = cm4000_resume, |
2054 | .event = cm4000_event, | 2038 | .event = cm4000_event, |
@@ -2071,13 +2055,8 @@ static int __init cmm_init(void) | |||
2071 | 2055 | ||
2072 | static void __exit cmm_exit(void) | 2056 | static void __exit cmm_exit(void) |
2073 | { | 2057 | { |
2074 | int i; | ||
2075 | |||
2076 | printk(KERN_INFO MODULE_NAME ": unloading\n"); | 2058 | printk(KERN_INFO MODULE_NAME ": unloading\n"); |
2077 | pcmcia_unregister_driver(&cm4000_driver); | 2059 | pcmcia_unregister_driver(&cm4000_driver); |
2078 | for (i = 0; i < CM4000_MAX_DEV; i++) | ||
2079 | if (dev_table[i]) | ||
2080 | cm4000_detach_by_devno(i, dev_table[i]); | ||
2081 | unregister_chrdev(major, DEVICE_NAME); | 2060 | unregister_chrdev(major, DEVICE_NAME); |
2082 | }; | 2061 | }; |
2083 | 2062 | ||
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 3622fd39c47b..e08ab949c116 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -65,7 +65,7 @@ static char *version = | |||
65 | #define POLL_PERIOD msecs_to_jiffies(10) | 65 | #define POLL_PERIOD msecs_to_jiffies(10) |
66 | 66 | ||
67 | static void reader_release(dev_link_t *link); | 67 | static void reader_release(dev_link_t *link); |
68 | static void reader_detach(dev_link_t *link); | 68 | static void reader_detach(struct pcmcia_device *p_dev); |
69 | 69 | ||
70 | static int major; | 70 | static int major; |
71 | 71 | ||
@@ -652,10 +652,6 @@ static int reader_event(event_t event, int priority, | |||
652 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 652 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
653 | reader_config(link, devno); | 653 | reader_config(link, devno); |
654 | break; | 654 | break; |
655 | case CS_EVENT_CARD_REMOVAL: | ||
656 | DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); | ||
657 | link->state &= ~DEV_PRESENT; | ||
658 | break; | ||
659 | 655 | ||
660 | default: | 656 | default: |
661 | DEBUGP(5, dev, "reader_event: unknown event %.2x\n", | 657 | DEBUGP(5, dev, "reader_event: unknown event %.2x\n", |
@@ -734,7 +730,7 @@ static dev_link_t *reader_attach(void) | |||
734 | i = pcmcia_register_client(&link->handle, &client_reg); | 730 | i = pcmcia_register_client(&link->handle, &client_reg); |
735 | if (i) { | 731 | if (i) { |
736 | cs_error(link->handle, RegisterClient, i); | 732 | cs_error(link->handle, RegisterClient, i); |
737 | reader_detach(link); | 733 | reader_detach(link->handle); |
738 | return NULL; | 734 | return NULL; |
739 | } | 735 | } |
740 | init_waitqueue_head(&dev->devq); | 736 | init_waitqueue_head(&dev->devq); |
@@ -747,36 +743,28 @@ static dev_link_t *reader_attach(void) | |||
747 | return link; | 743 | return link; |
748 | } | 744 | } |
749 | 745 | ||
750 | static void reader_detach_by_devno(int devno, dev_link_t *link) | 746 | static void reader_detach(struct pcmcia_device *p_dev) |
751 | { | 747 | { |
748 | dev_link_t *link = dev_to_instance(p_dev); | ||
752 | struct reader_dev *dev = link->priv; | 749 | struct reader_dev *dev = link->priv; |
753 | 750 | int devno; | |
754 | if (link->state & DEV_CONFIG) { | ||
755 | DEBUGP(5, dev, "device still configured (try to release it)\n"); | ||
756 | reader_release(link); | ||
757 | } | ||
758 | |||
759 | pcmcia_deregister_client(link->handle); | ||
760 | dev_table[devno] = NULL; | ||
761 | DEBUGP(5, dev, "freeing dev=%p\n", dev); | ||
762 | cm4040_stop_poll(dev); | ||
763 | kfree(dev); | ||
764 | return; | ||
765 | } | ||
766 | |||
767 | static void reader_detach(dev_link_t *link) | ||
768 | { | ||
769 | int i; | ||
770 | 751 | ||
771 | /* find device */ | 752 | /* find device */ |
772 | for (i = 0; i < CM_MAX_DEV; i++) { | 753 | for (devno = 0; devno < CM_MAX_DEV; devno++) { |
773 | if (dev_table[i] == link) | 754 | if (dev_table[devno] == link) |
774 | break; | 755 | break; |
775 | } | 756 | } |
776 | if (i == CM_MAX_DEV) | 757 | if (devno == CM_MAX_DEV) |
777 | return; | 758 | return; |
778 | 759 | ||
779 | reader_detach_by_devno(i, link); | 760 | link->state &= ~DEV_PRESENT; |
761 | |||
762 | if (link->state & DEV_CONFIG) | ||
763 | reader_release(link); | ||
764 | |||
765 | dev_table[devno] = NULL; | ||
766 | kfree(dev); | ||
767 | |||
780 | return; | 768 | return; |
781 | } | 769 | } |
782 | 770 | ||
@@ -803,7 +791,7 @@ static struct pcmcia_driver reader_driver = { | |||
803 | .name = "cm4040_cs", | 791 | .name = "cm4040_cs", |
804 | }, | 792 | }, |
805 | .attach = reader_attach, | 793 | .attach = reader_attach, |
806 | .detach = reader_detach, | 794 | .remove = reader_detach, |
807 | .suspend = reader_suspend, | 795 | .suspend = reader_suspend, |
808 | .resume = reader_resume, | 796 | .resume = reader_resume, |
809 | .event = reader_event, | 797 | .event = reader_event, |
@@ -825,14 +813,8 @@ static int __init cm4040_init(void) | |||
825 | 813 | ||
826 | static void __exit cm4040_exit(void) | 814 | static void __exit cm4040_exit(void) |
827 | { | 815 | { |
828 | int i; | ||
829 | |||
830 | printk(KERN_INFO MODULE_NAME ": unloading\n"); | 816 | printk(KERN_INFO MODULE_NAME ": unloading\n"); |
831 | pcmcia_unregister_driver(&reader_driver); | 817 | 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); | 818 | unregister_chrdev(major, DEVICE_NAME); |
837 | } | 819 | } |
838 | 820 | ||
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 776103e56042..34597144d9c1 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -489,7 +489,7 @@ static void mgslpc_release(u_long arg); | |||
489 | static int mgslpc_event(event_t event, int priority, | 489 | static int mgslpc_event(event_t event, int priority, |
490 | event_callback_args_t *args); | 490 | event_callback_args_t *args); |
491 | static dev_link_t *mgslpc_attach(void); | 491 | static dev_link_t *mgslpc_attach(void); |
492 | static void mgslpc_detach(dev_link_t *); | 492 | static void mgslpc_detach(struct pcmcia_device *p_dev); |
493 | 493 | ||
494 | static dev_info_t dev_info = "synclink_cs"; | 494 | static dev_info_t dev_info = "synclink_cs"; |
495 | static dev_link_t *dev_list = NULL; | 495 | static dev_link_t *dev_list = NULL; |
@@ -598,7 +598,7 @@ static dev_link_t *mgslpc_attach(void) | |||
598 | ret = pcmcia_register_client(&link->handle, &client_reg); | 598 | ret = pcmcia_register_client(&link->handle, &client_reg); |
599 | if (ret != CS_SUCCESS) { | 599 | if (ret != CS_SUCCESS) { |
600 | cs_error(link->handle, RegisterClient, ret); | 600 | cs_error(link->handle, RegisterClient, ret); |
601 | mgslpc_detach(link); | 601 | mgslpc_detach(link->handle); |
602 | return NULL; | 602 | return NULL; |
603 | } | 603 | } |
604 | 604 | ||
@@ -736,17 +736,16 @@ static void mgslpc_release(u_long arg) | |||
736 | pcmcia_release_io(link->handle, &link->io); | 736 | pcmcia_release_io(link->handle, &link->io); |
737 | if (link->irq.AssignedIRQ) | 737 | if (link->irq.AssignedIRQ) |
738 | pcmcia_release_irq(link->handle, &link->irq); | 738 | pcmcia_release_irq(link->handle, &link->irq); |
739 | if (link->state & DEV_STALE_LINK) | ||
740 | mgslpc_detach(link); | ||
741 | } | 739 | } |
742 | 740 | ||
743 | static void mgslpc_detach(dev_link_t *link) | 741 | static void mgslpc_detach(struct pcmcia_device *p_dev) |
744 | { | 742 | { |
743 | dev_link_t *link = dev_to_instance(p_dev); | ||
745 | dev_link_t **linkp; | 744 | dev_link_t **linkp; |
746 | 745 | ||
747 | if (debug_level >= DEBUG_LEVEL_INFO) | 746 | if (debug_level >= DEBUG_LEVEL_INFO) |
748 | printk("mgslpc_detach(0x%p)\n", link); | 747 | printk("mgslpc_detach(0x%p)\n", link); |
749 | 748 | ||
750 | /* find device */ | 749 | /* find device */ |
751 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | 750 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) |
752 | if (*linkp == link) break; | 751 | if (*linkp == link) break; |
@@ -754,20 +753,10 @@ static void mgslpc_detach(dev_link_t *link) | |||
754 | return; | 753 | return; |
755 | 754 | ||
756 | if (link->state & DEV_CONFIG) { | 755 | if (link->state & DEV_CONFIG) { |
757 | /* device is configured/active, mark it so when | 756 | ((MGSLPC_INFO *)link->priv)->stop = 1; |
758 | * release() is called a proper detach() occurs. | 757 | mgslpc_release((u_long)link); |
759 | */ | ||
760 | if (debug_level >= DEBUG_LEVEL_INFO) | ||
761 | printk(KERN_DEBUG "synclinkpc: detach postponed, '%s' " | ||
762 | "still locked\n", link->dev->dev_name); | ||
763 | link->state |= DEV_STALE_LINK; | ||
764 | return; | ||
765 | } | 758 | } |
766 | 759 | ||
767 | /* Break the link with Card Services */ | ||
768 | if (link->handle) | ||
769 | pcmcia_deregister_client(link->handle); | ||
770 | |||
771 | /* Unlink device structure, and free it */ | 760 | /* Unlink device structure, and free it */ |
772 | *linkp = link->next; | 761 | *linkp = link->next; |
773 | mgslpc_remove_device((MGSLPC_INFO *)link->priv); | 762 | mgslpc_remove_device((MGSLPC_INFO *)link->priv); |
@@ -809,13 +798,6 @@ static int mgslpc_event(event_t event, int priority, | |||
809 | printk("mgslpc_event(0x%06x)\n", event); | 798 | printk("mgslpc_event(0x%06x)\n", event); |
810 | 799 | ||
811 | switch (event) { | 800 | switch (event) { |
812 | case CS_EVENT_CARD_REMOVAL: | ||
813 | link->state &= ~DEV_PRESENT; | ||
814 | if (link->state & DEV_CONFIG) { | ||
815 | ((MGSLPC_INFO *)link->priv)->stop = 1; | ||
816 | mgslpc_release((u_long)link); | ||
817 | } | ||
818 | break; | ||
819 | case CS_EVENT_CARD_INSERTION: | 801 | case CS_EVENT_CARD_INSERTION: |
820 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 802 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
821 | mgslpc_config(link); | 803 | mgslpc_config(link); |
@@ -3102,7 +3084,7 @@ static struct pcmcia_driver mgslpc_driver = { | |||
3102 | }, | 3084 | }, |
3103 | .attach = mgslpc_attach, | 3085 | .attach = mgslpc_attach, |
3104 | .event = mgslpc_event, | 3086 | .event = mgslpc_event, |
3105 | .detach = mgslpc_detach, | 3087 | .remove = mgslpc_detach, |
3106 | .id_table = mgslpc_ids, | 3088 | .id_table = mgslpc_ids, |
3107 | .suspend = mgslpc_suspend, | 3089 | .suspend = mgslpc_suspend, |
3108 | .resume = mgslpc_resume, | 3090 | .resume = mgslpc_resume, |
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 982b74af8c29..1fb8976496d9 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -94,7 +94,7 @@ static int ide_event(event_t event, int priority, | |||
94 | static dev_info_t dev_info = "ide-cs"; | 94 | static dev_info_t dev_info = "ide-cs"; |
95 | 95 | ||
96 | static dev_link_t *ide_attach(void); | 96 | static dev_link_t *ide_attach(void); |
97 | static void ide_detach(dev_link_t *); | 97 | static void ide_detach(struct pcmcia_device *p_dev); |
98 | 98 | ||
99 | static dev_link_t *dev_list = NULL; | 99 | static dev_link_t *dev_list = NULL; |
100 | 100 | ||
@@ -138,7 +138,7 @@ static dev_link_t *ide_attach(void) | |||
138 | ret = pcmcia_register_client(&link->handle, &client_reg); | 138 | ret = pcmcia_register_client(&link->handle, &client_reg); |
139 | if (ret != CS_SUCCESS) { | 139 | if (ret != CS_SUCCESS) { |
140 | cs_error(link->handle, RegisterClient, ret); | 140 | cs_error(link->handle, RegisterClient, ret); |
141 | ide_detach(link); | 141 | ide_detach(link->handle); |
142 | return NULL; | 142 | return NULL; |
143 | } | 143 | } |
144 | 144 | ||
@@ -154,10 +154,10 @@ static dev_link_t *ide_attach(void) | |||
154 | 154 | ||
155 | ======================================================================*/ | 155 | ======================================================================*/ |
156 | 156 | ||
157 | static void ide_detach(dev_link_t *link) | 157 | static void ide_detach(struct pcmcia_device *p_dev) |
158 | { | 158 | { |
159 | dev_link_t *link = dev_to_instance(p_dev); | ||
159 | dev_link_t **linkp; | 160 | dev_link_t **linkp; |
160 | int ret; | ||
161 | 161 | ||
162 | DEBUG(0, "ide_detach(0x%p)\n", link); | 162 | DEBUG(0, "ide_detach(0x%p)\n", link); |
163 | 163 | ||
@@ -170,12 +170,6 @@ static void ide_detach(dev_link_t *link) | |||
170 | if (link->state & DEV_CONFIG) | 170 | if (link->state & DEV_CONFIG) |
171 | ide_release(link); | 171 | ide_release(link); |
172 | 172 | ||
173 | if (link->handle) { | ||
174 | ret = pcmcia_deregister_client(link->handle); | ||
175 | if (ret != CS_SUCCESS) | ||
176 | cs_error(link->handle, DeregisterClient, ret); | ||
177 | } | ||
178 | |||
179 | /* Unlink, free device structure */ | 173 | /* Unlink, free device structure */ |
180 | *linkp = link->next; | 174 | *linkp = link->next; |
181 | kfree(link->priv); | 175 | kfree(link->priv); |
@@ -445,11 +439,6 @@ int ide_event(event_t event, int priority, | |||
445 | DEBUG(1, "ide_event(0x%06x)\n", event); | 439 | DEBUG(1, "ide_event(0x%06x)\n", event); |
446 | 440 | ||
447 | switch (event) { | 441 | switch (event) { |
448 | case CS_EVENT_CARD_REMOVAL: | ||
449 | link->state &= ~DEV_PRESENT; | ||
450 | if (link->state & DEV_CONFIG) | ||
451 | ide_release(link); | ||
452 | break; | ||
453 | case CS_EVENT_CARD_INSERTION: | 442 | case CS_EVENT_CARD_INSERTION: |
454 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 443 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
455 | ide_config(link); | 444 | ide_config(link); |
@@ -504,7 +493,7 @@ static struct pcmcia_driver ide_cs_driver = { | |||
504 | }, | 493 | }, |
505 | .attach = ide_attach, | 494 | .attach = ide_attach, |
506 | .event = ide_event, | 495 | .event = ide_event, |
507 | .detach = ide_detach, | 496 | .remove = ide_detach, |
508 | .id_table = ide_ids, | 497 | .id_table = ide_ids, |
509 | .suspend = ide_suspend, | 498 | .suspend = ide_suspend, |
510 | .resume = ide_resume, | 499 | .resume = ide_resume, |
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 6d9816e10ecb..2d898d3afc97 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c | |||
@@ -63,7 +63,7 @@ static int avmcs_event(event_t event, int priority, | |||
63 | */ | 63 | */ |
64 | 64 | ||
65 | static dev_link_t *avmcs_attach(void); | 65 | static dev_link_t *avmcs_attach(void); |
66 | static void avmcs_detach(dev_link_t *); | 66 | static void avmcs_detach(struct pcmcia_device *p_dev); |
67 | 67 | ||
68 | /* | 68 | /* |
69 | The dev_info variable is the "key" that is used to match up this | 69 | The dev_info variable is the "key" that is used to match up this |
@@ -165,7 +165,7 @@ static dev_link_t *avmcs_attach(void) | |||
165 | ret = pcmcia_register_client(&link->handle, &client_reg); | 165 | ret = pcmcia_register_client(&link->handle, &client_reg); |
166 | if (ret != 0) { | 166 | if (ret != 0) { |
167 | cs_error(link->handle, RegisterClient, ret); | 167 | cs_error(link->handle, RegisterClient, ret); |
168 | avmcs_detach(link); | 168 | avmcs_detach(link->handle); |
169 | goto err; | 169 | goto err; |
170 | } | 170 | } |
171 | return link; | 171 | return link; |
@@ -185,8 +185,9 @@ static dev_link_t *avmcs_attach(void) | |||
185 | 185 | ||
186 | ======================================================================*/ | 186 | ======================================================================*/ |
187 | 187 | ||
188 | static void avmcs_detach(dev_link_t *link) | 188 | static void avmcs_detach(struct pcmcia_device *p_dev) |
189 | { | 189 | { |
190 | dev_link_t *link = dev_to_instance(p_dev); | ||
190 | dev_link_t **linkp; | 191 | dev_link_t **linkp; |
191 | 192 | ||
192 | /* Locate device structure */ | 193 | /* Locate device structure */ |
@@ -195,21 +196,9 @@ static void avmcs_detach(dev_link_t *link) | |||
195 | if (*linkp == NULL) | 196 | if (*linkp == NULL) |
196 | return; | 197 | return; |
197 | 198 | ||
198 | /* | 199 | if (link->state & DEV_CONFIG) |
199 | If the device is currently configured and active, we won't | 200 | avmcs_release(link); |
200 | actually delete it yet. Instead, it is marked so that when | ||
201 | the release() function is called, that will trigger a proper | ||
202 | detach(). | ||
203 | */ | ||
204 | if (link->state & DEV_CONFIG) { | ||
205 | link->state |= DEV_STALE_LINK; | ||
206 | return; | ||
207 | } | ||
208 | 201 | ||
209 | /* Break the link with Card Services */ | ||
210 | if (link->handle) | ||
211 | pcmcia_deregister_client(link->handle); | ||
212 | |||
213 | /* Unlink device structure, free pieces */ | 202 | /* Unlink device structure, free pieces */ |
214 | *linkp = link->next; | 203 | *linkp = link->next; |
215 | kfree(link->priv); | 204 | kfree(link->priv); |
@@ -424,10 +413,6 @@ static void avmcs_release(dev_link_t *link) | |||
424 | pcmcia_release_io(link->handle, &link->io); | 413 | pcmcia_release_io(link->handle, &link->io); |
425 | pcmcia_release_irq(link->handle, &link->irq); | 414 | pcmcia_release_irq(link->handle, &link->irq); |
426 | link->state &= ~DEV_CONFIG; | 415 | link->state &= ~DEV_CONFIG; |
427 | |||
428 | if (link->state & DEV_STALE_LINK) | ||
429 | avmcs_detach(link); | ||
430 | |||
431 | } /* avmcs_release */ | 416 | } /* avmcs_release */ |
432 | 417 | ||
433 | static int avmcs_suspend(struct pcmcia_device *dev) | 418 | static int avmcs_suspend(struct pcmcia_device *dev) |
@@ -472,11 +457,6 @@ static int avmcs_event(event_t event, int priority, | |||
472 | dev_link_t *link = args->client_data; | 457 | dev_link_t *link = args->client_data; |
473 | 458 | ||
474 | switch (event) { | 459 | switch (event) { |
475 | case CS_EVENT_CARD_REMOVAL: | ||
476 | link->state &= ~DEV_PRESENT; | ||
477 | if (link->state & DEV_CONFIG) | ||
478 | avmcs_release(link); | ||
479 | break; | ||
480 | case CS_EVENT_CARD_INSERTION: | 460 | case CS_EVENT_CARD_INSERTION: |
481 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 461 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
482 | avmcs_config(link); | 462 | avmcs_config(link); |
@@ -500,7 +480,7 @@ static struct pcmcia_driver avmcs_driver = { | |||
500 | }, | 480 | }, |
501 | .attach = avmcs_attach, | 481 | .attach = avmcs_attach, |
502 | .event = avmcs_event, | 482 | .event = avmcs_event, |
503 | .detach = avmcs_detach, | 483 | .remove = avmcs_detach, |
504 | .id_table = avmcs_ids, | 484 | .id_table = avmcs_ids, |
505 | .suspend= avmcs_suspend, | 485 | .suspend= avmcs_suspend, |
506 | .resume = avmcs_resume, | 486 | .resume = avmcs_resume, |
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 433cec4269a3..6b322e88c6c3 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c | |||
@@ -79,7 +79,7 @@ static int avma1cs_event(event_t event, int priority, | |||
79 | */ | 79 | */ |
80 | 80 | ||
81 | static dev_link_t *avma1cs_attach(void); | 81 | static dev_link_t *avma1cs_attach(void); |
82 | static void avma1cs_detach(dev_link_t *); | 82 | static void avma1cs_detach(struct pcmcia_device *p_dev); |
83 | 83 | ||
84 | /* | 84 | /* |
85 | The dev_info variable is the "key" that is used to match up this | 85 | The dev_info variable is the "key" that is used to match up this |
@@ -187,7 +187,7 @@ static dev_link_t *avma1cs_attach(void) | |||
187 | ret = pcmcia_register_client(&link->handle, &client_reg); | 187 | ret = pcmcia_register_client(&link->handle, &client_reg); |
188 | if (ret != 0) { | 188 | if (ret != 0) { |
189 | cs_error(link->handle, RegisterClient, ret); | 189 | cs_error(link->handle, RegisterClient, ret); |
190 | avma1cs_detach(link); | 190 | avma1cs_detach(link->handle); |
191 | return NULL; | 191 | return NULL; |
192 | } | 192 | } |
193 | 193 | ||
@@ -203,42 +203,26 @@ static dev_link_t *avma1cs_attach(void) | |||
203 | 203 | ||
204 | ======================================================================*/ | 204 | ======================================================================*/ |
205 | 205 | ||
206 | static void avma1cs_detach(dev_link_t *link) | 206 | static void avma1cs_detach(struct pcmcia_device *p_dev) |
207 | { | 207 | { |
208 | dev_link_t *link = dev_to_instance(p_dev); | ||
208 | dev_link_t **linkp; | 209 | dev_link_t **linkp; |
209 | 210 | ||
210 | DEBUG(0, "avma1cs_detach(0x%p)\n", link); | 211 | DEBUG(0, "avma1cs_detach(0x%p)\n", link); |
211 | 212 | ||
212 | /* Locate device structure */ | 213 | /* Locate device structure */ |
213 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | 214 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) |
214 | if (*linkp == link) break; | 215 | if (*linkp == link) break; |
215 | if (*linkp == NULL) | 216 | if (*linkp == NULL) |
216 | return; | 217 | return; |
217 | 218 | ||
218 | /* | 219 | if (link->state & DEV_CONFIG) |
219 | If the device is currently configured and active, we won't | 220 | avma1cs_release(link); |
220 | actually delete it yet. Instead, it is marked so that when | ||
221 | the release() function is called, that will trigger a proper | ||
222 | detach(). | ||
223 | */ | ||
224 | if (link->state & DEV_CONFIG) { | ||
225 | #ifdef PCMCIA_DEBUG | ||
226 | printk(KERN_DEBUG "avma1_cs: detach postponed, '%s' " | ||
227 | "still locked\n", link->dev->dev_name); | ||
228 | #endif | ||
229 | link->state |= DEV_STALE_LINK; | ||
230 | return; | ||
231 | } | ||
232 | 221 | ||
233 | /* Break the link with Card Services */ | ||
234 | if (link->handle) | ||
235 | pcmcia_deregister_client(link->handle); | ||
236 | |||
237 | /* Unlink device structure, free pieces */ | 222 | /* Unlink device structure, free pieces */ |
238 | *linkp = link->next; | 223 | *linkp = link->next; |
239 | kfree(link->priv); | 224 | kfree(link->priv); |
240 | kfree(link); | 225 | kfree(link); |
241 | |||
242 | } /* avma1cs_detach */ | 226 | } /* avma1cs_detach */ |
243 | 227 | ||
244 | /*====================================================================== | 228 | /*====================================================================== |
@@ -440,9 +424,6 @@ static void avma1cs_release(dev_link_t *link) | |||
440 | pcmcia_release_io(link->handle, &link->io); | 424 | pcmcia_release_io(link->handle, &link->io); |
441 | pcmcia_release_irq(link->handle, &link->irq); | 425 | pcmcia_release_irq(link->handle, &link->irq); |
442 | link->state &= ~DEV_CONFIG; | 426 | link->state &= ~DEV_CONFIG; |
443 | |||
444 | if (link->state & DEV_STALE_LINK) | ||
445 | avma1cs_detach(link); | ||
446 | } /* avma1cs_release */ | 427 | } /* avma1cs_release */ |
447 | 428 | ||
448 | static int avma1cs_suspend(struct pcmcia_device *dev) | 429 | static int avma1cs_suspend(struct pcmcia_device *dev) |
@@ -489,10 +470,6 @@ static int avma1cs_event(event_t event, int priority, | |||
489 | DEBUG(1, "avma1cs_event(0x%06x)\n", event); | 470 | DEBUG(1, "avma1cs_event(0x%06x)\n", event); |
490 | 471 | ||
491 | switch (event) { | 472 | switch (event) { |
492 | case CS_EVENT_CARD_REMOVAL: | ||
493 | if (link->state & DEV_CONFIG) | ||
494 | avma1cs_release(link); | ||
495 | break; | ||
496 | case CS_EVENT_CARD_INSERTION: | 473 | case CS_EVENT_CARD_INSERTION: |
497 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 474 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
498 | avma1cs_config(link); | 475 | avma1cs_config(link); |
@@ -515,7 +492,7 @@ static struct pcmcia_driver avma1cs_driver = { | |||
515 | }, | 492 | }, |
516 | .attach = avma1cs_attach, | 493 | .attach = avma1cs_attach, |
517 | .event = avma1cs_event, | 494 | .event = avma1cs_event, |
518 | .detach = avma1cs_detach, | 495 | .remove = avma1cs_detach, |
519 | .id_table = avma1cs_ids, | 496 | .id_table = avma1cs_ids, |
520 | .suspend = avma1cs_suspend, | 497 | .suspend = avma1cs_suspend, |
521 | .resume = avma1cs_resume, | 498 | .resume = avma1cs_resume, |
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index 0cbe04593d87..48cc677249f1 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c | |||
@@ -106,7 +106,7 @@ static int elsa_cs_event(event_t event, int priority, | |||
106 | */ | 106 | */ |
107 | 107 | ||
108 | static dev_link_t *elsa_cs_attach(void); | 108 | static dev_link_t *elsa_cs_attach(void); |
109 | static void elsa_cs_detach(dev_link_t *); | 109 | static void elsa_cs_detach(struct pcmcia_device *p_dev); |
110 | 110 | ||
111 | /* | 111 | /* |
112 | The dev_info variable is the "key" that is used to match up this | 112 | The dev_info variable is the "key" that is used to match up this |
@@ -216,7 +216,7 @@ static dev_link_t *elsa_cs_attach(void) | |||
216 | ret = pcmcia_register_client(&link->handle, &client_reg); | 216 | ret = pcmcia_register_client(&link->handle, &client_reg); |
217 | if (ret != CS_SUCCESS) { | 217 | if (ret != CS_SUCCESS) { |
218 | cs_error(link->handle, RegisterClient, ret); | 218 | cs_error(link->handle, RegisterClient, ret); |
219 | elsa_cs_detach(link); | 219 | elsa_cs_detach(link->handle); |
220 | return NULL; | 220 | return NULL; |
221 | } | 221 | } |
222 | 222 | ||
@@ -232,11 +232,11 @@ static dev_link_t *elsa_cs_attach(void) | |||
232 | 232 | ||
233 | ======================================================================*/ | 233 | ======================================================================*/ |
234 | 234 | ||
235 | static void elsa_cs_detach(dev_link_t *link) | 235 | static void elsa_cs_detach(struct pcmcia_device *p_dev) |
236 | { | 236 | { |
237 | dev_link_t *link = dev_to_instance(p_dev); | ||
237 | dev_link_t **linkp; | 238 | dev_link_t **linkp; |
238 | local_info_t *info = link->priv; | 239 | local_info_t *info = link->priv; |
239 | int ret; | ||
240 | 240 | ||
241 | DEBUG(0, "elsa_cs_detach(0x%p)\n", link); | 241 | DEBUG(0, "elsa_cs_detach(0x%p)\n", link); |
242 | 242 | ||
@@ -246,14 +246,9 @@ static void elsa_cs_detach(dev_link_t *link) | |||
246 | if (*linkp == NULL) | 246 | if (*linkp == NULL) |
247 | return; | 247 | return; |
248 | 248 | ||
249 | if (link->state & DEV_CONFIG) | 249 | if (link->state & DEV_CONFIG) { |
250 | ((local_info_t*)link->priv)->busy = 1; | ||
250 | elsa_cs_release(link); | 251 | elsa_cs_release(link); |
251 | |||
252 | /* Break the link with Card Services */ | ||
253 | if (link->handle) { | ||
254 | ret = pcmcia_deregister_client(link->handle); | ||
255 | if (ret != CS_SUCCESS) | ||
256 | cs_error(link->handle, DeregisterClient, ret); | ||
257 | } | 252 | } |
258 | 253 | ||
259 | /* Unlink device structure and free it */ | 254 | /* Unlink device structure and free it */ |
@@ -495,13 +490,6 @@ static int elsa_cs_event(event_t event, int priority, | |||
495 | DEBUG(1, "elsa_cs_event(%d)\n", event); | 490 | DEBUG(1, "elsa_cs_event(%d)\n", event); |
496 | 491 | ||
497 | switch (event) { | 492 | switch (event) { |
498 | case CS_EVENT_CARD_REMOVAL: | ||
499 | link->state &= ~DEV_PRESENT; | ||
500 | if (link->state & DEV_CONFIG) { | ||
501 | ((local_info_t*)link->priv)->busy = 1; | ||
502 | elsa_cs_release(link); | ||
503 | } | ||
504 | break; | ||
505 | case CS_EVENT_CARD_INSERTION: | 493 | case CS_EVENT_CARD_INSERTION: |
506 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 494 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
507 | elsa_cs_config(link); | 495 | elsa_cs_config(link); |
@@ -524,7 +512,7 @@ static struct pcmcia_driver elsa_cs_driver = { | |||
524 | }, | 512 | }, |
525 | .attach = elsa_cs_attach, | 513 | .attach = elsa_cs_attach, |
526 | .event = elsa_cs_event, | 514 | .event = elsa_cs_event, |
527 | .detach = elsa_cs_detach, | 515 | .remove = elsa_cs_detach, |
528 | .id_table = elsa_ids, | 516 | .id_table = elsa_ids, |
529 | .suspend = elsa_suspend, | 517 | .suspend = elsa_suspend, |
530 | .resume = elsa_resume, | 518 | .resume = elsa_resume, |
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 27dce7c7b760..d2386f6867b7 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c | |||
@@ -107,7 +107,7 @@ static int sedlbauer_event(event_t event, int priority, | |||
107 | */ | 107 | */ |
108 | 108 | ||
109 | static dev_link_t *sedlbauer_attach(void); | 109 | static dev_link_t *sedlbauer_attach(void); |
110 | static void sedlbauer_detach(dev_link_t *); | 110 | static void sedlbauer_detach(struct pcmcia_device *p_dev); |
111 | 111 | ||
112 | /* | 112 | /* |
113 | You'll also need to prototype all the functions that will actually | 113 | You'll also need to prototype all the functions that will actually |
@@ -230,7 +230,7 @@ static dev_link_t *sedlbauer_attach(void) | |||
230 | ret = pcmcia_register_client(&link->handle, &client_reg); | 230 | ret = pcmcia_register_client(&link->handle, &client_reg); |
231 | if (ret != CS_SUCCESS) { | 231 | if (ret != CS_SUCCESS) { |
232 | cs_error(link->handle, RegisterClient, ret); | 232 | cs_error(link->handle, RegisterClient, ret); |
233 | sedlbauer_detach(link); | 233 | sedlbauer_detach(link->handle); |
234 | return NULL; | 234 | return NULL; |
235 | } | 235 | } |
236 | 236 | ||
@@ -246,8 +246,9 @@ static dev_link_t *sedlbauer_attach(void) | |||
246 | 246 | ||
247 | ======================================================================*/ | 247 | ======================================================================*/ |
248 | 248 | ||
249 | static void sedlbauer_detach(dev_link_t *link) | 249 | static void sedlbauer_detach(struct pcmcia_device *p_dev) |
250 | { | 250 | { |
251 | dev_link_t *link = dev_to_instance(p_dev); | ||
251 | dev_link_t **linkp; | 252 | dev_link_t **linkp; |
252 | 253 | ||
253 | DEBUG(0, "sedlbauer_detach(0x%p)\n", link); | 254 | DEBUG(0, "sedlbauer_detach(0x%p)\n", link); |
@@ -258,25 +259,11 @@ static void sedlbauer_detach(dev_link_t *link) | |||
258 | if (*linkp == NULL) | 259 | if (*linkp == NULL) |
259 | return; | 260 | return; |
260 | 261 | ||
261 | /* | ||
262 | If the device is currently configured and active, we won't | ||
263 | actually delete it yet. Instead, it is marked so that when | ||
264 | the release() function is called, that will trigger a proper | ||
265 | detach(). | ||
266 | */ | ||
267 | if (link->state & DEV_CONFIG) { | 262 | if (link->state & DEV_CONFIG) { |
268 | #ifdef PCMCIA_DEBUG | 263 | ((local_info_t *)link->priv)->stop = 1; |
269 | printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' " | 264 | sedlbauer_release(link); |
270 | "still locked\n", link->dev->dev_name); | ||
271 | #endif | ||
272 | link->state |= DEV_STALE_LINK; | ||
273 | return; | ||
274 | } | 265 | } |
275 | 266 | ||
276 | /* Break the link with Card Services */ | ||
277 | if (link->handle) | ||
278 | pcmcia_deregister_client(link->handle); | ||
279 | |||
280 | /* Unlink device structure, and free it */ | 267 | /* Unlink device structure, and free it */ |
281 | *linkp = link->next; | 268 | *linkp = link->next; |
282 | /* This points to the parent local_info_t struct */ | 269 | /* This points to the parent local_info_t struct */ |
@@ -547,10 +534,6 @@ static void sedlbauer_release(dev_link_t *link) | |||
547 | if (link->irq.AssignedIRQ) | 534 | if (link->irq.AssignedIRQ) |
548 | pcmcia_release_irq(link->handle, &link->irq); | 535 | pcmcia_release_irq(link->handle, &link->irq); |
549 | link->state &= ~DEV_CONFIG; | 536 | link->state &= ~DEV_CONFIG; |
550 | |||
551 | if (link->state & DEV_STALE_LINK) | ||
552 | sedlbauer_detach(link); | ||
553 | |||
554 | } /* sedlbauer_release */ | 537 | } /* sedlbauer_release */ |
555 | 538 | ||
556 | static int sedlbauer_suspend(struct pcmcia_device *p_dev) | 539 | static int sedlbauer_suspend(struct pcmcia_device *p_dev) |
@@ -599,13 +582,6 @@ static int sedlbauer_event(event_t event, int priority, | |||
599 | DEBUG(1, "sedlbauer_event(0x%06x)\n", event); | 582 | DEBUG(1, "sedlbauer_event(0x%06x)\n", event); |
600 | 583 | ||
601 | switch (event) { | 584 | switch (event) { |
602 | case CS_EVENT_CARD_REMOVAL: | ||
603 | link->state &= ~DEV_PRESENT; | ||
604 | if (link->state & DEV_CONFIG) { | ||
605 | ((local_info_t *)link->priv)->stop = 1; | ||
606 | sedlbauer_release(link); | ||
607 | } | ||
608 | break; | ||
609 | case CS_EVENT_CARD_INSERTION: | 585 | case CS_EVENT_CARD_INSERTION: |
610 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 586 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
611 | sedlbauer_config(link); | 587 | sedlbauer_config(link); |
@@ -633,7 +609,7 @@ static struct pcmcia_driver sedlbauer_driver = { | |||
633 | }, | 609 | }, |
634 | .attach = sedlbauer_attach, | 610 | .attach = sedlbauer_attach, |
635 | .event = sedlbauer_event, | 611 | .event = sedlbauer_event, |
636 | .detach = sedlbauer_detach, | 612 | .remove = sedlbauer_detach, |
637 | .id_table = sedlbauer_ids, | 613 | .id_table = sedlbauer_ids, |
638 | .suspend = sedlbauer_suspend, | 614 | .suspend = sedlbauer_suspend, |
639 | .resume = sedlbauer_resume, | 615 | .resume = sedlbauer_resume, |
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index 70213bc1d30c..cd0f86f0975b 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c | |||
@@ -87,7 +87,7 @@ static int teles_cs_event(event_t event, int priority, | |||
87 | */ | 87 | */ |
88 | 88 | ||
89 | static dev_link_t *teles_attach(void); | 89 | static dev_link_t *teles_attach(void); |
90 | static void teles_detach(dev_link_t *); | 90 | static void teles_detach(struct pcmcia_device *p_dev); |
91 | 91 | ||
92 | /* | 92 | /* |
93 | The dev_info variable is the "key" that is used to match up this | 93 | The dev_info variable is the "key" that is used to match up this |
@@ -197,7 +197,7 @@ static dev_link_t *teles_attach(void) | |||
197 | ret = pcmcia_register_client(&link->handle, &client_reg); | 197 | ret = pcmcia_register_client(&link->handle, &client_reg); |
198 | if (ret != CS_SUCCESS) { | 198 | if (ret != CS_SUCCESS) { |
199 | cs_error(link->handle, RegisterClient, ret); | 199 | cs_error(link->handle, RegisterClient, ret); |
200 | teles_detach(link); | 200 | teles_detach(link->handle); |
201 | return NULL; | 201 | return NULL; |
202 | } | 202 | } |
203 | 203 | ||
@@ -213,11 +213,11 @@ static dev_link_t *teles_attach(void) | |||
213 | 213 | ||
214 | ======================================================================*/ | 214 | ======================================================================*/ |
215 | 215 | ||
216 | static void teles_detach(dev_link_t *link) | 216 | static void teles_detach(struct pcmcia_device *p_dev) |
217 | { | 217 | { |
218 | dev_link_t *link = dev_to_instance(p_dev); | ||
218 | dev_link_t **linkp; | 219 | dev_link_t **linkp; |
219 | local_info_t *info = link->priv; | 220 | local_info_t *info = link->priv; |
220 | int ret; | ||
221 | 221 | ||
222 | DEBUG(0, "teles_detach(0x%p)\n", link); | 222 | DEBUG(0, "teles_detach(0x%p)\n", link); |
223 | 223 | ||
@@ -227,14 +227,9 @@ static void teles_detach(dev_link_t *link) | |||
227 | if (*linkp == NULL) | 227 | if (*linkp == NULL) |
228 | return; | 228 | return; |
229 | 229 | ||
230 | if (link->state & DEV_CONFIG) | 230 | if (link->state & DEV_CONFIG) { |
231 | info->busy = 1; | ||
231 | teles_cs_release(link); | 232 | teles_cs_release(link); |
232 | |||
233 | /* Break the link with Card Services */ | ||
234 | if (link->handle) { | ||
235 | ret = pcmcia_deregister_client(link->handle); | ||
236 | if (ret != CS_SUCCESS) | ||
237 | cs_error(link->handle, DeregisterClient, ret); | ||
238 | } | 233 | } |
239 | 234 | ||
240 | /* Unlink device structure and free it */ | 235 | /* Unlink device structure and free it */ |
@@ -476,13 +471,6 @@ static int teles_cs_event(event_t event, int priority, | |||
476 | DEBUG(1, "teles_cs_event(%d)\n", event); | 471 | DEBUG(1, "teles_cs_event(%d)\n", event); |
477 | 472 | ||
478 | switch (event) { | 473 | switch (event) { |
479 | case CS_EVENT_CARD_REMOVAL: | ||
480 | link->state &= ~DEV_PRESENT; | ||
481 | if (link->state & DEV_CONFIG) { | ||
482 | ((local_info_t*)link->priv)->busy = 1; | ||
483 | teles_cs_release(link); | ||
484 | } | ||
485 | break; | ||
486 | case CS_EVENT_CARD_INSERTION: | 474 | case CS_EVENT_CARD_INSERTION: |
487 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 475 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
488 | teles_cs_config(link); | 476 | teles_cs_config(link); |
@@ -504,7 +492,7 @@ static struct pcmcia_driver teles_cs_driver = { | |||
504 | }, | 492 | }, |
505 | .attach = teles_attach, | 493 | .attach = teles_attach, |
506 | .event = teles_cs_event, | 494 | .event = teles_cs_event, |
507 | .detach = teles_detach, | 495 | .remove = teles_detach, |
508 | .id_table = teles_ids, | 496 | .id_table = teles_ids, |
509 | .suspend = teles_suspend, | 497 | .suspend = teles_suspend, |
510 | .resume = teles_resume, | 498 | .resume = teles_resume, |
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 86443cf44dc6..3ddcb1bf6824 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c | |||
@@ -722,18 +722,6 @@ static int pcmciamtd_event(event_t event, int priority, | |||
722 | 722 | ||
723 | DEBUG(1, "event=0x%06x", event); | 723 | DEBUG(1, "event=0x%06x", event); |
724 | switch (event) { | 724 | switch (event) { |
725 | case CS_EVENT_CARD_REMOVAL: | ||
726 | DEBUG(2, "EVENT_CARD_REMOVAL"); | ||
727 | link->state &= ~DEV_PRESENT; | ||
728 | if (link->state & DEV_CONFIG) { | ||
729 | struct pcmciamtd_dev *dev = link->priv; | ||
730 | if(dev->mtd_info) { | ||
731 | del_mtd_device(dev->mtd_info); | ||
732 | info("mtd%d: Removed", dev->mtd_info->index); | ||
733 | } | ||
734 | pcmciamtd_release(link); | ||
735 | } | ||
736 | break; | ||
737 | case CS_EVENT_CARD_INSERTION: | 725 | case CS_EVENT_CARD_INSERTION: |
738 | DEBUG(2, "EVENT_CARD_INSERTION"); | 726 | DEBUG(2, "EVENT_CARD_INSERTION"); |
739 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 727 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
@@ -752,23 +740,21 @@ static int pcmciamtd_event(event_t event, int priority, | |||
752 | * when the device is released. | 740 | * when the device is released. |
753 | */ | 741 | */ |
754 | 742 | ||
755 | static void pcmciamtd_detach(dev_link_t *link) | 743 | static void pcmciamtd_detach(struct pcmcia_device *p_dev) |
756 | { | 744 | { |
745 | dev_link_t *link = dev_to_instance(p_dev); | ||
746 | |||
757 | DEBUG(3, "link=0x%p", link); | 747 | DEBUG(3, "link=0x%p", link); |
758 | 748 | ||
759 | if(link->state & DEV_CONFIG) { | 749 | if(link->state & DEV_CONFIG) { |
760 | pcmciamtd_release(link); | 750 | struct pcmciamtd_dev *dev = link->priv; |
761 | } | 751 | if(dev->mtd_info) { |
752 | del_mtd_device(dev->mtd_info); | ||
753 | info("mtd%d: Removed", dev->mtd_info->index); | ||
754 | } | ||
762 | 755 | ||
763 | if (link->handle) { | 756 | pcmciamtd_release(link); |
764 | int ret; | ||
765 | DEBUG(2, "Deregistering with card services"); | ||
766 | ret = pcmcia_deregister_client(link->handle); | ||
767 | if (ret != CS_SUCCESS) | ||
768 | cs_error(link->handle, DeregisterClient, ret); | ||
769 | } | 757 | } |
770 | |||
771 | link->state |= DEV_STALE_LINK; | ||
772 | } | 758 | } |
773 | 759 | ||
774 | 760 | ||
@@ -807,7 +793,7 @@ static dev_link_t *pcmciamtd_attach(void) | |||
807 | ret = pcmcia_register_client(&link->handle, &client_reg); | 793 | ret = pcmcia_register_client(&link->handle, &client_reg); |
808 | if (ret != 0) { | 794 | if (ret != 0) { |
809 | cs_error(link->handle, RegisterClient, ret); | 795 | cs_error(link->handle, RegisterClient, ret); |
810 | pcmciamtd_detach(link); | 796 | pcmciamtd_detach(link->handle); |
811 | return NULL; | 797 | return NULL; |
812 | } | 798 | } |
813 | DEBUG(2, "link = %p", link); | 799 | DEBUG(2, "link = %p", link); |
@@ -847,7 +833,7 @@ static struct pcmcia_driver pcmciamtd_driver = { | |||
847 | }, | 833 | }, |
848 | .attach = pcmciamtd_attach, | 834 | .attach = pcmciamtd_attach, |
849 | .event = pcmciamtd_event, | 835 | .event = pcmciamtd_event, |
850 | .detach = pcmciamtd_detach, | 836 | .remove = pcmciamtd_detach, |
851 | .owner = THIS_MODULE, | 837 | .owner = THIS_MODULE, |
852 | .id_table = pcmciamtd_ids, | 838 | .id_table = pcmciamtd_ids, |
853 | .suspend = pcmciamtd_suspend, | 839 | .suspend = pcmciamtd_suspend, |
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 80414a77fe75..60a3bc2b8fc4 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c | |||
@@ -253,7 +253,7 @@ static void set_rx_mode(struct net_device *dev); | |||
253 | static dev_info_t dev_info = "3c574_cs"; | 253 | static dev_info_t dev_info = "3c574_cs"; |
254 | 254 | ||
255 | static dev_link_t *tc574_attach(void); | 255 | static dev_link_t *tc574_attach(void); |
256 | static void tc574_detach(dev_link_t *); | 256 | static void tc574_detach(struct pcmcia_device *p_dev); |
257 | 257 | ||
258 | static dev_link_t *dev_list; | 258 | static dev_link_t *dev_list; |
259 | 259 | ||
@@ -316,7 +316,7 @@ static dev_link_t *tc574_attach(void) | |||
316 | ret = pcmcia_register_client(&link->handle, &client_reg); | 316 | ret = pcmcia_register_client(&link->handle, &client_reg); |
317 | if (ret != 0) { | 317 | if (ret != 0) { |
318 | cs_error(link->handle, RegisterClient, ret); | 318 | cs_error(link->handle, RegisterClient, ret); |
319 | tc574_detach(link); | 319 | tc574_detach(link->handle); |
320 | return NULL; | 320 | return NULL; |
321 | } | 321 | } |
322 | 322 | ||
@@ -332,8 +332,9 @@ static dev_link_t *tc574_attach(void) | |||
332 | 332 | ||
333 | */ | 333 | */ |
334 | 334 | ||
335 | static void tc574_detach(dev_link_t *link) | 335 | static void tc574_detach(struct pcmcia_device *p_dev) |
336 | { | 336 | { |
337 | dev_link_t *link = dev_to_instance(p_dev); | ||
337 | struct net_device *dev = link->priv; | 338 | struct net_device *dev = link->priv; |
338 | dev_link_t **linkp; | 339 | dev_link_t **linkp; |
339 | 340 | ||
@@ -351,9 +352,6 @@ static void tc574_detach(dev_link_t *link) | |||
351 | if (link->state & DEV_CONFIG) | 352 | if (link->state & DEV_CONFIG) |
352 | tc574_release(link); | 353 | tc574_release(link); |
353 | 354 | ||
354 | if (link->handle) | ||
355 | pcmcia_deregister_client(link->handle); | ||
356 | |||
357 | /* Unlink device structure, free bits */ | 355 | /* Unlink device structure, free bits */ |
358 | *linkp = link->next; | 356 | *linkp = link->next; |
359 | free_netdev(dev); | 357 | free_netdev(dev); |
@@ -590,16 +588,10 @@ static int tc574_event(event_t event, int priority, | |||
590 | event_callback_args_t *args) | 588 | event_callback_args_t *args) |
591 | { | 589 | { |
592 | dev_link_t *link = args->client_data; | 590 | dev_link_t *link = args->client_data; |
593 | struct net_device *dev = link->priv; | ||
594 | 591 | ||
595 | DEBUG(1, "3c574_event(0x%06x)\n", event); | 592 | DEBUG(1, "3c574_event(0x%06x)\n", event); |
596 | 593 | ||
597 | switch (event) { | 594 | switch (event) { |
598 | case CS_EVENT_CARD_REMOVAL: | ||
599 | link->state &= ~DEV_PRESENT; | ||
600 | if (link->state & DEV_CONFIG) | ||
601 | netif_device_detach(dev); | ||
602 | break; | ||
603 | case CS_EVENT_CARD_INSERTION: | 595 | case CS_EVENT_CARD_INSERTION: |
604 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 596 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
605 | tc574_config(link); | 597 | tc574_config(link); |
@@ -1304,7 +1296,7 @@ static struct pcmcia_driver tc574_driver = { | |||
1304 | }, | 1296 | }, |
1305 | .attach = tc574_attach, | 1297 | .attach = tc574_attach, |
1306 | .event = tc574_event, | 1298 | .event = tc574_event, |
1307 | .detach = tc574_detach, | 1299 | .remove = tc574_detach, |
1308 | .id_table = tc574_ids, | 1300 | .id_table = tc574_ids, |
1309 | .suspend = tc574_suspend, | 1301 | .suspend = tc574_suspend, |
1310 | .resume = tc574_resume, | 1302 | .resume = tc574_resume, |
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index bbda681ac102..09b96c76216e 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c | |||
@@ -164,7 +164,7 @@ static struct ethtool_ops netdev_ethtool_ops; | |||
164 | static dev_info_t dev_info = "3c589_cs"; | 164 | static dev_info_t dev_info = "3c589_cs"; |
165 | 165 | ||
166 | static dev_link_t *tc589_attach(void); | 166 | static dev_link_t *tc589_attach(void); |
167 | static void tc589_detach(dev_link_t *); | 167 | static void tc589_detach(struct pcmcia_device *p_dev); |
168 | 168 | ||
169 | static dev_link_t *dev_list; | 169 | static dev_link_t *dev_list; |
170 | 170 | ||
@@ -230,7 +230,7 @@ static dev_link_t *tc589_attach(void) | |||
230 | ret = pcmcia_register_client(&link->handle, &client_reg); | 230 | ret = pcmcia_register_client(&link->handle, &client_reg); |
231 | if (ret != 0) { | 231 | if (ret != 0) { |
232 | cs_error(link->handle, RegisterClient, ret); | 232 | cs_error(link->handle, RegisterClient, ret); |
233 | tc589_detach(link); | 233 | tc589_detach(link->handle); |
234 | return NULL; | 234 | return NULL; |
235 | } | 235 | } |
236 | 236 | ||
@@ -246,8 +246,9 @@ static dev_link_t *tc589_attach(void) | |||
246 | 246 | ||
247 | ======================================================================*/ | 247 | ======================================================================*/ |
248 | 248 | ||
249 | static void tc589_detach(dev_link_t *link) | 249 | static void tc589_detach(struct pcmcia_device *p_dev) |
250 | { | 250 | { |
251 | dev_link_t *link = dev_to_instance(p_dev); | ||
251 | struct net_device *dev = link->priv; | 252 | struct net_device *dev = link->priv; |
252 | dev_link_t **linkp; | 253 | dev_link_t **linkp; |
253 | 254 | ||
@@ -264,10 +265,7 @@ static void tc589_detach(dev_link_t *link) | |||
264 | 265 | ||
265 | if (link->state & DEV_CONFIG) | 266 | if (link->state & DEV_CONFIG) |
266 | tc589_release(link); | 267 | tc589_release(link); |
267 | 268 | ||
268 | if (link->handle) | ||
269 | pcmcia_deregister_client(link->handle); | ||
270 | |||
271 | /* Unlink device structure, free bits */ | 269 | /* Unlink device structure, free bits */ |
272 | *linkp = link->next; | 270 | *linkp = link->next; |
273 | free_netdev(dev); | 271 | free_netdev(dev); |
@@ -466,16 +464,10 @@ static int tc589_event(event_t event, int priority, | |||
466 | event_callback_args_t *args) | 464 | event_callback_args_t *args) |
467 | { | 465 | { |
468 | dev_link_t *link = args->client_data; | 466 | dev_link_t *link = args->client_data; |
469 | struct net_device *dev = link->priv; | ||
470 | 467 | ||
471 | DEBUG(1, "3c589_event(0x%06x)\n", event); | 468 | DEBUG(1, "3c589_event(0x%06x)\n", event); |
472 | 469 | ||
473 | switch (event) { | 470 | switch (event) { |
474 | case CS_EVENT_CARD_REMOVAL: | ||
475 | link->state &= ~DEV_PRESENT; | ||
476 | if (link->state & DEV_CONFIG) | ||
477 | netif_device_detach(dev); | ||
478 | break; | ||
479 | case CS_EVENT_CARD_INSERTION: | 471 | case CS_EVENT_CARD_INSERTION: |
480 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 472 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
481 | tc589_config(link); | 473 | tc589_config(link); |
@@ -1079,7 +1071,7 @@ static struct pcmcia_driver tc589_driver = { | |||
1079 | }, | 1071 | }, |
1080 | .attach = tc589_attach, | 1072 | .attach = tc589_attach, |
1081 | .event = tc589_event, | 1073 | .event = tc589_event, |
1082 | .detach = tc589_detach, | 1074 | .remove = tc589_detach, |
1083 | .id_table = tc589_ids, | 1075 | .id_table = tc589_ids, |
1084 | .suspend = tc589_suspend, | 1076 | .suspend = tc589_suspend, |
1085 | .resume = tc589_resume, | 1077 | .resume = tc589_resume, |
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 6c6b25265659..11f701a8ff02 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
@@ -108,7 +108,7 @@ static void block_output(struct net_device *dev, int count, | |||
108 | const u_char *buf, const int start_page); | 108 | const u_char *buf, const int start_page); |
109 | 109 | ||
110 | static dev_link_t *axnet_attach(void); | 110 | static dev_link_t *axnet_attach(void); |
111 | static void axnet_detach(dev_link_t *); | 111 | static void axnet_detach(struct pcmcia_device *p_dev); |
112 | 112 | ||
113 | static dev_info_t dev_info = "axnet_cs"; | 113 | static dev_info_t dev_info = "axnet_cs"; |
114 | static dev_link_t *dev_list; | 114 | static dev_link_t *dev_list; |
@@ -185,7 +185,7 @@ static dev_link_t *axnet_attach(void) | |||
185 | ret = pcmcia_register_client(&link->handle, &client_reg); | 185 | ret = pcmcia_register_client(&link->handle, &client_reg); |
186 | if (ret != CS_SUCCESS) { | 186 | if (ret != CS_SUCCESS) { |
187 | cs_error(link->handle, RegisterClient, ret); | 187 | cs_error(link->handle, RegisterClient, ret); |
188 | axnet_detach(link); | 188 | axnet_detach(link->handle); |
189 | return NULL; | 189 | return NULL; |
190 | } | 190 | } |
191 | 191 | ||
@@ -201,8 +201,9 @@ static dev_link_t *axnet_attach(void) | |||
201 | 201 | ||
202 | ======================================================================*/ | 202 | ======================================================================*/ |
203 | 203 | ||
204 | static void axnet_detach(dev_link_t *link) | 204 | static void axnet_detach(struct pcmcia_device *p_dev) |
205 | { | 205 | { |
206 | dev_link_t *link = dev_to_instance(p_dev); | ||
206 | struct net_device *dev = link->priv; | 207 | struct net_device *dev = link->priv; |
207 | dev_link_t **linkp; | 208 | dev_link_t **linkp; |
208 | 209 | ||
@@ -220,9 +221,6 @@ static void axnet_detach(dev_link_t *link) | |||
220 | if (link->state & DEV_CONFIG) | 221 | if (link->state & DEV_CONFIG) |
221 | axnet_release(link); | 222 | axnet_release(link); |
222 | 223 | ||
223 | if (link->handle) | ||
224 | pcmcia_deregister_client(link->handle); | ||
225 | |||
226 | /* Unlink device structure, free bits */ | 224 | /* Unlink device structure, free bits */ |
227 | *linkp = link->next; | 225 | *linkp = link->next; |
228 | free_netdev(dev); | 226 | free_netdev(dev); |
@@ -537,16 +535,10 @@ static int axnet_event(event_t event, int priority, | |||
537 | event_callback_args_t *args) | 535 | event_callback_args_t *args) |
538 | { | 536 | { |
539 | dev_link_t *link = args->client_data; | 537 | dev_link_t *link = args->client_data; |
540 | struct net_device *dev = link->priv; | ||
541 | 538 | ||
542 | DEBUG(2, "axnet_event(0x%06x)\n", event); | 539 | DEBUG(2, "axnet_event(0x%06x)\n", event); |
543 | 540 | ||
544 | switch (event) { | 541 | switch (event) { |
545 | case CS_EVENT_CARD_REMOVAL: | ||
546 | link->state &= ~DEV_PRESENT; | ||
547 | if (link->state & DEV_CONFIG) | ||
548 | netif_device_detach(dev); | ||
549 | break; | ||
550 | case CS_EVENT_CARD_INSERTION: | 542 | case CS_EVENT_CARD_INSERTION: |
551 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 543 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
552 | axnet_config(link); | 544 | axnet_config(link); |
@@ -890,7 +882,7 @@ static struct pcmcia_driver axnet_cs_driver = { | |||
890 | }, | 882 | }, |
891 | .attach = axnet_attach, | 883 | .attach = axnet_attach, |
892 | .event = axnet_event, | 884 | .event = axnet_event, |
893 | .detach = axnet_detach, | 885 | .remove = axnet_detach, |
894 | .id_table = axnet_ids, | 886 | .id_table = axnet_ids, |
895 | .suspend = axnet_suspend, | 887 | .suspend = axnet_suspend, |
896 | .resume = axnet_resume, | 888 | .resume = axnet_resume, |
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 68612222de6e..6970888cba10 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c | |||
@@ -126,7 +126,7 @@ static int com20020_event(event_t event, int priority, | |||
126 | static dev_info_t dev_info = "com20020_cs"; | 126 | static dev_info_t dev_info = "com20020_cs"; |
127 | 127 | ||
128 | static dev_link_t *com20020_attach(void); | 128 | static dev_link_t *com20020_attach(void); |
129 | static void com20020_detach(dev_link_t *); | 129 | static void com20020_detach(struct pcmcia_device *p_dev); |
130 | 130 | ||
131 | static dev_link_t *dev_list; | 131 | static dev_link_t *dev_list; |
132 | 132 | ||
@@ -204,7 +204,7 @@ static dev_link_t *com20020_attach(void) | |||
204 | ret = pcmcia_register_client(&link->handle, &client_reg); | 204 | ret = pcmcia_register_client(&link->handle, &client_reg); |
205 | if (ret != 0) { | 205 | if (ret != 0) { |
206 | cs_error(link->handle, RegisterClient, ret); | 206 | cs_error(link->handle, RegisterClient, ret); |
207 | com20020_detach(link); | 207 | com20020_detach(link->handle); |
208 | return NULL; | 208 | return NULL; |
209 | } | 209 | } |
210 | 210 | ||
@@ -226,8 +226,9 @@ fail_alloc_info: | |||
226 | 226 | ||
227 | ======================================================================*/ | 227 | ======================================================================*/ |
228 | 228 | ||
229 | static void com20020_detach(dev_link_t *link) | 229 | static void com20020_detach(struct pcmcia_device *p_dev) |
230 | { | 230 | { |
231 | dev_link_t *link = dev_to_instance(p_dev); | ||
231 | struct com20020_dev_t *info = link->priv; | 232 | struct com20020_dev_t *info = link->priv; |
232 | dev_link_t **linkp; | 233 | dev_link_t **linkp; |
233 | struct net_device *dev; | 234 | struct net_device *dev; |
@@ -260,9 +261,6 @@ static void com20020_detach(dev_link_t *link) | |||
260 | if (link->state & DEV_CONFIG) | 261 | if (link->state & DEV_CONFIG) |
261 | com20020_release(link); | 262 | com20020_release(link); |
262 | 263 | ||
263 | if (link->handle) | ||
264 | pcmcia_deregister_client(link->handle); | ||
265 | |||
266 | /* Unlink device structure, free bits */ | 264 | /* Unlink device structure, free bits */ |
267 | DEBUG(1,"unlinking...\n"); | 265 | DEBUG(1,"unlinking...\n"); |
268 | *linkp = link->next; | 266 | *linkp = link->next; |
@@ -470,17 +468,10 @@ static int com20020_event(event_t event, int priority, | |||
470 | event_callback_args_t *args) | 468 | event_callback_args_t *args) |
471 | { | 469 | { |
472 | dev_link_t *link = args->client_data; | 470 | dev_link_t *link = args->client_data; |
473 | com20020_dev_t *info = link->priv; | ||
474 | struct net_device *dev = info->dev; | ||
475 | 471 | ||
476 | DEBUG(1, "com20020_event(0x%06x)\n", event); | 472 | DEBUG(1, "com20020_event(0x%06x)\n", event); |
477 | 473 | ||
478 | switch (event) { | 474 | switch (event) { |
479 | case CS_EVENT_CARD_REMOVAL: | ||
480 | link->state &= ~DEV_PRESENT; | ||
481 | if (link->state & DEV_CONFIG) | ||
482 | netif_device_detach(dev); | ||
483 | break; | ||
484 | case CS_EVENT_CARD_INSERTION: | 475 | case CS_EVENT_CARD_INSERTION: |
485 | link->state |= DEV_PRESENT; | 476 | link->state |= DEV_PRESENT; |
486 | com20020_config(link); | 477 | com20020_config(link); |
@@ -502,7 +493,7 @@ static struct pcmcia_driver com20020_cs_driver = { | |||
502 | }, | 493 | }, |
503 | .attach = com20020_attach, | 494 | .attach = com20020_attach, |
504 | .event = com20020_event, | 495 | .event = com20020_event, |
505 | .detach = com20020_detach, | 496 | .remove = com20020_detach, |
506 | .id_table = com20020_ids, | 497 | .id_table = com20020_ids, |
507 | .suspend = com20020_suspend, | 498 | .suspend = com20020_suspend, |
508 | .resume = com20020_resume, | 499 | .resume = com20020_resume, |
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 388ecade13de..560d4ee22803 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c | |||
@@ -91,7 +91,7 @@ static void fmvj18x_release(dev_link_t *link); | |||
91 | static int fmvj18x_event(event_t event, int priority, | 91 | static int fmvj18x_event(event_t event, int priority, |
92 | event_callback_args_t *args); | 92 | event_callback_args_t *args); |
93 | static dev_link_t *fmvj18x_attach(void); | 93 | static dev_link_t *fmvj18x_attach(void); |
94 | static void fmvj18x_detach(dev_link_t *); | 94 | static void fmvj18x_detach(struct pcmcia_device *p_dev); |
95 | 95 | ||
96 | /* | 96 | /* |
97 | LAN controller(MBH86960A) specific routines | 97 | LAN controller(MBH86960A) specific routines |
@@ -291,7 +291,7 @@ static dev_link_t *fmvj18x_attach(void) | |||
291 | ret = pcmcia_register_client(&link->handle, &client_reg); | 291 | ret = pcmcia_register_client(&link->handle, &client_reg); |
292 | if (ret != 0) { | 292 | if (ret != 0) { |
293 | cs_error(link->handle, RegisterClient, ret); | 293 | cs_error(link->handle, RegisterClient, ret); |
294 | fmvj18x_detach(link); | 294 | fmvj18x_detach(link->handle); |
295 | return NULL; | 295 | return NULL; |
296 | } | 296 | } |
297 | 297 | ||
@@ -300,8 +300,9 @@ static dev_link_t *fmvj18x_attach(void) | |||
300 | 300 | ||
301 | /*====================================================================*/ | 301 | /*====================================================================*/ |
302 | 302 | ||
303 | static void fmvj18x_detach(dev_link_t *link) | 303 | static void fmvj18x_detach(struct pcmcia_device *p_dev) |
304 | { | 304 | { |
305 | dev_link_t *link = dev_to_instance(p_dev); | ||
305 | struct net_device *dev = link->priv; | 306 | struct net_device *dev = link->priv; |
306 | dev_link_t **linkp; | 307 | dev_link_t **linkp; |
307 | 308 | ||
@@ -319,10 +320,6 @@ static void fmvj18x_detach(dev_link_t *link) | |||
319 | if (link->state & DEV_CONFIG) | 320 | if (link->state & DEV_CONFIG) |
320 | fmvj18x_release(link); | 321 | fmvj18x_release(link); |
321 | 322 | ||
322 | /* Break the link with Card Services */ | ||
323 | if (link->handle) | ||
324 | pcmcia_deregister_client(link->handle); | ||
325 | |||
326 | /* Unlink device structure, free pieces */ | 323 | /* Unlink device structure, free pieces */ |
327 | *linkp = link->next; | 324 | *linkp = link->next; |
328 | free_netdev(dev); | 325 | free_netdev(dev); |
@@ -752,16 +749,10 @@ static int fmvj18x_event(event_t event, int priority, | |||
752 | event_callback_args_t *args) | 749 | event_callback_args_t *args) |
753 | { | 750 | { |
754 | dev_link_t *link = args->client_data; | 751 | dev_link_t *link = args->client_data; |
755 | struct net_device *dev = link->priv; | ||
756 | 752 | ||
757 | DEBUG(1, "fmvj18x_event(0x%06x)\n", event); | 753 | DEBUG(1, "fmvj18x_event(0x%06x)\n", event); |
758 | 754 | ||
759 | switch (event) { | 755 | switch (event) { |
760 | case CS_EVENT_CARD_REMOVAL: | ||
761 | link->state &= ~DEV_PRESENT; | ||
762 | if (link->state & DEV_CONFIG) | ||
763 | netif_device_detach(dev); | ||
764 | break; | ||
765 | case CS_EVENT_CARD_INSERTION: | 756 | case CS_EVENT_CARD_INSERTION: |
766 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 757 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
767 | fmvj18x_config(link); | 758 | fmvj18x_config(link); |
@@ -802,7 +793,7 @@ static struct pcmcia_driver fmvj18x_cs_driver = { | |||
802 | }, | 793 | }, |
803 | .attach = fmvj18x_attach, | 794 | .attach = fmvj18x_attach, |
804 | .event = fmvj18x_event, | 795 | .event = fmvj18x_event, |
805 | .detach = fmvj18x_detach, | 796 | .remove = fmvj18x_detach, |
806 | .id_table = fmvj18x_ids, | 797 | .id_table = fmvj18x_ids, |
807 | .suspend = fmvj18x_suspend, | 798 | .suspend = fmvj18x_suspend, |
808 | .resume = fmvj18x_resume, | 799 | .resume = fmvj18x_resume, |
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index 3a7218e51b73..961294983354 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c | |||
@@ -114,7 +114,7 @@ static int ibmtr_event(event_t event, int priority, | |||
114 | static dev_info_t dev_info = "ibmtr_cs"; | 114 | static dev_info_t dev_info = "ibmtr_cs"; |
115 | 115 | ||
116 | static dev_link_t *ibmtr_attach(void); | 116 | static dev_link_t *ibmtr_attach(void); |
117 | static void ibmtr_detach(dev_link_t *); | 117 | static void ibmtr_detach(struct pcmcia_device *p_dev); |
118 | 118 | ||
119 | static dev_link_t *dev_list; | 119 | static dev_link_t *dev_list; |
120 | 120 | ||
@@ -201,7 +201,7 @@ out: | |||
201 | return link; | 201 | return link; |
202 | 202 | ||
203 | out_detach: | 203 | out_detach: |
204 | ibmtr_detach(link); | 204 | ibmtr_detach(link->handle); |
205 | link = NULL; | 205 | link = NULL; |
206 | goto out; | 206 | goto out; |
207 | } /* ibmtr_attach */ | 207 | } /* ibmtr_attach */ |
@@ -215,8 +215,9 @@ out_detach: | |||
215 | 215 | ||
216 | ======================================================================*/ | 216 | ======================================================================*/ |
217 | 217 | ||
218 | static void ibmtr_detach(dev_link_t *link) | 218 | static void ibmtr_detach(struct pcmcia_device *p_dev) |
219 | { | 219 | { |
220 | dev_link_t *link = dev_to_instance(p_dev); | ||
220 | struct ibmtr_dev_t *info = link->priv; | 221 | struct ibmtr_dev_t *info = link->priv; |
221 | dev_link_t **linkp; | 222 | dev_link_t **linkp; |
222 | struct net_device *dev; | 223 | struct net_device *dev; |
@@ -241,9 +242,6 @@ static void ibmtr_detach(dev_link_t *link) | |||
241 | if (link->state & DEV_CONFIG) | 242 | if (link->state & DEV_CONFIG) |
242 | ibmtr_release(link); | 243 | ibmtr_release(link); |
243 | 244 | ||
244 | if (link->handle) | ||
245 | pcmcia_deregister_client(link->handle); | ||
246 | |||
247 | /* Unlink device structure, free bits */ | 245 | /* Unlink device structure, free bits */ |
248 | *linkp = link->next; | 246 | *linkp = link->next; |
249 | free_netdev(dev); | 247 | free_netdev(dev); |
@@ -449,21 +447,10 @@ static int ibmtr_event(event_t event, int priority, | |||
449 | event_callback_args_t *args) | 447 | event_callback_args_t *args) |
450 | { | 448 | { |
451 | dev_link_t *link = args->client_data; | 449 | dev_link_t *link = args->client_data; |
452 | ibmtr_dev_t *info = link->priv; | ||
453 | struct net_device *dev = info->dev; | ||
454 | 450 | ||
455 | DEBUG(1, "ibmtr_event(0x%06x)\n", event); | 451 | DEBUG(1, "ibmtr_event(0x%06x)\n", event); |
456 | 452 | ||
457 | switch (event) { | 453 | switch (event) { |
458 | case CS_EVENT_CARD_REMOVAL: | ||
459 | link->state &= ~DEV_PRESENT; | ||
460 | if (link->state & DEV_CONFIG) { | ||
461 | /* set flag to bypass normal interrupt code */ | ||
462 | struct tok_info *priv = netdev_priv(dev); | ||
463 | priv->sram_phys |= 1; | ||
464 | netif_device_detach(dev); | ||
465 | } | ||
466 | break; | ||
467 | case CS_EVENT_CARD_INSERTION: | 454 | case CS_EVENT_CARD_INSERTION: |
468 | link->state |= DEV_PRESENT; | 455 | link->state |= DEV_PRESENT; |
469 | ibmtr_config(link); | 456 | ibmtr_config(link); |
@@ -529,7 +516,7 @@ static struct pcmcia_driver ibmtr_cs_driver = { | |||
529 | }, | 516 | }, |
530 | .attach = ibmtr_attach, | 517 | .attach = ibmtr_attach, |
531 | .event = ibmtr_event, | 518 | .event = ibmtr_event, |
532 | .detach = ibmtr_detach, | 519 | .remove = ibmtr_detach, |
533 | .id_table = ibmtr_ids, | 520 | .id_table = ibmtr_ids, |
534 | .suspend = ibmtr_suspend, | 521 | .suspend = ibmtr_suspend, |
535 | .resume = ibmtr_resume, | 522 | .resume = ibmtr_resume, |
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index fa4921f8b9fc..011ceb090320 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c | |||
@@ -440,7 +440,7 @@ static struct ethtool_ops netdev_ethtool_ops; | |||
440 | 440 | ||
441 | 441 | ||
442 | static dev_link_t *nmclan_attach(void); | 442 | static dev_link_t *nmclan_attach(void); |
443 | static void nmclan_detach(dev_link_t *); | 443 | static void nmclan_detach(struct pcmcia_device *p_dev); |
444 | 444 | ||
445 | /* ---------------------------------------------------------------------------- | 445 | /* ---------------------------------------------------------------------------- |
446 | nmclan_attach | 446 | nmclan_attach |
@@ -506,7 +506,7 @@ static dev_link_t *nmclan_attach(void) | |||
506 | ret = pcmcia_register_client(&link->handle, &client_reg); | 506 | ret = pcmcia_register_client(&link->handle, &client_reg); |
507 | if (ret != 0) { | 507 | if (ret != 0) { |
508 | cs_error(link->handle, RegisterClient, ret); | 508 | cs_error(link->handle, RegisterClient, ret); |
509 | nmclan_detach(link); | 509 | nmclan_detach(link->handle); |
510 | return NULL; | 510 | return NULL; |
511 | } | 511 | } |
512 | 512 | ||
@@ -521,8 +521,9 @@ nmclan_detach | |||
521 | when the device is released. | 521 | when the device is released. |
522 | ---------------------------------------------------------------------------- */ | 522 | ---------------------------------------------------------------------------- */ |
523 | 523 | ||
524 | static void nmclan_detach(dev_link_t *link) | 524 | static void nmclan_detach(struct pcmcia_device *p_dev) |
525 | { | 525 | { |
526 | dev_link_t *link = dev_to_instance(p_dev); | ||
526 | struct net_device *dev = link->priv; | 527 | struct net_device *dev = link->priv; |
527 | dev_link_t **linkp; | 528 | dev_link_t **linkp; |
528 | 529 | ||
@@ -540,9 +541,6 @@ static void nmclan_detach(dev_link_t *link) | |||
540 | if (link->state & DEV_CONFIG) | 541 | if (link->state & DEV_CONFIG) |
541 | nmclan_release(link); | 542 | nmclan_release(link); |
542 | 543 | ||
543 | if (link->handle) | ||
544 | pcmcia_deregister_client(link->handle); | ||
545 | |||
546 | /* Unlink device structure, free bits */ | 544 | /* Unlink device structure, free bits */ |
547 | *linkp = link->next; | 545 | *linkp = link->next; |
548 | free_netdev(dev); | 546 | free_netdev(dev); |
@@ -845,16 +843,10 @@ static int nmclan_event(event_t event, int priority, | |||
845 | event_callback_args_t *args) | 843 | event_callback_args_t *args) |
846 | { | 844 | { |
847 | dev_link_t *link = args->client_data; | 845 | dev_link_t *link = args->client_data; |
848 | struct net_device *dev = link->priv; | ||
849 | 846 | ||
850 | DEBUG(1, "nmclan_event(0x%06x)\n", event); | 847 | DEBUG(1, "nmclan_event(0x%06x)\n", event); |
851 | 848 | ||
852 | switch (event) { | 849 | switch (event) { |
853 | case CS_EVENT_CARD_REMOVAL: | ||
854 | link->state &= ~DEV_PRESENT; | ||
855 | if (link->state & DEV_CONFIG) | ||
856 | netif_device_detach(dev); | ||
857 | break; | ||
858 | case CS_EVENT_CARD_INSERTION: | 850 | case CS_EVENT_CARD_INSERTION: |
859 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 851 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
860 | nmclan_config(link); | 852 | nmclan_config(link); |
@@ -1694,7 +1686,7 @@ static struct pcmcia_driver nmclan_cs_driver = { | |||
1694 | }, | 1686 | }, |
1695 | .attach = nmclan_attach, | 1687 | .attach = nmclan_attach, |
1696 | .event = nmclan_event, | 1688 | .event = nmclan_event, |
1697 | .detach = nmclan_detach, | 1689 | .remove = nmclan_detach, |
1698 | .id_table = nmclan_ids, | 1690 | .id_table = nmclan_ids, |
1699 | .suspend = nmclan_suspend, | 1691 | .suspend = nmclan_suspend, |
1700 | .resume = nmclan_resume, | 1692 | .resume = nmclan_resume, |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 7db4d6f3db45..fb3e411d6daf 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -121,7 +121,7 @@ static int setup_dma_config(dev_link_t *link, int start_pg, | |||
121 | int stop_pg); | 121 | int stop_pg); |
122 | 122 | ||
123 | static dev_link_t *pcnet_attach(void); | 123 | static dev_link_t *pcnet_attach(void); |
124 | static void pcnet_detach(dev_link_t *); | 124 | static void pcnet_detach(struct pcmcia_device *p_dev); |
125 | 125 | ||
126 | static dev_info_t dev_info = "pcnet_cs"; | 126 | static dev_info_t dev_info = "pcnet_cs"; |
127 | static dev_link_t *dev_list; | 127 | static dev_link_t *dev_list; |
@@ -280,7 +280,7 @@ static dev_link_t *pcnet_attach(void) | |||
280 | ret = pcmcia_register_client(&link->handle, &client_reg); | 280 | ret = pcmcia_register_client(&link->handle, &client_reg); |
281 | if (ret != CS_SUCCESS) { | 281 | if (ret != CS_SUCCESS) { |
282 | cs_error(link->handle, RegisterClient, ret); | 282 | cs_error(link->handle, RegisterClient, ret); |
283 | pcnet_detach(link); | 283 | pcnet_detach(link->handle); |
284 | return NULL; | 284 | return NULL; |
285 | } | 285 | } |
286 | 286 | ||
@@ -296,31 +296,29 @@ static dev_link_t *pcnet_attach(void) | |||
296 | 296 | ||
297 | ======================================================================*/ | 297 | ======================================================================*/ |
298 | 298 | ||
299 | static void pcnet_detach(dev_link_t *link) | 299 | static void pcnet_detach(struct pcmcia_device *p_dev) |
300 | { | 300 | { |
301 | struct net_device *dev = link->priv; | 301 | dev_link_t *link = dev_to_instance(p_dev); |
302 | dev_link_t **linkp; | 302 | struct net_device *dev = link->priv; |
303 | 303 | dev_link_t **linkp; | |
304 | DEBUG(0, "pcnet_detach(0x%p)\n", link); | ||
305 | 304 | ||
306 | /* Locate device structure */ | 305 | DEBUG(0, "pcnet_detach(0x%p)\n", link); |
307 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
308 | if (*linkp == link) break; | ||
309 | if (*linkp == NULL) | ||
310 | return; | ||
311 | 306 | ||
312 | if (link->dev) | 307 | /* Locate device structure */ |
313 | unregister_netdev(dev); | 308 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) |
309 | if (*linkp == link) break; | ||
310 | if (*linkp == NULL) | ||
311 | return; | ||
314 | 312 | ||
315 | if (link->state & DEV_CONFIG) | 313 | if (link->dev) |
316 | pcnet_release(link); | 314 | unregister_netdev(dev); |
317 | 315 | ||
318 | if (link->handle) | 316 | if (link->state & DEV_CONFIG) |
319 | pcmcia_deregister_client(link->handle); | 317 | pcnet_release(link); |
320 | 318 | ||
321 | /* Unlink device structure, free bits */ | 319 | /* Unlink device structure, free bits */ |
322 | *linkp = link->next; | 320 | *linkp = link->next; |
323 | free_netdev(dev); | 321 | free_netdev(dev); |
324 | } /* pcnet_detach */ | 322 | } /* pcnet_detach */ |
325 | 323 | ||
326 | /*====================================================================== | 324 | /*====================================================================== |
@@ -817,16 +815,10 @@ static int pcnet_event(event_t event, int priority, | |||
817 | event_callback_args_t *args) | 815 | event_callback_args_t *args) |
818 | { | 816 | { |
819 | dev_link_t *link = args->client_data; | 817 | dev_link_t *link = args->client_data; |
820 | struct net_device *dev = link->priv; | ||
821 | 818 | ||
822 | DEBUG(2, "pcnet_event(0x%06x)\n", event); | 819 | DEBUG(2, "pcnet_event(0x%06x)\n", event); |
823 | 820 | ||
824 | switch (event) { | 821 | switch (event) { |
825 | case CS_EVENT_CARD_REMOVAL: | ||
826 | link->state &= ~DEV_PRESENT; | ||
827 | if (link->state & DEV_CONFIG) | ||
828 | netif_device_detach(dev); | ||
829 | break; | ||
830 | case CS_EVENT_CARD_INSERTION: | 822 | case CS_EVENT_CARD_INSERTION: |
831 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 823 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
832 | pcnet_config(link); | 824 | pcnet_config(link); |
@@ -1856,7 +1848,7 @@ static struct pcmcia_driver pcnet_driver = { | |||
1856 | }, | 1848 | }, |
1857 | .attach = pcnet_attach, | 1849 | .attach = pcnet_attach, |
1858 | .event = pcnet_event, | 1850 | .event = pcnet_event, |
1859 | .detach = pcnet_detach, | 1851 | .remove = pcnet_detach, |
1860 | .owner = THIS_MODULE, | 1852 | .owner = THIS_MODULE, |
1861 | .id_table = pcnet_ids, | 1853 | .id_table = pcnet_ids, |
1862 | .suspend = pcnet_suspend, | 1854 | .suspend = pcnet_suspend, |
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 7c61ec90c2c3..6cb5198d6094 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c | |||
@@ -282,7 +282,7 @@ enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002, | |||
282 | /*====================================================================*/ | 282 | /*====================================================================*/ |
283 | 283 | ||
284 | static dev_link_t *smc91c92_attach(void); | 284 | static dev_link_t *smc91c92_attach(void); |
285 | static void smc91c92_detach(dev_link_t *); | 285 | static void smc91c92_detach(struct pcmcia_device *p_dev); |
286 | static void smc91c92_config(dev_link_t *link); | 286 | static void smc91c92_config(dev_link_t *link); |
287 | static void smc91c92_release(dev_link_t *link); | 287 | static void smc91c92_release(dev_link_t *link); |
288 | static int smc91c92_event(event_t event, int priority, | 288 | static int smc91c92_event(event_t event, int priority, |
@@ -375,7 +375,7 @@ static dev_link_t *smc91c92_attach(void) | |||
375 | ret = pcmcia_register_client(&link->handle, &client_reg); | 375 | ret = pcmcia_register_client(&link->handle, &client_reg); |
376 | if (ret != 0) { | 376 | if (ret != 0) { |
377 | cs_error(link->handle, RegisterClient, ret); | 377 | cs_error(link->handle, RegisterClient, ret); |
378 | smc91c92_detach(link); | 378 | smc91c92_detach(link->handle); |
379 | return NULL; | 379 | return NULL; |
380 | } | 380 | } |
381 | 381 | ||
@@ -391,8 +391,9 @@ static dev_link_t *smc91c92_attach(void) | |||
391 | 391 | ||
392 | ======================================================================*/ | 392 | ======================================================================*/ |
393 | 393 | ||
394 | static void smc91c92_detach(dev_link_t *link) | 394 | static void smc91c92_detach(struct pcmcia_device *p_dev) |
395 | { | 395 | { |
396 | dev_link_t *link = dev_to_instance(p_dev); | ||
396 | struct net_device *dev = link->priv; | 397 | struct net_device *dev = link->priv; |
397 | dev_link_t **linkp; | 398 | dev_link_t **linkp; |
398 | 399 | ||
@@ -410,9 +411,6 @@ static void smc91c92_detach(dev_link_t *link) | |||
410 | if (link->state & DEV_CONFIG) | 411 | if (link->state & DEV_CONFIG) |
411 | smc91c92_release(link); | 412 | smc91c92_release(link); |
412 | 413 | ||
413 | if (link->handle) | ||
414 | pcmcia_deregister_client(link->handle); | ||
415 | |||
416 | /* Unlink device structure, free bits */ | 414 | /* Unlink device structure, free bits */ |
417 | *linkp = link->next; | 415 | *linkp = link->next; |
418 | free_netdev(dev); | 416 | free_netdev(dev); |
@@ -1237,16 +1235,10 @@ static int smc91c92_event(event_t event, int priority, | |||
1237 | event_callback_args_t *args) | 1235 | event_callback_args_t *args) |
1238 | { | 1236 | { |
1239 | dev_link_t *link = args->client_data; | 1237 | dev_link_t *link = args->client_data; |
1240 | struct net_device *dev = link->priv; | ||
1241 | 1238 | ||
1242 | DEBUG(1, "smc91c92_event(0x%06x)\n", event); | 1239 | DEBUG(1, "smc91c92_event(0x%06x)\n", event); |
1243 | 1240 | ||
1244 | switch (event) { | 1241 | switch (event) { |
1245 | case CS_EVENT_CARD_REMOVAL: | ||
1246 | link->state &= ~DEV_PRESENT; | ||
1247 | if (link->state & DEV_CONFIG) | ||
1248 | netif_device_detach(dev); | ||
1249 | break; | ||
1250 | case CS_EVENT_CARD_INSERTION: | 1242 | case CS_EVENT_CARD_INSERTION: |
1251 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 1243 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
1252 | smc91c92_config(link); | 1244 | smc91c92_config(link); |
@@ -2371,7 +2363,7 @@ static struct pcmcia_driver smc91c92_cs_driver = { | |||
2371 | }, | 2363 | }, |
2372 | .attach = smc91c92_attach, | 2364 | .attach = smc91c92_attach, |
2373 | .event = smc91c92_event, | 2365 | .event = smc91c92_event, |
2374 | .detach = smc91c92_detach, | 2366 | .remove = smc91c92_detach, |
2375 | .id_table = smc91c92_ids, | 2367 | .id_table = smc91c92_ids, |
2376 | .suspend = smc91c92_suspend, | 2368 | .suspend = smc91c92_suspend, |
2377 | .resume = smc91c92_resume, | 2369 | .resume = smc91c92_resume, |
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 917e50ac37f3..804e56771baf 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c | |||
@@ -302,7 +302,7 @@ static int xirc2ps_event(event_t event, int priority, | |||
302 | */ | 302 | */ |
303 | 303 | ||
304 | static dev_link_t *xirc2ps_attach(void); | 304 | static dev_link_t *xirc2ps_attach(void); |
305 | static void xirc2ps_detach(dev_link_t *); | 305 | static void xirc2ps_detach(struct pcmcia_device *p_dev); |
306 | 306 | ||
307 | /**************** | 307 | /**************** |
308 | * You'll also need to prototype all the functions that will actually | 308 | * You'll also need to prototype all the functions that will actually |
@@ -622,7 +622,7 @@ xirc2ps_attach(void) | |||
622 | client_reg.event_callback_args.client_data = link; | 622 | client_reg.event_callback_args.client_data = link; |
623 | if ((err = pcmcia_register_client(&link->handle, &client_reg))) { | 623 | if ((err = pcmcia_register_client(&link->handle, &client_reg))) { |
624 | cs_error(link->handle, RegisterClient, err); | 624 | cs_error(link->handle, RegisterClient, err); |
625 | xirc2ps_detach(link); | 625 | xirc2ps_detach(link->handle); |
626 | return NULL; | 626 | return NULL; |
627 | } | 627 | } |
628 | 628 | ||
@@ -637,8 +637,9 @@ xirc2ps_attach(void) | |||
637 | */ | 637 | */ |
638 | 638 | ||
639 | static void | 639 | static void |
640 | xirc2ps_detach(dev_link_t * link) | 640 | xirc2ps_detach(struct pcmcia_device *p_dev) |
641 | { | 641 | { |
642 | dev_link_t *link = dev_to_instance(p_dev); | ||
642 | struct net_device *dev = link->priv; | 643 | struct net_device *dev = link->priv; |
643 | dev_link_t **linkp; | 644 | dev_link_t **linkp; |
644 | 645 | ||
@@ -656,19 +657,9 @@ xirc2ps_detach(dev_link_t * link) | |||
656 | if (link->dev) | 657 | if (link->dev) |
657 | unregister_netdev(dev); | 658 | unregister_netdev(dev); |
658 | 659 | ||
659 | /* | ||
660 | * If the device is currently configured and active, we won't | ||
661 | * actually delete it yet. Instead, it is marked so that when | ||
662 | * the release() function is called, that will trigger a proper | ||
663 | * detach(). | ||
664 | */ | ||
665 | if (link->state & DEV_CONFIG) | 660 | if (link->state & DEV_CONFIG) |
666 | xirc2ps_release(link); | 661 | xirc2ps_release(link); |
667 | 662 | ||
668 | /* Break the link with Card Services */ | ||
669 | if (link->handle) | ||
670 | pcmcia_deregister_client(link->handle); | ||
671 | |||
672 | /* Unlink device structure, free it */ | 663 | /* Unlink device structure, free it */ |
673 | *linkp = link->next; | 664 | *linkp = link->next; |
674 | free_netdev(dev); | 665 | free_netdev(dev); |
@@ -1209,19 +1200,10 @@ xirc2ps_event(event_t event, int priority, | |||
1209 | event_callback_args_t * args) | 1200 | event_callback_args_t * args) |
1210 | { | 1201 | { |
1211 | dev_link_t *link = args->client_data; | 1202 | dev_link_t *link = args->client_data; |
1212 | struct net_device *dev = link->priv; | ||
1213 | 1203 | ||
1214 | DEBUG(0, "event(%d)\n", (int)event); | 1204 | DEBUG(0, "event(%d)\n", (int)event); |
1215 | 1205 | ||
1216 | switch (event) { | 1206 | switch (event) { |
1217 | case CS_EVENT_REGISTRATION_COMPLETE: | ||
1218 | DEBUG(0, "registration complete\n"); | ||
1219 | break; | ||
1220 | case CS_EVENT_CARD_REMOVAL: | ||
1221 | link->state &= ~DEV_PRESENT; | ||
1222 | if (link->state & DEV_CONFIG) | ||
1223 | netif_device_detach(dev); | ||
1224 | break; | ||
1225 | case CS_EVENT_CARD_INSERTION: | 1207 | case CS_EVENT_CARD_INSERTION: |
1226 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 1208 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
1227 | xirc2ps_config(link); | 1209 | xirc2ps_config(link); |
@@ -2022,7 +2004,7 @@ static struct pcmcia_driver xirc2ps_cs_driver = { | |||
2022 | }, | 2004 | }, |
2023 | .attach = xirc2ps_attach, | 2005 | .attach = xirc2ps_attach, |
2024 | .event = xirc2ps_event, | 2006 | .event = xirc2ps_event, |
2025 | .detach = xirc2ps_detach, | 2007 | .remove = xirc2ps_detach, |
2026 | .id_table = xirc2ps_ids, | 2008 | .id_table = xirc2ps_ids, |
2027 | .suspend = xirc2ps_suspend, | 2009 | .suspend = xirc2ps_suspend, |
2028 | .resume = xirc2ps_resume, | 2010 | .resume = xirc2ps_resume, |
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index 80c9de749b52..7a28139544c0 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c | |||
@@ -92,7 +92,7 @@ static int airo_event(event_t event, int priority, | |||
92 | */ | 92 | */ |
93 | 93 | ||
94 | static dev_link_t *airo_attach(void); | 94 | static dev_link_t *airo_attach(void); |
95 | static void airo_detach(dev_link_t *); | 95 | static void airo_detach(struct pcmcia_device *p_dev); |
96 | 96 | ||
97 | /* | 97 | /* |
98 | You'll also need to prototype all the functions that will actually | 98 | You'll also need to prototype all the functions that will actually |
@@ -210,7 +210,7 @@ static dev_link_t *airo_attach(void) | |||
210 | ret = pcmcia_register_client(&link->handle, &client_reg); | 210 | ret = pcmcia_register_client(&link->handle, &client_reg); |
211 | if (ret != 0) { | 211 | if (ret != 0) { |
212 | cs_error(link->handle, RegisterClient, ret); | 212 | cs_error(link->handle, RegisterClient, ret); |
213 | airo_detach(link); | 213 | airo_detach(link->handle); |
214 | return NULL; | 214 | return NULL; |
215 | } | 215 | } |
216 | 216 | ||
@@ -226,8 +226,9 @@ static dev_link_t *airo_attach(void) | |||
226 | 226 | ||
227 | ======================================================================*/ | 227 | ======================================================================*/ |
228 | 228 | ||
229 | static void airo_detach(dev_link_t *link) | 229 | static void airo_detach(struct pcmcia_device *p_dev) |
230 | { | 230 | { |
231 | dev_link_t *link = dev_to_instance(p_dev); | ||
231 | dev_link_t **linkp; | 232 | dev_link_t **linkp; |
232 | 233 | ||
233 | DEBUG(0, "airo_detach(0x%p)\n", link); | 234 | DEBUG(0, "airo_detach(0x%p)\n", link); |
@@ -244,14 +245,8 @@ static void airo_detach(dev_link_t *link) | |||
244 | if ( ((local_info_t*)link->priv)->eth_dev ) { | 245 | if ( ((local_info_t*)link->priv)->eth_dev ) { |
245 | stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 ); | 246 | stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 ); |
246 | } | 247 | } |
247 | ((local_info_t*)link->priv)->eth_dev = NULL; | 248 | ((local_info_t*)link->priv)->eth_dev = NULL; |
248 | 249 | ||
249 | /* Break the link with Card Services */ | ||
250 | if (link->handle) | ||
251 | pcmcia_deregister_client(link->handle); | ||
252 | |||
253 | |||
254 | |||
255 | /* Unlink device structure, free pieces */ | 250 | /* Unlink device structure, free pieces */ |
256 | *linkp = link->next; | 251 | *linkp = link->next; |
257 | kfree(link->priv); | 252 | kfree(link->priv); |
@@ -537,18 +532,10 @@ static int airo_event(event_t event, int priority, | |||
537 | event_callback_args_t *args) | 532 | event_callback_args_t *args) |
538 | { | 533 | { |
539 | dev_link_t *link = args->client_data; | 534 | dev_link_t *link = args->client_data; |
540 | local_info_t *local = link->priv; | 535 | |
541 | |||
542 | DEBUG(1, "airo_event(0x%06x)\n", event); | 536 | DEBUG(1, "airo_event(0x%06x)\n", event); |
543 | 537 | ||
544 | switch (event) { | 538 | switch (event) { |
545 | case CS_EVENT_CARD_REMOVAL: | ||
546 | link->state &= ~DEV_PRESENT; | ||
547 | if (link->state & DEV_CONFIG) { | ||
548 | netif_device_detach(local->eth_dev); | ||
549 | airo_release(link); | ||
550 | } | ||
551 | break; | ||
552 | case CS_EVENT_CARD_INSERTION: | 539 | case CS_EVENT_CARD_INSERTION: |
553 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 540 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
554 | airo_config(link); | 541 | airo_config(link); |
@@ -573,7 +560,7 @@ static struct pcmcia_driver airo_driver = { | |||
573 | }, | 560 | }, |
574 | .attach = airo_attach, | 561 | .attach = airo_attach, |
575 | .event = airo_event, | 562 | .event = airo_event, |
576 | .detach = airo_detach, | 563 | .remove = airo_detach, |
577 | .id_table = airo_ids, | 564 | .id_table = airo_ids, |
578 | .suspend = airo_suspend, | 565 | .suspend = airo_suspend, |
579 | .resume = airo_resume, | 566 | .resume = airo_resume, |
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 598a9cd0f83e..3ab33dd49ea2 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c | |||
@@ -103,7 +103,7 @@ static int atmel_event(event_t event, int priority, | |||
103 | */ | 103 | */ |
104 | 104 | ||
105 | static dev_link_t *atmel_attach(void); | 105 | static dev_link_t *atmel_attach(void); |
106 | static void atmel_detach(dev_link_t *); | 106 | static void atmel_detach(struct pcmcia_device *p_dev); |
107 | 107 | ||
108 | /* | 108 | /* |
109 | You'll also need to prototype all the functions that will actually | 109 | You'll also need to prototype all the functions that will actually |
@@ -221,7 +221,7 @@ static dev_link_t *atmel_attach(void) | |||
221 | ret = pcmcia_register_client(&link->handle, &client_reg); | 221 | ret = pcmcia_register_client(&link->handle, &client_reg); |
222 | if (ret != 0) { | 222 | if (ret != 0) { |
223 | cs_error(link->handle, RegisterClient, ret); | 223 | cs_error(link->handle, RegisterClient, ret); |
224 | atmel_detach(link); | 224 | atmel_detach(link->handle); |
225 | return NULL; | 225 | return NULL; |
226 | } | 226 | } |
227 | 227 | ||
@@ -237,8 +237,9 @@ static dev_link_t *atmel_attach(void) | |||
237 | 237 | ||
238 | ======================================================================*/ | 238 | ======================================================================*/ |
239 | 239 | ||
240 | static void atmel_detach(dev_link_t *link) | 240 | static void atmel_detach(struct pcmcia_device *p_dev) |
241 | { | 241 | { |
242 | dev_link_t *link = dev_to_instance(p_dev); | ||
242 | dev_link_t **linkp; | 243 | dev_link_t **linkp; |
243 | 244 | ||
244 | DEBUG(0, "atmel_detach(0x%p)\n", link); | 245 | DEBUG(0, "atmel_detach(0x%p)\n", link); |
@@ -252,10 +253,6 @@ static void atmel_detach(dev_link_t *link) | |||
252 | if (link->state & DEV_CONFIG) | 253 | if (link->state & DEV_CONFIG) |
253 | atmel_release(link); | 254 | atmel_release(link); |
254 | 255 | ||
255 | /* Break the link with Card Services */ | ||
256 | if (link->handle) | ||
257 | pcmcia_deregister_client(link->handle); | ||
258 | |||
259 | /* Unlink device structure, free pieces */ | 256 | /* Unlink device structure, free pieces */ |
260 | *linkp = link->next; | 257 | *linkp = link->next; |
261 | kfree(link->priv); | 258 | kfree(link->priv); |
@@ -522,18 +519,10 @@ static int atmel_event(event_t event, int priority, | |||
522 | event_callback_args_t *args) | 519 | event_callback_args_t *args) |
523 | { | 520 | { |
524 | dev_link_t *link = args->client_data; | 521 | dev_link_t *link = args->client_data; |
525 | local_info_t *local = link->priv; | 522 | |
526 | |||
527 | DEBUG(1, "atmel_event(0x%06x)\n", event); | 523 | DEBUG(1, "atmel_event(0x%06x)\n", event); |
528 | 524 | ||
529 | switch (event) { | 525 | switch (event) { |
530 | case CS_EVENT_CARD_REMOVAL: | ||
531 | link->state &= ~DEV_PRESENT; | ||
532 | if (link->state & DEV_CONFIG) { | ||
533 | netif_device_detach(local->eth_dev); | ||
534 | atmel_release(link); | ||
535 | } | ||
536 | break; | ||
537 | case CS_EVENT_CARD_INSERTION: | 526 | case CS_EVENT_CARD_INSERTION: |
538 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 527 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
539 | atmel_config(link); | 528 | atmel_config(link); |
@@ -593,7 +582,7 @@ static struct pcmcia_driver atmel_driver = { | |||
593 | }, | 582 | }, |
594 | .attach = atmel_attach, | 583 | .attach = atmel_attach, |
595 | .event = atmel_event, | 584 | .event = atmel_event, |
596 | .detach = atmel_detach, | 585 | .remove = atmel_detach, |
597 | .id_table = atmel_ids, | 586 | .id_table = atmel_ids, |
598 | .suspend = atmel_suspend, | 587 | .suspend = atmel_suspend, |
599 | .resume = atmel_resume, | 588 | .resume = atmel_resume, |
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index ba4a7da98ccd..866142af7d92 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
@@ -203,7 +203,7 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len) | |||
203 | 203 | ||
204 | 204 | ||
205 | 205 | ||
206 | static void prism2_detach(dev_link_t *link); | 206 | static void prism2_detach(struct pcmcia_device *p_dev); |
207 | static void prism2_release(u_long arg); | 207 | static void prism2_release(u_long arg); |
208 | static int prism2_event(event_t event, int priority, | 208 | static int prism2_event(event_t event, int priority, |
209 | event_callback_args_t *args); | 209 | event_callback_args_t *args); |
@@ -528,15 +528,16 @@ static dev_link_t *prism2_attach(void) | |||
528 | ret = pcmcia_register_client(&link->handle, &client_reg); | 528 | ret = pcmcia_register_client(&link->handle, &client_reg); |
529 | if (ret != CS_SUCCESS) { | 529 | if (ret != CS_SUCCESS) { |
530 | cs_error(link->handle, RegisterClient, ret); | 530 | cs_error(link->handle, RegisterClient, ret); |
531 | prism2_detach(link); | 531 | prism2_detach(link->handle); |
532 | return NULL; | 532 | return NULL; |
533 | } | 533 | } |
534 | return link; | 534 | return link; |
535 | } | 535 | } |
536 | 536 | ||
537 | 537 | ||
538 | static void prism2_detach(dev_link_t *link) | 538 | static void prism2_detach(struct pcmcia_device *p_dev) |
539 | { | 539 | { |
540 | dev_link_t *link = dev_to_instance(p_dev); | ||
540 | dev_link_t **linkp; | 541 | dev_link_t **linkp; |
541 | 542 | ||
542 | PDEBUG(DEBUG_FLOW, "prism2_detach\n"); | 543 | PDEBUG(DEBUG_FLOW, "prism2_detach\n"); |
@@ -554,14 +555,6 @@ static void prism2_detach(dev_link_t *link) | |||
554 | prism2_release((u_long)link); | 555 | prism2_release((u_long)link); |
555 | } | 556 | } |
556 | 557 | ||
557 | if (link->handle) { | ||
558 | int res = pcmcia_deregister_client(link->handle); | ||
559 | if (res) { | ||
560 | printk("CardService(DeregisterClient) => %d\n", res); | ||
561 | cs_error(link->handle, DeregisterClient, res); | ||
562 | } | ||
563 | } | ||
564 | |||
565 | *linkp = link->next; | 558 | *linkp = link->next; |
566 | /* release net devices */ | 559 | /* release net devices */ |
567 | if (link->priv) { | 560 | if (link->priv) { |
@@ -902,7 +895,6 @@ static int prism2_event(event_t event, int priority, | |||
902 | event_callback_args_t *args) | 895 | event_callback_args_t *args) |
903 | { | 896 | { |
904 | dev_link_t *link = args->client_data; | 897 | dev_link_t *link = args->client_data; |
905 | struct net_device *dev = (struct net_device *) link->priv; | ||
906 | 898 | ||
907 | switch (event) { | 899 | switch (event) { |
908 | case CS_EVENT_CARD_INSERTION: | 900 | case CS_EVENT_CARD_INSERTION: |
@@ -913,16 +905,6 @@ static int prism2_event(event_t event, int priority, | |||
913 | } | 905 | } |
914 | break; | 906 | break; |
915 | 907 | ||
916 | case CS_EVENT_CARD_REMOVAL: | ||
917 | PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info); | ||
918 | link->state &= ~DEV_PRESENT; | ||
919 | if (link->state & DEV_CONFIG) { | ||
920 | netif_stop_queue(dev); | ||
921 | netif_device_detach(dev); | ||
922 | prism2_release((u_long) link); | ||
923 | } | ||
924 | break; | ||
925 | |||
926 | default: | 908 | default: |
927 | PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", | 909 | PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", |
928 | dev_info, event); | 910 | dev_info, event); |
@@ -991,7 +973,7 @@ static struct pcmcia_driver hostap_driver = { | |||
991 | .name = "hostap_cs", | 973 | .name = "hostap_cs", |
992 | }, | 974 | }, |
993 | .attach = prism2_attach, | 975 | .attach = prism2_attach, |
994 | .detach = prism2_detach, | 976 | .remove = prism2_detach, |
995 | .owner = THIS_MODULE, | 977 | .owner = THIS_MODULE, |
996 | .event = prism2_event, | 978 | .event = prism2_event, |
997 | .id_table = hostap_cs_ids, | 979 | .id_table = hostap_cs_ids, |
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index 7ab2d70ffddf..1770677d9e10 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c | |||
@@ -200,7 +200,7 @@ static int netwave_event(event_t event, int priority, | |||
200 | static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card | 200 | static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card |
201 | insertion */ | 201 | insertion */ |
202 | static dev_link_t *netwave_attach(void); /* Create instance */ | 202 | static dev_link_t *netwave_attach(void); /* Create instance */ |
203 | static void netwave_detach(dev_link_t *); /* Destroy instance */ | 203 | static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */ |
204 | 204 | ||
205 | /* Hardware configuration */ | 205 | /* Hardware configuration */ |
206 | static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase); | 206 | static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase); |
@@ -459,7 +459,7 @@ static dev_link_t *netwave_attach(void) | |||
459 | ret = pcmcia_register_client(&link->handle, &client_reg); | 459 | ret = pcmcia_register_client(&link->handle, &client_reg); |
460 | if (ret != 0) { | 460 | if (ret != 0) { |
461 | cs_error(link->handle, RegisterClient, ret); | 461 | cs_error(link->handle, RegisterClient, ret); |
462 | netwave_detach(link); | 462 | netwave_detach(link->handle); |
463 | return NULL; | 463 | return NULL; |
464 | } | 464 | } |
465 | 465 | ||
@@ -474,8 +474,9 @@ static dev_link_t *netwave_attach(void) | |||
474 | * structures are freed. Otherwise, the structures will be freed | 474 | * structures are freed. Otherwise, the structures will be freed |
475 | * when the device is released. | 475 | * when the device is released. |
476 | */ | 476 | */ |
477 | static void netwave_detach(dev_link_t *link) | 477 | static void netwave_detach(struct pcmcia_device *p_dev) |
478 | { | 478 | { |
479 | dev_link_t *link = dev_to_instance(p_dev); | ||
479 | struct net_device *dev = link->priv; | 480 | struct net_device *dev = link->priv; |
480 | dev_link_t **linkp; | 481 | dev_link_t **linkp; |
481 | 482 | ||
@@ -489,11 +490,7 @@ static void netwave_detach(dev_link_t *link) | |||
489 | */ | 490 | */ |
490 | if (link->state & DEV_CONFIG) | 491 | if (link->state & DEV_CONFIG) |
491 | netwave_release(link); | 492 | netwave_release(link); |
492 | 493 | ||
493 | /* Break the link with Card Services */ | ||
494 | if (link->handle) | ||
495 | pcmcia_deregister_client(link->handle); | ||
496 | |||
497 | /* Locate device structure */ | 494 | /* Locate device structure */ |
498 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | 495 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) |
499 | if (*linkp == link) break; | 496 | if (*linkp == link) break; |
@@ -986,22 +983,10 @@ static int netwave_event(event_t event, int priority, | |||
986 | event_callback_args_t *args) | 983 | event_callback_args_t *args) |
987 | { | 984 | { |
988 | dev_link_t *link = args->client_data; | 985 | dev_link_t *link = args->client_data; |
989 | struct net_device *dev = link->priv; | 986 | |
990 | |||
991 | DEBUG(1, "netwave_event(0x%06x)\n", event); | 987 | DEBUG(1, "netwave_event(0x%06x)\n", event); |
992 | |||
993 | switch (event) { | ||
994 | case CS_EVENT_REGISTRATION_COMPLETE: | ||
995 | DEBUG(0, "netwave_cs: registration complete\n"); | ||
996 | break; | ||
997 | 988 | ||
998 | case CS_EVENT_CARD_REMOVAL: | 989 | switch (event) { |
999 | link->state &= ~DEV_PRESENT; | ||
1000 | if (link->state & DEV_CONFIG) { | ||
1001 | netif_device_detach(dev); | ||
1002 | netwave_release(link); | ||
1003 | } | ||
1004 | break; | ||
1005 | case CS_EVENT_CARD_INSERTION: | 990 | case CS_EVENT_CARD_INSERTION: |
1006 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 991 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
1007 | netwave_pcmcia_config( link); | 992 | netwave_pcmcia_config( link); |
@@ -1504,7 +1489,7 @@ static struct pcmcia_driver netwave_driver = { | |||
1504 | }, | 1489 | }, |
1505 | .attach = netwave_attach, | 1490 | .attach = netwave_attach, |
1506 | .event = netwave_event, | 1491 | .event = netwave_event, |
1507 | .detach = netwave_detach, | 1492 | .remove = netwave_detach, |
1508 | .id_table = netwave_ids, | 1493 | .id_table = netwave_ids, |
1509 | .suspend = netwave_suspend, | 1494 | .suspend = netwave_suspend, |
1510 | .resume = netwave_resume, | 1495 | .resume = netwave_resume, |
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index 1d66050e3d6a..00679b6c87c1 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c | |||
@@ -81,7 +81,7 @@ static dev_link_t *dev_list; /* = NULL */ | |||
81 | /********************************************************************/ | 81 | /********************************************************************/ |
82 | 82 | ||
83 | static void orinoco_cs_release(dev_link_t *link); | 83 | static void orinoco_cs_release(dev_link_t *link); |
84 | static void orinoco_cs_detach(dev_link_t *link); | 84 | static void orinoco_cs_detach(struct pcmcia_device *p_dev); |
85 | 85 | ||
86 | /********************************************************************/ | 86 | /********************************************************************/ |
87 | /* Device methods */ | 87 | /* Device methods */ |
@@ -165,7 +165,7 @@ orinoco_cs_attach(void) | |||
165 | ret = pcmcia_register_client(&link->handle, &client_reg); | 165 | ret = pcmcia_register_client(&link->handle, &client_reg); |
166 | if (ret != CS_SUCCESS) { | 166 | if (ret != CS_SUCCESS) { |
167 | cs_error(link->handle, RegisterClient, ret); | 167 | cs_error(link->handle, RegisterClient, ret); |
168 | orinoco_cs_detach(link); | 168 | orinoco_cs_detach(link->handle); |
169 | return NULL; | 169 | return NULL; |
170 | } | 170 | } |
171 | 171 | ||
@@ -178,8 +178,9 @@ orinoco_cs_attach(void) | |||
178 | * are freed. Otherwise, the structures will be freed when the device | 178 | * are freed. Otherwise, the structures will be freed when the device |
179 | * is released. | 179 | * is released. |
180 | */ | 180 | */ |
181 | static void orinoco_cs_detach(dev_link_t *link) | 181 | static void orinoco_cs_detach(struct pcmcia_device *p_dev) |
182 | { | 182 | { |
183 | dev_link_t *link = dev_to_instance(p_dev); | ||
183 | dev_link_t **linkp; | 184 | dev_link_t **linkp; |
184 | struct net_device *dev = link->priv; | 185 | struct net_device *dev = link->priv; |
185 | 186 | ||
@@ -193,10 +194,6 @@ static void orinoco_cs_detach(dev_link_t *link) | |||
193 | if (link->state & DEV_CONFIG) | 194 | if (link->state & DEV_CONFIG) |
194 | orinoco_cs_release(link); | 195 | orinoco_cs_release(link); |
195 | 196 | ||
196 | /* Break the link with Card Services */ | ||
197 | if (link->handle) | ||
198 | pcmcia_deregister_client(link->handle); | ||
199 | |||
200 | /* Unlink device structure, and free it */ | 197 | /* Unlink device structure, and free it */ |
201 | *linkp = link->next; | 198 | *linkp = link->next; |
202 | DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); | 199 | DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); |
@@ -551,30 +548,15 @@ orinoco_cs_event(event_t event, int priority, | |||
551 | event_callback_args_t * args) | 548 | event_callback_args_t * args) |
552 | { | 549 | { |
553 | dev_link_t *link = args->client_data; | 550 | dev_link_t *link = args->client_data; |
554 | struct net_device *dev = link->priv; | ||
555 | struct orinoco_private *priv = netdev_priv(dev); | ||
556 | int err = 0; | ||
557 | 551 | ||
558 | switch (event) { | 552 | switch (event) { |
559 | case CS_EVENT_CARD_REMOVAL: | ||
560 | link->state &= ~DEV_PRESENT; | ||
561 | if (link->state & DEV_CONFIG) { | ||
562 | unsigned long flags; | ||
563 | |||
564 | spin_lock_irqsave(&priv->lock, flags); | ||
565 | netif_device_detach(dev); | ||
566 | priv->hw_unavailable++; | ||
567 | spin_unlock_irqrestore(&priv->lock, flags); | ||
568 | } | ||
569 | break; | ||
570 | |||
571 | case CS_EVENT_CARD_INSERTION: | 553 | case CS_EVENT_CARD_INSERTION: |
572 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 554 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
573 | orinoco_cs_config(link); | 555 | orinoco_cs_config(link); |
574 | break; | 556 | break; |
575 | } | 557 | } |
576 | 558 | ||
577 | return err; | 559 | return 0; |
578 | } /* orinoco_cs_event */ | 560 | } /* orinoco_cs_event */ |
579 | 561 | ||
580 | /********************************************************************/ | 562 | /********************************************************************/ |
@@ -677,7 +659,7 @@ static struct pcmcia_driver orinoco_driver = { | |||
677 | .name = DRIVER_NAME, | 659 | .name = DRIVER_NAME, |
678 | }, | 660 | }, |
679 | .attach = orinoco_cs_attach, | 661 | .attach = orinoco_cs_attach, |
680 | .detach = orinoco_cs_detach, | 662 | .remove = orinoco_cs_detach, |
681 | .event = orinoco_cs_event, | 663 | .event = orinoco_cs_event, |
682 | .id_table = orinoco_cs_ids, | 664 | .id_table = orinoco_cs_ids, |
683 | .suspend = orinoco_cs_suspend, | 665 | .suspend = orinoco_cs_suspend, |
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index c2cb6c8e6d7c..33a89e292126 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
@@ -94,7 +94,7 @@ static void ray_config(dev_link_t *link); | |||
94 | static void ray_release(dev_link_t *link); | 94 | static void ray_release(dev_link_t *link); |
95 | static int ray_event(event_t event, int priority, event_callback_args_t *args); | 95 | static int ray_event(event_t event, int priority, event_callback_args_t *args); |
96 | static dev_link_t *ray_attach(void); | 96 | static dev_link_t *ray_attach(void); |
97 | static void ray_detach(dev_link_t *); | 97 | static void ray_detach(struct pcmcia_device *p_dev); |
98 | 98 | ||
99 | /***** Prototypes indicated by device structure ******************************/ | 99 | /***** Prototypes indicated by device structure ******************************/ |
100 | static int ray_dev_close(struct net_device *dev); | 100 | static int ray_dev_close(struct net_device *dev); |
@@ -402,7 +402,7 @@ static dev_link_t *ray_attach(void) | |||
402 | if (ret != 0) { | 402 | if (ret != 0) { |
403 | printk("ray_cs ray_attach RegisterClient unhappy - detaching\n"); | 403 | printk("ray_cs ray_attach RegisterClient unhappy - detaching\n"); |
404 | cs_error(link->handle, RegisterClient, ret); | 404 | cs_error(link->handle, RegisterClient, ret); |
405 | ray_detach(link); | 405 | ray_detach(link->handle); |
406 | return NULL; | 406 | return NULL; |
407 | } | 407 | } |
408 | DEBUG(2,"ray_cs ray_attach ending\n"); | 408 | DEBUG(2,"ray_cs ray_attach ending\n"); |
@@ -418,9 +418,12 @@ fail_alloc_dev: | |||
418 | structures are freed. Otherwise, the structures will be freed | 418 | structures are freed. Otherwise, the structures will be freed |
419 | when the device is released. | 419 | when the device is released. |
420 | =============================================================================*/ | 420 | =============================================================================*/ |
421 | static void ray_detach(dev_link_t *link) | 421 | static void ray_detach(struct pcmcia_device *p_dev) |
422 | { | 422 | { |
423 | dev_link_t *link = dev_to_instance(p_dev); | ||
423 | dev_link_t **linkp; | 424 | dev_link_t **linkp; |
425 | struct net_device *dev; | ||
426 | ray_dev_t *local; | ||
424 | 427 | ||
425 | DEBUG(1, "ray_detach(0x%p)\n", link); | 428 | DEBUG(1, "ray_detach(0x%p)\n", link); |
426 | 429 | ||
@@ -430,22 +433,18 @@ static void ray_detach(dev_link_t *link) | |||
430 | if (*linkp == NULL) | 433 | if (*linkp == NULL) |
431 | return; | 434 | return; |
432 | 435 | ||
433 | /* If the device is currently configured and active, we won't | 436 | dev = link->priv; |
434 | actually delete it yet. Instead, it is marked so that when | 437 | |
435 | the release() function is called, that will trigger a proper | 438 | if (link->state & DEV_CONFIG) { |
436 | detach(). | 439 | ray_release(link); |
437 | */ | 440 | |
438 | if (link->state & DEV_CONFIG) | 441 | local = (ray_dev_t *)dev->priv; |
439 | ray_release(link); | 442 | del_timer(&local->timer); |
443 | } | ||
440 | 444 | ||
441 | /* Break the link with Card Services */ | ||
442 | if (link->handle) | ||
443 | pcmcia_deregister_client(link->handle); | ||
444 | |||
445 | /* Unlink device structure, free pieces */ | 445 | /* Unlink device structure, free pieces */ |
446 | *linkp = link->next; | 446 | *linkp = link->next; |
447 | if (link->priv) { | 447 | if (link->priv) { |
448 | struct net_device *dev = link->priv; | ||
449 | if (link->dev) unregister_netdev(dev); | 448 | if (link->dev) unregister_netdev(dev); |
450 | free_netdev(dev); | 449 | free_netdev(dev); |
451 | } | 450 | } |
@@ -940,19 +939,9 @@ static int ray_event(event_t event, int priority, | |||
940 | event_callback_args_t *args) | 939 | event_callback_args_t *args) |
941 | { | 940 | { |
942 | dev_link_t *link = args->client_data; | 941 | dev_link_t *link = args->client_data; |
943 | struct net_device *dev = link->priv; | ||
944 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
945 | DEBUG(1, "ray_event(0x%06x)\n", event); | 942 | DEBUG(1, "ray_event(0x%06x)\n", event); |
946 | 943 | ||
947 | switch (event) { | 944 | switch (event) { |
948 | case CS_EVENT_CARD_REMOVAL: | ||
949 | link->state &= ~DEV_PRESENT; | ||
950 | netif_device_detach(dev); | ||
951 | if (link->state & DEV_CONFIG) { | ||
952 | ray_release(link); | ||
953 | del_timer(&local->timer); | ||
954 | } | ||
955 | break; | ||
956 | case CS_EVENT_CARD_INSERTION: | 945 | case CS_EVENT_CARD_INSERTION: |
957 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 946 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
958 | ray_config(link); | 947 | ray_config(link); |
@@ -2958,7 +2947,7 @@ static struct pcmcia_driver ray_driver = { | |||
2958 | }, | 2947 | }, |
2959 | .attach = ray_attach, | 2948 | .attach = ray_attach, |
2960 | .event = ray_event, | 2949 | .event = ray_event, |
2961 | .detach = ray_detach, | 2950 | .remove = ray_detach, |
2962 | .id_table = ray_ids, | 2951 | .id_table = ray_ids, |
2963 | .suspend = ray_suspend, | 2952 | .suspend = ray_suspend, |
2964 | .resume = ray_resume, | 2953 | .resume = ray_resume, |
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c index 3938a5735659..a2dcab7995c1 100644 --- a/drivers/net/wireless/spectrum_cs.c +++ b/drivers/net/wireless/spectrum_cs.c | |||
@@ -90,7 +90,7 @@ static dev_link_t *dev_list; /* = NULL */ | |||
90 | /********************************************************************/ | 90 | /********************************************************************/ |
91 | 91 | ||
92 | static void spectrum_cs_release(dev_link_t *link); | 92 | static void spectrum_cs_release(dev_link_t *link); |
93 | static void spectrum_cs_detach(dev_link_t *link); | 93 | static void spectrum_cs_detach(struct pcmcia_device *p_dev); |
94 | 94 | ||
95 | /********************************************************************/ | 95 | /********************************************************************/ |
96 | /* Firmware downloader */ | 96 | /* Firmware downloader */ |
@@ -647,7 +647,7 @@ spectrum_cs_attach(void) | |||
647 | ret = pcmcia_register_client(&link->handle, &client_reg); | 647 | ret = pcmcia_register_client(&link->handle, &client_reg); |
648 | if (ret != CS_SUCCESS) { | 648 | if (ret != CS_SUCCESS) { |
649 | cs_error(link->handle, RegisterClient, ret); | 649 | cs_error(link->handle, RegisterClient, ret); |
650 | spectrum_cs_detach(link); | 650 | spectrum_cs_detach(link->handle); |
651 | return NULL; | 651 | return NULL; |
652 | } | 652 | } |
653 | 653 | ||
@@ -660,27 +660,14 @@ spectrum_cs_attach(void) | |||
660 | * are freed. Otherwise, the structures will be freed when the device | 660 | * are freed. Otherwise, the structures will be freed when the device |
661 | * is released. | 661 | * is released. |
662 | */ | 662 | */ |
663 | static void spectrum_cs_detach(dev_link_t *link) | 663 | static void spectrum_cs_detach(struct pcmcia_device *p_dev) |
664 | { | 664 | { |
665 | dev_link_t **linkp; | 665 | dev_link_t *link = dev_to_instance(p_dev); |
666 | struct net_device *dev = link->priv; | 666 | struct net_device *dev = link->priv; |
667 | 667 | ||
668 | /* Locate device structure */ | ||
669 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
670 | if (*linkp == link) | ||
671 | break; | ||
672 | |||
673 | BUG_ON(*linkp == NULL); | ||
674 | |||
675 | if (link->state & DEV_CONFIG) | 668 | if (link->state & DEV_CONFIG) |
676 | spectrum_cs_release(link); | 669 | spectrum_cs_release(link); |
677 | 670 | ||
678 | /* Break the link with Card Services */ | ||
679 | if (link->handle) | ||
680 | pcmcia_deregister_client(link->handle); | ||
681 | |||
682 | /* Unlink device structure, and free it */ | ||
683 | *linkp = link->next; | ||
684 | DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); | 671 | DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); |
685 | if (link->dev) { | 672 | if (link->dev) { |
686 | DEBUG(0, PFX "About to unregister net device %p\n", | 673 | DEBUG(0, PFX "About to unregister net device %p\n", |
@@ -1007,22 +994,8 @@ spectrum_cs_event(event_t event, int priority, | |||
1007 | event_callback_args_t * args) | 994 | event_callback_args_t * args) |
1008 | { | 995 | { |
1009 | dev_link_t *link = args->client_data; | 996 | dev_link_t *link = args->client_data; |
1010 | struct net_device *dev = link->priv; | ||
1011 | struct orinoco_private *priv = netdev_priv(dev); | ||
1012 | 997 | ||
1013 | switch (event) { | 998 | switch (event) { |
1014 | case CS_EVENT_CARD_REMOVAL: | ||
1015 | link->state &= ~DEV_PRESENT; | ||
1016 | if (link->state & DEV_CONFIG) { | ||
1017 | unsigned long flags; | ||
1018 | |||
1019 | spin_lock_irqsave(&priv->lock, flags); | ||
1020 | netif_device_detach(dev); | ||
1021 | priv->hw_unavailable++; | ||
1022 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1023 | } | ||
1024 | break; | ||
1025 | |||
1026 | case CS_EVENT_CARD_INSERTION: | 999 | case CS_EVENT_CARD_INSERTION: |
1027 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 1000 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
1028 | spectrum_cs_config(link); | 1001 | spectrum_cs_config(link); |
@@ -1057,7 +1030,7 @@ static struct pcmcia_driver orinoco_driver = { | |||
1057 | .name = DRIVER_NAME, | 1030 | .name = DRIVER_NAME, |
1058 | }, | 1031 | }, |
1059 | .attach = spectrum_cs_attach, | 1032 | .attach = spectrum_cs_attach, |
1060 | .detach = spectrum_cs_detach, | 1033 | .remove = spectrum_cs_detach, |
1061 | .suspend = spectrum_cs_suspend, | 1034 | .suspend = spectrum_cs_suspend, |
1062 | .resume = spectrum_cs_resume, | 1035 | .resume = spectrum_cs_resume, |
1063 | .event = spectrum_cs_event, | 1036 | .event = spectrum_cs_event, |
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index 3e3532830c26..255952d8cea0 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c | |||
@@ -4692,7 +4692,7 @@ wavelan_attach(void) | |||
4692 | if(ret != 0) | 4692 | if(ret != 0) |
4693 | { | 4693 | { |
4694 | cs_error(link->handle, RegisterClient, ret); | 4694 | cs_error(link->handle, RegisterClient, ret); |
4695 | wavelan_detach(link); | 4695 | wavelan_detach(link->handle); |
4696 | return NULL; | 4696 | return NULL; |
4697 | } | 4697 | } |
4698 | 4698 | ||
@@ -4711,8 +4711,10 @@ wavelan_attach(void) | |||
4711 | * is released. | 4711 | * is released. |
4712 | */ | 4712 | */ |
4713 | static void | 4713 | static void |
4714 | wavelan_detach(dev_link_t * link) | 4714 | wavelan_detach(struct pcmcia_device *p_dev) |
4715 | { | 4715 | { |
4716 | dev_link_t *link = dev_to_instance(p_dev); | ||
4717 | |||
4716 | #ifdef DEBUG_CALLBACK_TRACE | 4718 | #ifdef DEBUG_CALLBACK_TRACE |
4717 | printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link); | 4719 | printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link); |
4718 | #endif | 4720 | #endif |
@@ -4729,10 +4731,6 @@ wavelan_detach(dev_link_t * link) | |||
4729 | wv_pcmcia_release(link); | 4731 | wv_pcmcia_release(link); |
4730 | } | 4732 | } |
4731 | 4733 | ||
4732 | /* Break the link with Card Services */ | ||
4733 | if(link->handle) | ||
4734 | pcmcia_deregister_client(link->handle); | ||
4735 | |||
4736 | /* Remove the interface data from the linked list */ | 4734 | /* Remove the interface data from the linked list */ |
4737 | if(dev_list == link) | 4735 | if(dev_list == link) |
4738 | dev_list = link->next; | 4736 | dev_list = link->next; |
@@ -4854,25 +4852,6 @@ wavelan_event(event_t event, /* The event received */ | |||
4854 | 4852 | ||
4855 | switch(event) | 4853 | switch(event) |
4856 | { | 4854 | { |
4857 | case CS_EVENT_REGISTRATION_COMPLETE: | ||
4858 | #ifdef DEBUG_CONFIG_INFO | ||
4859 | printk(KERN_DEBUG "wavelan_cs: registration complete\n"); | ||
4860 | #endif | ||
4861 | break; | ||
4862 | |||
4863 | case CS_EVENT_CARD_REMOVAL: | ||
4864 | /* Oups ! The card is no more there */ | ||
4865 | link->state &= ~DEV_PRESENT; | ||
4866 | if(link->state & DEV_CONFIG) | ||
4867 | { | ||
4868 | /* Accept no more transmissions */ | ||
4869 | netif_device_detach(dev); | ||
4870 | |||
4871 | /* Release the card */ | ||
4872 | wv_pcmcia_release(link); | ||
4873 | } | ||
4874 | break; | ||
4875 | |||
4876 | case CS_EVENT_CARD_INSERTION: | 4855 | case CS_EVENT_CARD_INSERTION: |
4877 | /* Reset and configure the card */ | 4856 | /* Reset and configure the card */ |
4878 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 4857 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
@@ -4906,7 +4885,7 @@ static struct pcmcia_driver wavelan_driver = { | |||
4906 | }, | 4885 | }, |
4907 | .attach = wavelan_attach, | 4886 | .attach = wavelan_attach, |
4908 | .event = wavelan_event, | 4887 | .event = wavelan_event, |
4909 | .detach = wavelan_detach, | 4888 | .remove = wavelan_detach, |
4910 | .id_table = wavelan_ids, | 4889 | .id_table = wavelan_ids, |
4911 | .suspend = wavelan_suspend, | 4890 | .suspend = wavelan_suspend, |
4912 | .resume = wavelan_resume, | 4891 | .resume = wavelan_resume, |
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h index 724a715089c9..3cb34817c039 100644 --- a/drivers/net/wireless/wavelan_cs.p.h +++ b/drivers/net/wireless/wavelan_cs.p.h | |||
@@ -757,7 +757,7 @@ static int | |||
757 | static dev_link_t * | 757 | static dev_link_t * |
758 | wavelan_attach(void); /* Create a new device */ | 758 | wavelan_attach(void); /* Create a new device */ |
759 | static void | 759 | static void |
760 | wavelan_detach(dev_link_t *); /* Destroy a removed device */ | 760 | wavelan_detach(struct pcmcia_device *p_dev); /* Destroy a removed device */ |
761 | static int | 761 | static int |
762 | wavelan_event(event_t, /* Manage pcmcia events */ | 762 | wavelan_event(event_t, /* Manage pcmcia events */ |
763 | int, | 763 | int, |
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 75114318457e..21e498fe7b14 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c | |||
@@ -1498,9 +1498,11 @@ static struct ethtool_ops ops = { | |||
1498 | * Services. If it has been released, all local data structures are freed. | 1498 | * Services. If it has been released, all local data structures are freed. |
1499 | * Otherwise, the structures will be freed when the device is released. | 1499 | * Otherwise, the structures will be freed when the device is released. |
1500 | */ | 1500 | */ |
1501 | static void wl3501_detach(dev_link_t *link) | 1501 | static void wl3501_detach(struct pcmcia_device *p_dev) |
1502 | { | 1502 | { |
1503 | dev_link_t *link = dev_to_instance(p_dev); | ||
1503 | dev_link_t **linkp; | 1504 | dev_link_t **linkp; |
1505 | struct net_device *dev = link->priv; | ||
1504 | 1506 | ||
1505 | /* Locate device structure */ | 1507 | /* Locate device structure */ |
1506 | for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next) | 1508 | for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next) |
@@ -1514,16 +1516,12 @@ static void wl3501_detach(dev_link_t *link) | |||
1514 | * function is called, that will trigger a proper detach(). */ | 1516 | * function is called, that will trigger a proper detach(). */ |
1515 | 1517 | ||
1516 | if (link->state & DEV_CONFIG) { | 1518 | if (link->state & DEV_CONFIG) { |
1517 | #ifdef PCMCIA_DEBUG | 1519 | while (link->open > 0) |
1518 | printk(KERN_DEBUG "wl3501_cs: detach postponed, '%s' " | 1520 | wl3501_close(dev); |
1519 | "still locked\n", link->dev->dev_name); | ||
1520 | #endif | ||
1521 | goto out; | ||
1522 | } | ||
1523 | 1521 | ||
1524 | /* Break the link with Card Services */ | 1522 | netif_device_detach(dev); |
1525 | if (link->handle) | 1523 | wl3501_release(link); |
1526 | pcmcia_deregister_client(link->handle); | 1524 | } |
1527 | 1525 | ||
1528 | /* Unlink device structure, free pieces */ | 1526 | /* Unlink device structure, free pieces */ |
1529 | *linkp = link->next; | 1527 | *linkp = link->next; |
@@ -2012,7 +2010,7 @@ static dev_link_t *wl3501_attach(void) | |||
2012 | ret = pcmcia_register_client(&link->handle, &client_reg); | 2010 | ret = pcmcia_register_client(&link->handle, &client_reg); |
2013 | if (ret) { | 2011 | if (ret) { |
2014 | cs_error(link->handle, RegisterClient, ret); | 2012 | cs_error(link->handle, RegisterClient, ret); |
2015 | wl3501_detach(link); | 2013 | wl3501_detach(link->handle); |
2016 | link = NULL; | 2014 | link = NULL; |
2017 | } | 2015 | } |
2018 | out: | 2016 | out: |
@@ -2225,18 +2223,8 @@ static int wl3501_resume(struct pcmcia_device *p_dev) | |||
2225 | static int wl3501_event(event_t event, int pri, event_callback_args_t *args) | 2223 | static int wl3501_event(event_t event, int pri, event_callback_args_t *args) |
2226 | { | 2224 | { |
2227 | dev_link_t *link = args->client_data; | 2225 | dev_link_t *link = args->client_data; |
2228 | struct net_device *dev = link->priv; | ||
2229 | 2226 | ||
2230 | switch (event) { | 2227 | switch (event) { |
2231 | case CS_EVENT_CARD_REMOVAL: | ||
2232 | link->state &= ~DEV_PRESENT; | ||
2233 | if (link->state & DEV_CONFIG) { | ||
2234 | while (link->open > 0) | ||
2235 | wl3501_close(dev); | ||
2236 | netif_device_detach(dev); | ||
2237 | wl3501_release(link); | ||
2238 | } | ||
2239 | break; | ||
2240 | case CS_EVENT_CARD_INSERTION: | 2228 | case CS_EVENT_CARD_INSERTION: |
2241 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 2229 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
2242 | wl3501_config(link); | 2230 | wl3501_config(link); |
@@ -2258,7 +2246,7 @@ static struct pcmcia_driver wl3501_driver = { | |||
2258 | }, | 2246 | }, |
2259 | .attach = wl3501_attach, | 2247 | .attach = wl3501_attach, |
2260 | .event = wl3501_event, | 2248 | .event = wl3501_event, |
2261 | .detach = wl3501_detach, | 2249 | .remove = wl3501_detach, |
2262 | .id_table = wl3501_ids, | 2250 | .id_table = wl3501_ids, |
2263 | .suspend = wl3501_suspend, | 2251 | .suspend = wl3501_suspend, |
2264 | .resume = wl3501_resume, | 2252 | .resume = wl3501_resume, |
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index 4c89853785ed..063d22de9743 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c | |||
@@ -88,7 +88,7 @@ typedef struct parport_info_t { | |||
88 | } parport_info_t; | 88 | } parport_info_t; |
89 | 89 | ||
90 | static dev_link_t *parport_attach(void); | 90 | static dev_link_t *parport_attach(void); |
91 | static void parport_detach(dev_link_t *); | 91 | static void parport_detach(struct pcmcia_device *p_dev); |
92 | static void parport_config(dev_link_t *link); | 92 | static void parport_config(dev_link_t *link); |
93 | static void parport_cs_release(dev_link_t *); | 93 | static void parport_cs_release(dev_link_t *); |
94 | static int parport_event(event_t event, int priority, | 94 | static int parport_event(event_t event, int priority, |
@@ -137,7 +137,7 @@ static dev_link_t *parport_attach(void) | |||
137 | ret = pcmcia_register_client(&link->handle, &client_reg); | 137 | ret = pcmcia_register_client(&link->handle, &client_reg); |
138 | if (ret != CS_SUCCESS) { | 138 | if (ret != CS_SUCCESS) { |
139 | cs_error(link->handle, RegisterClient, ret); | 139 | cs_error(link->handle, RegisterClient, ret); |
140 | parport_detach(link); | 140 | parport_detach(link->handle); |
141 | return NULL; | 141 | return NULL; |
142 | } | 142 | } |
143 | 143 | ||
@@ -153,13 +153,13 @@ static dev_link_t *parport_attach(void) | |||
153 | 153 | ||
154 | ======================================================================*/ | 154 | ======================================================================*/ |
155 | 155 | ||
156 | static void parport_detach(dev_link_t *link) | 156 | static void parport_detach(struct pcmcia_device *p_dev) |
157 | { | 157 | { |
158 | dev_link_t *link = dev_to_instance(p_dev); | ||
158 | dev_link_t **linkp; | 159 | dev_link_t **linkp; |
159 | int ret; | ||
160 | 160 | ||
161 | DEBUG(0, "parport_detach(0x%p)\n", link); | 161 | DEBUG(0, "parport_detach(0x%p)\n", link); |
162 | 162 | ||
163 | /* Locate device structure */ | 163 | /* Locate device structure */ |
164 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | 164 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) |
165 | if (*linkp == link) break; | 165 | if (*linkp == link) break; |
@@ -168,17 +168,10 @@ static void parport_detach(dev_link_t *link) | |||
168 | 168 | ||
169 | if (link->state & DEV_CONFIG) | 169 | if (link->state & DEV_CONFIG) |
170 | parport_cs_release(link); | 170 | parport_cs_release(link); |
171 | 171 | ||
172 | if (link->handle) { | ||
173 | ret = pcmcia_deregister_client(link->handle); | ||
174 | if (ret != CS_SUCCESS) | ||
175 | cs_error(link->handle, DeregisterClient, ret); | ||
176 | } | ||
177 | |||
178 | /* Unlink, free device structure */ | 172 | /* Unlink, free device structure */ |
179 | *linkp = link->next; | 173 | *linkp = link->next; |
180 | kfree(link->priv); | 174 | kfree(link->priv); |
181 | |||
182 | } /* parport_detach */ | 175 | } /* parport_detach */ |
183 | 176 | ||
184 | /*====================================================================== | 177 | /*====================================================================== |
@@ -362,11 +355,6 @@ int parport_event(event_t event, int priority, | |||
362 | DEBUG(1, "parport_event(0x%06x)\n", event); | 355 | DEBUG(1, "parport_event(0x%06x)\n", event); |
363 | 356 | ||
364 | switch (event) { | 357 | switch (event) { |
365 | case CS_EVENT_CARD_REMOVAL: | ||
366 | link->state &= ~DEV_PRESENT; | ||
367 | if (link->state & DEV_CONFIG) | ||
368 | parport_cs_release(link); | ||
369 | break; | ||
370 | case CS_EVENT_CARD_INSERTION: | 358 | case CS_EVENT_CARD_INSERTION: |
371 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 359 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
372 | parport_config(link); | 360 | parport_config(link); |
@@ -389,7 +377,7 @@ static struct pcmcia_driver parport_cs_driver = { | |||
389 | }, | 377 | }, |
390 | .attach = parport_attach, | 378 | .attach = parport_attach, |
391 | .event = parport_event, | 379 | .event = parport_event, |
392 | .detach = parport_detach, | 380 | .remove = parport_detach, |
393 | .id_table = parport_ids, | 381 | .id_table = parport_ids, |
394 | .suspend = parport_suspend, | 382 | .suspend = parport_suspend, |
395 | .resume = parport_resume, | 383 | .resume = parport_resume, |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 5223395b246a..32b4d6baa917 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -57,8 +57,6 @@ module_param_named(pc_debug, ds_pc_debug, int, 0644); | |||
57 | 57 | ||
58 | spinlock_t pcmcia_dev_list_lock; | 58 | spinlock_t pcmcia_dev_list_lock; |
59 | 59 | ||
60 | static int unbind_request(struct pcmcia_socket *s); | ||
61 | |||
62 | /*====================================================================*/ | 60 | /*====================================================================*/ |
63 | 61 | ||
64 | /* code which was in cs.c before */ | 62 | /* code which was in cs.c before */ |
@@ -205,7 +203,7 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) | |||
205 | unsigned int i; | 203 | unsigned int i; |
206 | u32 hash; | 204 | u32 hash; |
207 | 205 | ||
208 | if (!p_drv->attach || !p_drv->event || !p_drv->detach) | 206 | if (!p_drv->attach || !p_drv->event || !p_drv->remove) |
209 | printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " | 207 | printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " |
210 | "function\n", p_drv->drv.name); | 208 | "function\n", p_drv->drv.name); |
211 | 209 | ||
@@ -399,13 +397,42 @@ static int pcmcia_device_remove(struct device * dev) | |||
399 | { | 397 | { |
400 | struct pcmcia_device *p_dev; | 398 | struct pcmcia_device *p_dev; |
401 | struct pcmcia_driver *p_drv; | 399 | struct pcmcia_driver *p_drv; |
400 | int i; | ||
402 | 401 | ||
403 | /* detach the "instance" */ | 402 | /* detach the "instance" */ |
404 | p_dev = to_pcmcia_dev(dev); | 403 | p_dev = to_pcmcia_dev(dev); |
405 | p_drv = to_pcmcia_drv(dev->driver); | 404 | p_drv = to_pcmcia_drv(dev->driver); |
406 | 405 | ||
406 | /* the likely, new path */ | ||
407 | if (p_drv && p_drv->remove) { | ||
408 | p_drv->remove(p_dev); | ||
409 | |||
410 | /* check for proper unloading */ | ||
411 | if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) | ||
412 | printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", | ||
413 | p_drv->drv.name); | ||
414 | |||
415 | for (i = 0; i < MAX_WIN; i++) | ||
416 | if (p_dev->state & CLIENT_WIN_REQ(i)) | ||
417 | printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n", | ||
418 | p_drv->drv.name); | ||
419 | |||
420 | /* undo pcmcia_register_client */ | ||
421 | p_dev->state = CLIENT_UNBOUND; | ||
422 | pcmcia_put_dev(p_dev); | ||
423 | |||
424 | /* references from pcmcia_probe_device */ | ||
425 | pcmcia_put_dev(p_dev); | ||
426 | module_put(p_drv->owner); | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | /* old path */ | ||
407 | if (p_drv) { | 432 | if (p_drv) { |
408 | if ((p_drv->detach) && (p_dev->instance)) { | 433 | if ((p_drv->detach) && (p_dev->instance)) { |
434 | printk(KERN_INFO "pcmcia: using deprecated detach mechanism. Fix the driver!\n"); | ||
435 | |||
409 | p_drv->detach(p_dev->instance); | 436 | p_drv->detach(p_dev->instance); |
410 | /* from pcmcia_probe_device */ | 437 | /* from pcmcia_probe_device */ |
411 | put_device(&p_dev->dev); | 438 | put_device(&p_dev->dev); |
@@ -417,6 +444,36 @@ static int pcmcia_device_remove(struct device * dev) | |||
417 | } | 444 | } |
418 | 445 | ||
419 | 446 | ||
447 | /* | ||
448 | * Removes a PCMCIA card from the device tree and socket list. | ||
449 | */ | ||
450 | static void pcmcia_card_remove(struct pcmcia_socket *s) | ||
451 | { | ||
452 | struct pcmcia_device *p_dev; | ||
453 | unsigned long flags; | ||
454 | |||
455 | ds_dbg(2, "unbind_request(%d)\n", s->sock); | ||
456 | |||
457 | s->device_count = 0; | ||
458 | |||
459 | for (;;) { | ||
460 | /* unregister all pcmcia_devices registered with this socket*/ | ||
461 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | ||
462 | if (list_empty(&s->devices_list)) { | ||
463 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
464 | return; | ||
465 | } | ||
466 | p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); | ||
467 | list_del(&p_dev->socket_device_list); | ||
468 | p_dev->state |= CLIENT_STALE; | ||
469 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
470 | |||
471 | device_unregister(&p_dev->dev); | ||
472 | } | ||
473 | |||
474 | return; | ||
475 | } /* unbind_request */ | ||
476 | |||
420 | 477 | ||
421 | /* | 478 | /* |
422 | * pcmcia_device_query -- determine information about a pcmcia device | 479 | * pcmcia_device_query -- determine information about a pcmcia device |
@@ -1059,8 +1116,8 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
1059 | 1116 | ||
1060 | case CS_EVENT_CARD_REMOVAL: | 1117 | case CS_EVENT_CARD_REMOVAL: |
1061 | s->pcmcia_state.present = 0; | 1118 | s->pcmcia_state.present = 0; |
1062 | send_event(skt, event, priority); | 1119 | send_event(skt, event, priority); |
1063 | unbind_request(skt); | 1120 | pcmcia_card_remove(skt); |
1064 | handle_event(skt, event); | 1121 | handle_event(skt, event); |
1065 | break; | 1122 | break; |
1066 | 1123 | ||
@@ -1177,36 +1234,6 @@ int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req) | |||
1177 | EXPORT_SYMBOL(pcmcia_register_client); | 1234 | EXPORT_SYMBOL(pcmcia_register_client); |
1178 | 1235 | ||
1179 | 1236 | ||
1180 | /* unbind _all_ devices attached to a given pcmcia_bus_socket. The | ||
1181 | * drivers have been called with EVENT_CARD_REMOVAL before. | ||
1182 | */ | ||
1183 | static int unbind_request(struct pcmcia_socket *s) | ||
1184 | { | ||
1185 | struct pcmcia_device *p_dev; | ||
1186 | unsigned long flags; | ||
1187 | |||
1188 | ds_dbg(2, "unbind_request(%d)\n", s->sock); | ||
1189 | |||
1190 | s->device_count = 0; | ||
1191 | |||
1192 | for (;;) { | ||
1193 | /* unregister all pcmcia_devices registered with this socket*/ | ||
1194 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | ||
1195 | if (list_empty(&s->devices_list)) { | ||
1196 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
1197 | return 0; | ||
1198 | } | ||
1199 | p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); | ||
1200 | list_del(&p_dev->socket_device_list); | ||
1201 | p_dev->state |= CLIENT_STALE; | ||
1202 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
1203 | |||
1204 | device_unregister(&p_dev->dev); | ||
1205 | } | ||
1206 | |||
1207 | return 0; | ||
1208 | } /* unbind_request */ | ||
1209 | |||
1210 | int pcmcia_deregister_client(struct pcmcia_device *p_dev) | 1237 | int pcmcia_deregister_client(struct pcmcia_device *p_dev) |
1211 | { | 1238 | { |
1212 | struct pcmcia_socket *s; | 1239 | struct pcmcia_socket *s; |
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 82988a3e35ec..3128ba8c57a9 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c | |||
@@ -99,7 +99,7 @@ static int aha152x_event(event_t event, int priority, | |||
99 | event_callback_args_t *args); | 99 | event_callback_args_t *args); |
100 | 100 | ||
101 | static dev_link_t *aha152x_attach(void); | 101 | static dev_link_t *aha152x_attach(void); |
102 | static void aha152x_detach(dev_link_t *); | 102 | static void aha152x_detach(struct pcmcia_device *p_dev); |
103 | 103 | ||
104 | static dev_link_t *dev_list; | 104 | static dev_link_t *dev_list; |
105 | static dev_info_t dev_info = "aha152x_cs"; | 105 | static dev_info_t dev_info = "aha152x_cs"; |
@@ -138,7 +138,7 @@ static dev_link_t *aha152x_attach(void) | |||
138 | ret = pcmcia_register_client(&link->handle, &client_reg); | 138 | ret = pcmcia_register_client(&link->handle, &client_reg); |
139 | if (ret != 0) { | 139 | if (ret != 0) { |
140 | cs_error(link->handle, RegisterClient, ret); | 140 | cs_error(link->handle, RegisterClient, ret); |
141 | aha152x_detach(link); | 141 | aha152x_detach(link->handle); |
142 | return NULL; | 142 | return NULL; |
143 | } | 143 | } |
144 | 144 | ||
@@ -147,8 +147,9 @@ static dev_link_t *aha152x_attach(void) | |||
147 | 147 | ||
148 | /*====================================================================*/ | 148 | /*====================================================================*/ |
149 | 149 | ||
150 | static void aha152x_detach(dev_link_t *link) | 150 | static void aha152x_detach(struct pcmcia_device *p_dev) |
151 | { | 151 | { |
152 | dev_link_t *link = dev_to_instance(p_dev); | ||
152 | dev_link_t **linkp; | 153 | dev_link_t **linkp; |
153 | 154 | ||
154 | DEBUG(0, "aha152x_detach(0x%p)\n", link); | 155 | DEBUG(0, "aha152x_detach(0x%p)\n", link); |
@@ -162,9 +163,6 @@ static void aha152x_detach(dev_link_t *link) | |||
162 | if (link->state & DEV_CONFIG) | 163 | if (link->state & DEV_CONFIG) |
163 | aha152x_release_cs(link); | 164 | aha152x_release_cs(link); |
164 | 165 | ||
165 | if (link->handle) | ||
166 | pcmcia_deregister_client(link->handle); | ||
167 | |||
168 | /* Unlink device structure, free bits */ | 166 | /* Unlink device structure, free bits */ |
169 | *linkp = link->next; | 167 | *linkp = link->next; |
170 | kfree(link->priv); | 168 | kfree(link->priv); |
@@ -307,11 +305,6 @@ static int aha152x_event(event_t event, int priority, | |||
307 | DEBUG(0, "aha152x_event(0x%06x)\n", event); | 305 | DEBUG(0, "aha152x_event(0x%06x)\n", event); |
308 | 306 | ||
309 | switch (event) { | 307 | switch (event) { |
310 | case CS_EVENT_CARD_REMOVAL: | ||
311 | link->state &= ~DEV_PRESENT; | ||
312 | if (link->state & DEV_CONFIG) | ||
313 | aha152x_release_cs(link); | ||
314 | break; | ||
315 | case CS_EVENT_CARD_INSERTION: | 308 | case CS_EVENT_CARD_INSERTION: |
316 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 309 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
317 | aha152x_config_cs(link); | 310 | aha152x_config_cs(link); |
@@ -337,7 +330,7 @@ static struct pcmcia_driver aha152x_cs_driver = { | |||
337 | }, | 330 | }, |
338 | .attach = aha152x_attach, | 331 | .attach = aha152x_attach, |
339 | .event = aha152x_event, | 332 | .event = aha152x_event, |
340 | .detach = aha152x_detach, | 333 | .remove = aha152x_detach, |
341 | .id_table = aha152x_ids, | 334 | .id_table = aha152x_ids, |
342 | .suspend = aha152x_suspend, | 335 | .suspend = aha152x_suspend, |
343 | .resume = aha152x_resume, | 336 | .resume = aha152x_resume, |
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 9e1d68c14694..5842c938fff5 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c | |||
@@ -84,7 +84,7 @@ static int fdomain_event(event_t event, int priority, | |||
84 | event_callback_args_t *args); | 84 | event_callback_args_t *args); |
85 | 85 | ||
86 | static dev_link_t *fdomain_attach(void); | 86 | static dev_link_t *fdomain_attach(void); |
87 | static void fdomain_detach(dev_link_t *); | 87 | static void fdomain_detach(struct pcmcia_device *p_dev); |
88 | 88 | ||
89 | 89 | ||
90 | static dev_link_t *dev_list = NULL; | 90 | static dev_link_t *dev_list = NULL; |
@@ -124,7 +124,7 @@ static dev_link_t *fdomain_attach(void) | |||
124 | ret = pcmcia_register_client(&link->handle, &client_reg); | 124 | ret = pcmcia_register_client(&link->handle, &client_reg); |
125 | if (ret != 0) { | 125 | if (ret != 0) { |
126 | cs_error(link->handle, RegisterClient, ret); | 126 | cs_error(link->handle, RegisterClient, ret); |
127 | fdomain_detach(link); | 127 | fdomain_detach(link->handle); |
128 | return NULL; | 128 | return NULL; |
129 | } | 129 | } |
130 | 130 | ||
@@ -133,8 +133,9 @@ static dev_link_t *fdomain_attach(void) | |||
133 | 133 | ||
134 | /*====================================================================*/ | 134 | /*====================================================================*/ |
135 | 135 | ||
136 | static void fdomain_detach(dev_link_t *link) | 136 | static void fdomain_detach(struct pcmcia_device *p_dev) |
137 | { | 137 | { |
138 | dev_link_t *link = dev_to_instance(p_dev); | ||
138 | dev_link_t **linkp; | 139 | dev_link_t **linkp; |
139 | 140 | ||
140 | DEBUG(0, "fdomain_detach(0x%p)\n", link); | 141 | DEBUG(0, "fdomain_detach(0x%p)\n", link); |
@@ -148,9 +149,6 @@ static void fdomain_detach(dev_link_t *link) | |||
148 | if (link->state & DEV_CONFIG) | 149 | if (link->state & DEV_CONFIG) |
149 | fdomain_release(link); | 150 | fdomain_release(link); |
150 | 151 | ||
151 | if (link->handle) | ||
152 | pcmcia_deregister_client(link->handle); | ||
153 | |||
154 | /* Unlink device structure, free bits */ | 152 | /* Unlink device structure, free bits */ |
155 | *linkp = link->next; | 153 | *linkp = link->next; |
156 | kfree(link->priv); | 154 | kfree(link->priv); |
@@ -288,11 +286,6 @@ static int fdomain_event(event_t event, int priority, | |||
288 | DEBUG(1, "fdomain_event(0x%06x)\n", event); | 286 | DEBUG(1, "fdomain_event(0x%06x)\n", event); |
289 | 287 | ||
290 | switch (event) { | 288 | switch (event) { |
291 | case CS_EVENT_CARD_REMOVAL: | ||
292 | link->state &= ~DEV_PRESENT; | ||
293 | if (link->state & DEV_CONFIG) | ||
294 | fdomain_release(link); | ||
295 | break; | ||
296 | case CS_EVENT_CARD_INSERTION: | 289 | case CS_EVENT_CARD_INSERTION: |
297 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 290 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
298 | fdomain_config(link); | 291 | fdomain_config(link); |
@@ -317,7 +310,7 @@ static struct pcmcia_driver fdomain_cs_driver = { | |||
317 | }, | 310 | }, |
318 | .attach = fdomain_attach, | 311 | .attach = fdomain_attach, |
319 | .event = fdomain_event, | 312 | .event = fdomain_event, |
320 | .detach = fdomain_detach, | 313 | .remove = fdomain_detach, |
321 | .id_table = fdomain_ids, | 314 | .id_table = fdomain_ids, |
322 | .suspend = fdomain_suspend, | 315 | .suspend = fdomain_suspend, |
323 | .resume = fdomain_resume, | 316 | .resume = fdomain_resume, |
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 870e87180d12..e40a8c22aa9d 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -1646,7 +1646,7 @@ static dev_link_t *nsp_cs_attach(void) | |||
1646 | ret = pcmcia_register_client(&link->handle, &client_reg); | 1646 | ret = pcmcia_register_client(&link->handle, &client_reg); |
1647 | if (ret != CS_SUCCESS) { | 1647 | if (ret != CS_SUCCESS) { |
1648 | cs_error(link->handle, RegisterClient, ret); | 1648 | cs_error(link->handle, RegisterClient, ret); |
1649 | nsp_cs_detach(link); | 1649 | nsp_cs_detach(link->handle); |
1650 | return NULL; | 1650 | return NULL; |
1651 | } | 1651 | } |
1652 | 1652 | ||
@@ -1662,8 +1662,9 @@ static dev_link_t *nsp_cs_attach(void) | |||
1662 | structures are freed. Otherwise, the structures will be freed | 1662 | structures are freed. Otherwise, the structures will be freed |
1663 | when the device is released. | 1663 | when the device is released. |
1664 | ======================================================================*/ | 1664 | ======================================================================*/ |
1665 | static void nsp_cs_detach(dev_link_t *link) | 1665 | static void nsp_cs_detach(struct pcmcia_device *p_dev) |
1666 | { | 1666 | { |
1667 | dev_link_t *link = dev_to_instance(p_dev); | ||
1667 | dev_link_t **linkp; | 1668 | dev_link_t **linkp; |
1668 | 1669 | ||
1669 | nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); | 1670 | nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); |
@@ -1678,12 +1679,9 @@ static void nsp_cs_detach(dev_link_t *link) | |||
1678 | return; | 1679 | return; |
1679 | } | 1680 | } |
1680 | 1681 | ||
1681 | if (link->state & DEV_CONFIG) | 1682 | if (link->state & DEV_CONFIG) { |
1683 | ((scsi_info_t *)link->priv)->stop = 1; | ||
1682 | nsp_cs_release(link); | 1684 | nsp_cs_release(link); |
1683 | |||
1684 | /* Break the link with Card Services */ | ||
1685 | if (link->handle) { | ||
1686 | pcmcia_deregister_client(link->handle); | ||
1687 | } | 1685 | } |
1688 | 1686 | ||
1689 | /* Unlink device structure, free bits */ | 1687 | /* Unlink device structure, free bits */ |
@@ -2096,15 +2094,6 @@ static int nsp_cs_event(event_t event, | |||
2096 | nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event); | 2094 | nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event); |
2097 | 2095 | ||
2098 | switch (event) { | 2096 | switch (event) { |
2099 | case CS_EVENT_CARD_REMOVAL: | ||
2100 | nsp_dbg(NSP_DEBUG_INIT, "event: remove"); | ||
2101 | link->state &= ~DEV_PRESENT; | ||
2102 | if (link->state & DEV_CONFIG) { | ||
2103 | ((scsi_info_t *)link->priv)->stop = 1; | ||
2104 | nsp_cs_release(link); | ||
2105 | } | ||
2106 | break; | ||
2107 | |||
2108 | case CS_EVENT_CARD_INSERTION: | 2097 | case CS_EVENT_CARD_INSERTION: |
2109 | nsp_dbg(NSP_DEBUG_INIT, "event: insert"); | 2098 | nsp_dbg(NSP_DEBUG_INIT, "event: insert"); |
2110 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 2099 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
@@ -2144,7 +2133,7 @@ static struct pcmcia_driver nsp_driver = { | |||
2144 | }, | 2133 | }, |
2145 | .attach = nsp_cs_attach, | 2134 | .attach = nsp_cs_attach, |
2146 | .event = nsp_cs_event, | 2135 | .event = nsp_cs_event, |
2147 | .detach = nsp_cs_detach, | 2136 | .remove = nsp_cs_detach, |
2148 | .id_table = nsp_cs_ids, | 2137 | .id_table = nsp_cs_ids, |
2149 | .suspend = nsp_cs_suspend, | 2138 | .suspend = nsp_cs_suspend, |
2150 | .resume = nsp_cs_resume, | 2139 | .resume = nsp_cs_resume, |
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index f8b943082717..d276c469edf1 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h | |||
@@ -297,7 +297,7 @@ typedef struct _nsp_hw_data { | |||
297 | 297 | ||
298 | /* Card service functions */ | 298 | /* Card service functions */ |
299 | static dev_link_t *nsp_cs_attach (void); | 299 | static dev_link_t *nsp_cs_attach (void); |
300 | static void nsp_cs_detach (dev_link_t *link); | 300 | static void nsp_cs_detach (struct pcmcia_device *p_dev); |
301 | static void nsp_cs_release(dev_link_t *link); | 301 | static void nsp_cs_release(dev_link_t *link); |
302 | static void nsp_cs_config (dev_link_t *link); | 302 | static void nsp_cs_config (dev_link_t *link); |
303 | static int nsp_cs_event (event_t event, int priority, event_callback_args_t *args); | 303 | static int nsp_cs_event (event_t event, int priority, event_callback_args_t *args); |
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index 2541a999a0e5..8351dc234ffb 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c | |||
@@ -101,7 +101,7 @@ static void qlogic_release(dev_link_t *link); | |||
101 | static int qlogic_event(event_t event, int priority, event_callback_args_t * args); | 101 | static int qlogic_event(event_t event, int priority, event_callback_args_t * args); |
102 | 102 | ||
103 | static dev_link_t *qlogic_attach(void); | 103 | static dev_link_t *qlogic_attach(void); |
104 | static void qlogic_detach(dev_link_t *); | 104 | static void qlogic_detach(struct pcmcia_device *p_dev); |
105 | 105 | ||
106 | 106 | ||
107 | static dev_link_t *dev_list = NULL; | 107 | static dev_link_t *dev_list = NULL; |
@@ -198,7 +198,7 @@ static dev_link_t *qlogic_attach(void) | |||
198 | ret = pcmcia_register_client(&link->handle, &client_reg); | 198 | ret = pcmcia_register_client(&link->handle, &client_reg); |
199 | if (ret != 0) { | 199 | if (ret != 0) { |
200 | cs_error(link->handle, RegisterClient, ret); | 200 | cs_error(link->handle, RegisterClient, ret); |
201 | qlogic_detach(link); | 201 | qlogic_detach(link->handle); |
202 | return NULL; | 202 | return NULL; |
203 | } | 203 | } |
204 | 204 | ||
@@ -207,8 +207,9 @@ static dev_link_t *qlogic_attach(void) | |||
207 | 207 | ||
208 | /*====================================================================*/ | 208 | /*====================================================================*/ |
209 | 209 | ||
210 | static void qlogic_detach(dev_link_t * link) | 210 | static void qlogic_detach(struct pcmcia_device *p_dev) |
211 | { | 211 | { |
212 | dev_link_t *link = dev_to_instance(p_dev); | ||
212 | dev_link_t **linkp; | 213 | dev_link_t **linkp; |
213 | 214 | ||
214 | DEBUG(0, "qlogic_detach(0x%p)\n", link); | 215 | DEBUG(0, "qlogic_detach(0x%p)\n", link); |
@@ -223,9 +224,6 @@ static void qlogic_detach(dev_link_t * link) | |||
223 | if (link->state & DEV_CONFIG) | 224 | if (link->state & DEV_CONFIG) |
224 | qlogic_release(link); | 225 | qlogic_release(link); |
225 | 226 | ||
226 | if (link->handle) | ||
227 | pcmcia_deregister_client(link->handle); | ||
228 | |||
229 | /* Unlink device structure, free bits */ | 227 | /* Unlink device structure, free bits */ |
230 | *linkp = link->next; | 228 | *linkp = link->next; |
231 | kfree(link->priv); | 229 | kfree(link->priv); |
@@ -390,11 +388,6 @@ static int qlogic_event(event_t event, int priority, event_callback_args_t * arg | |||
390 | DEBUG(1, "qlogic_event(0x%06x)\n", event); | 388 | DEBUG(1, "qlogic_event(0x%06x)\n", event); |
391 | 389 | ||
392 | switch (event) { | 390 | switch (event) { |
393 | case CS_EVENT_CARD_REMOVAL: | ||
394 | link->state &= ~DEV_PRESENT; | ||
395 | if (link->state & DEV_CONFIG) | ||
396 | qlogic_release(link); | ||
397 | break; | ||
398 | case CS_EVENT_CARD_INSERTION: | 391 | case CS_EVENT_CARD_INSERTION: |
399 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 392 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
400 | qlogic_config(link); | 393 | qlogic_config(link); |
@@ -432,7 +425,7 @@ static struct pcmcia_driver qlogic_cs_driver = { | |||
432 | }, | 425 | }, |
433 | .attach = qlogic_attach, | 426 | .attach = qlogic_attach, |
434 | .event = qlogic_event, | 427 | .event = qlogic_event, |
435 | .detach = qlogic_detach, | 428 | .remove = qlogic_detach, |
436 | .id_table = qlogic_ids, | 429 | .id_table = qlogic_ids, |
437 | .suspend = qlogic_suspend, | 430 | .suspend = qlogic_suspend, |
438 | .resume = qlogic_resume, | 431 | .resume = qlogic_resume, |
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index c4e3e2294c66..a0f8e2691f9c 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c | |||
@@ -918,11 +918,6 @@ SYM53C500_event(event_t event, int priority, event_callback_args_t *args) | |||
918 | DEBUG(1, "SYM53C500_event(0x%06x)\n", event); | 918 | DEBUG(1, "SYM53C500_event(0x%06x)\n", event); |
919 | 919 | ||
920 | switch (event) { | 920 | switch (event) { |
921 | case CS_EVENT_CARD_REMOVAL: | ||
922 | link->state &= ~DEV_PRESENT; | ||
923 | if (link->state & DEV_CONFIG) | ||
924 | SYM53C500_release(link); | ||
925 | break; | ||
926 | case CS_EVENT_CARD_INSERTION: | 921 | case CS_EVENT_CARD_INSERTION: |
927 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 922 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
928 | SYM53C500_config(link); | 923 | SYM53C500_config(link); |
@@ -932,8 +927,9 @@ SYM53C500_event(event_t event, int priority, event_callback_args_t *args) | |||
932 | } /* SYM53C500_event */ | 927 | } /* SYM53C500_event */ |
933 | 928 | ||
934 | static void | 929 | static void |
935 | SYM53C500_detach(dev_link_t *link) | 930 | SYM53C500_detach(struct pcmcia_device *p_dev) |
936 | { | 931 | { |
932 | dev_link_t *link = dev_to_instance(p_dev); | ||
937 | dev_link_t **linkp; | 933 | dev_link_t **linkp; |
938 | 934 | ||
939 | DEBUG(0, "SYM53C500_detach(0x%p)\n", link); | 935 | DEBUG(0, "SYM53C500_detach(0x%p)\n", link); |
@@ -948,9 +944,6 @@ SYM53C500_detach(dev_link_t *link) | |||
948 | if (link->state & DEV_CONFIG) | 944 | if (link->state & DEV_CONFIG) |
949 | SYM53C500_release(link); | 945 | SYM53C500_release(link); |
950 | 946 | ||
951 | if (link->handle) | ||
952 | pcmcia_deregister_client(link->handle); | ||
953 | |||
954 | /* Unlink device structure, free bits. */ | 947 | /* Unlink device structure, free bits. */ |
955 | *linkp = link->next; | 948 | *linkp = link->next; |
956 | kfree(link->priv); | 949 | kfree(link->priv); |
@@ -993,7 +986,7 @@ SYM53C500_attach(void) | |||
993 | ret = pcmcia_register_client(&link->handle, &client_reg); | 986 | ret = pcmcia_register_client(&link->handle, &client_reg); |
994 | if (ret != 0) { | 987 | if (ret != 0) { |
995 | cs_error(link->handle, RegisterClient, ret); | 988 | cs_error(link->handle, RegisterClient, ret); |
996 | SYM53C500_detach(link); | 989 | SYM53C500_detach(link->handle); |
997 | return NULL; | 990 | return NULL; |
998 | } | 991 | } |
999 | 992 | ||
@@ -1019,7 +1012,7 @@ static struct pcmcia_driver sym53c500_cs_driver = { | |||
1019 | }, | 1012 | }, |
1020 | .attach = SYM53C500_attach, | 1013 | .attach = SYM53C500_attach, |
1021 | .event = SYM53C500_event, | 1014 | .event = SYM53C500_event, |
1022 | .detach = SYM53C500_detach, | 1015 | .remove = SYM53C500_detach, |
1023 | .id_table = sym53c500_ids, | 1016 | .id_table = sym53c500_ids, |
1024 | .suspend = sym53c500_suspend, | 1017 | .suspend = sym53c500_suspend, |
1025 | .resume = sym53c500_resume, | 1018 | .resume = sym53c500_resume, |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 3487ee9eab1d..a95366366504 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -120,7 +120,7 @@ static int serial_event(event_t event, int priority, | |||
120 | static dev_info_t dev_info = "serial_cs"; | 120 | static dev_info_t dev_info = "serial_cs"; |
121 | 121 | ||
122 | static dev_link_t *serial_attach(void); | 122 | static dev_link_t *serial_attach(void); |
123 | static void serial_detach(dev_link_t *); | 123 | static void serial_detach(struct pcmcia_device *p_dev); |
124 | 124 | ||
125 | static dev_link_t *dev_list = NULL; | 125 | static dev_link_t *dev_list = NULL; |
126 | 126 | ||
@@ -242,7 +242,7 @@ static dev_link_t *serial_attach(void) | |||
242 | ret = pcmcia_register_client(&link->handle, &client_reg); | 242 | ret = pcmcia_register_client(&link->handle, &client_reg); |
243 | if (ret != CS_SUCCESS) { | 243 | if (ret != CS_SUCCESS) { |
244 | cs_error(link->handle, RegisterClient, ret); | 244 | cs_error(link->handle, RegisterClient, ret); |
245 | serial_detach(link); | 245 | serial_detach(link->handle); |
246 | return NULL; | 246 | return NULL; |
247 | } | 247 | } |
248 | 248 | ||
@@ -258,11 +258,11 @@ static dev_link_t *serial_attach(void) | |||
258 | 258 | ||
259 | ======================================================================*/ | 259 | ======================================================================*/ |
260 | 260 | ||
261 | static void serial_detach(dev_link_t * link) | 261 | static void serial_detach(struct pcmcia_device *p_dev) |
262 | { | 262 | { |
263 | dev_link_t *link = dev_to_instance(p_dev); | ||
263 | struct serial_info *info = link->priv; | 264 | struct serial_info *info = link->priv; |
264 | dev_link_t **linkp; | 265 | dev_link_t **linkp; |
265 | int ret; | ||
266 | 266 | ||
267 | DEBUG(0, "serial_detach(0x%p)\n", link); | 267 | DEBUG(0, "serial_detach(0x%p)\n", link); |
268 | 268 | ||
@@ -283,12 +283,6 @@ static void serial_detach(dev_link_t * link) | |||
283 | */ | 283 | */ |
284 | serial_remove(link); | 284 | serial_remove(link); |
285 | 285 | ||
286 | if (link->handle) { | ||
287 | ret = pcmcia_deregister_client(link->handle); | ||
288 | if (ret != CS_SUCCESS) | ||
289 | cs_error(link->handle, DeregisterClient, ret); | ||
290 | } | ||
291 | |||
292 | /* Unlink device structure, free bits */ | 286 | /* Unlink device structure, free bits */ |
293 | *linkp = link->next; | 287 | *linkp = link->next; |
294 | kfree(info); | 288 | kfree(info); |
@@ -741,9 +735,6 @@ serial_event(event_t event, int priority, event_callback_args_t * args) | |||
741 | DEBUG(1, "serial_event(0x%06x)\n", event); | 735 | DEBUG(1, "serial_event(0x%06x)\n", event); |
742 | 736 | ||
743 | switch (event) { | 737 | switch (event) { |
744 | case CS_EVENT_CARD_REMOVAL: | ||
745 | serial_remove(link); | ||
746 | break; | ||
747 | 738 | ||
748 | case CS_EVENT_CARD_INSERTION: | 739 | case CS_EVENT_CARD_INSERTION: |
749 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 740 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
@@ -866,7 +857,7 @@ static struct pcmcia_driver serial_cs_driver = { | |||
866 | }, | 857 | }, |
867 | .attach = serial_attach, | 858 | .attach = serial_attach, |
868 | .event = serial_event, | 859 | .event = serial_event, |
869 | .detach = serial_detach, | 860 | .remove = serial_detach, |
870 | .id_table = serial_ids, | 861 | .id_table = serial_ids, |
871 | .suspend = serial_suspend, | 862 | .suspend = serial_suspend, |
872 | .resume = serial_resume, | 863 | .resume = serial_resume, |
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c index 7cca46be0c0f..c58140dc7a73 100644 --- a/drivers/telephony/ixj_pcmcia.c +++ b/drivers/telephony/ixj_pcmcia.c | |||
@@ -35,7 +35,7 @@ typedef struct ixj_info_t { | |||
35 | } ixj_info_t; | 35 | } ixj_info_t; |
36 | 36 | ||
37 | static dev_link_t *ixj_attach(void); | 37 | static dev_link_t *ixj_attach(void); |
38 | static void ixj_detach(dev_link_t *); | 38 | static void ixj_detach(struct pcmcia_device *p_dev); |
39 | static void ixj_config(dev_link_t * link); | 39 | static void ixj_config(dev_link_t * link); |
40 | static void ixj_cs_release(dev_link_t * link); | 40 | static void ixj_cs_release(dev_link_t * link); |
41 | static int ixj_event(event_t event, int priority, event_callback_args_t * args); | 41 | static int ixj_event(event_t event, int priority, event_callback_args_t * args); |
@@ -73,16 +73,17 @@ static dev_link_t *ixj_attach(void) | |||
73 | ret = pcmcia_register_client(&link->handle, &client_reg); | 73 | ret = pcmcia_register_client(&link->handle, &client_reg); |
74 | if (ret != CS_SUCCESS) { | 74 | if (ret != CS_SUCCESS) { |
75 | cs_error(link->handle, RegisterClient, ret); | 75 | cs_error(link->handle, RegisterClient, ret); |
76 | ixj_detach(link); | 76 | ixj_detach(link->handle); |
77 | return NULL; | 77 | return NULL; |
78 | } | 78 | } |
79 | return link; | 79 | return link; |
80 | } | 80 | } |
81 | 81 | ||
82 | static void ixj_detach(dev_link_t * link) | 82 | static void ixj_detach(struct pcmcia_device *p_dev) |
83 | { | 83 | { |
84 | dev_link_t *link = dev_to_instance(p_dev); | ||
84 | dev_link_t **linkp; | 85 | dev_link_t **linkp; |
85 | int ret; | 86 | |
86 | DEBUG(0, "ixj_detach(0x%p)\n", link); | 87 | DEBUG(0, "ixj_detach(0x%p)\n", link); |
87 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | 88 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) |
88 | if (*linkp == link) | 89 | if (*linkp == link) |
@@ -92,11 +93,7 @@ static void ixj_detach(dev_link_t * link) | |||
92 | link->state &= ~DEV_RELEASE_PENDING; | 93 | link->state &= ~DEV_RELEASE_PENDING; |
93 | if (link->state & DEV_CONFIG) | 94 | if (link->state & DEV_CONFIG) |
94 | ixj_cs_release(link); | 95 | ixj_cs_release(link); |
95 | if (link->handle) { | 96 | |
96 | ret = pcmcia_deregister_client(link->handle); | ||
97 | if (ret != CS_SUCCESS) | ||
98 | cs_error(link->handle, DeregisterClient, ret); | ||
99 | } | ||
100 | /* Unlink device structure, free bits */ | 97 | /* Unlink device structure, free bits */ |
101 | *linkp = link->next; | 98 | *linkp = link->next; |
102 | kfree(link->priv); | 99 | kfree(link->priv); |
@@ -282,13 +279,6 @@ static int ixj_event(event_t event, int priority, event_callback_args_t * args) | |||
282 | dev_link_t *link = args->client_data; | 279 | dev_link_t *link = args->client_data; |
283 | DEBUG(1, "ixj_event(0x%06x)\n", event); | 280 | DEBUG(1, "ixj_event(0x%06x)\n", event); |
284 | switch (event) { | 281 | switch (event) { |
285 | case CS_EVENT_CARD_REMOVAL: | ||
286 | link->state &= ~DEV_PRESENT; | ||
287 | if (link->state & DEV_CONFIG) { | ||
288 | link->state |= DEV_RELEASE_PENDING; | ||
289 | ixj_cs_release(link); | ||
290 | } | ||
291 | break; | ||
292 | case CS_EVENT_CARD_INSERTION: | 282 | case CS_EVENT_CARD_INSERTION: |
293 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 283 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
294 | ixj_config(link); | 284 | ixj_config(link); |
@@ -310,7 +300,7 @@ static struct pcmcia_driver ixj_driver = { | |||
310 | }, | 300 | }, |
311 | .attach = ixj_attach, | 301 | .attach = ixj_attach, |
312 | .event = ixj_event, | 302 | .event = ixj_event, |
313 | .detach = ixj_detach, | 303 | .remove = ixj_detach, |
314 | .id_table = ixj_ids, | 304 | .id_table = ixj_ids, |
315 | .suspend = ixj_suspend, | 305 | .suspend = ixj_suspend, |
316 | .resume = ixj_resume, | 306 | .resume = ixj_resume, |
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index cb8c2bdbbd04..ed3e7014dbbc 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c | |||
@@ -73,6 +73,8 @@ typedef struct local_info_t { | |||
73 | dev_node_t node; | 73 | dev_node_t node; |
74 | } local_info_t; | 74 | } local_info_t; |
75 | 75 | ||
76 | static void sl811_cs_release(dev_link_t * link); | ||
77 | |||
76 | /*====================================================================*/ | 78 | /*====================================================================*/ |
77 | 79 | ||
78 | static void release_platform_dev(struct device * dev) | 80 | static void release_platform_dev(struct device * dev) |
@@ -138,8 +140,9 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) | |||
138 | 140 | ||
139 | /*====================================================================*/ | 141 | /*====================================================================*/ |
140 | 142 | ||
141 | static void sl811_cs_detach(dev_link_t *link) | 143 | static void sl811_cs_detach(struct pcmcia_device *p_dev) |
142 | { | 144 | { |
145 | dev_link_t *link = dev_to_instance(p_dev); | ||
143 | dev_link_t **linkp; | 146 | dev_link_t **linkp; |
144 | 147 | ||
145 | DBG(0, "sl811_cs_detach(0x%p)\n", link); | 148 | DBG(0, "sl811_cs_detach(0x%p)\n", link); |
@@ -152,9 +155,9 @@ static void sl811_cs_detach(dev_link_t *link) | |||
152 | if (*linkp == NULL) | 155 | if (*linkp == NULL) |
153 | return; | 156 | return; |
154 | 157 | ||
155 | /* Break the link with Card Services */ | 158 | link->state &= ~DEV_PRESENT; |
156 | if (link->handle) | 159 | if (link->state & DEV_CONFIG) |
157 | pcmcia_deregister_client(link->handle); | 160 | sl811_cs_release(link); |
158 | 161 | ||
159 | /* Unlink device structure, and free it */ | 162 | /* Unlink device structure, and free it */ |
160 | *linkp = link->next; | 163 | *linkp = link->next; |
@@ -167,13 +170,6 @@ static void sl811_cs_release(dev_link_t * link) | |||
167 | 170 | ||
168 | DBG(0, "sl811_cs_release(0x%p)\n", link); | 171 | DBG(0, "sl811_cs_release(0x%p)\n", link); |
169 | 172 | ||
170 | if (link->open) { | ||
171 | DBG(1, "sl811_cs: release postponed, '%s' still open\n", | ||
172 | link->dev->dev_name); | ||
173 | link->state |= DEV_STALE_CONFIG; | ||
174 | return; | ||
175 | } | ||
176 | |||
177 | /* Unlink the device chain */ | 173 | /* Unlink the device chain */ |
178 | link->dev = NULL; | 174 | link->dev = NULL; |
179 | 175 | ||
@@ -184,9 +180,6 @@ static void sl811_cs_release(dev_link_t * link) | |||
184 | if (link->irq.AssignedIRQ) | 180 | if (link->irq.AssignedIRQ) |
185 | pcmcia_release_irq(link->handle, &link->irq); | 181 | pcmcia_release_irq(link->handle, &link->irq); |
186 | link->state &= ~DEV_CONFIG; | 182 | link->state &= ~DEV_CONFIG; |
187 | |||
188 | if (link->state & DEV_STALE_LINK) | ||
189 | sl811_cs_detach(link); | ||
190 | } | 183 | } |
191 | 184 | ||
192 | static void sl811_cs_config(dev_link_t *link) | 185 | static void sl811_cs_config(dev_link_t *link) |
@@ -353,12 +346,6 @@ sl811_cs_event(event_t event, int priority, event_callback_args_t *args) | |||
353 | DBG(1, "sl811_cs_event(0x%06x)\n", event); | 346 | DBG(1, "sl811_cs_event(0x%06x)\n", event); |
354 | 347 | ||
355 | switch (event) { | 348 | switch (event) { |
356 | case CS_EVENT_CARD_REMOVAL: | ||
357 | link->state &= ~DEV_PRESENT; | ||
358 | if (link->state & DEV_CONFIG) | ||
359 | sl811_cs_release(link); | ||
360 | break; | ||
361 | |||
362 | case CS_EVENT_CARD_INSERTION: | 349 | case CS_EVENT_CARD_INSERTION: |
363 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 350 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
364 | sl811_cs_config(link); | 351 | sl811_cs_config(link); |
@@ -400,7 +387,7 @@ static dev_link_t *sl811_cs_attach(void) | |||
400 | ret = pcmcia_register_client(&link->handle, &client_reg); | 387 | ret = pcmcia_register_client(&link->handle, &client_reg); |
401 | if (ret != CS_SUCCESS) { | 388 | if (ret != CS_SUCCESS) { |
402 | cs_error(link->handle, RegisterClient, ret); | 389 | cs_error(link->handle, RegisterClient, ret); |
403 | sl811_cs_detach(link); | 390 | sl811_cs_detach(link->handle); |
404 | return NULL; | 391 | return NULL; |
405 | } | 392 | } |
406 | 393 | ||
@@ -420,7 +407,7 @@ static struct pcmcia_driver sl811_cs_driver = { | |||
420 | }, | 407 | }, |
421 | .attach = sl811_cs_attach, | 408 | .attach = sl811_cs_attach, |
422 | .event = sl811_cs_event, | 409 | .event = sl811_cs_event, |
423 | .detach = sl811_cs_detach, | 410 | .remove = sl811_cs_detach, |
424 | .id_table = sl811_ids, | 411 | .id_table = sl811_ids, |
425 | .suspend = sl811_suspend, | 412 | .suspend = sl811_suspend, |
426 | .resume = sl811_resume, | 413 | .resume = sl811_resume, |
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index 020055199008..2869283acd1d 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h | |||
@@ -138,6 +138,8 @@ struct pcmcia_driver { | |||
138 | event_callback_args_t *); | 138 | event_callback_args_t *); |
139 | void (*detach)(dev_link_t *); | 139 | void (*detach)(dev_link_t *); |
140 | 140 | ||
141 | void (*remove) (struct pcmcia_device *dev); | ||
142 | |||
141 | int (*suspend) (struct pcmcia_device *dev); | 143 | int (*suspend) (struct pcmcia_device *dev); |
142 | int (*resume) (struct pcmcia_device *dev); | 144 | int (*resume) (struct pcmcia_device *dev); |
143 | 145 | ||