aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2005-11-14 15:23:14 -0500
committerDominik Brodowski <linux@dominikbrodowski.net>2006-01-05 18:03:10 -0500
commitcc3b4866bee996c922e875b8c8efe9f0d8803aae (patch)
tree6632837b6986f33566f75ed971cecbdc210e3201
parent8e9e793d68fcda6cc84c18cedf85ca0f91d801a8 (diff)
[PATCH] pcmcia: unify detach, REMOVAL_EVENT handlers into one remove callback
Unify the "detach" and REMOVAL_EVENT handlers to one "remove" function. Old functionality is preserved, for the moment. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r--Documentation/pcmcia/driver-changes.txt3
-rw-r--r--drivers/bluetooth/bluecard_cs.c24
-rw-r--r--drivers/bluetooth/bt3c_cs.c24
-rw-r--r--drivers/bluetooth/btuart_cs.c24
-rw-r--r--drivers/bluetooth/dtl1_cs.c24
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c55
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c52
-rw-r--r--drivers/char/pcmcia/synclink_cs.c34
-rw-r--r--drivers/ide/legacy/ide-cs.c21
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c34
-rw-r--r--drivers/isdn/hisax/avma1_cs.c39
-rw-r--r--drivers/isdn/hisax/elsa_cs.c26
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c38
-rw-r--r--drivers/isdn/hisax/teles_cs.c26
-rw-r--r--drivers/mtd/maps/pcmciamtd.c36
-rw-r--r--drivers/net/pcmcia/3c574_cs.c18
-rw-r--r--drivers/net/pcmcia/3c589_cs.c20
-rw-r--r--drivers/net/pcmcia/axnet_cs.c18
-rw-r--r--drivers/net/pcmcia/com20020_cs.c19
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c19
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c23
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c18
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c48
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c18
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c28
-rw-r--r--drivers/net/wireless/airo_cs.c31
-rw-r--r--drivers/net/wireless/atmel_cs.c25
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c28
-rw-r--r--drivers/net/wireless/netwave_cs.c31
-rw-r--r--drivers/net/wireless/orinoco_cs.c30
-rw-r--r--drivers/net/wireless/ray_cs.c43
-rw-r--r--drivers/net/wireless/spectrum_cs.c37
-rw-r--r--drivers/net/wireless/wavelan_cs.c31
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h2
-rw-r--r--drivers/net/wireless/wl3501_cs.c32
-rw-r--r--drivers/parport/parport_cs.c26
-rw-r--r--drivers/pcmcia/ds.c97
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c17
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c17
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c23
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.h2
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c17
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c15
-rw-r--r--drivers/serial/serial_cs.c19
-rw-r--r--drivers/telephony/ixj_pcmcia.c24
-rw-r--r--drivers/usb/host/sl811_cs.c31
-rw-r--r--include/pcmcia/ds.h2
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 @@
1This file details changes in 2.6 which affect PCMCIA card driver authors: 1This 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
92static dev_info_t dev_info = "bluecard_cs"; 92static dev_info_t dev_info = "bluecard_cs";
93 93
94static dev_link_t *bluecard_attach(void); 94static dev_link_t *bluecard_attach(void);
95static void bluecard_detach(dev_link_t *); 95static void bluecard_detach(struct pcmcia_device *p_dev);
96 96
97static dev_link_t *dev_list = NULL; 97static 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
910static void bluecard_detach(dev_link_t *link) 910static 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)
1070static int bluecard_event(event_t event, int priority, event_callback_args_t *args) 1064static 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);
95static dev_info_t dev_info = "bt3c_cs"; 95static dev_info_t dev_info = "bt3c_cs";
96 96
97static dev_link_t *bt3c_attach(void); 97static dev_link_t *bt3c_attach(void);
98static void bt3c_detach(dev_link_t *); 98static void bt3c_detach(struct pcmcia_device *p_dev);
99 99
100static dev_link_t *dev_list = NULL; 100static 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
711static void bt3c_detach(dev_link_t *link) 711static 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)
916static int bt3c_event(event_t event, int priority, event_callback_args_t *args) 910static 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
91static dev_info_t dev_info = "btuart_cs"; 91static dev_info_t dev_info = "btuart_cs";
92 92
93static dev_link_t *btuart_attach(void); 93static dev_link_t *btuart_attach(void);
94static void btuart_detach(dev_link_t *); 94static void btuart_detach(struct pcmcia_device *p_dev);
95 95
96static dev_link_t *dev_list = NULL; 96static 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
630static void btuart_detach(dev_link_t *link) 630static 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)
837static int btuart_event(event_t event, int priority, event_callback_args_t *args) 831static 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);
94static dev_info_t dev_info = "dtl1_cs"; 94static dev_info_t dev_info = "dtl1_cs";
95 95
96static dev_link_t *dtl1_attach(void); 96static dev_link_t *dtl1_attach(void);
97static void dtl1_detach(dev_link_t *); 97static void dtl1_detach(struct pcmcia_device *p_dev);
98 98
99static dev_link_t *dev_list = NULL; 99static 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
609static void dtl1_detach(dev_link_t *link) 609static 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)
788static int dtl1_event(event_t event, int priority, event_callback_args_t *args) 782static 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
69static void cm4000_detach(dev_link_t *link); 69static void cm4000_detach(struct pcmcia_device *p_dev);
70static void cm4000_release(dev_link_t *link); 70static void cm4000_release(dev_link_t *link);
71 71
72static int major; /* major number we get from the kernel */ 72static 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
1993static void cm4000_detach_by_devno(int devno, dev_link_t * link) 1988static 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
2013static 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
2072static void __exit cmm_exit(void) 2056static 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
67static void reader_release(dev_link_t *link); 67static void reader_release(dev_link_t *link);
68static void reader_detach(dev_link_t *link); 68static void reader_detach(struct pcmcia_device *p_dev);
69 69
70static int major; 70static 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
750static void reader_detach_by_devno(int devno, dev_link_t *link) 746static 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
767static 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
826static void __exit cm4040_exit(void) 814static 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);
489static int mgslpc_event(event_t event, int priority, 489static int mgslpc_event(event_t event, int priority,
490 event_callback_args_t *args); 490 event_callback_args_t *args);
491static dev_link_t *mgslpc_attach(void); 491static dev_link_t *mgslpc_attach(void);
492static void mgslpc_detach(dev_link_t *); 492static void mgslpc_detach(struct pcmcia_device *p_dev);
493 493
494static dev_info_t dev_info = "synclink_cs"; 494static dev_info_t dev_info = "synclink_cs";
495static dev_link_t *dev_list = NULL; 495static 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
743static void mgslpc_detach(dev_link_t *link) 741static 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,
94static dev_info_t dev_info = "ide-cs"; 94static dev_info_t dev_info = "ide-cs";
95 95
96static dev_link_t *ide_attach(void); 96static dev_link_t *ide_attach(void);
97static void ide_detach(dev_link_t *); 97static void ide_detach(struct pcmcia_device *p_dev);
98 98
99static dev_link_t *dev_list = NULL; 99static 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
157static void ide_detach(dev_link_t *link) 157static 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
65static dev_link_t *avmcs_attach(void); 65static dev_link_t *avmcs_attach(void);
66static void avmcs_detach(dev_link_t *); 66static 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
188static void avmcs_detach(dev_link_t *link) 188static 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
433static int avmcs_suspend(struct pcmcia_device *dev) 418static 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
81static dev_link_t *avma1cs_attach(void); 81static dev_link_t *avma1cs_attach(void);
82static void avma1cs_detach(dev_link_t *); 82static 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
206static void avma1cs_detach(dev_link_t *link) 206static 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
448static int avma1cs_suspend(struct pcmcia_device *dev) 429static 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
108static dev_link_t *elsa_cs_attach(void); 108static dev_link_t *elsa_cs_attach(void);
109static void elsa_cs_detach(dev_link_t *); 109static 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
235static void elsa_cs_detach(dev_link_t *link) 235static 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
109static dev_link_t *sedlbauer_attach(void); 109static dev_link_t *sedlbauer_attach(void);
110static void sedlbauer_detach(dev_link_t *); 110static 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
249static void sedlbauer_detach(dev_link_t *link) 249static 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
556static int sedlbauer_suspend(struct pcmcia_device *p_dev) 539static 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
89static dev_link_t *teles_attach(void); 89static dev_link_t *teles_attach(void);
90static void teles_detach(dev_link_t *); 90static 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
216static void teles_detach(dev_link_t *link) 216static 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
755static void pcmciamtd_detach(dev_link_t *link) 743static 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);
253static dev_info_t dev_info = "3c574_cs"; 253static dev_info_t dev_info = "3c574_cs";
254 254
255static dev_link_t *tc574_attach(void); 255static dev_link_t *tc574_attach(void);
256static void tc574_detach(dev_link_t *); 256static void tc574_detach(struct pcmcia_device *p_dev);
257 257
258static dev_link_t *dev_list; 258static 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
335static void tc574_detach(dev_link_t *link) 335static 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;
164static dev_info_t dev_info = "3c589_cs"; 164static dev_info_t dev_info = "3c589_cs";
165 165
166static dev_link_t *tc589_attach(void); 166static dev_link_t *tc589_attach(void);
167static void tc589_detach(dev_link_t *); 167static void tc589_detach(struct pcmcia_device *p_dev);
168 168
169static dev_link_t *dev_list; 169static 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
249static void tc589_detach(dev_link_t *link) 249static 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
110static dev_link_t *axnet_attach(void); 110static dev_link_t *axnet_attach(void);
111static void axnet_detach(dev_link_t *); 111static void axnet_detach(struct pcmcia_device *p_dev);
112 112
113static dev_info_t dev_info = "axnet_cs"; 113static dev_info_t dev_info = "axnet_cs";
114static dev_link_t *dev_list; 114static 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
204static void axnet_detach(dev_link_t *link) 204static 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,
126static dev_info_t dev_info = "com20020_cs"; 126static dev_info_t dev_info = "com20020_cs";
127 127
128static dev_link_t *com20020_attach(void); 128static dev_link_t *com20020_attach(void);
129static void com20020_detach(dev_link_t *); 129static void com20020_detach(struct pcmcia_device *p_dev);
130 130
131static dev_link_t *dev_list; 131static 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
229static void com20020_detach(dev_link_t *link) 229static 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);
91static int fmvj18x_event(event_t event, int priority, 91static int fmvj18x_event(event_t event, int priority,
92 event_callback_args_t *args); 92 event_callback_args_t *args);
93static dev_link_t *fmvj18x_attach(void); 93static dev_link_t *fmvj18x_attach(void);
94static void fmvj18x_detach(dev_link_t *); 94static 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
303static void fmvj18x_detach(dev_link_t *link) 303static 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,
114static dev_info_t dev_info = "ibmtr_cs"; 114static dev_info_t dev_info = "ibmtr_cs";
115 115
116static dev_link_t *ibmtr_attach(void); 116static dev_link_t *ibmtr_attach(void);
117static void ibmtr_detach(dev_link_t *); 117static void ibmtr_detach(struct pcmcia_device *p_dev);
118 118
119static dev_link_t *dev_list; 119static dev_link_t *dev_list;
120 120
@@ -201,7 +201,7 @@ out:
201 return link; 201 return link;
202 202
203out_detach: 203out_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
218static void ibmtr_detach(dev_link_t *link) 218static 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
442static dev_link_t *nmclan_attach(void); 442static dev_link_t *nmclan_attach(void);
443static void nmclan_detach(dev_link_t *); 443static void nmclan_detach(struct pcmcia_device *p_dev);
444 444
445/* ---------------------------------------------------------------------------- 445/* ----------------------------------------------------------------------------
446nmclan_attach 446nmclan_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
524static void nmclan_detach(dev_link_t *link) 524static 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
123static dev_link_t *pcnet_attach(void); 123static dev_link_t *pcnet_attach(void);
124static void pcnet_detach(dev_link_t *); 124static void pcnet_detach(struct pcmcia_device *p_dev);
125 125
126static dev_info_t dev_info = "pcnet_cs"; 126static dev_info_t dev_info = "pcnet_cs";
127static dev_link_t *dev_list; 127static 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
299static void pcnet_detach(dev_link_t *link) 299static 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
284static dev_link_t *smc91c92_attach(void); 284static dev_link_t *smc91c92_attach(void);
285static void smc91c92_detach(dev_link_t *); 285static void smc91c92_detach(struct pcmcia_device *p_dev);
286static void smc91c92_config(dev_link_t *link); 286static void smc91c92_config(dev_link_t *link);
287static void smc91c92_release(dev_link_t *link); 287static void smc91c92_release(dev_link_t *link);
288static int smc91c92_event(event_t event, int priority, 288static 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
394static void smc91c92_detach(dev_link_t *link) 394static 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
304static dev_link_t *xirc2ps_attach(void); 304static dev_link_t *xirc2ps_attach(void);
305static void xirc2ps_detach(dev_link_t *); 305static 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
639static void 639static void
640xirc2ps_detach(dev_link_t * link) 640xirc2ps_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
94static dev_link_t *airo_attach(void); 94static dev_link_t *airo_attach(void);
95static void airo_detach(dev_link_t *); 95static 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
229static void airo_detach(dev_link_t *link) 229static 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
105static dev_link_t *atmel_attach(void); 105static dev_link_t *atmel_attach(void);
106static void atmel_detach(dev_link_t *); 106static 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
240static void atmel_detach(dev_link_t *link) 240static 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
206static void prism2_detach(dev_link_t *link); 206static void prism2_detach(struct pcmcia_device *p_dev);
207static void prism2_release(u_long arg); 207static void prism2_release(u_long arg);
208static int prism2_event(event_t event, int priority, 208static 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
538static void prism2_detach(dev_link_t *link) 538static 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,
200static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card 200static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card
201 insertion */ 201 insertion */
202static dev_link_t *netwave_attach(void); /* Create instance */ 202static dev_link_t *netwave_attach(void); /* Create instance */
203static void netwave_detach(dev_link_t *); /* Destroy instance */ 203static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */
204 204
205/* Hardware configuration */ 205/* Hardware configuration */
206static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase); 206static 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 */
477static void netwave_detach(dev_link_t *link) 477static 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
83static void orinoco_cs_release(dev_link_t *link); 83static void orinoco_cs_release(dev_link_t *link);
84static void orinoco_cs_detach(dev_link_t *link); 84static 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 */
181static void orinoco_cs_detach(dev_link_t *link) 181static 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);
94static void ray_release(dev_link_t *link); 94static void ray_release(dev_link_t *link);
95static int ray_event(event_t event, int priority, event_callback_args_t *args); 95static int ray_event(event_t event, int priority, event_callback_args_t *args);
96static dev_link_t *ray_attach(void); 96static dev_link_t *ray_attach(void);
97static void ray_detach(dev_link_t *); 97static void ray_detach(struct pcmcia_device *p_dev);
98 98
99/***** Prototypes indicated by device structure ******************************/ 99/***** Prototypes indicated by device structure ******************************/
100static int ray_dev_close(struct net_device *dev); 100static 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=============================================================================*/
421static void ray_detach(dev_link_t *link) 421static 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
92static void spectrum_cs_release(dev_link_t *link); 92static void spectrum_cs_release(dev_link_t *link);
93static void spectrum_cs_detach(dev_link_t *link); 93static 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 */
663static void spectrum_cs_detach(dev_link_t *link) 663static 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 */
4713static void 4713static void
4714wavelan_detach(dev_link_t * link) 4714wavelan_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
757static dev_link_t * 757static dev_link_t *
758 wavelan_attach(void); /* Create a new device */ 758 wavelan_attach(void); /* Create a new device */
759static void 759static void
760 wavelan_detach(dev_link_t *); /* Destroy a removed device */ 760 wavelan_detach(struct pcmcia_device *p_dev); /* Destroy a removed device */
761static int 761static 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 */
1501static void wl3501_detach(dev_link_t *link) 1501static 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 }
2018out: 2016out:
@@ -2225,18 +2223,8 @@ static int wl3501_resume(struct pcmcia_device *p_dev)
2225static int wl3501_event(event_t event, int pri, event_callback_args_t *args) 2223static 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
90static dev_link_t *parport_attach(void); 90static dev_link_t *parport_attach(void);
91static void parport_detach(dev_link_t *); 91static void parport_detach(struct pcmcia_device *p_dev);
92static void parport_config(dev_link_t *link); 92static void parport_config(dev_link_t *link);
93static void parport_cs_release(dev_link_t *); 93static void parport_cs_release(dev_link_t *);
94static int parport_event(event_t event, int priority, 94static 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
156static void parport_detach(dev_link_t *link) 156static 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
58spinlock_t pcmcia_dev_list_lock; 58spinlock_t pcmcia_dev_list_lock;
59 59
60static 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 */
450static 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)
1177EXPORT_SYMBOL(pcmcia_register_client); 1234EXPORT_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 */
1183static 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
1210int pcmcia_deregister_client(struct pcmcia_device *p_dev) 1237int 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
101static dev_link_t *aha152x_attach(void); 101static dev_link_t *aha152x_attach(void);
102static void aha152x_detach(dev_link_t *); 102static void aha152x_detach(struct pcmcia_device *p_dev);
103 103
104static dev_link_t *dev_list; 104static dev_link_t *dev_list;
105static dev_info_t dev_info = "aha152x_cs"; 105static 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
150static void aha152x_detach(dev_link_t *link) 150static 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
86static dev_link_t *fdomain_attach(void); 86static dev_link_t *fdomain_attach(void);
87static void fdomain_detach(dev_link_t *); 87static void fdomain_detach(struct pcmcia_device *p_dev);
88 88
89 89
90static dev_link_t *dev_list = NULL; 90static 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
136static void fdomain_detach(dev_link_t *link) 136static 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======================================================================*/
1665static void nsp_cs_detach(dev_link_t *link) 1665static 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 */
299static dev_link_t *nsp_cs_attach (void); 299static dev_link_t *nsp_cs_attach (void);
300static void nsp_cs_detach (dev_link_t *link); 300static void nsp_cs_detach (struct pcmcia_device *p_dev);
301static void nsp_cs_release(dev_link_t *link); 301static void nsp_cs_release(dev_link_t *link);
302static void nsp_cs_config (dev_link_t *link); 302static void nsp_cs_config (dev_link_t *link);
303static int nsp_cs_event (event_t event, int priority, event_callback_args_t *args); 303static 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);
101static int qlogic_event(event_t event, int priority, event_callback_args_t * args); 101static int qlogic_event(event_t event, int priority, event_callback_args_t * args);
102 102
103static dev_link_t *qlogic_attach(void); 103static dev_link_t *qlogic_attach(void);
104static void qlogic_detach(dev_link_t *); 104static void qlogic_detach(struct pcmcia_device *p_dev);
105 105
106 106
107static dev_link_t *dev_list = NULL; 107static 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
210static void qlogic_detach(dev_link_t * link) 210static 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
934static void 929static void
935SYM53C500_detach(dev_link_t *link) 930SYM53C500_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,
120static dev_info_t dev_info = "serial_cs"; 120static dev_info_t dev_info = "serial_cs";
121 121
122static dev_link_t *serial_attach(void); 122static dev_link_t *serial_attach(void);
123static void serial_detach(dev_link_t *); 123static void serial_detach(struct pcmcia_device *p_dev);
124 124
125static dev_link_t *dev_list = NULL; 125static 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
261static void serial_detach(dev_link_t * link) 261static 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
37static dev_link_t *ixj_attach(void); 37static dev_link_t *ixj_attach(void);
38static void ixj_detach(dev_link_t *); 38static void ixj_detach(struct pcmcia_device *p_dev);
39static void ixj_config(dev_link_t * link); 39static void ixj_config(dev_link_t * link);
40static void ixj_cs_release(dev_link_t * link); 40static void ixj_cs_release(dev_link_t * link);
41static int ixj_event(event_t event, int priority, event_callback_args_t * args); 41static 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
82static void ixj_detach(dev_link_t * link) 82static 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
76static void sl811_cs_release(dev_link_t * link);
77
76/*====================================================================*/ 78/*====================================================================*/
77 79
78static void release_platform_dev(struct device * dev) 80static 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
141static void sl811_cs_detach(dev_link_t *link) 143static 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
192static void sl811_cs_config(dev_link_t *link) 185static 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